Daily bump.
[official-gcc.git] / libgo / go / crypto / tls / key_agreement.go
blob7e820c1e7e91c978e41f489fa04ddfae80899c24
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.
5 package tls
7 import (
8 "crypto"
9 "crypto/ecdsa"
10 "crypto/elliptic"
11 "crypto/md5"
12 "crypto/rsa"
13 "crypto/sha1"
14 "crypto/sha256"
15 "crypto/x509"
16 "encoding/asn1"
17 "errors"
18 "io"
19 "math/big"
22 // rsaKeyAgreement implements the standard TLS key agreement where the client
23 // encrypts the pre-master secret to the server's public key.
24 type rsaKeyAgreement struct{}
26 func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
27 return nil, nil
30 func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
31 preMasterSecret := make([]byte, 48)
32 _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
33 if err != nil {
34 return nil, err
37 if len(ckx.ciphertext) < 2 {
38 return nil, errors.New("bad ClientKeyExchange")
41 ciphertext := ckx.ciphertext
42 if version != VersionSSL30 {
43 ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
44 if ciphertextLen != len(ckx.ciphertext)-2 {
45 return nil, errors.New("bad ClientKeyExchange")
47 ciphertext = ckx.ciphertext[2:]
50 err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
51 if err != nil {
52 return nil, err
54 // We don't check the version number in the premaster secret. For one,
55 // by checking it, we would leak information about the validity of the
56 // encrypted pre-master secret. Secondly, it provides only a small
57 // benefit against a downgrade attack and some implementations send the
58 // wrong version anyway. See the discussion at the end of section
59 // 7.4.7.1 of RFC 4346.
60 return preMasterSecret, nil
63 func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
64 return errors.New("unexpected ServerKeyExchange")
67 func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
68 preMasterSecret := make([]byte, 48)
69 preMasterSecret[0] = byte(clientHello.vers >> 8)
70 preMasterSecret[1] = byte(clientHello.vers)
71 _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
72 if err != nil {
73 return nil, nil, err
76 encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
77 if err != nil {
78 return nil, nil, err
80 ckx := new(clientKeyExchangeMsg)
81 ckx.ciphertext = make([]byte, len(encrypted)+2)
82 ckx.ciphertext[0] = byte(len(encrypted) >> 8)
83 ckx.ciphertext[1] = byte(len(encrypted))
84 copy(ckx.ciphertext[2:], encrypted)
85 return preMasterSecret, ckx, nil
88 // sha1Hash calculates a SHA1 hash over the given byte slices.
89 func sha1Hash(slices [][]byte) []byte {
90 hsha1 := sha1.New()
91 for _, slice := range slices {
92 hsha1.Write(slice)
94 return hsha1.Sum(nil)
97 // md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
98 // concatenation of an MD5 and SHA1 hash.
99 func md5SHA1Hash(slices [][]byte) []byte {
100 md5sha1 := make([]byte, md5.Size+sha1.Size)
101 hmd5 := md5.New()
102 for _, slice := range slices {
103 hmd5.Write(slice)
105 copy(md5sha1, hmd5.Sum(nil))
106 copy(md5sha1[md5.Size:], sha1Hash(slices))
107 return md5sha1
110 // sha256Hash implements TLS 1.2's hash function.
111 func sha256Hash(slices [][]byte) []byte {
112 h := sha256.New()
113 for _, slice := range slices {
114 h.Write(slice)
116 return h.Sum(nil)
119 // hashForServerKeyExchange hashes the given slices and returns their digest
120 // and the identifier of the hash function used. The hashFunc argument is only
121 // used for >= TLS 1.2 and precisely identifies the hash function to use.
122 func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
123 if version >= VersionTLS12 {
124 switch hashFunc {
125 case hashSHA256:
126 return sha256Hash(slices), crypto.SHA256, nil
127 case hashSHA1:
128 return sha1Hash(slices), crypto.SHA1, nil
129 default:
130 return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer")
133 if sigType == signatureECDSA {
134 return sha1Hash(slices), crypto.SHA1, nil
136 return md5SHA1Hash(slices), crypto.MD5SHA1, nil
139 // pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a
140 // ServerKeyExchange given the signature type being used and the client's
141 // advertized list of supported signature and hash combinations.
142 func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) {
143 if len(clientSignatureAndHashes) == 0 {
144 // If the client didn't specify any signature_algorithms
145 // extension then we can assume that it supports SHA1. See
146 // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
147 return hashSHA1, nil
150 for _, sigAndHash := range clientSignatureAndHashes {
151 if sigAndHash.signature != sigType {
152 continue
154 switch sigAndHash.hash {
155 case hashSHA1, hashSHA256:
156 return sigAndHash.hash, nil
160 return 0, errors.New("tls: client doesn't support any common hash functions")
163 // ecdheRSAKeyAgreement implements a TLS key agreement where the server
164 // generates a ephemeral EC public/private key pair and signs it. The
165 // pre-master secret is then calculated using ECDH. The signature may
166 // either be ECDSA or RSA.
167 type ecdheKeyAgreement struct {
168 version uint16
169 sigType uint8
170 privateKey []byte
171 curve elliptic.Curve
172 x, y *big.Int
175 func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
176 var curveid uint16
178 Curve:
179 for _, c := range clientHello.supportedCurves {
180 switch c {
181 case curveP256:
182 ka.curve = elliptic.P256()
183 curveid = c
184 break Curve
185 case curveP384:
186 ka.curve = elliptic.P384()
187 curveid = c
188 break Curve
189 case curveP521:
190 ka.curve = elliptic.P521()
191 curveid = c
192 break Curve
196 if curveid == 0 {
197 return nil, errors.New("tls: no supported elliptic curves offered")
200 var x, y *big.Int
201 var err error
202 ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
203 if err != nil {
204 return nil, err
206 ecdhePublic := elliptic.Marshal(ka.curve, x, y)
208 // http://tools.ietf.org/html/rfc4492#section-5.4
209 serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
210 serverECDHParams[0] = 3 // named curve
211 serverECDHParams[1] = byte(curveid >> 8)
212 serverECDHParams[2] = byte(curveid)
213 serverECDHParams[3] = byte(len(ecdhePublic))
214 copy(serverECDHParams[4:], ecdhePublic)
216 var tls12HashId uint8
217 if ka.version >= VersionTLS12 {
218 if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
219 return nil, err
223 digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams)
224 if err != nil {
225 return nil, err
227 var sig []byte
228 switch ka.sigType {
229 case signatureECDSA:
230 privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
231 if !ok {
232 return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
234 r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
235 if err != nil {
236 return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
238 sig, err = asn1.Marshal(ecdsaSignature{r, s})
239 case signatureRSA:
240 privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
241 if !ok {
242 return nil, errors.New("ECDHE RSA requires a RSA server private key")
244 sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
245 if err != nil {
246 return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
248 default:
249 return nil, errors.New("unknown ECDHE signature algorithm")
252 skx := new(serverKeyExchangeMsg)
253 sigAndHashLen := 0
254 if ka.version >= VersionTLS12 {
255 sigAndHashLen = 2
257 skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
258 copy(skx.key, serverECDHParams)
259 k := skx.key[len(serverECDHParams):]
260 if ka.version >= VersionTLS12 {
261 k[0] = tls12HashId
262 k[1] = ka.sigType
263 k = k[2:]
265 k[0] = byte(len(sig) >> 8)
266 k[1] = byte(len(sig))
267 copy(k[2:], sig)
269 return skx, nil
272 func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
273 if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
274 return nil, errors.New("bad ClientKeyExchange")
276 x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
277 if x == nil {
278 return nil, errors.New("bad ClientKeyExchange")
280 x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
281 preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
282 xBytes := x.Bytes()
283 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
285 return preMasterSecret, nil
288 var errServerKeyExchange = errors.New("invalid ServerKeyExchange")
290 func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
291 if len(skx.key) < 4 {
292 return errServerKeyExchange
294 if skx.key[0] != 3 { // named curve
295 return errors.New("server selected unsupported curve")
297 curveid := uint16(skx.key[1])<<8 | uint16(skx.key[2])
299 switch curveid {
300 case curveP256:
301 ka.curve = elliptic.P256()
302 case curveP384:
303 ka.curve = elliptic.P384()
304 case curveP521:
305 ka.curve = elliptic.P521()
306 default:
307 return errors.New("server selected unsupported curve")
310 publicLen := int(skx.key[3])
311 if publicLen+4 > len(skx.key) {
312 return errServerKeyExchange
314 ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
315 if ka.x == nil {
316 return errServerKeyExchange
318 serverECDHParams := skx.key[:4+publicLen]
320 sig := skx.key[4+publicLen:]
321 if len(sig) < 2 {
322 return errServerKeyExchange
325 var tls12HashId uint8
326 if ka.version >= VersionTLS12 {
327 // handle SignatureAndHashAlgorithm
328 var sigAndHash []uint8
329 sigAndHash, sig = sig[:2], sig[2:]
330 if sigAndHash[1] != ka.sigType {
331 return errServerKeyExchange
333 tls12HashId = sigAndHash[0]
334 if len(sig) < 2 {
335 return errServerKeyExchange
338 sigLen := int(sig[0])<<8 | int(sig[1])
339 if sigLen+2 != len(sig) {
340 return errServerKeyExchange
342 sig = sig[2:]
344 digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams)
345 if err != nil {
346 return err
348 switch ka.sigType {
349 case signatureECDSA:
350 pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
351 if !ok {
352 return errors.New("ECDHE ECDSA requires a ECDSA server public key")
354 ecdsaSig := new(ecdsaSignature)
355 if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
356 return err
358 if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
359 return errors.New("ECDSA signature contained zero or negative values")
361 if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
362 return errors.New("ECDSA verification failure")
364 case signatureRSA:
365 pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
366 if !ok {
367 return errors.New("ECDHE RSA requires a RSA server public key")
369 if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
370 return err
372 default:
373 return errors.New("unknown ECDHE signature algorithm")
376 return nil
379 func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
380 if ka.curve == nil {
381 return nil, nil, errors.New("missing ServerKeyExchange message")
383 priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
384 if err != nil {
385 return nil, nil, err
387 x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
388 preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
389 xBytes := x.Bytes()
390 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
392 serialized := elliptic.Marshal(ka.curve, mx, my)
394 ckx := new(clientKeyExchangeMsg)
395 ckx.ciphertext = make([]byte, 1+len(serialized))
396 ckx.ciphertext[0] = byte(len(serialized))
397 copy(ckx.ciphertext[1:], serialized)
399 return preMasterSecret, ckx, nil