Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40) #1156

Open
zxcvbnmlkjh opened this issue Apr 24, 2022 · 12 comments

Comments

@zxcvbnmlkjh
Copy link

Health Check: service at URL https://cobalt-gke/auditpublish-dev/greeting responded with message I/O error on GET request for "https://cobalt-gke/auditpublish-dev/greeting": handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)

@peterdettman
Copy link
Collaborator

We need more information to help you. What version of BC jars are you using? Do you have a full stack trace for the exception? What system are you trying to make a TLS connection to?

@zxcvbnmlkjh
Copy link
Author

@peterdettman Peter I am sharing all the detail, please help. Thanks

I am setting these Java options

export _JAVA_OPTIONS="-Djdk.tls.trustNameService=true -Dorg.bouncycastle.jca.enable_jks=true -Djava.security.debug=provider -Djava.security.properties==/Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/jre/lib/security/java.security.bcfips -Dorg.bouncycastle.fips.approved_only=true"

Changing these properties in JAVA.security file

security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=sun.security.provider.Sun

These are my jar versions.

bc-fips-1.0.2.1.jar
bcpkix-fips-1.0.5.jar
bctls-fips-1.0.12.1.jar
[bcmail-fips-1.0.3.jar

We are trying to connect to audit-publish service

https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting

This is full stack trace

Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [o.b.jsse.provider.ProvTlsClient: INFO ] - Client raised fatal(2) handshake_failure(40) alert: Failed to read record
org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:846)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(TlsProtocol.java:416)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:86)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:445)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:426)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:361)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckBase.checkHealth(HealthCheckBase.java:47)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckAuditService.checkHealth(HealthCheckAuditService.java:31)
at com.sap.ariba.security.file.fortification.service.monitoring.MasterHealthMetricsReporter.lambda$bindTo$1(MasterHealthMetricsReporter.java:98)
at io.micrometer.statsd.StatsdGauge.value(StatsdGauge.java:49)
at io.micrometer.statsd.StatsdGauge.poll(StatsdGauge.java:54)
at io.micrometer.statsd.StatsdMeterRegistry.poll(StatsdMeterRegistry.java:178)
at io.micrometer.statsd.StatsdMeterRegistry.lambda$startPolling$13(StatsdMeterRegistry.java:295)
at io.micrometer.shaded.reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onNext(FluxDoOnEach.java:140)
at io.micrometer.shaded.reactor.core.publisher.FluxInterval$IntervalRunnable.run(FluxInterval.java:123)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.call(PeriodicWorkerTask.java:59)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.run(PeriodicWorkerTask.java:73)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [c.s.a.s.f.f.s.m.m.HealthCheckBase: ERROR] - Health Check: service at URL https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting responded with message I/O error on GET request for "https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting": handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
Provider: SecureRandom.null algorithm from: BCFIPS_RNG
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS

@zxcvbnmlkjh
Copy link
Author

We need more information to help you. What version of BC jars are you using? Do you have a full stack trace for the exception? What system are you trying to make a TLS connection to?

@peterdettman Peter I am sharing all the detail, please help. Thanks

I am setting these Java options

export _JAVA_OPTIONS="-Djdk.tls.trustNameService=true -Dorg.bouncycastle.jca.enable_jks=true -Djava.security.debug=provider -Djava.security.properties==/Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/jre/lib/security/java.security.bcfips -Dorg.bouncycastle.fips.approved_only=true"

Changing these properties in JAVA.security file

security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=sun.security.provider.Sun

These are my jar versions.

