gitee.com/lh-her-team/common@v1.5.1/crypto/tls/gm_support.go (about) 1 // Copyright 2017 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/cipher" 10 "crypto/hmac" 11 "encoding/pem" 12 "errors" 13 "fmt" 14 "io/ioutil" 15 "strings" 16 "sync" 17 18 "gitee.com/lh-her-team/common/crypto/x509" 19 "github.com/tjfoc/gmsm/sm2" 20 "github.com/tjfoc/gmsm/sm3" 21 "github.com/tjfoc/gmsm/sm4" 22 ) 23 24 const VersionGMSSL = 0x0101 // GM/T 0024-2014 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 65 var certCAs []*x509.Certificate 66 67 var initonce sync.Once 68 69 func getCAs() []*x509.Certificate { 70 // mod by syl remove pre insert ca certs 71 return nil 72 initonce.Do(func() { 73 for _, pemca := range pemCAs { 74 block, _ := pem.Decode([]byte(pemca.pem)) 75 ca, err := x509.ParseCertificate(block.Bytes) 76 if err != nil { 77 panic(err) 78 } 79 certCAs = append(certCAs, ca) 80 } 81 }) 82 return certCAs 83 } 84 85 // A list of cipher suite IDs that are, or have been, implemented by this 86 // package. 87 const ( 88 //GM crypto suites ID Taken from GM/T 0024-2014 89 GMTLS_ECDHE_SM2_WITH_SM1_SM3 uint16 = 0xe001 90 GMTLS_SM2_WITH_SM1_SM3 uint16 = 0xe003 91 GMTLS_IBSDH_WITH_SM1_SM3 uint16 = 0xe005 92 GMTLS_IBC_WITH_SM1_SM3 uint16 = 0xe007 93 GMTLS_RSA_WITH_SM1_SM3 uint16 = 0xe009 94 GMTLS_RSA_WITH_SM1_SHA1 uint16 = 0xe00a 95 GMTLS_ECDHE_SM2_WITH_SM4_SM3 uint16 = 0xe011 96 GMTLS_ECDHE_SM4_CBC_SM3 uint16 = 0xe011 97 GMTLS_ECDHE_SM4_GCM_SM3 uint16 = 0xe051 98 GMTLS_SM2_WITH_SM4_SM3 uint16 = 0xe013 99 GMTLS_ECC_SM4_CBC_SM3 uint16 = 0xe013 100 GMTLS_ECC_SM4_GCM_SM3 uint16 = 0xe053 101 GMTLS_IBSDH_WITH_SM4_SM3 uint16 = 0xe015 102 GMTLS_IBC_WITH_SM4_SM3 uint16 = 0xe017 103 GMTLS_RSA_WITH_SM4_SM3 uint16 = 0xe019 104 GMTLS_RSA_WITH_SM4_SHA1 uint16 = 0xe01a 105 ) 106 107 var gmCipherSuites = []*cipherSuite{ 108 {GMTLS_ECC_SM4_CBC_SM3, 16, 32, 16, eccGMKA, suiteECSign, cipherSM4, macSM3, nil}, 109 {GMTLS_ECC_SM4_GCM_SM3, 16, 0, 4, eccGMKA, suiteECSign, nil, nil, aeadSM4GCM}, 110 111 {GMTLS_ECDHE_SM4_CBC_SM3, 16, 32, 16, ecdheGMKA, suiteECDHE | suiteECSign, cipherSM4, macSM3, nil}, 112 {GMTLS_ECDHE_SM4_GCM_SM3, 16, 0, 4, ecdheGMKA, suiteECDHE | suiteECSign, nil, nil, aeadSM4GCM}, 113 } 114 115 // aeadSM4GCM SM4 GCM向前加解密函数 116 // key: 对称密钥 117 // nonce: 隐式随机数 (implicit nonce 4 Byte) 118 func aeadSM4GCM(key []byte, nonce []byte) cipher.AEAD { 119 if len(nonce) != noncePrefixLength { 120 panic("tls: internal error: wrong implicit nonce length") 121 } 122 block, err := sm4.NewCipher(key) 123 if err != nil { 124 panic(err) 125 } 126 aead, err := cipher.NewGCMWithNonceSize(block, 12) 127 if err != nil { 128 panic(err) 129 } 130 // AEAD 使用的随机数应由显式和隐式两部分构成, 131 // 显式部分即 nonce explicit,客户端和服务端使用隐式部分 132 // 分别来自 client_write_iv 和 server_write_iv。 133 // AEAD使用的随机数和计数器的构造参见 RFC 5116 134 ret := &prefixNonceAEAD{aead: aead} 135 copy(ret.nonce[:], nonce) 136 return ret 137 } 138 139 func getCipherSuites(c *Config) []uint16 { 140 s := c.CipherSuites 141 if s == nil { 142 s = []uint16{ 143 GMTLS_ECC_SM4_CBC_SM3, 144 GMTLS_ECC_SM4_GCM_SM3, 145 GMTLS_ECDHE_SM4_CBC_SM3, 146 GMTLS_ECDHE_SM4_GCM_SM3, 147 } 148 } 149 return s 150 } 151 152 func cipherSM4(key, iv []byte, isRead bool) interface{} { 153 block, _ := sm4.NewCipher(key) 154 if isRead { 155 return cipher.NewCBCDecrypter(block, iv) 156 } 157 return cipher.NewCBCEncrypter(block, iv) 158 } 159 160 // macSHA1 returns a macFunction for the given protocol version. 161 func macSM3(version uint16, key []byte) macFunction { 162 return tls10MAC{h: hmac.New(sm3.New, key)} 163 } 164 165 //used for adapt the demand of finishHash write 166 type nilMD5Hash struct{} 167 168 func (nilMD5Hash) Write(p []byte) (n int, err error) { 169 return 0, nil 170 } 171 172 func (nilMD5Hash) Sum(b []byte) []byte { 173 return nil 174 } 175 176 func (nilMD5Hash) Reset() { 177 } 178 179 func (nilMD5Hash) Size() int { 180 return 0 181 } 182 183 func (nilMD5Hash) BlockSize() int { 184 return 0 185 } 186 187 func newFinishedHashGM(cipherSuite *cipherSuite) finishedHash { 188 return finishedHash{sm3.New(), sm3.New(), new(nilMD5Hash), new(nilMD5Hash), []byte{}, VersionGMSSL, prf12(sm3.New)} 189 } 190 191 func ecdheGMKA(version uint16) keyAgreement { 192 return &ecdheKeyAgreementGM{ 193 version: version, 194 } 195 } 196 197 func eccGMKA(version uint16) keyAgreement { 198 return &eccKeyAgreementGM{ 199 version: version, 200 } 201 } 202 203 // mutualCipherSuite returns a cipherSuite given a list of supported 204 // ciphersuites and the id requested by the peer. 205 func mutualCipherSuiteGM(have []uint16, want uint16) *cipherSuite { 206 for _, id := range have { 207 if id == want { 208 for _, suite := range gmCipherSuites { 209 if suite.id == want { 210 return suite 211 } 212 } 213 return nil 214 } 215 } 216 return nil 217 } 218 219 const ( 220 ModeGMSSLOnly = "GMSSLOnly" // only support GMSSL 221 ModeAutoSwitch = "AutoSwitch" // support GMSSL/TLS auto switch 222 ) 223 224 type GMSupport struct { 225 WorkMode string // working mode 226 EncCertEnable bool // enable encryption certificate 227 } 228 229 func NewGMSupport() *GMSupport { 230 return &GMSupport{WorkMode: ModeGMSSLOnly, EncCertEnable: true} 231 } 232 233 func (support *GMSupport) GetVersion() uint16 { 234 return VersionGMSSL 235 } 236 237 func (support *GMSupport) IsAvailable() bool { 238 return true 239 } 240 241 func (support *GMSupport) cipherSuites() []*cipherSuite { 242 return gmCipherSuites 243 } 244 245 // EnableMixMode 启用 GMSSL/TLS 自动切换的工作模式 246 func (support *GMSupport) EnableMixMode() { 247 support.WorkMode = ModeAutoSwitch 248 } 249 250 // IsAutoSwitchMode 是否处于混合工作模式 251 // return true - GMSSL/TLS 均支持, false - 不处于混合模式 252 func (support *GMSupport) IsAutoSwitchMode() bool { 253 return support.WorkMode == ModeAutoSwitch 254 } 255 256 // LoadGMX509KeyPairs reads and parses two public/private key pairs from pairs 257 // of files. The files must contain PEM encoded data. The certificate file 258 // may contain intermediate certificates following the leaf certificate to 259 // form a certificate chain. On successful return, Certificate.Leaf will 260 // be nil because the parsed form of the certificate is not retained. 261 func LoadGMX509KeyPairs(certFile, keyFile, encCertFile, encKeyFile string) (Certificate, error) { 262 certPEMBlock, err := ioutil.ReadFile(certFile) 263 if err != nil { 264 return Certificate{}, err 265 } 266 keyPEMBlock, err := ioutil.ReadFile(keyFile) 267 if err != nil { 268 return Certificate{}, err 269 } 270 encCertPEMBlock, err := ioutil.ReadFile(encCertFile) 271 if err != nil { 272 return Certificate{}, err 273 } 274 encKeyPEMBlock, err := ioutil.ReadFile(encKeyFile) 275 if err != nil { 276 return Certificate{}, err 277 } 278 return GMX509KeyPairs(certPEMBlock, keyPEMBlock, encCertPEMBlock, encKeyPEMBlock) 279 } 280 281 // add by syl add sigle key pair sitiation 282 func LoadGMX509KeyPair(certFile, keyFile string) (Certificate, error) { 283 certPEMBlock, err := ioutil.ReadFile(certFile) 284 if err != nil { 285 return Certificate{}, err 286 } 287 keyPEMBlock, err := ioutil.ReadFile(keyFile) 288 if err != nil { 289 return Certificate{}, err 290 } 291 return GMX509KeyPairsSingle(certPEMBlock, keyPEMBlock) 292 } 293 294 func getCert(certPEMBlock []byte) ([][]byte, error) { 295 var certs [][]byte 296 var skippedBlockTypes []string 297 for { 298 var certDERBlock *pem.Block 299 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) 300 if certDERBlock == nil { 301 break 302 } 303 if certDERBlock.Type == "CERTIFICATE" { 304 certs = append(certs, certDERBlock.Bytes) 305 } else { 306 skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) 307 } 308 } 309 if len(certs) == 0 { 310 if len(skippedBlockTypes) == 0 { 311 return nil, errors.New("tls: failed to find any PEM data in certificate input") 312 } 313 if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { 314 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") 315 } 316 return nil, fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes) 317 } 318 return certs, nil 319 } 320 321 func getKey(keyPEMBlock []byte) (*pem.Block, error) { 322 var skippedBlockTypes []string 323 var keyDERBlock *pem.Block 324 for { 325 keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) 326 if keyDERBlock == nil { 327 if len(skippedBlockTypes) == 0 { 328 return nil, errors.New("tls: failed to find any PEM data in key input") 329 } 330 if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { 331 return nil, errors.New("tls: found a certificate rather than a key in the PEM for the private key") 332 } 333 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) 334 } 335 if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { 336 break 337 } 338 skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) 339 } 340 return keyDERBlock, nil 341 } 342 343 func matchKeyCert(keyDERBlock *pem.Block, certDERBlock []byte) (crypto.PrivateKey, error) { 344 // We don't need to parse the public key for TLS, but we so do anyway 345 // to check that it looks sane and matches the private key. 346 x509Cert, err := x509.ParseCertificate(certDERBlock) 347 if err != nil { 348 return nil, err 349 } 350 privateKey, err := parsePrivateKey(keyDERBlock.Bytes) 351 if err != nil { 352 return nil, err 353 } 354 pubKey := x509Cert.PublicKey.ToStandardKey() 355 switch pub := pubKey.(type) { 356 case *sm2.PublicKey: 357 priv, ok := privateKey.(*sm2.PrivateKey) 358 if !ok { 359 return nil, errors.New("tls: private key type does not match public key type") 360 } 361 if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { 362 return nil, errors.New("tls: private key does not match public key") 363 } 364 default: 365 return nil, errors.New("tls: unknown public key algorithm") 366 } 367 return privateKey, nil 368 } 369 370 // X509KeyPair parses a public/private key pair from a pair of 371 // PEM encoded data. On successful return, Certificate.Leaf will be nil because 372 // the parsed form of the certificate is not retained. 373 func GMX509KeyPairs(certPEMBlock, keyPEMBlock, encCertPEMBlock, encKeyPEMBlock []byte) (Certificate, error) { 374 fail := func(err error) (Certificate, error) { return Certificate{}, err } 375 var certificate Certificate 376 signCerts, err := getCert(certPEMBlock) 377 if err != nil { 378 return certificate, err 379 } 380 if len(signCerts) == 0 { 381 return certificate, errors.New("tls: failed to find any sign cert PEM data in cert input") 382 } 383 certificate.Certificate = append(certificate.Certificate, signCerts[0]) 384 encCerts, err := getCert(encCertPEMBlock) 385 if err != nil { 386 return certificate, err 387 } 388 if len(encCerts) == 0 { 389 return certificate, errors.New("tls: failed to find any enc cert PEM data in cert input") 390 } 391 certificate.Certificate = append(certificate.Certificate, encCerts[0]) 392 keyDERBlock, err := getKey(keyPEMBlock) 393 if err != nil { 394 return certificate, err 395 } 396 certificate.PrivateKey, err = matchKeyCert(keyDERBlock, certificate.Certificate[0]) 397 if err != nil { 398 return fail(err) 399 } 400 return certificate, nil 401 } 402 403 //one cert for enc and sign 404 func GMX509KeyPairsSingle(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { 405 fail := func(err error) (Certificate, error) { return Certificate{}, err } 406 var certificate Certificate 407 certs, err := getCert(certPEMBlock) 408 if err != nil { 409 return certificate, err 410 } 411 if len(certs) == 0 { 412 return certificate, errors.New("tls: failed to find any sign cert PEM data in cert input") 413 } 414 checkCert, err := x509.ParseCertificate(certs[0]) 415 if err != nil { 416 return certificate, errors.New("tls: failed to parse certificate") 417 } 418 //if cert is not for GM, use default X509KeyPair 419 if checkCert.PublicKeyAlgorithm != x509.SM2 { 420 return X509KeyPair(certPEMBlock, keyPEMBlock) 421 } 422 certificate.Certificate = append(certificate.Certificate, certs[0]) //this is for sign and env 423 keyDERBlock, err := getKey(keyPEMBlock) 424 if err != nil { 425 return certificate, err 426 } 427 certificate.PrivateKey, err = matchKeyCert(keyDERBlock, certificate.Certificate[0]) 428 if err != nil { 429 return fail(err) 430 } 431 return certificate, nil 432 }