Apache HTTP Client javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated - apache

We are developing an application using tomcat and jersey.
Within this webapplication we need to connect to a https Website with a valid, not expired certificate.
If I do connect to this website locally via my chrome browser, everything works fine!
Unfortunately the tomcat server with our webapp throws an exception. We are using the Apache HttpClient (4.0) to connect to the https site:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:371)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:126)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:645)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:480)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
The server certificate is absolutely valid and from thawte.
Three different online tools validated the certificate successfully.
Openssl has an issue, too and showing me three certificates but throwing a simple error:
Verify return code: 20 (unable to get local issuer certificate)
The problem with openssl seems to be that it uses the wrong path /usr/lib/sslinstead of /etc/ssl/certs. If I use the CApath argument pointing to the proper path, openssl works fine so may this be an issue with the httpClient?
So our code for the default client is quite simple:
client = new DefaultHttpClient();
response = client.execute(url); //this throws the exception
EntityUtils.consume(response.getEntity());
It's not an option to allow any certificates by implementing a custom TrustedManager!
Futher I read, that some CA's are not part of the JDK/JRE and so it's certificates should be imported manually into the keystore or use a custom one, but thawte is a well known CA and shouldn't it work on default?
EDIT
I did set the javax.debug properties in catalina.sh so that I have further information about the problem:
http-bio-8080-exec-1, handling exception: javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path validation failed:
java.security.cert.CertPathValidatorException: basic constraints check failed:
pathLenConstraint violated - this cert must be the last cert in the certification path
I would appreciate any help!
Thanks in advance!

Okay, I got it working!
Although thawte is a well known CA it seems that Java SSL did have some problems with it.
After downloading the ssl Certificate via openssl:
echo |\
openssl s_client -connect ${REMHOST}:${REMPORT} 2>&1 |\
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
and saving it into an pem file, I did the manual import into the java keystore:
keytool -import -alias myAlias -file theCert.pem -keystore lib/security/cacerts
I have no idea why java ssl was not able to validate the thawte certificate properly.
Listing the keystore showed me, that there are 7 thawte trusted certificates in the standard keystore but bizarrely it did not work until I manually imported the pem file

I am trying to understand your setup. You have a SSL certificate (issued by Thwate), installed in tomcat and you can access your site just fine over SSL using say IE or Firefox or Chrome.
But when you try to access it using HttpClient, you receive the above error ?
Is that correct ?
The error clearly indicates that your client does not trust the CA. But if the cert is signed by Thwate (and is installed correctly and is acessible via IE/Firefox etc), then it should work fine.

Related

APACHE NIFI invokeHTTP to get token issue

I got a secure cluster NIFI with 3 nodes, configured with truststore.jks and keystore.jks
In my invokeHTTP, i've set "StandardSSLContextService" with keystore and trustore for https.
invokeHTTP works when i'm trying https://nifi:9443/nifi-api/controller/config
but not works when i'm trying "https://auth_server/oauth/access_token"
So when I'm trying use invokeHTTP to get token but it failed with this error :
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
thanks for helps
The StandardSSLContextService can be configured with a truststore, which is a Java KeyStore object which contains a collection of TrustedCertEntry objects -- each of which holds the public key and certificate information of a trusted entity. When Apache NiFi attempts to contact some other endpoint or service over HTTPS, it evaluates the received certificate identifying the service and attempts to validate that certificate. If the endpoint certificate is not directly contained in the truststore, it checks to see which certificate signed the leaf cert, and validate that one. This process continues up the certificate chain until either a cert is found that is trusted, or none are.
The error message you are receiving is stating that none of the certificates in the chain could be verified. As daggett pointed out, you could manually import the certificate of the service you want to validate into a custom truststore. If this is a service available on the public internet and signed by a generally trusted certificate authority (CA), you can also point your StandardSSLContextService to the default list provided by Java. The cacerts truststore is included automatically, and has a similar trusted entry list to modern browsers. It is found in $JAVA_HOME/jre/lib/security/cacerts. You can determine the value of $JAVA_HOME for your OS and Java version.
Truststore filename: /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre/lib/security/cacerts (example)
Truststore password: changeit (default value)
Truststore type: JKS

How to configure SoapUI mock service with non self signed certificate X509 for SSL

I have no problem to set up SoapUI mock service with self signed certificate by following the steps at
http://www.soapui.org/Service-Mocking/securing-mockservices-with-ssl.html .
But now I want to test the mock service with a "real" certificate issue by Entrust Certification Authority - L1C.
Other information for this certificate is
Ensures the identity of a remote computer
1.2.840.113533.7.75.2
2.23.140.1.2.2
It is valid until 2016.
I used the command to import the certificate to server.keystore .
c:\Program Files\Java\jre6\bin\keytool.exe -import -alias server -keystore server.keystore -storepass mypasss -file server_cer_issued_by_entrust.cer
(if I replace server_cer_issued_by_entrust.cer with a self signed (created) certificate it works)
I got the error in SoapUI which says ssh handshake error.
I just realize that it maybe not possible since the mock service is 127.0.0.1 but the actual certificate is issue for a web service like "mydomain.com", is that right?
SOAPUI runs over java, and when java connects to SSL url performs two validations:
Validate that the server certificate is trusted.
Validate that the common name in subject distinguished name of the server certificate matches the domain.
I assume that the first validation pass since in the link instructions which you provide its specify the same keystore in mock service for both: keystore and truststore, and since server certificate is imported in this one there is no problem to pass this validation.
So probably as you said the problem is that your mock service is on 127.0.0.1 and your certificate is issued to be used in mydomain.com.
A possible workaround is to disable SSL validation however this has no sense since as you said in the question you want to test the service with "real" certificate, instead maybe you can try editing host file and adding the mapping for 127.0.0.1 ip address for your certificate server domain, in your case:
127.0.0.1 mydomain.com
And then change the SOAPUI endpoint for your mock service to https://mydomain.com.
Hope this helps,

