Search in sources :

Example 6 with SignatureAndHashAlgorithm

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;
}
Also used : KeyExchange(sun.security.ssl.CipherSuite.KeyExchange) SignatureAndHashAlgorithm(sun.security.ssl.SignatureAndHashAlgorithm)

Aggregations

SignatureAndHashAlgorithm (sun.security.ssl.SignatureAndHashAlgorithm)6 CipherSuite (sun.security.ssl.CipherSuite)2 KeyExchange (sun.security.ssl.CipherSuite.KeyExchange)2 Subject (javax.security.auth.Subject)1