-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Hi,
I would like to apply Bouncy Castle FIPS TLS1.2 on my application which uses Java7 native code and SDK/JRE8 and Tomcat(7.0.69).
Is this possible combination to apply Bouncy Castle FIPS on my application?
(If not, would you let me know which one is incompatible and which version I need to update such as Tomcat 8, and Java8 native code? What is an ideal version combination to use BC-FIPS provider with Java application and tomcat?)
If it is possible combination to apply Bouncy Castle FIPS, how do I fix below errors I got?
Before adding BC-FIPS providers, I updated the certificate from JKS to BCFKS and changed java.security and java.policy following BC-FIPS guideline.
After changing some codes such as sslcontext, keymangerfactory, trustmanagerfactory and so on, I have faced lots of errors below.
- SSL handshake failed. Ciper suite in SSL Session is SSL_NULL_WITH_NULL_NULL
- org.bouncycastle.jsse.provider.ProvTlsServer processClientExtensions FINE: Server ignored SNI (no matchers specified)
- org.bouncycastle.tls.TlsFatalAlertReceived: certificate_unknown(46)
- Server raised fatal(2) internal_error(80) alert: Failed to write record
Full error stack trace:
2020/11/20 12:45:58 [http-bio-20080-exec-4] DEBUG [org.apache.tomcat.util.net.JIoEndpoint] - Handshake failed
java.io.IOException: SSL handshake failed. Ciper suite in SSL Session is SSL_NULL_WITH_NULL_NULL
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.handshake(JSSESocketFactory.java:291)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
2020/11/20 12:45:58 [http-bio-20080-exec-4] DEBUG [org.apache.tomcat.util.threads.LimitLatch] - Counting down[http-bio-20080-exec-4] latch=2
2020/11/20 12:45:58 [http-bio-20080-Acceptor-0] DEBUG [org.apache.tomcat.util.threads.LimitLatch] - Counting up[http-bio-20080-Acceptor-0] latch=2
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer getServerVersion
FINE: Server selected protocol version: TLSv1.2
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer getServerVersion
FINE: Server selected protocol version: TLSv1.2
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer processClientExtensions
FINE: Server ignored SNI (no matchers specified)
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer getSelectedCipherSuite
FINE: Server selected cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer processClientExtensions
FINE: Server ignored SNI (no matchers specified)
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer getSelectedCipherSuite
FINE: Server selected cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer notifyAlertReceived
INFO: Server received fatal(2) certificate_unknown(46) alert
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvSSLSocketDirect getConnection
FINE: Failed to establish connection
org.bouncycastle.tls.TlsFatalAlertReceived: certificate_unknown(46)
at org.bouncycastle.tls.TlsProtocol.handleAlertMessage(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.processAlertQueue(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.processRecord(Unknown Source)
at org.bouncycastle.tls.RecordStream.readRecord(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(Unknown Source)
at org.bouncycastle.tls.TlsServerProtocol.accept(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.handshakeIfNecessary(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.getConnection(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.getSessionImpl(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.getSession(Unknown Source)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.handshake(JSSESocketFactory.java:289)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Nov 20, 2020 12:45:58 PM org.bouncycastle.jsse.provider.ProvTlsServer notifyAlertRaised
WARNING: Server raised fatal(2) internal_error(80) alert: Failed to write record
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at org.bouncycastle.tls.RecordStream.writeRecord(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.safeWriteRecord(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.writeHandshakeMessage(Unknown Source)
at org.bouncycastle.tls.HandshakeMessageOutput.send(Unknown Source)
at org.bouncycastle.tls.HandshakeMessageOutput.send(Unknown Source)
at org.bouncycastle.tls.TlsServerProtocol.sendServerHelloDoneMessage(Unknown Source)
at org.bouncycastle.tls.TlsServerProtocol.handleHandshakeMessage(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.processRecord(Unknown Source)
at org.bouncycastle.tls.RecordStream.readRecord(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(Unknown Source)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(Unknown Source)
at org.bouncycastle.tls.TlsServerProtocol.accept(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.handshakeIfNecessary(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.getConnection(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.getSessionImpl(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.getSession(Unknown Source)
at org.apache.tomcat.util.net.jsse.JSSESocketFactory.handshake(JSSESocketFactory.java:289)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Regarding the SNI issue, I tried to apply the second alternative in Endpoint Identification section(3.5.1) https://downloads.bouncycastle.org/fips-java/BC-FJA-(D)TLSUserGuide-1.0.10.pdf
Since Java7 does not support SNIHostName class, I used BCSNIHostName, BCSSLParameters, and BCSNIServerName instead of default classes in my code.
try {
SSLContext context = SSLContext.getInstance("TLSv1.2", new BouncyCastleJsseProvider("fips:BCFIPS"));
context.init(null, tm, null);
serverURL = new URL("https://FQDN:port");
HttpsURLConnection.setDefaultSSLSocketFactory(new org.bouncycastle.jsse.util.CustomSSLSocketFactory(context.getSocketFactory()){
@Override
protected Socket configureSocket(Socket s)
{
if (s instanceof BCSSLSocket)
{
BCSSLSocket bcssl = (BCSSLSocket)s;
BCSNIHostName bcsniHostName = getSNIHostName(serverURL);
if (null != bcsniHostName)
{
BCSSLParameters bcsslParameters = new BCSSLParameters();
bcsslParameters.setServerNames(Collections.<BCSNIServerName>singletonList(bcsniHostName));
bcssl.setParameters(bcsslParameters);
}
}
return s;
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
private BCSNIHostName getSNIHostName(URL url)
{
String host = url.getHost();
if (null != host && host.indexOf('.') > 0 && !org.bouncycastle.util.IPAddress.isValid(host))
{
try{
return new BCSNIHostName(host);
}
catch (RuntimeException e){
// ignore – return null
}
}
return null;
}
I appreciate any comments or solution to figure out above errors.
Thanks