gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/gmtls/auth.go (about)

     1  // Copyright (c) 2022 zhaochun
     2  // gmgo 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/zhaochuninhefei/gmgo/ecdsa_ext"
    30  	"gitee.com/zhaochuninhefei/zcgolog/zclog"
    31  	"hash"
    32  	"io"
    33  
    34  	"gitee.com/zhaochuninhefei/gmgo/sm2"
    35  	"gitee.com/zhaochuninhefei/gmgo/x509"
    36  )
    37  
    38  // 使用pubkey,根据sigType选择对应的签名算法对sig进行验签。
    39  //  - sigType : 签名算法
    40  //  - pubkey : 公钥
    41  //  - hashFunc : 散列算法
    42  //  - signed : 签名内容
    43  //  - sig : 签名
    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  //  已补充国密SM2签名算法分支
   155  // typeAndHashFromSignatureScheme returns the corresponding signature type and
   156  // crypto.Hash for a given TLS SignatureScheme.
   157  func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash x509.Hash, err error) {
   158  	switch signatureAlgorithm {
   159  	// 补充国密SM2签名算法
   160  	case SM2WITHSM3:
   161  		sigType = signatureSM2
   162  	case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
   163  		sigType = signaturePKCS1v15
   164  	case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
   165  		sigType = signatureRSAPSS
   166  	case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
   167  		sigType = signatureECDSA
   168  	case ECDSAEXTWithP256AndSHA256, ECDSAEXTWithP384AndSHA384, ECDSAEXTWithP521AndSHA512:
   169  		sigType = signatureECDSAEXT
   170  	case Ed25519:
   171  		sigType = signatureEd25519
   172  	default:
   173  		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
   174  	}
   175  	switch signatureAlgorithm {
   176  	// 补充国密SM3散列算法
   177  	case SM2WITHSM3:
   178  		hash = x509.SM3
   179  	case PKCS1WithSHA1, ECDSAWithSHA1:
   180  		hash = x509.SHA1
   181  	case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256, ECDSAEXTWithP256AndSHA256:
   182  		hash = x509.SHA256
   183  	case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384, ECDSAEXTWithP384AndSHA384:
   184  		hash = x509.SHA384
   185  	case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512, ECDSAEXTWithP521AndSHA512:
   186  		hash = x509.SHA512
   187  	case Ed25519:
   188  		hash = directSigning
   189  	default:
   190  		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
   191  	}
   192  	return sigType, hash, nil
   193  }
   194  
   195  // 已补充国密SM2分支
   196  // legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for
   197  // a given public key used with TLS 1.0 and 1.1, before the introduction of
   198  // signature algorithm negotiation.
   199  func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash x509.Hash, err error) {
   200  	switch pub.(type) {
   201  	// 补充sm2分支
   202  	case *sm2.PublicKey:
   203  		return signatureSM2, x509.SM3, nil
   204  	case *rsa.PublicKey:
   205  		return signaturePKCS1v15, x509.MD5SHA1, nil
   206  	case *ecdsa.PublicKey:
   207  		//return signatureECDSA, x509.SHA1, nil
   208  		return signatureECDSA, x509.SHA256, nil
   209  	case *ecdsa_ext.PublicKey:
   210  		return signatureECDSAEXT, x509.SHA256, nil
   211  	case ed25519.PublicKey:
   212  		// RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1,
   213  		// but it requires holding on to a handshake transcript to do a
   214  		// full signature, and not even OpenSSL bothers with the
   215  		// complexity, so we can't even test it properly.
   216  		return 0, 0, fmt.Errorf("gmtls: Ed25519 public keys are not supported before TLS 1.2")
   217  	default:
   218  		return 0, 0, fmt.Errorf("gmtls: unsupported public key: %T", pub)
   219  	}
   220  }
   221  
   222  var rsaSignatureSchemes = []struct {
   223  	scheme          SignatureScheme
   224  	minModulusBytes int
   225  	maxVersion      uint16
   226  }{
   227  	// RSA-PSS is used with PSSSaltLengthEqualsHash, and requires
   228  	//    emLen >= hLen + sLen + 2
   229  	{PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13},
   230  	{PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13},
   231  	{PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13},
   232  	// PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires
   233  	//    emLen >= len(prefix) + hLen + 11
   234  	// TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS.
   235  	{PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12},
   236  	{PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12},
   237  	{PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12},
   238  	{PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12},
   239  }
   240  
   241  // 已补充国密SM2分支
   242  // signatureSchemesForCertificate returns the list of supported SignatureSchemes
   243  // for a given certificate, based on the public key and the protocol version,
   244  // and optionally filtered by its explicit SupportedSignatureAlgorithms.
   245  //
   246  // This function must be kept in sync with supportedSignatureAlgorithms.
   247  func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
   248  	priv, ok := cert.PrivateKey.(crypto.Signer)
   249  	if !ok {
   250  		return nil
   251  	}
   252  	zclog.Debugf("证书私钥类型: %T", priv)
   253  	zclog.Debugf("证书私钥内部公钥类型: %T", priv.Public())
   254  
   255  	var sigAlgs []SignatureScheme
   256  	switch pub := priv.Public().(type) {
   257  	// 补充国密sm2分支
   258  	case *sm2.PublicKey:
   259  		sigAlgs = []SignatureScheme{SM2WITHSM3}
   260  		zclog.Debugln("根据证书私钥内部公钥获取到sm2签名算法")
   261  	case *ecdsa.PublicKey:
   262  		zclog.Debugln("根据证书私钥内部公钥获取到ecdsa签名算法")
   263  		if version != VersionTLS13 {
   264  			// In TLS 1.2 and earlier, ECDSA algorithms are not
   265  			// constrained to a single curve.
   266  			sigAlgs = []SignatureScheme{
   267  				ECDSAWithP256AndSHA256,
   268  				ECDSAWithP384AndSHA384,
   269  				ECDSAWithP521AndSHA512,
   270  				ECDSAWithSHA1,
   271  			}
   272  			break
   273  		}
   274  		switch pub.Curve {
   275  		case elliptic.P256():
   276  			sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256}
   277  		case elliptic.P384():
   278  			sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384}
   279  		case elliptic.P521():
   280  			sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512}
   281  		default:
   282  			return nil
   283  		}
   284  	case *ecdsa_ext.PublicKey:
   285  		zclog.Debugln("根据证书私钥内部公钥获取到ecdsa_ext签名算法")
   286  		if version != VersionTLS13 {
   287  			// In TLS 1.2 and earlier, ECDSA algorithms are not
   288  			// constrained to a single curve.
   289  			sigAlgs = []SignatureScheme{
   290  				ECDSAEXTWithP256AndSHA256,
   291  				ECDSAEXTWithP384AndSHA384,
   292  				ECDSAEXTWithP521AndSHA512,
   293  			}
   294  			break
   295  		}
   296  		switch pub.Curve {
   297  		case elliptic.P256():
   298  			sigAlgs = []SignatureScheme{ECDSAEXTWithP256AndSHA256}
   299  		case elliptic.P384():
   300  			sigAlgs = []SignatureScheme{ECDSAEXTWithP384AndSHA384}
   301  		case elliptic.P521():
   302  			sigAlgs = []SignatureScheme{ECDSAEXTWithP521AndSHA512}
   303  		default:
   304  			return nil
   305  		}
   306  	case *rsa.PublicKey:
   307  		zclog.Debugln("根据证书私钥内部公钥获取到rsa签名算法")
   308  		size := pub.Size()
   309  		sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes))
   310  		for _, candidate := range rsaSignatureSchemes {
   311  			if size >= candidate.minModulusBytes && version <= candidate.maxVersion {
   312  				sigAlgs = append(sigAlgs, candidate.scheme)
   313  			}
   314  		}
   315  	case ed25519.PublicKey:
   316  		zclog.Debugln("根据证书私钥内部公钥获取到Ed25519签名算法")
   317  		sigAlgs = []SignatureScheme{Ed25519}
   318  	default:
   319  		zclog.Debugf("不支持的证书私钥内部公钥类型: %T", pub)
   320  		return nil
   321  	}
   322  	// 如果证书提供了支持签名算法信息,则检查是否与私钥对应的签名算法匹配,
   323  	// 并返回匹配的签名算法集合
   324  	if cert.SupportedSignatureAlgorithms != nil {
   325  		var filteredSigAlgs []SignatureScheme
   326  		for _, sigAlg := range sigAlgs {
   327  			if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) {
   328  				filteredSigAlgs = append(filteredSigAlgs, sigAlg)
   329  			}
   330  		}
   331  		if len(filteredSigAlgs) == 0 {
   332  			zclog.Errorf("证书私钥类型与证书支持的签名算法不匹配, 证书私钥类型: %T, 证书支持的签名算法: %s", priv, cert.SupportedSignatureAlgorithms)
   333  		} else {
   334  			zclog.Debugln("证书提供了支持签名算法信息,检查是否与私钥对应的签名算法匹配,结果OK")
   335  		}
   336  		return filteredSigAlgs
   337  	}
   338  	// 若证书没有提供支持签名算法信息,则直接返回私钥支持的签名算法集合
   339  	return sigAlgs
   340  }
   341  
   342  // selectSignatureScheme picks a SignatureScheme from the peer's preference list
   343  // that works with the selected certificate. It's only called for protocol
   344  // versions that support signature algorithms, so TLS 1.2 and 1.3.
   345  func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
   346  	// 获取证书支持的签名算法
   347  	supportedAlgs := signatureSchemesForCertificate(vers, c)
   348  	if len(supportedAlgs) == 0 {
   349  		return 0, unsupportedCertificateError(c)
   350  	}
   351  	if len(peerAlgs) == 0 && vers == VersionTLS12 {
   352  		// For TLS 1.2, if the client didn't send signature_algorithms then we
   353  		// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.
   354  		// 补充VersionTLS12下的国密签名算法组件
   355  		peerAlgs = []SignatureScheme{SM2WITHSM3, PKCS1WithSHA1, ECDSAWithSHA1}
   356  	}
   357  	// Pick signature scheme in the peer's preference order, as our
   358  	// preference order is not configurable.
   359  	for _, preferredAlg := range peerAlgs {
   360  		if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
   361  			// 返回第一个匹配的签名算法
   362  			return preferredAlg, nil
   363  		}
   364  	}
   365  	return 0, errors.New("gmtls: peer doesn't support any of the certificate's signature algorithms")
   366  }
   367  
   368  // 已补充国密sm2对应
   369  // unsupportedCertificateError returns a helpful error for certificates with
   370  // an unsupported private key.
   371  func unsupportedCertificateError(cert *Certificate) error {
   372  	zclog.ErrorStack("unsupportedCertificateError")
   373  	switch cert.PrivateKey.(type) {
   374  	// 补充sm2匹配条件
   375  	case rsa.PrivateKey, ecdsa.PrivateKey, ecdsa_ext.PrivateKey, sm2.PrivateKey:
   376  		return fmt.Errorf("gmtls: unsupported certificate: private key is %T, expected *%T",
   377  			cert.PrivateKey, cert.PrivateKey)
   378  	case *ed25519.PrivateKey:
   379  		return fmt.Errorf("gmtls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
   380  	}
   381  
   382  	signer, ok := cert.PrivateKey.(crypto.Signer)
   383  	if !ok {
   384  		return fmt.Errorf("gmtls: certificate private key (%T) does not implement crypto.Signer",
   385  			cert.PrivateKey)
   386  	}
   387  
   388  	switch pub := signer.Public().(type) {
   389  	// 补充sm2分支
   390  	case *sm2.PublicKey:
   391  		switch pub.Curve {
   392  		case sm2.P256Sm2():
   393  		default:
   394  			return fmt.Errorf("gmtls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
   395  		}
   396  	case *ecdsa.PublicKey:
   397  		switch pub.Curve {
   398  		case elliptic.P256():
   399  		case elliptic.P384():
   400  		case elliptic.P521():
   401  		default:
   402  			return fmt.Errorf("gmtls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
   403  		}
   404  	case *ecdsa_ext.PublicKey:
   405  		switch pub.Curve {
   406  		case elliptic.P256():
   407  		case elliptic.P384():
   408  		case elliptic.P521():
   409  		default:
   410  			return fmt.Errorf("gmtls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
   411  		}
   412  	case *rsa.PublicKey:
   413  		return fmt.Errorf("gmtls: certificate RSA key size too small for supported signature algorithms")
   414  	case ed25519.PublicKey:
   415  	default:
   416  		return fmt.Errorf("gmtls: unsupported certificate key (%T)", pub)
   417  	}
   418  
   419  	if cert.SupportedSignatureAlgorithms != nil {
   420  		return fmt.Errorf("gmtls: peer doesn't support the certificate custom signature algorithms")
   421  	}
   422  
   423  	return fmt.Errorf("gmtls: internal error: unsupported key (%T)", cert.PrivateKey)
   424  }