blob: f4789b66b1a6e069e8b464c5fada84322f105f37 [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 (
Robert Sloan4c22c5f2019-03-01 15:53:37 -08008 "crypto"
Adam Langleyd9e397b2015-01-22 14:27:53 -08009 "crypto/ecdsa"
10 "crypto/elliptic"
Adam Langleyd9e397b2015-01-22 14:27:53 -080011 "crypto/rsa"
Adam Langley4139edb2016-01-13 15:00:54 -080012 "crypto/subtle"
Adam Langleyd9e397b2015-01-22 14:27:53 -080013 "crypto/x509"
Adam Langleyd9e397b2015-01-22 14:27:53 -080014 "errors"
Adam Langley4139edb2016-01-13 15:00:54 -080015 "fmt"
Adam Langleyd9e397b2015-01-22 14:27:53 -080016 "io"
17 "math/big"
Adam Langley4139edb2016-01-13 15:00:54 -080018
Robert Sloanf573be72018-09-17 15:29:11 -070019 "boringssl.googlesource.com/boringssl/ssl/test/runner/curve25519"
20 "boringssl.googlesource.com/boringssl/ssl/test/runner/ed25519"
Robert Sloan11c28bd2018-12-17 12:09:20 -080021 "boringssl.googlesource.com/boringssl/ssl/test/runner/hrss"
Pete Bentley0c61efe2019-08-13 09:32:23 +010022 "boringssl.googlesource.com/boringssl/ssl/test/runner/sike"
Adam Langleyd9e397b2015-01-22 14:27:53 -080023)
24
David Benjaminc895d6b2016-08-11 13:26:41 -040025type keyType int
26
27const (
28 keyTypeRSA keyType = iota + 1
29 keyTypeECDSA
30)
31
Adam Langleyd9e397b2015-01-22 14:27:53 -080032var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
33var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
34
35// rsaKeyAgreement implements the standard TLS key agreement where the client
36// encrypts the pre-master secret to the server's public key.
37type rsaKeyAgreement struct {
Adam Langleye9ada862015-05-11 17:20:37 -070038 version uint16
Adam Langleyd9e397b2015-01-22 14:27:53 -080039 clientVersion uint16
Adam Langleye9ada862015-05-11 17:20:37 -070040 exportKey *rsa.PrivateKey
Adam Langleyd9e397b2015-01-22 14:27:53 -080041}
42
Robert Sloan11c28bd2018-12-17 12:09:20 -080043func (ka *rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) {
Adam Langleyd9e397b2015-01-22 14:27:53 -080044 // Save the client version for comparison later.
Steven Valdezbb1ceac2016-10-07 10:34:51 -040045 ka.clientVersion = clientHello.vers
Adam Langleyd9e397b2015-01-22 14:27:53 -080046
Adam Langleye9ada862015-05-11 17:20:37 -070047 if !config.Bugs.RSAEphemeralKey {
48 return nil, nil
Adam Langleyd9e397b2015-01-22 14:27:53 -080049 }
50
Adam Langleye9ada862015-05-11 17:20:37 -070051 // Generate an ephemeral RSA key to use instead of the real
52 // one, as in RSA_EXPORT.
53 key, err := rsa.GenerateKey(config.rand(), 512)
54 if err != nil {
55 return nil, err
56 }
57 ka.exportKey = key
58
59 modulus := key.N.Bytes()
60 exponent := big.NewInt(int64(key.E)).Bytes()
61 serverRSAParams := make([]byte, 0, 2+len(modulus)+2+len(exponent))
62 serverRSAParams = append(serverRSAParams, byte(len(modulus)>>8), byte(len(modulus)))
63 serverRSAParams = append(serverRSAParams, modulus...)
64 serverRSAParams = append(serverRSAParams, byte(len(exponent)>>8), byte(len(exponent)))
65 serverRSAParams = append(serverRSAParams, exponent...)
66
David Benjaminc895d6b2016-08-11 13:26:41 -040067 var sigAlg signatureAlgorithm
Adam Langleye9ada862015-05-11 17:20:37 -070068 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -040069 sigAlg, err = selectSignatureAlgorithm(ka.version, cert.PrivateKey, config, clientHello.signatureAlgorithms)
70 if err != nil {
Adam Langleye9ada862015-05-11 17:20:37 -070071 return nil, err
72 }
73 }
74
David Benjaminc895d6b2016-08-11 13:26:41 -040075 sig, err := signMessage(ka.version, cert.PrivateKey, config, sigAlg, serverRSAParams)
Adam Langleye9ada862015-05-11 17:20:37 -070076 if err != nil {
77 return nil, errors.New("failed to sign RSA parameters: " + err.Error())
78 }
79
80 skx := new(serverKeyExchangeMsg)
David Benjaminc895d6b2016-08-11 13:26:41 -040081 sigAlgsLen := 0
Adam Langleye9ada862015-05-11 17:20:37 -070082 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -040083 sigAlgsLen = 2
Adam Langleye9ada862015-05-11 17:20:37 -070084 }
David Benjaminc895d6b2016-08-11 13:26:41 -040085 skx.key = make([]byte, len(serverRSAParams)+sigAlgsLen+2+len(sig))
Adam Langleye9ada862015-05-11 17:20:37 -070086 copy(skx.key, serverRSAParams)
87 k := skx.key[len(serverRSAParams):]
88 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -040089 k[0] = byte(sigAlg >> 8)
90 k[1] = byte(sigAlg)
Adam Langleye9ada862015-05-11 17:20:37 -070091 k = k[2:]
92 }
93 k[0] = byte(len(sig) >> 8)
94 k[1] = byte(len(sig))
95 copy(k[2:], sig)
96
97 return skx, nil
Adam Langleyd9e397b2015-01-22 14:27:53 -080098}
99
100func (ka *rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
101 preMasterSecret := make([]byte, 48)
102 _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
103 if err != nil {
104 return nil, err
105 }
106
107 if len(ckx.ciphertext) < 2 {
108 return nil, errClientKeyExchange
109 }
110
111 ciphertext := ckx.ciphertext
112 if version != VersionSSL30 {
113 ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
114 if ciphertextLen != len(ckx.ciphertext)-2 {
115 return nil, errClientKeyExchange
116 }
117 ciphertext = ckx.ciphertext[2:]
118 }
119
Adam Langleye9ada862015-05-11 17:20:37 -0700120 key := cert.PrivateKey.(*rsa.PrivateKey)
121 if ka.exportKey != nil {
122 key = ka.exportKey
123 }
124 err = rsa.DecryptPKCS1v15SessionKey(config.rand(), key, ciphertext, preMasterSecret)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800125 if err != nil {
126 return nil, err
127 }
128 // This check should be done in constant-time, but this is a testing
129 // implementation. See the discussion at the end of section 7.4.7.1 of
130 // RFC 4346.
131 vers := uint16(preMasterSecret[0])<<8 | uint16(preMasterSecret[1])
132 if ka.clientVersion != vers {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400133 return nil, fmt.Errorf("tls: invalid version in RSA premaster (got %04x, wanted %04x)", vers, ka.clientVersion)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800134 }
135 return preMasterSecret, nil
136}
137
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800138func (ka *rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, skx *serverKeyExchangeMsg) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800139 return errors.New("tls: unexpected ServerKeyExchange")
140}
141
Robert Sloan921ef2c2017-10-17 09:02:20 -0700142func rsaSize(pub *rsa.PublicKey) int {
143 return (pub.N.BitLen() + 7) / 8
144}
145
146func rsaRawEncrypt(pub *rsa.PublicKey, msg []byte) ([]byte, error) {
147 k := rsaSize(pub)
148 if len(msg) != k {
149 return nil, errors.New("tls: bad padded RSA input")
150 }
151 m := new(big.Int).SetBytes(msg)
152 e := big.NewInt(int64(pub.E))
153 m.Exp(m, e, pub.N)
154 unpadded := m.Bytes()
155 ret := make([]byte, k)
156 copy(ret[len(ret)-len(unpadded):], unpadded)
157 return ret, nil
158}
159
160// nonZeroRandomBytes fills the given slice with non-zero random octets.
161func nonZeroRandomBytes(s []byte, rand io.Reader) {
162 if _, err := io.ReadFull(rand, s); err != nil {
163 panic(err)
164 }
165
166 for i := range s {
167 for s[i] == 0 {
168 if _, err := io.ReadFull(rand, s[i:i+1]); err != nil {
169 panic(err)
170 }
171 }
172 }
173}
174
Adam Langleyd9e397b2015-01-22 14:27:53 -0800175func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800176 bad := config.Bugs.BadRSAClientKeyExchange
Adam Langleyd9e397b2015-01-22 14:27:53 -0800177 preMasterSecret := make([]byte, 48)
178 vers := clientHello.vers
Robert Sloan921ef2c2017-10-17 09:02:20 -0700179 if bad == RSABadValueWrongVersion1 {
Adam Langley4139edb2016-01-13 15:00:54 -0800180 vers ^= 1
Robert Sloan921ef2c2017-10-17 09:02:20 -0700181 } else if bad == RSABadValueWrongVersion2 {
182 vers ^= 0x100
Adam Langleyd9e397b2015-01-22 14:27:53 -0800183 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800184 preMasterSecret[0] = byte(vers >> 8)
185 preMasterSecret[1] = byte(vers)
186 _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
187 if err != nil {
188 return nil, nil, err
189 }
190
Adam Langley4139edb2016-01-13 15:00:54 -0800191 sentPreMasterSecret := preMasterSecret
192 if bad == RSABadValueTooLong {
Robert Sloan921ef2c2017-10-17 09:02:20 -0700193 sentPreMasterSecret = make([]byte, 1, len(sentPreMasterSecret)+1)
194 sentPreMasterSecret = append(sentPreMasterSecret, preMasterSecret...)
Adam Langley4139edb2016-01-13 15:00:54 -0800195 } else if bad == RSABadValueTooShort {
196 sentPreMasterSecret = sentPreMasterSecret[:len(sentPreMasterSecret)-1]
197 }
198
Robert Sloan921ef2c2017-10-17 09:02:20 -0700199 // Pad for PKCS#1 v1.5.
200 padded := make([]byte, rsaSize(cert.PublicKey.(*rsa.PublicKey)))
201 padded[1] = 2
202 nonZeroRandomBytes(padded[2:len(padded)-len(sentPreMasterSecret)-1], config.rand())
203 copy(padded[len(padded)-len(sentPreMasterSecret):], sentPreMasterSecret)
204
205 if bad == RSABadValueWrongBlockType {
206 padded[1] = 3
207 } else if bad == RSABadValueWrongLeadingByte {
208 padded[0] = 1
209 } else if bad == RSABadValueNoZero {
210 for i := 2; i < len(padded); i++ {
211 if padded[i] == 0 {
212 padded[i]++
213 }
214 }
215 }
216
217 encrypted, err := rsaRawEncrypt(cert.PublicKey.(*rsa.PublicKey), padded)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800218 if err != nil {
219 return nil, nil, err
220 }
Adam Langley4139edb2016-01-13 15:00:54 -0800221 if bad == RSABadValueCorrupt {
222 encrypted[len(encrypted)-1] ^= 1
223 // Clear the high byte to ensure |encrypted| is still below the RSA modulus.
224 encrypted[0] = 0
225 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800226 ckx := new(clientKeyExchangeMsg)
Robert Sloan8ecb7cd2017-03-21 09:39:01 -0700227 if ka.version != VersionSSL30 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800228 ckx.ciphertext = make([]byte, len(encrypted)+2)
229 ckx.ciphertext[0] = byte(len(encrypted) >> 8)
230 ckx.ciphertext[1] = byte(len(encrypted))
231 copy(ckx.ciphertext[2:], encrypted)
232 } else {
233 ckx.ciphertext = encrypted
234 }
235 return preMasterSecret, ckx, nil
236}
237
David Benjaminc895d6b2016-08-11 13:26:41 -0400238func (ka *rsaKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
239 return 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800240}
241
Adam Langley4139edb2016-01-13 15:00:54 -0800242// A ecdhCurve is an instance of ECDH-style key agreement for TLS.
243type ecdhCurve interface {
David Benjamind316cba2016-06-02 16:17:39 -0400244 // offer generates a keypair using rand. It returns the encoded |publicKey|.
245 offer(rand io.Reader) (publicKey []byte, err error)
Adam Langley4139edb2016-01-13 15:00:54 -0800246
David Benjamind316cba2016-06-02 16:17:39 -0400247 // accept responds to the |peerKey| generated by |offer| with the acceptor's
248 // |publicKey|, and returns agreed-upon |preMasterSecret| to the acceptor.
249 accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error)
250
251 // finish returns the computed |preMasterSecret|, given the |peerKey|
252 // generated by |accept|.
253 finish(peerKey []byte) (preMasterSecret []byte, err error)
Adam Langley4139edb2016-01-13 15:00:54 -0800254}
255
256// ellipticECDHCurve implements ecdhCurve with an elliptic.Curve.
257type ellipticECDHCurve struct {
Robert Sloanab8b8882018-03-26 11:39:51 -0700258 curve elliptic.Curve
259 privateKey []byte
260 sendCompressed bool
Adam Langley4139edb2016-01-13 15:00:54 -0800261}
262
David Benjamind316cba2016-06-02 16:17:39 -0400263func (e *ellipticECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800264 var x, y *big.Int
265 e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand)
266 if err != nil {
267 return nil, err
268 }
Robert Sloanab8b8882018-03-26 11:39:51 -0700269 ret := elliptic.Marshal(e.curve, x, y)
270 if e.sendCompressed {
271 l := (len(ret) - 1) / 2
272 tmp := make([]byte, 1+l)
273 tmp[0] = byte(2 | y.Bit(0))
274 copy(tmp[1:], ret[1:1+l])
275 ret = tmp
276 }
277 return ret, nil
Adam Langley4139edb2016-01-13 15:00:54 -0800278}
279
David Benjamind316cba2016-06-02 16:17:39 -0400280func (e *ellipticECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
281 publicKey, err = e.offer(rand)
282 if err != nil {
283 return nil, nil, err
284 }
285 preMasterSecret, err = e.finish(peerKey)
286 if err != nil {
287 return nil, nil, err
288 }
289 return
290}
291
292func (e *ellipticECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800293 x, y := elliptic.Unmarshal(e.curve, peerKey)
294 if x == nil {
295 return nil, errors.New("tls: invalid peer key")
296 }
297 x, _ = e.curve.ScalarMult(x, y, e.privateKey)
298 preMasterSecret = make([]byte, (e.curve.Params().BitSize+7)>>3)
299 xBytes := x.Bytes()
300 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
301
302 return preMasterSecret, nil
303}
304
305// x25519ECDHCurve implements ecdhCurve with X25519.
306type x25519ECDHCurve struct {
307 privateKey [32]byte
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700308 setHighBit bool
Adam Langley4139edb2016-01-13 15:00:54 -0800309}
310
David Benjamind316cba2016-06-02 16:17:39 -0400311func (e *x25519ECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800312 _, err = io.ReadFull(rand, e.privateKey[:])
313 if err != nil {
314 return
315 }
316 var out [32]byte
317 curve25519.ScalarBaseMult(&out, &e.privateKey)
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700318 if e.setHighBit {
319 out[31] |= 0x80
320 }
Adam Langley4139edb2016-01-13 15:00:54 -0800321 return out[:], nil
322}
323
David Benjamind316cba2016-06-02 16:17:39 -0400324func (e *x25519ECDHCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
325 publicKey, err = e.offer(rand)
326 if err != nil {
327 return nil, nil, err
328 }
329 preMasterSecret, err = e.finish(peerKey)
330 if err != nil {
331 return nil, nil, err
332 }
333 return
334}
335
336func (e *x25519ECDHCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
Adam Langley4139edb2016-01-13 15:00:54 -0800337 if len(peerKey) != 32 {
338 return nil, errors.New("tls: invalid peer key")
339 }
340 var out, peerKeyCopy [32]byte
341 copy(peerKeyCopy[:], peerKey)
342 curve25519.ScalarMult(&out, &e.privateKey, &peerKeyCopy)
343
David Benjamin4969cc92016-04-22 15:02:23 -0400344 // Per RFC 7748, reject the all-zero value in constant time.
Adam Langley4139edb2016-01-13 15:00:54 -0800345 var zeros [32]byte
346 if subtle.ConstantTimeCompare(zeros[:], out[:]) == 1 {
347 return nil, errors.New("tls: X25519 value with wrong order")
348 }
349
350 return out[:], nil
351}
352
Robert Sloan11c28bd2018-12-17 12:09:20 -0800353// cecpq2Curve implements CECPQ2, which is HRSS+SXY combined with X25519.
354type cecpq2Curve struct {
355 x25519PrivateKey [32]byte
356 hrssPrivateKey hrss.PrivateKey
357}
358
359func (e *cecpq2Curve) offer(rand io.Reader) (publicKey []byte, err error) {
360 if _, err := io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil {
361 return nil, err
362 }
363
364 var x25519Public [32]byte
365 curve25519.ScalarBaseMult(&x25519Public, &e.x25519PrivateKey)
366
367 e.hrssPrivateKey = hrss.GenerateKey(rand)
368 hrssPublic := e.hrssPrivateKey.PublicKey.Marshal()
369
370 var ret []byte
371 ret = append(ret, x25519Public[:]...)
372 ret = append(ret, hrssPublic...)
373 return ret, nil
374}
375
376func (e *cecpq2Curve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
377 if len(peerKey) != 32+hrss.PublicKeySize {
378 return nil, nil, errors.New("tls: bad length CECPQ2 offer")
379 }
380
381 if _, err := io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil {
382 return nil, nil, err
383 }
384
385 var x25519Shared, x25519PeerKey, x25519Public [32]byte
386 copy(x25519PeerKey[:], peerKey)
387 curve25519.ScalarBaseMult(&x25519Public, &e.x25519PrivateKey)
388 curve25519.ScalarMult(&x25519Shared, &e.x25519PrivateKey, &x25519PeerKey)
389
390 // Per RFC 7748, reject the all-zero value in constant time.
391 var zeros [32]byte
392 if subtle.ConstantTimeCompare(zeros[:], x25519Shared[:]) == 1 {
393 return nil, nil, errors.New("tls: X25519 value with wrong order")
394 }
395
396 hrssPublicKey, ok := hrss.ParsePublicKey(peerKey[32:])
397 if !ok {
398 return nil, nil, errors.New("tls: bad CECPQ2 offer")
399 }
400
401 hrssCiphertext, hrssShared := hrssPublicKey.Encap(rand)
402
403 publicKey = append(publicKey, x25519Public[:]...)
404 publicKey = append(publicKey, hrssCiphertext...)
405 preMasterSecret = append(preMasterSecret, x25519Shared[:]...)
406 preMasterSecret = append(preMasterSecret, hrssShared...)
407
408 return publicKey, preMasterSecret, nil
409}
410
411func (e *cecpq2Curve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
412 if len(peerKey) != 32+hrss.CiphertextSize {
413 return nil, errors.New("tls: bad length CECPQ2 reply")
414 }
415
416 var x25519Shared, x25519PeerKey [32]byte
417 copy(x25519PeerKey[:], peerKey)
418 curve25519.ScalarMult(&x25519Shared, &e.x25519PrivateKey, &x25519PeerKey)
419
420 // Per RFC 7748, reject the all-zero value in constant time.
421 var zeros [32]byte
422 if subtle.ConstantTimeCompare(zeros[:], x25519Shared[:]) == 1 {
423 return nil, errors.New("tls: X25519 value with wrong order")
424 }
425
426 hrssShared, ok := e.hrssPrivateKey.Decap(peerKey[32:])
427 if !ok {
428 return nil, errors.New("tls: invalid HRSS ciphertext")
429 }
430
431 preMasterSecret = append(preMasterSecret, x25519Shared[:]...)
432 preMasterSecret = append(preMasterSecret, hrssShared...)
433
434 return preMasterSecret, nil
435}
436
Pete Bentley0c61efe2019-08-13 09:32:23 +0100437// cecpq2BCurve implements CECPQ2b, which is SIKE combined with X25519.
438type cecpq2BCurve struct {
439 // Both public key and shared secret size
440 x25519PrivateKey [32]byte
441 sikePrivateKey *sike.PrivateKey
442}
443
444func (e *cecpq2BCurve) offer(rand io.Reader) (publicKey []byte, err error) {
445 if _, err = io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil {
446 return nil, err
447 }
448
449 var x25519Public [32]byte
450 curve25519.ScalarBaseMult(&x25519Public, &e.x25519PrivateKey)
451
452 e.sikePrivateKey = sike.NewPrivateKey(sike.KeyVariant_SIKE)
453 if err = e.sikePrivateKey.Generate(rand); err != nil {
454 return nil, err
455 }
456
457 sikePublic := e.sikePrivateKey.GeneratePublicKey().Export()
458 var ret []byte
459 ret = append(ret, x25519Public[:]...)
460 ret = append(ret, sikePublic...)
461 return ret, nil
462}
463
464func (e *cecpq2BCurve) accept(rand io.Reader, peerKey []byte) (publicKey []byte, preMasterSecret []byte, err error) {
465 if len(peerKey) != 32+sike.Params.PublicKeySize {
466 return nil, nil, errors.New("tls: bad length CECPQ2b offer")
467 }
468
469 if _, err = io.ReadFull(rand, e.x25519PrivateKey[:]); err != nil {
470 return nil, nil, err
471 }
472
473 var x25519Shared, x25519PeerKey, x25519Public [32]byte
474 copy(x25519PeerKey[:], peerKey)
475 curve25519.ScalarBaseMult(&x25519Public, &e.x25519PrivateKey)
476 curve25519.ScalarMult(&x25519Shared, &e.x25519PrivateKey, &x25519PeerKey)
477
478 // Per RFC 7748, reject the all-zero value in constant time.
479 var zeros [32]byte
480 if subtle.ConstantTimeCompare(zeros[:], x25519Shared[:]) == 1 {
481 return nil, nil, errors.New("tls: X25519 value with wrong order")
482 }
483
484 var sikePubKey = sike.NewPublicKey(sike.KeyVariant_SIKE)
485 if err = sikePubKey.Import(peerKey[32:]); err != nil {
486 // should never happen as size was already checked
487 return nil, nil, errors.New("tls: implementation error")
488 }
489 sikeCiphertext, sikeShared, err := sike.Encapsulate(rand, sikePubKey)
490 if err != nil {
491 return nil, nil, err
492 }
493
494 publicKey = append(publicKey, x25519Public[:]...)
495 publicKey = append(publicKey, sikeCiphertext...)
496 preMasterSecret = append(preMasterSecret, x25519Shared[:]...)
497 preMasterSecret = append(preMasterSecret, sikeShared...)
498
499 return publicKey, preMasterSecret, nil
500}
501
502func (e *cecpq2BCurve) finish(peerKey []byte) (preMasterSecret []byte, err error) {
503 if len(peerKey) != 32+(sike.Params.PublicKeySize+sike.Params.MsgLen) {
504 return nil, errors.New("tls: bad length CECPQ2b reply")
505 }
506
507 var x25519Shared, x25519PeerKey [32]byte
508 copy(x25519PeerKey[:], peerKey)
509 curve25519.ScalarMult(&x25519Shared, &e.x25519PrivateKey, &x25519PeerKey)
510
511 // Per RFC 7748, reject the all-zero value in constant time.
512 var zeros [32]byte
513 if subtle.ConstantTimeCompare(zeros[:], x25519Shared[:]) == 1 {
514 return nil, errors.New("tls: X25519 value with wrong order")
515 }
516
517 var sikePubKey = e.sikePrivateKey.GeneratePublicKey()
518 sikeShared, err := sike.Decapsulate(e.sikePrivateKey, sikePubKey, peerKey[32:])
519 if err != nil {
520 return nil, errors.New("tls: invalid SIKE ciphertext")
521 }
522
523 preMasterSecret = append(preMasterSecret, x25519Shared[:]...)
524 preMasterSecret = append(preMasterSecret, sikeShared...)
525
526 return preMasterSecret, nil
527}
528
Robert Sloanab8b8882018-03-26 11:39:51 -0700529func curveForCurveID(id CurveID, config *Config) (ecdhCurve, bool) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800530 switch id {
Adam Langleye9ada862015-05-11 17:20:37 -0700531 case CurveP224:
Robert Sloanab8b8882018-03-26 11:39:51 -0700532 return &ellipticECDHCurve{curve: elliptic.P224(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800533 case CurveP256:
Robert Sloanab8b8882018-03-26 11:39:51 -0700534 return &ellipticECDHCurve{curve: elliptic.P256(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800535 case CurveP384:
Robert Sloanab8b8882018-03-26 11:39:51 -0700536 return &ellipticECDHCurve{curve: elliptic.P384(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800537 case CurveP521:
Robert Sloanab8b8882018-03-26 11:39:51 -0700538 return &ellipticECDHCurve{curve: elliptic.P521(), sendCompressed: config.Bugs.SendCompressedCoordinates}, true
Adam Langley4139edb2016-01-13 15:00:54 -0800539 case CurveX25519:
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700540 return &x25519ECDHCurve{setHighBit: config.Bugs.SetX25519HighBit}, true
Robert Sloan11c28bd2018-12-17 12:09:20 -0800541 case CurveCECPQ2:
542 return &cecpq2Curve{}, true
Pete Bentley0c61efe2019-08-13 09:32:23 +0100543 case CurveCECPQ2b:
544 return &cecpq2BCurve{}, true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800545 default:
546 return nil, false
547 }
548
549}
550
551// keyAgreementAuthentication is a helper interface that specifies how
552// to authenticate the ServerKeyExchange parameters.
553type keyAgreementAuthentication interface {
554 signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error)
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800555 verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, params []byte, sig []byte) error
Adam Langleyd9e397b2015-01-22 14:27:53 -0800556}
557
558// nilKeyAgreementAuthentication does not authenticate the key
559// agreement parameters.
560type nilKeyAgreementAuthentication struct{}
561
562func (ka *nilKeyAgreementAuthentication) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
563 skx := new(serverKeyExchangeMsg)
564 skx.key = params
565 return skx, nil
566}
567
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800568func (ka *nilKeyAgreementAuthentication) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, params []byte, sig []byte) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800569 return nil
570}
571
572// signedKeyAgreement signs the ServerKeyExchange parameters with the
573// server's private key.
574type signedKeyAgreement struct {
David Benjaminc895d6b2016-08-11 13:26:41 -0400575 keyType keyType
576 version uint16
577 peerSignatureAlgorithm signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800578}
579
580func (ka *signedKeyAgreement) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400581 // The message to be signed is prepended by the randoms.
582 var msg []byte
583 msg = append(msg, clientHello.random...)
584 msg = append(msg, hello.random...)
585 msg = append(msg, params...)
586
587 var sigAlg signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800588 var err error
589 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400590 sigAlg, err = selectSignatureAlgorithm(ka.version, cert.PrivateKey, config, clientHello.signatureAlgorithms)
591 if err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800592 return nil, err
593 }
594 }
595
David Benjaminc895d6b2016-08-11 13:26:41 -0400596 sig, err := signMessage(ka.version, cert.PrivateKey, config, sigAlg, msg)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800597 if err != nil {
598 return nil, err
599 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400600 if config.Bugs.SendSignatureAlgorithm != 0 {
601 sigAlg = config.Bugs.SendSignatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800602 }
603
604 skx := new(serverKeyExchangeMsg)
605 if config.Bugs.UnauthenticatedECDH {
606 skx.key = params
607 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400608 sigAlgsLen := 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800609 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400610 sigAlgsLen = 2
Adam Langleyd9e397b2015-01-22 14:27:53 -0800611 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400612 skx.key = make([]byte, len(params)+sigAlgsLen+2+len(sig))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800613 copy(skx.key, params)
614 k := skx.key[len(params):]
615 if ka.version >= VersionTLS12 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400616 k[0] = byte(sigAlg >> 8)
617 k[1] = byte(sigAlg)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800618 k = k[2:]
619 }
620 k[0] = byte(len(sig) >> 8)
621 k[1] = byte(len(sig))
622 copy(k[2:], sig)
623 }
624
625 return skx, nil
626}
627
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800628func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, publicKey crypto.PublicKey, params []byte, sig []byte) error {
David Benjaminc895d6b2016-08-11 13:26:41 -0400629 // The peer's key must match the cipher type.
630 switch ka.keyType {
631 case keyTypeECDSA:
Robert Sloan572a4e22017-04-17 10:52:19 -0700632 _, edsaOk := publicKey.(*ecdsa.PublicKey)
633 _, ed25519Ok := publicKey.(ed25519.PublicKey)
634 if !edsaOk && !ed25519Ok {
635 return errors.New("tls: ECDHE ECDSA requires a ECDSA or Ed25519 server public key")
David Benjaminc895d6b2016-08-11 13:26:41 -0400636 }
637 case keyTypeRSA:
Robert Sloan572a4e22017-04-17 10:52:19 -0700638 _, ok := publicKey.(*rsa.PublicKey)
David Benjaminc895d6b2016-08-11 13:26:41 -0400639 if !ok {
640 return errors.New("tls: ECDHE RSA requires a RSA server public key")
641 }
642 default:
643 return errors.New("tls: unknown key type")
Adam Langleyd9e397b2015-01-22 14:27:53 -0800644 }
645
David Benjaminc895d6b2016-08-11 13:26:41 -0400646 // The message to be signed is prepended by the randoms.
647 var msg []byte
648 msg = append(msg, clientHello.random...)
649 msg = append(msg, serverHello.random...)
650 msg = append(msg, params...)
651
652 var sigAlg signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -0800653 if ka.version >= VersionTLS12 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800654 if len(sig) < 2 {
655 return errServerKeyExchange
656 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400657 sigAlg = signatureAlgorithm(sig[0])<<8 | signatureAlgorithm(sig[1])
658 sig = sig[2:]
659 // Stash the signature algorithm to be extracted by the handshake.
660 ka.peerSignatureAlgorithm = sigAlg
661 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800662
David Benjaminc895d6b2016-08-11 13:26:41 -0400663 if len(sig) < 2 {
664 return errServerKeyExchange
Adam Langleyd9e397b2015-01-22 14:27:53 -0800665 }
666 sigLen := int(sig[0])<<8 | int(sig[1])
667 if sigLen+2 != len(sig) {
668 return errServerKeyExchange
669 }
670 sig = sig[2:]
671
Robert Sloan572a4e22017-04-17 10:52:19 -0700672 return verifyMessage(ka.version, publicKey, config, sigAlg, msg, sig)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800673}
674
David Benjaminc895d6b2016-08-11 13:26:41 -0400675// ecdheKeyAgreement implements a TLS key agreement where the server
Adam Langleyd9e397b2015-01-22 14:27:53 -0800676// generates a ephemeral EC public/private key pair and signs it. The
677// pre-master secret is then calculated using ECDH. The signature may
678// either be ECDSA or RSA.
679type ecdheKeyAgreement struct {
Adam Langley4139edb2016-01-13 15:00:54 -0800680 auth keyAgreementAuthentication
681 curve ecdhCurve
David Benjaminc895d6b2016-08-11 13:26:41 -0400682 curveID CurveID
Adam Langley4139edb2016-01-13 15:00:54 -0800683 peerKey []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -0800684}
685
Robert Sloan11c28bd2018-12-17 12:09:20 -0800686func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800687 var curveid CurveID
688 preferredCurves := config.curvePreferences()
689
690NextCandidate:
691 for _, candidate := range preferredCurves {
Pete Bentley0c61efe2019-08-13 09:32:23 +0100692 if isPqGroup(candidate) && version < VersionTLS13 {
693 // CECPQ2 and CECPQ2b is TLS 1.3-only.
Robert Sloan11c28bd2018-12-17 12:09:20 -0800694 continue
695 }
696
Adam Langleyd9e397b2015-01-22 14:27:53 -0800697 for _, c := range clientHello.supportedCurves {
698 if candidate == c {
699 curveid = c
700 break NextCandidate
701 }
702 }
703 }
704
705 if curveid == 0 {
706 return nil, errors.New("tls: no supported elliptic curves offered")
707 }
708
709 var ok bool
Robert Sloanab8b8882018-03-26 11:39:51 -0700710 if ka.curve, ok = curveForCurveID(curveid, config); !ok {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800711 return nil, errors.New("tls: preferredCurves includes unsupported curve")
712 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400713 ka.curveID = curveid
Adam Langleyd9e397b2015-01-22 14:27:53 -0800714
David Benjamind316cba2016-06-02 16:17:39 -0400715 publicKey, err := ka.curve.offer(config.rand())
Adam Langleyd9e397b2015-01-22 14:27:53 -0800716 if err != nil {
717 return nil, err
718 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800719
720 // http://tools.ietf.org/html/rfc4492#section-5.4
Adam Langley4139edb2016-01-13 15:00:54 -0800721 serverECDHParams := make([]byte, 1+2+1+len(publicKey))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800722 serverECDHParams[0] = 3 // named curve
David Benjaminc895d6b2016-08-11 13:26:41 -0400723 if config.Bugs.SendCurve != 0 {
724 curveid = config.Bugs.SendCurve
725 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800726 serverECDHParams[1] = byte(curveid >> 8)
727 serverECDHParams[2] = byte(curveid)
Adam Langley4139edb2016-01-13 15:00:54 -0800728 serverECDHParams[3] = byte(len(publicKey))
729 copy(serverECDHParams[4:], publicKey)
David Benjamin4969cc92016-04-22 15:02:23 -0400730 if config.Bugs.InvalidECDHPoint {
731 serverECDHParams[4] ^= 0xff
732 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800733
734 return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
735}
736
737func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
738 if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
739 return nil, errClientKeyExchange
740 }
David Benjamind316cba2016-06-02 16:17:39 -0400741 return ka.curve.finish(ckx.ciphertext[1:])
Adam Langleyd9e397b2015-01-22 14:27:53 -0800742}
743
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800744func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, skx *serverKeyExchangeMsg) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800745 if len(skx.key) < 4 {
746 return errServerKeyExchange
747 }
748 if skx.key[0] != 3 { // named curve
749 return errors.New("tls: server selected unsupported curve")
750 }
751 curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
David Benjaminc895d6b2016-08-11 13:26:41 -0400752 ka.curveID = curveid
Adam Langleyd9e397b2015-01-22 14:27:53 -0800753
754 var ok bool
Robert Sloanab8b8882018-03-26 11:39:51 -0700755 if ka.curve, ok = curveForCurveID(curveid, config); !ok {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800756 return errors.New("tls: server selected unsupported curve")
757 }
758
759 publicLen := int(skx.key[3])
760 if publicLen+4 > len(skx.key) {
761 return errServerKeyExchange
762 }
Adam Langley4139edb2016-01-13 15:00:54 -0800763 // Save the peer key for later.
764 ka.peerKey = skx.key[4 : 4+publicLen]
765
766 // Check the signature.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800767 serverECDHParams := skx.key[:4+publicLen]
768 sig := skx.key[4+publicLen:]
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800769 return ka.auth.verifyParameters(config, clientHello, serverHello, key, serverECDHParams, sig)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800770}
771
772func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
773 if ka.curve == nil {
774 return nil, nil, errors.New("missing ServerKeyExchange message")
775 }
Adam Langley4139edb2016-01-13 15:00:54 -0800776
David Benjamind316cba2016-06-02 16:17:39 -0400777 publicKey, preMasterSecret, err := ka.curve.accept(config.rand(), ka.peerKey)
Adam Langley4139edb2016-01-13 15:00:54 -0800778 if err != nil {
779 return nil, nil, err
780 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800781
782 ckx := new(clientKeyExchangeMsg)
Adam Langley4139edb2016-01-13 15:00:54 -0800783 ckx.ciphertext = make([]byte, 1+len(publicKey))
784 ckx.ciphertext[0] = byte(len(publicKey))
785 copy(ckx.ciphertext[1:], publicKey)
David Benjamin4969cc92016-04-22 15:02:23 -0400786 if config.Bugs.InvalidECDHPoint {
787 ckx.ciphertext[1] ^= 0xff
788 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800789
790 return preMasterSecret, ckx, nil
791}
792
David Benjaminc895d6b2016-08-11 13:26:41 -0400793func (ka *ecdheKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
794 if auth, ok := ka.auth.(*signedKeyAgreement); ok {
795 return auth.peerSignatureAlgorithm
796 }
797 return 0
798}
799
Adam Langleyd9e397b2015-01-22 14:27:53 -0800800// nilKeyAgreement is a fake key agreement used to implement the plain PSK key
801// exchange.
802type nilKeyAgreement struct{}
803
Robert Sloan11c28bd2018-12-17 12:09:20 -0800804func (ka *nilKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800805 return nil, nil
806}
807
808func (ka *nilKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
809 if len(ckx.ciphertext) != 0 {
810 return nil, errClientKeyExchange
811 }
812
813 // Although in plain PSK, otherSecret is all zeros, the base key
814 // agreement does not access to the length of the pre-shared
815 // key. pskKeyAgreement instead interprets nil to mean to use all zeros
816 // of the appropriate length.
817 return nil, nil
818}
819
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800820func (ka *nilKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, skx *serverKeyExchangeMsg) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800821 if len(skx.key) != 0 {
822 return errServerKeyExchange
823 }
824 return nil
825}
826
827func (ka *nilKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
828 // Although in plain PSK, otherSecret is all zeros, the base key
829 // agreement does not access to the length of the pre-shared
830 // key. pskKeyAgreement instead interprets nil to mean to use all zeros
831 // of the appropriate length.
832 return nil, &clientKeyExchangeMsg{}, nil
833}
834
David Benjaminc895d6b2016-08-11 13:26:41 -0400835func (ka *nilKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
836 return 0
837}
838
Adam Langleyd9e397b2015-01-22 14:27:53 -0800839// makePSKPremaster formats a PSK pre-master secret based on otherSecret from
840// the base key exchange and psk.
841func makePSKPremaster(otherSecret, psk []byte) []byte {
842 out := make([]byte, 0, 2+len(otherSecret)+2+len(psk))
843 out = append(out, byte(len(otherSecret)>>8), byte(len(otherSecret)))
844 out = append(out, otherSecret...)
845 out = append(out, byte(len(psk)>>8), byte(len(psk)))
846 out = append(out, psk...)
847 return out
848}
849
850// pskKeyAgreement implements the PSK key agreement.
851type pskKeyAgreement struct {
852 base keyAgreement
853 identityHint string
854}
855
Robert Sloan11c28bd2018-12-17 12:09:20 -0800856func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, version uint16) (*serverKeyExchangeMsg, error) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800857 // Assemble the identity hint.
858 bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
859 bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
860 bytes[1] = byte(len(config.PreSharedKeyIdentity))
861 copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
862
863 // If there is one, append the base key agreement's
864 // ServerKeyExchange.
Robert Sloan11c28bd2018-12-17 12:09:20 -0800865 baseSkx, err := ka.base.generateServerKeyExchange(config, cert, clientHello, hello, version)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800866 if err != nil {
867 return nil, err
868 }
869
870 if baseSkx != nil {
871 bytes = append(bytes, baseSkx.key...)
David Benjamin7c0d06c2016-08-11 13:26:41 -0400872 } else if config.PreSharedKeyIdentity == "" && !config.Bugs.AlwaysSendPreSharedKeyIdentityHint {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800873 // ServerKeyExchange is optional if the identity hint is empty
874 // and there would otherwise be no ServerKeyExchange.
875 return nil, nil
876 }
877
878 skx := new(serverKeyExchangeMsg)
879 skx.key = bytes
880 return skx, nil
881}
882
883func (ka *pskKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
884 // First, process the PSK identity.
885 if len(ckx.ciphertext) < 2 {
886 return nil, errClientKeyExchange
887 }
888 identityLen := (int(ckx.ciphertext[0]) << 8) | int(ckx.ciphertext[1])
889 if 2+identityLen > len(ckx.ciphertext) {
890 return nil, errClientKeyExchange
891 }
892 identity := string(ckx.ciphertext[2 : 2+identityLen])
893
894 if identity != config.PreSharedKeyIdentity {
895 return nil, errors.New("tls: unexpected identity")
896 }
897
898 if config.PreSharedKey == nil {
899 return nil, errors.New("tls: pre-shared key not configured")
900 }
901
902 // Process the remainder of the ClientKeyExchange to compute the base
903 // pre-master secret.
904 newCkx := new(clientKeyExchangeMsg)
905 newCkx.ciphertext = ckx.ciphertext[2+identityLen:]
906 otherSecret, err := ka.base.processClientKeyExchange(config, cert, newCkx, version)
907 if err != nil {
908 return nil, err
909 }
910
911 if otherSecret == nil {
912 // Special-case for the plain PSK key exchanges.
913 otherSecret = make([]byte, len(config.PreSharedKey))
914 }
915 return makePSKPremaster(otherSecret, config.PreSharedKey), nil
916}
917
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800918func (ka *pskKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, key crypto.PublicKey, skx *serverKeyExchangeMsg) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800919 if len(skx.key) < 2 {
920 return errServerKeyExchange
921 }
922 identityLen := (int(skx.key[0]) << 8) | int(skx.key[1])
923 if 2+identityLen > len(skx.key) {
924 return errServerKeyExchange
925 }
926 ka.identityHint = string(skx.key[2 : 2+identityLen])
927
928 // Process the remainder of the ServerKeyExchange.
929 newSkx := new(serverKeyExchangeMsg)
930 newSkx.key = skx.key[2+identityLen:]
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800931 return ka.base.processServerKeyExchange(config, clientHello, serverHello, key, newSkx)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800932}
933
934func (ka *pskKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
935 // The server only sends an identity hint but, for purposes of
936 // test code, the server always sends the hint and it is
937 // required to match.
938 if ka.identityHint != config.PreSharedKeyIdentity {
939 return nil, nil, errors.New("tls: unexpected identity")
940 }
941
942 // Serialize the identity.
943 bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
944 bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
945 bytes[1] = byte(len(config.PreSharedKeyIdentity))
946 copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
947
948 // Append the base key exchange's ClientKeyExchange.
949 otherSecret, baseCkx, err := ka.base.generateClientKeyExchange(config, clientHello, cert)
950 if err != nil {
951 return nil, nil, err
952 }
953 ckx := new(clientKeyExchangeMsg)
954 ckx.ciphertext = append(bytes, baseCkx.ciphertext...)
955
956 if config.PreSharedKey == nil {
957 return nil, nil, errors.New("tls: pre-shared key not configured")
958 }
959 if otherSecret == nil {
960 otherSecret = make([]byte, len(config.PreSharedKey))
961 }
962 return makePSKPremaster(otherSecret, config.PreSharedKey), ckx, nil
963}
David Benjaminc895d6b2016-08-11 13:26:41 -0400964
965func (ka *pskKeyAgreement) peerSignatureAlgorithm() signatureAlgorithm {
966 return 0
967}