jws.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. //go:generate ./gen.sh
  2. // Package jws implements the digital signature on JSON based data
  3. // structures as described in https://tools.ietf.org/html/rfc7515
  4. //
  5. // If you do not care about the details, the only things that you
  6. // would need to use are the following functions:
  7. //
  8. // jws.Sign(payload, algorithm, key)
  9. // jws.Verify(encodedjws, algorithm, key)
  10. //
  11. // To sign, simply use `jws.Sign`. `payload` is a []byte buffer that
  12. // contains whatever data you want to sign. `alg` is one of the
  13. // jwa.SignatureAlgorithm constants from package jwa. For RSA and
  14. // ECDSA family of algorithms, you will need to prepare a private key.
  15. // For HMAC family, you just need a []byte value. The `jws.Sign`
  16. // function will return the encoded JWS message on success.
  17. //
  18. // To verify, use `jws.Verify`. It will parse the `encodedjws` buffer
  19. // and verify the result using `algorithm` and `key`. Upon successful
  20. // verification, the original payload is returned, so you can work on it.
  21. package jws
  22. import (
  23. "bufio"
  24. "bytes"
  25. "context"
  26. "crypto/ecdsa"
  27. "crypto/ed25519"
  28. "crypto/rsa"
  29. "fmt"
  30. "io"
  31. "io/ioutil"
  32. "net/http"
  33. "net/url"
  34. "reflect"
  35. "strings"
  36. "sync"
  37. "unicode"
  38. "unicode/utf8"
  39. "github.com/lestrrat-go/backoff/v2"
  40. "github.com/lestrrat-go/jwx/internal/base64"
  41. "github.com/lestrrat-go/jwx/internal/json"
  42. "github.com/lestrrat-go/jwx/internal/pool"
  43. "github.com/lestrrat-go/jwx/jwa"
  44. "github.com/lestrrat-go/jwx/jwk"
  45. "github.com/lestrrat-go/jwx/x25519"
  46. "github.com/pkg/errors"
  47. )
  48. var registry = json.NewRegistry()
  49. type payloadSigner struct {
  50. signer Signer
  51. key interface{}
  52. protected Headers
  53. public Headers
  54. }
  55. func (s *payloadSigner) Sign(payload []byte) ([]byte, error) {
  56. return s.signer.Sign(payload, s.key)
  57. }
  58. func (s *payloadSigner) Algorithm() jwa.SignatureAlgorithm {
  59. return s.signer.Algorithm()
  60. }
  61. func (s *payloadSigner) ProtectedHeader() Headers {
  62. return s.protected
  63. }
  64. func (s *payloadSigner) PublicHeader() Headers {
  65. return s.public
  66. }
  67. var signers = make(map[jwa.SignatureAlgorithm]Signer)
  68. var muSigner = &sync.Mutex{}
  69. // Sign generates a signature for the given payload, and serializes
  70. // it in compact serialization format. In this format you may NOT use
  71. // multiple signers.
  72. //
  73. // The `alg` parameter is the identifier for the signature algorithm
  74. // that should be used.
  75. //
  76. // For the `key` parameter, any of the following is accepted:
  77. // * A "raw" key (e.g. rsa.PrivateKey, ecdsa.PrivateKey, etc)
  78. // * A crypto.Signer
  79. // * A jwk.Key
  80. //
  81. // A `crypto.Signer` is used when the private part of a key is
  82. // kept in an inaccessible location, such as hardware.
  83. // `crypto.Signer` is currently supported for RSA, ECDSA, and EdDSA
  84. // family of algorithms.
  85. //
  86. // If the key is a jwk.Key and the key contains a key ID (`kid` field),
  87. // then it is added to the protected header generated by the signature
  88. //
  89. // The algorithm specified in the `alg` parameter must be able to support
  90. // the type of key you provided, otherwise an error is returned.
  91. //
  92. // If you would like to pass custom headers, use the WithHeaders option.
  93. //
  94. // If the headers contain "b64" field, then the boolean value for the field
  95. // is respected when creating the compact serialization form. That is,
  96. // if you specify a header with `{"b64": false}`, then the payload is
  97. // not base64 encoded.
  98. //
  99. // If you want to use a detached payload, use `jws.WithDetachedPayload()` as
  100. // one of the options. When you use this option, you must always set the
  101. // first parameter (`payload`) to `nil`, or the function will return an error
  102. func Sign(payload []byte, alg jwa.SignatureAlgorithm, key interface{}, options ...SignOption) ([]byte, error) {
  103. var hdrs Headers
  104. var detached bool
  105. for _, o := range options {
  106. //nolint:forcetypeassert
  107. switch o.Ident() {
  108. case identHeaders{}:
  109. hdrs = o.Value().(Headers)
  110. case identDetachedPayload{}:
  111. detached = true
  112. if payload != nil {
  113. return nil, errors.New(`jws.Sign: payload must be nil when jws.WithDetachedPayload() is specified`)
  114. }
  115. payload = o.Value().([]byte)
  116. }
  117. }
  118. muSigner.Lock()
  119. signer, ok := signers[alg]
  120. if !ok {
  121. v, err := NewSigner(alg)
  122. if err != nil {
  123. muSigner.Unlock()
  124. return nil, errors.Wrap(err, `failed to create signer`)
  125. }
  126. signers[alg] = v
  127. signer = v
  128. }
  129. muSigner.Unlock()
  130. // XXX This is cheating. Ideally `detached` should be passed as a parameter
  131. // but since this is an exported method, we can't change this without bumping
  132. // major versions.... But we don't want to do that now, so we will cheat by
  133. // making it part of the object
  134. sig := &Signature{
  135. protected: hdrs,
  136. detached: detached,
  137. }
  138. _, signature, err := sig.Sign(payload, signer, key)
  139. if err != nil {
  140. return nil, errors.Wrap(err, `failed sign payload`)
  141. }
  142. return signature, nil
  143. }
  144. // SignMulti accepts multiple signers via the options parameter,
  145. // and creates a JWS in JSON serialization format that contains
  146. // signatures from applying aforementioned signers.
  147. //
  148. // Use `jws.WithSigner(...)` to specify values how to generate
  149. // each signature in the `"signatures": [ ... ]` field.
  150. func SignMulti(payload []byte, options ...Option) ([]byte, error) {
  151. var signers []*payloadSigner
  152. for _, o := range options {
  153. //nolint:forcetypeassert
  154. switch o.Ident() {
  155. case identPayloadSigner{}:
  156. signers = append(signers, o.Value().(*payloadSigner))
  157. }
  158. }
  159. if len(signers) == 0 {
  160. return nil, errors.New(`no signers provided`)
  161. }
  162. var result Message
  163. result.payload = payload
  164. result.signatures = make([]*Signature, 0, len(signers))
  165. for i, signer := range signers {
  166. protected := signer.ProtectedHeader()
  167. if protected == nil {
  168. protected = NewHeaders()
  169. }
  170. if err := protected.Set(AlgorithmKey, signer.Algorithm()); err != nil {
  171. return nil, errors.Wrap(err, `failed to set "alg" header`)
  172. }
  173. if key, ok := signer.key.(jwk.Key); ok {
  174. if kid := key.KeyID(); kid != "" {
  175. if err := protected.Set(KeyIDKey, kid); err != nil {
  176. return nil, errors.Wrap(err, `failed to set "kid" header`)
  177. }
  178. }
  179. }
  180. sig := &Signature{
  181. headers: signer.PublicHeader(),
  182. protected: protected,
  183. }
  184. _, _, err := sig.Sign(payload, signer.signer, signer.key)
  185. if err != nil {
  186. return nil, errors.Wrapf(err, `failed to generate signature for signer #%d (alg=%s)`, i, signer.Algorithm())
  187. }
  188. result.signatures = append(result.signatures, sig)
  189. }
  190. return json.Marshal(result)
  191. }
  192. type verifyCtx struct {
  193. dst *Message
  194. detachedPayload []byte
  195. alg jwa.SignatureAlgorithm
  196. key interface{}
  197. useJKU bool
  198. jwksFetcher JWKSetFetcher
  199. // This is only used to differentiate compact/JSON serialization
  200. // because certain features are enabled/disabled in each
  201. isJSON bool
  202. }
  203. var allowNoneWhitelist = jwk.WhitelistFunc(func(string) bool {
  204. return false
  205. })
  206. // VerifyAuto is a special case of Verify(), where verification is done
  207. // using verifications parameters that can be obtained using the information
  208. // that is carried within the JWS message itself.
  209. //
  210. // Currently it only supports verification via `jku` which will be fetched
  211. // using the object specified in `jws.JWKSetFetcher`. Note that URLs in `jku` can
  212. // only have https scheme.
  213. //
  214. // Using this function will result in your program accessing remote resources via https,
  215. // and therefore extreme caution should be taken which urls can be accessed.
  216. //
  217. // Without specifying extra arguments, the default `jws.JWKSetFetcher` will be
  218. // configured with a whitelist that rejects *ALL URLSs*. This is to
  219. // protect users from unintentionally allowing their projects to
  220. // make unwanted requests. Therefore you must explicitly provide an
  221. // instance of `jwk.Whitelist` that does what you want.
  222. //
  223. // If you want open access to any URLs in the `jku`, you can do this by
  224. // using `jwk.InsecureWhitelist` as the whitelist, but this should be avoided in
  225. // most cases, especially if the payload comes from outside of a controlled
  226. // environment.
  227. //
  228. // It is also advised that you consider using some sort of backoff via `jws.WithFetchBackoff`
  229. //
  230. // Alternatively, you can provide your own `jws.JWKSetFetcher`. In this case
  231. // there is no way for the framework to force you to set a whitelist, so the
  232. // default behavior is to allow any URLs. You are responsible for providing
  233. // your own safety measures.
  234. func VerifyAuto(buf []byte, options ...VerifyOption) ([]byte, error) {
  235. var ctx verifyCtx
  236. // enable JKU processing
  237. ctx.useJKU = true
  238. var fetchOptions []jwk.FetchOption
  239. //nolint:forcetypeassert
  240. for _, option := range options {
  241. switch option.Ident() {
  242. case identMessage{}:
  243. ctx.dst = option.Value().(*Message)
  244. case identDetachedPayload{}:
  245. ctx.detachedPayload = option.Value().([]byte)
  246. case identJWKSetFetcher{}:
  247. ctx.jwksFetcher = option.Value().(JWKSetFetcher)
  248. case identFetchWhitelist{}:
  249. fetchOptions = append(fetchOptions, jwk.WithFetchWhitelist(option.Value().(jwk.Whitelist)))
  250. case identFetchBackoff{}:
  251. fetchOptions = append(fetchOptions, jwk.WithFetchBackoff(option.Value().(backoff.Policy)))
  252. case identHTTPClient{}:
  253. fetchOptions = append(fetchOptions, jwk.WithHTTPClient(option.Value().(*http.Client)))
  254. }
  255. }
  256. // We shove the default Whitelist in the front of the option list.
  257. // If the user provided one, it will overwrite our default value
  258. if ctx.jwksFetcher == nil {
  259. fetchOptions = append([]jwk.FetchOption{jwk.WithFetchWhitelist(allowNoneWhitelist)}, fetchOptions...)
  260. ctx.jwksFetcher = NewJWKSetFetcher(fetchOptions...)
  261. }
  262. return ctx.verify(buf)
  263. }
  264. // Verify checks if the given JWS message is verifiable using `alg` and `key`.
  265. // `key` may be a "raw" key (e.g. rsa.PublicKey) or a jwk.Key
  266. //
  267. // If the verification is successful, `err` is nil, and the content of the
  268. // payload that was signed is returned. If you need more fine-grained
  269. // control of the verification process, manually generate a
  270. // `Verifier` in `verify` subpackage, and call `Verify` method on it.
  271. // If you need to access signatures and JOSE headers in a JWS message,
  272. // use `Parse` function to get `Message` object.
  273. func Verify(buf []byte, alg jwa.SignatureAlgorithm, key interface{}, options ...VerifyOption) ([]byte, error) {
  274. var ctx verifyCtx
  275. ctx.alg = alg
  276. ctx.key = key
  277. //nolint:forcetypeassert
  278. for _, option := range options {
  279. switch option.Ident() {
  280. case identMessage{}:
  281. ctx.dst = option.Value().(*Message)
  282. case identDetachedPayload{}:
  283. ctx.detachedPayload = option.Value().([]byte)
  284. default:
  285. return nil, errors.Errorf(`invalid jws.VerifyOption %q passed`, `With`+strings.TrimPrefix(fmt.Sprintf(`%T`, option.Ident()), `jws.ident`))
  286. }
  287. }
  288. return ctx.verify(buf)
  289. }
  290. func (ctx *verifyCtx) verify(buf []byte) ([]byte, error) {
  291. buf = bytes.TrimSpace(buf)
  292. if len(buf) == 0 {
  293. return nil, errors.New(`attempt to verify empty buffer`)
  294. }
  295. if buf[0] == '{' {
  296. return ctx.verifyJSON(buf)
  297. }
  298. return ctx.verifyCompact(buf)
  299. }
  300. // VerifySet uses keys store in a jwk.Set to verify the payload in `buf`.
  301. //
  302. // In order for `VerifySet()` to use a key in the given set, the
  303. // `jwk.Key` object must have a valid "alg" field, and it also must
  304. // have either an empty value or the value "sig" in the "use" field.
  305. //
  306. // Furthermore if the JWS signature asks for a spefici "kid", the
  307. // `jwk.Key` must have the same "kid" as the signature.
  308. func VerifySet(buf []byte, set jwk.Set) ([]byte, error) {
  309. n := set.Len()
  310. for i := 0; i < n; i++ {
  311. key, ok := set.Get(i)
  312. if !ok {
  313. continue
  314. }
  315. if key.Algorithm() == "" { // algorithm is not
  316. continue
  317. }
  318. if usage := key.KeyUsage(); usage != "" && usage != jwk.ForSignature.String() {
  319. continue
  320. }
  321. buf, err := Verify(buf, jwa.SignatureAlgorithm(key.Algorithm()), key)
  322. if err != nil {
  323. continue
  324. }
  325. return buf, nil
  326. }
  327. return nil, errors.New(`failed to verify message with any of the keys in the jwk.Set object`)
  328. }
  329. func (ctx *verifyCtx) verifyJSON(signed []byte) ([]byte, error) {
  330. ctx.isJSON = true
  331. var m Message
  332. m.SetDecodeCtx(collectRawCtx{})
  333. defer m.clearRaw()
  334. if err := json.Unmarshal(signed, &m); err != nil {
  335. return nil, errors.Wrap(err, `failed to unmarshal JSON message`)
  336. }
  337. m.SetDecodeCtx(nil)
  338. if len(m.payload) != 0 && ctx.detachedPayload != nil {
  339. return nil, errors.New(`can't specify detached payload for JWS with payload`)
  340. }
  341. if ctx.detachedPayload != nil {
  342. m.payload = ctx.detachedPayload
  343. }
  344. // Pre-compute the base64 encoded version of payload
  345. var payload string
  346. if m.b64 {
  347. payload = base64.EncodeToString(m.payload)
  348. } else {
  349. payload = string(m.payload)
  350. }
  351. buf := pool.GetBytesBuffer()
  352. defer pool.ReleaseBytesBuffer(buf)
  353. for i, sig := range m.signatures {
  354. buf.Reset()
  355. var encodedProtectedHeader string
  356. if rbp, ok := sig.protected.(interface{ rawBuffer() []byte }); ok {
  357. if raw := rbp.rawBuffer(); raw != nil {
  358. encodedProtectedHeader = base64.EncodeToString(raw)
  359. }
  360. }
  361. if encodedProtectedHeader == "" {
  362. protected, err := json.Marshal(sig.protected)
  363. if err != nil {
  364. return nil, errors.Wrapf(err, `failed to marshal "protected" for signature #%d`, i+1)
  365. }
  366. encodedProtectedHeader = base64.EncodeToString(protected)
  367. }
  368. buf.WriteString(encodedProtectedHeader)
  369. buf.WriteByte('.')
  370. buf.WriteString(payload)
  371. if !ctx.useJKU {
  372. if hdr := sig.protected; hdr != nil && hdr.KeyID() != "" {
  373. if jwkKey, ok := ctx.key.(jwk.Key); ok {
  374. if jwkKey.KeyID() != hdr.KeyID() {
  375. continue
  376. }
  377. }
  378. }
  379. verifier, err := NewVerifier(ctx.alg)
  380. if err != nil {
  381. return nil, errors.Wrap(err, "failed to create verifier")
  382. }
  383. if _, err := ctx.tryVerify(verifier, sig.protected, buf.Bytes(), sig.signature, m.payload); err == nil {
  384. if ctx.dst != nil {
  385. *(ctx.dst) = m
  386. }
  387. return m.payload, nil
  388. }
  389. // Don't fallthrough or bail out. Try the next signature.
  390. continue
  391. }
  392. if _, err := ctx.verifyJKU(sig.protected, buf.Bytes(), sig.signature, m.payload); err == nil {
  393. if ctx.dst != nil {
  394. *(ctx.dst) = m
  395. }
  396. return m.payload, nil
  397. }
  398. // try next
  399. }
  400. return nil, errors.New(`could not verify with any of the signatures`)
  401. }
  402. // get the value of b64 header field.
  403. // If the field does not exist, returns true (default)
  404. // Otherwise return the value specified by the header field.
  405. func getB64Value(hdr Headers) bool {
  406. b64raw, ok := hdr.Get("b64")
  407. if !ok {
  408. return true // default
  409. }
  410. b64, ok := b64raw.(bool) // default
  411. if !ok {
  412. return false
  413. }
  414. return b64
  415. }
  416. func (ctx *verifyCtx) verifyCompact(signed []byte) ([]byte, error) {
  417. protected, payload, signature, err := SplitCompact(signed)
  418. if err != nil {
  419. return nil, errors.Wrap(err, `failed extract from compact serialization format`)
  420. }
  421. decodedSignature, err := base64.Decode(signature)
  422. if err != nil {
  423. return nil, errors.Wrap(err, `failed to decode signature`)
  424. }
  425. hdr := NewHeaders()
  426. decodedProtected, err := base64.Decode(protected)
  427. if err != nil {
  428. return nil, errors.Wrap(err, `failed to decode headers`)
  429. }
  430. if err := json.Unmarshal(decodedProtected, hdr); err != nil {
  431. return nil, errors.Wrap(err, `failed to decode headers`)
  432. }
  433. verifyBuf := pool.GetBytesBuffer()
  434. defer pool.ReleaseBytesBuffer(verifyBuf)
  435. verifyBuf.Write(protected)
  436. verifyBuf.WriteByte('.')
  437. if len(payload) == 0 && ctx.detachedPayload != nil {
  438. if getB64Value(hdr) {
  439. payload = base64.Encode(ctx.detachedPayload)
  440. } else {
  441. payload = ctx.detachedPayload
  442. }
  443. }
  444. verifyBuf.Write(payload)
  445. if !ctx.useJKU {
  446. if hdr.KeyID() != "" {
  447. if jwkKey, ok := ctx.key.(jwk.Key); ok {
  448. if jwkKey.KeyID() != hdr.KeyID() {
  449. return nil, errors.New(`"kid" fields do not match`)
  450. }
  451. }
  452. }
  453. verifier, err := NewVerifier(ctx.alg)
  454. if err != nil {
  455. return nil, errors.Wrap(err, "failed to create verifier")
  456. }
  457. return ctx.tryVerify(verifier, hdr, verifyBuf.Bytes(), decodedSignature, payload)
  458. }
  459. return ctx.verifyJKU(hdr, verifyBuf.Bytes(), decodedSignature, payload)
  460. }
  461. // JWKSetFetcher is used to fetch JWK Set spcified in the `jku` field.
  462. type JWKSetFetcher interface {
  463. Fetch(string) (jwk.Set, error)
  464. }
  465. // SimpleJWKSetFetcher is the default object used to fetch JWK Sets specified in `jku`,
  466. // which uses `jwk.Fetch()`
  467. //
  468. // For more complicated cases, such as using `jwk.AutoRefetch`, you will have to
  469. // create your custom instance of `jws.JWKSetFetcher`
  470. type SimpleJWKSetFetcher struct {
  471. options []jwk.FetchOption
  472. }
  473. func NewJWKSetFetcher(options ...jwk.FetchOption) *SimpleJWKSetFetcher {
  474. return &SimpleJWKSetFetcher{options: options}
  475. }
  476. func (f *SimpleJWKSetFetcher) Fetch(u string) (jwk.Set, error) {
  477. return jwk.Fetch(context.TODO(), u, f.options...)
  478. }
  479. type JWKSetFetchFunc func(string) (jwk.Set, error)
  480. func (f JWKSetFetchFunc) Fetch(u string) (jwk.Set, error) {
  481. return f(u)
  482. }
  483. func (ctx *verifyCtx) verifyJKU(hdr Headers, verifyBuf, decodedSignature, payload []byte) ([]byte, error) {
  484. u := hdr.JWKSetURL()
  485. if u == "" {
  486. return nil, errors.New(`use of "jku" field specified, but the field is empty`)
  487. }
  488. uo, err := url.Parse(u)
  489. if err != nil {
  490. return nil, errors.Wrap(err, `failed to parse "jku"`)
  491. }
  492. if uo.Scheme != "https" {
  493. return nil, errors.New(`url in "jku" must be HTTPS`)
  494. }
  495. set, err := ctx.jwksFetcher.Fetch(u)
  496. if err != nil {
  497. return nil, errors.Wrapf(err, `failed to fetch "jku"`)
  498. }
  499. // Because we're using a JWKS here, we MUST have "kid" that matches
  500. // the payload
  501. if hdr.KeyID() == "" {
  502. return nil, errors.Errorf(`"kid" is required on the JWS message to use "jku"`)
  503. }
  504. key, ok := set.LookupKeyID(hdr.KeyID())
  505. if !ok {
  506. return nil, errors.New(`key specified via "kid" is not present in the JWK set specified by "jku"`)
  507. }
  508. // hooray, we found a key. Now the algorithm will have to be inferred.
  509. algs, err := AlgorithmsForKey(key)
  510. if err != nil {
  511. return nil, errors.Wrapf(err, `failed to get a list of signature methods for key type %s`, key.KeyType())
  512. }
  513. // for each of these algorithms, just ... keep trying ...
  514. ctx.key = key
  515. hdrAlg := hdr.Algorithm()
  516. for _, alg := range algs {
  517. // if we have a "alg" field in the JWS, we can only proceed if
  518. // the inferred algorithm matches
  519. if hdrAlg != "" && hdrAlg != alg {
  520. continue
  521. }
  522. verifier, err := NewVerifier(alg)
  523. if err != nil {
  524. return nil, errors.Wrap(err, "failed to create verifier")
  525. }
  526. if decoded, err := ctx.tryVerify(verifier, hdr, verifyBuf, decodedSignature, payload); err == nil {
  527. return decoded, nil
  528. }
  529. }
  530. return nil, errors.New(`failed to verify payload using key in "jku"`)
  531. }
  532. func (ctx *verifyCtx) tryVerify(verifier Verifier, hdr Headers, buf, decodedSignature, payload []byte) ([]byte, error) {
  533. if err := verifier.Verify(buf, decodedSignature, ctx.key); err != nil {
  534. return nil, errors.Wrap(err, `failed to verify message`)
  535. }
  536. var decodedPayload []byte
  537. // When verifying JSON messages, we do not need to decode
  538. // the payload, as we already have it
  539. if !ctx.isJSON {
  540. // This is a special case for RFC7797
  541. if !getB64Value(hdr) { // it's not base64 encoded
  542. decodedPayload = payload
  543. }
  544. if decodedPayload == nil {
  545. v, err := base64.Decode(payload)
  546. if err != nil {
  547. return nil, errors.Wrap(err, `message verified, failed to decode payload`)
  548. }
  549. decodedPayload = v
  550. }
  551. // For compact serialization, we need to create and assign the message
  552. // if requested
  553. if ctx.dst != nil {
  554. // Construct a new Message object
  555. m := NewMessage()
  556. m.SetPayload(decodedPayload)
  557. sig := NewSignature()
  558. sig.SetProtectedHeaders(hdr)
  559. sig.SetSignature(decodedSignature)
  560. m.AppendSignature(sig)
  561. *(ctx.dst) = *m
  562. }
  563. }
  564. return decodedPayload, nil
  565. }
  566. // This is an "optimized" ioutil.ReadAll(). It will attempt to read
  567. // all of the contents from the reader IF the reader is of a certain
  568. // concrete type.
  569. func readAll(rdr io.Reader) ([]byte, bool) {
  570. switch rdr.(type) {
  571. case *bytes.Reader, *bytes.Buffer, *strings.Reader:
  572. data, err := ioutil.ReadAll(rdr)
  573. if err != nil {
  574. return nil, false
  575. }
  576. return data, true
  577. default:
  578. return nil, false
  579. }
  580. }
  581. // Parse parses contents from the given source and creates a jws.Message
  582. // struct. The input can be in either compact or full JSON serialization.
  583. func Parse(src []byte) (*Message, error) {
  584. for i := 0; i < len(src); i++ {
  585. r := rune(src[i])
  586. if r >= utf8.RuneSelf {
  587. r, _ = utf8.DecodeRune(src)
  588. }
  589. if !unicode.IsSpace(r) {
  590. if r == '{' {
  591. return parseJSON(src)
  592. }
  593. return parseCompact(src)
  594. }
  595. }
  596. return nil, errors.New("invalid byte sequence")
  597. }
  598. // Parse parses contents from the given source and creates a jws.Message
  599. // struct. The input can be in either compact or full JSON serialization.
  600. func ParseString(src string) (*Message, error) {
  601. return Parse([]byte(src))
  602. }
  603. // Parse parses contents from the given source and creates a jws.Message
  604. // struct. The input can be in either compact or full JSON serialization.
  605. func ParseReader(src io.Reader) (*Message, error) {
  606. if data, ok := readAll(src); ok {
  607. return Parse(data)
  608. }
  609. rdr := bufio.NewReader(src)
  610. var first rune
  611. for {
  612. r, _, err := rdr.ReadRune()
  613. if err != nil {
  614. return nil, errors.Wrap(err, `failed to read rune`)
  615. }
  616. if !unicode.IsSpace(r) {
  617. first = r
  618. if err := rdr.UnreadRune(); err != nil {
  619. return nil, errors.Wrap(err, `failed to unread rune`)
  620. }
  621. break
  622. }
  623. }
  624. var parser func(io.Reader) (*Message, error)
  625. if first == '{' {
  626. parser = parseJSONReader
  627. } else {
  628. parser = parseCompactReader
  629. }
  630. m, err := parser(rdr)
  631. if err != nil {
  632. return nil, errors.Wrap(err, `failed to parse jws message`)
  633. }
  634. return m, nil
  635. }
  636. func parseJSONReader(src io.Reader) (result *Message, err error) {
  637. var m Message
  638. if err := json.NewDecoder(src).Decode(&m); err != nil {
  639. return nil, errors.Wrap(err, `failed to unmarshal jws message`)
  640. }
  641. return &m, nil
  642. }
  643. func parseJSON(data []byte) (result *Message, err error) {
  644. var m Message
  645. if err := json.Unmarshal(data, &m); err != nil {
  646. return nil, errors.Wrap(err, `failed to unmarshal jws message`)
  647. }
  648. return &m, nil
  649. }
  650. // SplitCompact splits a JWT and returns its three parts
  651. // separately: protected headers, payload and signature.
  652. func SplitCompact(src []byte) ([]byte, []byte, []byte, error) {
  653. parts := bytes.Split(src, []byte("."))
  654. if len(parts) < 3 {
  655. return nil, nil, nil, errors.New(`invalid number of segments`)
  656. }
  657. return parts[0], parts[1], parts[2], nil
  658. }
  659. // SplitCompactString splits a JWT and returns its three parts
  660. // separately: protected headers, payload and signature.
  661. func SplitCompactString(src string) ([]byte, []byte, []byte, error) {
  662. parts := strings.Split(src, ".")
  663. if len(parts) < 3 {
  664. return nil, nil, nil, errors.New(`invalid number of segments`)
  665. }
  666. return []byte(parts[0]), []byte(parts[1]), []byte(parts[2]), nil
  667. }
  668. // SplitCompactReader splits a JWT and returns its three parts
  669. // separately: protected headers, payload and signature.
  670. func SplitCompactReader(rdr io.Reader) ([]byte, []byte, []byte, error) {
  671. if data, ok := readAll(rdr); ok {
  672. return SplitCompact(data)
  673. }
  674. var protected []byte
  675. var payload []byte
  676. var signature []byte
  677. var periods int
  678. var state int
  679. buf := make([]byte, 4096)
  680. var sofar []byte
  681. for {
  682. // read next bytes
  683. n, err := rdr.Read(buf)
  684. // return on unexpected read error
  685. if err != nil && err != io.EOF {
  686. return nil, nil, nil, errors.Wrap(err, `unexpected end of input`)
  687. }
  688. // append to current buffer
  689. sofar = append(sofar, buf[:n]...)
  690. // loop to capture multiple '.' in current buffer
  691. for loop := true; loop; {
  692. var i = bytes.IndexByte(sofar, '.')
  693. if i == -1 && err != io.EOF {
  694. // no '.' found -> exit and read next bytes (outer loop)
  695. loop = false
  696. continue
  697. } else if i == -1 && err == io.EOF {
  698. // no '.' found -> process rest and exit
  699. i = len(sofar)
  700. loop = false
  701. } else {
  702. // '.' found
  703. periods++
  704. }
  705. // Reaching this point means we have found a '.' or EOF and process the rest of the buffer
  706. switch state {
  707. case 0:
  708. protected = sofar[:i]
  709. state++
  710. case 1:
  711. payload = sofar[:i]
  712. state++
  713. case 2:
  714. signature = sofar[:i]
  715. }
  716. // Shorten current buffer
  717. if len(sofar) > i {
  718. sofar = sofar[i+1:]
  719. }
  720. }
  721. // Exit on EOF
  722. if err == io.EOF {
  723. break
  724. }
  725. }
  726. if periods != 2 {
  727. return nil, nil, nil, errors.New(`invalid number of segments`)
  728. }
  729. return protected, payload, signature, nil
  730. }
  731. // parseCompactReader parses a JWS value serialized via compact serialization.
  732. func parseCompactReader(rdr io.Reader) (m *Message, err error) {
  733. protected, payload, signature, err := SplitCompactReader(rdr)
  734. if err != nil {
  735. return nil, errors.Wrap(err, `invalid compact serialization format`)
  736. }
  737. return parse(protected, payload, signature)
  738. }
  739. func parseCompact(data []byte) (m *Message, err error) {
  740. protected, payload, signature, err := SplitCompact(data)
  741. if err != nil {
  742. return nil, errors.Wrap(err, `invalid compact serialization format`)
  743. }
  744. return parse(protected, payload, signature)
  745. }
  746. func parse(protected, payload, signature []byte) (*Message, error) {
  747. decodedHeader, err := base64.Decode(protected)
  748. if err != nil {
  749. return nil, errors.Wrap(err, `failed to decode protected headers`)
  750. }
  751. hdr := NewHeaders()
  752. if err := json.Unmarshal(decodedHeader, hdr); err != nil {
  753. return nil, errors.Wrap(err, `failed to parse JOSE headers`)
  754. }
  755. decodedPayload, err := base64.Decode(payload)
  756. if err != nil {
  757. return nil, errors.Wrap(err, `failed to decode payload`)
  758. }
  759. decodedSignature, err := base64.Decode(signature)
  760. if err != nil {
  761. return nil, errors.Wrap(err, `failed to decode signature`)
  762. }
  763. var msg Message
  764. msg.payload = decodedPayload
  765. msg.signatures = append(msg.signatures, &Signature{
  766. protected: hdr,
  767. signature: decodedSignature,
  768. })
  769. return &msg, nil
  770. }
  771. // RegisterCustomField allows users to specify that a private field
  772. // be decoded as an instance of the specified type. This option has
  773. // a global effect.
  774. //
  775. // For example, suppose you have a custom field `x-birthday`, which
  776. // you want to represent as a string formatted in RFC3339 in JSON,
  777. // but want it back as `time.Time`.
  778. //
  779. // In that case you would register a custom field as follows
  780. //
  781. // jwe.RegisterCustomField(`x-birthday`, timeT)
  782. //
  783. // Then `hdr.Get("x-birthday")` will still return an `interface{}`,
  784. // but you can convert its type to `time.Time`
  785. //
  786. // bdayif, _ := hdr.Get(`x-birthday`)
  787. // bday := bdayif.(time.Time)
  788. //
  789. func RegisterCustomField(name string, object interface{}) {
  790. registry.Register(name, object)
  791. }
  792. // Helpers for signature verification
  793. var rawKeyToKeyType = make(map[reflect.Type]jwa.KeyType)
  794. var keyTypeToAlgorithms = make(map[jwa.KeyType][]jwa.SignatureAlgorithm)
  795. func init() {
  796. rawKeyToKeyType[reflect.TypeOf([]byte(nil))] = jwa.OctetSeq
  797. rawKeyToKeyType[reflect.TypeOf(ed25519.PublicKey(nil))] = jwa.OKP
  798. rawKeyToKeyType[reflect.TypeOf(rsa.PublicKey{})] = jwa.RSA
  799. rawKeyToKeyType[reflect.TypeOf((*rsa.PublicKey)(nil))] = jwa.RSA
  800. rawKeyToKeyType[reflect.TypeOf(ecdsa.PublicKey{})] = jwa.EC
  801. rawKeyToKeyType[reflect.TypeOf((*ecdsa.PublicKey)(nil))] = jwa.EC
  802. addAlgorithmForKeyType(jwa.OKP, jwa.EdDSA)
  803. for _, alg := range []jwa.SignatureAlgorithm{jwa.HS256, jwa.HS384, jwa.HS512} {
  804. addAlgorithmForKeyType(jwa.OctetSeq, alg)
  805. }
  806. for _, alg := range []jwa.SignatureAlgorithm{jwa.RS256, jwa.RS384, jwa.RS512, jwa.PS256, jwa.PS384, jwa.PS512} {
  807. addAlgorithmForKeyType(jwa.RSA, alg)
  808. }
  809. for _, alg := range []jwa.SignatureAlgorithm{jwa.ES256, jwa.ES384, jwa.ES512} {
  810. addAlgorithmForKeyType(jwa.EC, alg)
  811. }
  812. }
  813. func addAlgorithmForKeyType(kty jwa.KeyType, alg jwa.SignatureAlgorithm) {
  814. keyTypeToAlgorithms[kty] = append(keyTypeToAlgorithms[kty], alg)
  815. }
  816. // AlgorithmsForKey returns the possible signature algorithms that can
  817. // be used for a given key. It only takes in consideration keys/algorithms
  818. // for verification purposes, as this is the only usage where one may need
  819. // dynamically figure out which method to use.
  820. func AlgorithmsForKey(key interface{}) ([]jwa.SignatureAlgorithm, error) {
  821. var kty jwa.KeyType
  822. switch key := key.(type) {
  823. case jwk.Key:
  824. kty = key.KeyType()
  825. case rsa.PublicKey, *rsa.PublicKey, rsa.PrivateKey, *rsa.PrivateKey:
  826. kty = jwa.RSA
  827. case ecdsa.PublicKey, *ecdsa.PublicKey, ecdsa.PrivateKey, *ecdsa.PrivateKey:
  828. kty = jwa.EC
  829. case ed25519.PublicKey, ed25519.PrivateKey, x25519.PublicKey, x25519.PrivateKey:
  830. kty = jwa.OKP
  831. case []byte:
  832. kty = jwa.OctetSeq
  833. default:
  834. return nil, errors.Errorf(`invalid key %T`, key)
  835. }
  836. algs, ok := keyTypeToAlgorithms[kty]
  837. if !ok {
  838. return nil, errors.Errorf(`invalid key type %q`, kty)
  839. }
  840. return algs, nil
  841. }