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.