This question already has answers here:
Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?
(33 answers)
Closed 6 years ago.
Update: I never got this working over SSL. I ended up implementing a VPN in order to get the security.
I've been trubleshooting this problem for 2 days and cannot figure it out for the life of me. I've reviewed the following threads:
Resolving javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed Error?
https://stackoverflow.com/questions/14465089/ssl-connection-in-glassfish-3-1
Among many others.
UPDATE: Sorry, I didn't even post the error I'm getting. Here it is:
javax.naming.CommunicationException: simple bind failed: server.local:636 [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
I'm also using GlassFish server 3.1.2 and NetBeans 7.3 on Win7 pro.
Here is the code that is causing the error:
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://server.local:636/");
// Specify SSL
env.put(Context.SECURITY_PROTOCOL, "ssl");
// Fill in secuirty/bind variables
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, config.Config.getSECURITY_PRINCIPAL()); //returns user#domain.local
env.put(Context.SECURITY_CREDENTIALS, config.Config.getSECURITY_CREDENTIALS()); //returns password
// Create the initial context
ctx = new InitialDirContext(env); //defined above as InitialDirContext ctx = null;
I have used ldp.exe to confirm that SSL is configured properly on our AD server. Furthermore, I've tried the following:
Importing the client certificate (and the CA root certificate from AD CS) as outlined here
a. I used the following commands:
C:\Program Files (x86)\Java\jdk1.7.0_25>bin\keytool -import -file SBS2011.sage.local_sage-SBS2011-CA.crt -keystore .\jre\lib\security\cacerts -alias SBS2011
Enter keystore password:
Certificate already exists in keystore under alias <mykey>
Do you still want to add it? [no]: yes
Certificate was added to keystore
C:\Program Files (x86)\Java\jdk1.7.0_25>
Uninstalling Java and reinstalling, then repeating step 1.
Adding the following lines of code:
System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files (x86)\\Java\\jdk1.7.0_25\\jre\\lib\\security\\cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Other notes: the code works fine using non-SSL connection but then I get LDAP error 53 when trying to update user's information. In the end if there is a solution that involves not using SSL, I don't mind.
Your truststore doesn't trust the LDAP server certificate.
Your step (3) above is the default.
If your LDAP server has a CA-signed certificate step (1) was unnecessary.
I don't know why you speak of 'client certificate' when it is the LDAP server's certificate you may need to import.
env.put(Context.PROVIDER_URL, "ldap://server.local:636/");
should be
env.put(Context.PROVIDER_URL, "ldaps://server.local:636/");
Related
I am running a local Spring boot app that uses oauth2.0 and ssl.
I am using a zerossl signed certificate which is stored in /src/main/resources, and I've imported into the keychain in the project resources.
I am able to retrieve a token and call the /oauth/check_token endpoint manually, however when I try to hit any other endpoint I get the following error:
.o.s.r.w.BearerTokenAuthenticationFilter : Authentication request for failed!
org.springframework.security.authentication.AuthenticationServiceException: I/O error on POST request for "https://localhost:8443/oauth/check_token": PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;
nested exception is javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
application.properties:
# The format used for the keystore. It could be set to JKS in case it is a JKS file
server.ssl.key-store-type=PKCS12
# The path to the keystore containing the certificate
server.ssl.key-store=classpath:demo.p12
# The password used to generate the certificate
server.ssl.key-store-password=*****
# The alias mapped to the certificate
server.ssl.key-alias=demo
server.ssl.enabled=true
security.oauth2.resource.token-info-uri=https://localhost:8443/oauth/check_token
security.oauth2.client.registered-redirect-uri=https://localhost:8443/test
spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://localhost:8443/oauth/check_token
Stepping through the code it looks like when the NimbusOpaqueTokenIntrospector tries to check the token by calling POST https://localhost:8443/oauth/check_token it is not even hitting the endpoint (I placed a breakpoint in CheckTokenEndpoint controller) and getting the above KPIX error. I've tried using a custom RestTemplate that specifies the SSL context but I'm still seeing the same error.
If you are still struggling with this, I also experienced the same issue and also tried to install the Valid certificate into my JDK ca-certs. That was actually the correct solution except that even though both the RootCa and ActualDomain certs were installed as trusted certs in JDK ca-certs, there was an intermediate certificate issued just recently that I had left out. I installed the intermediate certificate as a trusted cert into the JDK ca-certs and the TLS certificate is no more.
RootCA=>!!!IntermediateCert!!!=>SubdomainCert
I'm using smtp.gmail.com:465 as the mail server for coldfusion. I used the command openssl s_client -connect smtp.gmail.com:465 to get its cert and import it into its Java truststore.
It works perfectly for awhile with no issues. Then after a random number of weeks it stops working and it gives this error:
javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 465; nested exception is: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
It works after grabbing the cert and importing it again.
It gets annoying that I have to keeping doing this.
Anyone know what might be causing the issue and a solution if possible?
After some digging, I realized that the java truststore (cacert) was missing all root CA certs including gmail's root CA. A found a list of common root CA certs including gmail's and import them into the truststore.
Recently the cert got expired both on Jenkins server (Linux) and IIS server (windows) and we have imported the new certs for both Jenkins and remote slave.
post that it was able to connect when we launch through browser (but pop up with java - (The certificate is not valid and cannot be used to verify the identity of this website) and if we install Jenkins as a service on windows machine it was in starting state (not proceeding with the Running state) and unable to start the Jenkins as slave in logs
i can see this error as following:
"Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"
Your certs are not correct. Make sure the values for CN and hostname on the cert you imported are the same as the old cert. Make sure you have the intermediate and root certificates imported/trusted as well, as those may have changed with the new certs.
Windows: certlm to check that the intermediate and root certificates are also trusted.
Currently I try to make a play application be able to communicate SSL encrypted with the database.
I created self-signed certificate and CA for mysql. There is no problem with that normally, I can make the application communicate with the db server encrypted, when I add this CA to the JAVA_OPTS
-Djavax.net.ssl.trustStore=/app/path/conf/truststore
Everything goes well until my application not tries to communicate with other sites via SSL:
java.net.ConnectException: General SSLEngine problem to https://api.twitter.com/1/statuses/oembed.json?<meh>
[...]
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
[...]
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
[...]
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
[...]
The error is pretty obvious: twitter's ssl cert cannot be checked, because my truststore doesn't contains the CA which signed twitters certificate. IIRC I cannot add more than one "javax.net.ssl.trustStore" parameter for JVM, so I have to inject my CA's into the play framework. For luck, play framework supports ssl, and regarding the documentation I can add multiple truststores: https://www.playframework.com/documentation/2.4.x/WsSSL
I created a config file for ssl:
play.ws.ssl {
trustManager = {
stores = [
{ path: /path/to/truststore, type: "JKS", password = "<whatever is it" }
{ path: ${java.home}/lib/security/cacerts } # Default trust store
]
}
But when I start the server, I got the following error message:
Oops, cannot start the server.
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
And now, I am stuck. I can inject my truststore for JVM, but when I do this, the app cannot communicate with other SSL enabled hosts - there's no cert, but when I try to add my truststore for play framework it doesn't accept it, because nobody signed my cert.
Is there a way to solve this somehow? I suspect if I take the system wide cacert file (which is used by java) and my truststore, and then I merge them with keytool, it will solve this, but this is not the best way - it would be more sane if I could pack my self signed certs next to the application.
I had the same problem for some reason my own trust store wouldn't be recognized so I ended up adding my certificate to the default keystore (${java.home}/lib/security/cacerts). You can use this command to do this (BTW cacerts default password is changeit):
keytool -v -importkeystore -srckeystore alice.p12 -srcstoretype PKCS12 -destkeystore "c:\Program Files\Java\jre1.8.0_71\lib\security\cacerts" -deststoretype JKS
Then you need to have the trustManager and the key manager defined. The trustManager points to the trust store and the keyManager to your certificate.
play.ws.ssl {
trustManager = {
stores = [
{
path: ${java.home}/lib/security/cacerts
}
]
}
keyManager = {
stores = [
{
type: "PKCS12",
path: "/Users/work/Documents/path/to/certificate/certificate.p12",
password: "pass"
}
]
}
}
That error means Play can't find the stores. Is the path correct?
I had the same error message: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty caused by empty store. According to Key store docs there could be password field in the configuration but it was ignored therefore certificates were not read from the store. I had to use PEM format or you can include certificates in config see Configure store. The password field is added/put back in commit #e867e729. I'm on Play 2.6 so I couldn't test it.
I had to enable SSL over Active Directory server, to do that I followed each and every steps mentioned here: http://www.linuxmail.info/enable-ldap-ssl-active-directory/
Now I am not sure if SSL is really enabled properly?
On server itself if I run ldp, I think I can connect on 636 port. However on my system I don't see SSL option on ldp client?
I've two other LDAP clients (Softerra LDAP Browser and Apache Directory Studio) but I am not able to connect using ldaps (on 636 port). I guess I'll need to import certificate used in AD server so these tools can trust that self sign certificate which I used on AD server.
Using Java code, I've added certificate into cacerts (got certificate using steps mentioned here: http://www.linuxmail.info/export-ssl-certificate-windows-2003/), however I still can't connect to AD using SSL.
I tried SSL as well as TSL:
TLS:
// got LdapContext using ldap (not with ldaps)
StartTlsResponse tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
It gives following exception:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
SSL:
String ldapURL = "ldaps://<domain-name>:636";
String keystore = "C:/Oracle/Middleware/jdk160_24/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore",keystore);
env.put(Context.SECURITY_PROTOCOL,"ssl");
// other properties are set in env
LdapContext ctx = new InitialLdapContext(env, null);
It gives following exception:
javax.naming.CommunicationException: <domain-name>:636 [Root exception is java.net.ConnectException: Connection timed out: connect]
Can anyone please suggest where I am wrong?
Thanks.
This one was fixed.
I was using wrong (rather incomplete) command to import certificate.
I was using:
keytool -import -alias mycert -keystore cacerts -file d:\mycert.cer
When I used follwing:
keytool -import -noprompt -trustcacerts -alias mycert -file c:/mycert.cer -keystore C:/Oracle/Middleware/jdk160_24/jre/lib/security/cacerts -storepass changeit
And it started working.
If you can't get TLS to work, it is unlikely that SSL will work. Are you sure that you got the right certificate and configured the keystore correctly? Based on the SSLHandshakeException when trying to use TLS, it would seem that may not be set up correctly.
Check out this SO answer for some tips on how to verify that your keystore is correctly set up: https://stackoverflow.com/a/9619478/1792088