mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
e43ef0a979
Earlier this evening I tried to run the Go [modernize](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize) analyzer on OPA. That didn't go as planned: - https://github.com/golang/go/issues/73661 - https://github.com/golang/go/issues/73663 While we wait for that to be fixed, I figured an old-fashioned search-and-replace across the repo may work for at least the `interface{}` to `any` conversion. That should help make it easier to see the other fixes as applied by the modernize tool once it has had those issues resolved. Signed-off-by: Anders Eknert <anders@styra.com>
154 lines
3.7 KiB
Go
154 lines
3.7 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 any) (any, 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 any
|
|
// 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 any) 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 any) (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
|
|
}
|