github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/gmtls/gm_handshake_client_double.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gmtls 6 7 import ( 8 "bytes" 9 "crypto" 10 "crypto/ecdsa" 11 "crypto/rsa" 12 "crypto/subtle" 13 "errors" 14 "fmt" 15 "github.com/Hyperledger-TWGC/tjfoc-gm/sm2" 16 "github.com/Hyperledger-TWGC/tjfoc-gm/x509" 17 "io" 18 "strconv" 19 "sync/atomic" 20 ) 21 22 type clientHandshakeStateGM struct { 23 c *Conn 24 serverHello *serverHelloMsg 25 hello *clientHelloMsg 26 suite *cipherSuite 27 finishedHash finishedHash 28 masterSecret []byte 29 session *ClientSessionState 30 } 31 32 func makeClientHelloGM(config *Config) (*clientHelloMsg, error) { 33 if len(config.ServerName) == 0 && !config.InsecureSkipVerify { 34 return nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config") 35 } 36 37 hello := &clientHelloMsg{ 38 vers: config.GMSupport.GetVersion(), 39 compressionMethods: []uint8{compressionNone}, 40 random: make([]byte, 32), 41 } 42 possibleCipherSuites := getCipherSuites(config) 43 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) 44 45 NextCipherSuite: 46 for _, suiteId := range possibleCipherSuites { 47 for _, suite := range config.GMSupport.cipherSuites() { 48 if suite.id != suiteId { 49 continue 50 } 51 hello.cipherSuites = append(hello.cipherSuites, suiteId) 52 continue NextCipherSuite 53 } 54 } 55 56 _, err := io.ReadFull(config.rand(), hello.random) 57 if err != nil { 58 return nil, errors.New("tls: short read from Rand: " + err.Error()) 59 } 60 61 return hello, nil 62 } 63 64 // Does the handshake, either a full one or resumes old session. 65 // Requires hs.c, hs.hello, and, optionally, hs.session to be set. 66 func (hs *clientHandshakeStateGM) handshake() error { 67 c := hs.c 68 69 // send ClientHello 70 if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { 71 return err 72 } 73 74 msg, err := c.readHandshake() 75 if err != nil { 76 return err 77 } 78 79 var ok bool 80 if hs.serverHello, ok = msg.(*serverHelloMsg); !ok { 81 c.sendAlert(alertUnexpectedMessage) 82 return unexpectedMessageError(hs.serverHello, msg) 83 } 84 85 if hs.serverHello.vers != VersionGMSSL { 86 hs.c.sendAlert(alertProtocolVersion) 87 return fmt.Errorf("tls: server selected unsupported protocol version %x, while expecting %x", hs.serverHello.vers, VersionGMSSL) 88 } 89 90 if err = hs.pickCipherSuite(); err != nil { 91 return err 92 } 93 94 isResume, err := hs.processServerHello() 95 if err != nil { 96 return err 97 } 98 99 hs.finishedHash = newFinishedHashGM(hs.suite) 100 101 // No signatures of the handshake are needed in a resumption. 102 // Otherwise, in a full handshake, if we don't have any certificates 103 // configured then we will never send a CertificateVerify message and 104 // thus no signatures are needed in that case either. 105 if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) { 106 hs.finishedHash.discardHandshakeBuffer() 107 } 108 109 hs.finishedHash.Write(hs.hello.marshal()) 110 hs.finishedHash.Write(hs.serverHello.marshal()) 111 112 c.buffering = true 113 if isResume { 114 if err := hs.establishKeys(); err != nil { 115 return err 116 } 117 if err := hs.readSessionTicket(); err != nil { 118 return err 119 } 120 if err := hs.readFinished(c.serverFinished[:]); err != nil { 121 return err 122 } 123 c.clientFinishedIsFirst = false 124 if err := hs.sendFinished(c.clientFinished[:]); err != nil { 125 return err 126 } 127 if _, err := c.flush(); err != nil { 128 return err 129 } 130 } else { 131 if err := hs.doFullHandshake(); err != nil { 132 return err 133 } 134 if err := hs.establishKeys(); err != nil { 135 return err 136 } 137 if err := hs.sendFinished(c.clientFinished[:]); err != nil { 138 return err 139 } 140 if _, err := c.flush(); err != nil { 141 return err 142 } 143 c.clientFinishedIsFirst = true 144 if err := hs.readSessionTicket(); err != nil { 145 return err 146 } 147 if err := hs.readFinished(c.serverFinished[:]); err != nil { 148 return err 149 } 150 } 151 152 c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random) 153 c.didResume = isResume 154 atomic.StoreUint32(&c.handshakeStatus, 1) 155 156 return nil 157 } 158 159 func (hs *clientHandshakeStateGM) pickCipherSuite() error { 160 if hs.suite = mutualCipherSuiteGM(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil { 161 hs.c.sendAlert(alertHandshakeFailure) 162 return errors.New("tls: server chose an unconfigured cipher suite") 163 } 164 165 hs.c.cipherSuite = hs.suite.id 166 return nil 167 } 168 169 func (hs *clientHandshakeStateGM) doFullHandshake() error { 170 c := hs.c 171 172 msg, err := c.readHandshake() 173 if err != nil { 174 return err 175 } 176 certMsg, ok := msg.(*certificateMsg) 177 if !ok || len(certMsg.certificates) == 0 { 178 c.sendAlert(alertUnexpectedMessage) 179 return unexpectedMessageError(certMsg, msg) 180 } 181 182 // mod by syl only one cert 183 // Thanks to dual certificates mechanism, length of certificates in GMT0024 must great than 2 184 if len(certMsg.certificates) < 2 { 185 c.sendAlert(alertInsufficientSecurity) 186 return fmt.Errorf("tls: length of certificates in GMT0024 must great than 2") 187 } 188 189 hs.finishedHash.Write(certMsg.marshal()) 190 191 if c.handshakes == 0 { 192 // If this is the first handshake on a connection, process and 193 // (optionally) verify the server's certificates. 194 certs := make([]*x509.Certificate, len(certMsg.certificates)) 195 for i, asn1Data := range certMsg.certificates { 196 cert, err := x509.ParseCertificate(asn1Data) 197 if err != nil { 198 c.sendAlert(alertBadCertificate) 199 return errors.New("tls: failed to parse certificate from server: " + err.Error()) 200 } 201 202 pubKey, _ := cert.PublicKey.(*ecdsa.PublicKey) 203 if pubKey.Curve != sm2.P256Sm2() { 204 c.sendAlert(alertUnsupportedCertificate) 205 return fmt.Errorf("tls: pubkey type of cert is error, expect sm2.publicKey") 206 } 207 208 //cert[0] is for signature while cert[1] is for encipher, refer to GMT0024 209 //check key usage 210 switch i { 211 case 0: 212 if cert.KeyUsage == 0 || (cert.KeyUsage&(x509.KeyUsageDigitalSignature|cert.KeyUsage&x509.KeyUsageContentCommitment)) == 0 { 213 c.sendAlert(alertInsufficientSecurity) 214 return fmt.Errorf("tls: the keyusage of cert[0] does not exist or is not for KeyUsageDigitalSignature/KeyUsageContentCommitment, value:%d", cert.KeyUsage) 215 } 216 case 1: 217 if cert.KeyUsage == 0 || (cert.KeyUsage&(x509.KeyUsageDataEncipherment|x509.KeyUsageKeyEncipherment|x509.KeyUsageKeyAgreement)) == 0 { 218 c.sendAlert(alertInsufficientSecurity) 219 return fmt.Errorf("tls: the keyusage of cert[1] does not exist or is not for KeyUsageDataEncipherment/KeyUsageKeyEncipherment/KeyUsageKeyAgreement, value:%d", cert.KeyUsage) 220 } 221 } 222 223 certs[i] = cert 224 } 225 226 if !c.config.InsecureSkipVerify { 227 opts := x509.VerifyOptions{ 228 Roots: c.config.RootCAs, 229 CurrentTime: c.config.time(), 230 DNSName: c.config.ServerName, 231 Intermediates: x509.NewCertPool(), 232 } 233 if opts.Roots == nil { 234 opts.Roots = x509.NewCertPool() 235 } 236 237 for _, rootca := range getCAs() { 238 opts.Roots.AddCert(rootca) 239 } 240 for i, cert := range certs { 241 c.verifiedChains, err = certs[i].Verify(opts) 242 if err != nil { 243 c.sendAlert(alertBadCertificate) 244 return err 245 } 246 if i == 0 || i == 1 { 247 continue 248 } 249 opts.Intermediates.AddCert(cert) 250 } 251 252 } 253 254 if c.config.VerifyPeerCertificate != nil { 255 if err := c.config.VerifyPeerCertificate(certMsg.certificates, c.verifiedChains); err != nil { 256 c.sendAlert(alertBadCertificate) 257 return err 258 } 259 } 260 261 switch certs[0].PublicKey.(type) { 262 case *sm2.PublicKey, *ecdsa.PublicKey, *rsa.PublicKey: 263 break 264 default: 265 c.sendAlert(alertUnsupportedCertificate) 266 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey) 267 } 268 269 c.peerCertificates = certs 270 } else { 271 // This is a renegotiation handshake. We require that the 272 // server's identity (i.e. leaf certificate) is unchanged and 273 // thus any previous trust decision is still valid. 274 // 275 // See https://mitls.org/pages/attacks/3SHAKE for the 276 // motivation behind this requirement. 277 if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) { 278 c.sendAlert(alertBadCertificate) 279 return errors.New("tls: server's identity changed during renegotiation") 280 } 281 } 282 283 msg, err = c.readHandshake() 284 if err != nil { 285 return err 286 } 287 288 keyAgreement := hs.suite.ka(c.vers) 289 if ka, ok := keyAgreement.(*eccKeyAgreementGM); ok { 290 ka.encipherCert = c.peerCertificates[1] 291 } 292 293 skx, ok := msg.(*serverKeyExchangeMsg) 294 if ok { 295 hs.finishedHash.Write(skx.marshal()) 296 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx) 297 if err != nil { 298 c.sendAlert(alertUnexpectedMessage) 299 return err 300 } 301 302 msg, err = c.readHandshake() 303 if err != nil { 304 return err 305 } 306 } 307 308 var chainToSend *Certificate 309 var certRequested bool 310 certReq, ok := msg.(*certificateRequestMsgGM) 311 if ok { 312 certRequested = true 313 hs.finishedHash.Write(certReq.marshal()) 314 315 if chainToSend, err = hs.getCertificate(certReq); err != nil { 316 c.sendAlert(alertInternalError) 317 return err 318 } 319 320 msg, err = c.readHandshake() 321 if err != nil { 322 return err 323 } 324 } 325 326 shd, ok := msg.(*serverHelloDoneMsg) 327 if !ok { 328 c.sendAlert(alertUnexpectedMessage) 329 return unexpectedMessageError(shd, msg) 330 } 331 hs.finishedHash.Write(shd.marshal()) 332 333 // If the server requested a certificate then we have to send a 334 // Certificate message, even if it's empty because we don't have a 335 // certificate to send. 336 if certRequested { 337 certMsg = new(certificateMsg) 338 certMsg.certificates = chainToSend.Certificate 339 hs.finishedHash.Write(certMsg.marshal()) 340 if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { 341 return err 342 } 343 } 344 345 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[1]) 346 if err != nil { 347 c.sendAlert(alertInternalError) 348 return err 349 } 350 if ckx != nil { 351 hs.finishedHash.Write(ckx.marshal()) 352 if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil { 353 return err 354 } 355 } 356 357 if chainToSend != nil && len(chainToSend.Certificate) > 0 { 358 certVerify := &certificateVerifyMsg{} 359 360 key, ok := chainToSend.PrivateKey.(crypto.Signer) 361 if !ok { 362 c.sendAlert(alertInternalError) 363 return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey) 364 } 365 366 digest := hs.finishedHash.client.Sum(nil) 367 368 certVerify.signature, err = key.Sign(c.config.rand(), digest, nil) 369 if err != nil { 370 c.sendAlert(alertInternalError) 371 return err 372 } 373 374 hs.finishedHash.Write(certVerify.marshal()) 375 if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil { 376 return err 377 } 378 } 379 380 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random) 381 if err := c.config.writeKeyLog(hs.hello.random, hs.masterSecret); err != nil { 382 c.sendAlert(alertInternalError) 383 return errors.New("tls: failed to write to key log: " + err.Error()) 384 } 385 386 hs.finishedHash.discardHandshakeBuffer() 387 388 return nil 389 } 390 391 func (hs *clientHandshakeStateGM) establishKeys() error { 392 c := hs.c 393 394 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := 395 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) 396 var clientCipher, serverCipher interface{} 397 var clientHash, serverHash macFunction 398 if hs.suite.cipher != nil { 399 clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) 400 clientHash = hs.suite.mac(c.vers, clientMAC) 401 serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) 402 serverHash = hs.suite.mac(c.vers, serverMAC) 403 } else { 404 clientCipher = hs.suite.aead(clientKey, clientIV) 405 serverCipher = hs.suite.aead(serverKey, serverIV) 406 } 407 408 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) 409 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) 410 return nil 411 } 412 413 func (hs *clientHandshakeStateGM) serverResumedSession() bool { 414 // If the server responded with the same sessionId then it means the 415 // sessionTicket is being used to resume a TLS session. 416 return hs.session != nil && hs.hello.sessionId != nil && 417 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId) 418 } 419 420 func (hs *clientHandshakeStateGM) processServerHello() (bool, error) { 421 c := hs.c 422 423 if hs.serverHello.compressionMethod != compressionNone { 424 c.sendAlert(alertUnexpectedMessage) 425 return false, errors.New("tls: server selected unsupported compression format") 426 } 427 428 if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported { 429 c.secureRenegotiation = true 430 if len(hs.serverHello.secureRenegotiation) != 0 { 431 c.sendAlert(alertHandshakeFailure) 432 return false, errors.New("tls: initial handshake had non-empty renegotiation extension") 433 } 434 } 435 436 if c.handshakes > 0 && c.secureRenegotiation { 437 var expectedSecureRenegotiation [24]byte 438 copy(expectedSecureRenegotiation[:], c.clientFinished[:]) 439 copy(expectedSecureRenegotiation[12:], c.serverFinished[:]) 440 if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) { 441 c.sendAlert(alertHandshakeFailure) 442 return false, errors.New("tls: incorrect renegotiation extension contents") 443 } 444 } 445 446 clientDidNPN := hs.hello.nextProtoNeg 447 clientDidALPN := len(hs.hello.alpnProtocols) > 0 448 serverHasNPN := hs.serverHello.nextProtoNeg 449 serverHasALPN := len(hs.serverHello.alpnProtocol) > 0 450 451 if !clientDidNPN && serverHasNPN { 452 c.sendAlert(alertHandshakeFailure) 453 return false, errors.New("tls: server advertised unrequested NPN extension") 454 } 455 456 if !clientDidALPN && serverHasALPN { 457 c.sendAlert(alertHandshakeFailure) 458 return false, errors.New("tls: server advertised unrequested ALPN extension") 459 } 460 461 if serverHasNPN && serverHasALPN { 462 c.sendAlert(alertHandshakeFailure) 463 return false, errors.New("tls: server advertised both NPN and ALPN extensions") 464 } 465 466 if serverHasALPN { 467 c.clientProtocol = hs.serverHello.alpnProtocol 468 c.clientProtocolFallback = false 469 } 470 c.scts = hs.serverHello.scts 471 472 if !hs.serverResumedSession() { 473 return false, nil 474 } 475 476 if hs.session.vers != c.vers { 477 c.sendAlert(alertHandshakeFailure) 478 return false, errors.New("tls: server resumed a session with a different version") 479 } 480 481 if hs.session.cipherSuite != hs.suite.id { 482 c.sendAlert(alertHandshakeFailure) 483 return false, errors.New("tls: server resumed a session with a different cipher suite") 484 } 485 486 // Restore masterSecret and peerCerts from previous state 487 hs.masterSecret = hs.session.masterSecret 488 c.peerCertificates = hs.session.serverCertificates 489 c.verifiedChains = hs.session.verifiedChains 490 return true, nil 491 } 492 493 func (hs *clientHandshakeStateGM) readFinished(out []byte) error { 494 c := hs.c 495 496 c.readRecord(recordTypeChangeCipherSpec) 497 if c.in.err != nil { 498 return c.in.err 499 } 500 501 msg, err := c.readHandshake() 502 if err != nil { 503 return err 504 } 505 serverFinished, ok := msg.(*finishedMsg) 506 if !ok { 507 c.sendAlert(alertUnexpectedMessage) 508 return unexpectedMessageError(serverFinished, msg) 509 } 510 511 verify := hs.finishedHash.serverSum(hs.masterSecret) 512 if len(verify) != len(serverFinished.verifyData) || 513 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { 514 c.sendAlert(alertHandshakeFailure) 515 return errors.New("tls: server's Finished message was incorrect") 516 } 517 hs.finishedHash.Write(serverFinished.marshal()) 518 copy(out, verify) 519 return nil 520 } 521 522 func (hs *clientHandshakeStateGM) readSessionTicket() error { 523 if !hs.serverHello.ticketSupported { 524 return nil 525 } 526 527 c := hs.c 528 msg, err := c.readHandshake() 529 if err != nil { 530 return err 531 } 532 sessionTicketMsg, ok := msg.(*newSessionTicketMsg) 533 if !ok { 534 c.sendAlert(alertUnexpectedMessage) 535 return unexpectedMessageError(sessionTicketMsg, msg) 536 } 537 hs.finishedHash.Write(sessionTicketMsg.marshal()) 538 539 hs.session = &ClientSessionState{ 540 sessionTicket: sessionTicketMsg.ticket, 541 vers: c.vers, 542 cipherSuite: hs.suite.id, 543 masterSecret: hs.masterSecret, 544 serverCertificates: c.peerCertificates, 545 verifiedChains: c.verifiedChains, 546 } 547 548 return nil 549 } 550 551 func (hs *clientHandshakeStateGM) sendFinished(out []byte) error { 552 c := hs.c 553 554 if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { 555 return err 556 } 557 if hs.serverHello.nextProtoNeg { 558 nextProto := new(nextProtoMsg) 559 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos) 560 nextProto.proto = proto 561 c.clientProtocol = proto 562 c.clientProtocolFallback = fallback 563 564 hs.finishedHash.Write(nextProto.marshal()) 565 if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil { 566 return err 567 } 568 } 569 570 finished := new(finishedMsg) 571 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) 572 hs.finishedHash.Write(finished.marshal()) 573 if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { 574 return err 575 } 576 copy(out, finished.verifyData) 577 return nil 578 } 579 580 //// tls11SignatureSchemes contains the signature schemes that we synthesise for 581 //// a TLS <= 1.1 connection, based on the supported certificate types. 582 //var tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1} 583 // 584 //const ( 585 // // tls11SignatureSchemesNumECDSA is the number of initial elements of 586 // // tls11SignatureSchemes that use ECDSA. 587 // tls11SignatureSchemesNumECDSA = 3 588 // // tls11SignatureSchemesNumRSA is the number of trailing elements of 589 // // tls11SignatureSchemes that use RSA. 590 // tls11SignatureSchemesNumRSA = 4 591 //) 592 593 func (hs *clientHandshakeStateGM) getCertificate(certReq *certificateRequestMsgGM) (*Certificate, error) { 594 c := hs.c 595 596 if c.config.GetClientCertificate != nil { 597 var signatureSchemes []SignatureScheme 598 599 return c.config.GetClientCertificate(&CertificateRequestInfo{ 600 AcceptableCAs: certReq.certificateAuthorities, 601 SignatureSchemes: signatureSchemes, 602 }) 603 } 604 605 // RFC 4346 on the certificateAuthorities field: A list of the 606 // distinguished names of acceptable certificate authorities. 607 // These distinguished names may specify a desired 608 // distinguished name for a root CA or for a subordinate CA; 609 // thus, this message can be used to describe both known roots 610 // and a desired authorization space. If the 611 // certificate_authorities list is empty then the client MAY 612 // send any certificate of the appropriate 613 // ClientCertificateType, unless there is some external 614 // arrangement to the contrary. 615 616 // We need to search our list of client certs for one 617 // where SignatureAlgorithm is acceptable to the server and the 618 // Issuer is in certReq.certificateAuthorities 619 findCert: 620 for i, chain := range c.config.Certificates { 621 622 for j, cert := range chain.Certificate { 623 x509Cert := chain.Leaf 624 // parse the certificate if this isn't the leaf 625 // node, or if chain.Leaf was nil 626 if j != 0 || x509Cert == nil { 627 var err error 628 if x509Cert, err = x509.ParseCertificate(cert); err != nil { 629 c.sendAlert(alertInternalError) 630 return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) 631 } 632 } 633 634 var isGMCert bool 635 636 if x509Cert.PublicKeyAlgorithm == x509.ECDSA { 637 pubKey, ok := x509Cert.PublicKey.(*ecdsa.PublicKey) 638 if ok && pubKey.Curve == sm2.P256Sm2(){ 639 isGMCert = true 640 } 641 } 642 643 if !isGMCert { 644 continue findCert 645 } 646 647 if len(certReq.certificateAuthorities) == 0 { 648 // they gave us an empty list, so just take the 649 // first cert from c.config.Certificates 650 return &chain, nil 651 } 652 653 for _, ca := range certReq.certificateAuthorities { 654 if bytes.Equal(x509Cert.RawIssuer, ca) { 655 return &chain, nil 656 } 657 } 658 } 659 } 660 661 // No acceptable certificate found. Don't send a certificate. 662 return new(Certificate), nil 663 }