1// Copyright 2010 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package tls
6
7import (
8	"crypto"
9	"crypto/ecdh"
10	"crypto/md5"
11	"crypto/rsa"
12	"crypto/sha1"
13	"crypto/x509"
14	"errors"
15	"fmt"
16	"io"
17)
18
19// A keyAgreement implements the client and server side of a TLS 1.0–1.2 key
20// agreement protocol by generating and processing key exchange messages.
21type keyAgreement interface {
22	// On the server side, the first two methods are called in order.
23
24	// In the case that the key agreement protocol doesn't use a
25	// ServerKeyExchange message, generateServerKeyExchange can return nil,
26	// nil.
27	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
28	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
29
30	// On the client side, the next two methods are called in order.
31
32	// This method may not be called if the server doesn't send a
33	// ServerKeyExchange message.
34	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
35	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
36}
37
38var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
39var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
40
41// rsaKeyAgreement implements the standard TLS key agreement where the client
42// encrypts the pre-master secret to the server's public key.
43type rsaKeyAgreement struct{}
44
45func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
46	return nil, nil
47}
48
49func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
50	if len(ckx.ciphertext) < 2 {
51		return nil, errClientKeyExchange
52	}
53	ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
54	if ciphertextLen != len(ckx.ciphertext)-2 {
55		return nil, errClientKeyExchange
56	}
57	ciphertext := ckx.ciphertext[2:]
58
59	priv, ok := cert.PrivateKey.(crypto.Decrypter)
60	if !ok {
61		return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter")
62	}
63	// Perform constant time RSA PKCS #1 v1.5 decryption
64	preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48})
65	if err != nil {
66		return nil, err
67	}
68	// We don't check the version number in the premaster secret. For one,
69	// by checking it, we would leak information about the validity of the
70	// encrypted pre-master secret. Secondly, it provides only a small
71	// benefit against a downgrade attack and some implementations send the
72	// wrong version anyway. See the discussion at the end of section
73	// 7.4.7.1 of RFC 4346.
74	return preMasterSecret, nil
75}
76
77func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
78	return errors.New("tls: unexpected ServerKeyExchange")
79}
80
81func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
82	preMasterSecret := make([]byte, 48)
83	preMasterSecret[0] = byte(clientHello.vers >> 8)
84	preMasterSecret[1] = byte(clientHello.vers)
85	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
86	if err != nil {
87		return nil, nil, err
88	}
89
90	rsaKey, ok := cert.PublicKey.(*rsa.PublicKey)
91	if !ok {
92		return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite")
93	}
94	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret)
95	if err != nil {
96		return nil, nil, err
97	}
98	ckx := new(clientKeyExchangeMsg)
99	ckx.ciphertext = make([]byte, len(encrypted)+2)
100	ckx.ciphertext[0] = byte(len(encrypted) >> 8)
101	ckx.ciphertext[1] = byte(len(encrypted))
102	copy(ckx.ciphertext[2:], encrypted)
103	return preMasterSecret, ckx, nil
104}
105
106// sha1Hash calculates a SHA1 hash over the given byte slices.
107func sha1Hash(slices [][]byte) []byte {
108	hsha1 := sha1.New()
109	for _, slice := range slices {
110		hsha1.Write(slice)
111	}
112	return hsha1.Sum(nil)
113}
114
115// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
116// concatenation of an MD5 and SHA1 hash.
117func md5SHA1Hash(slices [][]byte) []byte {
118	md5sha1 := make([]byte, md5.Size+sha1.Size)
119	hmd5 := md5.New()
120	for _, slice := range slices {
121		hmd5.Write(slice)
122	}
123	copy(md5sha1, hmd5.Sum(nil))
124	copy(md5sha1[md5.Size:], sha1Hash(slices))
125	return md5sha1
126}
127
128// hashForServerKeyExchange hashes the given slices and returns their digest
129// using the given hash function (for TLS 1.2) or using a default based on
130// the sigType (for earlier TLS versions). For Ed25519 signatures, which don't
131// do pre-hashing, it returns the concatenation of the slices.
132func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte {
133	if sigType == signatureEd25519 {
134		var signed []byte
135		for _, slice := range slices {
136			signed = append(signed, slice...)
137		}
138		return signed
139	}
140	if version >= VersionTLS12 {
141		h := hashFunc.New()
142		for _, slice := range slices {
143			h.Write(slice)
144		}
145		digest := h.Sum(nil)
146		return digest
147	}
148	if sigType == signatureECDSA {
149		return sha1Hash(slices)
150	}
151	return md5SHA1Hash(slices)
152}
153
154// ecdheKeyAgreement implements a TLS key agreement where the server
155// generates an ephemeral EC public/private key pair and signs it. The
156// pre-master secret is then calculated using ECDH. The signature may
157// be ECDSA, Ed25519 or RSA.
158type ecdheKeyAgreement struct {
159	version uint16
160	isRSA   bool
161	key     *ecdh.PrivateKey
162
163	// ckx and preMasterSecret are generated in processServerKeyExchange
164	// and returned in generateClientKeyExchange.
165	ckx             *clientKeyExchangeMsg
166	preMasterSecret []byte
167}
168
169func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
170	var curveID CurveID
171	for _, c := range clientHello.supportedCurves {
172		if config.supportsCurve(ka.version, c) {
173			curveID = c
174			break
175		}
176	}
177
178	if curveID == 0 {
179		return nil, errors.New("tls: no supported elliptic curves offered")
180	}
181	if _, ok := curveForCurveID(curveID); !ok {
182		return nil, errors.New("tls: CurvePreferences includes unsupported curve")
183	}
184
185	key, err := generateECDHEKey(config.rand(), curveID)
186	if err != nil {
187		return nil, err
188	}
189	ka.key = key
190
191	// See RFC 4492, Section 5.4.
192	ecdhePublic := key.PublicKey().Bytes()
193	serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))
194	serverECDHEParams[0] = 3 // named curve
195	serverECDHEParams[1] = byte(curveID >> 8)
196	serverECDHEParams[2] = byte(curveID)
197	serverECDHEParams[3] = byte(len(ecdhePublic))
198	copy(serverECDHEParams[4:], ecdhePublic)
199
200	priv, ok := cert.PrivateKey.(crypto.Signer)
201	if !ok {
202		return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey)
203	}
204
205	var signatureAlgorithm SignatureScheme
206	var sigType uint8
207	var sigHash crypto.Hash
208	if ka.version >= VersionTLS12 {
209		signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms)
210		if err != nil {
211			return nil, err
212		}
213		sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
214		if err != nil {
215			return nil, err
216		}
217	} else {
218		sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public())
219		if err != nil {
220			return nil, err
221		}
222	}
223	if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
224		return nil, errors.New("tls: certificate cannot be used with the selected cipher suite")
225	}
226
227	signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams)
228
229	signOpts := crypto.SignerOpts(sigHash)
230	if sigType == signatureRSAPSS {
231		signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
232	}
233	sig, err := priv.Sign(config.rand(), signed, signOpts)
234	if err != nil {
235		return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error())
236	}
237
238	skx := new(serverKeyExchangeMsg)
239	sigAndHashLen := 0
240	if ka.version >= VersionTLS12 {
241		sigAndHashLen = 2
242	}
243	skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig))
244	copy(skx.key, serverECDHEParams)
245	k := skx.key[len(serverECDHEParams):]
246	if ka.version >= VersionTLS12 {
247		k[0] = byte(signatureAlgorithm >> 8)
248		k[1] = byte(signatureAlgorithm)
249		k = k[2:]
250	}
251	k[0] = byte(len(sig) >> 8)
252	k[1] = byte(len(sig))
253	copy(k[2:], sig)
254
255	return skx, nil
256}
257
258func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
259	if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
260		return nil, errClientKeyExchange
261	}
262
263	peerKey, err := ka.key.Curve().NewPublicKey(ckx.ciphertext[1:])
264	if err != nil {
265		return nil, errClientKeyExchange
266	}
267	preMasterSecret, err := ka.key.ECDH(peerKey)
268	if err != nil {
269		return nil, errClientKeyExchange
270	}
271
272	return preMasterSecret, nil
273}
274
275func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
276	if len(skx.key) < 4 {
277		return errServerKeyExchange
278	}
279	if skx.key[0] != 3 { // named curve
280		return errors.New("tls: server selected unsupported curve")
281	}
282	curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
283
284	publicLen := int(skx.key[3])
285	if publicLen+4 > len(skx.key) {
286		return errServerKeyExchange
287	}
288	serverECDHEParams := skx.key[:4+publicLen]
289	publicKey := serverECDHEParams[4:]
290
291	sig := skx.key[4+publicLen:]
292	if len(sig) < 2 {
293		return errServerKeyExchange
294	}
295
296	if _, ok := curveForCurveID(curveID); !ok {
297		return errors.New("tls: server selected unsupported curve")
298	}
299
300	key, err := generateECDHEKey(config.rand(), curveID)
301	if err != nil {
302		return err
303	}
304	ka.key = key
305
306	peerKey, err := key.Curve().NewPublicKey(publicKey)
307	if err != nil {
308		return errServerKeyExchange
309	}
310	ka.preMasterSecret, err = key.ECDH(peerKey)
311	if err != nil {
312		return errServerKeyExchange
313	}
314
315	ourPublicKey := key.PublicKey().Bytes()
316	ka.ckx = new(clientKeyExchangeMsg)
317	ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey))
318	ka.ckx.ciphertext[0] = byte(len(ourPublicKey))
319	copy(ka.ckx.ciphertext[1:], ourPublicKey)
320
321	var sigType uint8
322	var sigHash crypto.Hash
323	if ka.version >= VersionTLS12 {
324		signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])
325		sig = sig[2:]
326		if len(sig) < 2 {
327			return errServerKeyExchange
328		}
329
330		if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) {
331			return errors.New("tls: certificate used with invalid signature algorithm")
332		}
333		sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
334		if err != nil {
335			return err
336		}
337	} else {
338		sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey)
339		if err != nil {
340			return err
341		}
342	}
343	if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
344		return errServerKeyExchange
345	}
346
347	sigLen := int(sig[0])<<8 | int(sig[1])
348	if sigLen+2 != len(sig) {
349		return errServerKeyExchange
350	}
351	sig = sig[2:]
352
353	signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams)
354	if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil {
355		return errors.New("tls: invalid signature by the server certificate: " + err.Error())
356	}
357	return nil
358}
359
360func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
361	if ka.ckx == nil {
362		return nil, nil, errors.New("tls: missing ServerKeyExchange message")
363	}
364
365	return ka.preMasterSecret, ka.ckx, nil
366}
367