541
542 // Use server preference order
543 for (String ap : localApl) {
544 if (protocols.contains(ap)) {
545 negotiatedValue = ap;
546 break;
547 }
548 }
549
550 if (negotiatedValue == null) {
551 fatalSE(Alerts.alert_no_application_protocol,
552 new SSLHandshakeException(
553 "No matching ALPN values"));
554 }
555 applicationProtocol = negotiatedValue;
556
557 } else {
558 applicationProtocol = "";
559 }
560
561 // cookie exchange
562 if (isDTLS) {
563 HelloCookieManager hcMgr = sslContext.getHelloCookieManager();
564 if ((mesg.cookie == null) || (mesg.cookie.length == 0) ||
565 (!hcMgr.isValid(mesg))) {
566
567 //
568 // Perform cookie exchange for DTLS handshaking if no cookie
569 // or the cookie is invalid in the ClientHello message.
570 //
571 HelloVerifyRequest m0 = new HelloVerifyRequest(hcMgr, mesg);
572
573 if (debug != null && Debug.isOn("handshake")) {
574 m0.print(System.out);
575 }
576
577 m0.write(output);
578 handshakeState.update(m0, resumingSession);
579 output.flush();
580
581 return;
582 }
583 }
584
585 /*
586 * FIRST, construct the ServerHello using the options and priorities
587 * from the ClientHello. Update the (pending) cipher spec as we do
588 * so, and save the client's version to protect against rollback
589 * attacks.
590 *
591 * There are a bunch of minor tasks here, and one major one: deciding
592 * if the short or the full handshake sequence will be used.
593 */
594 ServerHello m1 = new ServerHello();
595
596 clientRequestedVersion = mesg.protocolVersion;
597
598 // select a proper protocol version.
599 ProtocolVersion selectedVersion =
600 selectProtocolVersion(clientRequestedVersion);
601 if (selectedVersion == null ||
602 selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
603 fatalSE(Alerts.alert_handshake_failure,
604 "Client requested protocol " + clientRequestedVersion +
605 " not enabled or not supported");
606 }
607
608 handshakeHash.protocolDetermined(selectedVersion);
609 setVersion(selectedVersion);
610
611 m1.protocolVersion = protocolVersion;
612
613 //
614 // random ... save client and server values for later use
615 // in computing the master secret (from pre-master secret)
616 // and thence the other crypto keys.
617 //
618 // NOTE: this use of three inputs to generating _each_ set
619 // of ciphers slows things down, but it does increase the
620 // security since each connection in the session can hold
621 // its own authenticated (and strong) keys. One could make
622 // creation of a session a rare thing...
623 //
624 clnt_random = mesg.clnt_random;
625 svr_random = new RandomCookie(sslContext.getSecureRandom());
626 m1.svr_random = svr_random;
627
628 session = null; // forget about the current session
629 //
630 // Here we go down either of two paths: (a) the fast one, where
631 // the client's asked to rejoin an existing session, and the server
632 // permits this; (b) the other one, where a new session is created.
633 //
634 if (mesg.sessionId.length() != 0) {
635 // client is trying to resume a session, let's see...
636
637 SSLSessionImpl previous = ((SSLSessionContextImpl)sslContext
638 .engineGetServerSessionContext())
639 .get(mesg.sessionId.getId());
640 //
641 // Check if we can use the fast path, resuming a session. We
642 // can do so iff we have a valid record for that session, and
643 // the cipher suite for that session was on the list which the
644 // client requested, and if we're not forgetting any needed
645 // authentication on the part of the client.
646 //
647 if (previous != null) {
715 (mesg.getCipherSuites().contains(suite) == false)) {
716 resumingSession = false;
717 } else {
718 // everything looks ok, set the ciphersuite
719 // this should be done last when we are sure we
720 // will resume
721 setCipherSuite(suite);
722 }
723 }
724
725 if (resumingSession) {
726 session = previous;
727 if (debug != null &&
728 (Debug.isOn("handshake") || Debug.isOn("session"))) {
729 System.out.println("%% Resuming " + session);
730 }
731 }
732 }
733 } // else client did not try to resume
734
735 //
736 // If client hasn't specified a session we can resume, start a
737 // new one and choose its cipher suite and compression options.
738 // Unless new session creation is disabled for this connection!
739 //
740 if (session == null) {
741 if (!enableNewSession) {
742 throw new SSLException("Client did not resume a session");
743 }
744
745 requestedCurves = (EllipticCurvesExtension)
746 mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
747
748 // We only need to handle the "signature_algorithm" extension
749 // for full handshakes and TLS 1.2 or later.
750 if (protocolVersion.useTLS12PlusSpec()) {
751 SignatureAlgorithmsExtension signAlgs =
752 (SignatureAlgorithmsExtension)mesg.extensions.get(
753 ExtensionType.EXT_SIGNATURE_ALGORITHMS);
754 if (signAlgs != null) {
755 Collection<SignatureAndHashAlgorithm> peerSignAlgs =
|
541
542 // Use server preference order
543 for (String ap : localApl) {
544 if (protocols.contains(ap)) {
545 negotiatedValue = ap;
546 break;
547 }
548 }
549
550 if (negotiatedValue == null) {
551 fatalSE(Alerts.alert_no_application_protocol,
552 new SSLHandshakeException(
553 "No matching ALPN values"));
554 }
555 applicationProtocol = negotiatedValue;
556
557 } else {
558 applicationProtocol = "";
559 }
560
561 session = null; // forget about the current session
562 //
563 // Here we go down either of two paths: (a) the fast one, where
564 // the client's asked to rejoin an existing session, and the server
565 // permits this; (b) the other one, where a new session is created.
566 //
567 if (mesg.sessionId.length() != 0) {
568 // client is trying to resume a session, let's see...
569
570 SSLSessionImpl previous = ((SSLSessionContextImpl)sslContext
571 .engineGetServerSessionContext())
572 .get(mesg.sessionId.getId());
573 //
574 // Check if we can use the fast path, resuming a session. We
575 // can do so iff we have a valid record for that session, and
576 // the cipher suite for that session was on the list which the
577 // client requested, and if we're not forgetting any needed
578 // authentication on the part of the client.
579 //
580 if (previous != null) {
648 (mesg.getCipherSuites().contains(suite) == false)) {
649 resumingSession = false;
650 } else {
651 // everything looks ok, set the ciphersuite
652 // this should be done last when we are sure we
653 // will resume
654 setCipherSuite(suite);
655 }
656 }
657
658 if (resumingSession) {
659 session = previous;
660 if (debug != null &&
661 (Debug.isOn("handshake") || Debug.isOn("session"))) {
662 System.out.println("%% Resuming " + session);
663 }
664 }
665 }
666 } // else client did not try to resume
667
668 // cookie exchange
669 if (isDTLS && !resumingSession) {
670 HelloCookieManager hcMgr = sslContext.getHelloCookieManager();
671 if ((mesg.cookie == null) || (mesg.cookie.length == 0) ||
672 (!hcMgr.isValid(mesg))) {
673
674 //
675 // Perform cookie exchange for DTLS handshaking if no cookie
676 // or the cookie is invalid in the ClientHello message.
677 //
678 HelloVerifyRequest m0 = new HelloVerifyRequest(hcMgr, mesg);
679
680 if (debug != null && Debug.isOn("handshake")) {
681 m0.print(System.out);
682 }
683
684 m0.write(output);
685 handshakeState.update(m0, resumingSession);
686 output.flush();
687
688 return;
689 }
690 }
691
692 /*
693 * FIRST, construct the ServerHello using the options and priorities
694 * from the ClientHello. Update the (pending) cipher spec as we do
695 * so, and save the client's version to protect against rollback
696 * attacks.
697 *
698 * There are a bunch of minor tasks here, and one major one: deciding
699 * if the short or the full handshake sequence will be used.
700 */
701 ServerHello m1 = new ServerHello();
702
703 clientRequestedVersion = mesg.protocolVersion;
704
705 // select a proper protocol version.
706 ProtocolVersion selectedVersion =
707 selectProtocolVersion(clientRequestedVersion);
708 if (selectedVersion == null ||
709 selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
710 fatalSE(Alerts.alert_handshake_failure,
711 "Client requested protocol " + clientRequestedVersion +
712 " not enabled or not supported");
713 }
714
715 handshakeHash.protocolDetermined(selectedVersion);
716 setVersion(selectedVersion);
717
718 m1.protocolVersion = protocolVersion;
719
720 //
721 // random ... save client and server values for later use
722 // in computing the master secret (from pre-master secret)
723 // and thence the other crypto keys.
724 //
725 // NOTE: this use of three inputs to generating _each_ set
726 // of ciphers slows things down, but it does increase the
727 // security since each connection in the session can hold
728 // its own authenticated (and strong) keys. One could make
729 // creation of a session a rare thing...
730 //
731 clnt_random = mesg.clnt_random;
732 svr_random = new RandomCookie(sslContext.getSecureRandom());
733 m1.svr_random = svr_random;
734
735 //
736 // If client hasn't specified a session we can resume, start a
737 // new one and choose its cipher suite and compression options.
738 // Unless new session creation is disabled for this connection!
739 //
740 if (session == null) {
741 if (!enableNewSession) {
742 throw new SSLException("Client did not resume a session");
743 }
744
745 requestedCurves = (EllipticCurvesExtension)
746 mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
747
748 // We only need to handle the "signature_algorithm" extension
749 // for full handshakes and TLS 1.2 or later.
750 if (protocolVersion.useTLS12PlusSpec()) {
751 SignatureAlgorithmsExtension signAlgs =
752 (SignatureAlgorithmsExtension)mesg.extensions.get(
753 ExtensionType.EXT_SIGNATURE_ALGORITHMS);
754 if (signAlgs != null) {
755 Collection<SignatureAndHashAlgorithm> peerSignAlgs =
|