mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
internal/providers/aws: Refactor deprecated crypto/elliptic APIs to crypto/ecdh (#8395)
Following SA1019 deprecation warnings in Go 1.21+, the legacy curve.ScalarBaseMult and curve.IsOnCurve calls for NIST curves (like P256) are substituted with their crypto/ecdh standard equivalents. Tests continue to parse and verify AWS V4a signatures equivalently under the new module constraints. Signed-off-by: kanywst <niwatakuma@icloud.com>
This commit is contained in:
@@ -2,6 +2,7 @@ package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdh"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/hmac"
|
||||
@@ -27,27 +28,77 @@ func ECDSAKey(curve elliptic.Curve, d []byte) *ecdsa.PrivateKey {
|
||||
// ECDSAKeyFromPoint takes the given elliptic curve and point and returns the
|
||||
// private and public keypair
|
||||
func ECDSAKeyFromPoint(curve elliptic.Curve, d *big.Int) *ecdsa.PrivateKey {
|
||||
pX, pY := curve.ScalarBaseMult(d.Bytes())
|
||||
dBytes := make([]byte, (curve.Params().BitSize+7)/8)
|
||||
d.FillBytes(dBytes)
|
||||
|
||||
privKey := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: pX,
|
||||
Y: pY,
|
||||
},
|
||||
D: d,
|
||||
}
|
||||
|
||||
var pubBytes []byte
|
||||
switch curve {
|
||||
case elliptic.P256():
|
||||
if ecdhPriv, err := ecdh.P256().NewPrivateKey(dBytes); err == nil {
|
||||
pubBytes = ecdhPriv.PublicKey().Bytes()
|
||||
}
|
||||
case elliptic.P384():
|
||||
if ecdhPriv, err := ecdh.P384().NewPrivateKey(dBytes); err == nil {
|
||||
pubBytes = ecdhPriv.PublicKey().Bytes()
|
||||
}
|
||||
case elliptic.P521():
|
||||
if ecdhPriv, err := ecdh.P521().NewPrivateKey(dBytes); err == nil {
|
||||
pubBytes = ecdhPriv.PublicKey().Bytes()
|
||||
}
|
||||
}
|
||||
|
||||
if len(pubBytes) > 0 {
|
||||
byteLen := (curve.Params().BitSize + 7) / 8
|
||||
privKey.X = new(big.Int).SetBytes(pubBytes[1 : 1+byteLen])
|
||||
privKey.Y = new(big.Int).SetBytes(pubBytes[1+byteLen:])
|
||||
} else {
|
||||
panic(fmt.Sprintf("unsupported curve or invalid private key: %v", curve))
|
||||
}
|
||||
|
||||
return privKey
|
||||
}
|
||||
|
||||
// mathIntToBytes writes val as a big-endian, fixed-length byte slice into out,
|
||||
// zero-padding on the left when val.Bytes() is shorter than out. This satisfies
|
||||
// the uncompressed SEC 1 encoding (0x04 || X || Y) expected by crypto/ecdh's
|
||||
// NewPublicKey: https://pkg.go.dev/crypto/ecdh#Curve.NewPublicKey
|
||||
func mathIntToBytes(val *big.Int, out []byte) {
|
||||
valBytes := val.Bytes()
|
||||
copy(out[len(out)-len(valBytes):], valBytes)
|
||||
}
|
||||
|
||||
// ECDSAPublicKey takes the provide curve and (x, y) coordinates and returns
|
||||
// *ecdsa.PublicKey. Returns an error if the given points are not on the curve.
|
||||
func ECDSAPublicKey(curve elliptic.Curve, x, y []byte) (*ecdsa.PublicKey, error) {
|
||||
xPoint := (&big.Int{}).SetBytes(x)
|
||||
yPoint := (&big.Int{}).SetBytes(y)
|
||||
|
||||
if !curve.IsOnCurve(xPoint, yPoint) {
|
||||
byteLen := (curve.Params().BitSize + 7) / 8
|
||||
buf := make([]byte, 1+2*byteLen)
|
||||
buf[0] = 4 // uncompressed point
|
||||
mathIntToBytes(xPoint, buf[1:1+byteLen])
|
||||
mathIntToBytes(yPoint, buf[1+byteLen:])
|
||||
|
||||
var err error
|
||||
switch curve {
|
||||
case elliptic.P256():
|
||||
_, err = ecdh.P256().NewPublicKey(buf)
|
||||
case elliptic.P384():
|
||||
_, err = ecdh.P384().NewPublicKey(buf)
|
||||
case elliptic.P521():
|
||||
_, err = ecdh.P521().NewPublicKey(buf)
|
||||
default:
|
||||
err = fmt.Errorf("unsupported curve for ECDSA: %v", curve)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("point(%v, %v) is not on the given curve", xPoint.String(), yPoint.String())
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package aws
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ecdh"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
@@ -115,7 +116,18 @@ func deriveKeyFromAccessKeyPair(accessKey, secretKey string) (*ecdsa.PrivateKey,
|
||||
priv := new(ecdsa.PrivateKey)
|
||||
priv.PublicKey.Curve = p256
|
||||
priv.D = d
|
||||
priv.PublicKey.X, priv.PublicKey.Y = p256.ScalarBaseMult(d.Bytes())
|
||||
|
||||
dBytes := make([]byte, 32)
|
||||
d.FillBytes(dBytes)
|
||||
|
||||
ecdhPriv, err := ecdh.P256().NewPrivateKey(dBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pubBytes := ecdhPriv.PublicKey().Bytes()
|
||||
|
||||
priv.PublicKey.X = new(big.Int).SetBytes(pubBytes[1:33])
|
||||
priv.PublicKey.Y = new(big.Int).SetBytes(pubBytes[33:])
|
||||
|
||||
return priv, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user