src/java.base/share/classes/sun/security/ssl/ServerHandshaker.java

Print this page
8167680 DTLS implementation bugs


 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 =