556 |
556 |
557 } else { |
557 } else { |
558 applicationProtocol = ""; |
558 applicationProtocol = ""; |
559 } |
559 } |
560 |
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) { |
|
581 resumingSession = previous.isRejoinable(); |
|
582 |
|
583 if (resumingSession) { |
|
584 ProtocolVersion oldVersion = previous.getProtocolVersion(); |
|
585 // cannot resume session with different version |
|
586 if (oldVersion != protocolVersion) { |
|
587 resumingSession = false; |
|
588 } |
|
589 } |
|
590 |
|
591 // cannot resume session with different server name indication |
|
592 if (resumingSession) { |
|
593 List<SNIServerName> oldServerNames = |
|
594 previous.getRequestedServerNames(); |
|
595 if (clientHelloSNIExt != null) { |
|
596 if (!clientHelloSNIExt.isIdentical(oldServerNames)) { |
|
597 resumingSession = false; |
|
598 } |
|
599 } else if (!oldServerNames.isEmpty()) { |
|
600 resumingSession = false; |
|
601 } |
|
602 |
|
603 if (!resumingSession && |
|
604 debug != null && Debug.isOn("handshake")) { |
|
605 System.out.println( |
|
606 "The requested server name indication " + |
|
607 "is not identical to the previous one"); |
|
608 } |
|
609 } |
|
610 |
|
611 if (resumingSession && |
|
612 (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED)) { |
|
613 try { |
|
614 previous.getPeerPrincipal(); |
|
615 } catch (SSLPeerUnverifiedException e) { |
|
616 resumingSession = false; |
|
617 } |
|
618 } |
|
619 |
|
620 // validate subject identity |
|
621 if (resumingSession) { |
|
622 CipherSuite suite = previous.getSuite(); |
|
623 ClientKeyExchangeService p = |
|
624 ClientKeyExchangeService.find(suite.keyExchange.name); |
|
625 if (p != null) { |
|
626 Principal localPrincipal = previous.getLocalPrincipal(); |
|
627 |
|
628 if (p.isRelated( |
|
629 false, getAccSE(), localPrincipal)) { |
|
630 if (debug != null && Debug.isOn("session")) |
|
631 System.out.println("Subject can" + |
|
632 " provide creds for princ"); |
|
633 } else { |
|
634 resumingSession = false; |
|
635 if (debug != null && Debug.isOn("session")) |
|
636 System.out.println("Subject cannot" + |
|
637 " provide creds for princ"); |
|
638 } |
|
639 } |
|
640 } |
|
641 |
|
642 if (resumingSession) { |
|
643 CipherSuite suite = previous.getSuite(); |
|
644 // verify that the ciphersuite from the cached session |
|
645 // is in the list of client requested ciphersuites and |
|
646 // we have it enabled |
|
647 if ((isNegotiable(suite) == false) || |
|
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 |
561 // cookie exchange |
668 // cookie exchange |
562 if (isDTLS) { |
669 if (isDTLS && !resumingSession) { |
563 HelloCookieManager hcMgr = sslContext.getHelloCookieManager(); |
670 HelloCookieManager hcMgr = sslContext.getHelloCookieManager(); |
564 if ((mesg.cookie == null) || (mesg.cookie.length == 0) || |
671 if ((mesg.cookie == null) || (mesg.cookie.length == 0) || |
565 (!hcMgr.isValid(mesg))) { |
672 (!hcMgr.isValid(mesg))) { |
566 |
673 |
567 // |
674 // |
622 // creation of a session a rare thing... |
729 // creation of a session a rare thing... |
623 // |
730 // |
624 clnt_random = mesg.clnt_random; |
731 clnt_random = mesg.clnt_random; |
625 svr_random = new RandomCookie(sslContext.getSecureRandom()); |
732 svr_random = new RandomCookie(sslContext.getSecureRandom()); |
626 m1.svr_random = svr_random; |
733 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) { |
|
648 resumingSession = previous.isRejoinable(); |
|
649 |
|
650 if (resumingSession) { |
|
651 ProtocolVersion oldVersion = previous.getProtocolVersion(); |
|
652 // cannot resume session with different version |
|
653 if (oldVersion != protocolVersion) { |
|
654 resumingSession = false; |
|
655 } |
|
656 } |
|
657 |
|
658 // cannot resume session with different server name indication |
|
659 if (resumingSession) { |
|
660 List<SNIServerName> oldServerNames = |
|
661 previous.getRequestedServerNames(); |
|
662 if (clientHelloSNIExt != null) { |
|
663 if (!clientHelloSNIExt.isIdentical(oldServerNames)) { |
|
664 resumingSession = false; |
|
665 } |
|
666 } else if (!oldServerNames.isEmpty()) { |
|
667 resumingSession = false; |
|
668 } |
|
669 |
|
670 if (!resumingSession && |
|
671 debug != null && Debug.isOn("handshake")) { |
|
672 System.out.println( |
|
673 "The requested server name indication " + |
|
674 "is not identical to the previous one"); |
|
675 } |
|
676 } |
|
677 |
|
678 if (resumingSession && |
|
679 (doClientAuth == ClientAuthType.CLIENT_AUTH_REQUIRED)) { |
|
680 try { |
|
681 previous.getPeerPrincipal(); |
|
682 } catch (SSLPeerUnverifiedException e) { |
|
683 resumingSession = false; |
|
684 } |
|
685 } |
|
686 |
|
687 // validate subject identity |
|
688 if (resumingSession) { |
|
689 CipherSuite suite = previous.getSuite(); |
|
690 ClientKeyExchangeService p = |
|
691 ClientKeyExchangeService.find(suite.keyExchange.name); |
|
692 if (p != null) { |
|
693 Principal localPrincipal = previous.getLocalPrincipal(); |
|
694 |
|
695 if (p.isRelated( |
|
696 false, getAccSE(), localPrincipal)) { |
|
697 if (debug != null && Debug.isOn("session")) |
|
698 System.out.println("Subject can" + |
|
699 " provide creds for princ"); |
|
700 } else { |
|
701 resumingSession = false; |
|
702 if (debug != null && Debug.isOn("session")) |
|
703 System.out.println("Subject cannot" + |
|
704 " provide creds for princ"); |
|
705 } |
|
706 } |
|
707 } |
|
708 |
|
709 if (resumingSession) { |
|
710 CipherSuite suite = previous.getSuite(); |
|
711 // verify that the ciphersuite from the cached session |
|
712 // is in the list of client requested ciphersuites and |
|
713 // we have it enabled |
|
714 if ((isNegotiable(suite) == false) || |
|
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 |
734 |
735 // |
735 // |
736 // If client hasn't specified a session we can resume, start a |
736 // If client hasn't specified a session we can resume, start a |
737 // new one and choose its cipher suite and compression options. |
737 // new one and choose its cipher suite and compression options. |
738 // Unless new session creation is disabled for this connection! |
738 // Unless new session creation is disabled for this connection! |