bc-fips-1.0.2.1.jar
bcpkix-fips-1.0.5.jar
bctls-fips-1.0.12.1.jar
[bcmail-fips-1.0.3.jar

We are trying to connect to audit-publish service

https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting

This is full stack trace

Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [o.b.jsse.provider.ProvTlsClient: INFO ] - Client raised fatal(2) handshake_failure(40) alert: Failed to read record
org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:846)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(TlsProtocol.java:416)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:86)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:445)
at org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(ProvSSLSocketDirect.java:426)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:197)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:167)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:776)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:361)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckBase.checkHealth(HealthCheckBase.java:47)
at com.sap.ariba.security.file.fortification.service.monitoring.monitors.HealthCheckAuditService.checkHealth(HealthCheckAuditService.java:31)
at com.sap.ariba.security.file.fortification.service.monitoring.MasterHealthMetricsReporter.lambda$bindTo$1(MasterHealthMetricsReporter.java:98)
at io.micrometer.statsd.StatsdGauge.value(StatsdGauge.java:49)
at io.micrometer.statsd.StatsdGauge.poll(StatsdGauge.java:54)
at io.micrometer.statsd.StatsdMeterRegistry.poll(StatsdMeterRegistry.java:178)
at io.micrometer.statsd.StatsdMeterRegistry.lambda$startPolling$13(StatsdMeterRegistry.java:295)
at io.micrometer.shaded.reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onNext(FluxDoOnEach.java:140)
at io.micrometer.shaded.reactor.core.publisher.FluxInterval$IntervalRunnable.run(FluxInterval.java:123)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.call(PeriodicWorkerTask.java:59)
at io.micrometer.shaded.reactor.core.scheduler.PeriodicWorkerTask.run(PeriodicWorkerTask.java:73)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Mon Apr 25 01:32:25.273 GMT 2022 [parallel-1] [c.s.a.s.f.f.s.m.m.HealthCheckBase: ERROR] - Health Check: service at URL https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting responded with message I/O error on GET request for "https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting": handshake_failure(40); nested exception is org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
Provider: SecureRandom.null algorithm from: BCFIPS_RNG
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding encryption algorithm from: BCFIPS
Provider: Cipher.AES/GCM/NoPadding decryption algorithm from: BCFIPS

@peterdettman
Copy link
Collaborator

This exception happens when the server simply closes the connection before the handshake has completed. It means that you would need to look at the server logs in order to know the reason for the failure. If the server logs aren't accessible, you could get a packet capture of the connection attempt using e.g. Wireshark and we might be able to see something obvious.

It might also be worth trying with the latest available FIPS jars (at least we can rule out already-fixed bugs):

bc-fips-1.0.2.3.jar
bcmail-fips-1.0.4.jar
bcpkix-fips-1.0.6.jar
bctls-fips-1.0.13.jar

@zxcvbnmlkjh
Copy link
Author

zxcvbnmlkjh commented Apr 26, 2022

This exception happens when the server simply closes the connection before the handshake has completed. It means that you would need to look at the server logs in order to know the reason for the failure. If the server logs aren't accessible, you could get a packet capture of the connection attempt using e.g. Wireshark and we might be able to see something obvious.

It might also be worth trying with the latest available FIPS jars (at least we can rule out already-fixed bugs):

bc-fips-1.0.2.3.jar bcmail-fips-1.0.4.jar bcpkix-fips-1.0.6.jar bctls-fips-1.0.13.jar

