Imposta le estensioni TLS in Java (ad esempio trusted_ca_keys)

1

Sto cercando di capire come impostare l'estensione trusted_ca_keys in un client JAVA 8 TLS. O anche in generale: come faccio a impostare qualsiasi estensione TLS utilizzando la libreria JSSE standard fornita da Oracle? Non voglio usare librerie di terze parti come BouncyCastle.

Questo è il modo in cui ho configurato il mio client SSL finora, senza alcuna estensione:

/**
 * Initializes the TLS client 
 * 
 * @param host The address of the TLS server to connect to
 * @param port The port of the TLS server to connect to
 */
public boolean initialize(Inet6Address host, int port) {
    super.initialize();

    try {
        /*
         * Setting the system property for the keystore and truststore via 
         * - System.setProperty("javax.net.ssl.keyStore", [filePath given as a String])
         * - System.setProperty("javax.net.ssl.trustStore", [filePath given as a String])
         * does not work in a JAR file since only getResourceAsStream works there (which on the other
         * hand only returns an InputStream, not a file resource). Thus use setSSLFactories()
         */
        SecurityUtils.setSSLContext(
                GlobalValues.EVCC_KEYSTORE_FILEPATH.toString(), 
                GlobalValues.EVCC_TRUSTSTORE_FILEPATH.toString(),
                GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString());

        SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
        getLogger().debug("Creating socket to TLS server ...");
        setTlsSocketToServer((SSLSocket) sslSocketFactory.createSocket(host, port));
        getLogger().debug("TLS socket to server created");
        setInStream(getTlsSocketToServer().getInputStream());
        setOutStream(getTlsSocketToServer().getOutputStream());

        /*
         * The EVCC shall support at least one cipher suite as listed below according to 
         * the standard. An implementer may decide to choose only one of them:
         * - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
         * - TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
         */
        String[] enabledCipherSuites = {
                "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", 
                "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256" // this cipher suite should be avoided, ECDH does not support perfect forward secrecy
        };
        getTlsSocketToServer().setEnabledCipherSuites(enabledCipherSuites);

        // Set the supported TLS protocol
        String[] enabledProtocols = {"TLSv1.2"};
        getTlsSocketToServer().setEnabledProtocols(enabledProtocols);

        /*
         * The communication session setup timeout needs to be set here in case there is any problem with the
         * TLS handshake.
         * The timeout value will be overwritten with every new message being sent
         */
        getTlsSocketToServer().setSoTimeout(TimeRestrictions.V2G_EVCC_COMMUNICATION_SETUP_TIMEOUT);



        getLogger().debug("Starting TLS handshake ...");
        getTlsSocketToServer().startHandshake();
        getLogger().debug("TLS handshake finished");

        getLogger().info("TLS client connection established \n\t from link-local address " +
                          getClientAddress() + " and port " + getClientPort() + 
                          "\n\t to host " + host.getHostAddress() + " and port " + port);

        return true;
    } catch (UnknownHostException e) {
        getLogger().error("TLS client connection failed (UnknownHostException)!", e);
    } catch (SSLHandshakeException e) {
        getLogger().error("TLS client connection failed (SSLHandshakeException)", e);
    } catch (SocketTimeoutException e) {
        getLogger().fatal("TLS client connection failed (SocketTimeoutException) due to session setup timeout", e);
    } catch (IOException e) {
        getLogger().error("TLS client connection failed (IOException)!", e);
    } catch (NullPointerException e) {
        getLogger().fatal("NullPointerException while trying to set keystores, resource path to keystore/truststore might be incorrect");
    } 

    return false;
}

Ed ecco, per completezza, il codice per setSSLContext:

/**
 * Sets the SSLContext of the TLSServer and TLSClient with the given keystore and truststore locations as
 * well as the password protecting the keystores/truststores.
 * 
 * @param keyStorePath The relative path and filename for the keystore
 * @param trustStorePath The relative path and filename for the truststore
 * @param keyStorePassword The password protecting the keystore
 */
public static void setSSLContext(
        String keyStorePath, 
        String trustStorePath,
        String keyStorePassword) {
    KeyStore keyStore = SecurityUtils.getKeyStore(keyStorePath, keyStorePassword);
    KeyStore trustStore = SecurityUtils.getKeyStore(trustStorePath, keyStorePassword);

    try {
        // Initialize a key manager factory with the keystore
        KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyFactory.init(keyStore, keyStorePassword.toCharArray());
        KeyManager[] keyManagers = keyFactory.getKeyManagers();

        // Initialize a trust manager factory with the truststore
        TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());    
        trustFactory.init(trustStore);
        TrustManager[] trustManagers = trustFactory.getTrustManagers();

        // Initialize an SSL context to use these managers and set as default
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagers, trustManagers, null);
        SSLContext.setDefault(sslContext); 
    } catch (NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException | 
            KeyManagementException e) {
        getLogger().error(e.getClass().getSimpleName() + " occurred while trying to initialize SSL context");
    }    
}

Quindi ora ho bisogno di sapere dove nel codice sopra posso dire a Java di usare certe estensioni TLS. Ho bisogno di "trusted_ca_keys" e "staus_request_v2" (quest'ultimo è per la multi-pinzatura OCSP).

Ho anche implementato il server e ho bisogno di supportare queste estensioni anche nel server, ma questo esempio di codice dovrebbe essere sufficiente.

Qualsiasi aiuto è molto apprezzato.

    
posta 17.12.2018 - 23:01
fonte

0 risposte

Leggi altre domande sui tag