1
2
3
4
5 package gmtls
6
7 import (
8 "crypto"
9 "crypto/cipher"
10 "crypto/hmac"
11 "encoding/pem"
12 "errors"
13 "fmt"
14 "io/ioutil"
15 "strings"
16 "sync"
17
18 "github.com/tjfoc/gmsm/sm2"
19 "github.com/tjfoc/gmsm/sm3"
20 "github.com/tjfoc/gmsm/sm4"
21 "github.com/tjfoc/gmsm/x509"
22 )
23
24 const VersionGMSSL = 0x0101
25
26 var pemCAs = []struct {
27 name string
28 pem string
29 }{
30 {
31 name: "CFCA",
32 pem: `-----BEGIN CERTIFICATE-----
33 MIICezCCAh6gAwIBAgIQJRABs1dlPn+86pb7bT74wjAMBggqgRzPVQGDdQUAMFgx
34 CzAJBgNVBAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNh
35 dGlvbiBBdXRob3JpdHkxFzAVBgNVBAMMDkNGQ0EgQ1MgU00yIENBMB4XDTE1MDcx
36 MTAzMTUxM1oXDTM1MDcwNDAzMTUxM1owJTELMAkGA1UEBhMCQ04xFjAUBgNVBAoM
37 DUNGQ0EgU00yIE9DQTEwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAR8mpCijT4m
38 jIJHLSaxLZibTvrydXWlIu4r261LWKPfyhtYPKarSgxFHBTMMwRAjX0JqOjclSgY
39 XE6+wD5ha7dco4H6MIH3MB8GA1UdIwQYMBaAFOSO3dSj57YP7h0nls113CUlcmnd
40 MA8GA1UdEwEB/wQFMAMBAf8wgZMGA1UdHwSBizCBiDBVoFOgUaRPME0xCzAJBgNV
41 BAYTAkNOMRMwEQYDVQQKDApDRkNBIENTIENBMQwwCgYDVQQLDANDUkwxDDAKBgNV
42 BAsMA1NNMjENMAsGA1UEAwwEY3JsMTAvoC2gK4YpaHR0cDovL2NybC5jZmNhLmNv
43 bS5jbi9jc3JjYS9TTTIvY3JsMS5jcmwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQW
44 BBRck1ggWiRzVhAbZFAQ7OmnygdBETAMBggqgRzPVQGDdQUAA0kAMEYCIQCka+W4
45 lEDJGbdoQKfMyMIrwkuRjxV4fXu+CQZIsYGFnQIhAKFs1nR4OHFxsdjHPXG0CBx+
46 1C++KMPnVTWTsfH9fKPf
47 -----END CERTIFICATE-----`,
48 },
49 {
50 name: "TEST",
51 pem: `-----BEGIN CERTIFICATE-----
52 MIIBgTCCASegAwIBAgIRAJa6ZDaSc3wau4+2sLM2zhMwCgYIKoEcz1UBg3UwJTEL
53 MAkGA1UEBhMCQ04xFjAUBgNVBAoTDWNhLmNldGNzYy5jb20wHhcNMTgxMjI0MDk1
54 NDMyWhcNMzgxMjE5MDk1NDMyWjAlMQswCQYDVQQGEwJDTjEWMBQGA1UEChMNY2Eu
55 Y2V0Y3NjLmNvbTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNzzDdS5/RMcpbYW
56 d+hzCdocFpSOynYzalPvPWdyINM/7AP3DKYrYKyfa4jtW5xqYTpufWUabhSkvG3C
57 DGBbmE6jODA2MA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggrBgEFBQcDATAP
58 BgNVHRMBAf8EBTADAQH/MAoGCCqBHM9VAYN1A0gAMEUCIQCsbtt9tJOtgwO6iavS
59 NB8Cs3U2so5gFQq6YdtX7d4EtgIgcVu9SQzlDmmmk61AaEES9UJgENmxrdhkon2T
60 vHTeE7Y=
61 -----END CERTIFICATE-----`,
62 },
63 {
64 name: "FABRIC",
65 pem: `-----BEGIN CERTIFICATE-----
66 MIICMDCCAdagAwIBAgIRANnwbA2SIB/k0VNSkTi7TYUwCgYIKoEcz1UBg3UwaTEL
67 MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
68 cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRcwFQYDVQQDEw5jYS5leGFt
69 cGxlLmNvbTAeFw0xODEyMjcwNzE3MzBaFw0yODEyMjQwNzE3MzBaMGkxCzAJBgNV
70 BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
71 c2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEXMBUGA1UEAxMOY2EuZXhhbXBsZS5j
72 b20wWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAARAp0oXL9xvWjkipnru0gsuL95g
73 jpjscT5fQw0bHXPBSzYSq0+hoJf7C3t6tzjnI6pN0156KZg8Y1Bg7fx9xxOHo18w
74 XTAOBgNVHQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTAD
75 AQH/MCkGA1UdDgQiBCAt1zWEo9mUfmTAZlZthCkppNjgQlpQ9A77ylguCH4tRDAK
76 BggqgRzPVQGDdQNIADBFAiBFx066bqQswz5eFA6IWZjj7GmdAyypq48IUaI8cs+b
77 AwIhAPKX+rTHK3IHmZ3MHU2ajoJcGwq0h7aWpcpljF6cld4r
78 -----END CERTIFICATE-----`,
79 },
80 }
81
82 var certCAs []*x509.Certificate
83
84 var initonce sync.Once
85
86 func getCAs() []*x509.Certificate {
87
88 return nil
89 initonce.Do(func() {
90 for _, pemca := range pemCAs {
91 block, _ := pem.Decode([]byte(pemca.pem))
92 ca, err := x509.ParseCertificate(block.Bytes)
93 if err != nil {
94 panic(err)
95 }
96 certCAs = append(certCAs, ca)
97 }
98 })
99 return certCAs
100 }
101
102
103
104 const (
105
106 GMTLS_ECDHE_SM2_WITH_SM1_SM3 uint16 = 0xe001
107 GMTLS_SM2_WITH_SM1_SM3 uint16 = 0xe003
108 GMTLS_IBSDH_WITH_SM1_SM3 uint16 = 0xe005
109 GMTLS_IBC_WITH_SM1_SM3 uint16 = 0xe007
110 GMTLS_RSA_WITH_SM1_SM3 uint16 = 0xe009
111 GMTLS_RSA_WITH_SM1_SHA1 uint16 = 0xe00a
112 GMTLS_ECDHE_SM2_WITH_SM4_SM3 uint16 = 0xe011
113 GMTLS_SM2_WITH_SM4_SM3 uint16 = 0xe013
114 GMTLS_IBSDH_WITH_SM4_SM3 uint16 = 0xe015
115 GMTLS_IBC_WITH_SM4_SM3 uint16 = 0xe017
116 GMTLS_RSA_WITH_SM4_SM3 uint16 = 0xe019
117 GMTLS_RSA_WITH_SM4_SHA1 uint16 = 0xe01a
118 )
119
120 var gmCipherSuites = []*cipherSuite{
121 {GMTLS_SM2_WITH_SM4_SM3, 16, 32, 16, eccGMKA, suiteECDSA, cipherSM4, macSM3, nil},
122 {GMTLS_ECDHE_SM2_WITH_SM4_SM3, 16, 32, 16, ecdheGMKA, suiteECDHE | suiteECDSA, cipherSM4, macSM3, nil},
123 }
124
125 func getCipherSuites(c *Config) []uint16 {
126 s := c.CipherSuites
127 if s == nil {
128 s = []uint16{GMTLS_SM2_WITH_SM4_SM3, GMTLS_ECDHE_SM2_WITH_SM4_SM3}
129 }
130 return s
131 }
132
133 func cipherSM4(key, iv []byte, isRead bool) interface{} {
134 block, _ := sm4.NewCipher(key)
135 if isRead {
136 return cipher.NewCBCDecrypter(block, iv)
137 }
138 return cipher.NewCBCEncrypter(block, iv)
139 }
140
141
142 func macSM3(version uint16, key []byte) macFunction {
143 return tls10MAC{hmac.New(sm3.New, key)}
144 }
145
146
147 type nilMD5Hash struct{}
148
149 func (nilMD5Hash) Write(p []byte) (n int, err error) {
150 return 0, nil
151 }
152
153 func (nilMD5Hash) Sum(b []byte) []byte {
154 return nil
155 }
156
157 func (nilMD5Hash) Reset() {
158 }
159
160 func (nilMD5Hash) Size() int {
161 return 0
162 }
163
164 func (nilMD5Hash) BlockSize() int {
165 return 0
166 }
167
168 func newFinishedHashGM(cipherSuite *cipherSuite) finishedHash {
169 return finishedHash{sm3.New(), sm3.New(), new(nilMD5Hash), new(nilMD5Hash), []byte{}, VersionGMSSL, prf12(sm3.New)}
170
171 }
172
173 func ecdheGMKA(version uint16) keyAgreement {
174 return &ecdheKeyAgreementGM{
175 version: version,
176 }
177 }
178
179 func eccGMKA(version uint16) keyAgreement {
180 return &eccKeyAgreementGM{
181 version: version,
182 }
183 }
184
185
186
187 func mutualCipherSuiteGM(have []uint16, want uint16) *cipherSuite {
188 for _, id := range have {
189 if id == want {
190 for _, suite := range gmCipherSuites {
191 if suite.id == want {
192 return suite
193 }
194 }
195 return nil
196 }
197 }
198 return nil
199 }
200
201 const (
202 ModeGMSSLOnly = "GMSSLOnly"
203 ModeAutoSwitch = "AutoSwitch"
204 )
205
206 type GMSupport struct {
207 WorkMode string
208 }
209
210 func NewGMSupport() *GMSupport {
211 return &GMSupport{WorkMode: ModeGMSSLOnly}
212 }
213
214 func (support *GMSupport) GetVersion() uint16 {
215 return VersionGMSSL
216 }
217
218 func (support *GMSupport) IsAvailable() bool {
219 return true
220 }
221
222 func (support *GMSupport) cipherSuites() []*cipherSuite {
223 return gmCipherSuites
224 }
225
226
227 func (support *GMSupport) EnableMixMode() {
228 support.WorkMode = ModeAutoSwitch
229 }
230
231
232
233 func (support *GMSupport) IsAutoSwitchMode() bool {
234 return support.WorkMode == ModeAutoSwitch
235 }
236
237
238
239
240
241
242 func LoadGMX509KeyPairs(certFile, keyFile, encCertFile, encKeyFile string) (Certificate, error) {
243 certPEMBlock, err := ioutil.ReadFile(certFile)
244 if err != nil {
245 return Certificate{}, err
246 }
247 keyPEMBlock, err := ioutil.ReadFile(keyFile)
248 if err != nil {
249 return Certificate{}, err
250 }
251 encCertPEMBlock, err := ioutil.ReadFile(encCertFile)
252 if err != nil {
253 return Certificate{}, err
254 }
255 encKeyPEMBlock, err := ioutil.ReadFile(encKeyFile)
256 if err != nil {
257 return Certificate{}, err
258 }
259
260 return GMX509KeyPairs(certPEMBlock, keyPEMBlock, encCertPEMBlock, encKeyPEMBlock)
261 }
262
263
264 func LoadGMX509KeyPair(certFile, keyFile string) (Certificate, error) {
265 certPEMBlock, err := ioutil.ReadFile(certFile)
266 if err != nil {
267 return Certificate{}, err
268 }
269 keyPEMBlock, err := ioutil.ReadFile(keyFile)
270 if err != nil {
271 return Certificate{}, err
272 }
273
274 return GMX509KeyPairsSingle(certPEMBlock, keyPEMBlock)
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299 func getCert(certPEMBlock []byte) ([][]byte, error) {
300
301 var certs [][]byte
302 var skippedBlockTypes []string
303 for {
304 var certDERBlock *pem.Block
305 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
306 if certDERBlock == nil {
307 break
308 }
309 if certDERBlock.Type == "CERTIFICATE" {
310 certs = append(certs, certDERBlock.Bytes)
311 } else {
312 skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type)
313 }
314 }
315
316 if len(certs) == 0 {
317 if len(skippedBlockTypes) == 0 {
318 return nil, errors.New("tls: failed to find any PEM data in certificate input")
319 }
320 if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
321 return nil, errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched")
322 }
323 return nil, fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)
324 }
325 return certs, nil
326 }
327
328 func getKey(keyPEMBlock []byte) (*pem.Block, error) {
329 var skippedBlockTypes []string
330 var keyDERBlock *pem.Block
331 for {
332 keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
333 if keyDERBlock == nil {
334 if len(skippedBlockTypes) == 0 {
335 return nil, errors.New("tls: failed to find any PEM data in key input")
336 }
337 if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
338 return nil, errors.New("tls: found a certificate rather than a key in the PEM for the private key")
339 }
340 return nil, fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)
341 }
342 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
343 break
344 }
345 skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
346 }
347 return keyDERBlock, nil
348 }
349
350 func matchKeyCert(keyDERBlock *pem.Block, certDERBlock []byte) (crypto.PrivateKey, error) {
351
352
353 x509Cert, err := x509.ParseCertificate(certDERBlock)
354 if err != nil {
355 return nil, err
356 }
357
358 privateKey, err := parsePrivateKey(keyDERBlock.Bytes)
359 if err != nil {
360 return nil, err
361 }
362
363 switch pub := x509Cert.PublicKey.(type) {
364 case *sm2.PublicKey:
365 priv, ok := privateKey.(*sm2.PrivateKey)
366 if !ok {
367 return nil, errors.New("tls: private key type does not match public key type")
368 }
369 if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
370 return nil, errors.New("tls: private key does not match public key")
371 }
372 default:
373 return nil, errors.New("tls: unknown public key algorithm")
374 }
375 return privateKey, nil
376 }
377
378
379
380
381 func GMX509KeyPairs(certPEMBlock, keyPEMBlock, encCertPEMBlock, encKeyPEMBlock []byte) (Certificate, error) {
382 fail := func(err error) (Certificate, error) { return Certificate{}, err }
383
384 var certificate Certificate
385
386 signCerts, err := getCert(certPEMBlock)
387 if err != nil {
388 return certificate, err
389 }
390 if len(signCerts) == 0 {
391 return certificate, errors.New("tls: failed to find any sign cert PEM data in cert input")
392 }
393 certificate.Certificate = append(certificate.Certificate, signCerts[0])
394
395 encCerts, err := getCert(encCertPEMBlock)
396 if err != nil {
397 return certificate, err
398 }
399 if len(encCerts) == 0 {
400 return certificate, errors.New("tls: failed to find any enc cert PEM data in cert input")
401 }
402 certificate.Certificate = append(certificate.Certificate, encCerts[0])
403
404 keyDERBlock, err := getKey(keyPEMBlock)
405 if err != nil {
406 return certificate, err
407 }
408
409 certificate.PrivateKey, err = matchKeyCert(keyDERBlock, certificate.Certificate[0])
410 if err != nil {
411 return fail(err)
412 }
413
414 return certificate, nil
415 }
416
417
418 func GMX509KeyPairsSingle(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
419 fail := func(err error) (Certificate, error) { return Certificate{}, err }
420
421 var certificate Certificate
422
423 certs, err := getCert(certPEMBlock)
424 if err != nil {
425 return certificate, err
426 }
427 if len(certs) == 0 {
428 return certificate, errors.New("tls: failed to find any sign cert PEM data in cert input")
429 }
430 checkCert, err := x509.ParseCertificate(certs[0])
431 if err != nil {
432 return certificate, errors.New("tls: failed to parse certificate")
433 }
434
435
436 if checkCert.PublicKeyAlgorithm != x509.SM2 {
437 return X509KeyPair(certPEMBlock, keyPEMBlock)
438 }
439
440 certificate.Certificate = append(certificate.Certificate, certs[0])
441
442 keyDERBlock, err := getKey(keyPEMBlock)
443 if err != nil {
444 return certificate, err
445 }
446
447 certificate.PrivateKey, err = matchKeyCert(keyDERBlock, certificate.Certificate[0])
448 if err != nil {
449 return fail(err)
450 }
451
452 return certificate, nil
453 }
454
View as plain text