Upgrade dependent version: github.com/open-policy-agent/opa v0.18.0 -> v0.45.0 Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
121 lines
3.1 KiB
Go
121 lines
3.1 KiB
Go
package jwk
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
|
|
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
|
)
|
|
|
|
func newECDSAPublicKey(key *ecdsa.PublicKey) (*ECDSAPublicKey, error) {
|
|
|
|
var hdr StandardHeaders
|
|
err := hdr.Set(KeyTypeKey, jwa.EC)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to set Key Type: %w", err)
|
|
}
|
|
|
|
return &ECDSAPublicKey{
|
|
StandardHeaders: &hdr,
|
|
key: key,
|
|
}, nil
|
|
}
|
|
|
|
func newECDSAPrivateKey(key *ecdsa.PrivateKey) (*ECDSAPrivateKey, error) {
|
|
|
|
var hdr StandardHeaders
|
|
err := hdr.Set(KeyTypeKey, jwa.EC)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to set Key Type: %w", err)
|
|
}
|
|
|
|
return &ECDSAPrivateKey{
|
|
StandardHeaders: &hdr,
|
|
key: key,
|
|
}, nil
|
|
}
|
|
|
|
// Materialize returns the EC-DSA public key represented by this JWK
|
|
func (k ECDSAPublicKey) Materialize() (interface{}, error) {
|
|
return k.key, nil
|
|
}
|
|
|
|
// Materialize returns the EC-DSA private key represented by this JWK
|
|
func (k ECDSAPrivateKey) Materialize() (interface{}, error) {
|
|
return k.key, nil
|
|
}
|
|
|
|
// GenerateKey creates a ECDSAPublicKey from JWK format
|
|
func (k *ECDSAPublicKey) GenerateKey(keyJSON *RawKeyJSON) error {
|
|
|
|
var x, y big.Int
|
|
|
|
if keyJSON.X == nil || keyJSON.Y == nil || keyJSON.Crv == "" {
|
|
return errors.New("missing mandatory key parameters X, Y or Crv")
|
|
}
|
|
|
|
x.SetBytes(keyJSON.X.Bytes())
|
|
y.SetBytes(keyJSON.Y.Bytes())
|
|
|
|
var curve elliptic.Curve
|
|
switch keyJSON.Crv {
|
|
case jwa.P256:
|
|
curve = elliptic.P256()
|
|
case jwa.P384:
|
|
curve = elliptic.P384()
|
|
case jwa.P521:
|
|
curve = elliptic.P521()
|
|
default:
|
|
return fmt.Errorf("invalid curve name %s", keyJSON.Crv)
|
|
}
|
|
|
|
*k = ECDSAPublicKey{
|
|
StandardHeaders: &keyJSON.StandardHeaders,
|
|
key: &ecdsa.PublicKey{
|
|
Curve: curve,
|
|
X: &x,
|
|
Y: &y,
|
|
},
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GenerateKey creates a ECDSAPrivateKey from JWK format
|
|
func (k *ECDSAPrivateKey) GenerateKey(keyJSON *RawKeyJSON) error {
|
|
|
|
if keyJSON.D == nil {
|
|
return errors.New("missing mandatory key parameter D")
|
|
}
|
|
eCDSAPublicKey := &ECDSAPublicKey{}
|
|
err := eCDSAPublicKey.GenerateKey(keyJSON)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to generate public key: %w", err)
|
|
}
|
|
dBytes := keyJSON.D.Bytes()
|
|
// The length of this octet string MUST be ceiling(log-base-2(n)/8)
|
|
// octets (where n is the order of the curve). This is because the private
|
|
// key d must be in the interval [1, n-1] so the bitlength of d should be
|
|
// no larger than the bitlength of n-1. The easiest way to find the octet
|
|
// length is to take bitlength(n-1), add 7 to force a carry, and shift this
|
|
// bit sequence right by 3, which is essentially dividing by 8 and adding
|
|
// 1 if there is any remainder. Thus, the private key value d should be
|
|
// output to (bitlength(n-1)+7)>>3 octets.
|
|
n := eCDSAPublicKey.key.Params().N
|
|
octetLength := (new(big.Int).Sub(n, big.NewInt(1)).BitLen() + 7) >> 3
|
|
if octetLength-len(dBytes) != 0 {
|
|
return errors.New("failed to generate private key. Incorrect D value")
|
|
}
|
|
privateKey := &ecdsa.PrivateKey{
|
|
PublicKey: *eCDSAPublicKey.key,
|
|
D: (&big.Int{}).SetBytes(keyJSON.D.Bytes()),
|
|
}
|
|
|
|
k.key = privateKey
|
|
k.StandardHeaders = &keyJSON.StandardHeaders
|
|
|
|
return nil
|
|
}
|