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.
19
// rsaKeyAgreement implements the standard TLS key agreement where the client
20
// encrypts the pre-master secret to the server's public key.
21
type rsaKeyAgreement struct{}
23
func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
27
func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
28
preMasterSecret := make([]byte, 48)
29
_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
34
if len(ckx.ciphertext) < 2 {
35
return nil, errors.New("bad ClientKeyExchange")
38
ciphertext := ckx.ciphertext
39
if version != versionSSL30 {
40
ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
41
if ciphertextLen != len(ckx.ciphertext)-2 {
42
return nil, errors.New("bad ClientKeyExchange")
44
ciphertext = ckx.ciphertext[2:]
47
err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
51
// We don't check the version number in the premaster secret. For one,
52
// by checking it, we would leak information about the validity of the
53
// encrypted pre-master secret. Secondly, it provides only a small
54
// benefit against a downgrade attack and some implementations send the
55
// wrong version anyway. See the discussion at the end of section
56
// 7.4.7.1 of RFC 4346.
57
return preMasterSecret, nil
60
func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
61
return errors.New("unexpected ServerKeyExchange")
64
func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
65
preMasterSecret := make([]byte, 48)
66
preMasterSecret[0] = byte(clientHello.vers >> 8)
67
preMasterSecret[1] = byte(clientHello.vers)
68
_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
73
encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
77
ckx := new(clientKeyExchangeMsg)
78
ckx.ciphertext = make([]byte, len(encrypted)+2)
79
ckx.ciphertext[0] = byte(len(encrypted) >> 8)
80
ckx.ciphertext[1] = byte(len(encrypted))
81
copy(ckx.ciphertext[2:], encrypted)
82
return preMasterSecret, ckx, nil
85
// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
86
// concatenation of an MD5 and SHA1 hash.
87
func md5SHA1Hash(slices ...[]byte) []byte {
88
md5sha1 := make([]byte, md5.Size+sha1.Size)
90
for _, slice := range slices {
93
copy(md5sha1, hmd5.Sum(nil))
96
for _, slice := range slices {
99
copy(md5sha1[md5.Size:], hsha1.Sum(nil))
103
// ecdheRSAKeyAgreement implements a TLS key agreement where the server
104
// generates a ephemeral EC public/private key pair and signs it. The
105
// pre-master secret is then calculated using ECDH.
106
type ecdheRSAKeyAgreement struct {
112
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
116
for _, c := range clientHello.supportedCurves {
119
ka.curve = elliptic.P256()
123
ka.curve = elliptic.P384()
127
ka.curve = elliptic.P521()
134
return nil, errors.New("tls: no supported elliptic curves offered")
139
ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
143
ecdhePublic := elliptic.Marshal(ka.curve, x, y)
145
// http://tools.ietf.org/html/rfc4492#section-5.4
146
serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
147
serverECDHParams[0] = 3 // named curve
148
serverECDHParams[1] = byte(curveid >> 8)
149
serverECDHParams[2] = byte(curveid)
150
serverECDHParams[3] = byte(len(ecdhePublic))
151
copy(serverECDHParams[4:], ecdhePublic)
153
md5sha1 := md5SHA1Hash(clientHello.random, hello.random, serverECDHParams)
154
sig, err := rsa.SignPKCS1v15(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1)
156
return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
159
skx := new(serverKeyExchangeMsg)
160
skx.key = make([]byte, len(serverECDHParams)+2+len(sig))
161
copy(skx.key, serverECDHParams)
162
k := skx.key[len(serverECDHParams):]
163
k[0] = byte(len(sig) >> 8)
164
k[1] = byte(len(sig))
170
func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
171
if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
172
return nil, errors.New("bad ClientKeyExchange")
174
x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
176
return nil, errors.New("bad ClientKeyExchange")
178
x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
179
preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
181
copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
183
return preMasterSecret, nil
186
var errServerKeyExchange = errors.New("invalid ServerKeyExchange")
188
func (ka *ecdheRSAKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
189
if len(skx.key) < 4 {
190
return errServerKeyExchange
192
if skx.key[0] != 3 { // named curve
193
return errors.New("server selected unsupported curve")
195
curveid := uint16(skx.key[1])<<8 | uint16(skx.key[2])
199
ka.curve = elliptic.P256()
201
ka.curve = elliptic.P384()
203
ka.curve = elliptic.P521()
205
return errors.New("server selected unsupported curve")
208
publicLen := int(skx.key[3])
209
if publicLen+4 > len(skx.key) {
210
return errServerKeyExchange
212
ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
214
return errServerKeyExchange
216
serverECDHParams := skx.key[:4+publicLen]
218
sig := skx.key[4+publicLen:]
220
return errServerKeyExchange
222
sigLen := int(sig[0])<<8 | int(sig[1])
223
if sigLen+2 != len(sig) {
224
return errServerKeyExchange
228
md5sha1 := md5SHA1Hash(clientHello.random, serverHello.random, serverECDHParams)
229
return rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), crypto.MD5SHA1, md5sha1, sig)
232
func (ka *ecdheRSAKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
234
return nil, nil, errors.New("missing ServerKeyExchange message")
236
priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
240
x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
241
preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
243
copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
245
serialized := elliptic.Marshal(ka.curve, mx, my)
247
ckx := new(clientKeyExchangeMsg)
248
ckx.ciphertext = make([]byte, 1+len(serialized))
249
ckx.ciphertext[0] = byte(len(serialized))
250
copy(ckx.ciphertext[1:], serialized)
252
return preMasterSecret, ckx, nil