blob: 1b4dfc4ccbaaeefe1e04b5a0bf9e0ea3baa553a7 [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 {
Robert Sloanab8b8882018-03-26 11:39:51 -0700255 curve elliptic.Curve
256 privateKey []byte
257 sendCompressed bool
Adam Langley4139edb2016-01-13 15:00:54 -0800258}
259
David Benjamind316cba2016-06-02 16:17:39 -0400260func (e *ellipticECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800261 var x, y *big.Int
262 e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand)
263 if err != nil {
264 return nil, err
265 }
Robert Sloanab8b8882018-03-26 11:39:51 -0700266 ret := elliptic.Marshal(e.curve, x, y)
267 if e.sendCompressed {
268 l := (len(ret) - 1) / 2
269 tmp := make([]byte, 1+l)
270 tmp[0] = byte(2 | y.Bit(0))
271 copy(tmp[1:], ret[1:1+l])
272 ret = tmp
273 }
274 return ret, nil
Adam Langley4139edb2016-01-13 15:00:54 -0800275}
276
David Benjamind316cba2016-06-02 16:17:39 -0400277func (e *ellipticECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
278 publicKey, err = e.offer(rand)
279 if err != nil {
280 return nil, nil, err
281 }
282 preMasterSecret, err = e.finish(peerKey)
283 if err != nil {
284 return nil, nil, err
285 }
286 return
287}
288
289func (e *ellipticECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800290 x, y := elliptic.Unmarshal(e.curve, peerKey)
291 if x == nil {
292 return nil, errors.New("tls: invalid peer key")
293 }
294 x, _ = e.curve.ScalarMult(x, y, e.privateKey)
295 preMasterSecret = make([]byte, (e.curve.Params().BitSize+7)>>3)
296 xBytes := x.Bytes()
297 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
298
299 return preMasterSecret, nil
300}
301
302// x25519ECDHCurve implements ecdhCurve with X25519.
303type x25519ECDHCurve struct {
304 privateKey [32]byte
305}
306
David Benjamind316cba2016-06-02 16:17:39 -0400307func (e *x25519ECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800308 _, err = io.ReadFull(rand, e.privateKey[:])
309 if err != nil {
310 return
311 }
312 var out [32]byte
313 curve25519.ScalarBaseMult(&out, &e.privateKey)
314 return out[:], nil
315}
316
David Benjamind316cba2016-06-02 16:17:39 -0400317func (e *x25519ECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
318 publicKey, err = e.offer(rand)
319 if err != nil {
320 return nil, nil, err
321 }
322 preMasterSecret, err = e.finish(peerKey)
323 if err != nil {
324 return nil, nil, err
325 }
326 return
327}
328
329func (e *x25519ECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800330 if len(peerKey) != 32 {
331 return nil, errors.New("tls: invalid peer key")
332 }
333 var out, peerKeyCopy [32]byte
334 copy(peerKeyCopy[:], peerKey)
335 curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy)
336
David Benjamin4969cc92016-04-22 15:02:23 -0400337 // Per RFC 7748, reject the all-zero value in constant time.
Adam Langley4139edb2016-01-13 15:00:54 -0800338 var zeros [32]byte
339 if subtle.ConstantTimeCompare(zeros[:], out[:]) == 1 {
340 return nil, errors.New("tls: X25519 value with wrong order")
341 }
342
343 return out[:], nil
344}
345
Robert Sloanab8b8882018-03-26 11:39:51 -0700346func curveForCurveID(id CurveID, config *Config) (ecdhCurve, bool) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800347 switch id {
Adam Langleye9ada862015-05-11 17:20:37 -0700348 case CurveP224:
Robert Sloanab8b8882018-03-26 11:39:51 -0700349 return &ellipticECDHCurve{curve: elliptic.P224(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800350 case CurveP256:
Robert Sloanab8b8882018-03-26 11:39:51 -0700351 return &ellipticECDHCurve{curve: elliptic.P256(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800352 case CurveP384:
Robert Sloanab8b8882018-03-26 11:39:51 -0700353 return &ellipticECDHCurve{curve: elliptic.P384(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800354 case CurveP521:
Robert Sloanab8b8882018-03-26 11:39:51 -0700355 return &ellipticECDHCurve{curve: elliptic.P521(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langley4139edb2016-01-13 15:00:54 -0800356 case CurveX25519:
357 return &x25519ECDHCurve{}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800358 default:
359 return nil, false
360 }
361
362}
363
364// keyAgreementAuthentication is a helper interface that specifies how
365// to authenticate the ServerKeyExchange parameters.
366type keyAgreementAuthentication interface {
367 signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error)
368 verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error
369}
370
371// nilKeyAgreementAuthentication does not authenticate the key
372// agreement parameters.
373type nilKeyAgreementAuthentication struct{}
374
375func (ka *nilKeyAgreementAuthentication) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
376 skx := new(serverKeyExchangeMsg)
377 skx.key = params
378 return skx, nil
379}
380
381func (ka *nilKeyAgreementAuthentication) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error {
382 return nil
383}
384
385// signedKeyAgreement signs the ServerKeyExchange parameters with the
386// server's private key.
387type signedKeyAgreement struct {
David Benjaminc895d6b2016-08-11 13:26:41 -0400388 keyType keyType
389 version uint16
390 peerSignatureAlgorithm signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800391}
392
393func (ka *signedKeyAgreement) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400394 // The message to be signed is prepended by the randoms.
395 var msg []byte
396 msg = append(msg, clientHello.random...)
397 msg = append(msg, hello.random...)
398 msg = append(msg, params...)
399
400 var sigAlg signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800401 var err error
402 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400403 sigAlg, err = selectSignatureAlgorithm(ka.version, cert.PrivateKey, config, clientHello.signatureAlgorithms)
404 if err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800405 return nil, err
406 }
407 }
408
David Benjaminc895d6b2016-08-11 13:26:41 -0400409 sig, err := signMessage(ka.version, cert.PrivateKey, config, sigAlg, msg)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800410 if err != nil {
411 return nil, err
412 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400413 if config.Bugs.SendSignatureAlgorithm != 0 {
414 sigAlg = config.Bugs.SendSignatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800415 }
416
417 skx := new(serverKeyExchangeMsg)
418 if config.Bugs.UnauthenticatedECDH {
419 skx.key = params
420 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400421 sigAlgsLen := 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800422 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400423 sigAlgsLen = 2
Adam Langleyd9e397b2015-01-22 14:27:53 -0800424 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400425 skx.key = make([]byte, len(params)+sigAlgsLen+2+len(sig))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800426 copy(skx.key, params)
427 k := skx.key[len(params):]
428 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400429 k[0] = byte(sigAlg >> 8)
430 k[1] = byte(sigAlg)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800431 k = k[2:]
432 }
433 k[0] = byte(len(sig) >> 8)
434 k[1] = byte(len(sig))
435 copy(k[2:], sig)
436 }
437
438 return skx, nil
439}
440
441func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error {
David Benjaminc895d6b2016-08-11 13:26:41 -0400442 // The peer's key must match the cipher type.
Robert Sloan572a4e22017-04-17 10:52:19 -0700443 publicKey := getCertificatePublicKey(cert)
David Benjaminc895d6b2016-08-11 13:26:41 -0400444 switch ka.keyType {
445 case keyTypeECDSA:
Robert Sloan572a4e22017-04-17 10:52:19 -0700446 _, edsaOk := publicKey.(*ecdsa.PublicKey)
447 _, ed25519Ok := publicKey.(ed25519.PublicKey)
448 if !edsaOk && !ed25519Ok {
449 return errors.New("tls: ECDHE ECDSA requires a ECDSA or Ed25519 server public key")
David Benjaminc895d6b2016-08-11 13:26:41 -0400450 }
451 case keyTypeRSA:
Robert Sloan572a4e22017-04-17 10:52:19 -0700452 _, ok := publicKey.(*rsa.PublicKey)
David Benjaminc895d6b2016-08-11 13:26:41 -0400453 if !ok {
454 return errors.New("tls: ECDHE RSA requires a RSA server public key")
455 }
456 default:
457 return errors.New("tls: unknown key type")
Adam Langleyd9e397b2015-01-22 14:27:53 -0800458 }
459
David Benjaminc895d6b2016-08-11 13:26:41 -0400460 // The message to be signed is prepended by the randoms.
461 var msg []byte
462 msg = append(msg, clientHello.random...)
463 msg = append(msg, serverHello.random...)
464 msg = append(msg, params...)
465
466 var sigAlg signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800467 if ka.version >= VersionTLS12 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800468 if len(sig) < 2 {
469 return errServerKeyExchange
470 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400471 sigAlg = signatureAlgorithm(sig[0])<<8 | signatureAlgorithm(sig[1])
472 sig = sig[2:]
473 // Stash the signature algorithm to be extracted by the handshake.
474 ka.peerSignatureAlgorithm = sigAlg
475 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800476
David Benjaminc895d6b2016-08-11 13:26:41 -0400477 if len(sig) < 2 {
478 return errServerKeyExchange
Adam Langleyd9e397b2015-01-22 14:27:53 -0800479 }
480 sigLen := int(sig[0])<<8 | int(sig[1])
481 if sigLen+2 != len(sig) {
482 return errServerKeyExchange
483 }
484 sig = sig[2:]
485
Robert Sloan572a4e22017-04-17 10:52:19 -0700486 return verifyMessage(ka.version, publicKey, config, sigAlg, msg, sig)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800487}
488
David Benjaminc895d6b2016-08-11 13:26:41 -0400489// ecdheKeyAgreement implements a TLS key agreement where the server
Adam Langleyd9e397b2015-01-22 14:27:53 -0800490// generates a ephemeral EC public/private key pair and signs it. The
491// pre-master secret is then calculated using ECDH. The signature may
492// either be ECDSA or RSA.
493type ecdheKeyAgreement struct {
Adam Langley4139edb2016-01-13 15:00:54 -0800494 auth keyAgreementAuthentication
495 curve ecdhCurve
David Benjaminc895d6b2016-08-11 13:26:41 -0400496 curveID CurveID
Adam Langley4139edb2016-01-13 15:00:54 -0800497 peerKey []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -0800498}
499
500func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
501 var curveid CurveID
502 preferredCurves := config.curvePreferences()
503
504NextCandidate:
505 for _, candidate := range preferredCurves {
506 for _, c := range clientHello.supportedCurves {
507 if candidate == c {
508 curveid = c
509 break NextCandidate
510 }
511 }
512 }
513
514 if curveid == 0 {
515 return nil, errors.New("tls: no supported elliptic curves offered")
516 }
517
518 var ok bool
Robert Sloanab8b8882018-03-26 11:39:51 -0700519 if ka.curve, ok = curveForCurveID(curveid, config); !ok {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800520 return nil, errors.New("tls: preferredCurves includes unsupported curve")
521 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400522 ka.curveID = curveid
Adam Langleyd9e397b2015-01-22 14:27:53 -0800523
David Benjamind316cba2016-06-02 16:17:39 -0400524 publicKey, err := ka.curve.offer(config.rand())
Adam Langleyd9e397b2015-01-22 14:27:53 -0800525 if err != nil {
526 return nil, err
527 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800528
529 // http://tools.ietf.org/html/rfc4492#section-5.4
Adam Langley4139edb2016-01-13 15:00:54 -0800530 serverECDHParams := make([]byte, 1+2+1+len(publicKey))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800531 serverECDHParams[0] = 3 // named curve
David Benjaminc895d6b2016-08-11 13:26:41 -0400532 if config.Bugs.SendCurve != 0 {
533 curveid = config.Bugs.SendCurve
534 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800535 serverECDHParams[1] = byte(curveid >> 8)
536 serverECDHParams[2] = byte(curveid)
Adam Langley4139edb2016-01-13 15:00:54 -0800537 serverECDHParams[3] = byte(len(publicKey))
538 copy(serverECDHParams[4:], publicKey)
David Benjamin4969cc92016-04-22 15:02:23 -0400539 if config.Bugs.InvalidECDHPoint {
540 serverECDHParams[4] ^= 0xff
541 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800542
543 return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
544}
545
546func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
547 if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
548 return nil, errClientKeyExchange
549 }
David Benjamind316cba2016-06-02 16:17:39 -0400550 return ka.curve.finish(ckx.ciphertext[1:])
Adam Langleyd9e397b2015-01-22 14:27:53 -0800551}
552
553func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
554 if len(skx.key) < 4 {
555 return errServerKeyExchange
556 }
557 if skx.key[0] != 3 { // named curve
558 return errors.New("tls: server selected unsupported curve")
559 }
560 curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
David Benjaminc895d6b2016-08-11 13:26:41 -0400561 ka.curveID = curveid
Adam Langleyd9e397b2015-01-22 14:27:53 -0800562
563 var ok bool
Robert Sloanab8b8882018-03-26 11:39:51 -0700564 if ka.curve, ok = curveForCurveID(curveid, config); !ok {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800565 return errors.New("tls: server selected unsupported curve")
566 }
567
568 publicLen := int(skx.key[3])
569 if publicLen+4 > len(skx.key) {
570 return errServerKeyExchange
571 }
Adam Langley4139edb2016-01-13 15:00:54 -0800572 // Save the peer key for later.
573 ka.peerKey = skx.key[4 : 4+publicLen]
574
575 // Check the signature.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800576 serverECDHParams := skx.key[:4+publicLen]
577 sig := skx.key[4+publicLen:]
Adam Langleyd9e397b2015-01-22 14:27:53 -0800578 return ka.auth.verifyParameters(config, clientHello, serverHello, cert, serverECDHParams, sig)
579}
580
581func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
582 if ka.curve == nil {
583 return nil, nil, errors.New("missing ServerKeyExchange message")
584 }
Adam Langley4139edb2016-01-13 15:00:54 -0800585
David Benjamind316cba2016-06-02 16:17:39 -0400586 publicKey, preMasterSecret, err := ka.curve.accept(config.rand(), ka.peerKey)
Adam Langley4139edb2016-01-13 15:00:54 -0800587 if err != nil {
588 return nil, nil, err
589 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800590
591 ckx := new(clientKeyExchangeMsg)
Adam Langley4139edb2016-01-13 15:00:54 -0800592 ckx.ciphertext = make([]byte, 1+len(publicKey))
593 ckx.ciphertext[0] = byte(len(publicKey))
594 copy(ckx.ciphertext[1:], publicKey)
David Benjamin4969cc92016-04-22 15:02:23 -0400595 if config.Bugs.InvalidECDHPoint {
596 ckx.ciphertext[1] ^= 0xff
597 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800598
599 return preMasterSecret, ckx, nil
600}
601
David Benjaminc895d6b2016-08-11 13:26:41 -0400602func (ka *ecdheKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
603 if auth, ok := ka.auth.(*signedKeyAgreement); ok {
604 return auth.peerSignatureAlgorithm
605 }
606 return 0
607}
608
Adam Langleyd9e397b2015-01-22 14:27:53 -0800609// nilKeyAgreement is a fake key agreement used to implement the plain PSK key
610// exchange.
611type nilKeyAgreement struct{}
612
613func (ka *nilKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
614 return nil, nil
615}
616
617func (ka *nilKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
618 if len(ckx.ciphertext) != 0 {
619 return nil, errClientKeyExchange
620 }
621
622 // Although in plain PSK, otherSecret is all zeros, the base key
623 // agreement does not access to the length of the pre-shared
624 // key. pskKeyAgreement instead interprets nil to mean to use all zeros
625 // of the appropriate length.
626 return nil, nil
627}
628
629func (ka *nilKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
630 if len(skx.key) != 0 {
631 return errServerKeyExchange
632 }
633 return nil
634}
635
636func (ka *nilKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
637 // Although in plain PSK, otherSecret is all zeros, the base key
638 // agreement does not access to the length of the pre-shared
639 // key. pskKeyAgreement instead interprets nil to mean to use all zeros
640 // of the appropriate length.
641 return nil, &clientKeyExchangeMsg{}, nil
642}
643
David Benjaminc895d6b2016-08-11 13:26:41 -0400644func (ka *nilKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
645 return 0
646}
647
Adam Langleyd9e397b2015-01-22 14:27:53 -0800648// makePSKPremaster formats a PSK pre-master secret based on otherSecret from
649// the base key exchange and psk.
650func makePSKPremaster(otherSecret, psk []byte) []byte {
651 out := make([]byte, 0, 2+len(otherSecret)+2+len(psk))
652 out = append(out, byte(len(otherSecret)>>8), byte(len(otherSecret)))
653 out = append(out, otherSecret...)
654 out = append(out, byte(len(psk)>>8), byte(len(psk)))
655 out = append(out, psk...)
656 return out
657}
658
659// pskKeyAgreement implements the PSK key agreement.
660type pskKeyAgreement struct {
661 base keyAgreement
662 identityHint string
663}
664
665func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
666 // Assemble the identity hint.
667 bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
668 bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
669 bytes[1] = byte(len(config.PreSharedKeyIdentity))
670 copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
671
672 // If there is one, append the base key agreement's
673 // ServerKeyExchange.
674 baseSkx, err := ka.base.generateServerKeyExchange(config, cert, clientHello, hello)
675 if err != nil {
676 return nil, err
677 }
678
679 if baseSkx != nil {
680 bytes = append(bytes, baseSkx.key...)
David Benjamin7c0d06c2016-08-11 13:26:41 -0400681 } else if config.PreSharedKeyIdentity == "" && !config.Bugs.AlwaysSendPreSharedKeyIdentityHint {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800682 // ServerKeyExchange is optional if the identity hint is empty
683 // and there would otherwise be no ServerKeyExchange.
684 return nil, nil
685 }
686
687 skx := new(serverKeyExchangeMsg)
688 skx.key = bytes
689 return skx, nil
690}
691
692func (ka *pskKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
693 // First, process the PSK identity.
694 if len(ckx.ciphertext) < 2 {
695 return nil, errClientKeyExchange
696 }
697 identityLen := (int(ckx.ciphertext[0]) << 8) | int(ckx.ciphertext[1])
698 if 2+identityLen > len(ckx.ciphertext) {
699 return nil, errClientKeyExchange
700 }
701 identity := string(ckx.ciphertext[2 : 2+identityLen])
702
703 if identity != config.PreSharedKeyIdentity {
704 return nil, errors.New("tls: unexpected identity")
705 }
706
707 if config.PreSharedKey == nil {
708 return nil, errors.New("tls: pre-shared key not configured")
709 }
710
711 // Process the remainder of the ClientKeyExchange to compute the base
712 // pre-master secret.
713 newCkx := new(clientKeyExchangeMsg)
714 newCkx.ciphertext = ckx.ciphertext[2+identityLen:]
715 otherSecret, err := ka.base.processClientKeyExchange(config, cert, newCkx, version)
716 if err != nil {
717 return nil, err
718 }
719
720 if otherSecret == nil {
721 // Special-case for the plain PSK key exchanges.
722 otherSecret = make([]byte, len(config.PreSharedKey))
723 }
724 return makePSKPremaster(otherSecret, config.PreSharedKey), nil
725}
726
727func (ka *pskKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
728 if len(skx.key) < 2 {
729 return errServerKeyExchange
730 }
731 identityLen := (int(skx.key[0]) << 8) | int(skx.key[1])
732 if 2+identityLen > len(skx.key) {
733 return errServerKeyExchange
734 }
735 ka.identityHint = string(skx.key[2 : 2+identityLen])
736
737 // Process the remainder of the ServerKeyExchange.
738 newSkx := new(serverKeyExchangeMsg)
739 newSkx.key = skx.key[2+identityLen:]
740 return ka.base.processServerKeyExchange(config, clientHello, serverHello, cert, newSkx)
741}
742
743func (ka *pskKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
744 // The server only sends an identity hint but, for purposes of
745 // test code, the server always sends the hint and it is
746 // required to match.
747 if ka.identityHint != config.PreSharedKeyIdentity {
748 return nil, nil, errors.New("tls: unexpected identity")
749 }
750
751 // Serialize the identity.
752 bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
753 bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
754 bytes[1] = byte(len(config.PreSharedKeyIdentity))
755 copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
756
757 // Append the base key exchange's ClientKeyExchange.
758 otherSecret, baseCkx, err := ka.base.generateClientKeyExchange(config, clientHello, cert)
759 if err != nil {
760 return nil, nil, err
761 }
762 ckx := new(clientKeyExchangeMsg)
763 ckx.ciphertext = append(bytes, baseCkx.ciphertext...)
764
765 if config.PreSharedKey == nil {
766 return nil, nil, errors.New("tls: pre-shared key not configured")
767 }
768 if otherSecret == nil {
769 otherSecret = make([]byte, len(config.PreSharedKey))
770 }
771 return makePSKPremaster(otherSecret, config.PreSharedKey), ckx, nil
772}
David Benjaminc895d6b2016-08-11 13:26:41 -0400773
774func (ka *pskKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
775 return 0
776}