Does the handshake, either a full one or resumes old session. Requires hs.c, hs.hello, hs.serverHello, and, optionally, hs.session to be set.
()
| 551 | // Does the handshake, either a full one or resumes old session. Requires hs.c, |
| 552 | // hs.hello, hs.serverHello, and, optionally, hs.session to be set. |
| 553 | func (hs *clientHandshakeState) handshake() error { |
| 554 | c := hs.c |
| 555 | |
| 556 | // If we did not load a session (hs.session == nil), but we did set a |
| 557 | // session ID in the transmitted client hello (hs.hello.sessionId != nil), |
| 558 | // it means we tried to negotiate TLS 1.3 and sent a random session ID as a |
| 559 | // compatibility measure (see RFC 8446, Section 4.1.2). |
| 560 | // |
| 561 | // Since we're now handshaking for TLS 1.2, if the server echoed the |
| 562 | // transmitted ID back to us, we know mischief is afoot: the session ID |
| 563 | // was random and can't possibly be recognized by the server. |
| 564 | if hs.session == nil && hs.hello.sessionId != nil && bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) { |
| 565 | c.sendAlert(alertIllegalParameter) |
| 566 | return errors.New("tls: server echoed TLS 1.3 compatibility session ID in TLS 1.2") |
| 567 | } |
| 568 | |
| 569 | isResume, err := hs.processServerHello() |
| 570 | if err != nil { |
| 571 | return err |
| 572 | } |
| 573 | |
| 574 | hs.finishedHash = newFinishedHash(c.vers, hs.suite) |
| 575 | |
| 576 | // No signatures of the handshake are needed in a resumption. |
| 577 | // Otherwise, in a full handshake, if we don't have any certificates |
| 578 | // configured then we will never send a CertificateVerify message and |
| 579 | // thus no signatures are needed in that case either. |
| 580 | if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) { |
| 581 | hs.finishedHash.discardHandshakeBuffer() |
| 582 | } |
| 583 | |
| 584 | if err := transcriptMsg(hs.hello, &hs.finishedHash); err != nil { |
| 585 | return err |
| 586 | } |
| 587 | if err := transcriptMsg(hs.serverHello, &hs.finishedHash); err != nil { |
| 588 | return err |
| 589 | } |
| 590 | |
| 591 | c.buffering = true |
| 592 | c.didResume = isResume |
| 593 | if isResume { |
| 594 | if err := hs.establishKeys(); err != nil { |
| 595 | return err |
| 596 | } |
| 597 | if err := hs.readSessionTicket(); err != nil { |
| 598 | return err |
| 599 | } |
| 600 | if err := hs.readFinished(c.serverFinished[:]); err != nil { |
| 601 | return err |
| 602 | } |
| 603 | c.clientFinishedIsFirst = false |
| 604 | // Make sure the connection is still being verified whether or not this |
| 605 | // is a resumption. Resumptions currently don't reverify certificates so |
| 606 | // they don't call verifyServerCertificate. See Issue 31641. |
| 607 | if c.config.VerifyConnection != nil { |
| 608 | if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { |
| 609 | c.sendAlert(alertBadCertificate) |
| 610 | return err |
no test coverage detected