Search in sources :

Example 1 with CipherSuite

use of sun.security.ssl.CipherSuite in project jdk8u_jdk by JetBrains.

the class Handshaker method getActiveCipherSuites.

/**
     * Get the active cipher suites.
     *
     * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
     * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
     * negotiate these cipher suites in TLS 1.1 or later mode.
     *
     * Therefore, when the active protocols only include TLS 1.1 or later,
     * the client cannot request to negotiate those obsoleted cipher
     * suites.  That is, the obsoleted suites should not be included in the
     * client hello. So we need to create a subset of the enabled cipher
     * suites, the active cipher suites, which does not contain obsoleted
     * cipher suites of the minimum active protocol.
     *
     * Return empty list instead of null if no active cipher suites.
     */
CipherSuiteList getActiveCipherSuites() {
    if (activeCipherSuites == null) {
        if (activeProtocols == null) {
            activeProtocols = getActiveProtocols();
        }
        ArrayList<CipherSuite> suites = new ArrayList<>();
        if (!(activeProtocols.collection().isEmpty()) && activeProtocols.min.v != ProtocolVersion.NONE.v) {
            boolean checkedCurves = false;
            boolean hasCurves = false;
            for (CipherSuite suite : enabledCipherSuites.collection()) {
                if (suite.obsoleted > activeProtocols.min.v && suite.supported <= activeProtocols.max.v) {
                    if (algorithmConstraints.permits(EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
                        boolean available = true;
                        if (suite.keyExchange.isEC) {
                            if (!checkedCurves) {
                                hasCurves = SupportedEllipticCurvesExtension.hasActiveCurves(algorithmConstraints);
                                checkedCurves = true;
                                if (!hasCurves && debug != null && Debug.isOn("verbose")) {
                                    System.out.println("No available elliptic curves");
                                }
                            }
                            available = hasCurves;
                            if (!available && debug != null && Debug.isOn("verbose")) {
                                System.out.println("No active elliptic curves, ignore " + suite);
                            }
                        }
                        if (available) {
                            suites.add(suite);
                        }
                    }
                } else if (debug != null && Debug.isOn("verbose")) {
                    if (suite.obsoleted <= activeProtocols.min.v) {
                        System.out.println("Ignoring obsoleted cipher suite: " + suite);
                    } else {
                        System.out.println("Ignoring unsupported cipher suite: " + suite);
                    }
                }
            }
        }
        activeCipherSuites = new CipherSuiteList(suites);
    }
    return activeCipherSuites;
}
Also used : CipherSuite(sun.security.ssl.CipherSuite)

Example 2 with CipherSuite

use of sun.security.ssl.CipherSuite in project jdk8u_jdk by JetBrains.

the class ServerHandshaker method clientHello.

/*
     * ClientHello presents the server with a bunch of options, to which the
     * server replies with a ServerHello listing the ones which this session
     * will use.  If needed, it also writes its Certificate plus in some cases
     * a ServerKeyExchange message.  It may also write a CertificateRequest,
     * to elicit a client certificate.
     *
     * All these messages are terminated by a ServerHelloDone message.  In
     * most cases, all this can be sent in a single Record.
     */
private void clientHello(ClientHello mesg) throws IOException {
    if (debug != null && Debug.isOn("handshake")) {
        mesg.print(System.out);
    }
    // This will not have any impact on server initiated renegotiation.
    if (rejectClientInitiatedRenego && !isInitialHandshake && state != HandshakeMessage.ht_hello_request) {
        fatalSE(Alerts.alert_handshake_failure, "Client initiated renegotiation is not allowed");
    }
    // check the server name indication if required
    ServerNameExtension clientHelloSNIExt = (ServerNameExtension) mesg.extensions.get(ExtensionType.EXT_SERVER_NAME);
    if (!sniMatchers.isEmpty()) {
        // we do not reject client without SNI extension
        if (clientHelloSNIExt != null && !clientHelloSNIExt.isMatched(sniMatchers)) {
            fatalSE(Alerts.alert_unrecognized_name, "Unrecognized server name indication");
        }
    }
    // Does the message include security renegotiation indication?
    boolean renegotiationIndicated = false;
    // check the TLS_EMPTY_RENEGOTIATION_INFO_SCSV
    CipherSuiteList cipherSuites = mesg.getCipherSuites();
    if (cipherSuites.contains(CipherSuite.C_SCSV)) {
        renegotiationIndicated = true;
        if (isInitialHandshake) {
            secureRenegotiation = true;
        } else {
            // abort the handshake with a fatal handshake_failure alert
            if (secureRenegotiation) {
                fatalSE(Alerts.alert_handshake_failure, "The SCSV is present in a secure renegotiation");
            } else {
                fatalSE(Alerts.alert_handshake_failure, "The SCSV is present in a insecure renegotiation");
            }
        }
    }
    // check the "renegotiation_info" extension
    RenegotiationInfoExtension clientHelloRI = (RenegotiationInfoExtension) mesg.extensions.get(ExtensionType.EXT_RENEGOTIATION_INFO);
    if (clientHelloRI != null) {
        renegotiationIndicated = true;
        if (isInitialHandshake) {
            // verify the length of the "renegotiated_connection" field
            if (!clientHelloRI.isEmpty()) {
                // abort the handshake with a fatal handshake_failure alert
                fatalSE(Alerts.alert_handshake_failure, "The renegotiation_info field is not empty");
            }
            secureRenegotiation = true;
        } else {
            if (!secureRenegotiation) {
                // unexpected RI extension for insecure renegotiation,
                // abort the handshake with a fatal handshake_failure alert
                fatalSE(Alerts.alert_handshake_failure, "The renegotiation_info is present in a insecure " + "renegotiation");
            }
            // verify the client_verify_data value
            if (!MessageDigest.isEqual(clientVerifyData, clientHelloRI.getRenegotiatedConnection())) {
                fatalSE(Alerts.alert_handshake_failure, "Incorrect verify data in ClientHello " + "renegotiation_info message");
            }
        }
    } else if (!isInitialHandshake && secureRenegotiation) {
        // if the connection's "secure_renegotiation" flag is set to TRUE
        // and the "renegotiation_info" extension is not present, abort
        // the handshake.
        fatalSE(Alerts.alert_handshake_failure, "Inconsistent secure renegotiation indication");
    }
    // handshake is insecure.
    if (!renegotiationIndicated || !secureRenegotiation) {
        if (isInitialHandshake) {
            if (!allowLegacyHelloMessages) {
                // abort the handshake with a fatal handshake_failure alert
                fatalSE(Alerts.alert_handshake_failure, "Failed to negotiate the use of secure renegotiation");
            }
            // continue with legacy ClientHello
            if (debug != null && Debug.isOn("handshake")) {
                System.out.println("Warning: No renegotiation " + "indication in ClientHello, allow legacy ClientHello");
            }
        } else if (!allowUnsafeRenegotiation) {
            // abort the handshake
            if (activeProtocolVersion.v >= ProtocolVersion.TLS10.v) {
                // respond with a no_renegotiation warning
                warningSE(Alerts.alert_no_renegotiation);
                // invalidate the handshake so that the caller can
                // dispose this object.
                invalidated = true;
                // in the handshake input stream.
                if (input.available() > 0) {
                    fatalSE(Alerts.alert_unexpected_message, "ClientHello followed by an unexpected  " + "handshake message");
                }
                return;
            } else {
                // For SSLv3, send the handshake_failure fatal error.
                // Note that SSLv3 does not define a no_renegotiation
                // alert like TLSv1. However we cannot ignore the message
                // simply, otherwise the other side was waiting for a
                // response that would never come.
                fatalSE(Alerts.alert_handshake_failure, "Renegotiation is not allowed");
            }
        } else {
            // continue with unsafe renegotiation.
            if (debug != null && Debug.isOn("handshake")) {
                System.out.println("Warning: continue with insecure renegotiation");
            }
        }
    }
    /*
         * Always make sure this entire record has been digested before we
         * start emitting output, to ensure correct digesting order.
         */
    input.digestNow();
    /*
         * FIRST, construct the ServerHello using the options and priorities
         * from the ClientHello.  Update the (pending) cipher spec as we do
         * so, and save the client's version to protect against rollback
         * attacks.
         *
         * There are a bunch of minor tasks here, and one major one: deciding
         * if the short or the full handshake sequence will be used.
         */
    ServerHello m1 = new ServerHello();
    clientRequestedVersion = mesg.protocolVersion;
    // select a proper protocol version.
    ProtocolVersion selectedVersion = selectProtocolVersion(clientRequestedVersion);
    if (selectedVersion == null || selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
        fatalSE(Alerts.alert_handshake_failure, "Client requested protocol " + clientRequestedVersion + " not enabled or not supported");
    }
    handshakeHash.protocolDetermined(selectedVersion);
    setVersion(selectedVersion);
    m1.protocolVersion = protocolVersion;
    //
    // random ... save client and server values for later use
    // in computing the master secret (from pre-master secret)
    // and thence the other crypto keys.
    //
    // NOTE:  this use of three inputs to generating _each_ set
    // of ciphers slows things down, but it does increase the
    // security since each connection in the session can hold
    // its own authenticated (and strong) keys.  One could make
    // creation of a session a rare thing...
    //
    clnt_random = mesg.clnt_random;
    svr_random = new RandomCookie(sslContext.getSecureRandom());
    m1.svr_random = svr_random;
    // forget about the current session
    session = null;
    //
    if (mesg.sessionId.length() != 0) {
        // client is trying to resume a session, let's see...
        SSLSessionImpl previous = ((SSLSessionContextImpl) sslContext.engineGetServerSessionContext()).get(mesg.sessionId.getId());
        //
        if (previous != null) {
            resumingSession = previous.isRejoinable();
            if (resumingSession) {
                ProtocolVersion oldVersion = previous.getProtocolVersion();
                // cannot resume session with different version
                if (oldVersion != protocolVersion) {
                    resumingSession = false;
                }
            }
            // cannot resume session with different server name indication
            if (resumingSession) {
                List<SNIServerName> oldServerNames = previous.getRequestedServerNames();
                if (clientHelloSNIExt != null) {
                    if (!clientHelloSNIExt.isIdentical(oldServerNames)) {
                        resumingSession = false;
                    }
                } else if (!oldServerNames.isEmpty()) {
                    resumingSession = false;
                }
                if (!resumingSession && debug != null && Debug.isOn("handshake")) {
                    System.out.println("The requested server name indication " + "is not identical to the previous one");
                }
            }
            if (resumingSession && (doClientAuth == SSLEngineImpl.clauth_required)) {
                try {
                    previous.getPeerPrincipal();
                } catch (SSLPeerUnverifiedException e) {
                    resumingSession = false;
                }
            }
            // validate subject identity
            if (resumingSession) {
                CipherSuite suite = previous.getSuite();
                if (suite.keyExchange == K_KRB5 || suite.keyExchange == K_KRB5_EXPORT) {
                    Principal localPrincipal = previous.getLocalPrincipal();
                    Subject subject = null;
                    try {
                        subject = AccessController.doPrivileged(new PrivilegedExceptionAction<Subject>() {

                            @Override
                            public Subject run() throws Exception {
                                return Krb5Helper.getServerSubject(getAccSE());
                            }
                        });
                    } catch (PrivilegedActionException e) {
                        subject = null;
                        if (debug != null && Debug.isOn("session")) {
                            System.out.println("Attempt to obtain" + " subject failed!");
                        }
                    }
                    if (subject != null) {
                        // Eliminate dependency on KerberosPrincipal
                        if (Krb5Helper.isRelated(subject, localPrincipal)) {
                            if (debug != null && Debug.isOn("session"))
                                System.out.println("Subject can" + " provide creds for princ");
                        } else {
                            resumingSession = false;
                            if (debug != null && Debug.isOn("session"))
                                System.out.println("Subject cannot" + " provide creds for princ");
                        }
                    } else {
                        resumingSession = false;
                        if (debug != null && Debug.isOn("session"))
                            System.out.println("Kerberos credentials are" + " not present in the current Subject;" + " check if " + " javax.security.auth.useSubjectAsCreds" + " system property has been set to false");
                    }
                }
            }
            if (resumingSession) {
                CipherSuite suite = previous.getSuite();
                // we have it enabled
                if ((isNegotiable(suite) == false) || (mesg.getCipherSuites().contains(suite) == false)) {
                    resumingSession = false;
                } else {
                    // everything looks ok, set the ciphersuite
                    // this should be done last when we are sure we
                    // will resume
                    setCipherSuite(suite);
                }
            }
            if (resumingSession) {
                session = previous;
                if (debug != null && (Debug.isOn("handshake") || Debug.isOn("session"))) {
                    System.out.println("%% Resuming " + session);
                }
            }
        }
    }
    //
    if (session == null) {
        if (!enableNewSession) {
            throw new SSLException("Client did not resume a session");
        }
        requestedCurves = (SupportedEllipticCurvesExtension) mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
        // for full handshakes and TLS 1.2 or later.
        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
            SignatureAlgorithmsExtension signAlgs = (SignatureAlgorithmsExtension) mesg.extensions.get(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
            if (signAlgs != null) {
                Collection<SignatureAndHashAlgorithm> peerSignAlgs = signAlgs.getSignAlgorithms();
                if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
                    throw new SSLHandshakeException("No peer supported signature algorithms");
                }
                Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs = SignatureAndHashAlgorithm.getSupportedAlgorithms(algorithmConstraints, peerSignAlgs);
                if (supportedPeerSignAlgs.isEmpty()) {
                    throw new SSLHandshakeException("No signature and hash algorithm in common");
                }
                setPeerSupportedSignAlgs(supportedPeerSignAlgs);
            }
        // else, need to use peer implicit supported signature algs
        }
        session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL, getLocalSupportedSignAlgs(), sslContext.getSecureRandom(), getHostAddressSE(), getPortSE());
        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
            if (peerSupportedSignAlgs != null) {
                session.setPeerSupportedSignatureAlgorithms(peerSupportedSignAlgs);
            }
        // else, we will set the implicit peer supported signature
        // algorithms in chooseCipherSuite()
        }
        // set the server name indication in the session
        List<SNIServerName> clientHelloSNI = Collections.<SNIServerName>emptyList();
        if (clientHelloSNIExt != null) {
            clientHelloSNI = clientHelloSNIExt.getServerNames();
        }
        session.setRequestedServerNames(clientHelloSNI);
        // set the handshake session
        setHandshakeSessionSE(session);
        // choose cipher suite and corresponding private key
        chooseCipherSuite(mesg);
        session.setSuite(cipherSuite);
        session.setLocalPrivateKey(privateKey);
    // chooseCompression(mesg);
    } else {
        // set the handshake session
        setHandshakeSessionSE(session);
    }
    if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
        handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
    }
    m1.cipherSuite = cipherSuite;
    m1.sessionId = session.getSessionId();
    m1.compression_method = session.getCompression();
    if (secureRenegotiation) {
        // For ServerHellos that are initial handshakes, then the
        // "renegotiated_connection" field in "renegotiation_info"
        // extension is of zero length.
        //
        // For ServerHellos that are renegotiating, this field contains
        // the concatenation of client_verify_data and server_verify_data.
        //
        // Note that for initial handshakes, both the clientVerifyData
        // variable and serverVerifyData variable are of zero length.
        HelloExtension serverHelloRI = new RenegotiationInfoExtension(clientVerifyData, serverVerifyData);
        m1.extensions.add(serverHelloRI);
    }
    if (!sniMatchers.isEmpty() && clientHelloSNIExt != null) {
        // server_name extension in the server hello.
        if (!resumingSession) {
            ServerNameExtension serverHelloSNI = new ServerNameExtension();
            m1.extensions.add(serverHelloSNI);
        }
    }
    if (debug != null && Debug.isOn("handshake")) {
        m1.print(System.out);
        System.out.println("Cipher suite:  " + session.getSuite());
    }
    m1.write(output);
    //
    if (resumingSession) {
        calculateConnectionKeys(session.getMasterSecret());
        sendChangeCipherAndFinish(false);
        return;
    }
    /*
         * SECOND, write the server Certificate(s) if we need to.
         *
         * NOTE:  while an "anonymous RSA" mode is explicitly allowed by
         * the protocol, we can't support it since all of the SSL flavors
         * defined in the protocol spec are explicitly stated to require
         * using RSA certificates.
         */
    if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
    // Server certificates are omitted for Kerberos ciphers
    } else if ((keyExchange != K_DH_ANON) && (keyExchange != K_ECDH_ANON)) {
        if (certs == null) {
            throw new RuntimeException("no certificates");
        }
        CertificateMsg m2 = new CertificateMsg(certs);
        /*
             * Set local certs in the SSLSession, output
             * debug info, and then actually write to the client.
             */
        session.setLocalCertificates(certs);
        if (debug != null && Debug.isOn("handshake")) {
            m2.print(System.out);
        }
        m2.write(output);
    // XXX has some side effects with OS TCP buffering,
    // leave it out for now
    // let client verify chain in the meantime...
    // output.flush();
    } else {
        if (certs != null) {
            throw new RuntimeException("anonymous keyexchange with certs");
        }
    }
    /*
         * THIRD, the ServerKeyExchange message ... iff it's needed.
         *
         * It's usually needed unless there's an encryption-capable
         * RSA cert, or a D-H cert.  The notable exception is that
         * exportable ciphers used with big RSA keys need to downgrade
         * to use short RSA keys, even when the key/cert encrypts OK.
         */
    ServerKeyExchange m3;
    switch(keyExchange) {
        case K_RSA:
        case K_KRB5:
        case K_KRB5_EXPORT:
            // no server key exchange for RSA or KRB5 ciphersuites
            m3 = null;
            break;
        case K_RSA_EXPORT:
            if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
                try {
                    m3 = new RSA_ServerKeyExchange(tempPublicKey, privateKey, clnt_random, svr_random, sslContext.getSecureRandom());
                    privateKey = tempPrivateKey;
                } catch (GeneralSecurityException e) {
                    throwSSLException("Error generating RSA server key exchange", e);
                    // make compiler happy
                    m3 = null;
                }
            } else {
                // RSA_EXPORT with short key, don't need ServerKeyExchange
                m3 = null;
            }
            break;
        case K_DHE_RSA:
        case K_DHE_DSS:
            try {
                m3 = new DH_ServerKeyExchange(dh, privateKey, clnt_random.random_bytes, svr_random.random_bytes, sslContext.getSecureRandom(), preferableSignatureAlgorithm, protocolVersion);
            } catch (GeneralSecurityException e) {
                throwSSLException("Error generating DH server key exchange", e);
                // make compiler happy
                m3 = null;
            }
            break;
        case K_DH_ANON:
            m3 = new DH_ServerKeyExchange(dh, protocolVersion);
            break;
        case K_ECDHE_RSA:
        case K_ECDHE_ECDSA:
        case K_ECDH_ANON:
            try {
                m3 = new ECDH_ServerKeyExchange(ecdh, privateKey, clnt_random.random_bytes, svr_random.random_bytes, sslContext.getSecureRandom(), preferableSignatureAlgorithm, protocolVersion);
            } catch (GeneralSecurityException e) {
                throwSSLException("Error generating ECDH server key exchange", e);
                // make compiler happy
                m3 = null;
            }
            break;
        case K_ECDH_RSA:
        case K_ECDH_ECDSA:
            // ServerKeyExchange not used for fixed ECDH
            m3 = null;
            break;
        default:
            throw new RuntimeException("internal error: " + keyExchange);
    }
    if (m3 != null) {
        if (debug != null && Debug.isOn("handshake")) {
            m3.print(System.out);
        }
        m3.write(output);
    }
    // CertificateRequest is omitted for Kerberos ciphers
    if (doClientAuth != SSLEngineImpl.clauth_none && keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON && keyExchange != K_KRB5 && keyExchange != K_KRB5_EXPORT) {
        CertificateRequest m4;
        X509Certificate[] caCerts;
        Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
        if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
            // We currently use all local upported signature and hash
            // algorithms. However, to minimize the computation cost
            // of requested hash algorithms, we may use a restricted
            // set of signature algorithms in the future.
            localSignAlgs = getLocalSupportedSignAlgs();
            if (localSignAlgs.isEmpty()) {
                throw new SSLHandshakeException("No supported signature algorithm");
            }
            Set<String> localHashAlgs = SignatureAndHashAlgorithm.getHashAlgorithmNames(localSignAlgs);
            if (localHashAlgs.isEmpty()) {
                throw new SSLHandshakeException("No supported signature algorithm");
            }
        }
        caCerts = sslContext.getX509TrustManager().getAcceptedIssuers();
        m4 = new CertificateRequest(caCerts, keyExchange, localSignAlgs, protocolVersion);
        if (debug != null && Debug.isOn("handshake")) {
            m4.print(System.out);
        }
        m4.write(output);
    }
    /*
         * FIFTH, say ServerHelloDone.
         */
    ServerHelloDone m5 = new ServerHelloDone();
    if (debug != null && Debug.isOn("handshake")) {
        m5.print(System.out);
    }
    m5.write(output);
    /*
         * Flush any buffered messages so the client will see them.
         * Ideally, all the messages above go in a single network level
         * message to the client.  Without big Certificate chains, it's
         * going to be the common case.
         */
    output.flush();
}
Also used : CipherSuite(sun.security.ssl.CipherSuite) SignatureAndHashAlgorithm(sun.security.ssl.SignatureAndHashAlgorithm) Subject(javax.security.auth.Subject)

Example 3 with CipherSuite

use of sun.security.ssl.CipherSuite in project jdk8u_jdk by JetBrains.

the class ServerHandshaker method chooseCipherSuite.

/*
     * Choose cipher suite from among those supported by client. Sets
     * the cipherSuite and keyExchange variables.
     */
private void chooseCipherSuite(ClientHello mesg) throws IOException {
    CipherSuiteList prefered;
    CipherSuiteList proposed;
    if (preferLocalCipherSuites) {
        prefered = getActiveCipherSuites();
        proposed = mesg.getCipherSuites();
    } else {
        prefered = mesg.getCipherSuites();
        proposed = getActiveCipherSuites();
    }
    List<CipherSuite> legacySuites = new ArrayList<>();
    for (CipherSuite suite : prefered.collection()) {
        if (isNegotiable(proposed, suite) == false) {
            continue;
        }
        if (doClientAuth == SSLEngineImpl.clauth_required) {
            if ((suite.keyExchange == K_DH_ANON) || (suite.keyExchange == K_ECDH_ANON)) {
                continue;
            }
        }
        if (!legacyAlgorithmConstraints.permits(null, suite.name, null)) {
            legacySuites.add(suite);
            continue;
        }
        if (trySetCipherSuite(suite) == false) {
            continue;
        }
        if (debug != null && Debug.isOn("handshake")) {
            System.out.println("Standard ciphersuite chosen: " + suite);
        }
        return;
    }
    for (CipherSuite suite : legacySuites) {
        if (trySetCipherSuite(suite)) {
            if (debug != null && Debug.isOn("handshake")) {
                System.out.println("Legacy ciphersuite chosen: " + suite);
            }
            return;
        }
    }
    fatalSE(Alerts.alert_handshake_failure, "no cipher suites in common");
}
Also used : CipherSuite(sun.security.ssl.CipherSuite)

Example 4 with CipherSuite

use of sun.security.ssl.CipherSuite in project Bytecoder by mirkosertic.

the class Handshaker method getActiveProtocols.

/*
     * Get the active protocol versions.
     *
     * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
     * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
     * negotiate these cipher suites in TLS 1.1 or later mode.
     *
     * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
     * only enabled cipher suite, the client cannot request TLS 1.1 or
     * later, even though TLS 1.1 or later is enabled.  We need to create a
     * subset of the enabled protocols, called the active protocols, which
     * contains protocols appropriate to the list of enabled Ciphersuites.
     *
     * Return empty list instead of null if no active protocol versions.
     */
ProtocolList getActiveProtocols() {
    if (activeProtocols == null) {
        boolean enabledSSL20Hello = false;
        boolean checkedCurves = false;
        boolean hasCurves = false;
        ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
        for (ProtocolVersion protocol : enabledProtocols.collection()) {
            // Need not to check the SSL20Hello protocol.
            if (protocol.v == ProtocolVersion.SSL20Hello.v) {
                enabledSSL20Hello = true;
                continue;
            }
            if (!algorithmConstraints.permits(EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), protocol.name, null)) {
                if (debug != null && Debug.isOn("verbose")) {
                    System.out.println("Ignoring disabled protocol: " + protocol);
                }
                continue;
            }
            boolean found = false;
            Map<NamedGroupType, Boolean> cachedStatus = new EnumMap<>(NamedGroupType.class);
            for (CipherSuite suite : enabledCipherSuites.collection()) {
                if (suite.isAvailable() && (!protocol.obsoletes(suite)) && protocol.supports(suite)) {
                    if (isActivatable(suite, cachedStatus)) {
                        protocols.add(protocol);
                        found = true;
                        break;
                    }
                } else if (debug != null && Debug.isOn("verbose")) {
                    System.out.println("Ignoring unsupported cipher suite: " + suite + " for " + protocol);
                }
            }
            if (!found && (debug != null) && Debug.isOn("handshake")) {
                System.out.println("No available cipher suite for " + protocol);
            }
        }
        if (!protocols.isEmpty() && enabledSSL20Hello) {
            protocols.add(ProtocolVersion.SSL20Hello);
        }
        activeProtocols = new ProtocolList(protocols);
    }
    return activeProtocols;
}
Also used : NamedGroupType(sun.security.ssl.NamedGroupType) CipherSuite(sun.security.ssl.CipherSuite)