@peterdettman Peter

 public double checkHealth (final String healthCheckServiceUrl)
{   
 final RestTemplate restTemplate = new RestTemplate();
    try {
        final ResponseEntity<String> responseEntity =
                restTemplate.getForEntity(healthCheckServiceUrl, String.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            log.debug("Health Check: service Running at URL {} is up", healthCheckServiceUrl);
            return SERVICE_UP;

I had this code which was creating issue, When i changed this Code to this it worked,

  public double checkHealth (final String healthCheckServiceUrl)
{
    final HttpClient client = HttpClients.createDefault();
    final ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(client);
    final RestTemplate restTemplate = new RestTemplate(factory);
    try {
        final ResponseEntity<String> responseEntity =
                restTemplate.getForEntity(healthCheckServiceUrl, String.class);
        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            log.debug("Health Check: service Running at URL {} is up", healthCheckServiceUrl);
            return SERVICE_UP;

}

When I am using HttpClient to make Https call it works and when it uses HttpsUrlConnection it throws me handshake failure, Is it the expected behaviour of HttpsUrlConnection with BCFIPS? Please provide your thoughts on it.

@peterdettman
Copy link
Collaborator

The two code examples look the same to me. Do you mean that you changed the URL from http to https?

HTTP doesn't use TLS at all, so it doesn't have much to do with this issue. The question is why the TLS connection fails and from what I can see the error happens at the server.

Do you know of any other client software that is able to make an HTTPS connection to this same server?

@zxcvbnmlkjh
Copy link
Author

The two code examples look the same to me. Do you mean that you changed the URL from http to https?

HTTP doesn't use TLS at all, so it doesn't have much to do with this issue. The question is why the TLS connection fails and from what I can see the error happens at the server.

Do you know of any other client software that is able to make an HTTPS connection to this same server?

@peterdettman Sorry Peter i updated the above answer, two codes are now different, Can you check now.

@peterdettman
Copy link
Collaborator

The HTTP connection doesn't use TLS, and the HTTPS connection does use TLS, but gets the handshake_failure exception. The TLS connection happens (and fails) before any request is sent, so the error has nothing to do with the application traffic (HTTP).

Do you have other software that can connect to the HTTPS URL?

@zxcvbnmlkjh
Copy link
Author

zxcvbnmlkjh commented Apr 26, 2022

The HTTP connection doesn't use TLS, and the HTTPS connection does use TLS, but gets the handshake_failure exception. The TLS connection happens (and fails) before any request is sent, so the error has nothing to do with the application traffic (HTTP).

Do you have other software that can connect to the HTTPS URL?

My current service makes an outbound TLS connection to AuditPublish service to check the status of this service using this url https://cobalt-gke.gk.cobalt.only.sap/auditpublish-dev/greeting". For which I am getting Handshake failure. This is the code for the Https call.

     public double checkHealth (final String healthCheckServiceUrl)
      {   
     final RestTemplate restTemplate = new RestTemplate();
        try {
            final ResponseEntity<String> responseEntity =
                    restTemplate.getForEntity(healthCheckServiceUrl, String.class);
            if (responseEntity.getStatusCode() == HttpStatus.OK) {
                log.debug("Health Check: service Running at URL {} is up", healthCheckServiceUrl);
                return SERVICE_UP;
    
    }

@isaacjensen
Copy link

I think im seeing this exact same issue. My keycloak has an auditlog .jar deployed which makes HTTPS requests. We have 2 requests happening -- one to our AuthZ server to get an access token, another to actually POST to auditlog (behind apigateway). The call to AuthZ goes through perfectly (not hosted on AWS infra), but when we try to hit auditlog, we see handshake_failed(40) with no other informative errors. Seems like this handshake_failed is due to client/server not agreeing on terms of connection. I have forced TLSv1.2, so im sure keycloak is using it for the AuthZ call and the Auditlog call.

@amitlpande
Copy link

I ran into similar issue and setting :

ssl.KeyManagerFactory.algorithm=PKIX in the java.security file worked for me.

Seems like BCFIPS doesn't support SunX509.

@marnix
Copy link

marnix commented Dec 4, 2023

I ran into similar issue and setting :

ssl.KeyManagerFactory.algorithm=PKIX in the java.security file worked for me.

Seems like BCFIPS doesn't support SunX509.

@amitlpande You say "similar issue". Can you please confirm whether or not you had the exact same stack trace, namely

org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
at org.bouncycastle.tls.TlsProtocol.safeReadRecord(TlsProtocol.java:846)
at org.bouncycastle.tls.TlsProtocol.blockForHandshake(TlsProtocol.java:416)
at org.bouncycastle.tls.TlsClientProtocol.connect(TlsClientProtocol.java:86)

(perhaps with some slightly different line numbers)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants