github.com/lestrrat-go/jwx/v2@v2.0.21/jwk/jwk.go (about)

     1  //go:generate ../tools/cmd/genjwk.sh
     2  
     3  // Package jwk implements JWK as described in https://tools.ietf.org/html/rfc7517
     4  package jwk
     5  
     6  import (
     7  	"bytes"
     8  	"crypto"
     9  	"crypto/ecdsa"
    10  	"crypto/ed25519"
    11  	"crypto/elliptic"
    12  	"crypto/rsa"
    13  	"crypto/x509"
    14  	"encoding/pem"
    15  	"errors"
    16  	"fmt"
    17  	"io"
    18  	"math/big"
    19  
    20  	"github.com/lestrrat-go/jwx/v2/internal/base64"
    21  	"github.com/lestrrat-go/jwx/v2/internal/ecutil"
    22  	"github.com/lestrrat-go/jwx/v2/internal/json"
    23  	"github.com/lestrrat-go/jwx/v2/jwa"
    24  	"github.com/lestrrat-go/jwx/v2/x25519"
    25  )
    26  
    27  var registry = json.NewRegistry()
    28  
    29  func bigIntToBytes(n *big.Int) ([]byte, error) {
    30  	if n == nil {
    31  		return nil, fmt.Errorf(`invalid *big.Int value`)
    32  	}
    33  	return n.Bytes(), nil
    34  }
    35  
    36  // FromRaw creates a jwk.Key from the given key (RSA/ECDSA/symmetric keys).
    37  //
    38  // The constructor auto-detects the type of key to be instantiated
    39  // based on the input type:
    40  //
    41  //   - "crypto/rsa".PrivateKey and "crypto/rsa".PublicKey creates an RSA based key
    42  //   - "crypto/ecdsa".PrivateKey and "crypto/ecdsa".PublicKey creates an EC based key
    43  //   - "crypto/ed25519".PrivateKey and "crypto/ed25519".PublicKey creates an OKP based key
    44  //   - []byte creates a symmetric key
    45  func FromRaw(key interface{}) (Key, error) {
    46  	if key == nil {
    47  		return nil, fmt.Errorf(`jwk.FromRaw requires a non-nil key`)
    48  	}
    49  
    50  	var ptr interface{}
    51  	switch v := key.(type) {
    52  	case rsa.PrivateKey:
    53  		ptr = &v
    54  	case rsa.PublicKey:
    55  		ptr = &v
    56  	case ecdsa.PrivateKey:
    57  		ptr = &v
    58  	case ecdsa.PublicKey:
    59  		ptr = &v
    60  	default:
    61  		ptr = v
    62  	}
    63  
    64  	switch rawKey := ptr.(type) {
    65  	case *rsa.PrivateKey:
    66  		k := newRSAPrivateKey()
    67  		if err := k.FromRaw(rawKey); err != nil {
    68  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
    69  		}
    70  		return k, nil
    71  	case *rsa.PublicKey:
    72  		k := newRSAPublicKey()
    73  		if err := k.FromRaw(rawKey); err != nil {
    74  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
    75  		}
    76  		return k, nil
    77  	case *ecdsa.PrivateKey:
    78  		k := newECDSAPrivateKey()
    79  		if err := k.FromRaw(rawKey); err != nil {
    80  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
    81  		}
    82  		return k, nil
    83  	case *ecdsa.PublicKey:
    84  		k := newECDSAPublicKey()
    85  		if err := k.FromRaw(rawKey); err != nil {
    86  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
    87  		}
    88  		return k, nil
    89  	case ed25519.PrivateKey:
    90  		k := newOKPPrivateKey()
    91  		if err := k.FromRaw(rawKey); err != nil {
    92  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
    93  		}
    94  		return k, nil
    95  	case ed25519.PublicKey:
    96  		k := newOKPPublicKey()
    97  		if err := k.FromRaw(rawKey); err != nil {
    98  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
    99  		}
   100  		return k, nil
   101  	case x25519.PrivateKey:
   102  		k := newOKPPrivateKey()
   103  		if err := k.FromRaw(rawKey); err != nil {
   104  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
   105  		}
   106  		return k, nil
   107  	case x25519.PublicKey:
   108  		k := newOKPPublicKey()
   109  		if err := k.FromRaw(rawKey); err != nil {
   110  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
   111  		}
   112  		return k, nil
   113  	case []byte:
   114  		k := newSymmetricKey()
   115  		if err := k.FromRaw(rawKey); err != nil {
   116  			return nil, fmt.Errorf(`failed to initialize %T from %T: %w`, k, rawKey, err)
   117  		}
   118  		return k, nil
   119  	default:
   120  		return nil, fmt.Errorf(`invalid key type '%T' for jwk.New`, key)
   121  	}
   122  }
   123  
   124  // PublicSetOf returns a new jwk.Set consisting of
   125  // public keys of the keys contained in the set.
   126  //
   127  // This is useful when you are generating a set of private keys, and
   128  // you want to generate the corresponding public versions for the
   129  // users to verify with.
   130  //
   131  // Be aware that all fields will be copied onto the new public key. It is the caller's
   132  // responsibility to remove any fields, if necessary.
   133  func PublicSetOf(v Set) (Set, error) {
   134  	newSet := NewSet()
   135  
   136  	n := v.Len()
   137  	for i := 0; i < n; i++ {
   138  		k, ok := v.Key(i)
   139  		if !ok {
   140  			return nil, fmt.Errorf(`key not found`)
   141  		}
   142  		pubKey, err := PublicKeyOf(k)
   143  		if err != nil {
   144  			return nil, fmt.Errorf(`failed to get public key of %T: %w`, k, err)
   145  		}
   146  		if err := newSet.AddKey(pubKey); err != nil {
   147  			return nil, fmt.Errorf(`failed to add key to public key set: %w`, err)
   148  		}
   149  	}
   150  
   151  	return newSet, nil
   152  }
   153  
   154  // PublicKeyOf returns the corresponding public version of the jwk.Key.
   155  // If `v` is a SymmetricKey, then the same value is returned.
   156  // If `v` is already a public key, the key itself is returned.
   157  //
   158  // If `v` is a private key type that has a `PublicKey()` method, be aware
   159  // that all fields will be copied onto the new public key. It is the caller's
   160  // responsibility to remove any fields, if necessary
   161  //
   162  // If `v` is a raw key, the key is first converted to a `jwk.Key`
   163  func PublicKeyOf(v interface{}) (Key, error) {
   164  	// This should catch all jwk.Key instances
   165  	if pk, ok := v.(PublicKeyer); ok {
   166  		return pk.PublicKey()
   167  	}
   168  
   169  	jk, err := FromRaw(v)
   170  	if err != nil {
   171  		return nil, fmt.Errorf(`failed to convert key into JWK: %w`, err)
   172  	}
   173  
   174  	return jk.PublicKey()
   175  }
   176  
   177  // PublicRawKeyOf returns the corresponding public key of the given
   178  // value `v` (e.g. given *rsa.PrivateKey, *rsa.PublicKey is returned)
   179  // If `v` is already a public key, the key itself is returned.
   180  //
   181  // The returned value will always be a pointer to the public key,
   182  // except when a []byte (e.g. symmetric key, ed25519 key) is passed to `v`.
   183  // In this case, the same []byte value is returned.
   184  func PublicRawKeyOf(v interface{}) (interface{}, error) {
   185  	if pk, ok := v.(PublicKeyer); ok {
   186  		pubk, err := pk.PublicKey()
   187  		if err != nil {
   188  			return nil, fmt.Errorf(`failed to obtain public key from %T: %w`, v, err)
   189  		}
   190  
   191  		var raw interface{}
   192  		if err := pubk.Raw(&raw); err != nil {
   193  			return nil, fmt.Errorf(`failed to obtain raw key from %T: %w`, pubk, err)
   194  		}
   195  		return raw, nil
   196  	}
   197  
   198  	// This may be a silly idea, but if the user gave us a non-pointer value...
   199  	var ptr interface{}
   200  	switch v := v.(type) {
   201  	case rsa.PrivateKey:
   202  		ptr = &v
   203  	case rsa.PublicKey:
   204  		ptr = &v
   205  	case ecdsa.PrivateKey:
   206  		ptr = &v
   207  	case ecdsa.PublicKey:
   208  		ptr = &v
   209  	default:
   210  		ptr = v
   211  	}
   212  
   213  	switch x := ptr.(type) {
   214  	case *rsa.PrivateKey:
   215  		return &x.PublicKey, nil
   216  	case *rsa.PublicKey:
   217  		return x, nil
   218  	case *ecdsa.PrivateKey:
   219  		return &x.PublicKey, nil
   220  	case *ecdsa.PublicKey:
   221  		return x, nil
   222  	case ed25519.PrivateKey:
   223  		return x.Public(), nil
   224  	case ed25519.PublicKey:
   225  		return x, nil
   226  	case x25519.PrivateKey:
   227  		return x.Public(), nil
   228  	case x25519.PublicKey:
   229  		return x, nil
   230  	case []byte:
   231  		return x, nil
   232  	default:
   233  		return nil, fmt.Errorf(`invalid key type passed to PublicKeyOf (%T)`, v)
   234  	}
   235  }
   236  
   237  const (
   238  	pmPrivateKey    = `PRIVATE KEY`
   239  	pmPublicKey     = `PUBLIC KEY`
   240  	pmECPrivateKey  = `EC PRIVATE KEY`
   241  	pmRSAPublicKey  = `RSA PUBLIC KEY`
   242  	pmRSAPrivateKey = `RSA PRIVATE KEY`
   243  )
   244  
   245  // EncodeX509 encodes the key into a byte sequence in ASN.1 DER format
   246  // suitable for to be PEM encoded. The key can be a jwk.Key or a raw key
   247  // instance, but it must be one of the types supported by `x509` package.
   248  //
   249  // This function will try to do the right thing depending on the key type
   250  // (i.e. switch between `x509.MarshalPKCS1PRivateKey` and `x509.MarshalECPrivateKey`),
   251  // but for public keys, it will always use `x509.MarshalPKIXPublicKey`.
   252  // Please manually perform the encoding if you need more fine grained control
   253  //
   254  // The first return value is the name that can be used for `(pem.Block).Type`.
   255  // The second return value is the encoded byte sequence.
   256  func EncodeX509(v interface{}) (string, []byte, error) {
   257  	// we can't import jwk, so just use the interface
   258  	if key, ok := v.(interface{ Raw(interface{}) error }); ok {
   259  		var raw interface{}
   260  		if err := key.Raw(&raw); err != nil {
   261  			return "", nil, fmt.Errorf(`failed to get raw key out of %T: %w`, key, err)
   262  		}
   263  
   264  		v = raw
   265  	}
   266  
   267  	// Try to convert it into a certificate
   268  	switch v := v.(type) {
   269  	case *rsa.PrivateKey:
   270  		return pmRSAPrivateKey, x509.MarshalPKCS1PrivateKey(v), nil
   271  	case *ecdsa.PrivateKey:
   272  		marshaled, err := x509.MarshalECPrivateKey(v)
   273  		if err != nil {
   274  			return "", nil, err
   275  		}
   276  		return pmECPrivateKey, marshaled, nil
   277  	case ed25519.PrivateKey:
   278  		marshaled, err := x509.MarshalPKCS8PrivateKey(v)
   279  		if err != nil {
   280  			return "", nil, err
   281  		}
   282  		return pmPrivateKey, marshaled, nil
   283  	case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
   284  		marshaled, err := x509.MarshalPKIXPublicKey(v)
   285  		if err != nil {
   286  			return "", nil, err
   287  		}
   288  		return pmPublicKey, marshaled, nil
   289  	default:
   290  		return "", nil, fmt.Errorf(`unsupported type %T for ASN.1 DER encoding`, v)
   291  	}
   292  }
   293  
   294  // EncodePEM encodes the key into a PEM encoded ASN.1 DER format.
   295  // The key can be a jwk.Key or a raw key instance, but it must be one of
   296  // the types supported by `x509` package.
   297  //
   298  // Internally, it uses the same routine as `jwk.EncodeX509()`, and therefore
   299  // the same caveats apply
   300  func EncodePEM(v interface{}) ([]byte, error) {
   301  	typ, marshaled, err := EncodeX509(v)
   302  	if err != nil {
   303  		return nil, fmt.Errorf(`failed to encode key in x509: %w`, err)
   304  	}
   305  
   306  	block := &pem.Block{
   307  		Type:  typ,
   308  		Bytes: marshaled,
   309  	}
   310  	return pem.EncodeToMemory(block), nil
   311  }
   312  
   313  // DecodePEM decodes a key in PEM encoded ASN.1 DER format.
   314  // and returns a raw key
   315  func DecodePEM(src []byte) (interface{}, []byte, error) {
   316  	block, rest := pem.Decode(src)
   317  	if block == nil {
   318  		return nil, nil, fmt.Errorf(`failed to decode PEM data`)
   319  	}
   320  
   321  	switch block.Type {
   322  	// Handle the semi-obvious cases
   323  	case pmRSAPrivateKey:
   324  		key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
   325  		if err != nil {
   326  			return nil, nil, fmt.Errorf(`failed to parse PKCS1 private key: %w`, err)
   327  		}
   328  		return key, rest, nil
   329  	case pmRSAPublicKey:
   330  		key, err := x509.ParsePKCS1PublicKey(block.Bytes)
   331  		if err != nil {
   332  			return nil, nil, fmt.Errorf(`failed to parse PKCS1 public key: %w`, err)
   333  		}
   334  		return key, rest, nil
   335  	case pmECPrivateKey:
   336  		key, err := x509.ParseECPrivateKey(block.Bytes)
   337  		if err != nil {
   338  			return nil, nil, fmt.Errorf(`failed to parse EC private key: %w`, err)
   339  		}
   340  		return key, rest, nil
   341  	case pmPublicKey:
   342  		// XXX *could* return dsa.PublicKey
   343  		key, err := x509.ParsePKIXPublicKey(block.Bytes)
   344  		if err != nil {
   345  			return nil, nil, fmt.Errorf(`failed to parse PKIX public key: %w`, err)
   346  		}
   347  		return key, rest, nil
   348  	case pmPrivateKey:
   349  		key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
   350  		if err != nil {
   351  			return nil, nil, fmt.Errorf(`failed to parse PKCS8 private key: %w`, err)
   352  		}
   353  		return key, rest, nil
   354  	case "CERTIFICATE":
   355  		cert, err := x509.ParseCertificate(block.Bytes)
   356  		if err != nil {
   357  			return nil, nil, fmt.Errorf(`failed to parse certificate: %w`, err)
   358  		}
   359  		return cert.PublicKey, rest, nil
   360  	default:
   361  		return nil, nil, fmt.Errorf(`invalid PEM block type %s`, block.Type)
   362  	}
   363  }
   364  
   365  // ParseRawKey is a combination of ParseKey and Raw. It parses a single JWK key,
   366  // and assigns the "raw" key to the given parameter. The key must either be
   367  // a pointer to an empty interface, or a pointer to the actual raw key type
   368  // such as *rsa.PrivateKey, *ecdsa.PublicKey, *[]byte, etc.
   369  func ParseRawKey(data []byte, rawkey interface{}) error {
   370  	key, err := ParseKey(data)
   371  	if err != nil {
   372  		return fmt.Errorf(`failed to parse key: %w`, err)
   373  	}
   374  
   375  	if err := key.Raw(rawkey); err != nil {
   376  		return fmt.Errorf(`failed to assign to raw key variable: %w`, err)
   377  	}
   378  
   379  	return nil
   380  }
   381  
   382  type setDecodeCtx struct {
   383  	json.DecodeCtx
   384  	ignoreParseError bool
   385  }
   386  
   387  func (ctx *setDecodeCtx) IgnoreParseError() bool {
   388  	return ctx.ignoreParseError
   389  }
   390  
   391  // ParseKey parses a single key JWK. Unlike `jwk.Parse` this method will
   392  // report failure if you attempt to pass a JWK set. Only use this function
   393  // when you know that the data is a single JWK.
   394  //
   395  // Given a WithPEM(true) option, this function assumes that the given input
   396  // is PEM encoded ASN.1 DER format key.
   397  //
   398  // Note that a successful parsing of any type of key does NOT necessarily
   399  // guarantee a valid key. For example, no checks against expiration dates
   400  // are performed for certificate expiration, no checks against missing
   401  // parameters are performed, etc.
   402  func ParseKey(data []byte, options ...ParseOption) (Key, error) {
   403  	var parsePEM bool
   404  	var localReg *json.Registry
   405  	for _, option := range options {
   406  		//nolint:forcetypeassert
   407  		switch option.Ident() {
   408  		case identPEM{}:
   409  			parsePEM = option.Value().(bool)
   410  		case identLocalRegistry{}:
   411  			// in reality you can only pass either withLocalRegistry or
   412  			// WithTypedField, but since withLocalRegistry is used only by us,
   413  			// we skip checking
   414  			localReg = option.Value().(*json.Registry)
   415  		case identTypedField{}:
   416  			pair := option.Value().(typedFieldPair)
   417  			if localReg == nil {
   418  				localReg = json.NewRegistry()
   419  			}
   420  			localReg.Register(pair.Name, pair.Value)
   421  		case identIgnoreParseError{}:
   422  			return nil, fmt.Errorf(`jwk.WithIgnoreParseError() cannot be used for ParseKey()`)
   423  		}
   424  	}
   425  
   426  	if parsePEM {
   427  		raw, _, err := DecodePEM(data)
   428  		if err != nil {
   429  			return nil, fmt.Errorf(`failed to parse PEM encoded key: %w`, err)
   430  		}
   431  		return FromRaw(raw)
   432  	}
   433  
   434  	var hint struct {
   435  		Kty string          `json:"kty"`
   436  		D   json.RawMessage `json:"d"`
   437  	}
   438  
   439  	if err := json.Unmarshal(data, &hint); err != nil {
   440  		return nil, fmt.Errorf(`failed to unmarshal JSON into key hint: %w`, err)
   441  	}
   442  
   443  	var key Key
   444  	switch jwa.KeyType(hint.Kty) {
   445  	case jwa.RSA:
   446  		if len(hint.D) > 0 {
   447  			key = newRSAPrivateKey()
   448  		} else {
   449  			key = newRSAPublicKey()
   450  		}
   451  	case jwa.EC:
   452  		if len(hint.D) > 0 {
   453  			key = newECDSAPrivateKey()
   454  		} else {
   455  			key = newECDSAPublicKey()
   456  		}
   457  	case jwa.OctetSeq:
   458  		key = newSymmetricKey()
   459  	case jwa.OKP:
   460  		if len(hint.D) > 0 {
   461  			key = newOKPPrivateKey()
   462  		} else {
   463  			key = newOKPPublicKey()
   464  		}
   465  	default:
   466  		return nil, fmt.Errorf(`invalid key type from JSON (%s)`, hint.Kty)
   467  	}
   468  
   469  	if localReg != nil {
   470  		dcKey, ok := key.(json.DecodeCtxContainer)
   471  		if !ok {
   472  			return nil, fmt.Errorf(`typed field was requested, but the key (%T) does not support DecodeCtx`, key)
   473  		}
   474  		dc := json.NewDecodeCtx(localReg)
   475  		dcKey.SetDecodeCtx(dc)
   476  		defer func() { dcKey.SetDecodeCtx(nil) }()
   477  	}
   478  
   479  	if err := json.Unmarshal(data, key); err != nil {
   480  		return nil, fmt.Errorf(`failed to unmarshal JSON into key (%T): %w`, key, err)
   481  	}
   482  
   483  	return key, nil
   484  }
   485  
   486  // Parse parses JWK from the incoming []byte.
   487  //
   488  // For JWK sets, this is a convenience function. You could just as well
   489  // call `json.Unmarshal` against an empty set created by `jwk.NewSet()`
   490  // to parse a JSON buffer into a `jwk.Set`.
   491  //
   492  // This function exists because many times the user does not know before hand
   493  // if a JWK(s) resource at a remote location contains a single JWK key or
   494  // a JWK set, and `jwk.Parse()` can handle either case, returning a JWK Set
   495  // even if the data only contains a single JWK key
   496  //
   497  // If you are looking for more information on how JWKs are parsed, or if
   498  // you know for sure that you have a single key, please see the documentation
   499  // for `jwk.ParseKey()`.
   500  func Parse(src []byte, options ...ParseOption) (Set, error) {
   501  	var parsePEM bool
   502  	var localReg *json.Registry
   503  	var ignoreParseError bool
   504  	for _, option := range options {
   505  		//nolint:forcetypeassert
   506  		switch option.Ident() {
   507  		case identPEM{}:
   508  			parsePEM = option.Value().(bool)
   509  		case identIgnoreParseError{}:
   510  			ignoreParseError = option.Value().(bool)
   511  		case identTypedField{}:
   512  			pair := option.Value().(typedFieldPair)
   513  			if localReg == nil {
   514  				localReg = json.NewRegistry()
   515  			}
   516  			localReg.Register(pair.Name, pair.Value)
   517  		}
   518  	}
   519  
   520  	s := NewSet()
   521  
   522  	if parsePEM {
   523  		src = bytes.TrimSpace(src)
   524  		for len(src) > 0 {
   525  			raw, rest, err := DecodePEM(src)
   526  			if err != nil {
   527  				return nil, fmt.Errorf(`failed to parse PEM encoded key: %w`, err)
   528  			}
   529  			key, err := FromRaw(raw)
   530  			if err != nil {
   531  				return nil, fmt.Errorf(`failed to create jwk.Key from %T: %w`, raw, err)
   532  			}
   533  			if err := s.AddKey(key); err != nil {
   534  				return nil, fmt.Errorf(`failed to add jwk.Key to set: %w`, err)
   535  			}
   536  			src = bytes.TrimSpace(rest)
   537  		}
   538  		return s, nil
   539  	}
   540  
   541  	if localReg != nil || ignoreParseError {
   542  		dcKs, ok := s.(KeyWithDecodeCtx)
   543  		if !ok {
   544  			return nil, fmt.Errorf(`typed field was requested, but the key set (%T) does not support DecodeCtx`, s)
   545  		}
   546  		dc := &setDecodeCtx{
   547  			DecodeCtx:        json.NewDecodeCtx(localReg),
   548  			ignoreParseError: ignoreParseError,
   549  		}
   550  		dcKs.SetDecodeCtx(dc)
   551  		defer func() { dcKs.SetDecodeCtx(nil) }()
   552  	}
   553  
   554  	if err := json.Unmarshal(src, s); err != nil {
   555  		return nil, fmt.Errorf(`failed to unmarshal JWK set: %w`, err)
   556  	}
   557  
   558  	return s, nil
   559  }
   560  
   561  // ParseReader parses a JWK set from the incoming byte buffer.
   562  func ParseReader(src io.Reader, options ...ParseOption) (Set, error) {
   563  	// meh, there's no way to tell if a stream has "ended" a single
   564  	// JWKs except when we encounter an EOF, so just... ReadAll
   565  	buf, err := io.ReadAll(src)
   566  	if err != nil {
   567  		return nil, fmt.Errorf(`failed to read from io.Reader: %w`, err)
   568  	}
   569  
   570  	return Parse(buf, options...)
   571  }
   572  
   573  // ParseString parses a JWK set from the incoming string.
   574  func ParseString(s string, options ...ParseOption) (Set, error) {
   575  	return Parse([]byte(s), options...)
   576  }
   577  
   578  // AssignKeyID is a convenience function to automatically assign the "kid"
   579  // section of the key, if it already doesn't have one. It uses Key.Thumbprint
   580  // method with crypto.SHA256 as the default hashing algorithm
   581  func AssignKeyID(key Key, options ...AssignKeyIDOption) error {
   582  	if _, ok := key.Get(KeyIDKey); ok {
   583  		return nil
   584  	}
   585  
   586  	hash := crypto.SHA256
   587  	for _, option := range options {
   588  		//nolint:forcetypeassert
   589  		switch option.Ident() {
   590  		case identThumbprintHash{}:
   591  			hash = option.Value().(crypto.Hash)
   592  		}
   593  	}
   594  
   595  	h, err := key.Thumbprint(hash)
   596  	if err != nil {
   597  		return fmt.Errorf(`failed to generate thumbprint: %w`, err)
   598  	}
   599  
   600  	if err := key.Set(KeyIDKey, base64.EncodeToString(h)); err != nil {
   601  		return fmt.Errorf(`failed to set "kid": %w`, err)
   602  	}
   603  
   604  	return nil
   605  }
   606  
   607  func cloneKey(src Key) (Key, error) {
   608  	var dst Key
   609  	switch src.(type) {
   610  	case RSAPrivateKey:
   611  		dst = newRSAPrivateKey()
   612  	case RSAPublicKey:
   613  		dst = newRSAPublicKey()
   614  	case ECDSAPrivateKey:
   615  		dst = newECDSAPrivateKey()
   616  	case ECDSAPublicKey:
   617  		dst = newECDSAPublicKey()
   618  	case OKPPrivateKey:
   619  		dst = newOKPPrivateKey()
   620  	case OKPPublicKey:
   621  		dst = newOKPPublicKey()
   622  	case SymmetricKey:
   623  		dst = newSymmetricKey()
   624  	default:
   625  		return nil, fmt.Errorf(`unknown key type %T`, src)
   626  	}
   627  
   628  	for _, pair := range src.makePairs() {
   629  		//nolint:forcetypeassert
   630  		key := pair.Key.(string)
   631  		if err := dst.Set(key, pair.Value); err != nil {
   632  			return nil, fmt.Errorf(`failed to set %q: %w`, key, err)
   633  		}
   634  	}
   635  	return dst, nil
   636  }
   637  
   638  // Pem serializes the given jwk.Key in PEM encoded ASN.1 DER format,
   639  // using either PKCS8 for private keys and PKIX for public keys.
   640  // If you need to encode using PKCS1 or SEC1, you must do it yourself.
   641  //
   642  // # Argument must be of type jwk.Key or jwk.Set
   643  //
   644  // Currently only EC (including Ed25519) and RSA keys (and jwk.Set
   645  // comprised of these key types) are supported.
   646  func Pem(v interface{}) ([]byte, error) {
   647  	var set Set
   648  	switch v := v.(type) {
   649  	case Key:
   650  		set = NewSet()
   651  		if err := set.AddKey(v); err != nil {
   652  			return nil, fmt.Errorf(`failed to add key to set: %w`, err)
   653  		}
   654  	case Set:
   655  		set = v
   656  	default:
   657  		return nil, fmt.Errorf(`argument to Pem must be either jwk.Key or jwk.Set: %T`, v)
   658  	}
   659  
   660  	var ret []byte
   661  	for i := 0; i < set.Len(); i++ {
   662  		key, _ := set.Key(i)
   663  		typ, buf, err := asnEncode(key)
   664  		if err != nil {
   665  			return nil, fmt.Errorf(`failed to encode content for key #%d: %w`, i, err)
   666  		}
   667  
   668  		var block pem.Block
   669  		block.Type = typ
   670  		block.Bytes = buf
   671  		ret = append(ret, pem.EncodeToMemory(&block)...)
   672  	}
   673  	return ret, nil
   674  }
   675  
   676  func asnEncode(key Key) (string, []byte, error) {
   677  	switch key := key.(type) {
   678  	case RSAPrivateKey, ECDSAPrivateKey, OKPPrivateKey:
   679  		var rawkey interface{}
   680  		if err := key.Raw(&rawkey); err != nil {
   681  			return "", nil, fmt.Errorf(`failed to get raw key from jwk.Key: %w`, err)
   682  		}
   683  		buf, err := x509.MarshalPKCS8PrivateKey(rawkey)
   684  		if err != nil {
   685  			return "", nil, fmt.Errorf(`failed to marshal PKCS8: %w`, err)
   686  		}
   687  		return pmPrivateKey, buf, nil
   688  	case RSAPublicKey, ECDSAPublicKey, OKPPublicKey:
   689  		var rawkey interface{}
   690  		if err := key.Raw(&rawkey); err != nil {
   691  			return "", nil, fmt.Errorf(`failed to get raw key from jwk.Key: %w`, err)
   692  		}
   693  		buf, err := x509.MarshalPKIXPublicKey(rawkey)
   694  		if err != nil {
   695  			return "", nil, fmt.Errorf(`failed to marshal PKIX: %w`, err)
   696  		}
   697  		return pmPublicKey, buf, nil
   698  	default:
   699  		return "", nil, fmt.Errorf(`unsupported key type %T`, key)
   700  	}
   701  }
   702  
   703  // RegisterCustomField allows users to specify that a private field
   704  // be decoded as an instance of the specified type. This option has
   705  // a global effect.
   706  //
   707  // For example, suppose you have a custom field `x-birthday`, which
   708  // you want to represent as a string formatted in RFC3339 in JSON,
   709  // but want it back as `time.Time`.
   710  //
   711  // In that case you would register a custom field as follows
   712  //
   713  //	jwk.RegisterCustomField(`x-birthday`, timeT)
   714  //
   715  // Then `key.Get("x-birthday")` will still return an `interface{}`,
   716  // but you can convert its type to `time.Time`
   717  //
   718  //	bdayif, _ := key.Get(`x-birthday`)
   719  //	bday := bdayif.(time.Time)
   720  func RegisterCustomField(name string, object interface{}) {
   721  	registry.Register(name, object)
   722  }
   723  
   724  func AvailableCurves() []elliptic.Curve {
   725  	return ecutil.AvailableCurves()
   726  }
   727  
   728  func CurveForAlgorithm(alg jwa.EllipticCurveAlgorithm) (elliptic.Curve, bool) {
   729  	return ecutil.CurveForAlgorithm(alg)
   730  }
   731  
   732  // Equal compares two keys and returns true if they are equal. The comparison
   733  // is solely done against the thumbprints of k1 and k2. It is possible for keys
   734  // that have, for example, different key IDs, key usage, etc, to be considered equal.
   735  func Equal(k1, k2 Key) bool {
   736  	h := crypto.SHA256
   737  	tp1, err := k1.Thumbprint(h)
   738  	if err != nil {
   739  		return false // can't report error
   740  	}
   741  	tp2, err := k2.Thumbprint(h)
   742  	if err != nil {
   743  		return false // can't report error
   744  	}
   745  
   746  	return bytes.Equal(tp1, tp2)
   747  }
   748  
   749  // IsPrivateKey returns true if the supplied key is a private key of an
   750  // asymmetric key pair. The argument `k` must implement the `AsymmetricKey`
   751  // interface.
   752  //
   753  // An error is returned if the supplied key is not an `AsymmetricKey`.
   754  func IsPrivateKey(k Key) (bool, error) {
   755  	asymmetric, ok := k.(AsymmetricKey)
   756  	if ok {
   757  		return asymmetric.IsPrivate(), nil
   758  	}
   759  	return false, fmt.Errorf("jwk.IsPrivateKey: %T is not an asymmetric key", k)
   760  }
   761  
   762  type keyValidationError struct {
   763  	err error
   764  }
   765  
   766  func (e *keyValidationError) Error() string {
   767  	return fmt.Sprintf(`key validation failed: %s`, e.err)
   768  }
   769  
   770  func (e *keyValidationError) Unwrap() error {
   771  	return e.err
   772  }
   773  
   774  func (e *keyValidationError) Is(target error) bool {
   775  	_, ok := target.(*keyValidationError)
   776  	return ok
   777  }
   778  
   779  // NewKeyValidationError wraps the given error with an error that denotes
   780  // `key.Validate()` has failed. This error type should ONLY be used as
   781  // return value from the `Validate()` method.
   782  func NewKeyValidationError(err error) error {
   783  	return &keyValidationError{err: err}
   784  }
   785  
   786  func IsKeyValidationError(err error) bool {
   787  	var kve keyValidationError
   788  	return errors.Is(err, &kve)
   789  }