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>
154 lines
3.8 KiB
Go
154 lines
3.8 KiB
Go
// Package jwk implements JWK as described in https://tools.ietf.org/html/rfc7517
|
|
package jwk
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/rsa"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
|
)
|
|
|
|
// GetPublicKey returns the public key based on the private key type.
|
|
// For rsa key types *rsa.PublicKey is returned; for ecdsa key types *ecdsa.PublicKey;
|
|
// for byte slice (raw) keys, the key itself is returned. If the corresponding
|
|
// public key cannot be deduced, an error is returned
|
|
func GetPublicKey(key interface{}) (interface{}, error) {
|
|
if key == nil {
|
|
return nil, errors.New("jwk.New requires a non-nil key")
|
|
}
|
|
|
|
switch v := key.(type) {
|
|
// Mental note: although Public() is defined in both types,
|
|
// you can not coalesce the clauses for rsa.PrivateKey and
|
|
// ecdsa.PrivateKey, as then `v` becomes interface{}
|
|
// b/c the compiler cannot deduce the exact type.
|
|
case *rsa.PrivateKey:
|
|
return v.Public(), nil
|
|
case *ecdsa.PrivateKey:
|
|
return v.Public(), nil
|
|
case []byte:
|
|
return v, nil
|
|
default:
|
|
return nil, fmt.Errorf("invalid key type %T", key)
|
|
}
|
|
}
|
|
|
|
// GetKeyTypeFromKey creates a jwk.Key from the given key.
|
|
func GetKeyTypeFromKey(key interface{}) jwa.KeyType {
|
|
|
|
switch key.(type) {
|
|
case *rsa.PrivateKey, *rsa.PublicKey:
|
|
return jwa.RSA
|
|
case *ecdsa.PrivateKey, *ecdsa.PublicKey:
|
|
return jwa.EC
|
|
case []byte:
|
|
return jwa.OctetSeq
|
|
default:
|
|
return jwa.InvalidKeyType
|
|
}
|
|
}
|
|
|
|
// New creates a jwk.Key from the given key.
|
|
func New(key interface{}) (Key, error) {
|
|
if key == nil {
|
|
return nil, errors.New("jwk.New requires a non-nil key")
|
|
}
|
|
|
|
switch v := key.(type) {
|
|
case *rsa.PrivateKey:
|
|
return newRSAPrivateKey(v)
|
|
case *rsa.PublicKey:
|
|
return newRSAPublicKey(v)
|
|
case *ecdsa.PrivateKey:
|
|
return newECDSAPrivateKey(v)
|
|
case *ecdsa.PublicKey:
|
|
return newECDSAPublicKey(v)
|
|
case []byte:
|
|
return newSymmetricKey(v)
|
|
default:
|
|
return nil, fmt.Errorf("invalid key type %T", key)
|
|
}
|
|
}
|
|
|
|
func parse(jwkSrc string) (*Set, error) {
|
|
|
|
var jwkKeySet Set
|
|
var jwkKey Key
|
|
rawKeySetJSON := &RawKeySetJSON{}
|
|
err := json.Unmarshal([]byte(jwkSrc), rawKeySetJSON)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to unmarshal JWK Set: %w", err)
|
|
}
|
|
if len(rawKeySetJSON.Keys) == 0 {
|
|
|
|
// It might be a single key
|
|
rawKeyJSON := &RawKeyJSON{}
|
|
err := json.Unmarshal([]byte(jwkSrc), rawKeyJSON)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to unmarshal JWK: %w", err)
|
|
}
|
|
jwkKey, err = rawKeyJSON.GenerateKey()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate key: %w", err)
|
|
}
|
|
// Add to set
|
|
jwkKeySet.Keys = append(jwkKeySet.Keys, jwkKey)
|
|
} else {
|
|
for i := range rawKeySetJSON.Keys {
|
|
rawKeyJSON := rawKeySetJSON.Keys[i]
|
|
if rawKeyJSON.Algorithm != nil && *rawKeyJSON.Algorithm == jwa.Unsupported {
|
|
continue
|
|
}
|
|
jwkKey, err = rawKeyJSON.GenerateKey()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate key: %w", err)
|
|
}
|
|
jwkKeySet.Keys = append(jwkKeySet.Keys, jwkKey)
|
|
}
|
|
}
|
|
return &jwkKeySet, nil
|
|
}
|
|
|
|
// ParseBytes parses JWK from the incoming byte buffer.
|
|
func ParseBytes(buf []byte) (*Set, error) {
|
|
return parse(string(buf[:]))
|
|
}
|
|
|
|
// ParseString parses JWK from the incoming string.
|
|
func ParseString(s string) (*Set, error) {
|
|
return parse(s)
|
|
}
|
|
|
|
// GenerateKey creates an internal representation of a key from a raw JWK JSON
|
|
func (r *RawKeyJSON) GenerateKey() (Key, error) {
|
|
|
|
var key Key
|
|
|
|
switch r.KeyType {
|
|
case jwa.RSA:
|
|
if r.D != nil {
|
|
key = &RSAPrivateKey{}
|
|
} else {
|
|
key = &RSAPublicKey{}
|
|
}
|
|
case jwa.EC:
|
|
if r.D != nil {
|
|
key = &ECDSAPrivateKey{}
|
|
} else {
|
|
key = &ECDSAPublicKey{}
|
|
}
|
|
case jwa.OctetSeq:
|
|
key = &SymmetricKey{}
|
|
default:
|
|
return nil, errors.New("unrecognized key type")
|
|
}
|
|
err := key.GenerateKey(r)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate key from JWK: %w", err)
|
|
}
|
|
return key, nil
|
|
}
|