I'm trying to authorize an old JBoss 5 running on JRockit 6 to access to a CAS server using a Let's encrypt certificate.
The problem is that Let's encrypt is not supported on JDK6 so I added the root certificate to the cacerts file.
Now the problem is that JDK 6 does not understand such big key (java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)) so I tried to switch to Bouncy Castle JCE/JCA by adding bcprov-jdk15on-1.61.jar & bctls-jdk15on-1.61.jar to the $JAVA_HOME/jre/lib/ext folder & added org.bouncycastle.jce.provider.BouncyCastleProvider & org.bouncycastle.jsse.provider.BouncyCastleJsseProvider as first security providers in $JAVA_HOME/jre/lib/security/java.security file as explained partly here.
After a java.lang.ArrayIndexOutOfBoundsException: 64 I switched from SunX509 to X.509 value for ssl.KeyManagerFactory.algorithm key in java.security file.
Now I have the following error (I think the same as this thread on Oracle forum):
java.security.NoSuchAlgorithmException: Algorithm ECDH not available
javax.crypto.KeyAgreement.getInstance(DashoA13*..)
org.bouncycastle.jcajce.util.DefaultJcaJceHelper.createKeyAgreement(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.calculateKeyAgreement(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JceTlsECDomain.calculateECDHAgreement(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JceTlsECDH.calculateSecret(Unknown Source)
org.bouncycastle.tls.TlsECDHEKeyExchange.generatePreMasterSecret(Unknown Source)
org.bouncycastle.tls.TlsProtocol.establishMasterSecret(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.handleHandshakeMessage(Unknown Source)
org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(Unknown Source)
org.bouncycastle.tls.TlsProtocol.processRecord(Unknown Source)
org.bouncycastle.tls.RecordStream.readRecord(Unknown Source)
org.bouncycastle.tls.TlsProtocol.safeReadRecord(Unknown Source)
org.bouncycastle.tls.TlsProtocol.blockForHandshake(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.connect(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:167)
sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:216)
But by looking at org.bouncycastle.jcajce.provider.asymmetric.EC's sources such KeyAgreement should be correctly set by org.bouncycastle.jce.provider.BouncyCastleProvider.
But effectively, as it is the org.bouncycastle.jsse.provider.BouncyCastleJsseProvider which is used when creating a https client, this provider doesn't register this algorithm and I don't know how to do this.
Someone knows how to workaround this?
I have also tried to declare those jars as dependencies to my war and explicitely instanciate them like this:
static {
org.bouncycastle.jce.provider.BouncyCastleProvider bcp = new org.bouncycastle.jce.provider.BouncyCastleProvider();
java.security.Security.insertProviderAt(bcp, 1);
org.bouncycastle.jsse.provider.BouncyCastleJsseProvider bcjp = new org.bouncycastle.jsse.provider.BouncyCastleJsseProvider(bcp);
java.security.Security.insertProviderAt(bcjp, 1);
}
But then, I have this stack that seems to be linked to a problem in JBoss:
java.lang.SecurityException: JCE cannot authenticate the provider BC
javax.crypto.Cipher.getInstance(DashoA13*..)
org.bouncycastle.jcajce.util.ProviderJcaJceHelper.createCipher(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.hasEncryptionAlgorithm(Unknown Source)
org.bouncycastle.tls.TlsUtils.isSupportedCipherSuite(Unknown Source)
org.bouncycastle.tls.TlsUtils.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.jsse.provider.ProvTlsClient.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.tls.AbstractTlsClient.init(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.connect(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:167)
sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:216)
Caused by: java.util.jar.JarException: Cannot parse jar:file:/opt/jboss-5.1.0.GA/server/default/deploy/myapp.war/WEB-INF/lib/bcprov-jdk15on-1.61.jar!/
javax.crypto.SunJCE_c.a(DashoA13*..)
javax.crypto.SunJCE_b.b(DashoA13*..)
javax.crypto.SunJCE_b.a(DashoA13*..)
javax.crypto.Cipher.getInstance(DashoA13*..)
org.bouncycastle.jcajce.util.ProviderJcaJceHelper.createCipher(Unknown Source)
org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto.hasEncryptionAlgorithm(Unknown Source)
org.bouncycastle.tls.TlsUtils.isSupportedCipherSuite(Unknown Source)
org.bouncycastle.tls.TlsUtils.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.jsse.provider.ProvTlsClient.getSupportedCipherSuites(Unknown Source)
org.bouncycastle.tls.AbstractTlsClient.init(Unknown Source)
org.bouncycastle.tls.TlsClientProtocol.connect(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
org.bouncycastle.jsse.provider.ProvSSLSocketDirect.startHandshake(Unknown Source)
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:167)
sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
org.jasig.cas.client.validation.Saml11TicketValidator.retrieveResponseFromServer(Saml11TicketValidator.java:216)
In case, I have opened the issue #514 on BouncyCastle GitHub.
What you are seeing is consistent with the BouncyCastle JCE Provider not being registered. Hence the search for the ECDH Agreement is not finding it in the JCE search path.
To register the Provider dynamically simply add the following lines to your code
as per the BouncyCastle Specifications section 6.1 and the test sample code BouncyCastle JSSE Test Code
I suspect that you are not correctly initiating the environment