BouncyCastle FIPS: getting StackOverFlowError when converting default keystore from JKS to BCFKS - ssl

So I am working on a FIPS compliant java base image with JDK11. The requirement was to convert the default keystore from JKS to BCFKS.
This is my java.security setting:
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
security.provider.3=SUN
security.provider.4=SunRsaSign
security.provider.5=SunEC
security.provider.6=SunJSSE BCFIPS
security.provider.7=SunJCE
security.provider.8=SunJGSS
security.provider.9=SunSASL
security.provider.10=XMLDSig
security.provider.11=SunPCSC
security.provider.12=JdkLDAP
security.provider.13=JdkSASL
security.provider.14=Apple
security.provider.15=SunPKCS11
#
# Default keystore type.
#
keystore.type=BCFKS
So when I try to convert the default keystore from JKS to BCFKS with the following command:
keytool -importkeystore -srckeystore /etc/ssl/certs/java/cacerts.orig -srcstoretype JKS \
-srcstorepass changeit -destkeystore /etc/ssl/certs/java/cacerts -deststorepass changeit \
-deststoretype BCFKS -providerClass org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider \
--providerpath /usr/lib/jvm/java-11-openjdk-amd64/jar/bc-fips-1.0.2.3.jar
I get the following error:
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.util.Dictionary.<init>(Dictionary.java:55)
at java.base/java.util.Hashtable.<init>(Hashtable.java:239)
at java.base/java.util.Properties.<init>(Properties.java:206)
at java.base/java.util.Properties.<init>(Properties.java:174)
at java.base/java.security.Provider.<init>(Provider.java:262)
at java.base/sun.security.ssl.SunJSSE.<init>(SunJSSE.java:138)
at java.base/sun.security.ssl.SunJSSE.<init>(SunJSSE.java:126)
at java.base/com.sun.net.ssl.internal.ssl.Provider.<init>(Provider.java:52)
at java.base/sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:183)
at java.base/sun.security.jca.ProviderList.getProvider(ProviderList.java:266)
at java.base/sun.security.jca.ProviderList.getIndex(ProviderList.java:296)
at java.base/sun.security.jca.ProviderList.getProviderConfig(ProviderList.java:280)
at java.base/sun.security.jca.ProviderList.getProvider(ProviderList.java:286)
...
When I remove "BCFIPS" in provider.6, the error is gone, but I do need it to be there for the SSL to load BCFIPS as provider.
The same settings worked fine by my colleagues, but a notable difference is they use JDK8. Not sure if that's the reason.
Also I saw this https://github.com/bcgit/bc-java/issues/1000 who has exactly the same issue with me, unfortunately the workaround didn't work for me and there was no follow-up.
I've been stuck with this for days...HELP appreciated! Thank you!s
I tried the settings mentioned above, tried the keytool command, was expecting the keystore type converted correctly from JKS to BCFKS, but StackOverFlowError happened.

Related

kafka 2 way ssl authentication

I am trying to setup 2 way ssl authentication. My requirement is broker should authenticate only specific clients.
My organization has a CA which issue all certificates in pkcs12 format. steps i followed are as follows.
get a certificate for the broker and configured it in the broker keystore
ssl.keystore.location=/home/kafka/certificate.p12
ssl.keystore.password=xxxxx
ssl.client.auth=required
get a certificate for the client and configured it in the client keystore
ssl.keystore.location=/home/kafka/certificate.p12
ssl.keystore.password=xxxxx
extracted the public certificate from the client certificate using keytool command
keytool -export -file cert -keystore certificate.p12 -alias "12345" -storetype pkcs12 -storepass xxxxx
imported the certificate into broker truststore. broker truststore contains only the client 12345 certificate.
keytool -keystore truststore.p12 -import -file cert -alias 12345 -storetype pkcs12 -storepass xxxxx -noprompt
configured the truststore in the broker.
ssl.truststore.location=/home/kafka/truststore.p12
ssl.truststore.password=xxxxx
configured the truststore in client. client truststore contains CA certificates.
ssl.truststore.location=/etc/pki/java/cacerts
ssl.truststore.password=xxxxx
When i run the broker and client i expect the broker to authenticate the client and establish ssl connection. but instead following error is thrown.
[2021-06-03 23:32:06,864] ERROR [AdminClient clientId=adminclient-1] Connection to node -1 (abc.com/10.129.140.212:9093) failed authentication due to: SSL handshake failed (org.apache.kafka.clients.NetworkClient)
[2021-06-03 23:32:06,866] WARN [AdminClient clientId=adminclient-1] Metadata update failed due to authentication error (org.apache.kafka.clients.admin.internals.AdminMetadataManager)
org.apache.kafka.common.errors.SslAuthenticationException: SSL handshake failed
Caused by: javax.net.ssl.SSLProtocolException: Unexpected handshake message: server_hello
I tried various things but nothing seems to work. when i replace the broker truststore with /etc/pki/java/cacerts truststore file which contains only the CA certificate
then it works fine. but it will authenticate any client which has certificate issued by the CA.
what could be the issue ?
The default format is jks,
use keytool to create a Java KeyStore (JKS) with the certificate and key for use by Kafka. You'll be prompted to create a new password for the resulting file as well as enter the password for the PKCS12 file from the previous step. Hang onto the new JKS password for use in configuration below.
$ keytool -importkeystore -srckeystore server.p12 -destkeystore kafka.server.keystore.jks -srcstoretype pkcs12 -alias myserver.internal.net
Note: It's safe to ignore the following warning from keytool.
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore server.p12 -destkeystore kafka.server.keystore.jks -srcstoretype pkcs12"

