bcgit / bc-java

Bouncy Castle Java Distribution (Mirror)
https://www.bouncycastle.org/java.html
MIT License
2.29k stars 1.13k forks source link

ClassCastException BCXDHPublicKey to XECPublicKey on JDK 17 #1824

Open gtoison opened 3 weeks ago

gtoison commented 3 weeks ago

Hello, We are observing this exception on a modular (packaged with jpackage) application running on JDK 17 and with BC 1.78.1

javax.net.ssl.SSLException : class org.bouncycastle.jcajce.provider.asymmetric.edec.BCXDHPublicKey cannot be cast to class java.security.interfaces.XECPublicKey (org.bouncycastle.jcajce.provider.asymmetric.edec.BCXDHPublicKey is in unnamed module of loader 'app'; java.security.interfaces.XECPublicKey is in module java.base of loader 'bootstrap')

java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
java.base/sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)

My understanding is that this is supposed to work because BC is released as a multi release jar. However since 1.78 I see that the content of the Java 11 folder has changed in bcprov-jdk18on:

image

On 1.77 (and earlier versions) I see that the 11+ classes were packaged:

image

The osgi manifest was also added, maybe removing the 11+ classes was an unintended change? Could you please advise if I'm misunderstanding the problem? Thanks in advance!

dghgit commented 3 weeks ago

Okay, I'm not sure what happened there. Would you check the latest beta at https://downloads.bouncycastle.org/betas you should find that's correct.

One further question on this one - where did the 1.78.1 jar come from? I've just checked the one we're distributing and it's definitely got the files in there.

gtoison commented 2 weeks ago

Thank you very much for looking into it, now I got a bit worried where that .jar was coming from but opening up the in the local maven repository folder shows that the java 11+ classes are there indeed in 1.78.1 I guess that, for some reason, Eclipse hides them when there's also an osgi manifest.

Now that this red herring is gone I have no idea why we're getting this ClassCastException. We seem to get it occasionally only, and to be clear the application is not running from Eclipse: it is packaged with jpackage and runs on Java 17/Windows 10

dghgit commented 2 weeks ago

Okay, I'd suspect jpackage. Not that there is anything wrong with it, but the problem you will run into with a Java cryptography provider is that it has to be loaded by the system class loader as there will be situations where it does not trust anything else. In the past we have seen this cause class annotation issues so for example a class which should be okay will fail like your seeing because it is under an untrusted class loader.

gtoison commented 2 weeks ago

I looked a bit more into this because I was not sure why BC would kick in, also because the issue only seems to happen rarely (for now I can't reproduce it). We are using icepdf, I think that when the user displays an encrypted PDF file it triggers this initialization:

    static {
        // Load security handler from system property if possible
        String defaultSecurityProvider =
                "org.bouncycastle.jce.provider.BouncyCastleProvider";

        // check system property security provider
        String customSecurityProvider =
                Defs.sysProperty("org.icepdf.core.security.jceProvider");

        // if no custom security provider load default security provider
        if (customSecurityProvider != null) {
            defaultSecurityProvider = customSecurityProvider;
        }
        try {
            // try and create a new provider
            Object provider = Class.forName(defaultSecurityProvider).getDeclaredConstructor().newInstance();
            Security.addProvider((Provider) provider);

https://github.com/pcorless/icepdf/blob/a50ab930afcf3759d1f17f82753600bd615f3367/core/core-awt/src/main/java/org/icepdf/core/pobjects/security/SecurityManager.java#L89