Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / ssl / test / runner / key_agreement.go
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package main
6
7 import (
8         "crypto"
9         "crypto/ecdsa"
10         "crypto/elliptic"
11         "crypto/md5"
12         "crypto/rand"
13         "crypto/rsa"
14         "crypto/sha1"
15         "crypto/sha256"
16         "crypto/x509"
17         "encoding/asn1"
18         "errors"
19         "io"
20         "math/big"
21 )
22
23 var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
24 var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
25
26 // rsaKeyAgreement implements the standard TLS key agreement where the client
27 // encrypts the pre-master secret to the server's public key.
28 type rsaKeyAgreement struct{}
29
30 func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
31         return nil, nil
32 }
33
34 func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
35         preMasterSecret := make([]byte, 48)
36         _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
37         if err != nil {
38                 return nil, err
39         }
40
41         if len(ckx.ciphertext) < 2 {
42                 return nil, errClientKeyExchange
43         }
44
45         ciphertext := ckx.ciphertext
46         if version != VersionSSL30 {
47                 ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
48                 if ciphertextLen != len(ckx.ciphertext)-2 {
49                         return nil, errClientKeyExchange
50                 }
51                 ciphertext = ckx.ciphertext[2:]
52         }
53
54         err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
55         if err != nil {
56                 return nil, err
57         }
58         // We don't check the version number in the premaster secret.  For one,
59         // by checking it, we would leak information about the validity of the
60         // encrypted pre-master secret. Secondly, it provides only a small
61         // benefit against a downgrade attack and some implementations send the
62         // wrong version anyway. See the discussion at the end of section
63         // 7.4.7.1 of RFC 4346.
64         return preMasterSecret, nil
65 }
66
67 func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
68         return errors.New("tls: unexpected ServerKeyExchange")
69 }
70
71 func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
72         preMasterSecret := make([]byte, 48)
73         vers := clientHello.vers
74         if config.Bugs.RsaClientKeyExchangeVersion != 0 {
75                 vers = config.Bugs.RsaClientKeyExchangeVersion
76         }
77         vers = versionToWire(vers, clientHello.isDTLS)
78         preMasterSecret[0] = byte(vers >> 8)
79         preMasterSecret[1] = byte(vers)
80         _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
81         if err != nil {
82                 return nil, nil, err
83         }
84
85         encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
86         if err != nil {
87                 return nil, nil, err
88         }
89         ckx := new(clientKeyExchangeMsg)
90         if clientHello.vers != VersionSSL30 && !config.Bugs.SSL3RSAKeyExchange {
91                 ckx.ciphertext = make([]byte, len(encrypted)+2)
92                 ckx.ciphertext[0] = byte(len(encrypted) >> 8)
93                 ckx.ciphertext[1] = byte(len(encrypted))
94                 copy(ckx.ciphertext[2:], encrypted)
95         } else {
96                 ckx.ciphertext = encrypted
97         }
98         return preMasterSecret, ckx, nil
99 }
100
101 // sha1Hash calculates a SHA1 hash over the given byte slices.
102 func sha1Hash(slices [][]byte) []byte {
103         hsha1 := sha1.New()
104         for _, slice := range slices {
105                 hsha1.Write(slice)
106         }
107         return hsha1.Sum(nil)
108 }
109
110 // md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
111 // concatenation of an MD5 and SHA1 hash.
112 func md5SHA1Hash(slices [][]byte) []byte {
113         md5sha1 := make([]byte, md5.Size+sha1.Size)
114         hmd5 := md5.New()
115         for _, slice := range slices {
116                 hmd5.Write(slice)
117         }
118         copy(md5sha1, hmd5.Sum(nil))
119         copy(md5sha1[md5.Size:], sha1Hash(slices))
120         return md5sha1
121 }
122
123 // sha256Hash implements TLS 1.2's hash function.
124 func sha256Hash(slices [][]byte) []byte {
125         h := sha256.New()
126         for _, slice := range slices {
127                 h.Write(slice)
128         }
129         return h.Sum(nil)
130 }
131
132 // hashForServerKeyExchange hashes the given slices and returns their digest
133 // and the identifier of the hash function used. The hashFunc argument is only
134 // used for >= TLS 1.2 and precisely identifies the hash function to use.
135 func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
136         if version >= VersionTLS12 {
137                 switch hashFunc {
138                 case hashSHA256:
139                         return sha256Hash(slices), crypto.SHA256, nil
140                 case hashSHA1:
141                         return sha1Hash(slices), crypto.SHA1, nil
142                 default:
143                         return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer")
144                 }
145         }
146         if sigType == signatureECDSA {
147                 return sha1Hash(slices), crypto.SHA1, nil
148         }
149         return md5SHA1Hash(slices), crypto.MD5SHA1, nil
150 }
151
152 // pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a
153 // ServerKeyExchange given the signature type being used and the client's
154 // advertized list of supported signature and hash combinations.
155 func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) {
156         if len(clientSignatureAndHashes) == 0 {
157                 // If the client didn't specify any signature_algorithms
158                 // extension then we can assume that it supports SHA1. See
159                 // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
160                 return hashSHA1, nil
161         }
162
163         for _, sigAndHash := range clientSignatureAndHashes {
164                 if sigAndHash.signature != sigType {
165                         continue
166                 }
167                 switch sigAndHash.hash {
168                 case hashSHA1, hashSHA256:
169                         return sigAndHash.hash, nil
170                 }
171         }
172
173         return 0, errors.New("tls: client doesn't support any common hash functions")
174 }
175
176 func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
177         switch id {
178         case CurveP256:
179                 return elliptic.P256(), true
180         case CurveP384:
181                 return elliptic.P384(), true
182         case CurveP521:
183                 return elliptic.P521(), true
184         default:
185                 return nil, false
186         }
187
188 }
189
190 // keyAgreementAuthentication is a helper interface that specifies how
191 // to authenticate the ServerKeyExchange parameters.
192 type keyAgreementAuthentication interface {
193         signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error)
194         verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error
195 }
196
197 // nilKeyAgreementAuthentication does not authenticate the key
198 // agreement parameters.
199 type nilKeyAgreementAuthentication struct{}
200
201 func (ka *nilKeyAgreementAuthentication) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
202         skx := new(serverKeyExchangeMsg)
203         skx.key = params
204         return skx, nil
205 }
206
207 func (ka *nilKeyAgreementAuthentication) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error {
208         return nil
209 }
210
211 // signedKeyAgreement signs the ServerKeyExchange parameters with the
212 // server's private key.
213 type signedKeyAgreement struct {
214         version uint16
215         sigType uint8
216 }
217
218 func (ka *signedKeyAgreement) signParameters(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg, params []byte) (*serverKeyExchangeMsg, error) {
219         var tls12HashId uint8
220         var err error
221         if ka.version >= VersionTLS12 {
222                 if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
223                         return nil, err
224                 }
225         }
226
227         digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, params)
228         if err != nil {
229                 return nil, err
230         }
231
232         if config.Bugs.InvalidSKXSignature {
233                 digest[0] ^= 0x80
234         }
235
236         var sig []byte
237         switch ka.sigType {
238         case signatureECDSA:
239                 privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
240                 if !ok {
241                         return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
242                 }
243                 r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
244                 if err != nil {
245                         return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
246                 }
247                 order := privKey.Curve.Params().N
248                 r = maybeCorruptECDSAValue(r, config.Bugs.BadECDSAR, order)
249                 s = maybeCorruptECDSAValue(s, config.Bugs.BadECDSAS, order)
250                 sig, err = asn1.Marshal(ecdsaSignature{r, s})
251         case signatureRSA:
252                 privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
253                 if !ok {
254                         return nil, errors.New("ECDHE RSA requires a RSA server private key")
255                 }
256                 sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
257                 if err != nil {
258                         return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
259                 }
260         default:
261                 return nil, errors.New("unknown ECDHE signature algorithm")
262         }
263
264         skx := new(serverKeyExchangeMsg)
265         if config.Bugs.UnauthenticatedECDH {
266                 skx.key = params
267         } else {
268                 sigAndHashLen := 0
269                 if ka.version >= VersionTLS12 {
270                         sigAndHashLen = 2
271                 }
272                 skx.key = make([]byte, len(params)+sigAndHashLen+2+len(sig))
273                 copy(skx.key, params)
274                 k := skx.key[len(params):]
275                 if ka.version >= VersionTLS12 {
276                         k[0] = tls12HashId
277                         k[1] = ka.sigType
278                         k = k[2:]
279                 }
280                 k[0] = byte(len(sig) >> 8)
281                 k[1] = byte(len(sig))
282                 copy(k[2:], sig)
283         }
284
285         return skx, nil
286 }
287
288 func (ka *signedKeyAgreement) verifyParameters(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, params []byte, sig []byte) error {
289         if len(sig) < 2 {
290                 return errServerKeyExchange
291         }
292
293         var tls12HashId uint8
294         if ka.version >= VersionTLS12 {
295                 // handle SignatureAndHashAlgorithm
296                 var sigAndHash []uint8
297                 sigAndHash, sig = sig[:2], sig[2:]
298                 if sigAndHash[1] != ka.sigType {
299                         return errServerKeyExchange
300                 }
301                 tls12HashId = sigAndHash[0]
302                 if len(sig) < 2 {
303                         return errServerKeyExchange
304                 }
305         }
306         sigLen := int(sig[0])<<8 | int(sig[1])
307         if sigLen+2 != len(sig) {
308                 return errServerKeyExchange
309         }
310         sig = sig[2:]
311
312         digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, params)
313         if err != nil {
314                 return err
315         }
316         switch ka.sigType {
317         case signatureECDSA:
318                 pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
319                 if !ok {
320                         return errors.New("ECDHE ECDSA requires a ECDSA server public key")
321                 }
322                 ecdsaSig := new(ecdsaSignature)
323                 if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
324                         return err
325                 }
326                 if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
327                         return errors.New("ECDSA signature contained zero or negative values")
328                 }
329                 if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
330                         return errors.New("ECDSA verification failure")
331                 }
332         case signatureRSA:
333                 pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
334                 if !ok {
335                         return errors.New("ECDHE RSA requires a RSA server public key")
336                 }
337                 if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
338                         return err
339                 }
340         default:
341                 return errors.New("unknown ECDHE signature algorithm")
342         }
343
344         return nil
345 }
346
347 // ecdheRSAKeyAgreement implements a TLS key agreement where the server
348 // generates a ephemeral EC public/private key pair and signs it. The
349 // pre-master secret is then calculated using ECDH. The signature may
350 // either be ECDSA or RSA.
351 type ecdheKeyAgreement struct {
352         auth       keyAgreementAuthentication
353         privateKey []byte
354         curve      elliptic.Curve
355         x, y       *big.Int
356 }
357
358 func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int {
359         switch typeOfCorruption {
360         case BadValueNone:
361                 return n
362         case BadValueNegative:
363                 return new(big.Int).Neg(n)
364         case BadValueZero:
365                 return big.NewInt(0)
366         case BadValueLimit:
367                 return limit
368         case BadValueLarge:
369                 bad := new(big.Int).Set(limit)
370                 return bad.Lsh(bad, 20)
371         default:
372                 panic("unknown BadValue type")
373         }
374 }
375
376 func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
377         var curveid CurveID
378         preferredCurves := config.curvePreferences()
379
380 NextCandidate:
381         for _, candidate := range preferredCurves {
382                 for _, c := range clientHello.supportedCurves {
383                         if candidate == c {
384                                 curveid = c
385                                 break NextCandidate
386                         }
387                 }
388         }
389
390         if curveid == 0 {
391                 return nil, errors.New("tls: no supported elliptic curves offered")
392         }
393
394         var ok bool
395         if ka.curve, ok = curveForCurveID(curveid); !ok {
396                 return nil, errors.New("tls: preferredCurves includes unsupported curve")
397         }
398
399         var x, y *big.Int
400         var err error
401         ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
402         if err != nil {
403                 return nil, err
404         }
405         ecdhePublic := elliptic.Marshal(ka.curve, x, y)
406
407         // http://tools.ietf.org/html/rfc4492#section-5.4
408         serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
409         serverECDHParams[0] = 3 // named curve
410         serverECDHParams[1] = byte(curveid >> 8)
411         serverECDHParams[2] = byte(curveid)
412         if config.Bugs.InvalidSKXCurve {
413                 serverECDHParams[2] ^= 0xff
414         }
415         serverECDHParams[3] = byte(len(ecdhePublic))
416         copy(serverECDHParams[4:], ecdhePublic)
417
418         return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
419 }
420
421 func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
422         if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
423                 return nil, errClientKeyExchange
424         }
425         x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
426         if x == nil {
427                 return nil, errClientKeyExchange
428         }
429         x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
430         preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
431         xBytes := x.Bytes()
432         copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
433
434         return preMasterSecret, nil
435 }
436
437 func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
438         if len(skx.key) < 4 {
439                 return errServerKeyExchange
440         }
441         if skx.key[0] != 3 { // named curve
442                 return errors.New("tls: server selected unsupported curve")
443         }
444         curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
445
446         var ok bool
447         if ka.curve, ok = curveForCurveID(curveid); !ok {
448                 return errors.New("tls: server selected unsupported curve")
449         }
450
451         publicLen := int(skx.key[3])
452         if publicLen+4 > len(skx.key) {
453                 return errServerKeyExchange
454         }
455         ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
456         if ka.x == nil {
457                 return errServerKeyExchange
458         }
459         serverECDHParams := skx.key[:4+publicLen]
460         sig := skx.key[4+publicLen:]
461
462         return ka.auth.verifyParameters(config, clientHello, serverHello, cert, serverECDHParams, sig)
463 }
464
465 func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
466         if ka.curve == nil {
467                 return nil, nil, errors.New("missing ServerKeyExchange message")
468         }
469         priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
470         if err != nil {
471                 return nil, nil, err
472         }
473         x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
474         preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
475         xBytes := x.Bytes()
476         copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
477
478         serialized := elliptic.Marshal(ka.curve, mx, my)
479
480         ckx := new(clientKeyExchangeMsg)
481         ckx.ciphertext = make([]byte, 1+len(serialized))
482         ckx.ciphertext[0] = byte(len(serialized))
483         copy(ckx.ciphertext[1:], serialized)
484
485         return preMasterSecret, ckx, nil
486 }
487
488 // dheRSAKeyAgreement implements a TLS key agreement where the server generates
489 // an ephemeral Diffie-Hellman public/private key pair and signs it. The
490 // pre-master secret is then calculated using Diffie-Hellman.
491 type dheKeyAgreement struct {
492         auth    keyAgreementAuthentication
493         p, g    *big.Int
494         yTheirs *big.Int
495         xOurs   *big.Int
496 }
497
498 func (ka *dheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
499         // 2048-bit MODP Group with 256-bit Prime Order Subgroup (RFC
500         // 5114, Section 2.3)
501         ka.p, _ = new(big.Int).SetString("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597", 16)
502         ka.g, _ = new(big.Int).SetString("3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659", 16)
503         q, _ := new(big.Int).SetString("8CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3", 16)
504
505         var err error
506         ka.xOurs, err = rand.Int(config.rand(), q)
507         if err != nil {
508                 return nil, err
509         }
510         yOurs := new(big.Int).Exp(ka.g, ka.xOurs, ka.p)
511
512         // http://tools.ietf.org/html/rfc5246#section-7.4.3
513         pBytes := ka.p.Bytes()
514         gBytes := ka.g.Bytes()
515         yBytes := yOurs.Bytes()
516         serverDHParams := make([]byte, 0, 2+len(pBytes)+2+len(gBytes)+2+len(yBytes))
517         serverDHParams = append(serverDHParams, byte(len(pBytes)>>8), byte(len(pBytes)))
518         serverDHParams = append(serverDHParams, pBytes...)
519         serverDHParams = append(serverDHParams, byte(len(gBytes)>>8), byte(len(gBytes)))
520         serverDHParams = append(serverDHParams, gBytes...)
521         serverDHParams = append(serverDHParams, byte(len(yBytes)>>8), byte(len(yBytes)))
522         serverDHParams = append(serverDHParams, yBytes...)
523
524         return ka.auth.signParameters(config, cert, clientHello, hello, serverDHParams)
525 }
526
527 func (ka *dheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
528         if len(ckx.ciphertext) < 2 {
529                 return nil, errClientKeyExchange
530         }
531         yLen := (int(ckx.ciphertext[0]) << 8) | int(ckx.ciphertext[1])
532         if yLen != len(ckx.ciphertext)-2 {
533                 return nil, errClientKeyExchange
534         }
535         yTheirs := new(big.Int).SetBytes(ckx.ciphertext[2:])
536         if yTheirs.Sign() <= 0 || yTheirs.Cmp(ka.p) >= 0 {
537                 return nil, errClientKeyExchange
538         }
539         return new(big.Int).Exp(yTheirs, ka.xOurs, ka.p).Bytes(), nil
540 }
541
542 func (ka *dheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
543         // Read dh_p
544         k := skx.key
545         if len(k) < 2 {
546                 return errServerKeyExchange
547         }
548         pLen := (int(k[0]) << 8) | int(k[1])
549         k = k[2:]
550         if len(k) < pLen {
551                 return errServerKeyExchange
552         }
553         ka.p = new(big.Int).SetBytes(k[:pLen])
554         k = k[pLen:]
555
556         // Read dh_g
557         if len(k) < 2 {
558                 return errServerKeyExchange
559         }
560         gLen := (int(k[0]) << 8) | int(k[1])
561         k = k[2:]
562         if len(k) < gLen {
563                 return errServerKeyExchange
564         }
565         ka.g = new(big.Int).SetBytes(k[:gLen])
566         k = k[gLen:]
567
568         // Read dh_Ys
569         if len(k) < 2 {
570                 return errServerKeyExchange
571         }
572         yLen := (int(k[0]) << 8) | int(k[1])
573         k = k[2:]
574         if len(k) < yLen {
575                 return errServerKeyExchange
576         }
577         ka.yTheirs = new(big.Int).SetBytes(k[:yLen])
578         k = k[yLen:]
579         if ka.yTheirs.Sign() <= 0 || ka.yTheirs.Cmp(ka.p) >= 0 {
580                 return errServerKeyExchange
581         }
582
583         sig := k
584         serverDHParams := skx.key[:len(skx.key)-len(sig)]
585
586         return ka.auth.verifyParameters(config, clientHello, serverHello, cert, serverDHParams, sig)
587 }
588
589 func (ka *dheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
590         if ka.p == nil || ka.g == nil || ka.yTheirs == nil {
591                 return nil, nil, errors.New("missing ServerKeyExchange message")
592         }
593
594         xOurs, err := rand.Int(config.rand(), ka.p)
595         if err != nil {
596                 return nil, nil, err
597         }
598         preMasterSecret := new(big.Int).Exp(ka.yTheirs, xOurs, ka.p).Bytes()
599
600         yOurs := new(big.Int).Exp(ka.g, xOurs, ka.p)
601         yBytes := yOurs.Bytes()
602         ckx := new(clientKeyExchangeMsg)
603         ckx.ciphertext = make([]byte, 2+len(yBytes))
604         ckx.ciphertext[0] = byte(len(yBytes) >> 8)
605         ckx.ciphertext[1] = byte(len(yBytes))
606         copy(ckx.ciphertext[2:], yBytes)
607
608         return preMasterSecret, ckx, nil
609 }
610
611 // nilKeyAgreement is a fake key agreement used to implement the plain PSK key
612 // exchange.
613 type nilKeyAgreement struct{}
614
615 func (ka *nilKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
616         return nil, nil
617 }
618
619 func (ka *nilKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
620         if len(ckx.ciphertext) != 0 {
621                 return nil, errClientKeyExchange
622         }
623
624         // Although in plain PSK, otherSecret is all zeros, the base key
625         // agreement does not access to the length of the pre-shared
626         // key. pskKeyAgreement instead interprets nil to mean to use all zeros
627         // of the appropriate length.
628         return nil, nil
629 }
630
631 func (ka *nilKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
632         if len(skx.key) != 0 {
633                 return errServerKeyExchange
634         }
635         return nil
636 }
637
638 func (ka *nilKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
639         // Although in plain PSK, otherSecret is all zeros, the base key
640         // agreement does not access to the length of the pre-shared
641         // key. pskKeyAgreement instead interprets nil to mean to use all zeros
642         // of the appropriate length.
643         return nil, &clientKeyExchangeMsg{}, nil
644 }
645
646 // makePSKPremaster formats a PSK pre-master secret based on otherSecret from
647 // the base key exchange and psk.
648 func makePSKPremaster(otherSecret, psk []byte) []byte {
649         out := make([]byte, 0, 2+len(otherSecret)+2+len(psk))
650         out = append(out, byte(len(otherSecret)>>8), byte(len(otherSecret)))
651         out = append(out, otherSecret...)
652         out = append(out, byte(len(psk)>>8), byte(len(psk)))
653         out = append(out, psk...)
654         return out
655 }
656
657 // pskKeyAgreement implements the PSK key agreement.
658 type pskKeyAgreement struct {
659         base         keyAgreement
660         identityHint string
661 }
662
663 func (ka *pskKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
664         // Assemble the identity hint.
665         bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
666         bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
667         bytes[1] = byte(len(config.PreSharedKeyIdentity))
668         copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
669
670         // If there is one, append the base key agreement's
671         // ServerKeyExchange.
672         baseSkx, err := ka.base.generateServerKeyExchange(config, cert, clientHello, hello)
673         if err != nil {
674                 return nil, err
675         }
676
677         if baseSkx != nil {
678                 bytes = append(bytes, baseSkx.key...)
679         } else if config.PreSharedKeyIdentity == "" {
680                 // ServerKeyExchange is optional if the identity hint is empty
681                 // and there would otherwise be no ServerKeyExchange.
682                 return nil, nil
683         }
684
685         skx := new(serverKeyExchangeMsg)
686         skx.key = bytes
687         return skx, nil
688 }
689
690 func (ka *pskKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
691         // First, process the PSK identity.
692         if len(ckx.ciphertext) < 2 {
693                 return nil, errClientKeyExchange
694         }
695         identityLen := (int(ckx.ciphertext[0]) << 8) | int(ckx.ciphertext[1])
696         if 2+identityLen > len(ckx.ciphertext) {
697                 return nil, errClientKeyExchange
698         }
699         identity := string(ckx.ciphertext[2 : 2+identityLen])
700
701         if identity != config.PreSharedKeyIdentity {
702                 return nil, errors.New("tls: unexpected identity")
703         }
704
705         if config.PreSharedKey == nil {
706                 return nil, errors.New("tls: pre-shared key not configured")
707         }
708
709         // Process the remainder of the ClientKeyExchange to compute the base
710         // pre-master secret.
711         newCkx := new(clientKeyExchangeMsg)
712         newCkx.ciphertext = ckx.ciphertext[2+identityLen:]
713         otherSecret, err := ka.base.processClientKeyExchange(config, cert, newCkx, version)
714         if err != nil {
715                 return nil, err
716         }
717
718         if otherSecret == nil {
719                 // Special-case for the plain PSK key exchanges.
720                 otherSecret = make([]byte, len(config.PreSharedKey))
721         }
722         return makePSKPremaster(otherSecret, config.PreSharedKey), nil
723 }
724
725 func (ka *pskKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
726         if len(skx.key) < 2 {
727                 return errServerKeyExchange
728         }
729         identityLen := (int(skx.key[0]) << 8) | int(skx.key[1])
730         if 2+identityLen > len(skx.key) {
731                 return errServerKeyExchange
732         }
733         ka.identityHint = string(skx.key[2 : 2+identityLen])
734
735         // Process the remainder of the ServerKeyExchange.
736         newSkx := new(serverKeyExchangeMsg)
737         newSkx.key = skx.key[2+identityLen:]
738         return ka.base.processServerKeyExchange(config, clientHello, serverHello, cert, newSkx)
739 }
740
741 func (ka *pskKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
742         // The server only sends an identity hint but, for purposes of
743         // test code, the server always sends the hint and it is
744         // required to match.
745         if ka.identityHint != config.PreSharedKeyIdentity {
746                 return nil, nil, errors.New("tls: unexpected identity")
747         }
748
749         // Serialize the identity.
750         bytes := make([]byte, 2+len(config.PreSharedKeyIdentity))
751         bytes[0] = byte(len(config.PreSharedKeyIdentity) >> 8)
752         bytes[1] = byte(len(config.PreSharedKeyIdentity))
753         copy(bytes[2:], []byte(config.PreSharedKeyIdentity))
754
755         // Append the base key exchange's ClientKeyExchange.
756         otherSecret, baseCkx, err := ka.base.generateClientKeyExchange(config, clientHello, cert)
757         if err != nil {
758                 return nil, nil, err
759         }
760         ckx := new(clientKeyExchangeMsg)
761         ckx.ciphertext = append(bytes, baseCkx.ciphertext...)
762
763         if config.PreSharedKey == nil {
764                 return nil, nil, errors.New("tls: pre-shared key not configured")
765         }
766         if otherSecret == nil {
767                 otherSecret = make([]byte, len(config.PreSharedKey))
768         }
769         return makePSKPremaster(otherSecret, config.PreSharedKey), ckx, nil
770 }