OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [crypto/] [tls/] [key_agreement.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// 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 tls
6
 
7
import (
8
        "crypto"
9
        "crypto/elliptic"
10
        "crypto/md5"
11
        "crypto/rsa"
12
        "crypto/sha1"
13
        "crypto/x509"
14
        "errors"
15
        "io"
16
        "math/big"
17
)
18
 
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{}
22
 
23
func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
24
        return nil, nil
25
}
26
 
27
func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
28
        preMasterSecret := make([]byte, 48)
29
        _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
30
        if err != nil {
31
                return nil, err
32
        }
33
 
34
        if len(ckx.ciphertext) < 2 {
35
                return nil, errors.New("bad ClientKeyExchange")
36
        }
37
 
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")
43
                }
44
                ciphertext = ckx.ciphertext[2:]
45
        }
46
 
47
        err = rsa.DecryptPKCS1v15SessionKey(config.rand(), config.Certificates[0].PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
48
        if err != nil {
49
                return nil, err
50
        }
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
58
}
59
 
60
func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
61
        return errors.New("unexpected ServerKeyExchange")
62
}
63
 
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:])
69
        if err != nil {
70
                return nil, nil, err
71
        }
72
 
73
        encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
74
        if err != nil {
75
                return nil, nil, err
76
        }
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
83
}
84
 
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)
89
        hmd5 := md5.New()
90
        for _, slice := range slices {
91
                hmd5.Write(slice)
92
        }
93
        copy(md5sha1, hmd5.Sum(nil))
94
 
95
        hsha1 := sha1.New()
96
        for _, slice := range slices {
97
                hsha1.Write(slice)
98
        }
99
        copy(md5sha1[md5.Size:], hsha1.Sum(nil))
100
        return md5sha1
101
}
102
 
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 {
107
        privateKey []byte
108
        curve      elliptic.Curve
109
        x, y       *big.Int
110
}
111
 
112
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
113
        var curveid uint16
114
 
115
Curve:
116
        for _, c := range clientHello.supportedCurves {
117
                switch c {
118
                case curveP256:
119
                        ka.curve = elliptic.P256()
120
                        curveid = c
121
                        break Curve
122
                case curveP384:
123
                        ka.curve = elliptic.P384()
124
                        curveid = c
125
                        break Curve
126
                case curveP521:
127
                        ka.curve = elliptic.P521()
128
                        curveid = c
129
                        break Curve
130
                }
131
        }
132
 
133
        var x, y *big.Int
134
        var err error
135
        ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
136
        if err != nil {
137
                return nil, err
138
        }
139
        ecdhePublic := elliptic.Marshal(ka.curve, x, y)
140
 
141
        // http://tools.ietf.org/html/rfc4492#section-5.4
142
        serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
143
        serverECDHParams[0] = 3 // named curve
144
        serverECDHParams[1] = byte(curveid >> 8)
145
        serverECDHParams[2] = byte(curveid)
146
        serverECDHParams[3] = byte(len(ecdhePublic))
147
        copy(serverECDHParams[4:], ecdhePublic)
148
 
149
        md5sha1 := md5SHA1Hash(clientHello.random, hello.random, serverECDHParams)
150
        sig, err := rsa.SignPKCS1v15(config.rand(), config.Certificates[0].PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1)
151
        if err != nil {
152
                return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
153
        }
154
 
155
        skx := new(serverKeyExchangeMsg)
156
        skx.key = make([]byte, len(serverECDHParams)+2+len(sig))
157
        copy(skx.key, serverECDHParams)
158
        k := skx.key[len(serverECDHParams):]
159
        k[0] = byte(len(sig) >> 8)
160
        k[1] = byte(len(sig))
161
        copy(k[2:], sig)
162
 
163
        return skx, nil
164
}
165
 
166
func (ka *ecdheRSAKeyAgreement) processClientKeyExchange(config *Config, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
167
        if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
168
                return nil, errors.New("bad ClientKeyExchange")
169
        }
170
        x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
171
        if x == nil {
172
                return nil, errors.New("bad ClientKeyExchange")
173
        }
174
        x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
175
        preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
176
        xBytes := x.Bytes()
177
        copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
178
 
179
        return preMasterSecret, nil
180
}
181
 
182
var errServerKeyExchange = errors.New("invalid ServerKeyExchange")
183
 
184
func (ka *ecdheRSAKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
185
        if len(skx.key) < 4 {
186
                return errServerKeyExchange
187
        }
188
        if skx.key[0] != 3 { // named curve
189
                return errors.New("server selected unsupported curve")
190
        }
191
        curveid := uint16(skx.key[1])<<8 | uint16(skx.key[2])
192
 
193
        switch curveid {
194
        case curveP256:
195
                ka.curve = elliptic.P256()
196
        case curveP384:
197
                ka.curve = elliptic.P384()
198
        case curveP521:
199
                ka.curve = elliptic.P521()
200
        default:
201
                return errors.New("server selected unsupported curve")
202
        }
203
 
204
        publicLen := int(skx.key[3])
205
        if publicLen+4 > len(skx.key) {
206
                return errServerKeyExchange
207
        }
208
        ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
209
        if ka.x == nil {
210
                return errServerKeyExchange
211
        }
212
        serverECDHParams := skx.key[:4+publicLen]
213
 
214
        sig := skx.key[4+publicLen:]
215
        if len(sig) < 2 {
216
                return errServerKeyExchange
217
        }
218
        sigLen := int(sig[0])<<8 | int(sig[1])
219
        if sigLen+2 != len(sig) {
220
                return errServerKeyExchange
221
        }
222
        sig = sig[2:]
223
 
224
        md5sha1 := md5SHA1Hash(clientHello.random, serverHello.random, serverECDHParams)
225
        return rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), crypto.MD5SHA1, md5sha1, sig)
226
}
227
 
228
func (ka *ecdheRSAKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
229
        if ka.curve == nil {
230
                return nil, nil, errors.New("missing ServerKeyExchange message")
231
        }
232
        priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
233
        if err != nil {
234
                return nil, nil, err
235
        }
236
        x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
237
        preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
238
        xBytes := x.Bytes()
239
        copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
240
 
241
        serialized := elliptic.Marshal(ka.curve, mx, my)
242
 
243
        ckx := new(clientKeyExchangeMsg)
244
        ckx.ciphertext = make([]byte, 1+len(serialized))
245
        ckx.ciphertext[0] = byte(len(serialized))
246
        copy(ckx.ciphertext[1:], serialized)
247
 
248
        return preMasterSecret, ckx, nil
249
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.