asymmetric.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  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. "crypto"
  19. "crypto/aes"
  20. "crypto/ecdsa"
  21. "crypto/rand"
  22. "crypto/rsa"
  23. "crypto/sha1"
  24. "crypto/sha256"
  25. "errors"
  26. "fmt"
  27. "math/big"
  28. "golang.org/x/crypto/ed25519"
  29. josecipher "gopkg.in/square/go-jose.v2/cipher"
  30. "gopkg.in/square/go-jose.v2/json"
  31. )
  32. // A generic RSA-based encrypter/verifier
  33. type rsaEncrypterVerifier struct {
  34. publicKey *rsa.PublicKey
  35. }
  36. // A generic RSA-based decrypter/signer
  37. type rsaDecrypterSigner struct {
  38. privateKey *rsa.PrivateKey
  39. }
  40. // A generic EC-based encrypter/verifier
  41. type ecEncrypterVerifier struct {
  42. publicKey *ecdsa.PublicKey
  43. }
  44. type edEncrypterVerifier struct {
  45. publicKey ed25519.PublicKey
  46. }
  47. // A key generator for ECDH-ES
  48. type ecKeyGenerator struct {
  49. size int
  50. algID string
  51. publicKey *ecdsa.PublicKey
  52. }
  53. // A generic EC-based decrypter/signer
  54. type ecDecrypterSigner struct {
  55. privateKey *ecdsa.PrivateKey
  56. }
  57. type edDecrypterSigner struct {
  58. privateKey ed25519.PrivateKey
  59. }
  60. // newRSARecipient creates recipientKeyInfo based on the given key.
  61. func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) {
  62. // Verify that key management algorithm is supported by this encrypter
  63. switch keyAlg {
  64. case RSA1_5, RSA_OAEP, RSA_OAEP_256:
  65. default:
  66. return recipientKeyInfo{}, ErrUnsupportedAlgorithm
  67. }
  68. if publicKey == nil {
  69. return recipientKeyInfo{}, errors.New("invalid public key")
  70. }
  71. return recipientKeyInfo{
  72. keyAlg: keyAlg,
  73. keyEncrypter: &rsaEncrypterVerifier{
  74. publicKey: publicKey,
  75. },
  76. }, nil
  77. }
  78. // newRSASigner creates a recipientSigInfo based on the given key.
  79. func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) {
  80. // Verify that key management algorithm is supported by this encrypter
  81. switch sigAlg {
  82. case RS256, RS384, RS512, PS256, PS384, PS512:
  83. default:
  84. return recipientSigInfo{}, ErrUnsupportedAlgorithm
  85. }
  86. if privateKey == nil {
  87. return recipientSigInfo{}, errors.New("invalid private key")
  88. }
  89. return recipientSigInfo{
  90. sigAlg: sigAlg,
  91. publicKey: staticPublicKey(&JSONWebKey{
  92. Key: privateKey.Public(),
  93. }),
  94. signer: &rsaDecrypterSigner{
  95. privateKey: privateKey,
  96. },
  97. }, nil
  98. }
  99. func newEd25519Signer(sigAlg SignatureAlgorithm, privateKey ed25519.PrivateKey) (recipientSigInfo, error) {
  100. if sigAlg != EdDSA {
  101. return recipientSigInfo{}, ErrUnsupportedAlgorithm
  102. }
  103. if privateKey == nil {
  104. return recipientSigInfo{}, errors.New("invalid private key")
  105. }
  106. return recipientSigInfo{
  107. sigAlg: sigAlg,
  108. publicKey: staticPublicKey(&JSONWebKey{
  109. Key: privateKey.Public(),
  110. }),
  111. signer: &edDecrypterSigner{
  112. privateKey: privateKey,
  113. },
  114. }, nil
  115. }
  116. // newECDHRecipient creates recipientKeyInfo based on the given key.
  117. func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) {
  118. // Verify that key management algorithm is supported by this encrypter
  119. switch keyAlg {
  120. case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
  121. default:
  122. return recipientKeyInfo{}, ErrUnsupportedAlgorithm
  123. }
  124. if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
  125. return recipientKeyInfo{}, errors.New("invalid public key")
  126. }
  127. return recipientKeyInfo{
  128. keyAlg: keyAlg,
  129. keyEncrypter: &ecEncrypterVerifier{
  130. publicKey: publicKey,
  131. },
  132. }, nil
  133. }
  134. // newECDSASigner creates a recipientSigInfo based on the given key.
  135. func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) {
  136. // Verify that key management algorithm is supported by this encrypter
  137. switch sigAlg {
  138. case ES256, ES384, ES512:
  139. default:
  140. return recipientSigInfo{}, ErrUnsupportedAlgorithm
  141. }
  142. if privateKey == nil {
  143. return recipientSigInfo{}, errors.New("invalid private key")
  144. }
  145. return recipientSigInfo{
  146. sigAlg: sigAlg,
  147. publicKey: staticPublicKey(&JSONWebKey{
  148. Key: privateKey.Public(),
  149. }),
  150. signer: &ecDecrypterSigner{
  151. privateKey: privateKey,
  152. },
  153. }, nil
  154. }
  155. // Encrypt the given payload and update the object.
  156. func (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
  157. encryptedKey, err := ctx.encrypt(cek, alg)
  158. if err != nil {
  159. return recipientInfo{}, err
  160. }
  161. return recipientInfo{
  162. encryptedKey: encryptedKey,
  163. header: &rawHeader{},
  164. }, nil
  165. }
  166. // Encrypt the given payload. Based on the key encryption algorithm,
  167. // this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
  168. func (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) {
  169. switch alg {
  170. case RSA1_5:
  171. return rsa.EncryptPKCS1v15(RandReader, ctx.publicKey, cek)
  172. case RSA_OAEP:
  173. return rsa.EncryptOAEP(sha1.New(), RandReader, ctx.publicKey, cek, []byte{})
  174. case RSA_OAEP_256:
  175. return rsa.EncryptOAEP(sha256.New(), RandReader, ctx.publicKey, cek, []byte{})
  176. }
  177. return nil, ErrUnsupportedAlgorithm
  178. }
  179. // Decrypt the given payload and return the content encryption key.
  180. func (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
  181. return ctx.decrypt(recipient.encryptedKey, headers.getAlgorithm(), generator)
  182. }
  183. // Decrypt the given payload. Based on the key encryption algorithm,
  184. // this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
  185. func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) {
  186. // Note: The random reader on decrypt operations is only used for blinding,
  187. // so stubbing is meanlingless (hence the direct use of rand.Reader).
  188. switch alg {
  189. case RSA1_5:
  190. defer func() {
  191. // DecryptPKCS1v15SessionKey sometimes panics on an invalid payload
  192. // because of an index out of bounds error, which we want to ignore.
  193. // This has been fixed in Go 1.3.1 (released 2014/08/13), the recover()
  194. // only exists for preventing crashes with unpatched versions.
  195. // See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k
  196. // See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33
  197. _ = recover()
  198. }()
  199. // Perform some input validation.
  200. keyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8
  201. if keyBytes != len(jek) {
  202. // Input size is incorrect, the encrypted payload should always match
  203. // the size of the public modulus (e.g. using a 2048 bit key will
  204. // produce 256 bytes of output). Reject this since it's invalid input.
  205. return nil, ErrCryptoFailure
  206. }
  207. cek, _, err := generator.genKey()
  208. if err != nil {
  209. return nil, ErrCryptoFailure
  210. }
  211. // When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to
  212. // prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing
  213. // the Million Message Attack on Cryptographic Message Syntax". We are
  214. // therefore deliberately ignoring errors here.
  215. _ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek)
  216. return cek, nil
  217. case RSA_OAEP:
  218. // Use rand.Reader for RSA blinding
  219. return rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{})
  220. case RSA_OAEP_256:
  221. // Use rand.Reader for RSA blinding
  222. return rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{})
  223. }
  224. return nil, ErrUnsupportedAlgorithm
  225. }
  226. // Sign the given payload
  227. func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
  228. var hash crypto.Hash
  229. switch alg {
  230. case RS256, PS256:
  231. hash = crypto.SHA256
  232. case RS384, PS384:
  233. hash = crypto.SHA384
  234. case RS512, PS512:
  235. hash = crypto.SHA512
  236. default:
  237. return Signature{}, ErrUnsupportedAlgorithm
  238. }
  239. hasher := hash.New()
  240. // According to documentation, Write() on hash never fails
  241. _, _ = hasher.Write(payload)
  242. hashed := hasher.Sum(nil)
  243. var out []byte
  244. var err error
  245. switch alg {
  246. case RS256, RS384, RS512:
  247. out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)
  248. case PS256, PS384, PS512:
  249. out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{
  250. SaltLength: rsa.PSSSaltLengthEqualsHash,
  251. })
  252. }
  253. if err != nil {
  254. return Signature{}, err
  255. }
  256. return Signature{
  257. Signature: out,
  258. protected: &rawHeader{},
  259. }, nil
  260. }
  261. // Verify the given payload
  262. func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
  263. var hash crypto.Hash
  264. switch alg {
  265. case RS256, PS256:
  266. hash = crypto.SHA256
  267. case RS384, PS384:
  268. hash = crypto.SHA384
  269. case RS512, PS512:
  270. hash = crypto.SHA512
  271. default:
  272. return ErrUnsupportedAlgorithm
  273. }
  274. hasher := hash.New()
  275. // According to documentation, Write() on hash never fails
  276. _, _ = hasher.Write(payload)
  277. hashed := hasher.Sum(nil)
  278. switch alg {
  279. case RS256, RS384, RS512:
  280. return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature)
  281. case PS256, PS384, PS512:
  282. return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil)
  283. }
  284. return ErrUnsupportedAlgorithm
  285. }
  286. // Encrypt the given payload and update the object.
  287. func (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
  288. switch alg {
  289. case ECDH_ES:
  290. // ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key.
  291. return recipientInfo{
  292. header: &rawHeader{},
  293. }, nil
  294. case ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
  295. default:
  296. return recipientInfo{}, ErrUnsupportedAlgorithm
  297. }
  298. generator := ecKeyGenerator{
  299. algID: string(alg),
  300. publicKey: ctx.publicKey,
  301. }
  302. switch alg {
  303. case ECDH_ES_A128KW:
  304. generator.size = 16
  305. case ECDH_ES_A192KW:
  306. generator.size = 24
  307. case ECDH_ES_A256KW:
  308. generator.size = 32
  309. }
  310. kek, header, err := generator.genKey()
  311. if err != nil {
  312. return recipientInfo{}, err
  313. }
  314. block, err := aes.NewCipher(kek)
  315. if err != nil {
  316. return recipientInfo{}, err
  317. }
  318. jek, err := josecipher.KeyWrap(block, cek)
  319. if err != nil {
  320. return recipientInfo{}, err
  321. }
  322. return recipientInfo{
  323. encryptedKey: jek,
  324. header: &header,
  325. }, nil
  326. }
  327. // Get key size for EC key generator
  328. func (ctx ecKeyGenerator) keySize() int {
  329. return ctx.size
  330. }
  331. // Get a content encryption key for ECDH-ES
  332. func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {
  333. priv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, RandReader)
  334. if err != nil {
  335. return nil, rawHeader{}, err
  336. }
  337. out := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size)
  338. b, err := json.Marshal(&JSONWebKey{
  339. Key: &priv.PublicKey,
  340. })
  341. if err != nil {
  342. return nil, nil, err
  343. }
  344. headers := rawHeader{
  345. headerEPK: makeRawMessage(b),
  346. }
  347. return out, headers, nil
  348. }
  349. // Decrypt the given payload and return the content encryption key.
  350. func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
  351. epk, err := headers.getEPK()
  352. if err != nil {
  353. return nil, errors.New("square/go-jose: invalid epk header")
  354. }
  355. if epk == nil {
  356. return nil, errors.New("square/go-jose: missing epk header")
  357. }
  358. publicKey, ok := epk.Key.(*ecdsa.PublicKey)
  359. if publicKey == nil || !ok {
  360. return nil, errors.New("square/go-jose: invalid epk header")
  361. }
  362. if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
  363. return nil, errors.New("square/go-jose: invalid public key in epk header")
  364. }
  365. apuData, err := headers.getAPU()
  366. if err != nil {
  367. return nil, errors.New("square/go-jose: invalid apu header")
  368. }
  369. apvData, err := headers.getAPV()
  370. if err != nil {
  371. return nil, errors.New("square/go-jose: invalid apv header")
  372. }
  373. deriveKey := func(algID string, size int) []byte {
  374. return josecipher.DeriveECDHES(algID, apuData.bytes(), apvData.bytes(), ctx.privateKey, publicKey, size)
  375. }
  376. var keySize int
  377. algorithm := headers.getAlgorithm()
  378. switch algorithm {
  379. case ECDH_ES:
  380. // ECDH-ES uses direct key agreement, no key unwrapping necessary.
  381. return deriveKey(string(headers.getEncryption()), generator.keySize()), nil
  382. case ECDH_ES_A128KW:
  383. keySize = 16
  384. case ECDH_ES_A192KW:
  385. keySize = 24
  386. case ECDH_ES_A256KW:
  387. keySize = 32
  388. default:
  389. return nil, ErrUnsupportedAlgorithm
  390. }
  391. key := deriveKey(string(algorithm), keySize)
  392. block, err := aes.NewCipher(key)
  393. if err != nil {
  394. return nil, err
  395. }
  396. return josecipher.KeyUnwrap(block, recipient.encryptedKey)
  397. }
  398. func (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
  399. if alg != EdDSA {
  400. return Signature{}, ErrUnsupportedAlgorithm
  401. }
  402. sig, err := ctx.privateKey.Sign(RandReader, payload, crypto.Hash(0))
  403. if err != nil {
  404. return Signature{}, err
  405. }
  406. return Signature{
  407. Signature: sig,
  408. protected: &rawHeader{},
  409. }, nil
  410. }
  411. func (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
  412. if alg != EdDSA {
  413. return ErrUnsupportedAlgorithm
  414. }
  415. ok := ed25519.Verify(ctx.publicKey, payload, signature)
  416. if !ok {
  417. return errors.New("square/go-jose: ed25519 signature failed to verify")
  418. }
  419. return nil
  420. }
  421. // Sign the given payload
  422. func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
  423. var expectedBitSize int
  424. var hash crypto.Hash
  425. switch alg {
  426. case ES256:
  427. expectedBitSize = 256
  428. hash = crypto.SHA256
  429. case ES384:
  430. expectedBitSize = 384
  431. hash = crypto.SHA384
  432. case ES512:
  433. expectedBitSize = 521
  434. hash = crypto.SHA512
  435. }
  436. curveBits := ctx.privateKey.Curve.Params().BitSize
  437. if expectedBitSize != curveBits {
  438. return Signature{}, fmt.Errorf("square/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits)
  439. }
  440. hasher := hash.New()
  441. // According to documentation, Write() on hash never fails
  442. _, _ = hasher.Write(payload)
  443. hashed := hasher.Sum(nil)
  444. r, s, err := ecdsa.Sign(RandReader, ctx.privateKey, hashed)
  445. if err != nil {
  446. return Signature{}, err
  447. }
  448. keyBytes := curveBits / 8
  449. if curveBits%8 > 0 {
  450. keyBytes++
  451. }
  452. // We serialize the outputs (r and s) into big-endian byte arrays and pad
  453. // them with zeros on the left to make sure the sizes work out. Both arrays
  454. // must be keyBytes long, and the output must be 2*keyBytes long.
  455. rBytes := r.Bytes()
  456. rBytesPadded := make([]byte, keyBytes)
  457. copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
  458. sBytes := s.Bytes()
  459. sBytesPadded := make([]byte, keyBytes)
  460. copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
  461. out := append(rBytesPadded, sBytesPadded...)
  462. return Signature{
  463. Signature: out,
  464. protected: &rawHeader{},
  465. }, nil
  466. }
  467. // Verify the given payload
  468. func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
  469. var keySize int
  470. var hash crypto.Hash
  471. switch alg {
  472. case ES256:
  473. keySize = 32
  474. hash = crypto.SHA256
  475. case ES384:
  476. keySize = 48
  477. hash = crypto.SHA384
  478. case ES512:
  479. keySize = 66
  480. hash = crypto.SHA512
  481. default:
  482. return ErrUnsupportedAlgorithm
  483. }
  484. if len(signature) != 2*keySize {
  485. return fmt.Errorf("square/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize)
  486. }
  487. hasher := hash.New()
  488. // According to documentation, Write() on hash never fails
  489. _, _ = hasher.Write(payload)
  490. hashed := hasher.Sum(nil)
  491. r := big.NewInt(0).SetBytes(signature[:keySize])
  492. s := big.NewInt(0).SetBytes(signature[keySize:])
  493. match := ecdsa.Verify(ctx.publicKey, hashed, r, s)
  494. if !match {
  495. return errors.New("square/go-jose: ecdsa signature failed to verify")
  496. }
  497. return nil
  498. }