BC occasionally fails to establish a TLS connection

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

BC occasionally fails to establish a TLS connection

Daniel Jeliński
Hello all,
I'm running an evaluation of BC-FIPS (1.0.2) library, and I'm
regularly encountering the following entries in application logs:

2019-11-07 13:00:14 UTC WARNING Client raised fatal(2)
internal_error(80) alert: Failed to read record
java.lang.IllegalStateException: Secret has already been extracted or destroyed
at org.bouncycastle.tls.crypto.impl.AbstractTlsSecret.checkAlive(Unknown Source)
at org.bouncycastle.tls.crypto.impl.jcajce.JceTlsSecret.deriveUsingPRF(Unknown
Source)
at org.bouncycastle.tls.crypto.impl.TlsImplUtils.PRF(Unknown Source)
at org.bouncycastle.tls.crypto.impl.TlsImplUtils.calculateKeyBlock(Unknown
Source)
at org.bouncycastle.tls.crypto.impl.TlsAEADCipher.<init>(Unknown Source)
at org.bouncycastle.tls.crypto.impl.TlsAEADCipher.<init>(Unknown Source)
at org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.createCipher_AES_GCM(Unknown
Source)
at org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.createCipher(Unknown
Source)
at org.bouncycastle.tls.crypto.impl.AbstractTlsSecret.createCipher(Unknown
Source)
at org.bouncycastle.tls.TlsUtils.initCipher(Unknown Source)
at org.bouncycastle.tls.TlsClientProtocol.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.TlsClientProtocol.connect(Unknown Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(Unknown
Source)
at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(Unknown
Source)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
(removed the rest of stack trace, probably irrelevant).

My application is sending a request to the same server once every
minute. I was able to capture the failing session in Wireshark; from
what I can see, the client is asking for an abbreviated handshake, the
server agrees and sends back the same session ID, then the client
aborts the handshake reporting internal error.

While I'm seeing the error regularly, I wasn't able to create a repro.
The application is pretty big, and it's hard to tell which parts are
relevant to the issue.

Is that a known issue? Any troubleshooting and/or mitigation
instructions welcome.

For what it's worth, I'm running the application on Windows machine
with the following security providers configured:
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
C:HYBRID;ENABLE{ALL}
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
fips:BCFIPS
security.provider.3=sun.security.provider.Sun

I'm also using BCTLS-FIPS-1.0.9 and BCPKIX-FIPS-1.0.3. The problem
appears both in approved and non-approved mode.
Thanks,
Daniel

Reply | Threaded
Open this post in threaded view
|

Re: BC occasionally fails to establish a TLS connection

Daniel Jeliński
I dug a bit deeper in the wireshark logs and noticed something
interesting, and probably related.
We are establishing 2 connections at roughly the same time, and the
problem sequence is as follows:
TCP 1. > ClientHello, sessionID cab8..
TCP 2. > ClientHello, sessionID cab8...
TCP 1. < ServerHello, sessionID 8766... (NEW)
TCP 2. < ServerHello, sessionID cab8.. (reused)
TCP 1. > Client key exchange
TCP 2. > TLS alert.

At this point I'm thinking that maybe BC destroys the old sessionID
right after it gets a new sessionID from the server, and when it later
gets the old sessionID from the server, it sends the alert. Does that
sound right?
Thanks,
Daniel

czw., 7 lis 2019 o 14:49 Daniel Jeliński <[hidden email]> napisał(a):

>
> Hello all,
> I'm running an evaluation of BC-FIPS (1.0.2) library, and I'm
> regularly encountering the following entries in application logs:
>
> 2019-11-07 13:00:14 UTC WARNING Client raised fatal(2)
> internal_error(80) alert: Failed to read record
> java.lang.IllegalStateException: Secret has already been extracted or destroyed
> at org.bouncycastle.tls.crypto.impl.AbstractTlsSecret.checkAlive(Unknown Source)
> at org.bouncycastle.tls.crypto.impl.jcajce.JceTlsSecret.deriveUsingPRF(Unknown
> Source)
> at org.bouncycastle.tls.crypto.impl.TlsImplUtils.PRF(Unknown Source)
> at org.bouncycastle.tls.crypto.impl.TlsImplUtils.calculateKeyBlock(Unknown
> Source)
> at org.bouncycastle.tls.crypto.impl.TlsAEADCipher.<init>(Unknown Source)
> at org.bouncycastle.tls.crypto.impl.TlsAEADCipher.<init>(Unknown Source)
> at org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.createCipher_AES_GCM(Unknown
> Source)
> at org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.createCipher(Unknown
> Source)
> at org.bouncycastle.tls.crypto.impl.AbstractTlsSecret.createCipher(Unknown
> Source)
> at org.bouncycastle.tls.TlsUtils.initCipher(Unknown Source)
> at org.bouncycastle.tls.TlsClientProtocol.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.TlsClientProtocol.connect(Unknown Source)
> at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(Unknown
> Source)
> at org.bouncycastle.jsse.provider.ProvSSLSocketWrap.startHandshake(Unknown
> Source)
> at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:396)
> (removed the rest of stack trace, probably irrelevant).
>
> My application is sending a request to the same server once every
> minute. I was able to capture the failing session in Wireshark; from
> what I can see, the client is asking for an abbreviated handshake, the
> server agrees and sends back the same session ID, then the client
> aborts the handshake reporting internal error.
>
> While I'm seeing the error regularly, I wasn't able to create a repro.
> The application is pretty big, and it's hard to tell which parts are
> relevant to the issue.
>
> Is that a known issue? Any troubleshooting and/or mitigation
> instructions welcome.
>
> For what it's worth, I'm running the application on Windows machine
> with the following security providers configured:
> security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
> C:HYBRID;ENABLE{ALL}
> security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
> fips:BCFIPS
> security.provider.3=sun.security.provider.Sun
>
> I'm also using BCTLS-FIPS-1.0.9 and BCPKIX-FIPS-1.0.3. The problem
> appears both in approved and non-approved mode.
> Thanks,
> Daniel

Reply | Threaded
Open this post in threaded view
|

Re: BC occasionally fails to establish a TLS connection

Peter Dettman-3
Hi Daniel,
Yes I think you may be onto something. If a client offers a session and
the server does not resume it, the client will invalidate it, which
destroys the master secret; it creates a race condition with other
clients that have offered the same session and may yet try to resume it.

We will fix this for the next release.

Regards,
Pete Dettman

On 8/11/19 1:09 am, Daniel Jeliński wrote:

> I dug a bit deeper in the wireshark logs and noticed something
> interesting, and probably related.
> We are establishing 2 connections at roughly the same time, and the
> problem sequence is as follows:
> TCP 1. > ClientHello, sessionID cab8..
> TCP 2. > ClientHello, sessionID cab8...
> TCP 1. < ServerHello, sessionID 8766... (NEW)
> TCP 2. < ServerHello, sessionID cab8.. (reused)
> TCP 1. > Client key exchange
> TCP 2. > TLS alert.
>
> At this point I'm thinking that maybe BC destroys the old sessionID
> right after it gets a new sessionID from the server, and when it later
> gets the old sessionID from the server, it sends the alert. Does that
> sound right?
> Thanks,
> Daniel