Keystore and truststore issue with elasticsearch and searchguard ssl - java

Let me give a little bit of background before I ask the question, so that we have clarity on the problem itself. We need to support one way SSL with Elasticsearch (v5.2.x), using searchguard ssl. We have a list of procedures for developers (not for production), which takes care of generating a self signed SSL cert. Here we've one root (locally created) and the actual cert. If we import the keystore (containing the private key and signed cert) and the truststore (containing the root cert) everything works fine.
But couple of days back, we got one request from a client. There, in production we need to support SSL. So, we followed the steps below:
with our script, we generated the private key, imported it into the keystore, and also generated the csr.
We gave the client the csr. He got it signed by a proper CA, and gave us back the cert.
Now the chain of trust is of length 3, for the cert given. So, there's a root CA, which signed the cert (issuer1), which signed the cert (issuer2), which in turn signed the actual csr.
For importing the actual cert to the keystore, we imported all the three parents, and then imported the actual cert.
Then we removed all the parent certs from keystore. So, now the keystore has only the private key and the actual cert.
We imported all the three parent certs into the truststore.
Now, if we start Elasticsearch, the following error is thrown: [ERROR][c.f.s.s.t.SearchGuardSSLNettyTransport] [uyyIg3i] SSL Problem Received fatal alert: certificate_unknown
javax.net.ssl.SSLException: Received fatal alert: certificate_unknown
Funny thing is, the exact procedure works, if we have only the root ca, signing the actual csr. Any help is appreciated for figuring out the root cause of this issue, as I'm sort of out of ideas now.

After couple of tiresome debugging sessions, we found out the CN-name and the actual host-name to be different. After making both of them same, we got it working.

Related

TLS Client Auth | Sectigo CA | Java

I generated a private key pair using KeyStore Explorer that was signed by Sectigo [formerly Comodo] yesterday. The goal is to employ this in an SSL mutual authentication scenario. I work with iWay, a java application, that will post messages to SAP's CPI, a service on cloud. The service on CPI has client authentication enabled [specific to the resource, not at host:port]. I have created a keystore with our private key and a truststore with some public certs in it. In response to a failed communication, I've enabled SSL debug on the application and here are my findings:
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***
This is reported at a stage when server cert was validated and accepted. In order to ensure whether or not the key in question took effect, I verified the logs and noticed the following, which assures that, it did [key name changed for security reasons]:
found key for : self_***.com_priv
I also verified that SAP accepts certificates when signed by valid CAs in the log that looked like this:
Cert Authorities:
...
<CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US>
...
This is how the signed cert look like, when opened on Windows:
I have the following questions:
1) The chain is displayed in the certificate when opened on Windows but not on KeyStore Explorer. Anyone know why?
2) The USERTrust root CA appears to be imported into SAP's trust store based on the log given above. In the picture above, the root cert, although, reported as Sectigo, which happens to be a friendly name, has its issuer name conforming to the one imported onto SAP's trust store:
I hence am not sure why java will not render this cert to SAP during TLS handshake. Any thoughts please?
3) The intermediate certificate has a property named Authority Information Access, in which, a link to its root is present. The properties of this root is entirely different from that of the root I see in picture at item 2 above. Does this matter at all?
Any help will be appreciated. Thanks.
Problem solved. It was due to the way, I imported the CA Reply into my private key. I imported only the signed entity certificate while it looks like I must had imported in PEM format. Thanks to Bruno who have explained the resolution HERE. I am relieved!

SSLHandshakeException: PKIX path building failed with Unable to find certificate chain

I am trying to Connect SSRS ReportServer with HTTPS Protocol from Java Client it's giving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: java.security.cert.CertPathBuilderException: Unable to find certificate chain
But I have added the certificate in Java Keystore, It the keystore the certificate is showing with the defined alias name.
But Same SSRS Request call is working with HTTP Protocol.
Note: We are using a wildcard certificate from Go-Daddy for secure communication
Can you verify that the certificate is added to 'Java Truststore' and not Keystore (although both have .jks extension).
Have a look at this https://docs.oracle.com/cd/E19830-01/819-4712/ablqw/index.html
Keystore file, keystore.jks, contains the Application Server’s certificate, including its private key
Truststore file, cacerts.jks, contains the Application Server’s trusted certificates
When you got your certificate, there should have been a p7b (possibly) included with it.
Essentially, when GoDaddy issues a certificate, they are not issued from the root directly.
Most likely you have one issued from an intermediate authority.
You can get the intermediate certificates at https://ssl-ccp.godaddy.com/repository?origin=CALLISTO
The certificate chain needs to be appended to the actual certificate and imported on the server.
The PEM file containing the cert being imported should look like:
<actual certificate>
<intermediate certificate>
[<intermediate certificate> ...]
After that you shouldn't have a need to do anything else on the client.
EDIT
After re-reading my answer, I realized there may be a little bit of vagueness with regard to the process. So in efforts to bring this more full cycle here we go.
Generate keypair / self-signed certificate as say PKCS#12 container.
Create PKCS#10 certificate signing request to send to GoDaddy of above certificate.
GoDaddy returns signed X.509 Certificate (typically with instructions on how to install it).
Taking the certificate (assuming PEM format) and concatenate the issuance chain from https://ssl-ccp.godaddy.com/repository?origin=CALLISTO and import that back into the PKCS#12 from step 1.
Assign the PKCS#12 as the TLS certificate store on the SSRS server.

