Skip to content

bouncycastle failures related to TLS 1.3 Hybrid Key Exchange - DER input not an octet string #2247

@cushon

Description

@cushon

I am seeing a regression that affects bouncycastle when testing with the latest JDK EA builds that include the changes for JEP 527: Post-Quantum Hybrid Key Exchange for TLS 1.3.

In JDK versions that include those changes, the following test fails.

import java.net.HttpURLConnection;
import java.net.URL;
import java.security.Security;
import java.time.Duration;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public final class DownloadTest {

  private static final Duration TIMEOUT = Duration.ofSeconds(1);

  public static void main(String[] args) throws Exception {

    if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
      Security.insertProviderAt(new BouncyCastleProvider(), 1);
    }

    String url = "https://storage.googleapis.com/diagnostic_service_storage/google_wifi_512dp.png";
    HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
    connection.setReadTimeout((int) TIMEOUT.toMillis());
    connection.setConnectTimeout((int) TIMEOUT.toMillis());
    connection.setRequestMethod("GET");
    connection.connect();
  }
}
$ java -Djdk.tls.namedGroups=X25519MLKEM768 -cp bcprov-jdk18on-1.83.jar DownloadTest.java
...
Exception in thread "main" javax.net.ssl.SSLException: (bad_record_mac) mac check in GCM failed
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:132)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:375)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:318)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:313)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:123)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
	at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:490)
	at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:141)
	at DownloadTest.main(DownloadTest.java:22)
Caused by: javax.crypto.AEADBadTagException: mac check in GCM failed
	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:483)
	at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(Unknown Source)
	at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
	at java.base/javax.crypto.CipherSpi.bufferCrypt(CipherSpi.java:788)
	at java.base/javax.crypto.CipherSpi.engineDoFinal(CipherSpi.java:723)
	at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2539)
	at java.base/sun.security.ssl.SSLCipher$T13GcmReadCipherGenerator$GcmReadCipher.decrypt(SSLCipher.java:1909)
	at java.base/sun.security.ssl.SSLSocketInputRecord.decodeInputRecord(SSLSocketInputRecord.java:264)
	at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:181)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
	at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:490)
	at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187)
	at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:141)
	at DownloadTest.main(DownloadTest.java:22)

I was initially investigating this problem on a different machine, where the same repro fails with a different error, the DER input not an octet string crash below:

javax.net.ssl.SSLHandshakeException: Could not generate secret
        at java.base/sun.security.ssl.KAKeyDerivation.t13DeriveKey(KAKeyDerivation.java:228)
        at java.base/sun.security.ssl.KAKeyDerivation.deriveKey(KAKeyDerivation.java:87)
        at java.base/sun.security.ssl.ServerHello$T13ServerHelloConsumer.consume(ServerHello.java:1347)
        at java.base/sun.security.ssl.ServerHello$ServerHelloConsumer.onServerHello(ServerHello.java:1061)
        at java.base/sun.security.ssl.ServerHello$ServerHelloConsumer.consume(ServerHello.java:941)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:421)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:477)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:448)
        at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:198)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1506)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1421)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
        at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:490)
        at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:187)
        at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:141)
        at DownloadTest.download(DownloadTest.java:26)
        ... 21 trimmed
Caused by: java.security.InvalidKeyException: Cannot parse input
        at java.base/sun.security.pkcs.NamedPKCS8Key.<init>(NamedPKCS8Key.java:95)
        at java.base/sun.security.provider.NamedKeyFactory.fromPKCS8(NamedKeyFactory.java:160)
        at java.base/sun.security.provider.NamedKeyFactory.engineTranslateKey(NamedKeyFactory.java:272)
        at java.base/sun.security.provider.NamedKEM.engineNewDecapsulator(NamedKEM.java:96)
        at java.base/javax.crypto.KEM$DelayedKEM.newDecapsulator(KEM.java:508)
        at java.base/javax.crypto.KEM.newDecapsulator(KEM.java:770)
        at java.base/javax.crypto.KEM.newDecapsulator(KEM.java:751)
        at java.base/sun.security.ssl.Hybrid$KEMImpl.engineNewDecapsulator(Hybrid.java:292)
        at java.base/javax.crypto.KEM.newDecapsulator(KEM.java:771)
        at java.base/javax.crypto.KEM.newDecapsulator(KEM.java:751)
        at java.base/sun.security.ssl.KAKeyDerivation.t13DeriveKey(KAKeyDerivation.java:214)
        ... 39 more
Caused by: java.io.IOException: DER input not an octet string
        at java.base/sun.security.util.DerInputStream.getOctetString(DerInputStream.java:155)
        at java.base/sun.security.pkcs.NamedPKCS8Key.<init>(NamedPKCS8Key.java:93)
        ... 49 more

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions