Search in sources :

Example 6 with CipherSuite

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

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 == ClientAuthType.CLIENT_AUTH_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 7 with CipherSuite

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

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 && !serverHelloRequested) {
        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.useTLS10PlusSpec()) {
                // 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");
            }
        }
    }
    // check the "max_fragment_length" extension
    MaxFragmentLengthExtension maxFragLenExt = (MaxFragmentLengthExtension) mesg.extensions.get(ExtensionType.EXT_MAX_FRAGMENT_LENGTH);
    if ((maxFragLenExt != null) && (maximumPacketSize != 0)) {
        // Not yet consider the impact of IV/MAC/padding.
        int estimatedMaxFragSize = maximumPacketSize;
        if (isDTLS) {
            estimatedMaxFragSize -= DTLSRecord.headerSize;
        } else {
            estimatedMaxFragSize -= SSLRecord.headerSize;
        }
        if (maxFragLenExt.getMaxFragLen() > estimatedMaxFragSize) {
            // For better interoperability, abort the maximum fragment
            // length negotiation, rather than terminate the connection
            // with a fatal alert.
            maxFragLenExt = null;
        // fatalSE(Alerts.alert_illegal_parameter,
        // "Not an allowed max_fragment_length value");
        }
    }
    // check the ALPN extension
    ALPNExtension clientHelloALPN = (ALPNExtension) mesg.extensions.get(ExtensionType.EXT_ALPN);
    // Use the application protocol callback when provided.
    // Otherwise use the local list of application protocols.
    boolean hasAPCallback = ((engine != null && appProtocolSelectorSSLEngine != null) || (conn != null && appProtocolSelectorSSLSocket != null));
    if (!hasAPCallback) {
        if ((clientHelloALPN != null) && (localApl.length > 0)) {
            // Intersect the requested and the locally supported,
            // and save for later.
            String negotiatedValue = null;
            List<String> protocols = clientHelloALPN.getPeerAPs();
            // Use server preference order
            for (String ap : localApl) {
                if (protocols.contains(ap)) {
                    negotiatedValue = ap;
                    break;
                }
            }
            if (negotiatedValue == null) {
                fatalSE(Alerts.alert_no_application_protocol, new SSLHandshakeException("No matching ALPN values"));
            }
            applicationProtocol = negotiatedValue;
        } else {
            applicationProtocol = "";
        }
    }
    // Otherwise, applicationProtocol will be set by the callback.
    // 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 == ClientAuthType.CLIENT_AUTH_REQUIRED)) {
                try {
                    previous.getPeerPrincipal();
                } catch (SSLPeerUnverifiedException e) {
                    resumingSession = false;
                }
            }
            // validate subject identity
            if (resumingSession) {
                CipherSuite suite = previous.getSuite();
                ClientKeyExchangeService p = ClientKeyExchangeService.find(suite.keyExchange.name);
                if (p != null) {
                    Principal localPrincipal = previous.getLocalPrincipal();
                    if (p.isRelated(false, getAccSE(), 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");
                    }
                }
            }
            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);
                }
            }
        }
    }
    // cookie exchange
    if (isDTLS && !resumingSession) {
        HelloCookieManager hcMgr = sslContext.getHelloCookieManager();
        if ((mesg.cookie == null) || (mesg.cookie.length == 0) || (!hcMgr.isValid(mesg))) {
            // 
            // Perform cookie exchange for DTLS handshaking if no cookie
            // or the cookie is invalid in the ClientHello message.
            // 
            HelloVerifyRequest m0 = new HelloVerifyRequest(hcMgr, mesg);
            if (debug != null && Debug.isOn("handshake")) {
                m0.print(System.out);
            }
            m0.write(output);
            handshakeState.update(m0, resumingSession);
            output.flush();
            return;
        }
    }
    /*
         * 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;
    // 
    if (session == null) {
        if (!enableNewSession) {
            throw new SSLException("Client did not resume a session");
        }
        requestedGroups = (SupportedGroupsExtension) mesg.extensions.get(ExtensionType.EXT_SUPPORTED_GROUPS);
        // for full handshakes and TLS 1.2 or later.
        if (protocolVersion.useTLS12PlusSpec()) {
            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.useTLS12PlusSpec()) {
            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);
        // in previous processes.
        if (maxFragLenExt != null) {
            int maxFragLen = maxFragLenExt.getMaxFragLen();
            // More check of the requested "max_fragment_length" extension.
            if (maximumPacketSize != 0) {
                int estimatedMaxFragSize = cipherSuite.calculatePacketSize(maxFragLen, protocolVersion, isDTLS);
                if (estimatedMaxFragSize > maximumPacketSize) {
                    // For better interoperability, abort the maximum
                    // fragment length negotiation, rather than terminate
                    // the connection with a fatal alert.
                    maxFragLenExt = null;
                // fatalSE(Alerts.alert_illegal_parameter,
                // "Not an allowed max_fragment_length value");
                }
            }
            if (maxFragLenExt != null) {
                session.setNegotiatedMaxFragSize(maxFragLen);
            }
        }
        session.setMaximumPacketSize(maximumPacketSize);
    } else {
        // set the handshake session
        setHandshakeSessionSE(session);
    }
    if (protocolVersion.useTLS12PlusSpec()) {
        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 ((maxFragLenExt != null) && !resumingSession) {
        // When resuming a session, the server MUST NOT include a
        // max_fragment_length extension in the server hello.
        // 
        // Otherwise, use the same value as the requested extension.
        m1.extensions.add(maxFragLenExt);
    }
    StaplingParameters staplingParams = processStapling(mesg);
    if (staplingParams != null) {
        // responses back to this client for this connection.
        if (staplingParams.statusRespExt == ExtensionType.EXT_STATUS_REQUEST) {
            m1.extensions.add(new CertStatusReqExtension());
        } else if (staplingParams.statusRespExt == ExtensionType.EXT_STATUS_REQUEST_V2) {
            m1.extensions.add(new CertStatusReqListV2Extension());
        }
    }
    // Prepare the ALPN response
    if (clientHelloALPN != null) {
        List<String> peerAPs = clientHelloALPN.getPeerAPs();
        // check for a callback function
        if (hasAPCallback) {
            if (conn != null) {
                applicationProtocol = appProtocolSelectorSSLSocket.apply(conn, peerAPs);
            } else {
                applicationProtocol = appProtocolSelectorSSLEngine.apply(engine, peerAPs);
            }
        }
        // by the TLS peer
        if (applicationProtocol == null || (!applicationProtocol.isEmpty() && !peerAPs.contains(applicationProtocol))) {
            fatalSE(Alerts.alert_no_application_protocol, new SSLHandshakeException("No matching ALPN values"));
        } else if (!applicationProtocol.isEmpty()) {
            m1.extensions.add(new ALPNExtension(applicationProtocol));
        }
    } else {
        // Nothing was negotiated, returned at end of the handshake
        applicationProtocol = "";
    }
    if (debug != null && Debug.isOn("handshake")) {
        m1.print(System.out);
        System.out.println("Cipher suite:  " + session.getSuite());
    }
    m1.write(output);
    handshakeState.update(m1, resumingSession);
    // 
    if (resumingSession) {
        calculateConnectionKeys(session.getMasterSecret());
        sendChangeCipherAndFinish(false);
        // expecting the final ChangeCipherSpec and Finished messages
        expectingFinishFlightSE();
        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 (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
    // No external key exchange provider needs a cert now.
    } 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);
        handshakeState.update(m2, resumingSession);
    // 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");
        }
    }
    /**
     * The CertificateStatus message ... only if it is needed.
     * This would only be needed if we've established that this handshake
     * supports status stapling and there is at least one response to
     * return to the client.
     */
    if (staplingParams != null) {
        CertificateStatus csMsg = new CertificateStatus(staplingParams.statReqType, certs, staplingParams.responseMap);
        if (debug != null && Debug.isOn("handshake")) {
            csMsg.print(System.out);
        }
        csMsg.write(output);
        handshakeState.update(csMsg, resumingSession);
    }
    /*
         * 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:
            // no server key exchange for RSA 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) {
                    // make compiler happy
                    m3 = null;
                    throw new SSLException("Error generating RSA server key exchange", e);
                }
            } 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) {
                // make compiler happy
                m3 = null;
                throw new SSLException("Error generating DH server key exchange", e);
            }
            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) {
                // make compiler happy
                m3 = null;
                throw new SSLException("Error generating ECDH server key exchange", e);
            }
            break;
        case K_ECDH_RSA:
        case K_ECDH_ECDSA:
            // ServerKeyExchange not used for fixed ECDH
            m3 = null;
            break;
        default:
            ClientKeyExchangeService p = ClientKeyExchangeService.find(keyExchange.name);
            if (p != null) {
                // No external key exchange provider needs a cert now.
                m3 = null;
                break;
            }
            throw new RuntimeException("internal error: " + keyExchange);
    }
    if (m3 != null) {
        if (debug != null && Debug.isOn("handshake")) {
            m3.print(System.out);
        }
        m3.write(output);
        handshakeState.update(m3, resumingSession);
    }
    // No external key exchange provider needs a cert now.
    if (doClientAuth != ClientAuthType.CLIENT_AUTH_NONE && keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON && ClientKeyExchangeService.find(keyExchange.name) == null) {
        CertificateRequest m4;
        X509Certificate[] caCerts;
        Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
        if (protocolVersion.useTLS12PlusSpec()) {
            // 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);
        handshakeState.update(m4, resumingSession);
    }
    /*
         * FIFTH, say ServerHelloDone.
         */
    ServerHelloDone m5 = new ServerHelloDone();
    if (debug != null && Debug.isOn("handshake")) {
        m5.print(System.out);
    }
    m5.write(output);
    handshakeState.update(m5, resumingSession);
    /*
         * 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)

Example 8 with CipherSuite

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

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) {
            Map<NamedGroupType, Boolean> cachedStatus = new EnumMap<>(NamedGroupType.class);
            for (CipherSuite suite : enabledCipherSuites.collection()) {
                if (suite.isAvailable() && (!activeProtocols.min.obsoletes(suite)) && activeProtocols.max.supports(suite)) {
                    if (isActivatable(suite, cachedStatus)) {
                        suites.add(suite);
                    }
                } else if (debug != null && Debug.isOn("verbose")) {
                    if (activeProtocols.min.obsoletes(suite)) {
                        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 : NamedGroupType(sun.security.ssl.NamedGroupType) 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