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.
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
) {
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:])
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
)
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:])
76 encrypted
, err
:= rsa
.EncryptPKCS1v15(config
.rand(), cert
.PublicKey
.(*rsa
.PublicKey
), preMasterSecret
)
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 {
91 for _
, slice
:= range slices
{
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
)
102 for _
, slice
:= range slices
{
105 copy(md5sha1
, hmd5
.Sum(nil))
106 copy(md5sha1
[md5
.Size
:], sha1Hash(slices
))
110 // sha256Hash implements TLS 1.2's hash function.
111 func sha256Hash(slices
[][]byte) []byte {
113 for _
, slice
:= range slices
{
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
{
126 return sha256Hash(slices
), crypto
.SHA256
, nil
128 return sha1Hash(slices
), crypto
.SHA1
, nil
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
150 for _
, sigAndHash
:= range clientSignatureAndHashes
{
151 if sigAndHash
.signature
!= sigType
{
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 {
175 func (ka
*ecdheKeyAgreement
) generateServerKeyExchange(config
*Config
, cert
*Certificate
, clientHello
*clientHelloMsg
, hello
*serverHelloMsg
) (*serverKeyExchangeMsg
, error
) {
179 for _
, c
:= range clientHello
.supportedCurves
{
182 ka
.curve
= elliptic
.P256()
186 ka
.curve
= elliptic
.P384()
190 ka
.curve
= elliptic
.P521()
197 return nil, errors
.New("tls: no supported elliptic curves offered")
202 ka
.privateKey
, x
, y
, err
= elliptic
.GenerateKey(ka
.curve
, config
.rand())
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 {
223 digest
, hashFunc
, err
:= hashForServerKeyExchange(ka
.sigType
, tls12HashId
, ka
.version
, clientHello
.random
, hello
.random
, serverECDHParams
)
230 privKey
, ok
:= cert
.PrivateKey
.(*ecdsa
.PrivateKey
)
232 return nil, errors
.New("ECDHE ECDSA requires an ECDSA server private key")
234 r
, s
, err
:= ecdsa
.Sign(config
.rand(), privKey
, digest
)
236 return nil, errors
.New("failed to sign ECDHE parameters: " + err
.Error())
238 sig
, err
= asn1
.Marshal(ecdsaSignature
{r
, s
})
240 privKey
, ok
:= cert
.PrivateKey
.(*rsa
.PrivateKey
)
242 return nil, errors
.New("ECDHE RSA requires a RSA server private key")
244 sig
, err
= rsa
.SignPKCS1v15(config
.rand(), privKey
, hashFunc
, digest
)
246 return nil, errors
.New("failed to sign ECDHE parameters: " + err
.Error())
249 return nil, errors
.New("unknown ECDHE signature algorithm")
252 skx
:= new(serverKeyExchangeMsg
)
254 if ka
.version
>= VersionTLS12
{
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
{
265 k
[0] = byte(len(sig
) >> 8)
266 k
[1] = byte(len(sig
))
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:])
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)
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])
301 ka
.curve
= elliptic
.P256()
303 ka
.curve
= elliptic
.P384()
305 ka
.curve
= elliptic
.P521()
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
])
316 return errServerKeyExchange
318 serverECDHParams
:= skx
.key
[:4+publicLen
]
320 sig
:= skx
.key
[4+publicLen
:]
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]
335 return errServerKeyExchange
338 sigLen
:= int(sig
[0])<<8 |
int(sig
[1])
339 if sigLen
+2 != len(sig
) {
340 return errServerKeyExchange
344 digest
, hashFunc
, err
:= hashForServerKeyExchange(ka
.sigType
, tls12HashId
, ka
.version
, clientHello
.random
, serverHello
.random
, serverECDHParams
)
350 pubKey
, ok
:= cert
.PublicKey
.(*ecdsa
.PublicKey
)
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 {
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")
365 pubKey
, ok
:= cert
.PublicKey
.(*rsa
.PublicKey
)
367 return errors
.New("ECDHE RSA requires a RSA server public key")
369 if err
:= rsa
.VerifyPKCS1v15(pubKey
, hashFunc
, digest
, sig
); err
!= nil {
373 return errors
.New("unknown ECDHE signature algorithm")
379 func (ka
*ecdheKeyAgreement
) generateClientKeyExchange(config
*Config
, clientHello
*clientHelloMsg
, cert
*x509
.Certificate
) ([]byte, *clientKeyExchangeMsg
, error
) {
381 return nil, nil, errors
.New("missing ServerKeyExchange message")
383 priv
, mx
, my
, err
:= elliptic
.GenerateKey(ka
.curve
, config
.rand())
387 x
, _
:= ka
.curve
.ScalarMult(ka
.x
, ka
.y
, priv
)
388 preMasterSecret
:= make([]byte, (ka
.curve
.Params().BitSize
+7)>>3)
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