1
2
3
4
5 package gmtls
6
7 import (
8 "bytes"
9 "crypto"
10 "crypto/ecdsa"
11 "crypto/elliptic"
12 "encoding/asn1"
13 "errors"
14 "io"
15 "math/big"
16
17 "github.com/tjfoc/gmsm/sm2"
18 "github.com/tjfoc/gmsm/x509"
19
20 "golang.org/x/crypto/curve25519"
21 )
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 type ecdheKeyAgreementGM struct {
59 version uint16
60 privateKey []byte
61 curveid CurveID
62
63
64
65 publicKey []byte
66
67
68 x, y *big.Int
69 }
70
71 func (ka *ecdheKeyAgreementGM) generateServerKeyExchange(config *Config, signCert, cipherCert *Certificate,
72 clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
73 panic("")
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169 }
170
171 func (ka *ecdheKeyAgreementGM) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
172 panic("")
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 }
204
205 func (ka *ecdheKeyAgreementGM) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
206 if len(skx.key) < 4 {
207 return errServerKeyExchange
208 }
209 if skx.key[0] != 3 {
210 return errors.New("tls: server selected unsupported curve")
211 }
212 ka.curveid = CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
213
214 publicLen := int(skx.key[3])
215 if publicLen+4 > len(skx.key) {
216 return errServerKeyExchange
217 }
218 serverECDHParams := skx.key[:4+publicLen]
219 publicKey := serverECDHParams[4:]
220
221 sig := skx.key[4+publicLen:]
222 if len(sig) < 2 {
223 return errServerKeyExchange
224 }
225
226
227 curve := sm2.P256Sm2()
228 ka.x, ka.y = elliptic.Unmarshal(curve, publicKey)
229 if ka.x == nil {
230 return errServerKeyExchange
231 }
232
233 var signatureAlgorithm SignatureScheme
234 _, sigType, hashFunc, err := pickSignatureAlgorithm(cert.PublicKey, []SignatureScheme{signatureAlgorithm}, clientHello.supportedSignatureAlgorithms, ka.version)
235
236 sigLen := int(sig[0])<<8 | int(sig[1])
237 if sigLen+2 != len(sig) {
238 return errServerKeyExchange
239 }
240 sig = sig[2:]
241
242 digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, serverHello.random, serverECDHParams)
243 if err != nil {
244 return err
245 }
246 return verifyHandshakeSignature(sigType, cert.PublicKey, hashFunc, digest, sig)
247 }
248
249 func (ka *ecdheKeyAgreementGM) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
250 if ka.curveid == 0 {
251 return nil, nil, errors.New("tls: missing ServerKeyExchange message")
252 }
253
254 var serialized, preMasterSecret []byte
255
256 if ka.curveid == X25519 {
257 var ourPublic, theirPublic, sharedKey, scalar [32]byte
258
259 if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil {
260 return nil, nil, err
261 }
262
263 copy(theirPublic[:], ka.publicKey)
264 curve25519.ScalarBaseMult(&ourPublic, &scalar)
265 curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic)
266 serialized = ourPublic[:]
267 preMasterSecret = sharedKey[:]
268 } else {
269 curve, ok := curveForCurveID(ka.curveid)
270 if !ok {
271 panic("internal error")
272 }
273 priv, mx, my, err := elliptic.GenerateKey(curve, config.rand())
274 if err != nil {
275 return nil, nil, err
276 }
277 x, _ := curve.ScalarMult(ka.x, ka.y, priv)
278 preMasterSecret = make([]byte, (curve.Params().BitSize+7)>>3)
279 xBytes := x.Bytes()
280 copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
281
282 serialized = elliptic.Marshal(curve, mx, my)
283 }
284
285 ckx := new(clientKeyExchangeMsg)
286 ckx.ciphertext = make([]byte, 1+len(serialized))
287 ckx.ciphertext[0] = byte(len(serialized))
288 copy(ckx.ciphertext[1:], serialized)
289
290 return preMasterSecret, ckx, nil
291 }
292
293
294
295
296 type eccKeyAgreementGM struct {
297 version uint16
298 privateKey []byte
299 curveid CurveID
300
301
302
303 publicKey []byte
304
305
306 x, y *big.Int
307
308
309 encipherCert *x509.Certificate
310 }
311
312 func (ka *eccKeyAgreementGM) generateServerKeyExchange(config *Config, signCert, cipherCert *Certificate,
313 clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
314
315
316 digest := ka.hashForServerKeyExchange(clientHello.random, hello.random, cipherCert.Certificate[0])
317
318 priv, ok := signCert.PrivateKey.(crypto.Signer)
319 if !ok {
320 return nil, errors.New("tls: certificate private key does not implement crypto.Signer")
321 }
322 sig, err := priv.Sign(config.rand(), digest, nil)
323 if err != nil {
324 return nil, err
325 }
326
327 len := len(sig)
328
329 ske := new(serverKeyExchangeMsg)
330 ske.key = make([]byte, len+2)
331 ske.key[0] = byte(len >> 8)
332 ske.key[1] = byte(len)
333 copy(ske.key[2:], sig)
334
335 return ske, nil
336 }
337
338 func (ka *eccKeyAgreementGM) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
339 if len(ckx.ciphertext) == 0 {
340 return nil, errClientKeyExchange
341 }
342
343 if int(ckx.ciphertext[0]<<8|ckx.ciphertext[1]) != len(ckx.ciphertext)-2 {
344 return nil, errClientKeyExchange
345 }
346
347 cipher := ckx.ciphertext[2:]
348
349 decrypter, ok := cert.PrivateKey.(crypto.Decrypter)
350 if !ok {
351 return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter")
352 }
353
354 cipher, err := sm2.CipherUnmarshal(cipher)
355 if err != nil {
356 return nil, err
357 }
358 plain, err := decrypter.Decrypt(config.rand(), cipher, nil)
359 if err != nil {
360 return nil, err
361 }
362
363 if len(plain) != 48 {
364 return nil, errClientKeyExchange
365 }
366
367
368 return plain, nil
369 }
370
371 func (ka *eccKeyAgreementGM) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
372 if len(skx.key) <= 2 {
373 return errServerKeyExchange
374 }
375 sigLen := int(skx.key[0]<<8 | skx.key[1])
376 if sigLen+2 != len(skx.key) {
377 return errServerKeyExchange
378 }
379 sig := skx.key[2:]
380
381
382 digest := ka.hashForServerKeyExchange(clientHello.random, serverHello.random, ka.encipherCert.Raw)
383
384
385 pubKey, _ := cert.PublicKey.(*ecdsa.PublicKey)
386 if pubKey.Curve != sm2.P256Sm2() {
387 return errors.New("tls: sm2 signing requires a sm2 public key")
388 }
389
390 ecdsaSig := new(ecdsaSignature)
391 rest, err := asn1.Unmarshal(sig, ecdsaSig)
392 if err != nil {
393 return err
394 }
395 if len(rest) != 0 {
396 return errors.New("tls:processServerKeyExchange: sm2 get signature failed")
397 }
398 if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
399 return errors.New("tls: processServerKeyExchange: sm2 signature contained zero or negative values")
400 }
401
402 sm2PubKey := sm2.PublicKey{
403 Curve: pubKey.Curve,
404 X: pubKey.X,
405 Y: pubKey.Y,
406 }
407
408 if !sm2PubKey.Verify(digest, sig) {
409 return errors.New("tls: processServerKeyExchange: sm2 verification failure")
410 }
411
412 return nil
413 }
414
415 func (ka *eccKeyAgreementGM) hashForServerKeyExchange(slices ...[]byte) []byte {
416 buffer := new(bytes.Buffer)
417 for i, slice := range slices {
418 if i == 2 {
419 buffer.Write([]byte{byte(len(slice) >> 16), byte(len(slice) >> 8), byte(len(slice))})
420 }
421 buffer.Write(slice)
422 }
423 return buffer.Bytes()
424 }
425
426 func (ka *eccKeyAgreementGM) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
427 preMasterSecret := make([]byte, 48)
428 preMasterSecret[0] = byte(clientHello.vers >> 8)
429 preMasterSecret[1] = byte(clientHello.vers)
430 _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
431 if err != nil {
432 return nil, nil, err
433 }
434 pubKey := ka.encipherCert.PublicKey.(*ecdsa.PublicKey)
435 sm2PubKey := &sm2.PublicKey{Curve: pubKey.Curve, X: pubKey.X, Y: pubKey.Y}
436 encrypted, err := sm2.Encrypt(sm2PubKey, preMasterSecret, config.rand(), sm2.C1C3C2)
437 if err != nil {
438 return nil, nil, err
439 }
440
441 encrypted, err = sm2.CipherMarshal(encrypted)
442 if err != nil {
443 return nil, nil, err
444 }
445 ckx := new(clientKeyExchangeMsg)
446 ckx.ciphertext = make([]byte, len(encrypted)+2)
447 ckx.ciphertext[0] = byte(len(encrypted) >> 8)
448 ckx.ciphertext[1] = byte(len(encrypted))
449 copy(ckx.ciphertext[2:], encrypted)
450 return preMasterSecret, ckx, nil
451 }
452
View as plain text