blob: 5071985469ad58f02ee670899c3d4b6187da38f9 [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001// 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
Kenny Roote99801b2015-11-06 15:31:15 -08005package runner
Adam Langleyd9e397b2015-01-22 14:27:53 -08006
7import (
Adam Langleyd9e397b2015-01-22 14:27:53 -08008 "crypto/ecdsa"
9 "crypto/elliptic"
Adam Langleyd9e397b2015-01-22 14:27:53 -080010 "crypto/rsa"
Adam Langley4139edb2016-01-13 15:00:54 -080011 "crypto/subtle"
Adam Langleyd9e397b2015-01-22 14:27:53 -080012 "crypto/x509"
Adam Langleyd9e397b2015-01-22 14:27:53 -080013 "errors"
Adam Langley4139edb2016-01-13 15:00:54 -080014 "fmt"
Adam Langleyd9e397b2015-01-22 14:27:53 -080015 "io"
16 "math/big"
Adam Langley4139edb2016-01-13 15:00:54 -080017
18 "./curve25519"
Robert Sloan572a4e22017-04-17 10:52:19 -070019 "./ed25519"
Adam Langleyd9e397b2015-01-22 14:27:53 -080020)
21
David Benjaminc895d6b2016-08-11 13:26:41 -040022type keyType int
23
24const (
25 keyTypeRSA keyType = iota + 1
26 keyTypeECDSA
27)
28
Adam Langleyd9e397b2015-01-22 14:27:53 -080029var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
30var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
31
32// rsaKeyAgreement implements the standard TLS key agreement where the client
33// encrypts the pre-master secret to the server's public key.
34type rsaKeyAgreement struct {
Adam Langleye9ada862015-05-11 17:20:37 -070035 version uint16
Adam Langleyd9e397b2015-01-22 14:27:53 -080036 clientVersion uint16
Adam Langleye9ada862015-05-11 17:20:37 -070037 exportKey *rsa.PrivateKey
Adam Langleyd9e397b2015-01-22 14:27:53 -080038}
39
40func (ka *rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
41 // Save the client version for comparison later.
Steven Valdezbb1ceac2016-10-07 10:34:51 -040042 ka.clientVersion = clientHello.vers
Adam Langleyd9e397b2015-01-22 14:27:53 -080043
Adam Langleye9ada862015-05-11 17:20:37 -070044 if !config.Bugs.RSAEphemeralKey {
45 return nil, nil
Adam Langleyd9e397b2015-01-22 14:27:53 -080046 }
47
Adam Langleye9ada862015-05-11 17:20:37 -070048 // Generate an ephemeral RSA key to use instead of the real
49 // one, as in RSA_EXPORT.
50 key, err := rsa.GenerateKey(config.rand(), 512)
51 if err != nil {
52 return nil, err
53 }
54 ka.exportKey = key
55
56 modulus := key.N.Bytes()
57 exponent := big.NewInt(int64(key.E)).Bytes()
58 serverRSAParams := make([]byte, 0, 2+len(modulus)+2+len(exponent))
59 serverRSAParams = append(serverRSAParams, byte(len(modulus)>>8), byte(len(modulus)))
60 serverRSAParams = append(serverRSAParams, modulus...)
61 serverRSAParams = append(serverRSAParams, byte(len(exponent)>>8), byte(len(exponent)))
62 serverRSAParams = append(serverRSAParams, exponent...)
63
David Benjaminc895d6b2016-08-11 13:26:41 -040064 var sigAlg signatureAlgorithm
Adam Langleye9ada862015-05-11 17:20:37 -070065 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -040066 sigAlg, err = selectSignatureAlgorithm(ka.version, cert.PrivateKey, config, clientHello.signatureAlgorithms)
67 if err != nil {
Adam Langleye9ada862015-05-11 17:20:37 -070068 return nil, err
69 }
70 }
71
David Benjaminc895d6b2016-08-11 13:26:41 -040072 sig, err := signMessage(ka.version, cert.PrivateKey, config, sigAlg, serverRSAParams)
Adam Langleye9ada862015-05-11 17:20:37 -070073 if err != nil {
74 return nil, errors.New("failed to sign RSA parameters: " + err.Error())
75 }
76
77 skx := new(serverKeyExchangeMsg)
David Benjaminc895d6b2016-08-11 13:26:41 -040078 sigAlgsLen := 0
Adam Langleye9ada862015-05-11 17:20:37 -070079 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -040080 sigAlgsLen = 2
Adam Langleye9ada862015-05-11 17:20:37 -070081 }
David Benjaminc895d6b2016-08-11 13:26:41 -040082 skx.key = make([]byte, len(serverRSAParams)+sigAlgsLen+2+len(sig))
Adam Langleye9ada862015-05-11 17:20:37 -070083 copy(skx.key, serverRSAParams)
84 k := skx.key[len(serverRSAParams):]
85 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -040086 k[0] = byte(sigAlg >> 8)
87 k[1] = byte(sigAlg)
Adam Langleye9ada862015-05-11 17:20:37 -070088 k = k[2:]
89 }
90 k[0] = byte(len(sig) >> 8)
91 k[1] = byte(len(sig))
92 copy(k[2:], sig)
93
94 return skx, nil
Adam Langleyd9e397b2015-01-22 14:27:53 -080095}
96
97func (ka *rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
98 preMasterSecret := make([]byte, 48)
99 _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
100 if err != nil {
101 return nil, err
102 }
103
104 if len(ckx.ciphertext) < 2 {
105 return nil, errClientKeyExchange
106 }
107
108 ciphertext := ckx.ciphertext
109 if version != VersionSSL30 {
110 ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
111 if ciphertextLen != len(ckx.ciphertext)-2 {
112 return nil, errClientKeyExchange
113 }
114 ciphertext = ckx.ciphertext[2:]
115 }
116
Adam Langleye9ada862015-05-11 17:20:37 -0700117 key := cert.PrivateKey.(*rsa.PrivateKey)
118 if ka.exportKey != nil {
119 key = ka.exportKey
120 }
121 err = rsa.DecryptPKCS1v15SessionKey(config.rand(), key, ciphertext, preMasterSecret)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800122 if err != nil {
123 return nil, err
124 }
125 // This check should be done in constant-time, but this is a testing
126 // implementation. See the discussion at the end of section 7.4.7.1 of
127 // RFC 4346.
128 vers := uint16(preMasterSecret[0])<<8 | uint16(preMasterSecret[1])
129 if ka.clientVersion != vers {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400130 return nil, fmt.Errorf("tls: invalid version in RSA premaster (got %04x, wanted %04x)", vers, ka.clientVersion)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800131 }
132 return preMasterSecret, nil
133}
134
135func (ka *rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
136 return errors.New("tls: unexpected ServerKeyExchange")
137}
138
Robert Sloan921ef2c2017-10-17 09:02:20 -0700139func rsaSize(pub *rsa.PublicKey) int {
140 return (pub.N.BitLen() + 7) / 8
141}
142
143func rsaRawEncrypt(pub *rsa.PublicKey, msg []byte) ([]byte, error) {
144 k := rsaSize(pub)
145 if len(msg) != k {
146 return nil, errors.New("tls: bad padded RSA input")
147 }
148 m := new(big.Int).SetBytes(msg)
149 e := big.NewInt(int64(pub.E))
150 m.Exp(m, e, pub.N)
151 unpadded := m.Bytes()
152 ret := make([]byte, k)
153 copy(ret[len(ret)-len(unpadded):], unpadded)
154 return ret, nil
155}
156
157// nonZeroRandomBytes fills the given slice with non-zero random octets.
158func nonZeroRandomBytes(s []byte, rand io.Reader) {
159 if _, err := io.ReadFull(rand, s); err != nil {
160 panic(err)
161 }
162
163 for i := range s {
164 for s[i] == 0 {
165 if _, err := io.ReadFull(rand, s[i:i+1]); err != nil {
166 panic(err)
167 }
168 }
169 }
170}
171
Adam Langleyd9e397b2015-01-22 14:27:53 -0800172func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800173 bad := config.Bugs.BadRSAClientKeyExchange
Adam Langleyd9e397b2015-01-22 14:27:53 -0800174 preMasterSecret := make([]byte, 48)
175 vers := clientHello.vers
Robert Sloan921ef2c2017-10-17 09:02:20 -0700176 if bad == RSABadValueWrongVersion1 {
Adam Langley4139edb2016-01-13 15:00:54 -0800177 vers ^= 1
Robert Sloan921ef2c2017-10-17 09:02:20 -0700178 } else if bad == RSABadValueWrongVersion2 {
179 vers ^= 0x100
Adam Langleyd9e397b2015-01-22 14:27:53 -0800180 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800181 preMasterSecret[0] = byte(vers >> 8)
182 preMasterSecret[1] = byte(vers)
183 _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
184 if err != nil {
185 return nil, nil, err
186 }
187
Adam Langley4139edb2016-01-13 15:00:54 -0800188 sentPreMasterSecret := preMasterSecret
189 if bad == RSABadValueTooLong {
Robert Sloan921ef2c2017-10-17 09:02:20 -0700190 sentPreMasterSecret = make([]byte, 1, len(sentPreMasterSecret)+1)
191 sentPreMasterSecret = append(sentPreMasterSecret, preMasterSecret...)
Adam Langley4139edb2016-01-13 15:00:54 -0800192 } else if bad == RSABadValueTooShort {
193 sentPreMasterSecret = sentPreMasterSecret[:len(sentPreMasterSecret)-1]
194 }
195
Robert Sloan921ef2c2017-10-17 09:02:20 -0700196 // Pad for PKCS#1 v1.5.
197 padded := make([]byte, rsaSize(cert.PublicKey.(*rsa.PublicKey)))
198 padded[1] = 2
199 nonZeroRandomBytes(padded[2:len(padded)-len(sentPreMasterSecret)-1], config.rand())
200 copy(padded[len(padded)-len(sentPreMasterSecret):], sentPreMasterSecret)
201
202 if bad == RSABadValueWrongBlockType {
203 padded[1] = 3
204 } else if bad == RSABadValueWrongLeadingByte {
205 padded[0] = 1
206 } else if bad == RSABadValueNoZero {
207 for i := 2; i < len(padded); i++ {
208 if padded[i] == 0 {
209 padded[i]++
210 }
211 }
212 }
213
214 encrypted, err := rsaRawEncrypt(cert.PublicKey.(*rsa.PublicKey), padded)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800215 if err != nil {
216 return nil, nil, err
217 }
Adam Langley4139edb2016-01-13 15:00:54 -0800218 if bad == RSABadValueCorrupt {
219 encrypted[len(encrypted)-1] ^= 1
220 // Clear the high byte to ensure |encrypted| is still below the RSA modulus.
221 encrypted[0] = 0
222 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800223 ckx := new(clientKeyExchangeMsg)
Robert Sloan8ecb7cd2017-03-21 09:39:01 -0700224 if ka.version != VersionSSL30 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800225 ckx.ciphertext = make([]byte, len(encrypted)+2)
226 ckx.ciphertext[0] = byte(len(encrypted) >> 8)
227 ckx.ciphertext[1] = byte(len(encrypted))
228 copy(ckx.ciphertext[2:], encrypted)
229 } else {
230 ckx.ciphertext = encrypted
231 }
232 return preMasterSecret, ckx, nil
233}
234
David Benjaminc895d6b2016-08-11 13:26:41 -0400235func (ka *rsaKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
236 return 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800237}
238
Adam Langley4139edb2016-01-13 15:00:54 -0800239// A ecdhCurve is an instance of ECDH-style key agreement for TLS.
240type ecdhCurve interface {
David Benjamind316cba2016-06-02 16:17:39 -0400241 // offer generates a keypair using rand. It returns the encoded |publicKey|.
242 offer(rand io.Reader) (publicKey []byte, err error)
Adam Langley4139edb2016-01-13 15:00:54 -0800243
David Benjamind316cba2016-06-02 16:17:39 -0400244 // accept responds to the |peerKey| generated by |offer| with the acceptor's
245 // |publicKey|, and returns agreed-upon |preMasterSecret| to the acceptor.
246 accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error)
247
248 // finish returns the computed |preMasterSecret|, given the |peerKey|
249 // generated by |accept|.
250 finish(peerKey []byte) (preMasterSecret []byte, err error)
Adam Langley4139edb2016-01-13 15:00:54 -0800251}
252
253// ellipticECDHCurve implements ecdhCurve with an elliptic.Curve.
254type ellipticECDHCurve struct {
255 curve elliptic.Curve
256 privateKey []byte
257}
258
David Benjamind316cba2016-06-02 16:17:39 -0400259func (e *ellipticECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800260 var x, y *big.Int
261 e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand)
262 if err != nil {
263 return nil, err
264 }
265 return elliptic.Marshal(e.curve, x, y), nil
266}
267
David Benjamind316cba2016-06-02 16:17:39 -0400268func (e *ellipticECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
269 publicKey, err = e.offer(rand)
270 if err != nil {
271 return nil, nil, err
272 }
273 preMasterSecret, err = e.finish(peerKey)
274 if err != nil {
275 return nil, nil, err
276 }
277 return
278}
279
280func (e *ellipticECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800281 x, y := elliptic.Unmarshal(e.curve, peerKey)
282 if x == nil {
283 return nil, errors.New("tls: invalid peer key")
284 }
285 x, _ = e.curve.ScalarMult(x, y, e.privateKey)
286 preMasterSecret = make([]byte, (e.curve.Params().BitSize+7)>>3)
287 xBytes := x.Bytes()
288 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
289
290 return preMasterSecret, nil
291}
292
293// x25519ECDHCurve implements ecdhCurve with X25519.
294type x25519ECDHCurve struct {
295 privateKey [32]byte
296}
297
David Benjamind316cba2016-06-02 16:17:39 -0400298func (e *x25519ECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800299 _, err = io.ReadFull(rand, e.privateKey[:])
300 if err != nil {
301 return
302 }
303 var out [32]byte
304 curve25519.ScalarBaseMult(&out, &e.privateKey)
305 return out[:], nil
306}
307
David Benjamind316cba2016-06-02 16:17:39 -0400308func (e *x25519ECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
309 publicKey, err = e.offer(rand)
310 if err != nil {
311 return nil, nil, err
312 }
313 preMasterSecret, err = e.finish(peerKey)
314 if err != nil {
315 return nil, nil, err
316 }
317 return
318}
319
320func (e *x25519ECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800321 if len(peerKey) != 32 {
322 return nil, errors.New("tls: invalid peer key")
323 }
324 var out, peerKeyCopy [32]byte
325 copy(peerKeyCopy[:], peerKey)
326 curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy)
327
David Benjamin4969cc92016-04-22 15:02:23 -0400328 // Per RFC 7748, reject the all-zero value in constant time.
Adam Langley4139edb2016-01-13 15:00:54 -0800329 var zeros [32]byte
330 if subtle.ConstantTimeCompare(zeros[:], out[:]) == 1 {
331 return nil, errors.New("tls: X25519 value with wrong order")
332 }
333
334 return out[:], nil
335}
336
337func curveForCurveID(id CurveID) (ecdhCurve, bool) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800338 switch id {
Adam Langleye9ada862015-05-11 17:20:37 -0700339 case CurveP224:
Adam Langley4139edb2016-01-13 15:00:54 -0800340 return &ellipticECDHCurve{curve: elliptic.P224()}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800341 case CurveP256:
Adam Langley4139edb2016-01-13 15:00:54 -0800342 return &ellipticECDHCurve{curve: elliptic.P256()}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800343 case CurveP384:
Adam Langley4139edb2016-01-13 15:00:54 -0800344 return &ellipticECDHCurve{curve: elliptic.P384()}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800345 case CurveP521:
Adam Langley4139edb2016-01-13 15:00:54 -0800346 return &ellipticECDHCurve{curve: elliptic.P521()}, true
347 case CurveX25519:
348 return &x25519ECDHCurve{}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800349 default:
350 return nil, false
351 }
352
353}
354
355// keyAgreementAuthentication is a helper interface that specifies how
356// to authenticate the ServerKeyExchange parameters.
357type keyAgreementAuthentication interface {
358 signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error)
359 verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error
360}
361
362// nilKeyAgreementAuthentication does not authenticate the key
363// agreement parameters.
364type nilKeyAgreementAuthentication struct{}
365
366func (ka *nilKeyAgreementAuthentication) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
367 skx := new(serverKeyExchangeMsg)
368 skx.key = params
369 return skx, nil
370}
371
372func (ka *nilKeyAgreementAuthentication) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error {
373 return nil
374}
375
376// signedKeyAgreement signs the ServerKeyExchange parameters with the
377// server's private key.
378type signedKeyAgreement struct {
David Benjaminc895d6b2016-08-11 13:26:41 -0400379 keyType keyType
380 version uint16
381 peerSignatureAlgorithm signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800382}
383
384func (ka *signedKeyAgreement) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400385 // The message to be signed is prepended by the randoms.
386 var msg []byte
387 msg = append(msg, clientHello.random...)
388 msg = append(msg, hello.random...)
389 msg = append(msg, params...)
390
391 var sigAlg signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800392 var err error
393 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400394 sigAlg, err = selectSignatureAlgorithm(ka.version, cert.PrivateKey, config, clientHello.signatureAlgorithms)
395 if err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800396 return nil, err
397 }
398 }
399
David Benjaminc895d6b2016-08-11 13:26:41 -0400400 sig, err := signMessage(ka.version, cert.PrivateKey, config, sigAlg, msg)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800401 if err != nil {
402 return nil, err
403 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400404 if config.Bugs.SendSignatureAlgorithm != 0 {
405 sigAlg = config.Bugs.SendSignatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800406 }
407
408 skx := new(serverKeyExchangeMsg)
409 if config.Bugs.UnauthenticatedECDH {
410 skx.key = params
411 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400412 sigAlgsLen := 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800413 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400414 sigAlgsLen = 2
Adam Langleyd9e397b2015-01-22 14:27:53 -0800415 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400416 skx.key = make([]byte, len(params)+sigAlgsLen+2+len(sig))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800417 copy(skx.key, params)
418 k := skx.key[len(params):]
419 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400420 k[0] = byte(sigAlg >> 8)
421 k[1] = byte(sigAlg)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800422 k = k[2:]
423 }
424 k[0] = byte(len(sig) >> 8)
425 k[1] = byte(len(sig))
426 copy(k[2:], sig)
427 }
428
429 return skx, nil
430}
431
432func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error {
David Benjaminc895d6b2016-08-11 13:26:41 -0400433 // The peer's key must match the cipher type.
Robert Sloan572a4e22017-04-17 10:52:19 -0700434 publicKey := getCertificatePublicKey(cert)
David Benjaminc895d6b2016-08-11 13:26:41 -0400435 switch ka.keyType {
436 case keyTypeECDSA:
Robert Sloan572a4e22017-04-17 10:52:19 -0700437 _, edsaOk := publicKey.(*ecdsa.PublicKey)
438 _, ed25519Ok := publicKey.(ed25519.PublicKey)
439 if !edsaOk && !ed25519Ok {
440 return errors.New("tls: ECDHE ECDSA requires a ECDSA or Ed25519 server public key")
David Benjaminc895d6b2016-08-11 13:26:41 -0400441 }
442 case keyTypeRSA:
Robert Sloan572a4e22017-04-17 10:52:19 -0700443 _, ok := publicKey.(*rsa.PublicKey)
David Benjaminc895d6b2016-08-11 13:26:41 -0400444 if !ok {
445 return errors.New("tls: ECDHE RSA requires a RSA server public key")
446 }
447 default:
448 return errors.New("tls: unknown key type")
Adam Langleyd9e397b2015-01-22 14:27:53 -0800449 }
450
David Benjaminc895d6b2016-08-11 13:26:41 -0400451 // The message to be signed is prepended by the randoms.
452 var msg []byte
453 msg = append(msg, clientHello.random...)
454 msg = append(msg, serverHello.random...)
455 msg = append(msg, params...)
456
457 var sigAlg signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800458 if ka.version >= VersionTLS12 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800459 if len(sig) < 2 {
460 return errServerKeyExchange
461 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400462 sigAlg = signatureAlgorithm(sig[0])<<8 | signatureAlgorithm(sig[1])
463 sig = sig[2:]
464 // Stash the signature algorithm to be extracted by the handshake.
465 ka.peerSignatureAlgorithm = sigAlg
466 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800467
David Benjaminc895d6b2016-08-11 13:26:41 -0400468 if len(sig) < 2 {
469 return errServerKeyExchange
Adam Langleyd9e397b2015-01-22 14:27:53 -0800470 }
471 sigLen := int(sig[0])<<8 | int(sig[1])
472 if sigLen+2 != len(sig) {
473 return errServerKeyExchange
474 }
475 sig = sig[2:]
476
Robert Sloan572a4e22017-04-17 10:52:19 -0700477 return verifyMessage(ka.version, publicKey, config, sigAlg, msg, sig)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800478}
479
David Benjaminc895d6b2016-08-11 13:26:41 -0400480// ecdheKeyAgreement implements a TLS key agreement where the server
Adam Langleyd9e397b2015-01-22 14:27:53 -0800481// generates a ephemeral EC public/private key pair and signs it. The
482// pre-master secret is then calculated using ECDH. The signature may
483// either be ECDSA or RSA.
484type ecdheKeyAgreement struct {
Adam Langley4139edb2016-01-13 15:00:54 -0800485 auth keyAgreementAuthentication
486 curve ecdhCurve
David Benjaminc895d6b2016-08-11 13:26:41 -0400487 curveID CurveID
Adam Langley4139edb2016-01-13 15:00:54 -0800488 peerKey []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -0800489}
490
491func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
492 var curveid CurveID
493 preferredCurves := config.curvePreferences()
494
495NextCandidate:
496 for _, candidate := range preferredCurves {
497 for _, c := range clientHello.supportedCurves {
498 if candidate == c {
499 curveid = c
500 break NextCandidate
501 }
502 }
503 }
504
505 if curveid == 0 {
506 return nil, errors.New("tls: no supported elliptic curves offered")
507 }
508
509 var ok bool
510 if ka.curve, ok = curveForCurveID(curveid); !ok {
511 return nil, errors.New("tls: preferredCurves includes unsupported curve")
512 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400513 ka.curveID = curveid
Adam Langleyd9e397b2015-01-22 14:27:53 -0800514
David Benjamind316cba2016-06-02 16:17:39 -0400515 publicKey, err := ka.curve.offer(config.rand())
Adam Langleyd9e397b2015-01-22 14:27:53 -0800516 if err != nil {
517 return nil, err
518 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800519
520 // http://tools.ietf.org/html/rfc4492#section-5.4
Adam Langley4139edb2016-01-13 15:00:54 -0800521 serverECDHParams := make([]byte, 1+2+1+len(publicKey))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800522 serverECDHParams[0] = 3 // named curve
David Benjaminc895d6b2016-08-11 13:26:41 -0400523 if config.Bugs.SendCurve != 0 {
524 curveid = config.Bugs.SendCurve
525 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800526 serverECDHParams[1] = byte(curveid >> 8)
527 serverECDHParams[2] = byte(curveid)
Adam Langley4139edb2016-01-13 15:00:54 -0800528 serverECDHParams[3] = byte(len(publicKey))
529 copy(serverECDHParams[4:], publicKey)
David Benjamin4969cc92016-04-22 15:02:23 -0400530 if config.Bugs.InvalidECDHPoint {
531 serverECDHParams[4] ^= 0xff
532 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800533
534 return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
535}
536
537func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
538 if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
539 return nil, errClientKeyExchange
540 }
David Benjamind316cba2016-06-02 16:17:39 -0400541 return ka.curve.finish(ckx.ciphertext[1:])
Adam Langleyd9e397b2015-01-22 14:27:53 -0800542}
543
544func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
545 if len(skx.key) < 4 {
546 return errServerKeyExchange
547 }
548 if skx.key[0] != 3 { // named curve
549 return errors.New("tls: server selected unsupported curve")
550 }
551 curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
David Benjaminc895d6b2016-08-11 13:26:41 -0400552 ka.curveID = curveid
Adam Langleyd9e397b2015-01-22 14:27:53 -0800553
554 var ok bool
555 if ka.curve, ok = curveForCurveID(curveid); !ok {
556 return errors.New("tls: server selected unsupported curve")
557 }
558
559 publicLen := int(skx.key[3])
560 if publicLen+4 > len(skx.key) {
561 return errServerKeyExchange
562 }
Adam Langley4139edb2016-01-13 15:00:54 -0800563 // Save the peer key for later.
564 ka.peerKey = skx.key[4 : 4+publicLen]
565
566 // Check the signature.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800567 serverECDHParams := skx.key[:4+publicLen]
568 sig := skx.key[4+publicLen:]
Adam Langleyd9e397b2015-01-22 14:27:53 -0800569 return ka.auth.verifyParameters(config, clientHello, serverHello, cert, serverECDHParams, sig)
570}
571
572func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
573 if ka.curve == nil {
574 return nil, nil, errors.New("missing ServerKeyExchange message")
575 }
Adam Langley4139edb2016-01-13 15:00:54 -0800576
David Benjamind316cba2016-06-02 16:17:39 -0400577 publicKey, preMasterSecret, err := ka.curve.accept(config.rand(), ka.peerKey)
Adam Langley4139edb2016-01-13 15:00:54 -0800578 if err != nil {
579 return nil, nil, err
580 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800581
582 ckx := new(clientKeyExchangeMsg)
Adam Langley4139edb2016-01-13 15:00:54 -0800583 ckx.ciphertext = make([]byte, 1+len(publicKey))
584 ckx.ciphertext[0] = byte(len(publicKey))
585 copy(ckx.ciphertext[1:], publicKey)
David Benjamin4969cc92016-04-22 15:02:23 -0400586 if config.Bugs.InvalidECDHPoint {
587 ckx.ciphertext[1] ^= 0xff
588 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800589
590 return preMasterSecret, ckx, nil
591}
592
David Benjaminc895d6b2016-08-11 13:26:41 -0400593func (ka *ecdheKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
594 if auth, ok := ka.auth.(*signedKeyAgreement); ok {
595 return auth.peerSignatureAlgorithm
596 }
597 return 0
598}
599
Adam Langleyd9e397b2015-01-22 14:27:53 -0800600// nilKeyAgreement is a fake key agreement used to implement the plain PSK key
601// exchange.
602type nilKeyAgreement struct{}
603
604func (ka *nilKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
605 return nil, nil
606}
607
608func (ka *nilKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
609 if len(ckx.ciphertext) != 0 {
610 return nil, errClientKeyExchange
611 }
612
613 // Although in plain PSK, otherSecret is all zeros, the base key
614 // agreement does not access to the length of the pre-shared
615 // key. pskKeyAgreement instead interprets nil to mean to use all zeros
616 // of the appropriate length.
617 return nil, nil
618}
619
620func (ka *nilKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
621 if len(skx.key) != 0 {
622 return errServerKeyExchange
623 }
624 return nil
625}
626
627func (ka *nilKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
628 // Although in plain PSK, otherSecret is all zeros, the base key
629 // agreement does not access to the length of the pre-shared
630 // key. pskKeyAgreement instead interprets nil to mean to use all zeros
631 // of the appropriate length.
632 return nil, &clientKeyExchangeMsg{}, nil
633}
634
David Benjaminc895d6b2016-08-11 13:26:41 -0400635func (ka *nilKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
636 return 0
637}
638
Adam Langleyd9e397b2015-01-22 14:27:53 -0800639// makePSKPremaster formats a PSK pre-master secret based on otherSecret from
640// the base key exchange and psk.
641func makePSKPremaster(otherSecret, psk []byte) []byte {
642 out := make([]byte, 0, 2+len(otherSecret)+2+len(psk))
643 out = append(out, byte(len(otherSecret)>>8), byte(len(otherSecret)))
644 out = append(out, otherSecret...)
645 out = append(out, byte(len(psk)>>8), byte(len(psk)))
646 out = append(out, psk...)
647 return out
648}
649
650// pskKeyAgreement implements the PSK key agreement.
651type pskKeyAgreement struct {
652 base keyAgreement
653 identityHint string
654}
655
656func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
657 // Assemble the identity hint.
658 bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
659 bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
660 bytes[1] = byte(len(config.PreSharedKeyIdentity))
661 copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
662
663 // If there is one, append the base key agreement's
664 // ServerKeyExchange.
665 baseSkx, err := ka.base.generateServerKeyExchange(config, cert, clientHello, hello)
666 if err != nil {
667 return nil, err
668 }
669
670 if baseSkx != nil {
671 bytes = append(bytes, baseSkx.key...)
David Benjamin7c0d06c2016-08-11 13:26:41 -0400672 } else if config.PreSharedKeyIdentity == "" && !config.Bugs.AlwaysSendPreSharedKeyIdentityHint {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800673 // ServerKeyExchange is optional if the identity hint is empty
674 // and there would otherwise be no ServerKeyExchange.
675 return nil, nil
676 }
677
678 skx := new(serverKeyExchangeMsg)
679 skx.key = bytes
680 return skx, nil
681}
682
683func (ka *pskKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
684 // First, process the PSK identity.
685 if len(ckx.ciphertext) < 2 {
686 return nil, errClientKeyExchange
687 }
688 identityLen := (int(ckx.ciphertext[0]) << 8) | int(ckx.ciphertext[1])
689 if 2+identityLen > len(ckx.ciphertext) {
690 return nil, errClientKeyExchange
691 }
692 identity := string(ckx.ciphertext[2 : 2+identityLen])
693
694 if identity != config.PreSharedKeyIdentity {
695 return nil, errors.New("tls: unexpected identity")
696 }
697
698 if config.PreSharedKey == nil {
699 return nil, errors.New("tls: pre-shared key not configured")
700 }
701
702 // Process the remainder of the ClientKeyExchange to compute the base
703 // pre-master secret.
704 newCkx := new(clientKeyExchangeMsg)
705 newCkx.ciphertext = ckx.ciphertext[2+identityLen:]
706 otherSecret, err := ka.base.processClientKeyExchange(config, cert, newCkx, version)
707 if err != nil {
708 return nil, err
709 }
710
711 if otherSecret == nil {
712 // Special-case for the plain PSK key exchanges.
713 otherSecret = make([]byte, len(config.PreSharedKey))
714 }
715 return makePSKPremaster(otherSecret, config.PreSharedKey), nil
716}
717
718func (ka *pskKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
719 if len(skx.key) < 2 {
720 return errServerKeyExchange
721 }
722 identityLen := (int(skx.key[0]) << 8) | int(skx.key[1])
723 if 2+identityLen > len(skx.key) {
724 return errServerKeyExchange
725 }
726 ka.identityHint = string(skx.key[2 : 2+identityLen])
727
728 // Process the remainder of the ServerKeyExchange.
729 newSkx := new(serverKeyExchangeMsg)
730 newSkx.key = skx.key[2+identityLen:]
731 return ka.base.processServerKeyExchange(config, clientHello, serverHello, cert, newSkx)
732}
733
734func (ka *pskKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
735 // The server only sends an identity hint but, for purposes of
736 // test code, the server always sends the hint and it is
737 // required to match.
738 if ka.identityHint != config.PreSharedKeyIdentity {
739 return nil, nil, errors.New("tls: unexpected identity")
740 }
741
742 // Serialize the identity.
743 bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
744 bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
745 bytes[1] = byte(len(config.PreSharedKeyIdentity))
746 copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
747
748 // Append the base key exchange's ClientKeyExchange.
749 otherSecret, baseCkx, err := ka.base.generateClientKeyExchange(config, clientHello, cert)
750 if err != nil {
751 return nil, nil, err
752 }
753 ckx := new(clientKeyExchangeMsg)
754 ckx.ciphertext = append(bytes, baseCkx.ciphertext...)
755
756 if config.PreSharedKey == nil {
757 return nil, nil, errors.New("tls: pre-shared key not configured")
758 }
759 if otherSecret == nil {
760 otherSecret = make([]byte, len(config.PreSharedKey))
761 }
762 return makePSKPremaster(otherSecret, config.PreSharedKey), ckx, nil
763}
David Benjaminc895d6b2016-08-11 13:26:41 -0400764
765func (ka *pskKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
766 return 0
767}