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 }