signing.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. /*-
  2. * Copyright 2014 Square Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package jose
  17. import (
  18. "bytes"
  19. "crypto/ecdsa"
  20. "crypto/rsa"
  21. "encoding/base64"
  22. "errors"
  23. "fmt"
  24. "golang.org/x/crypto/ed25519"
  25. "gopkg.in/square/go-jose.v2/json"
  26. )
  27. // NonceSource represents a source of random nonces to go into JWS objects
  28. type NonceSource interface {
  29. Nonce() (string, error)
  30. }
  31. // Signer represents a signer which takes a payload and produces a signed JWS object.
  32. type Signer interface {
  33. Sign(payload []byte) (*JSONWebSignature, error)
  34. Options() SignerOptions
  35. }
  36. // SigningKey represents an algorithm/key used to sign a message.
  37. type SigningKey struct {
  38. Algorithm SignatureAlgorithm
  39. Key interface{}
  40. }
  41. // SignerOptions represents options that can be set when creating signers.
  42. type SignerOptions struct {
  43. NonceSource NonceSource
  44. EmbedJWK bool
  45. // Optional map of additional keys to be inserted into the protected header
  46. // of a JWS object. Some specifications which make use of JWS like to insert
  47. // additional values here. All values must be JSON-serializable.
  48. ExtraHeaders map[HeaderKey]interface{}
  49. }
  50. // WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
  51. // if necessary. It returns itself and so can be used in a fluent style.
  52. func (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions {
  53. if so.ExtraHeaders == nil {
  54. so.ExtraHeaders = map[HeaderKey]interface{}{}
  55. }
  56. so.ExtraHeaders[k] = v
  57. return so
  58. }
  59. // WithContentType adds a content type ("cty") header and returns the updated
  60. // SignerOptions.
  61. func (so *SignerOptions) WithContentType(contentType ContentType) *SignerOptions {
  62. return so.WithHeader(HeaderContentType, contentType)
  63. }
  64. // WithType adds a type ("typ") header and returns the updated SignerOptions.
  65. func (so *SignerOptions) WithType(typ ContentType) *SignerOptions {
  66. return so.WithHeader(HeaderType, typ)
  67. }
  68. // WithCritical adds the given names to the critical ("crit") header and returns
  69. // the updated SignerOptions.
  70. func (so *SignerOptions) WithCritical(names ...string) *SignerOptions {
  71. if so.ExtraHeaders[headerCritical] == nil {
  72. so.WithHeader(headerCritical, make([]string, 0, len(names)))
  73. }
  74. crit := so.ExtraHeaders[headerCritical].([]string)
  75. so.ExtraHeaders[headerCritical] = append(crit, names...)
  76. return so
  77. }
  78. // WithBase64 adds a base64url-encode payload ("b64") header and returns the updated
  79. // SignerOptions. When the "b64" value is "false", the payload is not base64 encoded.
  80. func (so *SignerOptions) WithBase64(b64 bool) *SignerOptions {
  81. if !b64 {
  82. so.WithHeader(headerB64, b64)
  83. so.WithCritical(headerB64)
  84. }
  85. return so
  86. }
  87. type payloadSigner interface {
  88. signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error)
  89. }
  90. type payloadVerifier interface {
  91. verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error
  92. }
  93. type genericSigner struct {
  94. recipients []recipientSigInfo
  95. nonceSource NonceSource
  96. embedJWK bool
  97. extraHeaders map[HeaderKey]interface{}
  98. }
  99. type recipientSigInfo struct {
  100. sigAlg SignatureAlgorithm
  101. publicKey func() *JSONWebKey
  102. signer payloadSigner
  103. }
  104. func staticPublicKey(jwk *JSONWebKey) func() *JSONWebKey {
  105. return func() *JSONWebKey {
  106. return jwk
  107. }
  108. }
  109. // NewSigner creates an appropriate signer based on the key type
  110. func NewSigner(sig SigningKey, opts *SignerOptions) (Signer, error) {
  111. return NewMultiSigner([]SigningKey{sig}, opts)
  112. }
  113. // NewMultiSigner creates a signer for multiple recipients
  114. func NewMultiSigner(sigs []SigningKey, opts *SignerOptions) (Signer, error) {
  115. signer := &genericSigner{recipients: []recipientSigInfo{}}
  116. if opts != nil {
  117. signer.nonceSource = opts.NonceSource
  118. signer.embedJWK = opts.EmbedJWK
  119. signer.extraHeaders = opts.ExtraHeaders
  120. }
  121. for _, sig := range sigs {
  122. err := signer.addRecipient(sig.Algorithm, sig.Key)
  123. if err != nil {
  124. return nil, err
  125. }
  126. }
  127. return signer, nil
  128. }
  129. // newVerifier creates a verifier based on the key type
  130. func newVerifier(verificationKey interface{}) (payloadVerifier, error) {
  131. switch verificationKey := verificationKey.(type) {
  132. case ed25519.PublicKey:
  133. return &edEncrypterVerifier{
  134. publicKey: verificationKey,
  135. }, nil
  136. case *rsa.PublicKey:
  137. return &rsaEncrypterVerifier{
  138. publicKey: verificationKey,
  139. }, nil
  140. case *ecdsa.PublicKey:
  141. return &ecEncrypterVerifier{
  142. publicKey: verificationKey,
  143. }, nil
  144. case []byte:
  145. return &symmetricMac{
  146. key: verificationKey,
  147. }, nil
  148. case JSONWebKey:
  149. return newVerifier(verificationKey.Key)
  150. case *JSONWebKey:
  151. return newVerifier(verificationKey.Key)
  152. }
  153. if ov, ok := verificationKey.(OpaqueVerifier); ok {
  154. return &opaqueVerifier{verifier: ov}, nil
  155. }
  156. return nil, ErrUnsupportedKeyType
  157. }
  158. func (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error {
  159. recipient, err := makeJWSRecipient(alg, signingKey)
  160. if err != nil {
  161. return err
  162. }
  163. ctx.recipients = append(ctx.recipients, recipient)
  164. return nil
  165. }
  166. func makeJWSRecipient(alg SignatureAlgorithm, signingKey interface{}) (recipientSigInfo, error) {
  167. switch signingKey := signingKey.(type) {
  168. case ed25519.PrivateKey:
  169. return newEd25519Signer(alg, signingKey)
  170. case *rsa.PrivateKey:
  171. return newRSASigner(alg, signingKey)
  172. case *ecdsa.PrivateKey:
  173. return newECDSASigner(alg, signingKey)
  174. case []byte:
  175. return newSymmetricSigner(alg, signingKey)
  176. case JSONWebKey:
  177. return newJWKSigner(alg, signingKey)
  178. case *JSONWebKey:
  179. return newJWKSigner(alg, *signingKey)
  180. }
  181. if signer, ok := signingKey.(OpaqueSigner); ok {
  182. return newOpaqueSigner(alg, signer)
  183. }
  184. return recipientSigInfo{}, ErrUnsupportedKeyType
  185. }
  186. func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) {
  187. recipient, err := makeJWSRecipient(alg, signingKey.Key)
  188. if err != nil {
  189. return recipientSigInfo{}, err
  190. }
  191. if recipient.publicKey != nil && recipient.publicKey() != nil {
  192. // recipient.publicKey is a JWK synthesized for embedding when recipientSigInfo
  193. // was created for the inner key (such as a RSA or ECDSA public key). It contains
  194. // the pub key for embedding, but doesn't have extra params like key id.
  195. publicKey := signingKey
  196. publicKey.Key = recipient.publicKey().Key
  197. recipient.publicKey = staticPublicKey(&publicKey)
  198. // This should be impossible, but let's check anyway.
  199. if !recipient.publicKey().IsPublic() {
  200. return recipientSigInfo{}, errors.New("square/go-jose: public key was unexpectedly not public")
  201. }
  202. }
  203. return recipient, nil
  204. }
  205. func (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {
  206. obj := &JSONWebSignature{}
  207. obj.payload = payload
  208. obj.Signatures = make([]Signature, len(ctx.recipients))
  209. for i, recipient := range ctx.recipients {
  210. protected := map[HeaderKey]interface{}{
  211. headerAlgorithm: string(recipient.sigAlg),
  212. }
  213. if recipient.publicKey != nil && recipient.publicKey() != nil {
  214. // We want to embed the JWK or set the kid header, but not both. Having a protected
  215. // header that contains an embedded JWK while also simultaneously containing the kid
  216. // header is confusing, and at least in ACME the two are considered to be mutually
  217. // exclusive. The fact that both can exist at the same time is a somewhat unfortunate
  218. // result of the JOSE spec. We've decided that this library will only include one or
  219. // the other to avoid this confusion.
  220. //
  221. // See https://github.com/square/go-jose/issues/157 for more context.
  222. if ctx.embedJWK {
  223. protected[headerJWK] = recipient.publicKey()
  224. } else {
  225. keyID := recipient.publicKey().KeyID
  226. if keyID != "" {
  227. protected[headerKeyID] = keyID
  228. }
  229. }
  230. }
  231. if ctx.nonceSource != nil {
  232. nonce, err := ctx.nonceSource.Nonce()
  233. if err != nil {
  234. return nil, fmt.Errorf("square/go-jose: Error generating nonce: %v", err)
  235. }
  236. protected[headerNonce] = nonce
  237. }
  238. for k, v := range ctx.extraHeaders {
  239. protected[k] = v
  240. }
  241. serializedProtected := mustSerializeJSON(protected)
  242. needsBase64 := true
  243. if b64, ok := protected[headerB64]; ok {
  244. if needsBase64, ok = b64.(bool); !ok {
  245. return nil, errors.New("square/go-jose: Invalid b64 header parameter")
  246. }
  247. }
  248. var input bytes.Buffer
  249. input.WriteString(base64.RawURLEncoding.EncodeToString(serializedProtected))
  250. input.WriteByte('.')
  251. if needsBase64 {
  252. input.WriteString(base64.RawURLEncoding.EncodeToString(payload))
  253. } else {
  254. input.Write(payload)
  255. }
  256. signatureInfo, err := recipient.signer.signPayload(input.Bytes(), recipient.sigAlg)
  257. if err != nil {
  258. return nil, err
  259. }
  260. signatureInfo.protected = &rawHeader{}
  261. for k, v := range protected {
  262. b, err := json.Marshal(v)
  263. if err != nil {
  264. return nil, fmt.Errorf("square/go-jose: Error marshalling item %#v: %v", k, err)
  265. }
  266. (*signatureInfo.protected)[k] = makeRawMessage(b)
  267. }
  268. obj.Signatures[i] = signatureInfo
  269. }
  270. return obj, nil
  271. }
  272. func (ctx *genericSigner) Options() SignerOptions {
  273. return SignerOptions{
  274. NonceSource: ctx.nonceSource,
  275. EmbedJWK: ctx.embedJWK,
  276. ExtraHeaders: ctx.extraHeaders,
  277. }
  278. }
  279. // Verify validates the signature on the object and returns the payload.
  280. // This function does not support multi-signature, if you desire multi-sig
  281. // verification use VerifyMulti instead.
  282. //
  283. // Be careful when verifying signatures based on embedded JWKs inside the
  284. // payload header. You cannot assume that the key received in a payload is
  285. // trusted.
  286. func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) {
  287. err := obj.DetachedVerify(obj.payload, verificationKey)
  288. if err != nil {
  289. return nil, err
  290. }
  291. return obj.payload, nil
  292. }
  293. // UnsafePayloadWithoutVerification returns the payload without
  294. // verifying it. The content returned from this function cannot be
  295. // trusted.
  296. func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte {
  297. return obj.payload
  298. }
  299. // DetachedVerify validates a detached signature on the given payload. In
  300. // most cases, you will probably want to use Verify instead. DetachedVerify
  301. // is only useful if you have a payload and signature that are separated from
  302. // each other.
  303. func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {
  304. verifier, err := newVerifier(verificationKey)
  305. if err != nil {
  306. return err
  307. }
  308. if len(obj.Signatures) > 1 {
  309. return errors.New("square/go-jose: too many signatures in payload; expecting only one")
  310. }
  311. signature := obj.Signatures[0]
  312. headers := signature.mergedHeaders()
  313. critical, err := headers.getCritical()
  314. if err != nil {
  315. return err
  316. }
  317. for _, name := range critical {
  318. if !supportedCritical[name] {
  319. return ErrCryptoFailure
  320. }
  321. }
  322. input, err := obj.computeAuthData(payload, &signature)
  323. if err != nil {
  324. return ErrCryptoFailure
  325. }
  326. alg := headers.getSignatureAlgorithm()
  327. err = verifier.verifyPayload(input, signature.Signature, alg)
  328. if err == nil {
  329. return nil
  330. }
  331. return ErrCryptoFailure
  332. }
  333. // VerifyMulti validates (one of the multiple) signatures on the object and
  334. // returns the index of the signature that was verified, along with the signature
  335. // object and the payload. We return the signature and index to guarantee that
  336. // callers are getting the verified value.
  337. func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) {
  338. idx, sig, err := obj.DetachedVerifyMulti(obj.payload, verificationKey)
  339. if err != nil {
  340. return -1, Signature{}, nil, err
  341. }
  342. return idx, sig, obj.payload, nil
  343. }
  344. // DetachedVerifyMulti validates a detached signature on the given payload with
  345. // a signature/object that has potentially multiple signers. This returns the index
  346. // of the signature that was verified, along with the signature object. We return
  347. // the signature and index to guarantee that callers are getting the verified value.
  348. //
  349. // In most cases, you will probably want to use Verify or VerifyMulti instead.
  350. // DetachedVerifyMulti is only useful if you have a payload and signature that are
  351. // separated from each other, and the signature can have multiple signers at the
  352. // same time.
  353. func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {
  354. verifier, err := newVerifier(verificationKey)
  355. if err != nil {
  356. return -1, Signature{}, err
  357. }
  358. outer:
  359. for i, signature := range obj.Signatures {
  360. headers := signature.mergedHeaders()
  361. critical, err := headers.getCritical()
  362. if err != nil {
  363. continue
  364. }
  365. for _, name := range critical {
  366. if !supportedCritical[name] {
  367. continue outer
  368. }
  369. }
  370. input, err := obj.computeAuthData(payload, &signature)
  371. if err != nil {
  372. continue
  373. }
  374. alg := headers.getSignatureAlgorithm()
  375. err = verifier.verifyPayload(input, signature.Signature, alg)
  376. if err == nil {
  377. return i, signature, nil
  378. }
  379. }
  380. return -1, Signature{}, ErrCryptoFailure
  381. }