use of sun.security.ssl.SignatureAndHashAlgorithm in project Bytecoder by mirkosertic.
the class ServerHandshaker method trySetCipherSuite.
/**
* Set the given CipherSuite, if possible. Return the result.
* The call succeeds if the CipherSuite is available and we have
* the necessary certificates to complete the handshake. We don't
* check if the CipherSuite is actually enabled.
*
* If successful, this method also generates ephemeral keys if
* required for this ciphersuite. This may take some time, so this
* method should only be called if you really want to use the
* CipherSuite.
*
* This method is called from chooseCipherSuite() in this class.
*/
boolean trySetCipherSuite(CipherSuite suite) {
/*
* If we're resuming a session we know we can
* support this key exchange algorithm and in fact
* have already cached the result of it in
* the session state.
*/
if (resumingSession) {
return true;
}
if (suite.isNegotiable() == false) {
return false;
}
// must not negotiate the obsoleted weak cipher suites.
if (protocolVersion.obsoletes(suite)) {
return false;
}
// must not negotiate unsupported cipher suites.
if (!protocolVersion.supports(suite)) {
return false;
}
KeyExchange keyExchange = suite.keyExchange;
// null out any existing references
privateKey = null;
certs = null;
dh = null;
tempPrivateKey = null;
tempPublicKey = null;
Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null;
if (protocolVersion.useTLS12PlusSpec()) {
if (peerSupportedSignAlgs != null) {
supportedSignAlgs = peerSupportedSignAlgs;
} else {
SignatureAndHashAlgorithm algorithm = null;
// we may optimize the performance
switch(keyExchange) {
// behave as if client had sent the value {sha1,rsa}.
case K_RSA:
case K_DHE_RSA:
case K_DH_RSA:
// case K_RSA_PSK:
case K_ECDH_RSA:
case K_ECDHE_RSA:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.RSA.value, 0);
break;
// sent the value {sha1,dsa}.
case K_DHE_DSS:
case K_DH_DSS:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.DSA.value, 0);
break;
// had sent value {sha1,ecdsa}.
case K_ECDH_ECDSA:
case K_ECDHE_ECDSA:
algorithm = SignatureAndHashAlgorithm.valueOf(HashAlgorithm.SHA1.value, SignatureAlgorithm.ECDSA.value, 0);
break;
default:
}
if (algorithm == null) {
supportedSignAlgs = Collections.<SignatureAndHashAlgorithm>emptySet();
} else {
supportedSignAlgs = new ArrayList<SignatureAndHashAlgorithm>(1);
supportedSignAlgs.add(algorithm);
supportedSignAlgs = SignatureAndHashAlgorithm.getSupportedAlgorithms(algorithmConstraints, supportedSignAlgs);
// May be no default activated signature algorithm, but
// let the following process make the final decision.
}
// Sets the peer supported signature algorithm to use in KM
// temporarily.
session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs);
}
}
// The named group used for ECDHE and FFDHE.
NamedGroup namedGroup = null;
switch(keyExchange) {
case K_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
break;
case K_RSA_EXPORT:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
try {
if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
if (!setupEphemeralRSAKeys(suite.exportable)) {
return false;
}
}
} catch (RuntimeException e) {
// could not determine keylength, ignore key
return false;
}
break;
case K_DHE_RSA:
// FFDHE extension will not be used.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) && (requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
setupEphemeralDHKeys(namedGroup, suite.exportable, privateKey);
break;
case K_ECDHE_RSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ? requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) : SupportedGroupsExtension.getPreferredECGroup(algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
setupEphemeralECDHKeys(namedGroup);
break;
case K_DHE_DSS:
// See comment in K_DHE_RSA case.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) && (requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "DSA");
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
// need DSS certs for authentication
if (setupPrivateKeyAndChain("DSA") == false) {
return false;
}
setupEphemeralDHKeys(namedGroup, suite.exportable, privateKey);
break;
case K_ECDHE_ECDSA:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ? requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) : SupportedGroupsExtension.getPreferredECGroup(algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// get preferable peer signature algorithm for server key exchange
if (protocolVersion.useTLS12PlusSpec()) {
preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm(supportedSignAlgs, "ECDSA");
if (preferableSignatureAlgorithm == null) {
if ((debug != null) && Debug.isOn("handshake")) {
System.out.println("No signature and hash algorithm for cipher " + suite);
}
return false;
}
}
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupEphemeralECDHKeys(namedGroup);
break;
case K_ECDH_RSA:
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
break;
case K_ECDH_ECDSA:
// need EC cert
if (setupPrivateKeyAndChain("EC") == false) {
return false;
}
setupStaticECDHKeys();
break;
case K_DH_ANON:
// See comment in K_DHE_RSA case.
if ((!useLegacyEphemeralDHKeys) && (!suite.exportable) && (requestedGroups != null) && requestedGroups.hasFFDHEGroup()) {
namedGroup = requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_FFDHE);
if (namedGroup == null) {
// no match found, cannot use this cipher suite.
return false;
}
}
// no certs needed for anonymous
setupEphemeralDHKeys(namedGroup, suite.exportable, null);
break;
case K_ECDH_ANON:
// Is ECDHE cipher suite usable for the connection?
namedGroup = (requestedGroups != null) ? requestedGroups.getPreferredGroup(algorithmConstraints, NamedGroupType.NAMED_GROUP_ECDHE) : SupportedGroupsExtension.getPreferredECGroup(algorithmConstraints);
if (namedGroup == null) {
// no match found, cannot use this ciphersuite
return false;
}
// no certs needed for anonymous
setupEphemeralECDHKeys(namedGroup);
break;
default:
ClientKeyExchangeService p = ClientKeyExchangeService.find(keyExchange.name);
if (p == null) {
// internal error, unknown key exchange
throw new RuntimeException("Unrecognized cipherSuite: " + suite);
}
// need service creds
if (serviceCreds == null) {
AccessControlContext acc = getAccSE();
serviceCreds = p.getServiceCreds(acc);
if (serviceCreds != null) {
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Using serviceCreds");
}
}
if (serviceCreds == null) {
return false;
}
}
break;
}
setCipherSuite(suite);
// set the peer implicit supported signature algorithms
if (protocolVersion.useTLS12PlusSpec()) {
if (peerSupportedSignAlgs == null) {
setPeerSupportedSignAlgs(supportedSignAlgs);
// we had alreay update the session
}
}
return true;
}
Aggregations