java.io.IOException: keystore password was incorrect

I am using command:
keytool -importkeystore -srckeystore "X\cert.pfx" -srcstorepass password -srcstoretype pkcs12 -destkeystore "X\keystore3.jks" -destkeypass password -deststoretype JKS -alias alias
and get java.io.IOException: keystore password was incorrect
However if I double click on cert.pfx and during installation process enter passphrase which is password I successfully install it.
Another strange thing is that I am asked for a new keystore passphrase even thought I have supplied it with -destkeypass password
Update:
Strange thing happened out of nowhere: I was unable to use keytool anymore - I got This app can’t run on your PC. After calling where keytool I went to that directory and saw that keytool.exe is of size 0KB. All I was doing this time was jus trying different versions of keytool and openssl commands so I've got no idea why this had happened. Since I could not use that instance of keytool anymore I tried using different one as I have installed multiple JDK instances on my machine and I it worked: I mean I do not get keystore password was incorrect error anymore. I get another error now but it is a different story.

bad_certificate when executing an API in WSO2Carbon

Although my site's certificate is fine, ("openssl verify mysite.com.cer" resulted in OK), and my site is ssl-certified including green lock in the url-bar, my site is generating a fatal alert: bad_certificate whenever a subscriber in my WSO2 app executes an api.
[2018-06-08 10:54:47,167] ERROR - SourceHandler I/O error: Received fatal alert: bad_certificate
javax.net.ssl.SSLException: Received fatal alert: bad_certificate
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634)
at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800)
at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1083)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:907)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at org.apache.http.nio.reactor.ssl.SSLIOSession.doUnwrap(SSLIOSession.java:245)
at org.apache.http.nio.reactor.ssl.SSLIOSession.decryptData(SSLIOSession.java:378)
at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:413)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:119)
at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:218)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:281)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:105)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:586)
at java.lang.Thread.run(Thread.java:748)
I browsed through several stackoverflow-questions about 'bad_certificate' but found no solution.
To import my certificate I followed WSO2's docs:
openssl pkcs12 -export -in SSL_certificate_www_mysite_com.crt -inkey www.mysite.com.key -name "mykeys" -certfile mysite.com.cer -out mykeys.pfx
keytool -importkeystore -srckeystore mykeys.pfx -srcstoretype pkcs12 -destkeystore mykeys.jks -deststoretype JKS
keytool -export -alias "mykeys" -keystore mykeys.jks -file mykeys.pem
copied mykeys.pem and mykeys.jks to /usr/local/opt/wso2am-2.2.0/repository/resources/security/
keytool -import -alias "mykeys" -file mykeys.pem -keystore client-truststore.jks -storepass wso2carbon and answered yes to include the certificate
Then I had to change several configuration files to use mykeys instead of wso2carbon. So I did.
Then I restarted wso2-carbon, logged in and checked that mykeys.JKS showed up in the list of keystores, it does.
My site is correctly ssl-certified, green lock showing in the url-bar. All works fine, upto the point that logged in as Subscriber I try to Execute an API, which results in the response "ERROR - SourceHandler I/O error: Received fatal alert: bad_certificate" and the above-mentioned log coming from sourcehandler
This error is logged in repository/logs/wso2-apigw-errors.log and wso2carbon.log, but only this message, nothing else.
Where to look next to find why my certificate is not getting validated correctly?
the problem is in the self-signed certificate
assume your service published at this endpoint:
https://192.168.99.3:8243/first/1.0.0
then you have to go into a new browser window
https://192.168.99.3:8243/
set browser to always accept the https certificate
after this the call in api console should work
If you have separate Store and gateway instances, open the gateway:9443/carbon in browser and accept the self signed certificate. That should work.

Importing a Certificate into Glassfish and Changing the Master Password

