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;
}
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();
}
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");
}
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;
}
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;
}
Aggregations