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