I have been attempting to help one of our sites with an error message they are getting while using an application that uses Glassfish. When signing into the application, the following errors are thrown:
CommunicationException: An error occurred while making the HTTP request to . This could be due to the fact that the server certificate is notconfigured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.
In Server.log, the following is displayed:
0400|SEVERE|glassfish3.1|com.sun.grizzly.config.GrizzlyServiceListener|_ThreadID=287;_ThreadName=Thread-1;|Failed to load keystore type JKS with path C:\glassfishv3\glassfish\domains\domain1/config/keystore.jks due to Keystore was tampered with, or password was incorrect
java.io.IOException: Keystore was tampered with, or password was incorrect
The site is only experiencing this problem when they change the glassfish master password. When the master password is left as its default setting, everything works correctly. The default master password is "changeit".
Additionally, the site generates and imports a certificate for use with glassfish. The following are the steps that are performed, in order, for generating a certificate and changing the password:
Stopped Glassfish service.
Opened MMC.MSC: Action --> All Tasks --> Request New Certificate
From the Certificate Enrollment wizard, chose a Computer type certificate. Click Properties Button and configure certificate. It gets a friendly name of "s1as" and an exportable private key of key size 2048. Private key is exported as a pfx file and certificate is exported as a cer file. The files are saved in the glassfish config folder. Details about this process available if needed.
DOS prompt opened and this command is run inside the glassfish config folder:
keytool -delete -alias s1as -keystore keystore.jks -storepass changeit
Following command is run:
keytool -import -v -trustcacerts -alias -file root.cer -keystore cacerts.jks -storepass changeit
Answered "Y" to trust the certificate.
Ran the following command to replace the original self-signed certificate with the pfx one.
keytool -importkeystore -srckeystore .pfx -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype JKS
Entered password, and a success message appears afterwards that 1 entry was succesfully imported.
Ran this command:
keytool -list -keystore keystore.jks -rfc
A lot of output is produced, including a long Alias name. Thsi long alias is used in the next command.
Ran the following command:
keytool -changealias -alias "" -destalias "s1as" -keypass changeit -keystore keystore.jks -storepass changeit
Ran the following command in asadmin:
change-master-password --savemasterpassword=true
Entered Current password of "changeit"
Entered new password of 123456
Re-entered 123456.
Success message that master password changed succesfully.
Started glassfish service
In my local testing, this procedure has worked and I am able to use the application with no errors. But on the site I am aiding, when they follow the same process, they receive the errors I listed at the top of this message.
My specific questions:
Could the site's certificate be causing this problem? If so, is there a way I could test that the certificate is the issue?
What other things might potentially be generating the errors? Could the "change-master-password" command not be properly changing the password, or could there be something else that needs to have the password changed as well?
I have found the solution to this, and I am posting it here should someone in the future encounter the same issue that I have. Hopefully this will save someone much frustration some day.
In domain.xml, the following 2 lines needed to be added in the jvm-options area.
<jvm-options>-Djavax.net.ssl.keyStorePassword=[password]</jvm-options>
<jvm-options>-Djavax.net.ssl.trustStorePassword=[password]</jvm-options>

Keystore password for Jetty 7.0 SSL configuration

Trying to setup SSL on jetty 7.2.2 using these instructions:
http://docs.codehaus.org/display/JETTY/How+to+configure+SSL
stuck on 3b:
keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore $JETTY_HOME/etc/keystore
jetty ships with default keystore at $JETTY_HOME/etc/keystore. I'm asked for password when running that command. I don't know default keystore password.
If I try to replace that keystore with newly created one - I'm getting IOException on jetty startup - keystore is tampered with or password incorrect.
What I'm doing wrong? Or what's default keystore jetty password?
The default password for the keystore that is shipped with jetty is storepwd. But I would highly recommend you follow the steps listed in the How to configure SSL and create your own keystore.
I think you just want to overwrite the keystore in etc/keystore with your new one. Then, update the Jetty conf as in Step 4. You will need to obfuscate your keystore password using the org.mortbay.jetty.security.Password class.
One more subtle steps that needs to be followed .
i.e Jetty has another file start.ini, un-comment jetty-ssl.xml line to make the SSL configuration active.
That was my bad. Didn't notice that there's jetty-ssl.xml also, that used default keystore. Moved addConnector to jetty-ssl.xml, put right passwords there, and everything works now like a charm.
One note, the eclipse version of jetty works a little differently http://www.eclipsezone.com/eclipse/forums/t88098.html
Today with jetty 9.4.34 and you'd like to use the default keystore password storepwd and default private key password keypwd, so that you don't have to modify the config, and you have cert/key in common PEM format...
tmpcert="/tmp/certkey$RANDOM.pkcs12" ; \
openssl pkcs12 -export -inkey "key.pem" \
-in "cert.pem" \
-passout "pass:storepwd" \
-out "$tmpcert" \
&& \
keytool -importkeystore \
-srckeystore "$tmpcert" -srcstoretype PKCS12 \
-srcstorepass storepwd \
-destkeystore "$JETTY_BASE/etc/keystore" -deststoretype JKS \
-deststorepass storepwd \
-destkeypass keypwd ; \
rm "$tmpcert"
That's all you need to import to provide SSL functionality
Because of JKS there is the
Warning: The JKS keystore uses a proprietary format. It is recommended
to migrate to PKCS12 which is an industry standard format using
...
But it is the only possibility to set a different keypass like keypwd for key and storepwd for keystore.
For pkcs12 storetype this distinction is impossible (at least with keytool, there is an error on execution).
For the rest (like config modifications for own passwords, and generating own passwords) the documentation at https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html is ok.