Skip to content

Bouncy Castle FIPS compatibility and errors. #851

@minQueue

Description

@minQueue

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.

  1. SSL handshake failed. Ciper suite in SSL Session is SSL_NULL_WITH_NULL_NULL
  2. org.bouncycastle.jsse.provider.ProvTlsServer processClientExtensions FINE: Server ignored SNI (no matchers specified)
  3. org.bouncycastle.tls.TlsFatalAlertReceived: certificate_unknown(46)
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    support requestCommunity assistance requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions