Upgrade dependent version: github.com/open-policy-agent/opa (#5315)
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>
This commit is contained in:
154
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/headers.go
generated
vendored
Normal file
154
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/headers.go
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
package jws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
)
|
||||
|
||||
// Constants for JWS Common parameters
|
||||
const (
|
||||
AlgorithmKey = "alg"
|
||||
ContentTypeKey = "cty"
|
||||
CriticalKey = "crit"
|
||||
JWKKey = "jwk"
|
||||
JWKSetURLKey = "jku"
|
||||
KeyIDKey = "kid"
|
||||
PrivateParamsKey = "privateParams"
|
||||
TypeKey = "typ"
|
||||
)
|
||||
|
||||
// Headers provides a common interface for common header parameters
|
||||
type Headers interface {
|
||||
Get(string) (interface{}, bool)
|
||||
Set(string, interface{}) error
|
||||
GetAlgorithm() jwa.SignatureAlgorithm
|
||||
}
|
||||
|
||||
// StandardHeaders contains JWS common parameters.
|
||||
type StandardHeaders struct {
|
||||
Algorithm jwa.SignatureAlgorithm `json:"alg,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.1
|
||||
ContentType string `json:"cty,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.10
|
||||
Critical []string `json:"crit,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.11
|
||||
JWK string `json:"jwk,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.3
|
||||
JWKSetURL string `json:"jku,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.2
|
||||
KeyID string `json:"kid,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.4
|
||||
PrivateParams map[string]interface{} `json:"privateParams,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.9
|
||||
Type string `json:"typ,omitempty"` // https://tools.ietf.org/html/rfc7515#section-4.1.9
|
||||
}
|
||||
|
||||
// GetAlgorithm returns algorithm
|
||||
func (h *StandardHeaders) GetAlgorithm() jwa.SignatureAlgorithm {
|
||||
return h.Algorithm
|
||||
}
|
||||
|
||||
// Get is a general getter function for StandardHeaders structure
|
||||
func (h *StandardHeaders) Get(name string) (interface{}, bool) {
|
||||
switch name {
|
||||
case AlgorithmKey:
|
||||
v := h.Algorithm
|
||||
if v == "" {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
case ContentTypeKey:
|
||||
v := h.ContentType
|
||||
if v == "" {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
case CriticalKey:
|
||||
v := h.Critical
|
||||
if len(v) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
case JWKKey:
|
||||
v := h.JWK
|
||||
if v == "" {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
case JWKSetURLKey:
|
||||
v := h.JWKSetURL
|
||||
if v == "" {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
case KeyIDKey:
|
||||
v := h.KeyID
|
||||
if v == "" {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
case PrivateParamsKey:
|
||||
v := h.PrivateParams
|
||||
if len(v) == 0 {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
case TypeKey:
|
||||
v := h.Type
|
||||
if v == "" {
|
||||
return nil, false
|
||||
}
|
||||
return v, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
// Set is a general setter function for StandardHeaders structure
|
||||
func (h *StandardHeaders) Set(name string, value interface{}) error {
|
||||
switch name {
|
||||
case AlgorithmKey:
|
||||
if err := h.Algorithm.Accept(value); err != nil {
|
||||
return fmt.Errorf("invalid value for %s key: %w", AlgorithmKey, err)
|
||||
}
|
||||
return nil
|
||||
case ContentTypeKey:
|
||||
if v, ok := value.(string); ok {
|
||||
h.ContentType = v
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid value for %s key: %T", ContentTypeKey, value)
|
||||
case CriticalKey:
|
||||
if v, ok := value.([]string); ok {
|
||||
h.Critical = v
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid value for %s key: %T", CriticalKey, value)
|
||||
case JWKKey:
|
||||
if v, ok := value.(string); ok {
|
||||
h.JWK = v
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid value for %s key: %T", JWKKey, value)
|
||||
case JWKSetURLKey:
|
||||
if v, ok := value.(string); ok {
|
||||
h.JWKSetURL = v
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid value for %s key: %T", JWKSetURLKey, value)
|
||||
case KeyIDKey:
|
||||
if v, ok := value.(string); ok {
|
||||
h.KeyID = v
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid value for %s key: %T", KeyIDKey, value)
|
||||
case PrivateParamsKey:
|
||||
if v, ok := value.(map[string]interface{}); ok {
|
||||
h.PrivateParams = v
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid value for %s key: %T", PrivateParamsKey, value)
|
||||
case TypeKey:
|
||||
if v, ok := value.(string); ok {
|
||||
h.Type = v
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid value for %s key: %T", TypeKey, value)
|
||||
default:
|
||||
return fmt.Errorf("invalid key: %s", name)
|
||||
}
|
||||
}
|
||||
22
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/interface.go
generated
vendored
Normal file
22
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/interface.go
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
package jws
|
||||
|
||||
// Message represents a full JWS encoded message. Flattened serialization
|
||||
// is not supported as a struct, but rather it's represented as a
|
||||
// Message struct with only one `Signature` element.
|
||||
//
|
||||
// Do not expect to use the Message object to verify or construct a
|
||||
// signed payloads with. You should only use this when you want to actually
|
||||
// want to programmatically view the contents for the full JWS Payload.
|
||||
//
|
||||
// To sign and verify, use the appropriate `SignWithOption()` nad `Verify()` functions
|
||||
type Message struct {
|
||||
Payload []byte `json:"payload"`
|
||||
Signatures []*Signature `json:"signatures,omitempty"`
|
||||
}
|
||||
|
||||
// Signature represents the headers and signature of a JWS message
|
||||
type Signature struct {
|
||||
Headers Headers `json:"header,omitempty"` // Unprotected Headers
|
||||
Protected Headers `json:"Protected,omitempty"` // Protected Headers
|
||||
Signature []byte `json:"signature,omitempty"` // GetSignature
|
||||
}
|
||||
221
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/jws.go
generated
vendored
Normal file
221
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/jws.go
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
// Package jws implements the digital Signature on JSON based data
|
||||
// structures as described in https://tools.ietf.org/html/rfc7515
|
||||
//
|
||||
// If you do not care about the details, the only things that you
|
||||
// would need to use are the following functions:
|
||||
//
|
||||
// jws.SignWithOption(Payload, algorithm, key)
|
||||
// jws.Verify(encodedjws, algorithm, key)
|
||||
//
|
||||
// To sign, simply use `jws.SignWithOption`. `Payload` is a []byte buffer that
|
||||
// contains whatever data you want to sign. `alg` is one of the
|
||||
// jwa.SignatureAlgorithm constants from package jwa. For RSA and
|
||||
// ECDSA family of algorithms, you will need to prepare a private key.
|
||||
// For HMAC family, you just need a []byte value. The `jws.SignWithOption`
|
||||
// function will return the encoded JWS message on success.
|
||||
//
|
||||
// To verify, use `jws.Verify`. It will parse the `encodedjws` buffer
|
||||
// and verify the result using `algorithm` and `key`. Upon successful
|
||||
// verification, the original Payload is returned, so you can work on it.
|
||||
package jws
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwk"
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jws/sign"
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jws/verify"
|
||||
)
|
||||
|
||||
// SignLiteral generates a Signature for the given Payload and Headers, and serializes
|
||||
// it in compact serialization format. In this format you may NOT use
|
||||
// multiple signers.
|
||||
//
|
||||
func SignLiteral(payload []byte, alg jwa.SignatureAlgorithm, key interface{}, hdrBuf []byte, rnd io.Reader) ([]byte, error) {
|
||||
encodedHdr := base64.RawURLEncoding.EncodeToString(hdrBuf)
|
||||
encodedPayload := base64.RawURLEncoding.EncodeToString(payload)
|
||||
signingInput := strings.Join(
|
||||
[]string{
|
||||
encodedHdr,
|
||||
encodedPayload,
|
||||
}, ".",
|
||||
)
|
||||
signer, err := sign.New(alg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create signer: %w", err)
|
||||
}
|
||||
|
||||
var signature []byte
|
||||
switch s := signer.(type) {
|
||||
case *sign.ECDSASigner:
|
||||
signature, err = s.SignWithRand([]byte(signingInput), key, rnd)
|
||||
default:
|
||||
signature, err = signer.Sign([]byte(signingInput), key)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to sign Payload: %w", err)
|
||||
}
|
||||
encodedSignature := base64.RawURLEncoding.EncodeToString(signature)
|
||||
compactSerialization := strings.Join(
|
||||
[]string{
|
||||
signingInput,
|
||||
encodedSignature,
|
||||
}, ".",
|
||||
)
|
||||
return []byte(compactSerialization), nil
|
||||
}
|
||||
|
||||
// SignWithOption generates a Signature for the given Payload, and serializes
|
||||
// it in compact serialization format. In this format you may NOT use
|
||||
// multiple signers.
|
||||
//
|
||||
// If you would like to pass custom Headers, use the WithHeaders option.
|
||||
func SignWithOption(payload []byte, alg jwa.SignatureAlgorithm, key interface{}) ([]byte, error) {
|
||||
var headers Headers = &StandardHeaders{}
|
||||
|
||||
err := headers.Set(AlgorithmKey, alg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set alg value: %w", err)
|
||||
}
|
||||
|
||||
hdrBuf, err := json.Marshal(headers)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal Headers: %w", err)
|
||||
}
|
||||
// NOTE(sr): we don't use SignWithOption -- if we did, this rand.Reader
|
||||
// should come from the BuiltinContext's Seed, too.
|
||||
return SignLiteral(payload, alg, key, hdrBuf, rand.Reader)
|
||||
}
|
||||
|
||||
// Verify checks if the given JWS message is verifiable using `alg` and `key`.
|
||||
// If the verification is successful, `err` is nil, and the content of the
|
||||
// Payload that was signed is returned. If you need more fine-grained
|
||||
// control of the verification process, manually call `Parse`, generate a
|
||||
// verifier, and call `Verify` on the parsed JWS message object.
|
||||
func Verify(buf []byte, alg jwa.SignatureAlgorithm, key interface{}) (ret []byte, err error) {
|
||||
|
||||
verifier, err := verify.New(alg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create verifier: %w", err)
|
||||
}
|
||||
|
||||
buf = bytes.TrimSpace(buf)
|
||||
if len(buf) == 0 {
|
||||
return nil, errors.New(`attempt to verify empty buffer`)
|
||||
}
|
||||
|
||||
parts, err := SplitCompact(string(buf[:]))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed extract from compact serialization format: %w", err)
|
||||
}
|
||||
|
||||
signingInput := strings.Join(
|
||||
[]string{
|
||||
parts[0],
|
||||
parts[1],
|
||||
}, ".",
|
||||
)
|
||||
|
||||
decodedSignature, err := base64.RawURLEncoding.DecodeString(parts[2])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode signature: %w", err)
|
||||
}
|
||||
if err := verifier.Verify([]byte(signingInput), decodedSignature, key); err != nil {
|
||||
return nil, fmt.Errorf("failed to verify message: %w", err)
|
||||
}
|
||||
|
||||
if decodedPayload, err := base64.RawURLEncoding.DecodeString(parts[1]); err == nil {
|
||||
return decodedPayload, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to decode Payload: %w", err)
|
||||
}
|
||||
|
||||
// VerifyWithJWK verifies the JWS message using the specified JWK
|
||||
func VerifyWithJWK(buf []byte, key jwk.Key) (payload []byte, err error) {
|
||||
|
||||
keyVal, err := key.Materialize()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to materialize key: %w", err)
|
||||
}
|
||||
return Verify(buf, key.GetAlgorithm(), keyVal)
|
||||
}
|
||||
|
||||
// VerifyWithJWKSet verifies the JWS message using JWK key set.
|
||||
// By default it will only pick up keys that have the "use" key
|
||||
// set to either "sig" or "enc", but you can override it by
|
||||
// providing a keyaccept function.
|
||||
func VerifyWithJWKSet(buf []byte, keyset *jwk.Set) (payload []byte, err error) {
|
||||
|
||||
for _, key := range keyset.Keys {
|
||||
payload, err := VerifyWithJWK(buf, key)
|
||||
if err == nil {
|
||||
return payload, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("failed to verify with any of the keys")
|
||||
}
|
||||
|
||||
// ParseByte parses a JWS value serialized via compact serialization and provided as []byte.
|
||||
func ParseByte(jwsCompact []byte) (m *Message, err error) {
|
||||
return parseCompact(string(jwsCompact[:]))
|
||||
}
|
||||
|
||||
// ParseString parses a JWS value serialized via compact serialization and provided as string.
|
||||
func ParseString(s string) (*Message, error) {
|
||||
return parseCompact(s)
|
||||
}
|
||||
|
||||
// SplitCompact splits a JWT and returns its three parts
|
||||
// separately: Protected Headers, Payload and Signature.
|
||||
func SplitCompact(jwsCompact string) ([]string, error) {
|
||||
|
||||
parts := strings.Split(jwsCompact, ".")
|
||||
if len(parts) < 3 {
|
||||
return nil, errors.New("failed to split compact serialization")
|
||||
}
|
||||
return parts, nil
|
||||
}
|
||||
|
||||
// parseCompact parses a JWS value serialized via compact serialization.
|
||||
func parseCompact(str string) (m *Message, err error) {
|
||||
|
||||
var decodedHeader, decodedPayload, decodedSignature []byte
|
||||
parts, err := SplitCompact(str)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid compact serialization format: %w", err)
|
||||
}
|
||||
|
||||
if decodedHeader, err = base64.RawURLEncoding.DecodeString(parts[0]); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode Headers: %w", err)
|
||||
}
|
||||
var hdr StandardHeaders
|
||||
if err := json.Unmarshal(decodedHeader, &hdr); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse JOSE Headers: %w", err)
|
||||
}
|
||||
|
||||
if decodedPayload, err = base64.RawURLEncoding.DecodeString(parts[1]); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode Payload: %w", err)
|
||||
}
|
||||
|
||||
if len(parts) > 2 {
|
||||
if decodedSignature, err = base64.RawURLEncoding.DecodeString(parts[2]); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode Signature: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var msg Message
|
||||
msg.Payload = decodedPayload
|
||||
msg.Signatures = append(msg.Signatures, &Signature{
|
||||
Protected: &hdr,
|
||||
Signature: decodedSignature,
|
||||
})
|
||||
return &msg, nil
|
||||
}
|
||||
26
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/message.go
generated
vendored
Normal file
26
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/message.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package jws
|
||||
|
||||
// PublicHeaders returns the public headers in a JWS
|
||||
func (s Signature) PublicHeaders() Headers {
|
||||
return s.Headers
|
||||
}
|
||||
|
||||
// ProtectedHeaders returns the protected headers in a JWS
|
||||
func (s Signature) ProtectedHeaders() Headers {
|
||||
return s.Protected
|
||||
}
|
||||
|
||||
// GetSignature returns the signature in a JWS
|
||||
func (s Signature) GetSignature() []byte {
|
||||
return s.Signature
|
||||
}
|
||||
|
||||
// GetPayload returns the payload in a JWS
|
||||
func (m Message) GetPayload() []byte {
|
||||
return m.Payload
|
||||
}
|
||||
|
||||
// GetSignatures returns the all signatures in a JWS
|
||||
func (m Message) GetSignatures() []*Signature {
|
||||
return m.Signatures
|
||||
}
|
||||
90
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/ecdsa.go
generated
vendored
Normal file
90
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/ecdsa.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
)
|
||||
|
||||
var ecdsaSignFuncs = map[jwa.SignatureAlgorithm]ecdsaSignFunc{}
|
||||
|
||||
func init() {
|
||||
algs := map[jwa.SignatureAlgorithm]crypto.Hash{
|
||||
jwa.ES256: crypto.SHA256,
|
||||
jwa.ES384: crypto.SHA384,
|
||||
jwa.ES512: crypto.SHA512,
|
||||
}
|
||||
|
||||
for alg, h := range algs {
|
||||
ecdsaSignFuncs[alg] = makeECDSASignFunc(h)
|
||||
}
|
||||
}
|
||||
|
||||
func makeECDSASignFunc(hash crypto.Hash) ecdsaSignFunc {
|
||||
return ecdsaSignFunc(func(payload []byte, key *ecdsa.PrivateKey, rnd io.Reader) ([]byte, error) {
|
||||
curveBits := key.Curve.Params().BitSize
|
||||
keyBytes := curveBits / 8
|
||||
// Curve bits do not need to be a multiple of 8.
|
||||
if curveBits%8 > 0 {
|
||||
keyBytes++
|
||||
}
|
||||
h := hash.New()
|
||||
h.Write(payload)
|
||||
r, s, err := ecdsa.Sign(rnd, key, h.Sum(nil))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to sign payload using ecdsa: %w", err)
|
||||
}
|
||||
|
||||
rBytes := r.Bytes()
|
||||
rBytesPadded := make([]byte, keyBytes)
|
||||
copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
|
||||
|
||||
sBytes := s.Bytes()
|
||||
sBytesPadded := make([]byte, keyBytes)
|
||||
copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
|
||||
|
||||
out := append(rBytesPadded, sBytesPadded...)
|
||||
return out, nil
|
||||
})
|
||||
}
|
||||
|
||||
func newECDSA(alg jwa.SignatureAlgorithm) (*ECDSASigner, error) {
|
||||
signfn, ok := ecdsaSignFuncs[alg]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported algorithm while trying to create ECDSA signer: %s", alg)
|
||||
}
|
||||
|
||||
return &ECDSASigner{
|
||||
alg: alg,
|
||||
sign: signfn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Algorithm returns the signer algorithm
|
||||
func (s ECDSASigner) Algorithm() jwa.SignatureAlgorithm {
|
||||
return s.alg
|
||||
}
|
||||
|
||||
// SignWithRand signs payload with a ECDSA private key and a provided randomness
|
||||
// source (such as `rand.Reader`).
|
||||
func (s ECDSASigner) SignWithRand(payload []byte, key interface{}, r io.Reader) ([]byte, error) {
|
||||
if key == nil {
|
||||
return nil, errors.New("missing private key while signing payload")
|
||||
}
|
||||
|
||||
privateKey, ok := key.(*ecdsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid key type %T. *ecdsa.PrivateKey is required", key)
|
||||
}
|
||||
return s.sign(payload, privateKey, r)
|
||||
}
|
||||
|
||||
// Sign signs payload with a ECDSA private key
|
||||
func (s ECDSASigner) Sign(payload []byte, key interface{}) ([]byte, error) {
|
||||
return s.SignWithRand(payload, key, rand.Reader)
|
||||
}
|
||||
66
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/hmac.go
generated
vendored
Normal file
66
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/hmac.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"hash"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var hmacSignFuncs = map[jwa.SignatureAlgorithm]hmacSignFunc{}
|
||||
|
||||
func init() {
|
||||
algs := map[jwa.SignatureAlgorithm]func() hash.Hash{
|
||||
jwa.HS256: sha256.New,
|
||||
jwa.HS384: sha512.New384,
|
||||
jwa.HS512: sha512.New,
|
||||
}
|
||||
|
||||
for alg, h := range algs {
|
||||
hmacSignFuncs[alg] = makeHMACSignFunc(h)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func newHMAC(alg jwa.SignatureAlgorithm) (*HMACSigner, error) {
|
||||
signer, ok := hmacSignFuncs[alg]
|
||||
if !ok {
|
||||
return nil, errors.Errorf(`unsupported algorithm while trying to create HMAC signer: %s`, alg)
|
||||
}
|
||||
|
||||
return &HMACSigner{
|
||||
alg: alg,
|
||||
sign: signer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func makeHMACSignFunc(hfunc func() hash.Hash) hmacSignFunc {
|
||||
return hmacSignFunc(func(payload []byte, key []byte) ([]byte, error) {
|
||||
h := hmac.New(hfunc, key)
|
||||
h.Write(payload)
|
||||
return h.Sum(nil), nil
|
||||
})
|
||||
}
|
||||
|
||||
// Algorithm returns the signer algorithm
|
||||
func (s HMACSigner) Algorithm() jwa.SignatureAlgorithm {
|
||||
return s.alg
|
||||
}
|
||||
|
||||
// Sign signs payload with a Symmetric key
|
||||
func (s HMACSigner) Sign(payload []byte, key interface{}) ([]byte, error) {
|
||||
hmackey, ok := key.([]byte)
|
||||
if !ok {
|
||||
return nil, errors.Errorf(`invalid key type %T. []byte is required`, key)
|
||||
}
|
||||
|
||||
if len(hmackey) == 0 {
|
||||
return nil, errors.New(`missing key while signing payload`)
|
||||
}
|
||||
|
||||
return s.sign(payload, hmackey)
|
||||
}
|
||||
46
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/interface.go
generated
vendored
Normal file
46
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/interface.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"io"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
)
|
||||
|
||||
// Signer provides a common interface for supported alg signing methods
|
||||
type Signer interface {
|
||||
// Sign creates a signature for the given `payload`.
|
||||
// `key` is the key used for signing the payload, and is usually
|
||||
// the private key type associated with the signature method. For example,
|
||||
// for `jwa.RSXXX` and `jwa.PSXXX` types, you need to pass the
|
||||
// `*"crypto/rsa".PrivateKey` type.
|
||||
// Check the documentation for each signer for details
|
||||
Sign(payload []byte, key interface{}) ([]byte, error)
|
||||
|
||||
Algorithm() jwa.SignatureAlgorithm
|
||||
}
|
||||
|
||||
type rsaSignFunc func([]byte, *rsa.PrivateKey) ([]byte, error)
|
||||
|
||||
// RSASigner uses crypto/rsa to sign the payloads.
|
||||
type RSASigner struct {
|
||||
alg jwa.SignatureAlgorithm
|
||||
sign rsaSignFunc
|
||||
}
|
||||
|
||||
type ecdsaSignFunc func([]byte, *ecdsa.PrivateKey, io.Reader) ([]byte, error)
|
||||
|
||||
// ECDSASigner uses crypto/ecdsa to sign the payloads.
|
||||
type ECDSASigner struct {
|
||||
alg jwa.SignatureAlgorithm
|
||||
sign ecdsaSignFunc
|
||||
}
|
||||
|
||||
type hmacSignFunc func([]byte, []byte) ([]byte, error)
|
||||
|
||||
// HMACSigner uses crypto/hmac to sign the payloads.
|
||||
type HMACSigner struct {
|
||||
alg jwa.SignatureAlgorithm
|
||||
sign hmacSignFunc
|
||||
}
|
||||
97
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/rsa.go
generated
vendored
Normal file
97
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/rsa.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var rsaSignFuncs = map[jwa.SignatureAlgorithm]rsaSignFunc{}
|
||||
|
||||
func init() {
|
||||
algs := map[jwa.SignatureAlgorithm]struct {
|
||||
Hash crypto.Hash
|
||||
SignFunc func(crypto.Hash) rsaSignFunc
|
||||
}{
|
||||
jwa.RS256: {
|
||||
Hash: crypto.SHA256,
|
||||
SignFunc: makeSignPKCS1v15,
|
||||
},
|
||||
jwa.RS384: {
|
||||
Hash: crypto.SHA384,
|
||||
SignFunc: makeSignPKCS1v15,
|
||||
},
|
||||
jwa.RS512: {
|
||||
Hash: crypto.SHA512,
|
||||
SignFunc: makeSignPKCS1v15,
|
||||
},
|
||||
jwa.PS256: {
|
||||
Hash: crypto.SHA256,
|
||||
SignFunc: makeSignPSS,
|
||||
},
|
||||
jwa.PS384: {
|
||||
Hash: crypto.SHA384,
|
||||
SignFunc: makeSignPSS,
|
||||
},
|
||||
jwa.PS512: {
|
||||
Hash: crypto.SHA512,
|
||||
SignFunc: makeSignPSS,
|
||||
},
|
||||
}
|
||||
|
||||
for alg, item := range algs {
|
||||
rsaSignFuncs[alg] = item.SignFunc(item.Hash)
|
||||
}
|
||||
}
|
||||
|
||||
func makeSignPKCS1v15(hash crypto.Hash) rsaSignFunc {
|
||||
return rsaSignFunc(func(payload []byte, key *rsa.PrivateKey) ([]byte, error) {
|
||||
h := hash.New()
|
||||
h.Write(payload)
|
||||
return rsa.SignPKCS1v15(rand.Reader, key, hash, h.Sum(nil))
|
||||
})
|
||||
}
|
||||
|
||||
func makeSignPSS(hash crypto.Hash) rsaSignFunc {
|
||||
return rsaSignFunc(func(payload []byte, key *rsa.PrivateKey) ([]byte, error) {
|
||||
h := hash.New()
|
||||
h.Write(payload)
|
||||
return rsa.SignPSS(rand.Reader, key, hash, h.Sum(nil), &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthAuto,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func newRSA(alg jwa.SignatureAlgorithm) (*RSASigner, error) {
|
||||
signfn, ok := rsaSignFuncs[alg]
|
||||
if !ok {
|
||||
return nil, errors.Errorf(`unsupported algorithm while trying to create RSA signer: %s`, alg)
|
||||
}
|
||||
return &RSASigner{
|
||||
alg: alg,
|
||||
sign: signfn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Algorithm returns the signer algorithm
|
||||
func (s RSASigner) Algorithm() jwa.SignatureAlgorithm {
|
||||
return s.alg
|
||||
}
|
||||
|
||||
// Sign creates a signature using crypto/rsa. key must be a non-nil instance of
|
||||
// `*"crypto/rsa".PrivateKey`.
|
||||
func (s RSASigner) Sign(payload []byte, key interface{}) ([]byte, error) {
|
||||
if key == nil {
|
||||
return nil, errors.New(`missing private key while signing payload`)
|
||||
}
|
||||
rsakey, ok := key.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, errors.Errorf(`invalid key type %T. *rsa.PrivateKey is required`, key)
|
||||
}
|
||||
|
||||
return s.sign(payload, rsakey)
|
||||
}
|
||||
67
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go
generated
vendored
Normal file
67
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/sign/sign.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
)
|
||||
|
||||
// New creates a signer that signs payloads using the given signature algorithm.
|
||||
func New(alg jwa.SignatureAlgorithm) (Signer, error) {
|
||||
switch alg {
|
||||
case jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512:
|
||||
return newRSA(alg)
|
||||
case jwa.ES256, jwa.ES384, jwa.ES512:
|
||||
return newECDSA(alg)
|
||||
case jwa.HS256, jwa.HS384, jwa.HS512:
|
||||
return newHMAC(alg)
|
||||
default:
|
||||
return nil, errors.Errorf(`unsupported signature algorithm %s`, alg)
|
||||
}
|
||||
}
|
||||
|
||||
// GetSigningKey returns a *rsa.PrivateKey or *ecdsa.PrivateKey typically encoded in PEM blocks of type "RSA PRIVATE KEY"
|
||||
// or "EC PRIVATE KEY" for RSA and ECDSA family of algorithms.
|
||||
// For HMAC family, it return a []byte value
|
||||
func GetSigningKey(key string, alg jwa.SignatureAlgorithm) (interface{}, error) {
|
||||
switch alg {
|
||||
case jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512:
|
||||
block, _ := pem.Decode([]byte(key))
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("failed to parse PEM block containing the key")
|
||||
}
|
||||
|
||||
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
pkcs8priv, err2 := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err2 != nil {
|
||||
return nil, fmt.Errorf("error parsing private key (%v), (%v)", err, err2)
|
||||
}
|
||||
return pkcs8priv, nil
|
||||
}
|
||||
return priv, nil
|
||||
case jwa.ES256, jwa.ES384, jwa.ES512:
|
||||
block, _ := pem.Decode([]byte(key))
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("failed to parse PEM block containing the key")
|
||||
}
|
||||
|
||||
priv, err := x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
pkcs8priv, err2 := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err2 != nil {
|
||||
return nil, fmt.Errorf("error parsing private key (%v), (%v)", err, err2)
|
||||
}
|
||||
return pkcs8priv, nil
|
||||
}
|
||||
return priv, nil
|
||||
case jwa.HS256, jwa.HS384, jwa.HS512:
|
||||
return []byte(key), nil
|
||||
default:
|
||||
return nil, errors.Errorf("unsupported signature algorithm: %s", alg)
|
||||
}
|
||||
}
|
||||
67
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/ecdsa.go
generated
vendored
Normal file
67
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/ecdsa.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"math/big"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
)
|
||||
|
||||
var ecdsaVerifyFuncs = map[jwa.SignatureAlgorithm]ecdsaVerifyFunc{}
|
||||
|
||||
func init() {
|
||||
algs := map[jwa.SignatureAlgorithm]crypto.Hash{
|
||||
jwa.ES256: crypto.SHA256,
|
||||
jwa.ES384: crypto.SHA384,
|
||||
jwa.ES512: crypto.SHA512,
|
||||
}
|
||||
|
||||
for alg, h := range algs {
|
||||
ecdsaVerifyFuncs[alg] = makeECDSAVerifyFunc(h)
|
||||
}
|
||||
}
|
||||
|
||||
func makeECDSAVerifyFunc(hash crypto.Hash) ecdsaVerifyFunc {
|
||||
return ecdsaVerifyFunc(func(payload []byte, signature []byte, key *ecdsa.PublicKey) error {
|
||||
|
||||
r, s := &big.Int{}, &big.Int{}
|
||||
n := len(signature) / 2
|
||||
r.SetBytes(signature[:n])
|
||||
s.SetBytes(signature[n:])
|
||||
|
||||
h := hash.New()
|
||||
h.Write(payload)
|
||||
|
||||
if !ecdsa.Verify(key, h.Sum(nil), r, s) {
|
||||
return errors.New(`failed to verify signature using ecdsa`)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func newECDSA(alg jwa.SignatureAlgorithm) (*ECDSAVerifier, error) {
|
||||
verifyfn, ok := ecdsaVerifyFuncs[alg]
|
||||
if !ok {
|
||||
return nil, errors.Errorf(`unsupported algorithm while trying to create ECDSA verifier: %s`, alg)
|
||||
}
|
||||
|
||||
return &ECDSAVerifier{
|
||||
verify: verifyfn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Verify checks whether the signature for a given input and key is correct
|
||||
func (v ECDSAVerifier) Verify(payload []byte, signature []byte, key interface{}) error {
|
||||
if key == nil {
|
||||
return errors.New(`missing public key while verifying payload`)
|
||||
}
|
||||
ecdsakey, ok := key.(*ecdsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.Errorf(`invalid key type %T. *ecdsa.PublicKey is required`, key)
|
||||
}
|
||||
|
||||
return v.verify(payload, signature, ecdsakey)
|
||||
}
|
||||
33
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/hmac.go
generated
vendored
Normal file
33
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/hmac.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"fmt"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jws/sign"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func newHMAC(alg jwa.SignatureAlgorithm) (*HMACVerifier, error) {
|
||||
|
||||
s, err := sign.New(alg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate HMAC signer: %w", err)
|
||||
}
|
||||
return &HMACVerifier{signer: s}, nil
|
||||
}
|
||||
|
||||
// Verify checks whether the signature for a given input and key is correct
|
||||
func (v HMACVerifier) Verify(signingInput, signature []byte, key interface{}) (err error) {
|
||||
|
||||
expected, err := v.signer.Sign(signingInput, key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generated signature: %w", err)
|
||||
}
|
||||
|
||||
if !hmac.Equal(signature, expected) {
|
||||
return errors.New("failed to match hmac signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
39
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/interface.go
generated
vendored
Normal file
39
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/interface.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jws/sign"
|
||||
)
|
||||
|
||||
// Verifier provides a common interface for supported alg verification methods
|
||||
type Verifier interface {
|
||||
// Verify checks whether the payload and signature are valid for
|
||||
// the given key.
|
||||
// `key` is the key used for verifying the payload, and is usually
|
||||
// the public key associated with the signature method. For example,
|
||||
// for `jwa.RSXXX` and `jwa.PSXXX` types, you need to pass the
|
||||
// `*"crypto/rsa".PublicKey` type.
|
||||
// Check the documentation for each verifier for details
|
||||
Verify(payload []byte, signature []byte, key interface{}) error
|
||||
}
|
||||
|
||||
type rsaVerifyFunc func([]byte, []byte, *rsa.PublicKey) error
|
||||
|
||||
// RSAVerifier implements the Verifier interface
|
||||
type RSAVerifier struct {
|
||||
verify rsaVerifyFunc
|
||||
}
|
||||
|
||||
type ecdsaVerifyFunc func([]byte, []byte, *ecdsa.PublicKey) error
|
||||
|
||||
// ECDSAVerifier implements the Verifier interface
|
||||
type ECDSAVerifier struct {
|
||||
verify ecdsaVerifyFunc
|
||||
}
|
||||
|
||||
// HMACVerifier implements the Verifier interface
|
||||
type HMACVerifier struct {
|
||||
signer sign.Signer
|
||||
}
|
||||
88
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/rsa.go
generated
vendored
Normal file
88
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/rsa.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var rsaVerifyFuncs = map[jwa.SignatureAlgorithm]rsaVerifyFunc{}
|
||||
|
||||
func init() {
|
||||
algs := map[jwa.SignatureAlgorithm]struct {
|
||||
Hash crypto.Hash
|
||||
VerifyFunc func(crypto.Hash) rsaVerifyFunc
|
||||
}{
|
||||
jwa.RS256: {
|
||||
Hash: crypto.SHA256,
|
||||
VerifyFunc: makeVerifyPKCS1v15,
|
||||
},
|
||||
jwa.RS384: {
|
||||
Hash: crypto.SHA384,
|
||||
VerifyFunc: makeVerifyPKCS1v15,
|
||||
},
|
||||
jwa.RS512: {
|
||||
Hash: crypto.SHA512,
|
||||
VerifyFunc: makeVerifyPKCS1v15,
|
||||
},
|
||||
jwa.PS256: {
|
||||
Hash: crypto.SHA256,
|
||||
VerifyFunc: makeVerifyPSS,
|
||||
},
|
||||
jwa.PS384: {
|
||||
Hash: crypto.SHA384,
|
||||
VerifyFunc: makeVerifyPSS,
|
||||
},
|
||||
jwa.PS512: {
|
||||
Hash: crypto.SHA512,
|
||||
VerifyFunc: makeVerifyPSS,
|
||||
},
|
||||
}
|
||||
|
||||
for alg, item := range algs {
|
||||
rsaVerifyFuncs[alg] = item.VerifyFunc(item.Hash)
|
||||
}
|
||||
}
|
||||
|
||||
func makeVerifyPKCS1v15(hash crypto.Hash) rsaVerifyFunc {
|
||||
return rsaVerifyFunc(func(payload, signature []byte, key *rsa.PublicKey) error {
|
||||
h := hash.New()
|
||||
h.Write(payload)
|
||||
return rsa.VerifyPKCS1v15(key, hash, h.Sum(nil), signature)
|
||||
})
|
||||
}
|
||||
|
||||
func makeVerifyPSS(hash crypto.Hash) rsaVerifyFunc {
|
||||
return rsaVerifyFunc(func(payload, signature []byte, key *rsa.PublicKey) error {
|
||||
h := hash.New()
|
||||
h.Write(payload)
|
||||
return rsa.VerifyPSS(key, hash, h.Sum(nil), signature, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func newRSA(alg jwa.SignatureAlgorithm) (*RSAVerifier, error) {
|
||||
verifyfn, ok := rsaVerifyFuncs[alg]
|
||||
if !ok {
|
||||
return nil, errors.Errorf(`unsupported algorithm while trying to create RSA verifier: %s`, alg)
|
||||
}
|
||||
|
||||
return &RSAVerifier{
|
||||
verify: verifyfn,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Verify checks if a JWS is valid.
|
||||
func (v RSAVerifier) Verify(payload, signature []byte, key interface{}) error {
|
||||
if key == nil {
|
||||
return errors.New(`missing public key while verifying payload`)
|
||||
}
|
||||
rsaKey, ok := key.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return errors.Errorf(`invalid key type %T. *rsa.PublicKey is required`, key)
|
||||
}
|
||||
|
||||
return v.verify(payload, signature, rsaKey)
|
||||
}
|
||||
57
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go
generated
vendored
Normal file
57
vendor/github.com/open-policy-agent/opa/internal/jwx/jws/verify/verify.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwa"
|
||||
)
|
||||
|
||||
// New creates a new JWS verifier using the specified algorithm
|
||||
// and the public key
|
||||
func New(alg jwa.SignatureAlgorithm) (Verifier, error) {
|
||||
switch alg {
|
||||
case jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512:
|
||||
return newRSA(alg)
|
||||
case jwa.ES256, jwa.ES384, jwa.ES512:
|
||||
return newECDSA(alg)
|
||||
case jwa.HS256, jwa.HS384, jwa.HS512:
|
||||
return newHMAC(alg)
|
||||
default:
|
||||
return nil, errors.Errorf(`unsupported signature algorithm: %s`, alg)
|
||||
}
|
||||
}
|
||||
|
||||
// GetSigningKey returns a *rsa.PublicKey or *ecdsa.PublicKey typically encoded in PEM blocks of type "PUBLIC KEY",
|
||||
// for RSA and ECDSA family of algorithms.
|
||||
// For HMAC family, it return a []byte value
|
||||
func GetSigningKey(key string, alg jwa.SignatureAlgorithm) (interface{}, error) {
|
||||
switch alg {
|
||||
case jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512, jwa.ES256, jwa.ES384, jwa.ES512:
|
||||
block, _ := pem.Decode([]byte(key))
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("failed to parse PEM block containing the key")
|
||||
}
|
||||
|
||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch pub := pub.(type) {
|
||||
case *rsa.PublicKey, *ecdsa.PublicKey:
|
||||
return pub, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid key type %T", pub)
|
||||
}
|
||||
case jwa.HS256, jwa.HS384, jwa.HS512:
|
||||
return []byte(key), nil
|
||||
default:
|
||||
return nil, errors.Errorf("unsupported signature algorithm: %s", alg)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user