gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/gmtls/common.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 import ( 17 "bytes" 18 "container/list" 19 "context" 20 "crypto" 21 "crypto/ecdsa" 22 "crypto/ed25519" 23 "crypto/elliptic" 24 "crypto/rand" 25 "crypto/rsa" 26 "crypto/sha512" 27 "errors" 28 "fmt" 29 "gitee.com/zhaochuninhefei/gmgo/ecdsa_ext" 30 "gitee.com/zhaochuninhefei/zcgolog/zclog" 31 "io" 32 "net" 33 "strings" 34 "sync" 35 "time" 36 37 "gitee.com/zhaochuninhefei/gmgo/sm2" 38 "gitee.com/zhaochuninhefei/gmgo/x509" 39 ) 40 41 //goland:noinspection GoCommentStart 42 const ( 43 // 国密SSL版本定义 GM/T 0024-2014 44 VersionGMSSL = 0x0101 45 VersionTLS10 = 0x0301 46 VersionTLS11 = 0x0302 47 VersionTLS12 = 0x0303 48 VersionTLS13 = 0x0304 49 50 // TO Deprecated: SSLv3 is cryptographically broken, and is no longer 51 // supported by this package. See golang.org/issue/32716. 52 VersionSSL30 = 0x0300 53 ) 54 55 func ShowTLSVersion(version int) string { 56 switch version { 57 case VersionGMSSL: 58 return "VersionGMSSL" 59 case VersionTLS10: 60 return "VersionTLS10" 61 case VersionTLS11: 62 return "VersionTLS11" 63 case VersionTLS12: 64 return "VersionTLS12" 65 case VersionTLS13: 66 return "VersionTLS13" 67 case VersionSSL30: 68 return "VersionSSL30" 69 default: 70 return "unknown" 71 } 72 } 73 74 const ( 75 maxPlaintext = 16384 // maximum plaintext payload length 76 maxCiphertext = 16384 + 2048 // maximum ciphertext payload length 77 maxCiphertextTLS13 = 16384 + 256 // maximum ciphertext length in TLS 1.3 78 recordHeaderLen = 5 // record header length 79 maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) 80 maxUselessRecords = 16 // maximum number of consecutive non-advancing records 81 82 // minVersion = VersionGMSSL 83 // maxVersion = VersionTLS13 84 ) 85 86 // TLS record types. 87 type recordType uint8 88 89 // tls记录类型 90 const ( 91 recordTypeChangeCipherSpec recordType = 20 92 recordTypeAlert recordType = 21 93 recordTypeHandshake recordType = 22 94 recordTypeApplicationData recordType = 23 95 ) 96 97 // TLS handshake message types. 98 //goland:noinspection GoUnusedConst 99 const ( 100 typeHelloRequest uint8 = 0 101 typeClientHello uint8 = 1 102 typeServerHello uint8 = 2 103 typeNewSessionTicket uint8 = 4 104 typeEndOfEarlyData uint8 = 5 105 typeEncryptedExtensions uint8 = 8 106 typeCertificate uint8 = 11 107 typeServerKeyExchange uint8 = 12 108 typeCertificateRequest uint8 = 13 109 typeServerHelloDone uint8 = 14 110 typeCertificateVerify uint8 = 15 111 typeClientKeyExchange uint8 = 16 112 typeFinished uint8 = 20 113 typeCertificateStatus uint8 = 22 114 typeKeyUpdate uint8 = 24 115 typeNextProtocol uint8 = 67 // Not IANA assigned 116 typeMessageHash uint8 = 254 // synthetic message 117 ) 118 119 // TLS compression types. 120 const ( 121 compressionNone uint8 = 0 122 ) 123 124 // TLS extension numbers 125 const ( 126 extensionServerName uint16 = 0 127 extensionStatusRequest uint16 = 5 128 extensionSupportedCurves uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7 129 extensionSupportedPoints uint16 = 11 130 extensionSignatureAlgorithms uint16 = 13 131 extensionALPN uint16 = 16 132 extensionSCT uint16 = 18 133 extensionSessionTicket uint16 = 35 134 extensionPreSharedKey uint16 = 41 135 extensionEarlyData uint16 = 42 136 extensionSupportedVersions uint16 = 43 137 extensionCookie uint16 = 44 138 extensionPSKModes uint16 = 45 139 extensionCertificateAuthorities uint16 = 47 140 extensionSignatureAlgorithmsCert uint16 = 50 141 extensionKeyShare uint16 = 51 142 extensionRenegotiationInfo uint16 = 0xff01 143 ) 144 145 // TLS signaling cipher suite values 146 const ( 147 scsvRenegotiation uint16 = 0x00ff 148 ) 149 150 // CurveID is the type of a TLS identifier for an elliptic curve. See 151 // https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8. 152 // 153 // In TLS 1.3, this type is called NamedGroup, but at this time this library 154 // only supports Elliptic Curve based groups. See RFC 8446, Section 4.2.7. 155 type CurveID uint16 156 157 // 支持的椭圆曲线ID 158 const ( 159 CurveP256 CurveID = 23 160 CurveP384 CurveID = 24 161 CurveP521 CurveID = 25 162 Curve256Sm2 CurveID = 26 // 添加国密SM2曲线ID 163 X25519 CurveID = 29 164 ) 165 166 // tls1.3的密钥交换算法参数,或者说共享密钥计算用参数。 167 // TLS 1.3 Key Share. See RFC 8446, Section 4.2.8. 168 type keyShare struct { 169 group CurveID // 椭圆曲线ID 170 data []byte // 公钥 171 } 172 173 // tls1.3的 PSK密钥交换模式 174 // TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9. 175 const ( 176 pskModePlain uint8 = 0 // 平文模式 177 pskModeDHE uint8 = 1 // DHE模式, 动态笛福赫尔曼密钥交换算法 178 ) 179 180 // tls1.3支持的psk身份,用作会话票据,或已保存的会话的引用。 181 // TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved 182 // session. See RFC 8446, Section 4.2.11. 183 type pskIdentity struct { 184 label []byte 185 obfuscatedTicketAge uint32 186 } 187 188 // TLS Elliptic Curve Point Formats 189 // https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 190 const ( 191 // 椭圆曲线上的点坐标的序列化格式 192 // 该格式是不压缩存储, 即将x,y坐标完整序列化 193 pointFormatUncompressed uint8 = 0 194 ) 195 196 // TLS CertificateStatusType (RFC 3546) 197 const ( 198 statusTypeOCSP uint8 = 1 199 ) 200 201 // Certificate types (for certificateRequestMsg) 202 const ( 203 certTypeRSASign = 1 204 certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3. 205 // 是否添加SM2Type 用于tls1.2及更老版本,暂时不做国密对应 206 // certTypeSM2Sign = 128 207 ) 208 209 // Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with 210 // TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do. 211 const ( 212 signaturePKCS1v15 uint8 = iota + 225 213 signatureRSAPSS 214 signatureECDSA 215 signatureEd25519 216 signatureSM2 217 signatureECDSAEXT 218 ) 219 220 // directSigning is a standard Hash value that signals that no pre-hashing 221 // should be performed, and that the input should be signed directly. It is the 222 // hash function associated with the Ed25519 signature scheme. 223 var directSigning x509.Hash = 0 224 225 // supportedSignatureAlgorithms contains the signature and hash algorithms that 226 // the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+ 227 // CertificateRequest. The two fields are merged to match with TLS 1.3. 228 // Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc. 229 var supportedSignatureAlgorithms = []SignatureScheme{ 230 PSSWithSHA256, 231 ECDSAWithP256AndSHA256, 232 SM2WITHSM3, // 增加SM2WithSM3 233 ECDSAEXTWithP256AndSHA256, // 添加ECDSAEXTWithP256AndSHA256 234 Ed25519, 235 PSSWithSHA384, 236 PSSWithSHA512, 237 PKCS1WithSHA256, 238 PKCS1WithSHA384, 239 PKCS1WithSHA512, 240 ECDSAWithP384AndSHA384, 241 ECDSAWithP521AndSHA512, 242 PKCS1WithSHA1, 243 ECDSAWithSHA1, 244 } 245 246 // 服务端未能获取到客户端公钥时,会发送HelloRetryRequest,请求客户端重新发送ClientHello。 247 // 此时需要将HelloRetryRequest中的random字段设置为该字段。 248 // helloRetryRequestRandom is set as the Random value of a ServerHello 249 // to signal that the message is actually a HelloRetryRequest. 250 var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3. 251 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 252 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, 253 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 254 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C, 255 } 256 257 const ( 258 // downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server 259 // random as a downgrade protection if the server would be capable of 260 // negotiating a higher version. See RFC 8446, Section 4.1.3. 261 downgradeCanaryTLS12 = "DOWNGRD\x01" 262 downgradeCanaryTLS11 = "DOWNGRD\x00" 263 ) 264 265 // testingOnlyForceDowngradeCanary is set in tests to force the server side to 266 // include downgrade canaries even if it's using its highers supported version. 267 var testingOnlyForceDowngradeCanary bool 268 269 // ConnectionState TLS握手过程中的连接状态管理用 270 // ConnectionState records basic TLS details about the connection. 271 type ConnectionState struct { 272 // Version is the TLS version used by the connection (e.g. VersionTLS12). 273 Version uint16 274 275 // HandshakeComplete is true if the handshake has concluded. 276 HandshakeComplete bool 277 278 // DidResume is true if this connection was successfully resumed from a 279 // previous session with a session ticket or similar mechanism. 280 DidResume bool 281 282 // CipherSuite is the cipher suite negotiated for the connection (e.g. 283 // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256). 284 CipherSuite uint16 285 286 // NegotiatedProtocol is the application protocol negotiated with ALPN. 287 NegotiatedProtocol string 288 289 // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation. 290 // 291 // ToDeprecated: this value is always true. 292 NegotiatedProtocolIsMutual bool 293 294 // ServerName is the value of the Server Name Indication extension sent by 295 // the client. It's available both on the server and on the client side. 296 ServerName string 297 298 // PeerCertificates are the parsed certificates sent by the peer, in the 299 // order in which they were sent. The first element is the leaf certificate 300 // that the connection is verified against. 301 // 302 // On the client side, it can't be empty. On the server side, it can be 303 // empty if Config.ClientAuth is not RequireAnyClientCert or 304 // RequireAndVerifyClientCert. 305 PeerCertificates []*x509.Certificate 306 307 // VerifiedChains is a list of one or more chains where the first element is 308 // PeerCertificates[0] and the last element is from Config.RootCAs (on the 309 // client side) or Config.ClientCAs (on the server side). 310 // 311 // On the client side, it's set if Config.InsecureSkipVerify is false. On 312 // the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven 313 // (and the peer provided a certificate) or RequireAndVerifyClientCert. 314 VerifiedChains [][]*x509.Certificate 315 316 // SignedCertificateTimestamps is a list of SCTs provided by the peer 317 // through the TLS handshake for the leaf certificate, if any. 318 SignedCertificateTimestamps [][]byte 319 320 // OCSPResponse is a stapled Online Certificate Status Protocol (OCSP) 321 // response provided by the peer for the leaf certificate, if any. 322 OCSPResponse []byte 323 324 // TLSUnique contains the "tls-unique" channel binding value (see RFC 5929, 325 // Section 3). This value will be nil for TLS 1.3 connections and for all 326 // resumed connections. 327 // 328 // ToDeprecated: there are conditions in which this value might not be unique 329 // to a connection. See the Security Considerations sections of RFC 5705 and 330 // RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings. 331 TLSUnique []byte 332 333 // ekm is a closure exposed via ExportKeyingMaterial. 334 ekm func(label string, context []byte, length int) ([]byte, error) 335 } 336 337 // ExportKeyingMaterial returns length bytes of exported key material in a new 338 // slice as defined in RFC 5705. If context is nil, it is not used as part of 339 // the seed. If the connection was set to allow renegotiation via 340 // Config.Renegotiation, this function will return an error. 341 func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) { 342 return cs.ekm(label, context, length) 343 } 344 345 // ClientAuthType declares the policy the server will follow for 346 // TLS Client Authentication. 347 type ClientAuthType int 348 349 const ( 350 // NoClientCert indicates that no client certificate should be requested 351 // during the handshake, and if any certificates are sent they will not 352 // be verified. 353 NoClientCert ClientAuthType = iota 354 // RequestClientCert indicates that a client certificate should be requested 355 // during the handshake, but does not require that the client send any 356 // certificates. 357 RequestClientCert 358 // RequireAnyClientCert indicates that a client certificate should be requested 359 // during the handshake, and that at least one certificate is required to be 360 // sent by the client, but that certificate is not required to be valid. 361 RequireAnyClientCert 362 // VerifyClientCertIfGiven indicates that a client certificate should be requested 363 // during the handshake, but does not require that the client sends a 364 // certificate. If the client does send a certificate it is required to be 365 // valid. 366 VerifyClientCertIfGiven 367 // RequireAndVerifyClientCert indicates that a client certificate should be requested 368 // during the handshake, and that at least one valid certificate is required 369 // to be sent by the client. 370 RequireAndVerifyClientCert 371 ) 372 373 // requiresClientCert reports whether the ClientAuthType requires a client 374 // certificate to be provided. 375 func requiresClientCert(c ClientAuthType) bool { 376 switch c { 377 case RequireAnyClientCert, RequireAndVerifyClientCert: 378 return true 379 default: 380 return false 381 } 382 } 383 384 // ClientSessionState contains the state needed by clients to resume TLS 385 // sessions. 386 type ClientSessionState struct { 387 sessionTicket []uint8 // Encrypted ticket used for session resumption with server 388 vers uint16 // TLS version negotiated for the session 389 cipherSuite uint16 // Ciphersuite negotiated for the session 390 masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret 391 serverCertificates []*x509.Certificate // Certificate chain presented by the server 392 verifiedChains [][]*x509.Certificate // Certificate chains we built for verification 393 receivedAt time.Time // When the session ticket was received from the server 394 ocspResponse []byte // Stapled OCSP response presented by the server 395 scts [][]byte // SCTs presented by the server 396 397 // TLS 1.3 fields. 398 nonce []byte // Ticket nonce sent by the server, to derive PSK 399 useBy time.Time // Expiration of the ticket lifetime as set by the server 400 ageAdd uint32 // Random obfuscation factor for sending the ticket age 401 } 402 403 // ClientSessionCache is a cache of ClientSessionState objects that can be used 404 // by a client to resume a TLS session with a given server. ClientSessionCache 405 // implementations should expect to be called concurrently from different 406 // goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not 407 // SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which 408 // are supported via this interface. 409 type ClientSessionCache interface { 410 // Get searches for a ClientSessionState associated with the given key. 411 // On return, ok is true if one was found. 412 Get(sessionKey string) (session *ClientSessionState, ok bool) 413 414 // Put adds the ClientSessionState to the cache with the given key. It might 415 // get called multiple times in a connection if a TLS 1.3 server provides 416 // more than one session ticket. If called with a nil *ClientSessionState, 417 // it should remove the cache entry. 418 Put(sessionKey string, cs *ClientSessionState) 419 } 420 421 //go:generate stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go 422 423 // SignatureScheme identifies a signature algorithm supported by TLS. See 424 // RFC 8446, Section 4.2.3. 425 type SignatureScheme uint16 426 427 //goland:noinspection GoCommentStart 428 const ( 429 // RSASSA-PKCS1-v1_5 algorithms. 430 PKCS1WithSHA256 SignatureScheme = 0x0401 431 PKCS1WithSHA384 SignatureScheme = 0x0501 432 PKCS1WithSHA512 SignatureScheme = 0x0601 433 434 // RSASSA-PSS algorithms with public key OID rsaEncryption. 435 PSSWithSHA256 SignatureScheme = 0x0804 436 PSSWithSHA384 SignatureScheme = 0x0805 437 PSSWithSHA512 SignatureScheme = 0x0806 438 439 // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3. 440 ECDSAWithP256AndSHA256 SignatureScheme = 0x0403 441 ECDSAWithP384AndSHA384 SignatureScheme = 0x0503 442 ECDSAWithP521AndSHA512 SignatureScheme = 0x0603 443 444 // ECDSAEXT algorithms. Only constrained to a specific curve in TLS 1.3. 445 ECDSAEXTWithP256AndSHA256 SignatureScheme = 0x0404 446 ECDSAEXTWithP384AndSHA384 SignatureScheme = 0x0504 447 ECDSAEXTWithP521AndSHA512 SignatureScheme = 0x0604 448 449 // EdDSA algorithms. 450 Ed25519 SignatureScheme = 0x0807 451 452 // Legacy signature and hash algorithms for TLS 1.2. 453 PKCS1WithSHA1 SignatureScheme = 0x0201 454 ECDSAWithSHA1 SignatureScheme = 0x0203 455 456 // 国密签名算法 457 SM2WITHSM3 SignatureScheme = 0x0204 458 ) 459 460 // ClientHelloInfo contains information from a ClientHello message in order to 461 // guide application logic in the GetCertificate and GetConfigForClient callbacks. 462 type ClientHelloInfo struct { 463 // CipherSuites lists the CipherSuites supported by the client (e.g. 464 // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256). 465 CipherSuites []uint16 466 467 // ServerName indicates the name of the server requested by the client 468 // in order to support virtual hosting. ServerName is only set if the 469 // client is using SNI (see RFC 4366, Section 3.1). 470 ServerName string 471 472 // SupportedCurves lists the elliptic curves supported by the client. 473 // SupportedCurves is set only if the Supported Elliptic Curves 474 // Extension is being used (see RFC 4492, Section 5.1.1). 475 SupportedCurves []CurveID 476 477 // SupportedPoints lists the point formats supported by the client. 478 // SupportedPoints is set only if the Supported Point Formats Extension 479 // is being used (see RFC 4492, Section 5.1.2). 480 SupportedPoints []uint8 481 482 // SignatureSchemes lists the signature and hash schemes that the client 483 // is willing to verify. SignatureSchemes is set only if the Signature 484 // Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1). 485 SignatureSchemes []SignatureScheme 486 487 // SupportedProtos lists the application protocols supported by the client. 488 // SupportedProtos is set only if the Application-Layer Protocol 489 // Negotiation Extension is being used (see RFC 7301, Section 3.1). 490 // 491 // Servers can select a protocol by setting Config.NextProtos in a 492 // GetConfigForClient return value. 493 SupportedProtos []string 494 495 // SupportedVersions lists the TLS versions supported by the client. 496 // For TLS versions less than 1.3, this is extrapolated from the max 497 // version advertised by the client, so values other than the greatest 498 // might be rejected if used. 499 SupportedVersions []uint16 500 501 // Conn is the underlying net.Conn for the connection. Do not read 502 // from, or write to, this connection; that will cause the TLS 503 // connection to fail. 504 Conn net.Conn 505 506 // config is embedded by the GetCertificate or GetConfigForClient caller, 507 // for use with SupportsCertificate. 508 config *Config 509 510 // ctx is the context of the handshake that is in progress. 511 ctx context.Context 512 } 513 514 // Context returns the context of the handshake that is in progress. 515 // This context is a child of the context passed to HandshakeContext, 516 // if any, and is canceled when the handshake concludes. 517 func (chi *ClientHelloInfo) Context() context.Context { 518 return chi.ctx 519 } 520 521 // CertificateRequestInfo contains information from a server's 522 // CertificateRequest message, which is used to demand a certificate and proof 523 // of control from a client. 524 type CertificateRequestInfo struct { 525 // AcceptableCAs contains zero or more, DER-encoded, X.501 526 // Distinguished Names. These are the names of root or intermediate CAs 527 // that the server wishes the returned certificate to be signed by. An 528 // empty slice indicates that the server has no preference. 529 AcceptableCAs [][]byte 530 531 // SignatureSchemes lists the signature schemes that the server is 532 // willing to verify. 533 SignatureSchemes []SignatureScheme 534 535 // Version is the TLS version that was negotiated for this connection. 536 Version uint16 537 538 // ctx is the context of the handshake that is in progress. 539 ctx context.Context 540 } 541 542 // Context returns the context of the handshake that is in progress. 543 // This context is a child of the context passed to HandshakeContext, 544 // if any, and is canceled when the handshake concludes. 545 func (cri *CertificateRequestInfo) Context() context.Context { 546 return cri.ctx 547 } 548 549 // RenegotiationSupport enumerates the different levels of support for TLS 550 // renegotiation. TLS renegotiation is the act of performing subsequent 551 // handshakes on a connection after the first. This significantly complicates 552 // the state machine and has been the source of numerous, subtle security 553 // issues. Initiating a renegotiation is not supported, but support for 554 // accepting renegotiation requests may be enabled. 555 // 556 // Even when enabled, the server may not change its identity between handshakes 557 // (i.e. the leaf certificate must be the same). Additionally, concurrent 558 // handshake and application data flow is not permitted so renegotiation can 559 // only be used with protocols that synchronise with the renegotiation, such as 560 // HTTPS. 561 // 562 // Renegotiation is not defined in TLS 1.3. 563 type RenegotiationSupport int 564 565 const ( 566 // RenegotiateNever disables renegotiation. 567 RenegotiateNever RenegotiationSupport = iota 568 569 // RenegotiateOnceAsClient allows a remote server to request 570 // renegotiation once per connection. 571 RenegotiateOnceAsClient 572 573 // RenegotiateFreelyAsClient allows a remote server to repeatedly 574 // request renegotiation. 575 RenegotiateFreelyAsClient 576 ) 577 578 // Config TLS通信配置 579 // A Config structure is used to configure a TLS client or server. 580 // After one has been passed to a TLS function it must not be 581 // modified. A Config may be reused; the tls package will also not 582 // modify it. 583 type Config struct { 584 585 // Rand provides the source of entropy for nonces and RSA blinding. 586 // If Rand is nil, TLS uses the cryptographic random reader in package 587 // crypto/rand. 588 // The Reader must be safe for use by multiple goroutines. 589 Rand io.Reader 590 591 // 当前时间 592 // Time returns the current time as the number of seconds since the epoch. 593 // If Time is nil, TLS uses time.Now. 594 Time func() time.Time 595 596 // Certificates 本地证书池,握手时可从这里选取合适的证书发送给对端用于身份验证 597 // 598 // Certificates contains one or more certificate chains to present to the 599 // other side of the connection. The first certificate compatible with the 600 // peer's requirements is selected automatically. 601 // 602 // Server configurations must set one of Certificates, GetCertificate or 603 // GetConfigForClient. Clients doing client-authentication may set either 604 // Certificates or GetClientCertificate. 605 // 606 // Note: if there are multiple Certificates, and they don't have the 607 // optional field Leaf set, certificate selection will incur a significant 608 // per-handshake performance cost. 609 Certificates []Certificate 610 611 // NameToCertificate 本地证书map, 握手时可以根据对端传来的ServerName匹配对应证书。目前不推荐使用。 612 // 613 // NameToCertificate maps from a certificate name to an element of 614 // Certificates. Note that a certificate name can be of the form 615 // '*.example.com' and so doesn't have to be a domain name as such. 616 // 617 // ToDeprecated: NameToCertificate only allows associating a single 618 // certificate with a given name. Leave this field nil to let the library 619 // select the first compatible chain from Certificates. 620 NameToCertificate map[string]*Certificate 621 622 // GetCertificate 根据ClientHelloInfo返回证书的函数,只在客户端提供了SNI或Certificates为空时调用。 623 // 该函数只在有特殊的证书选择逻辑时,通过这个自定义的函数来实现。比从Certificates获取更优先。 624 // 625 // GetCertificate returns a Certificate based on the given 626 // ClientHelloInfo. It will only be called if the client supplies SNI 627 // information or if Certificates is empty. 628 // 629 // If GetCertificate is nil or returns nil, then the certificate is 630 // retrieved from NameToCertificate. If NameToCertificate is nil, the 631 // best element of Certificates will be used. 632 GetCertificate func(*ClientHelloInfo) (*Certificate, error) 633 634 // GetKECertificate 获取密钥交换证书(加密证书) 635 // 这个方法只有在使用Config中Certificates为空或长度小于2时,才会被调用。 636 // 如果该方法为空,则默认从证书列表中 Certificates 取出第二个位置的证书,也就是加密证书。 637 // 该方法只有GMSSL流程中才会调用。 638 // GetKECertificate func(*ClientHelloInfo) (*Certificate, error) 639 640 // GetClientCertificate 当服务端向客户端请求证书时调用,用于获取客户端证书。该函数被设置时比Certificates优先。 641 // 642 // GetClientCertificate, if not nil, is called when a server requests a 643 // certificate from a client. If set, the contents of Certificates will 644 // be ignored. 645 // 646 // If GetClientCertificate returns an error, the handshake will be 647 // aborted and that error will be returned. Otherwise 648 // GetClientCertificate must return a non-nil Certificate. If 649 // Certificate.Certificate is empty then no certificate will be sent to 650 // the server. If this is unacceptable to the server then it may abort 651 // the handshake. 652 // 653 // GetClientCertificate may be called multiple times for the same 654 // connection if renegotiation occurs or if TLS 1.3 is in use. 655 GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error) 656 657 // GetConfigForClient 当服务端收到一个ClientHello后调用,用于获取客户端的TLS通信配置。 658 // 659 // GetConfigForClient, if not nil, is called after a ClientHello is 660 // received from a client. It may return a non-nil Config in order to 661 // change the Config that will be used to handle this connection. If 662 // the returned Config is nil, the original Config will be used. The 663 // Config returned by this callback may not be subsequently modified. 664 // 665 // If GetConfigForClient is nil, the Config passed to Server() will be 666 // used for all connections. 667 // 668 // If SessionTicketKey was explicitly set on the returned Config, or if 669 // SetSessionTicketKeys was called on the returned Config, those keys will 670 // be used. Otherwise, the original Config keys will be used (and possibly 671 // rotated if they are automatically managed). 672 GetConfigForClient func(*ClientHelloInfo) (*Config, error) 673 674 // VerifyPeerCertificate 预先定义好的额外的证书验证。 675 // 客户端或服务端进行正常的证书验证后调用,接收对方提供的ASN1格式证书或经过验证的证书链。 676 // 677 // VerifyPeerCertificate, if not nil, is called after normal 678 // certificate verification by either a TLS client or server. It 679 // receives the raw ASN.1 certificates provided by the peer and also 680 // any verified chains that normal processing found. If it returns a 681 // non-nil error, the handshake is aborted and that error results. 682 // 683 // If normal verification fails then the handshake will abort before 684 // considering this callback. If normal verification is disabled by 685 // setting InsecureSkipVerify, or (for a server) when ClientAuth is 686 // RequestClientCert or RequireAnyClientCert, then this callback will 687 // be considered but the verifiedChains argument will always be nil. 688 VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error 689 690 // VerifyConnection 预先定义好的额外的连接验证。 691 // 在正常的证书验证以及VerifyPeerCertificate之后调用。 692 // 693 // VerifyConnection, if not nil, is called after normal certificate 694 // verification and after VerifyPeerCertificate by either a TLS client 695 // or server. If it returns a non-nil error, the handshake is aborted 696 // and that error results. 697 // 698 // If normal verification fails then the handshake will abort before 699 // considering this callback. This callback will run for all connections 700 // regardless of InsecureSkipVerify or ClientAuth settings. 701 VerifyConnection func(ConnectionState) error 702 703 // RootCAs 客户端用来验证服务端证书的CA根证书池 704 // 705 // RootCAs defines the set of root certificate authorities 706 // that clients use when verifying server certificates. 707 // If RootCAs is nil, TLS uses the host's root CA set. 708 RootCAs *x509.CertPool 709 710 // NextProtos 应用层协议列表 711 // 如果双方都支持应用层协议协商(Application-Layer Protocol Negotiation,简称ALPN), 712 // 则从该列表中选择。 713 // 714 // NextProtos is a list of supported application level protocols, in 715 // order of preference. If both peers support ALPN, the selected 716 // protocol will be one from this list, and the connection will fail 717 // if there is no mutually supported protocol. If NextProtos is empty 718 // or the peer doesn't support ALPN, the connection will succeed and 719 // ConnectionState.NegotiatedProtocol will be empty. 720 NextProtos []string 721 722 // ServerName InsecureSkipVerify为设置时,根据ServerName检查收到的证书中的hostname。 723 // 724 // ServerName is used to verify the hostname on the returned 725 // certificates unless InsecureSkipVerify is given. It is also included 726 // in the client's handshake to support virtual hosting unless it is 727 // an IP address. 728 ServerName string 729 730 // ClientAuth 服务端对客户端认证的策略,默认NoClientCert,不需要客户端证书。 731 // 732 // ClientAuth determines the server's policy for 733 // TLS Client Authentication. The default is NoClientCert. 734 ClientAuth ClientAuthType 735 736 // ClientCAs 服务端用来验证客户端证书的CA根证书池, 当服务端需要客户端提供证书时,会使用这些CA证书验证。 737 // 738 // ClientCAs defines the set of root certificate authorities 739 // that servers use if required to verify a client certificate 740 // by the policy in ClientAuth. 741 ClientCAs *x509.CertPool 742 743 // InsecureSkipVerify 控制客户端是否验证服务器的证书链和主机名。 744 // 如果 InsecureSkipVerify 为真,crypto/tls 接受服务器提供的任何证书以及该证书中的任何主机名。 745 // 在这种模式下,除非使用自定义验证,否则 TLS 容易受到中间机攻击。 746 // 这应该仅用于测试或与 VerifyConnection 或 VerifyPeerCertificate 结合使用。 747 // 748 // InsecureSkipVerify controls whether a client verifies the server's 749 // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls 750 // accepts any certificate presented by the server and any host name in that 751 // certificate. In this mode, TLS is susceptible to machine-in-the-middle 752 // attacks unless custom verification is used. This should be used only for 753 // testing or in combination with VerifyConnection or VerifyPeerCertificate. 754 InsecureSkipVerify bool 755 756 // CipherSuites 是启用的 TLS 1.0–1.2 密码套件的列表。 列表的顺序被忽略。 757 // 请注意,TLS 1.3 密码套件不可配置。 758 // 759 // CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of 760 // the list is ignored. Note that TLS 1.3 ciphersuites are not configurable. 761 // 762 // If CipherSuites is nil, a safe default list is used. The default cipher 763 // suites might change over time. 764 CipherSuites []uint16 765 766 // PreferCipherSuites 优先密码套件列表, 客户端连接时优先想要使用的密码套件。 767 // tls1.3或gmssl支持。 768 // added by zhaochun 769 PreferCipherSuites []uint16 770 771 // PreferServerCipherSuites is a legacy field and has no effect. 772 // 773 // It used to control whether the server would follow the client's or the 774 // server's preference. Servers now select the best mutually supported 775 // cipher suite based on logic that takes into account inferred client 776 // hardware, server hardware, and security. 777 // 778 // Deprected: PreferServerCipherSuites is ignored. 779 PreferServerCipherSuites bool 780 781 // SessionTicketsDisabled 可以设置为 true 以禁用会话票证和 PSK(恢复)支持。 782 // 请注意,在客户端上,如果 ClientSessionCache 为 nil,会话票证支持也会被禁用。 783 // SessionTicketsDisabled may be set to true to disable session ticket and 784 // PSK (resumption) support. Note that on clients, session ticket support is 785 // also disabled if ClientSessionCache is nil. 786 SessionTicketsDisabled bool 787 788 // TLS 服务器使用 SessionTicketKey 来提供会话恢复。 789 // SessionTicketKey is used by TLS servers to provide session resumption. 790 // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled 791 // with random data before the first server handshake. 792 // 793 // ToDeprecated: if this field is left at zero, session ticket keys will be 794 // automatically rotated every day and dropped after seven days. For 795 // customizing the rotation schedule or synchronizing servers that are 796 // terminating connections for the same host, use SetSessionTicketKeys. 797 SessionTicketKey [32]byte 798 799 // ClientSessionCache 是用于 TLS 会话恢复的 ClientSessionState 条目的缓存。 800 // 它仅供客户使用。 801 // ClientSessionCache is a cache of ClientSessionState entries for TLS 802 // session resumption. It is only used by clients. 803 ClientSessionCache ClientSessionCache 804 805 // 支持的最低的TLS协议版本,默认 TLS 1.0 806 // 国密改造后默认是 GMSSL 807 // MinVersion contains the minimum TLS version that is acceptable. 808 // If zero, TLS 1.0 is currently taken as the minimum. 809 MinVersion uint16 810 811 // 支持的最高的TLS协议版本,默认 TLS 1.3 812 // MaxVersion contains the maximum TLS version that is acceptable. 813 // If zero, the maximum version supported by this package is used, 814 // which is currently TLS 1.3. 815 MaxVersion uint16 816 817 // CurvePreferences ECDHE握手支持的椭圆曲线ID 818 // 819 // CurvePreferences contains the elliptic curves that will be used in 820 // an ECDHE handshake, in preference order. If empty, the default will 821 // be used. The client will use the first preference as the type for 822 // its key share in TLS 1.3. This may change in the future. 823 CurvePreferences []CurveID 824 825 // SignAlgPrefer 优先选择的签名算法 826 // tls1.3或gmssl支持 827 // added by zhaochun 828 SignAlgPrefer []SignatureScheme 829 830 // DynamicRecordSizingDisabled 禁用 TLS 记录的自适应大小。 831 // 如果为 true,则始终使用最大可能的 TLS 记录大小。 832 // 如果为 false,则可能会调整 TLS 记录的大小以尝试改善延迟。 833 // DynamicRecordSizingDisabled disables adaptive sizing of TLS records. 834 // When true, the largest possible TLS record size is always used. When 835 // false, the size of TLS records may be adjusted in an attempt to 836 // improve latency. 837 DynamicRecordSizingDisabled bool 838 839 // 重新协商控制支持哪些类型的重新协商。 默认值 none 对于绝大多数应用程序都是正确的。 840 // Renegotiation controls what types of renegotiation are supported. 841 // The default, none, is correct for the vast majority of applications. 842 Renegotiation RenegotiationSupport 843 844 // KeyLogWriter 可以选择以 NSS 密钥日志格式指定 TLS 主密钥的存储目标。 845 // 该目标可用于允许 Wireshark 等外部程序解密 TLS 连接。 846 // KeyLogWriter optionally specifies a destination for TLS master secrets 847 // in NSS key log format that can be used to allow external programs 848 // such as Wireshark to decrypt TLS connections. 849 // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. 850 // Use of KeyLogWriter compromises security and should only be 851 // used for debugging. 852 KeyLogWriter io.Writer 853 854 // mutex protects sessionTicketKeys and autoSessionTicketKeys. 855 mutex sync.RWMutex 856 // sessionTicketKeys contains zero or more ticket keys. If set, it means the 857 // the keys were set with SessionTicketKey or SetSessionTicketKeys. The 858 // first key is used for new tickets and any subsequent keys can be used to 859 // decrypt old tickets. The slice contents are not protected by the mutex 860 // and are immutable. 861 sessionTicketKeys []ticketKey 862 // autoSessionTicketKeys is like sessionTicketKeys but is owned by the 863 // auto-rotation logic. See Config.ticketKeys. 864 autoSessionTicketKeys []ticketKey 865 } 866 867 const ( 868 // ticketKeyNameLen is the number of bytes of identifier that is prepended to 869 // an encrypted session ticket in order to identify the key used to encrypt it. 870 ticketKeyNameLen = 16 871 872 // ticketKeyLifetime is how long a ticket key remains valid and can be used to 873 // resume a client connection. 874 ticketKeyLifetime = 7 * 24 * time.Hour // 7 days 875 876 // ticketKeyRotation is how often the server should rotate the session ticket key 877 // that is used for new tickets. 878 ticketKeyRotation = 24 * time.Hour 879 ) 880 881 // ticketKey is the internal representation of a session ticket key. 882 type ticketKey struct { 883 // keyName is an opaque byte string that serves to identify the session 884 // ticket key. It's exposed as plaintext in every session ticket. 885 keyName [ticketKeyNameLen]byte 886 // 原先是aesKey,国密改造改为sm4 887 sm4Key [16]byte 888 hmacKey [16]byte 889 // created is the time at which this ticket key was created. See Config.ticketKeys. 890 created time.Time 891 } 892 893 // ticketKeyFromBytes converts from the external representation of a session 894 // ticket key to a ticketKey. Externally, session ticket keys are 32 random 895 // bytes and this function expands that into sufficient name and key material. 896 func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) { 897 // 目前只能继续采用sha512,因为sm3校验和长度只有32个字节,不够用。 898 hashed := sha512.Sum512(b[:]) 899 // 1~16字节作为 keyName 900 copy(key.keyName[:], hashed[:ticketKeyNameLen]) 901 // 17~32字节作为aesKey 902 copy(key.sm4Key[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16]) 903 // 33~64字节作为hmacKey 904 copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32]) 905 key.created = c.time() 906 return key 907 } 908 909 // maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session 910 // ticket, and the lifetime we set for tickets we send. 911 const maxSessionTicketLifetime = 7 * 24 * time.Hour 912 913 // Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is 914 // being used concurrently by a TLS client or server. 915 func (c *Config) Clone() *Config { 916 if c == nil { 917 return nil 918 } 919 c.mutex.RLock() 920 defer c.mutex.RUnlock() 921 return &Config{ 922 // GMSupport: c.GMSupport, 923 Rand: c.Rand, 924 Time: c.Time, 925 Certificates: c.Certificates, 926 NameToCertificate: c.NameToCertificate, 927 GetCertificate: c.GetCertificate, 928 // GetKECertificate: c.GetKECertificate, 929 GetClientCertificate: c.GetClientCertificate, 930 GetConfigForClient: c.GetConfigForClient, 931 VerifyPeerCertificate: c.VerifyPeerCertificate, 932 VerifyConnection: c.VerifyConnection, 933 RootCAs: c.RootCAs, 934 NextProtos: c.NextProtos, 935 ServerName: c.ServerName, 936 ClientAuth: c.ClientAuth, 937 ClientCAs: c.ClientCAs, 938 InsecureSkipVerify: c.InsecureSkipVerify, 939 CipherSuites: c.CipherSuites, 940 PreferServerCipherSuites: c.PreferServerCipherSuites, 941 SessionTicketsDisabled: c.SessionTicketsDisabled, 942 SessionTicketKey: c.SessionTicketKey, 943 ClientSessionCache: c.ClientSessionCache, 944 MinVersion: c.MinVersion, 945 MaxVersion: c.MaxVersion, 946 CurvePreferences: c.CurvePreferences, 947 DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, 948 Renegotiation: c.Renegotiation, 949 KeyLogWriter: c.KeyLogWriter, 950 sessionTicketKeys: c.sessionTicketKeys, 951 autoSessionTicketKeys: c.autoSessionTicketKeys, 952 PreferCipherSuites: c.PreferCipherSuites, 953 SignAlgPrefer: c.SignAlgPrefer, 954 } 955 } 956 957 // deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was 958 // randomized for backwards compatibility but is not in use. 959 var deprecatedSessionTicketKey = []byte("DEPRECATED") 960 961 // initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is 962 // randomized if empty, and that sessionTicketKeys is populated from it otherwise. 963 func (c *Config) initLegacySessionTicketKeyRLocked() { 964 // Don't write if SessionTicketKey is already defined as our deprecated string, 965 // or if it is defined by the user but sessionTicketKeys is already set. 966 if c.SessionTicketKey != [32]byte{} && 967 (bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) { 968 return 969 } 970 971 // We need to write some data, so get an exclusive lock and re-check any conditions. 972 c.mutex.RUnlock() 973 defer c.mutex.RLock() 974 c.mutex.Lock() 975 defer c.mutex.Unlock() 976 if c.SessionTicketKey == [32]byte{} { 977 // 生成一个长度32的随机SessionTicketKey 978 if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { 979 panic(fmt.Sprintf("gmtls: unable to generate random session ticket key: %v", err)) 980 } 981 // Write the deprecated prefix at the beginning so we know we created 982 // it. This key with the DEPRECATED prefix isn't used as an actual 983 // session ticket key, and is only randomized in case the application 984 // reuses it for some reason. 985 copy(c.SessionTicketKey[:], deprecatedSessionTicketKey) 986 } else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 { 987 c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)} 988 } 989 990 } 991 992 // 为当前连接获取ticketKeys。 993 // ticketKeys returns the ticketKeys for this connection. 994 // If configForClient has explicitly set keys, those will 995 // be returned. Otherwise, the keys on c will be used and 996 // may be rotated if auto-managed. 997 // During rotation, any expired session ticket keys are deleted from 998 // c.sessionTicketKeys. If the session ticket key that is currently 999 // encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys) 1000 // is not fresh, then a new session ticket key will be 1001 // created and prepended to c.sessionTicketKeys. 1002 func (c *Config) ticketKeys(configForClient *Config) []ticketKey { 1003 // If the ConfigForClient callback returned a Config with explicitly set 1004 // keys, use those, otherwise just use the original Config. 1005 if configForClient != nil { 1006 configForClient.mutex.RLock() 1007 if configForClient.SessionTicketsDisabled { 1008 return nil 1009 } 1010 configForClient.initLegacySessionTicketKeyRLocked() 1011 if len(configForClient.sessionTicketKeys) != 0 { 1012 ret := configForClient.sessionTicketKeys 1013 configForClient.mutex.RUnlock() 1014 return ret 1015 } 1016 configForClient.mutex.RUnlock() 1017 } 1018 1019 c.mutex.RLock() 1020 defer c.mutex.RUnlock() 1021 if c.SessionTicketsDisabled { 1022 return nil 1023 } 1024 c.initLegacySessionTicketKeyRLocked() 1025 if len(c.sessionTicketKeys) != 0 { 1026 return c.sessionTicketKeys 1027 } 1028 // Fast path for the common case where the key is fresh enough. 1029 if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation { 1030 return c.autoSessionTicketKeys 1031 } 1032 1033 // autoSessionTicketKeys are managed by auto-rotation. 1034 c.mutex.RUnlock() 1035 defer c.mutex.RLock() 1036 c.mutex.Lock() 1037 defer c.mutex.Unlock() 1038 // Re-check the condition in case it changed since obtaining the new lock. 1039 if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation { 1040 var newKey [32]byte 1041 if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil { 1042 panic(fmt.Sprintf("unable to generate random session ticket key: %v", err)) 1043 } 1044 valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1) 1045 valid = append(valid, c.ticketKeyFromBytes(newKey)) 1046 for _, k := range c.autoSessionTicketKeys { 1047 // While rotating the current key, also remove any expired ones. 1048 if c.time().Sub(k.created) < ticketKeyLifetime { 1049 valid = append(valid, k) 1050 } 1051 } 1052 c.autoSessionTicketKeys = valid 1053 } 1054 return c.autoSessionTicketKeys 1055 } 1056 1057 // SetSessionTicketKeys updates the session ticket keys for a server. 1058 // 1059 // The first key will be used when creating new tickets, while all keys can be 1060 // used for decrypting tickets. It is safe to call this function while the 1061 // server is running in order to rotate the session ticket keys. The function 1062 // will panic if keys is empty. 1063 // 1064 // Calling this function will turn off automatic session ticket key rotation. 1065 // 1066 // If multiple servers are terminating connections for the same host they should 1067 // all have the same session ticket keys. If the session ticket keys leaks, 1068 // previously recorded and future TLS connections using those keys might be 1069 // compromised. 1070 func (c *Config) SetSessionTicketKeys(keys [][32]byte) { 1071 if len(keys) == 0 { 1072 panic("gmtls: keys must have at least one key") 1073 } 1074 1075 newKeys := make([]ticketKey, len(keys)) 1076 for i, key := range keys { 1077 newKeys[i] = c.ticketKeyFromBytes(key) 1078 } 1079 1080 c.mutex.Lock() 1081 c.sessionTicketKeys = newKeys 1082 c.mutex.Unlock() 1083 } 1084 1085 func (c *Config) rand() io.Reader { 1086 r := c.Rand 1087 if r == nil { 1088 return rand.Reader 1089 } 1090 return r 1091 } 1092 1093 func (c *Config) time() time.Time { 1094 t := c.Time 1095 if t == nil { 1096 t = time.Now 1097 } 1098 return t() 1099 } 1100 1101 func (c *Config) cipherSuites() []uint16 { 1102 if c.CipherSuites != nil { 1103 return c.CipherSuites 1104 } 1105 return defaultCipherSuites 1106 } 1107 1108 // TODO: 可能需要调整 VersionGMSSL 的位置 1109 var supportedVersions = []uint16{ 1110 VersionTLS13, 1111 VersionTLS12, 1112 VersionTLS11, 1113 VersionTLS10, 1114 VersionGMSSL, 1115 } 1116 1117 // 获取目标Config支持的TLS协议 1118 // 协议版本需要位于[c.MinVersion, c.MaxVersion]之间 1119 func (c *Config) supportedVersions() []uint16 { 1120 versions := make([]uint16, 0, len(supportedVersions)) 1121 for _, v := range supportedVersions { 1122 if c != nil && c.MinVersion != 0 && v < c.MinVersion { 1123 continue 1124 } 1125 if c != nil && c.MaxVersion != 0 && v > c.MaxVersion { 1126 continue 1127 } 1128 versions = append(versions, v) 1129 } 1130 return versions 1131 } 1132 1133 // 获取支持的最高TLS协议版本 1134 func (c *Config) maxSupportedVersion() uint16 { 1135 supportedVersions := c.supportedVersions() 1136 if len(supportedVersions) == 0 { 1137 return 0 1138 } 1139 // supportedVersions列表中,越高的版本越靠前 1140 return supportedVersions[0] 1141 } 1142 1143 // supportedVersionsFromMax returns a list of supported versions derived from a 1144 // legacy maximum version value. Note that only versions supported by this 1145 // library are returned. Any newer peer will use supportedVersions anyway. 1146 func supportedVersionsFromMax(maxVersion uint16) []uint16 { 1147 versions := make([]uint16, 0, len(supportedVersions)) 1148 for _, v := range supportedVersions { 1149 if v > maxVersion { 1150 continue 1151 } 1152 versions = append(versions, v) 1153 } 1154 return versions 1155 } 1156 1157 // 将sm2p256列为默认曲线首位 1158 var defaultCurvePreferences = []CurveID{Curve256Sm2, X25519, CurveP256, CurveP384, CurveP521} 1159 1160 func (c *Config) curvePreferences() []CurveID { 1161 if c == nil || len(c.CurvePreferences) == 0 { 1162 return defaultCurvePreferences 1163 } 1164 return c.CurvePreferences 1165 } 1166 1167 func (c *Config) supportsCurve(curve CurveID) bool { 1168 for _, cc := range c.curvePreferences() { 1169 if cc == curve { 1170 return true 1171 } 1172 } 1173 return false 1174 } 1175 1176 // 协商tls协议 1177 // 根据对方传来的tls版本信息,从己方支持的版本列表中从前往后选取第一个匹配的版本。 1178 // 目前优先匹配顺序是 tls1.3 -> gmssl -> tls1.2 ... 1179 // mutualVersion returns the protocol version to use given the advertised 1180 // versions of the peer. Priority is given to the peer preference order. 1181 func (c *Config) mutualVersion(peerVersions []uint16) (uint16, bool) { 1182 supportedVersions := c.supportedVersions() 1183 for _, peerVersion := range peerVersions { 1184 for _, v := range supportedVersions { 1185 if v == peerVersion { 1186 return v, true 1187 } 1188 } 1189 } 1190 return 0, false 1191 } 1192 1193 // getCertificate 返回密钥交换使用的证书及密钥 1194 // 该方法只有GMSSL会调用 1195 // 如果 Certificates 长度大于等于2时,默认返回第2个证书密钥 1196 // 如果 Certificates 为空或不足2时,调用 GetEKCertificate 方法获取。 1197 // func (c *Config) getEKCertificate(clientHello *ClientHelloInfo) (*Certificate, error) { 1198 // if c.GetKECertificate != nil && (len(c.Certificates) < 2) { 1199 // cert, err := c.GetKECertificate(clientHello) 1200 // if cert != nil || err != nil { 1201 // return cert, err 1202 // } 1203 // } 1204 // if len(c.Certificates) >= 2 { 1205 // return &c.Certificates[1], nil 1206 // } 1207 // return nil, errors.New("gmtls: no key exchange (encrypt) certificate configured") 1208 // } 1209 1210 var errNoCertificates = errors.New("gmtls: no certificates configured") 1211 1212 // getCertificate returns the best certificate for the given ClientHelloInfo, 1213 // defaulting to the first element of c.Certificates. 1214 func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) { 1215 // 优先使用在config中设置的GetCertificate函数 1216 // 需要config配置GetCertificate且没有配置Certificates, 或config配置了GetCertificate且ClientHello中写入了ServerName 1217 if c.GetCertificate != nil && 1218 (len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) { 1219 zclog.Debugln("调用tlsConfig中配置的GetCertificate函数") 1220 cert, err := c.GetCertificate(clientHello) 1221 if cert != nil || err != nil { 1222 zclog.Debugf("调用tlsConfig中配置的GetCertificate函数获取服务端证书, 对应私钥类型: %T", cert.PrivateKey) 1223 return cert, err 1224 } 1225 } 1226 1227 if len(c.Certificates) == 0 { 1228 return nil, errNoCertificates 1229 } 1230 1231 if len(c.Certificates) == 1 { 1232 // There's only one choice, so no point doing any work. 1233 zclog.Debugf("tlsConfig的Certificates只存放了一个证书,直接返回它,对应私钥类型: %T", c.Certificates[0].PrivateKey) 1234 return &c.Certificates[0], nil 1235 } 1236 1237 // 次优先使用config中设置的NameToCertificate, 这是一个map,尝试用clientHello.ServerName为key获取对应证书 1238 if c.NameToCertificate != nil { 1239 name := strings.ToLower(clientHello.ServerName) 1240 if cert, ok := c.NameToCertificate[name]; ok { 1241 return cert, nil 1242 } 1243 if len(name) > 0 { 1244 labels := strings.Split(name, ".") 1245 labels[0] = "*" 1246 wildcardName := strings.Join(labels, ".") 1247 if cert, ok := c.NameToCertificate[wildcardName]; ok { 1248 return cert, nil 1249 } 1250 } 1251 } 1252 1253 for _, cert := range c.Certificates { 1254 if err := clientHello.SupportsCertificate(&cert); err == nil { 1255 zclog.Debugf("从tlsConfig配置的Certificates中匹配到服务端证书, 对应私钥类型: %T", cert.PrivateKey) 1256 return &cert, nil 1257 } 1258 } 1259 1260 // If nothing matches, return the first certificate. 1261 return &c.Certificates[0], nil 1262 } 1263 1264 // SupportsCertificate returns nil if the provided certificate is supported by 1265 // the client that sent the ClientHello. Otherwise, it returns an error 1266 // describing the reason for the incompatibility. 1267 // 1268 // If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate 1269 // callback, this method will take into account the associated Config. Note that 1270 // if GetConfigForClient returns a different Config, the change can't be 1271 // accounted for by this method. 1272 // 1273 // This function will call x509.ParseCertificate unless c.Leaf is set, which can 1274 // incur a significant performance cost. 1275 func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error { 1276 // Note we don't currently support certificate_authorities nor 1277 // signature_algorithms_cert, and don't check the algorithms of the 1278 // signatures on the chain (which anyway are a SHOULD, see RFC 8446, 1279 // Section 4.4.2.2). 1280 1281 config := chi.config 1282 if config == nil { 1283 config = &Config{} 1284 } 1285 vers, ok := config.mutualVersion(chi.SupportedVersions) 1286 if !ok { 1287 return errors.New("no mutually supported protocol versions") 1288 } 1289 1290 // If the client specified the name they are trying to connect to, the 1291 // certificate needs to be valid for it. 1292 if chi.ServerName != "" { 1293 x509Cert, err := c.leaf() 1294 if err != nil { 1295 return fmt.Errorf("failed to parse certificate: %w", err) 1296 } 1297 if err := x509Cert.VerifyHostname(chi.ServerName); err != nil { 1298 return fmt.Errorf("certificate is not valid for requested server name: %w", err) 1299 } 1300 } 1301 1302 // supportsRSAFallback returns nil if the certificate and connection support 1303 // the static RSA key exchange, and unsupported otherwise. The logic for 1304 // supporting static RSA is completely disjoint from the logic for 1305 // supporting signed key exchanges, so we just check it as a fallback. 1306 supportsRSAFallback := func(unsupported error) error { 1307 // TLS 1.3 dropped support for the static RSA key exchange. 1308 if vers == VersionTLS13 || vers == VersionGMSSL { 1309 return unsupported 1310 } 1311 // The static RSA key exchange works by decrypting a challenge with the 1312 // RSA private key, not by signing, so check the PrivateKey implements 1313 // crypto.Decrypter, like *rsa.PrivateKey does. 1314 if priv, ok := c.PrivateKey.(crypto.Decrypter); ok { 1315 if _, ok := priv.Public().(*rsa.PublicKey); !ok { 1316 return unsupported 1317 } 1318 } else { 1319 return unsupported 1320 } 1321 // Finally, there needs to be a mutual cipher suite that uses the static 1322 // RSA key exchange instead of ECDHE. 1323 rsaCipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool { 1324 if c.flags&suiteECDHE != 0 { 1325 return false 1326 } 1327 if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { 1328 return false 1329 } 1330 return true 1331 }) 1332 if rsaCipherSuite == nil { 1333 return unsupported 1334 } 1335 return nil 1336 } 1337 1338 // If the client sent the signature_algorithms extension, ensure it supports 1339 // schemes we can use with this certificate and TLS version. 1340 if len(chi.SignatureSchemes) > 0 { 1341 if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil { 1342 return supportsRSAFallback(err) 1343 } 1344 } 1345 1346 // In TLS 1.3 we are done because supported_groups is only relevant to the 1347 // ECDHE computation, point format negotiation is removed, cipher suites are 1348 // only relevant to the AEAD choice, and static RSA does not exist. 1349 //if vers == VersionTLS13 || vers == VersionGMSSL { 1350 // // TODO 需要添加 1351 // return nil 1352 //} 1353 1354 // The only signed key exchange we support is ECDHE. 1355 if !supportsECDHE(config, chi.SupportedCurves, chi.SupportedPoints) { 1356 return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange")) 1357 } 1358 1359 var ecdsaCipherSuite bool 1360 if priv, ok := c.PrivateKey.(crypto.Signer); ok { 1361 switch pub := priv.Public().(type) { 1362 // 添加sm2分支 1363 case *sm2.PublicKey: 1364 var curve CurveID 1365 switch pub.Curve { 1366 case sm2.P256Sm2(): 1367 curve = Curve256Sm2 1368 default: 1369 return supportsRSAFallback(unsupportedCertificateError(c)) 1370 } 1371 var curveOk bool 1372 for _, c := range chi.SupportedCurves { 1373 if c == curve && config.supportsCurve(c) { 1374 curveOk = true 1375 break 1376 } 1377 } 1378 if !curveOk { 1379 return errors.New("client doesn't support certificate curve") 1380 } 1381 ecdsaCipherSuite = true 1382 case *ecdsa.PublicKey: 1383 var curve CurveID 1384 switch pub.Curve { 1385 case elliptic.P256(): 1386 curve = CurveP256 1387 case elliptic.P384(): 1388 curve = CurveP384 1389 case elliptic.P521(): 1390 curve = CurveP521 1391 default: 1392 return supportsRSAFallback(unsupportedCertificateError(c)) 1393 } 1394 var curveOk bool 1395 for _, c := range chi.SupportedCurves { 1396 if c == curve && config.supportsCurve(c) { 1397 curveOk = true 1398 break 1399 } 1400 } 1401 if !curveOk { 1402 return errors.New("client doesn't support certificate curve") 1403 } 1404 if config.SignAlgPrefer != nil && 1405 len(config.SignAlgPrefer) > 0 { 1406 var sigAlgOk bool 1407 for _, signatureAlgorithm := range config.SignAlgPrefer { 1408 if signatureAlgorithm == ECDSAWithP256AndSHA256 || 1409 signatureAlgorithm == ECDSAWithP384AndSHA384 || 1410 signatureAlgorithm == ECDSAWithP521AndSHA512 { 1411 sigAlgOk = true 1412 break 1413 } 1414 } 1415 if !sigAlgOk { 1416 return errors.New("client doesn't support certificate signatureAlgorithm") 1417 } 1418 } 1419 1420 ecdsaCipherSuite = true 1421 case *ecdsa_ext.PublicKey: 1422 var curve CurveID 1423 switch pub.Curve { 1424 case elliptic.P256(): 1425 curve = CurveP256 1426 case elliptic.P384(): 1427 curve = CurveP384 1428 case elliptic.P521(): 1429 curve = CurveP521 1430 default: 1431 return supportsRSAFallback(unsupportedCertificateError(c)) 1432 } 1433 var curveOk bool 1434 for _, c := range chi.SupportedCurves { 1435 if c == curve && config.supportsCurve(c) { 1436 curveOk = true 1437 break 1438 } 1439 } 1440 if !curveOk { 1441 return errors.New("client doesn't support certificate curve") 1442 } 1443 if config.SignAlgPrefer != nil && 1444 len(config.SignAlgPrefer) > 0 { 1445 var sigAlgOk bool 1446 for _, signatureAlgorithm := range config.SignAlgPrefer { 1447 if signatureAlgorithm == ECDSAEXTWithP256AndSHA256 || 1448 signatureAlgorithm == ECDSAEXTWithP384AndSHA384 || 1449 signatureAlgorithm == ECDSAEXTWithP521AndSHA512 { 1450 sigAlgOk = true 1451 break 1452 } 1453 } 1454 if !sigAlgOk { 1455 return errors.New("client doesn't support certificate signatureAlgorithm") 1456 } 1457 } 1458 ecdsaCipherSuite = true 1459 case ed25519.PublicKey: 1460 if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 { 1461 return errors.New("connection doesn't support Ed25519") 1462 } 1463 ecdsaCipherSuite = true 1464 case *rsa.PublicKey: 1465 default: 1466 return supportsRSAFallback(unsupportedCertificateError(c)) 1467 } 1468 } else { 1469 return supportsRSAFallback(unsupportedCertificateError(c)) 1470 } 1471 1472 // Make sure that there is a mutually supported cipher suite that works with 1473 // this certificate. Cipher suite selection will then apply the logic in 1474 // reverse to pick it. See also serverHandshakeState.cipherSuiteOk. 1475 cipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool { 1476 if c.flags&suiteECDHE == 0 { 1477 return false 1478 } 1479 if c.flags&suiteECSign != 0 { 1480 if !ecdsaCipherSuite { 1481 return false 1482 } 1483 } else { 1484 if ecdsaCipherSuite { 1485 return false 1486 } 1487 } 1488 if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { 1489 return false 1490 } 1491 return true 1492 }) 1493 if cipherSuite == nil { 1494 return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate")) 1495 } 1496 1497 return nil 1498 } 1499 1500 // SupportsCertificate returns nil if the provided certificate is supported by 1501 // the server that sent the CertificateRequest. Otherwise, it returns an error 1502 // describing the reason for the incompatibility. 1503 func (cri *CertificateRequestInfo) SupportsCertificate(c *Certificate) error { 1504 if _, err := selectSignatureScheme(cri.Version, c, cri.SignatureSchemes); err != nil { 1505 return err 1506 } 1507 1508 if len(cri.AcceptableCAs) == 0 { 1509 return nil 1510 } 1511 1512 for j, cert := range c.Certificate { 1513 x509Cert := c.Leaf 1514 // Parse the certificate if this isn't the leaf node, or if 1515 // chain.Leaf was nil. 1516 if j != 0 || x509Cert == nil { 1517 var err error 1518 if x509Cert, err = x509.ParseCertificate(cert); err != nil { 1519 return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err) 1520 } 1521 } 1522 1523 for _, ca := range cri.AcceptableCAs { 1524 if bytes.Equal(x509Cert.RawIssuer, ca) { 1525 return nil 1526 } 1527 } 1528 } 1529 return errors.New("chain is not signed by an acceptable CA") 1530 } 1531 1532 // BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate 1533 // from the CommonName and SubjectAlternateName fields of each of the leaf 1534 // certificates. 1535 // 1536 // ToDeprecated: NameToCertificate only allows associating a single certificate 1537 // with a given name. Leave that field nil to let the library select the first 1538 // compatible chain from Certificates. 1539 func (c *Config) BuildNameToCertificate() { 1540 c.NameToCertificate = make(map[string]*Certificate) 1541 for i := range c.Certificates { 1542 cert := &c.Certificates[i] 1543 x509Cert, err := cert.leaf() 1544 if err != nil { 1545 continue 1546 } 1547 // If SANs are *not* present, some clients will consider the certificate 1548 // valid for the name in the Common Name. 1549 if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 { 1550 c.NameToCertificate[x509Cert.Subject.CommonName] = cert 1551 } 1552 for _, san := range x509Cert.DNSNames { 1553 c.NameToCertificate[san] = cert 1554 } 1555 } 1556 } 1557 1558 const ( 1559 keyLogLabelTLS12 = "CLIENT_RANDOM" 1560 keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET" 1561 keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET" 1562 keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0" 1563 keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0" 1564 ) 1565 1566 func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error { 1567 if c.KeyLogWriter == nil { 1568 return nil 1569 } 1570 1571 logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret)) 1572 1573 writerMutex.Lock() 1574 _, err := c.KeyLogWriter.Write(logLine) 1575 writerMutex.Unlock() 1576 1577 return err 1578 } 1579 1580 // writerMutex protects all KeyLogWriters globally. It is rarely enabled, 1581 // and is only for debugging, so a global mutex saves space. 1582 var writerMutex sync.Mutex 1583 1584 // Certificate 证书链, 子证书在前 1585 // A Certificate is a chain of one or more certificates, leaf first. 1586 type Certificate struct { 1587 // 证书列表 1588 Certificate [][]byte 1589 // 子证书公钥对应的私钥 1590 // PrivateKey contains the private key corresponding to the public key in 1591 // Leaf. This must implement crypto.Signer with an RSA, ECDSA or Ed25519 PublicKey. 1592 // For a server up to TLS 1.2, it can also implement crypto.Decrypter with 1593 // an RSA PublicKey. 1594 PrivateKey crypto.PrivateKey 1595 // 子证书私钥支持的签名算法列表 1596 // SupportedSignatureAlgorithms is an optional list restricting what 1597 // signature algorithms the PrivateKey can be used for. 1598 SupportedSignatureAlgorithms []SignatureScheme 1599 // 供客户端请求的OCSP响应 1600 // OCSPStaple contains an optional OCSP response which will be served 1601 // to clients that request it. 1602 OCSPStaple []byte 1603 // 供客户端请求的证书签名时间列表 1604 // SignedCertificateTimestamps contains an optional list of Signed 1605 // Certificate Timestamps which will be served to clients that request it. 1606 SignedCertificateTimestamps [][]byte 1607 // 子证书 1608 // Leaf is the parsed form of the leaf certificate, which may be initialized 1609 // using x509.ParseCertificate to reduce per-handshake processing. If nil, 1610 // the leaf certificate will be parsed as needed. 1611 Leaf *x509.Certificate 1612 } 1613 1614 // leaf returns the parsed leaf certificate, either from c.Leaf or by parsing 1615 // the corresponding c.Certificate[0]. 1616 func (c *Certificate) leaf() (*x509.Certificate, error) { 1617 if c.Leaf != nil { 1618 return c.Leaf, nil 1619 } 1620 return x509.ParseCertificate(c.Certificate[0]) 1621 } 1622 1623 type handshakeMessage interface { 1624 marshal() []byte 1625 unmarshal([]byte) bool 1626 } 1627 1628 // 使用LRU(近期最少使用)算法实现的客户端会话缓存。 1629 // lruSessionCache is a ClientSessionCache implementation that uses an LRU 1630 // caching strategy. 1631 type lruSessionCache struct { 1632 sync.Mutex 1633 1634 m map[string]*list.Element 1635 q *list.List 1636 capacity int 1637 } 1638 1639 type lruSessionCacheEntry struct { 1640 sessionKey string 1641 state *ClientSessionState 1642 } 1643 1644 // NewLRUClientSessionCache returns a ClientSessionCache with the given 1645 // capacity that uses an LRU strategy. If capacity is < 1, a default capacity 1646 // is used instead. 1647 func NewLRUClientSessionCache(capacity int) ClientSessionCache { 1648 const defaultSessionCacheCapacity = 64 1649 1650 if capacity < 1 { 1651 capacity = defaultSessionCacheCapacity 1652 } 1653 return &lruSessionCache{ 1654 m: make(map[string]*list.Element), 1655 q: list.New(), 1656 capacity: capacity, 1657 } 1658 } 1659 1660 // Put 存储会话到缓存, 实现了 ClientSessionCache 接口 1661 // Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry 1662 // corresponding to sessionKey is removed from the cache instead. 1663 func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) { 1664 c.Lock() 1665 defer c.Unlock() 1666 1667 if elem, ok := c.m[sessionKey]; ok { 1668 if cs == nil { 1669 c.q.Remove(elem) 1670 delete(c.m, sessionKey) 1671 } else { 1672 entry := elem.Value.(*lruSessionCacheEntry) 1673 entry.state = cs 1674 c.q.MoveToFront(elem) 1675 } 1676 return 1677 } 1678 1679 if c.q.Len() < c.capacity { 1680 entry := &lruSessionCacheEntry{sessionKey, cs} 1681 c.m[sessionKey] = c.q.PushFront(entry) 1682 return 1683 } 1684 1685 elem := c.q.Back() 1686 entry := elem.Value.(*lruSessionCacheEntry) 1687 delete(c.m, entry.sessionKey) 1688 entry.sessionKey = sessionKey 1689 entry.state = cs 1690 c.q.MoveToFront(elem) 1691 c.m[sessionKey] = elem 1692 } 1693 1694 // Get 从缓存获取会话, 实现了 ClientSessionCache 接口 1695 // Get returns the ClientSessionState value associated with a given key. It 1696 // returns (nil, false) if no value is found. 1697 func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) { 1698 c.Lock() 1699 defer c.Unlock() 1700 1701 if elem, ok := c.m[sessionKey]; ok { 1702 c.q.MoveToFront(elem) 1703 return elem.Value.(*lruSessionCacheEntry).state, true 1704 } 1705 return nil, false 1706 } 1707 1708 var emptyConfig Config 1709 1710 func defaultConfig() *Config { 1711 return &emptyConfig 1712 } 1713 1714 func unexpectedMessageError(wanted, got interface{}) error { 1715 return fmt.Errorf("gmtls: received unexpected handshake message of type %T when waiting for %T", got, wanted) 1716 } 1717 1718 // 判断是否支持目标签名算法 1719 // - sigAlg : 目标签名算法 1720 // - supportedSignatureAlgorithms : 支持的签名算法集合 1721 func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool { 1722 for _, s := range supportedSignatureAlgorithms { 1723 if s == sigAlg { 1724 return true 1725 } 1726 } 1727 return false 1728 }