Explicitly triggering 'peer not authenticated' exception for a Java client

I am working on a tutorial for some of my coworkers in an effort to educate them on how to diagnose and deal with SSL Certificate errors.
One of the specific errors we run into is the 'peer not authenticated' error that pops out in our logs when we have a bad SSL remote.
I have created a local set of certificates:
Root CA
Intermediate CA
Self-signed certificate
Root CA signed certificate
Intermediate CA signed certificate with no chain
Intermediate CA signed certificate with chain
Additionally, I've got a maven based project using the maven-jetty-plugin to run up the container with different SSL configurations on different ports. During the course of this I can get the PKIX path validation errors no problem, what I cannot seem to explicitly trigger is a 'peer not authenticated' error.
Can anyone point me in a direction to noodle this one out?

Can't get X509 root certificate from client in Tomcat

I'm trying to set up a test environment for our application that uses X.509 client authentication over HTTPS in Tomcat 6.0. The servlet code is expecting to get a certificate chain as an array of X509Certificate objects using the javax.servlet.request.X509Certificate of the servlet request. However, this array only contains a single item (the client certificate), where I'm expecting it to have two (the client certificate and the root CA certificate that signed it).
Here's what I've done so far:
Generate a self-signed CA certificate using openssl.
Import the CA certificate as a trusted root certificate into a newly create Java keystore.
Configure the Tomcat HTTPS connector to require client authentication using the keystore created in step 2 as the truststore:
clientAuth="true"
truststoreFile="<path_to_truststore>"
Generate a new client certificate using openssl and sign it with the CA certificate.
Start Tomcat.
Install the client certificate in Chrome and navigate to my server's homepage. Stepping through the code in debug, I can see that the array returned as the javax.servlet.request.X509Certificate attribute only has the client certificate.
I know that Tomcat is picking up the root CA certificate from the truststore because when I delete it from the truststore, I get an SSL connection error. It's just not making it into the servlet request like the documentation says it should. Am I missing any additional configuration here? Perhaps Tomcat (or Java or JSSE) is expecting some additional X509 V3 extensions or something?
Any help is appreciated!
EDIT
Looks like my setup is legit, and this falls into the category of unusual but expected behavior due to a simplified test environment. In an enterprise scenario it's unlikely that the root certificate authority is going to be directly signing client certificates for individual users. Clearly when this code was written and tested, there was at least one intermediate CA involved in the trust chain.
What your are seeing is what is expected: Chrome is not sending the CA.
During the TSL Handshake when authenticating the client, the server will send a list of acceptable CAs as part of its CertificateRequest Message (RFC), the browser will then present a Certificate signed by one of these CAs.
ADD
btw, a great way of debugging an SSL connection client side is to use the fantastic openssl tools
openssl s_client -connect ssl.server.com:443
or for SSLV3 only servers
openssl s_client -connect ssl.server.com:443 -ssl3
This will print (among other things) the list of acceptable CAs.
To debug the server side add this to the JVM command line -Djavax.net.debug=ssl
The identity keystore should contain the cert signed by the CA ; not the self-signed cert. The CA root should be in the truststore.
Also, what is the purpose of step 4 ?

Using HttpClient with SSL and certificates

While I've been familiar with HTTPS and the concept of SSL, I have recently begun some development and found I am a little confused.
The requirement was that I write a small Java application that runs on a machine attached to a scanner. When a document is scanned this is picked up and the file (usually PDF) sent over the internet to our application server that will then process it. I've written the application using Apache Commons libraries and HTTPClient.
The second requirement was to connect over SSL, requiring a certificate. Following guidance on the HTTPclient page I am using AuthSSLProtocolSocketFactory from the contributions page.
The constructor can take a keystore, keystore password, truststore and truststore password. As an initial test our DBA enabled SSL on one of our development webservers and provided me with a .p12 file which when I imported into IE allows me to connect successfully.
I am a bit confused between keystores and truststores and what steps I need to take using the keytool. I tried importing the p12 into a keystore file but get the error:
keytool error: java.lang.Exception: Input not an X.509 certificate
I followed a suggestion of importing the p12 into Internet Explorer and exporting as a .cer which I can then successfully import into a keystore. When I supply this as a keystore argument of the AuthSSLProtocolSocketFactory I get a meaningless errror, but if I try it as a truststore it seems like it reads it fine but ultimately I get
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
I am unsure if I have missed some steps, I am misunderstanding SSL and mutual authentication altogether or this is mis-configuration on the server side.
Can anyone provide suggestions or point me towards resources that might help me figure this out please?
The keystore holds your private keys and associated certificates. The truststore hold the certificates that you trust and that can therefore be used for certificate path building and verification.
Here are some links that may be useful:
java.lang.Exception: Input not an X.509 certificate
Import private key and certificate into Java Key Store
Configuring Keystores and Truststores
make sure your certificate file does not have anything before and after these.
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

Categories