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 }