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