Example 5 with CipherSuite

use of sun.security.ssl.CipherSuite in project jdk8u_jdk by JetBrains.

the class Handshaker method getActiveProtocols.

/*
     * Get the active protocol versions.
     *
     * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
     * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
     * negotiate these cipher suites in TLS 1.1 or later mode.
     *
     * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
     * only enabled cipher suite, the client cannot request TLS 1.1 or
     * later, even though TLS 1.1 or later is enabled.  We need to create a
     * subset of the enabled protocols, called the active protocols, which
     * contains protocols appropriate to the list of enabled Ciphersuites.
     *
     * Return empty list instead of null if no active protocol versions.
     */
ProtocolList getActiveProtocols() {
    if (activeProtocols == null) {
        boolean enabledSSL20Hello = false;
        boolean checkedCurves = false;
        boolean hasCurves = false;
        ArrayList<ProtocolVersion> protocols = new ArrayList<>(4);
        for (ProtocolVersion protocol : enabledProtocols.collection()) {
            // Need not to check the SSL20Hello protocol.
            if (protocol.v == ProtocolVersion.SSL20Hello.v) {
                enabledSSL20Hello = true;
                continue;
            }
            if (!algorithmConstraints.permits(EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), protocol.name, null)) {
                if (debug != null && Debug.isOn("verbose")) {
                    System.out.println("Ignoring disabled protocol: " + protocol);
                }
                continue;
            }
            boolean found = false;
            for (CipherSuite suite : enabledCipherSuites.collection()) {
                if (suite.isAvailable() && suite.obsoleted > protocol.v && suite.supported <= protocol.v) {
                    if (algorithmConstraints.permits(EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
                        boolean available = true;
                        if (suite.keyExchange.isEC) {
                            if (!checkedCurves) {
                                hasCurves = SupportedEllipticCurvesExtension.hasActiveCurves(algorithmConstraints);
                                checkedCurves = true;
                                if (!hasCurves && debug != null && Debug.isOn("verbose")) {
                                    System.out.println("No activated elliptic curves");
                                }
                            }
                            available = hasCurves;
                            if (!available && debug != null && Debug.isOn("verbose")) {
                                System.out.println("No active elliptic curves, ignore " + suite + " for " + protocol);
                            }
                        }
                        if (available) {
                            protocols.add(protocol);
                            found = true;
                            break;
                        }
                    } else if (debug != null && Debug.isOn("verbose")) {
                        System.out.println("Ignoring disabled cipher suite: " + suite + " for " + protocol);
                    }
                } else if (debug != null && Debug.isOn("verbose")) {
                    System.out.println("Ignoring unsupported cipher suite: " + suite + " for " + protocol);
                }
            }
            if (!found && (debug != null) && Debug.isOn("handshake")) {
                System.out.println("No available cipher suite for " + protocol);
            }
        }
        if (!protocols.isEmpty() && enabledSSL20Hello) {
            protocols.add(ProtocolVersion.SSL20Hello);
        }
        activeProtocols = new ProtocolList(protocols);
    }
    return activeProtocols;
}
Also used : CipherSuite(sun.security.ssl.CipherSuite)

Aggregations

CipherSuite (sun.security.ssl.CipherSuite)8 NamedGroupType (sun.security.ssl.NamedGroupType)2 SignatureAndHashAlgorithm (sun.security.ssl.SignatureAndHashAlgorithm)2 Subject (javax.security.auth.Subject)1