Unable to proxy Maven repo over https/ssl with Nexus

I followed the instructions given on this page to import the server certificate.
When I use keytool -list, I can see that the certificate is actually in the keystore. If I try to import the .crt file, keytool warns me that the keystore already contains the certificate.
Then I updated wrapper.conf with the two ssl options. I can see them on the command line of the Nexus process after a restart.
But when I try to add a proxy repo for the remote server, I always get sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
What did I miss?
You have to import the custom CA certificate into the 'trustStore' and not into the 'keyStore'.
The procedure for creating a 'trustStore' is the same as the one for the 'keyStore'.
Once you have your *.jks file then link it using the following system properties:
javax.net.ssl.trustStore=<file>
javax.net.ssl.trustStorePassword=<password>
Error message means the JVM cannot properly authenticate the remote server's SSL cert. Very common if the remote server is using a self-signed cert instead of one signed by an official certificate authority (like verisign).
Your message is confusing. You've enabled SSL on your Nexus instance, however you talk about a proxy repo implying the problem SSL cert might be on another server.

Having issues using existing Entrust certificates for Jetty SSL connection

I have three files from Entrust: *.csr, *.key and *.crt.
So far:
I have brought the *.key and *.crt into a PKCS12 keystore using OpenSSL
I have imported the *.pkcs12 into a keystore using keytool
Using this technique, I am able to use an SSL connection with Jetty
However, I'm getting a Certificate Error in IE (unsecured items in Chrome).
In our case, the certificates are currently being used for domain:80 (Apache) and I'm attempting to "reuse" them for domain:8443 (Jetty).
Am I wrong in thinking that I can use these for Jetty as well? On the same IP/domain, but on a different port and webserver? My gut is telling me that one of these files relates to Entrust recognizing Apache (*.csr) and that I should have to do the same for Jetty?
Edit #1
The error goes as follow:
Certificate Error
Untrusted Certificate
The security certificate presented by this webiste was not issued by a trusted certificate authority
This problem may indicate an attempt to fool you or intercept any data you send to the server.
We recommend that you close this webpage.
But yet Chrome, sees it as valid. I does have to work on IE since it's our standard.
Edit #2
Chrome doesn't complain
Nor does Firefox
Edit #3
I found our CA certificate specified in the Apache conf file. I then proceeded to concatenate our cert with the CA cert into a PKCS12 file. Then, using keytool, I generated the keystore.
I loaded it on the server, rebooted and viewed in IE. IE still shows a certificate issue.
In the concatenated file, I see in this order: our cert and then 2 other certificates.
On a side note, I called Entrust and the CSR saw no problems as he was using IE 8. We're on IE7.
Edit #4
Using this command:
keytool -list -keystore keystore -v
It shows 3 certificates (in this order):
Ours
Owner: CN=Entrust Certification Authority - L1C,
Owner: CN=Entrust.net Certification Authority (2048)
Edit 5
Solved! I guess I had a caching issue. Confirmed with colleagues.
Answer, Concatenating all my certs, including the CA cert, into the keystore solved my issue.
The port number, as stated in the comments, is irrelevant for trusting an SSL/TLS connection.
The problem is that the entire certificate chain from your certificate up to the Entrust root probably looks like this
your cert - intermediate CA 1 - intermediate CA 2 - ... - root CA
To make this work for IE you have to import not only your certificate into the PKCS#12 container, but additionally the intermediate certificates and also the root certificate. Otherwise your SSL implementation won't be able to provide the full path during the SSL handshake and thus IE has no means to build a proper chain to compare to its set of trusted root certificates.
So my advise would be to get the intermediate certificates from the appropriate web sites and importing them with keytool into your PKCS#12 key store.
Once done, IE should from then on accept without complaining.

SSL certificate verification fails, how to figure out what's causing it?

I've recently obtained a PositiveSSL certificate at Namecheap and installed it on my server. Accessing the site from Firefox works fine, but accessing it from Ruby's net/https library doesn't work: it fails to verify the connection certificate even though I've specified the path to the certificate and I've checked that the file is readable. Curl also fails:
curl --cacert /path/to/cert https://mysite.com/
It simply says something like this:
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
"certificate verify failed" isn't a terribly useful error message. How do I find out what exactly is wrong with my certificate and what to do about it? I find it confusing that it works in the browser but not anywhere else.
It looks like curl requires that the CA certificate file contains ALL certificates in the chain. I've downloaded all of them and combined them into a single file and now both Curl and Ruby are happy.