jwk.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. //go:generate ./gen.sh
  2. // Package jwk implements JWK as described in https://tools.ietf.org/html/rfc7517
  3. package jwk
  4. import (
  5. "bytes"
  6. "context"
  7. "crypto"
  8. "crypto/ecdsa"
  9. "crypto/ed25519"
  10. "crypto/rsa"
  11. "crypto/x509"
  12. "encoding/pem"
  13. "io"
  14. "io/ioutil"
  15. "math/big"
  16. "net/http"
  17. "github.com/lestrrat-go/backoff/v2"
  18. "github.com/lestrrat-go/jwx/internal/base64"
  19. "github.com/lestrrat-go/jwx/internal/json"
  20. "github.com/lestrrat-go/jwx/jwa"
  21. "github.com/lestrrat-go/jwx/x25519"
  22. "github.com/pkg/errors"
  23. )
  24. var registry = json.NewRegistry()
  25. func bigIntToBytes(n *big.Int) ([]byte, error) {
  26. if n == nil {
  27. return nil, errors.New(`invalid *big.Int value`)
  28. }
  29. return n.Bytes(), nil
  30. }
  31. // New creates a jwk.Key from the given key (RSA/ECDSA/symmetric keys).
  32. //
  33. // The constructor auto-detects the type of key to be instantiated
  34. // based on the input type:
  35. //
  36. // * "crypto/rsa".PrivateKey and "crypto/rsa".PublicKey creates an RSA based key
  37. // * "crypto/ecdsa".PrivateKey and "crypto/ecdsa".PublicKey creates an EC based key
  38. // * "crypto/ed25519".PrivateKey and "crypto/ed25519".PublicKey creates an OKP based key
  39. // * []byte creates a symmetric key
  40. func New(key interface{}) (Key, error) {
  41. if key == nil {
  42. return nil, errors.New(`jwk.New requires a non-nil key`)
  43. }
  44. var ptr interface{}
  45. switch v := key.(type) {
  46. case rsa.PrivateKey:
  47. ptr = &v
  48. case rsa.PublicKey:
  49. ptr = &v
  50. case ecdsa.PrivateKey:
  51. ptr = &v
  52. case ecdsa.PublicKey:
  53. ptr = &v
  54. default:
  55. ptr = v
  56. }
  57. switch rawKey := ptr.(type) {
  58. case *rsa.PrivateKey:
  59. k := NewRSAPrivateKey()
  60. if err := k.FromRaw(rawKey); err != nil {
  61. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  62. }
  63. return k, nil
  64. case *rsa.PublicKey:
  65. k := NewRSAPublicKey()
  66. if err := k.FromRaw(rawKey); err != nil {
  67. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  68. }
  69. return k, nil
  70. case *ecdsa.PrivateKey:
  71. k := NewECDSAPrivateKey()
  72. if err := k.FromRaw(rawKey); err != nil {
  73. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  74. }
  75. return k, nil
  76. case *ecdsa.PublicKey:
  77. k := NewECDSAPublicKey()
  78. if err := k.FromRaw(rawKey); err != nil {
  79. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  80. }
  81. return k, nil
  82. case ed25519.PrivateKey:
  83. k := NewOKPPrivateKey()
  84. if err := k.FromRaw(rawKey); err != nil {
  85. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  86. }
  87. return k, nil
  88. case ed25519.PublicKey:
  89. k := NewOKPPublicKey()
  90. if err := k.FromRaw(rawKey); err != nil {
  91. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  92. }
  93. return k, nil
  94. case x25519.PrivateKey:
  95. k := NewOKPPrivateKey()
  96. if err := k.FromRaw(rawKey); err != nil {
  97. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  98. }
  99. return k, nil
  100. case x25519.PublicKey:
  101. k := NewOKPPublicKey()
  102. if err := k.FromRaw(rawKey); err != nil {
  103. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  104. }
  105. return k, nil
  106. case []byte:
  107. k := NewSymmetricKey()
  108. if err := k.FromRaw(rawKey); err != nil {
  109. return nil, errors.Wrapf(err, `failed to initialize %T from %T`, k, rawKey)
  110. }
  111. return k, nil
  112. default:
  113. return nil, errors.Errorf(`invalid key type '%T' for jwk.New`, key)
  114. }
  115. }
  116. // PublicSetOf returns a new jwk.Set consisting of
  117. // public keys of the keys contained in the set.
  118. //
  119. // This is useful when you are generating a set of private keys, and
  120. // you want to generate the corresponding public versions for the
  121. // users to verify with.
  122. //
  123. // Be aware that all fields will be copied onto the new public key. It is the caller's
  124. // responsibility to remove any fields, if necessary.
  125. func PublicSetOf(v Set) (Set, error) {
  126. newSet := NewSet()
  127. n := v.Len()
  128. for i := 0; i < n; i++ {
  129. k, ok := v.Get(i)
  130. if !ok {
  131. return nil, errors.New("key not found")
  132. }
  133. pubKey, err := PublicKeyOf(k)
  134. if err != nil {
  135. return nil, errors.Wrapf(err, `failed to get public key of %T`, k)
  136. }
  137. newSet.Add(pubKey)
  138. }
  139. return newSet, nil
  140. }
  141. // PublicKeyOf returns the corresponding public version of the jwk.Key.
  142. // If `v` is a SymmetricKey, then the same value is returned.
  143. // If `v` is already a public key, the key itself is returned.
  144. //
  145. // If `v` is a private key type that has a `PublicKey()` method, be aware
  146. // that all fields will be copied onto the new public key. It is the caller's
  147. // responsibility to remove any fields, if necessary
  148. //
  149. // If `v` is a raw key, the key is first converted to a `jwk.Key`
  150. func PublicKeyOf(v interface{}) (Key, error) {
  151. if pk, ok := v.(PublicKeyer); ok {
  152. return pk.PublicKey()
  153. }
  154. jk, err := New(v)
  155. if err != nil {
  156. return nil, errors.Wrapf(err, `failed to convert key into JWK`)
  157. }
  158. return jk.PublicKey()
  159. }
  160. // PublicRawKeyOf returns the corresponding public key of the given
  161. // value `v` (e.g. given *rsa.PrivateKey, *rsa.PublicKey is returned)
  162. // If `v` is already a public key, the key itself is returned.
  163. //
  164. // The returned value will always be a pointer to the public key,
  165. // except when a []byte (e.g. symmetric key, ed25519 key) is passed to `v`.
  166. // In this case, the same []byte value is returned.
  167. func PublicRawKeyOf(v interface{}) (interface{}, error) {
  168. if pk, ok := v.(PublicKeyer); ok {
  169. pubk, err := pk.PublicKey()
  170. if err != nil {
  171. return nil, errors.Wrapf(err, `failed to obtain public key from %T`, v)
  172. }
  173. var raw interface{}
  174. if err := pubk.Raw(&raw); err != nil {
  175. return nil, errors.Wrapf(err, `failed to obtain raw key from %T`, pubk)
  176. }
  177. return raw, nil
  178. }
  179. // This may be a silly idea, but if the user gave us a non-pointer value...
  180. var ptr interface{}
  181. switch v := v.(type) {
  182. case rsa.PrivateKey:
  183. ptr = &v
  184. case rsa.PublicKey:
  185. ptr = &v
  186. case ecdsa.PrivateKey:
  187. ptr = &v
  188. case ecdsa.PublicKey:
  189. ptr = &v
  190. default:
  191. ptr = v
  192. }
  193. switch x := ptr.(type) {
  194. case *rsa.PrivateKey:
  195. return &x.PublicKey, nil
  196. case *rsa.PublicKey:
  197. return x, nil
  198. case *ecdsa.PrivateKey:
  199. return &x.PublicKey, nil
  200. case *ecdsa.PublicKey:
  201. return x, nil
  202. case ed25519.PrivateKey:
  203. return x.Public(), nil
  204. case ed25519.PublicKey:
  205. return x, nil
  206. case x25519.PrivateKey:
  207. return x.Public(), nil
  208. case x25519.PublicKey:
  209. return x, nil
  210. case []byte:
  211. return x, nil
  212. default:
  213. return nil, errors.Errorf(`invalid key type passed to PublicKeyOf (%T)`, v)
  214. }
  215. }
  216. // Fetch fetches a JWK resource specified by a URL. The url must be
  217. // pointing to a resource that is supported by `net/http`.
  218. //
  219. // If you are using the same `jwk.Set` for long periods of time during
  220. // the lifecycle of your program, and would like to periodically refresh the
  221. // contents of the object with the data at the remote resource,
  222. // consider using `jwk.AutoRefresh`, which automatically refreshes
  223. // jwk.Set objects asynchronously.
  224. //
  225. // See the list of `jwk.FetchOption`s for various options to tweak the
  226. // behavior, including providing alternate HTTP Clients, setting a backoff,
  227. // and using whitelists.
  228. func Fetch(ctx context.Context, urlstring string, options ...FetchOption) (Set, error) {
  229. res, err := fetch(ctx, urlstring, options...)
  230. if err != nil {
  231. return nil, err
  232. }
  233. defer res.Body.Close()
  234. keyset, err := ParseReader(res.Body)
  235. if err != nil {
  236. return nil, errors.Wrap(err, `failed to parse JWK set`)
  237. }
  238. return keyset, nil
  239. }
  240. func fetch(ctx context.Context, urlstring string, options ...FetchOption) (*http.Response, error) {
  241. var wl Whitelist
  242. var httpcl HTTPClient = http.DefaultClient
  243. bo := backoff.Null()
  244. for _, option := range options {
  245. //nolint:forcetypeassert
  246. switch option.Ident() {
  247. case identHTTPClient{}:
  248. httpcl = option.Value().(HTTPClient)
  249. case identFetchBackoff{}:
  250. bo = option.Value().(backoff.Policy)
  251. case identFetchWhitelist{}:
  252. wl = option.Value().(Whitelist)
  253. }
  254. }
  255. if wl != nil {
  256. if !wl.IsAllowed(urlstring) {
  257. return nil, errors.New(`url rejected by whitelist`)
  258. }
  259. }
  260. req, err := http.NewRequestWithContext(ctx, http.MethodGet, urlstring, nil)
  261. if err != nil {
  262. return nil, errors.Wrap(err, "failed to new request to remote JWK")
  263. }
  264. b := bo.Start(ctx)
  265. var lastError error
  266. for backoff.Continue(b) {
  267. res, err := httpcl.Do(req)
  268. if err != nil {
  269. lastError = errors.Wrap(err, "failed to fetch remote JWK")
  270. continue
  271. }
  272. if res.StatusCode != http.StatusOK {
  273. lastError = errors.Errorf("failed to fetch remote JWK (status = %d)", res.StatusCode)
  274. continue
  275. }
  276. return res, nil
  277. }
  278. // It's possible for us to get here without populating lastError.
  279. // e.g. what if we bailed out of `for backoff.Contineu(b)` without making
  280. // a single request? or, <-ctx.Done() returned?
  281. if lastError == nil {
  282. lastError = errors.New(`fetching remote JWK did not complete`)
  283. }
  284. return nil, lastError
  285. }
  286. // ParseRawKey is a combination of ParseKey and Raw. It parses a single JWK key,
  287. // and assigns the "raw" key to the given parameter. The key must either be
  288. // a pointer to an empty interface, or a pointer to the actual raw key type
  289. // such as *rsa.PrivateKey, *ecdsa.PublicKey, *[]byte, etc.
  290. func ParseRawKey(data []byte, rawkey interface{}) error {
  291. key, err := ParseKey(data)
  292. if err != nil {
  293. return errors.Wrap(err, `failed to parse key`)
  294. }
  295. if err := key.Raw(rawkey); err != nil {
  296. return errors.Wrap(err, `failed to assign to raw key variable`)
  297. }
  298. return nil
  299. }
  300. // parsePEMEncodedRawKey parses a key in PEM encoded ASN.1 DER format. It tires its
  301. // best to determine the key type, but when it just can't, it will return
  302. // an error
  303. func parsePEMEncodedRawKey(src []byte) (interface{}, []byte, error) {
  304. block, rest := pem.Decode(src)
  305. if block == nil {
  306. return nil, nil, errors.New(`failed to decode PEM data`)
  307. }
  308. switch block.Type {
  309. // Handle the semi-obvious cases
  310. case "RSA PRIVATE KEY":
  311. key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
  312. if err != nil {
  313. return nil, nil, errors.Wrap(err, `failed to parse PKCS1 private key`)
  314. }
  315. return key, rest, nil
  316. case "RSA PUBLIC KEY":
  317. key, err := x509.ParsePKCS1PublicKey(block.Bytes)
  318. if err != nil {
  319. return nil, nil, errors.Wrap(err, `failed to parse PKCS1 public key`)
  320. }
  321. return key, rest, nil
  322. case "EC PRIVATE KEY":
  323. key, err := x509.ParseECPrivateKey(block.Bytes)
  324. if err != nil {
  325. return nil, nil, errors.Wrap(err, `failed to parse EC private key`)
  326. }
  327. return key, rest, nil
  328. case "PUBLIC KEY":
  329. // XXX *could* return dsa.PublicKey
  330. key, err := x509.ParsePKIXPublicKey(block.Bytes)
  331. if err != nil {
  332. return nil, nil, errors.Wrap(err, `failed to parse PKIX public key`)
  333. }
  334. return key, rest, nil
  335. case "PRIVATE KEY":
  336. key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
  337. if err != nil {
  338. return nil, nil, errors.Wrap(err, `failed to parse PKCS8 private key`)
  339. }
  340. return key, rest, nil
  341. case "CERTIFICATE":
  342. cert, err := x509.ParseCertificate(block.Bytes)
  343. if err != nil {
  344. return nil, nil, errors.Wrap(err, `failed to parse certificate`)
  345. }
  346. return cert.PublicKey, rest, nil
  347. default:
  348. return nil, nil, errors.Errorf(`invalid PEM block type %s`, block.Type)
  349. }
  350. }
  351. type setDecodeCtx struct {
  352. json.DecodeCtx
  353. ignoreParseError bool
  354. }
  355. func (ctx *setDecodeCtx) IgnoreParseError() bool {
  356. return ctx.ignoreParseError
  357. }
  358. // ParseKey parses a single key JWK. Unlike `jwk.Parse` this method will
  359. // report failure if you attempt to pass a JWK set. Only use this function
  360. // when you know that the data is a single JWK.
  361. //
  362. // Given a WithPEM(true) option, this function assumes that the given input
  363. // is PEM encoded ASN.1 DER format key.
  364. //
  365. // Note that a successful parsing of any type of key does NOT necessarily
  366. // guarantee a valid key. For example, no checks against expiration dates
  367. // are performed for certificate expiration, no checks against missing
  368. // parameters are performed, etc.
  369. func ParseKey(data []byte, options ...ParseOption) (Key, error) {
  370. var parsePEM bool
  371. var localReg *json.Registry
  372. for _, option := range options {
  373. //nolint:forcetypeassert
  374. switch option.Ident() {
  375. case identPEM{}:
  376. parsePEM = option.Value().(bool)
  377. case identLocalRegistry{}:
  378. // in reality you can only pass either withLocalRegistry or
  379. // WithTypedField, but since withLocalRegistry is used only by us,
  380. // we skip checking
  381. localReg = option.Value().(*json.Registry)
  382. case identTypedField{}:
  383. pair := option.Value().(typedFieldPair)
  384. if localReg == nil {
  385. localReg = json.NewRegistry()
  386. }
  387. localReg.Register(pair.Name, pair.Value)
  388. case identIgnoreParseError{}:
  389. return nil, errors.Errorf(`jwk.WithIgnoreParseError() cannot be used for ParseKey()`)
  390. }
  391. }
  392. if parsePEM {
  393. raw, _, err := parsePEMEncodedRawKey(data)
  394. if err != nil {
  395. return nil, errors.Wrap(err, `failed to parse PEM encoded key`)
  396. }
  397. return New(raw)
  398. }
  399. var hint struct {
  400. Kty string `json:"kty"`
  401. D json.RawMessage `json:"d"`
  402. }
  403. if err := json.Unmarshal(data, &hint); err != nil {
  404. return nil, errors.Wrap(err, `failed to unmarshal JSON into key hint`)
  405. }
  406. var key Key
  407. switch jwa.KeyType(hint.Kty) {
  408. case jwa.RSA:
  409. if len(hint.D) > 0 {
  410. key = newRSAPrivateKey()
  411. } else {
  412. key = newRSAPublicKey()
  413. }
  414. case jwa.EC:
  415. if len(hint.D) > 0 {
  416. key = newECDSAPrivateKey()
  417. } else {
  418. key = newECDSAPublicKey()
  419. }
  420. case jwa.OctetSeq:
  421. key = newSymmetricKey()
  422. case jwa.OKP:
  423. if len(hint.D) > 0 {
  424. key = newOKPPrivateKey()
  425. } else {
  426. key = newOKPPublicKey()
  427. }
  428. default:
  429. return nil, errors.Errorf(`invalid key type from JSON (%s)`, hint.Kty)
  430. }
  431. if localReg != nil {
  432. dcKey, ok := key.(json.DecodeCtxContainer)
  433. if !ok {
  434. return nil, errors.Errorf(`typed field was requested, but the key (%T) does not support DecodeCtx`, key)
  435. }
  436. dc := json.NewDecodeCtx(localReg)
  437. dcKey.SetDecodeCtx(dc)
  438. defer func() { dcKey.SetDecodeCtx(nil) }()
  439. }
  440. if err := json.Unmarshal(data, key); err != nil {
  441. return nil, errors.Wrapf(err, `failed to unmarshal JSON into key (%T)`, key)
  442. }
  443. return key, nil
  444. }
  445. // Parse parses JWK from the incoming []byte.
  446. //
  447. // For JWK sets, this is a convenience function. You could just as well
  448. // call `json.Unmarshal` against an empty set created by `jwk.NewSet()`
  449. // to parse a JSON buffer into a `jwk.Set`.
  450. //
  451. // This function exists because many times the user does not know before hand
  452. // if a JWK(s) resource at a remote location contains a single JWK key or
  453. // a JWK set, and `jwk.Parse()` can handle either case, returning a JWK Set
  454. // even if the data only contains a single JWK key
  455. //
  456. // If you are looking for more information on how JWKs are parsed, or if
  457. // you know for sure that you have a single key, please see the documentation
  458. // for `jwk.ParseKey()`.
  459. func Parse(src []byte, options ...ParseOption) (Set, error) {
  460. var parsePEM bool
  461. var localReg *json.Registry
  462. var ignoreParseError bool
  463. for _, option := range options {
  464. //nolint:forcetypeassert
  465. switch option.Ident() {
  466. case identPEM{}:
  467. parsePEM = option.Value().(bool)
  468. case identIgnoreParseError{}:
  469. ignoreParseError = option.Value().(bool)
  470. case identTypedField{}:
  471. pair := option.Value().(typedFieldPair)
  472. if localReg == nil {
  473. localReg = json.NewRegistry()
  474. }
  475. localReg.Register(pair.Name, pair.Value)
  476. }
  477. }
  478. s := NewSet()
  479. if parsePEM {
  480. src = bytes.TrimSpace(src)
  481. for len(src) > 0 {
  482. raw, rest, err := parsePEMEncodedRawKey(src)
  483. if err != nil {
  484. return nil, errors.Wrap(err, `failed to parse PEM encoded key`)
  485. }
  486. key, err := New(raw)
  487. if err != nil {
  488. return nil, errors.Wrapf(err, `failed to create jwk.Key from %T`, raw)
  489. }
  490. s.Add(key)
  491. src = bytes.TrimSpace(rest)
  492. }
  493. return s, nil
  494. }
  495. if localReg != nil || ignoreParseError {
  496. dcKs, ok := s.(KeyWithDecodeCtx)
  497. if !ok {
  498. return nil, errors.Errorf(`typed field was requested, but the key set (%T) does not support DecodeCtx`, s)
  499. }
  500. dc := &setDecodeCtx{
  501. DecodeCtx: json.NewDecodeCtx(localReg),
  502. ignoreParseError: ignoreParseError,
  503. }
  504. dcKs.SetDecodeCtx(dc)
  505. defer func() { dcKs.SetDecodeCtx(nil) }()
  506. }
  507. if err := json.Unmarshal(src, s); err != nil {
  508. return nil, errors.Wrap(err, "failed to unmarshal JWK set")
  509. }
  510. return s, nil
  511. }
  512. // ParseReader parses a JWK set from the incoming byte buffer.
  513. func ParseReader(src io.Reader, options ...ParseOption) (Set, error) {
  514. // meh, there's no way to tell if a stream has "ended" a single
  515. // JWKs except when we encounter an EOF, so just... ReadAll
  516. buf, err := ioutil.ReadAll(src)
  517. if err != nil {
  518. return nil, errors.Wrap(err, `failed to read from io.Reader`)
  519. }
  520. return Parse(buf, options...)
  521. }
  522. // ParseString parses a JWK set from the incoming string.
  523. func ParseString(s string, options ...ParseOption) (Set, error) {
  524. return Parse([]byte(s), options...)
  525. }
  526. // AssignKeyID is a convenience function to automatically assign the "kid"
  527. // section of the key, if it already doesn't have one. It uses Key.Thumbprint
  528. // method with crypto.SHA256 as the default hashing algorithm
  529. func AssignKeyID(key Key, options ...Option) error {
  530. if _, ok := key.Get(KeyIDKey); ok {
  531. return nil
  532. }
  533. hash := crypto.SHA256
  534. for _, option := range options {
  535. //nolint:forcetypeassert
  536. switch option.Ident() {
  537. case identThumbprintHash{}:
  538. hash = option.Value().(crypto.Hash)
  539. }
  540. }
  541. h, err := key.Thumbprint(hash)
  542. if err != nil {
  543. return errors.Wrap(err, `failed to generate thumbprint`)
  544. }
  545. if err := key.Set(KeyIDKey, base64.EncodeToString(h)); err != nil {
  546. return errors.Wrap(err, `failed to set "kid"`)
  547. }
  548. return nil
  549. }
  550. func cloneKey(src Key) (Key, error) {
  551. var dst Key
  552. switch src.(type) {
  553. case RSAPrivateKey:
  554. dst = NewRSAPrivateKey()
  555. case RSAPublicKey:
  556. dst = NewRSAPublicKey()
  557. case ECDSAPrivateKey:
  558. dst = NewECDSAPrivateKey()
  559. case ECDSAPublicKey:
  560. dst = NewECDSAPublicKey()
  561. case OKPPrivateKey:
  562. dst = NewOKPPrivateKey()
  563. case OKPPublicKey:
  564. dst = NewOKPPublicKey()
  565. case SymmetricKey:
  566. dst = NewSymmetricKey()
  567. default:
  568. return nil, errors.Errorf(`unknown key type %T`, src)
  569. }
  570. for _, pair := range src.makePairs() {
  571. //nolint:forcetypeassert
  572. key := pair.Key.(string)
  573. if err := dst.Set(key, pair.Value); err != nil {
  574. return nil, errors.Wrapf(err, `failed to set %q`, key)
  575. }
  576. }
  577. return dst, nil
  578. }
  579. // Pem serializes the given jwk.Key in PEM encoded ASN.1 DER format,
  580. // using either PKCS8 for private keys and PKIX for public keys.
  581. // If you need to encode using PKCS1 or SEC1, you must do it yourself.
  582. //
  583. // Argument must be of type jwk.Key or jwk.Set
  584. //
  585. // Currently only EC (including Ed25519) and RSA keys (and jwk.Set
  586. // comprised of these key types) are supported.
  587. func Pem(v interface{}) ([]byte, error) {
  588. var set Set
  589. switch v := v.(type) {
  590. case Key:
  591. set = NewSet()
  592. set.Add(v)
  593. case Set:
  594. set = v
  595. default:
  596. return nil, errors.Errorf(`argument to Pem must be either jwk.Key or jwk.Set: %T`, v)
  597. }
  598. var ret []byte
  599. for i := 0; i < set.Len(); i++ {
  600. key, _ := set.Get(i)
  601. typ, buf, err := asnEncode(key)
  602. if err != nil {
  603. return nil, errors.Wrapf(err, `failed to encode content for key #%d`, i)
  604. }
  605. var block pem.Block
  606. block.Type = typ
  607. block.Bytes = buf
  608. ret = append(ret, pem.EncodeToMemory(&block)...)
  609. }
  610. return ret, nil
  611. }
  612. func asnEncode(key Key) (string, []byte, error) {
  613. switch key := key.(type) {
  614. case RSAPrivateKey, ECDSAPrivateKey, OKPPrivateKey:
  615. var rawkey interface{}
  616. if err := key.Raw(&rawkey); err != nil {
  617. return "", nil, errors.Wrap(err, `failed to get raw key from jwk.Key`)
  618. }
  619. buf, err := x509.MarshalPKCS8PrivateKey(rawkey)
  620. if err != nil {
  621. return "", nil, errors.Wrap(err, `failed to marshal PKCS8`)
  622. }
  623. return "PRIVATE KEY", buf, nil
  624. case RSAPublicKey, ECDSAPublicKey, OKPPublicKey:
  625. var rawkey interface{}
  626. if err := key.Raw(&rawkey); err != nil {
  627. return "", nil, errors.Wrap(err, `failed to get raw key from jwk.Key`)
  628. }
  629. buf, err := x509.MarshalPKIXPublicKey(rawkey)
  630. if err != nil {
  631. return "", nil, errors.Wrap(err, `failed to marshal PKIX`)
  632. }
  633. return "PUBLIC KEY", buf, nil
  634. default:
  635. return "", nil, errors.Errorf(`unsupported key type %T`, key)
  636. }
  637. }
  638. // RegisterCustomField allows users to specify that a private field
  639. // be decoded as an instance of the specified type. This option has
  640. // a global effect.
  641. //
  642. // For example, suppose you have a custom field `x-birthday`, which
  643. // you want to represent as a string formatted in RFC3339 in JSON,
  644. // but want it back as `time.Time`.
  645. //
  646. // In that case you would register a custom field as follows
  647. //
  648. // jwk.RegisterCustomField(`x-birthday`, timeT)
  649. //
  650. // Then `key.Get("x-birthday")` will still return an `interface{}`,
  651. // but you can convert its type to `time.Time`
  652. //
  653. // bdayif, _ := key.Get(`x-birthday`)
  654. // bday := bdayif.(time.Time)
  655. //
  656. func RegisterCustomField(name string, object interface{}) {
  657. registry.Register(name, object)
  658. }