To develop my ssl-grizzly-based server, I am currently writing a SSLEchoClient and SSLEchoServer based on this example https://github.com/GrizzlyNIO/grizzly-mirror/tree/2.3.x/samples/framework-samples/src/main/java/org/glassfish/grizzly/samples/ssl
After defining an sslContext based on my post configuring SSLContext using existing SSL key/certificate pair in java (JSSE API), I initialized an SSLFilter and I added it to my filterChainBuilder. The SSLEchoServer uses a jks-keystore for providing credentials to my SSLEchoClient and my SSLEchoClient uses an jks-truststore to verify credentials sent from SSLEchoServer. What I getting now is the following error:
Grizzly-worker(1), fatal error: 46: General SSLEngine problem
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256]
Grizzly-worker(1), SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
Grizzly-worker(1), WRITE: TLSv1.2 Alert, length = 2
Grizzly-worker(1), fatal: engine already closed. Rethrowing javax.net.ssl.SSLHandshakeException: General SSLEngine problem
After some readings, I added my two jks-files to:
$JAVA_HOME/jre/lib/security directory.
But I still having the same Problem. What is really confusing me is the second error:
Grizzly-worker(1), SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
I have valid certificates but the debugger is telling me that the certificate is unknown. If the client is not able to find the trusted root certificate. How did he check that the certificate sent from the server is unknown?
So now, the ssl-handshake is not successfull.Here is some code from my EchoClient:
public static void main(String[] args) throws IOException, UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
// Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
// Add TransportFilter, which is responsible
// for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
// Initialize and add SSLFilter which is responsible for SSLFilter, responsible for encoding/decoding SSL secured data.
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
final SSLFilter sslFilter = new SSLFilter(serverConfig, clientConfig);
filterChainBuilder.add(sslFilter);
// Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
.
.
.
}
private static SSLEngineConfigurator initializeSSL() throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException {
// Create/initialize the SSLContext with key material
char [] passphrase2="zzzzz".toCharArray();
KeyStore ksTrust = KeyStore.getInstance("JKS");
ksTrust.load(new FileInputStream("C:\\Program Files\\Java\\jre1.8.0_51\\lib\\security\\trustkeystore.jks"),passphrase2);
TrustManagerFactory ktf =TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
ktf.init(ksTrust);
SSLContext sslContext = SSLContext.getInstance("TLS");
//initialize the ssl-context
sslContext.init(null,ktf.getTrustManagers(),null);
System.out.println("SSL-Server: SSL-initialization terminate");
// Create SSLEngine configurator
return new SSLEngineConfigurator(sslContext,false, false, false);
}
Here is some code from my EchoServer
public static void main(String[] args) throws IOException, UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
// Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
// Add TransportFilter, which is responsible
// for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());
// Initialize and add SSLFilter which is responsible for SSLFilter, responsible for encoding/decoding SSL secured data.
final SSLEngineConfigurator serverConfig = initializeSSL();
final SSLEngineConfigurator clientConfig = serverConfig.copy().setClientMode(true);
final SSLFilter sslFilter = new SSLFilter(serverConfig, clientConfig);
filterChainBuilder.add(sslFilter);
// Add StringFilter, which will be responsible for Buffer <-> String transformation
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
.
.
.
}
private static SSLEngineConfigurator initializeSSL() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException, CertificateException, IOException {
// Create/initialize the SSLContext with key material
char[] keyphrase = "xxxxx".toCharArray();
char [] passphrase1= "yyyyy".toCharArray();
//keys
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(new File("C:\\Program Files\\Java\\jre1.8.0_51\\lib\\security\\my_keystore.jks")), passphrase1);
//create an factory for key-managers
KeyManagerFactory kmf =KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keyphrase);
SSLContext sslContext = SSLContext.getInstance("TLS");
//initialize the ssl-context
sslContext.init(kmf.getKeyManagers(),null,null);
System.out.println("SSL-Server: SSL-initialization terminate");
// Create SSLEngine configurator
return new SSLEngineConfigurator(sslContext,false, false, false);
}
}