gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/gmtls/auth.go (about)

     1  // Copyright (c) 2022 zhaochun
     2  // core-gm is licensed under Mulan PSL v2.
     3  // You can use this software according to the terms and conditions of the Mulan PSL v2.
     4  // You may obtain a copy of Mulan PSL v2 at:
     5  //          http://license.coscl.org.cn/MulanPSL2
     6  // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
     7  // See the Mulan PSL v2 for more details.
     8  
     9  /*
    10  gmtls是基于`golang/go`的`tls`包实现的国密改造版本。
    11  对应版权声明: thrid_licenses/github.com/golang/go/LICENSE
    12  */
    13  
    14  package gmtls
    15  
    16  /*
    17  gmtls/auth.go 补充了国密sm2相关处理
    18  */
    19  
    20  import (
    21  	"bytes"
    22  	"crypto"
    23  	"crypto/ecdsa"
    24  	"crypto/ed25519"
    25  	"crypto/elliptic"
    26  	"crypto/rsa"
    27  	"errors"
    28  	"fmt"
    29  	"gitee.com/ks-custle/core-gm/ecdsa_ext"
    30  	"hash"
    31  	"io"
    32  
    33  	"gitee.com/ks-custle/core-gm/sm2"
    34  	"gitee.com/ks-custle/core-gm/x509"
    35  )
    36  
    37  // 使用pubkey,根据sigType选择对应的签名算法对sig进行验签。
    38  //   - sigType : 签名算法
    39  //   - pubkey : 公钥
    40  //   - hashFunc : 散列算法
    41  //   - signed : 签名内容
    42  //   - sig : 签名
    43  //
    44  // 已补充国密SM2分支
    45  // verifyHandshakeSignature verifies a signature against pre-hashed
    46  // (if required) handshake contents.
    47  func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc x509.Hash, signed, sig []byte) error {
    48  	switch sigType {
    49  	// 补充sm2分支
    50  	case signatureSM2:
    51  		pub, ok := pubkey.(*sm2.PublicKey)
    52  		if !ok {
    53  			return fmt.Errorf("expected an SM2 public key, got %T", pubkey)
    54  		}
    55  		if !sm2.VerifyASN1(pub, signed, sig) {
    56  			return errors.New("SM2 verification failure")
    57  		}
    58  	case signatureECDSA:
    59  		pub, ok := pubkey.(*ecdsa.PublicKey)
    60  		if !ok {
    61  			return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
    62  		}
    63  		if !ecdsa.VerifyASN1(pub, signed, sig) {
    64  			return errors.New("ECDSA verification failure")
    65  		}
    66  	case signatureECDSAEXT:
    67  		pub, ok := pubkey.(*ecdsa_ext.PublicKey)
    68  		if !ok {
    69  			pub2, ok2 := pubkey.(*ecdsa.PublicKey)
    70  			if !ok2 {
    71  				return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
    72  			}
    73  			pub = &ecdsa_ext.PublicKey{
    74  				PublicKey: *pub2,
    75  			}
    76  		}
    77  		_, err := pub.EcVerify(signed, sig, nil)
    78  		if err != nil {
    79  			return errors.New("ECDSAEXT verification failure")
    80  		}
    81  	case signatureEd25519:
    82  		pubKey, ok := pubkey.(ed25519.PublicKey)
    83  		if !ok {
    84  			return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey)
    85  		}
    86  		if !ed25519.Verify(pubKey, signed, sig) {
    87  			return errors.New("ed25519 verification failure")
    88  		}
    89  	case signaturePKCS1v15:
    90  		pubKey, ok := pubkey.(*rsa.PublicKey)
    91  		if !ok {
    92  			return fmt.Errorf("expected an RSA public key, got %T", pubkey)
    93  		}
    94  		if err := rsa.VerifyPKCS1v15(pubKey, hashFunc.HashFunc(), signed, sig); err != nil {
    95  			return err
    96  		}
    97  	case signatureRSAPSS:
    98  		pubKey, ok := pubkey.(*rsa.PublicKey)
    99  		if !ok {
   100  			return fmt.Errorf("expected an RSA public key, got %T", pubkey)
   101  		}
   102  		signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
   103  		if err := rsa.VerifyPSS(pubKey, hashFunc.HashFunc(), signed, sig, signOpts); err != nil {
   104  			return err
   105  		}
   106  	default:
   107  		return errors.New("internal error: unknown signature type")
   108  	}
   109  	return nil
   110  }
   111  
   112  const (
   113  	serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
   114  	clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
   115  )
   116  
   117  var signaturePadding = []byte{
   118  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   119  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   120  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   121  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   122  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   123  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   124  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   125  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   126  }
   127  
   128  // 生成一个前置的消息散列,用于证书公私钥的签名与验签。
   129  // signedMessage returns the pre-hashed (if necessary) message to be signed by
   130  // certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3.
   131  func signedMessage(sigHash x509.Hash, context string, transcript hash.Hash) []byte {
   132  	// directSigning 表示不做签名内容的前置散列
   133  	if sigHash == directSigning {
   134  		b := &bytes.Buffer{}
   135  		b.Write(signaturePadding)
   136  		_, err := io.WriteString(b, context)
   137  		if err != nil {
   138  			panic(err)
   139  		}
   140  		b.Write(transcript.Sum(nil))
   141  		return b.Bytes()
   142  	}
   143  	h := sigHash.New()
   144  	h.Write(signaturePadding)
   145  	_, err := io.WriteString(h, context)
   146  	if err != nil {
   147  		panic(err)
   148  	}
   149  	h.Write(transcript.Sum(nil))
   150  	return h.Sum(nil)
   151  }
   152  
   153  // 获取签名算法与散列算法
   154  //
   155  //	已补充国密SM2签名算法分支
   156  //
   157  // typeAndHashFromSignatureScheme returns the corresponding signature type and
   158  // crypto.Hash for a given TLS SignatureScheme.
   159  func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash x509.Hash, err error) {
   160  	switch signatureAlgorithm {
   161  	// 补充国密SM2签名算法
   162  	case SM2WITHSM3:
   163  		sigType = signatureSM2
   164  	case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
   165  		sigType = signaturePKCS1v15
   166  	case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
   167  		sigType = signatureRSAPSS
   168  	case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
   169  		sigType = signatureECDSA
   170  	case ECDSAEXTWithP256AndSHA256, ECDSAEXTWithP384AndSHA384, ECDSAEXTWithP521AndSHA512:
   171  		sigType = signatureECDSAEXT
   172  	case Ed25519:
   173  		sigType = signatureEd25519
   174  	default:
   175  		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
   176  	}
   177  	switch signatureAlgorithm {
   178  	// 补充国密SM3散列算法
   179  	case SM2WITHSM3:
   180  		hash = x509.SM3
   181  	case PKCS1WithSHA1, ECDSAWithSHA1:
   182  		hash = x509.SHA1
   183  	case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256, ECDSAEXTWithP256AndSHA256:
   184  		hash = x509.SHA256
   185  	case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384, ECDSAEXTWithP384AndSHA384:
   186  		hash = x509.SHA384
   187  	case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512, ECDSAEXTWithP521AndSHA512:
   188  		hash = x509.SHA512
   189  	case Ed25519:
   190  		hash = directSigning
   191  	default:
   192  		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
   193  	}
   194  	return sigType, hash, nil
   195  }
   196  
   197  // 已补充国密SM2分支
   198  // legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for
   199  // a given public key used with TLS 1.0 and 1.1, before the introduction of
   200  // signature algorithm negotiation.
   201  func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash x509.Hash, err error) {
   202  	switch pub.(type) {
   203  	// 补充sm2分支
   204  	case *sm2.PublicKey:
   205  		return signatureSM2, x509.SM3, nil
   206  	case *rsa.PublicKey:
   207  		return signaturePKCS1v15, x509.MD5SHA1, nil
   208  	case *ecdsa.PublicKey:
   209  		//return signatureECDSA, x509.SHA1, nil
   210  		return signatureECDSA, x509.SHA256, nil
   211  	case *ecdsa_ext.PublicKey:
   212  		return signatureECDSAEXT, x509.SHA256, nil
   213  	case ed25519.PublicKey:
   214  		// RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1,
   215  		// but it requires holding on to a handshake transcript to do a
   216  		// full signature, and not even OpenSSL bothers with the
   217  		// complexity, so we can't even test it properly.
   218  		return 0, 0, fmt.Errorf("gmtls: Ed25519 public keys are not supported before TLS 1.2")
   219  	default:
   220  		return 0, 0, fmt.Errorf("gmtls: unsupported public key: %T", pub)
   221  	}
   222  }
   223  
   224  var rsaSignatureSchemes = []struct {
   225  	scheme          SignatureScheme
   226  	minModulusBytes int
   227  	maxVersion      uint16
   228  }{
   229  	// RSA-PSS is used with PSSSaltLengthEqualsHash, and requires
   230  	//    emLen >= hLen + sLen + 2
   231  	{PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13},
   232  	{PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13},
   233  	{PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13},
   234  	// PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires
   235  	//    emLen >= len(prefix) + hLen + 11
   236  	// TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS.
   237  	{PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12},
   238  	{PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12},
   239  	{PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12},
   240  	{PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12},
   241  }
   242  
   243  // 已补充国密SM2分支
   244  // signatureSchemesForCertificate returns the list of supported SignatureSchemes
   245  // for a given certificate, based on the public key and the protocol version,
   246  // and optionally filtered by its explicit SupportedSignatureAlgorithms.
   247  //
   248  // This function must be kept in sync with supportedSignatureAlgorithms.
   249  func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
   250  	priv, ok := cert.PrivateKey.(crypto.Signer)
   251  	if !ok {
   252  		return nil
   253  	}
   254  	fmt.Println("证书私钥类型: %T", priv)
   255  	fmt.Println("证书私钥内部公钥类型: %T", priv.Public())
   256  
   257  	var sigAlgs []SignatureScheme
   258  	switch pub := priv.Public().(type) {
   259  	// 补充国密sm2分支
   260  	case *sm2.PublicKey:
   261  		sigAlgs = []SignatureScheme{SM2WITHSM3}
   262  		fmt.Println("根据证书私钥内部公钥获取到sm2签名算法")
   263  	case *ecdsa.PublicKey:
   264  		fmt.Println("根据证书私钥内部公钥获取到ecdsa签名算法")
   265  		if version != VersionTLS13 {
   266  			// In TLS 1.2 and earlier, ECDSA algorithms are not
   267  			// constrained to a single curve.
   268  			sigAlgs = []SignatureScheme{
   269  				ECDSAWithP256AndSHA256,
   270  				ECDSAWithP384AndSHA384,
   271  				ECDSAWithP521AndSHA512,
   272  				ECDSAWithSHA1,
   273  			}
   274  			break
   275  		}
   276  		switch pub.Curve {
   277  		case elliptic.P256():
   278  			sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256}
   279  		case elliptic.P384():
   280  			sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384}
   281  		case elliptic.P521():
   282  			sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512}
   283  		default:
   284  			return nil
   285  		}
   286  	case *ecdsa_ext.PublicKey:
   287  		fmt.Println("根据证书私钥内部公钥获取到ecdsa_ext签名算法")
   288  		if version != VersionTLS13 {
   289  			// In TLS 1.2 and earlier, ECDSA algorithms are not
   290  			// constrained to a single curve.
   291  			sigAlgs = []SignatureScheme{
   292  				ECDSAEXTWithP256AndSHA256,
   293  				ECDSAEXTWithP384AndSHA384,
   294  				ECDSAEXTWithP521AndSHA512,
   295  			}
   296  			break
   297  		}
   298  		switch pub.Curve {
   299  		case elliptic.P256():
   300  			sigAlgs = []SignatureScheme{ECDSAEXTWithP256AndSHA256}
   301  		case elliptic.P384():
   302  			sigAlgs = []SignatureScheme{ECDSAEXTWithP384AndSHA384}
   303  		case elliptic.P521():
   304  			sigAlgs = []SignatureScheme{ECDSAEXTWithP521AndSHA512}
   305  		default:
   306  			return nil
   307  		}
   308  	case *rsa.PublicKey:
   309  		fmt.Println("根据证书私钥内部公钥获取到rsa签名算法")
   310  		size := pub.Size()
   311  		sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes))
   312  		for _, candidate := range rsaSignatureSchemes {
   313  			if size >= candidate.minModulusBytes && version <= candidate.maxVersion {
   314  				sigAlgs = append(sigAlgs, candidate.scheme)
   315  			}
   316  		}
   317  	case ed25519.PublicKey:
   318  		fmt.Println("根据证书私钥内部公钥获取到Ed25519签名算法")
   319  		sigAlgs = []SignatureScheme{Ed25519}
   320  	default:
   321  		fmt.Println("不支持的证书私钥内部公钥类型: %T", pub)
   322  		return nil
   323  	}
   324  	// 如果证书提供了支持签名算法信息,则检查是否与私钥对应的签名算法匹配,
   325  	// 并返回匹配的签名算法集合
   326  	if cert.SupportedSignatureAlgorithms != nil {
   327  		var filteredSigAlgs []SignatureScheme
   328  		for _, sigAlg := range sigAlgs {
   329  			if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) {
   330  				filteredSigAlgs = append(filteredSigAlgs, sigAlg)
   331  			}
   332  		}
   333  		if len(filteredSigAlgs) == 0 {
   334  			fmt.Println("证书私钥类型与证书支持的签名算法不匹配, 证书私钥类型: %T, 证书支持的签名算法: %s", priv, cert.SupportedSignatureAlgorithms)
   335  		} else {
   336  			fmt.Println("证书提供了支持签名算法信息,检查是否与私钥对应的签名算法匹配,结果OK")
   337  		}
   338  		return filteredSigAlgs
   339  	}
   340  	// 若证书没有提供支持签名算法信息,则直接返回私钥支持的签名算法集合
   341  	return sigAlgs
   342  }
   343  
   344  // selectSignatureScheme picks a SignatureScheme from the peer's preference list
   345  // that works with the selected certificate. It's only called for protocol
   346  // versions that support signature algorithms, so TLS 1.2 and 1.3.
   347  func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
   348  	// 获取证书支持的签名算法
   349  	supportedAlgs := signatureSchemesForCertificate(vers, c)
   350  	if len(supportedAlgs) == 0 {
   351  		return 0, unsupportedCertificateError(c)
   352  	}
   353  	if len(peerAlgs) == 0 && vers == VersionTLS12 {
   354  		// For TLS 1.2, if the client didn't send signature_algorithms then we
   355  		// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.
   356  		// 补充VersionTLS12下的国密签名算法组件
   357  		peerAlgs = []SignatureScheme{SM2WITHSM3, PKCS1WithSHA1, ECDSAWithSHA1}
   358  	}
   359  	// Pick signature scheme in the peer's preference order, as our
   360  	// preference order is not configurable.
   361  	for _, preferredAlg := range peerAlgs {
   362  		if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
   363  			// 返回第一个匹配的签名算法
   364  			return preferredAlg, nil
   365  		}
   366  	}
   367  	return 0, errors.New("gmtls: peer doesn't support any of the certificate's signature algorithms")
   368  }
   369  
   370  // 已补充国密sm2对应
   371  // unsupportedCertificateError returns a helpful error for certificates with
   372  // an unsupported private key.
   373  func unsupportedCertificateError(cert *Certificate) error {
   374  	fmt.Println("unsupportedCertificateError")
   375  	switch cert.PrivateKey.(type) {
   376  	// 补充sm2匹配条件
   377  	case rsa.PrivateKey, ecdsa.PrivateKey, ecdsa_ext.PrivateKey, sm2.PrivateKey:
   378  		return fmt.Errorf("gmtls: unsupported certificate: private key is %T, expected *%T",
   379  			cert.PrivateKey, cert.PrivateKey)
   380  	case *ed25519.PrivateKey:
   381  		return fmt.Errorf("gmtls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
   382  	}
   383  
   384  	signer, ok := cert.PrivateKey.(crypto.Signer)
   385  	if !ok {
   386  		return fmt.Errorf("gmtls: certificate private key (%T) does not implement crypto.Signer",
   387  			cert.PrivateKey)
   388  	}
   389  
   390  	switch pub := signer.Public().(type) {
   391  	// 补充sm2分支
   392  	case *sm2.PublicKey:
   393  		switch pub.Curve {
   394  		case sm2.P256Sm2():
   395  		default:
   396  			return fmt.Errorf("gmtls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
   397  		}
   398  	case *ecdsa.PublicKey:
   399  		switch pub.Curve {
   400  		case elliptic.P256():
   401  		case elliptic.P384():
   402  		case elliptic.P521():
   403  		default:
   404  			return fmt.Errorf("gmtls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
   405  		}
   406  	case *ecdsa_ext.PublicKey:
   407  		switch pub.Curve {
   408  		case elliptic.P256():
   409  		case elliptic.P384():
   410  		case elliptic.P521():
   411  		default:
   412  			return fmt.Errorf("gmtls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
   413  		}
   414  	case *rsa.PublicKey:
   415  		return fmt.Errorf("gmtls: certificate RSA key size too small for supported signature algorithms")
   416  	case ed25519.PublicKey:
   417  	default:
   418  		return fmt.Errorf("gmtls: unsupported certificate key (%T)", pub)
   419  	}
   420  
   421  	if cert.SupportedSignatureAlgorithms != nil {
   422  		return fmt.Errorf("gmtls: peer doesn't support the certificate custom signature algorithms")
   423  	}
   424  
   425  	return fmt.Errorf("gmtls: internal error: unsupported key (%T)", cert.PrivateKey)
   426  }