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 }