Spring Security with LDAP over SSL: need more details - ssl

I've got web application that uses authentification via LDAP. It works flawlessly, but production version is required to use SSL. We have a server running at "ldaps://ourserver.com:636", but Spring Security throws following exception when I try to connect to it:
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 targe
Apache Directory Studio also warns me about unknown certificate, but allows to ignore the check it and eventually to connect and read the data required.
There are plenty of questions and answers here about how to implement LDAP over SSL, but no one of them provide full solution. I've got two opportunities: to make the certificate trusted or to disable certificate check at all. No matter which way I choose, I can't figure out how to use the mechanism with Spring Security:
If I choose to use keytool and make the certificate trusted, I can't figure out how JVM / Tomcat / Spring Security will figure out which password I have defined (-keypass changeit).
If I choose to disable the certificate validation, I can't figure out what is the place the code should be placed.
I'm also curious on how Apache Directory Studio is able to make the certificate trusted for itself without that keytool import - which significantly reduces application portability? Solution like that would be perfect for my webapp, but I haven't found anything like that all.

Here is a solution I was able to use. The key thing I had to understand is that neither JVM, nor container with webapp needs to know alias and password. It's JVM headache to check all the certs registered, and this has nothing to do with your webapp. Unfortunately, the solution implies that you install the certificate for the whole JVM. That makes webapp less portable, but at least it works correctly. I've decided to provide following bash script with the webapp sources so other developers can install the cert easily on their machines:
SERVER="mydomain:636"
CRT_NAME="mydomain.crt"
CRT_ALIAS="mydomain_cert"
echo -n | openssl s_client -connect $SERVER | sed -ne '/-BEGIN
CERTIFICATE-/,/-END CERTIFICATE-/p' > $CRT_NAME
$JAVA_HOME/bin/keytool -import -alias $CRT_ALIAS -keystore $JAVA_HOME/lib/security/cacerts -file $CRT_NAME -storepass changeit
You may wish to add additional error checks, I've omitted them to simplify the script. You will need root priviledges to launch the second command.

Related

Jenkins doesn't connect to Internet (SSL trouble)

Error message: SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I been trying to configure the proxy correctly but some http servers respond with success, meanwhile all the https doesn't.
I installed all the necessary plugins manually for run a sample pipeline but the error in console output is just a nested page 404 by jenkins.
It's important to know that my OS have the cli internet connection blocked for security terms.
This is the last followable trouble that I have, but I'm a little bit confusing with the SSL cert, I tried to resolve it by this post but is not clear to me which SSL cert I have to download and if this could cause troubles with my PC restrictions.
One solution to resolve this issue is change the update url at management plugins > advanced setting > url update from this
https://updates.jenkins.io/update-center.json
to this
http://updates.jenkins.io/update-center.json
this solutions is not definitive and i won't recommend it.
Actually i solve this problem loading the plugins.jenkins.io cert to the javas's keystore using
.\keytool.exe -import -alias {alias} -keystore %JAVA%\lib\security\cacerts -file \path\to\your\cert
(Be sure than you are not overwritting anything and the password for -import param by default is changeit)

LDAPS Microsoft Active Directory Multiple Certificates RFC6125

We have an Microsoft Active Directory Domain with a large pool of domain controllers (DC) that are are setup with LDAP. These are all setup with LDAPS and uses Certificate Services via a template to setup a certificate with the domain name (i.e. test.corp) in the Subject Alternate Name (SAN) for the LDAPS server to serve.
Since these are DC's, DNS is setup in a pool for each these systems to respond to requests to test.corp in a round robin fashion.
Each of these DC's have multiple templates and multiple certificates in the Local Computer\Personal Certificate Store.
Upon testing, using a nodejs module, ldapjs when making a LDAPS request using the domain name, test.corp we notice that a handful of servers fail with the following message:
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match
certificate's altnames: Host: test.corp. is not in the cert's
altnames: othername:, DNS:.test.corp
As we investigated we found that these handful of LDAPS servers are serving the incorrect certificate. We determined this by using the following command
openssl s_client -connect .test.corp:636
If you take the certificate section of the output and put it in a file and use a tool such as the Certificate manager or certutil to read the file, you can see the certificate is not the correct one. (It does not have the domain "test.corp" SAN). We also verified this by comparing the Serial Numbers
As we investigated, since we have DC's that have multiple certificates in the Local Computer\Personal Certificate store, we came across the following article:
https://social.technet.microsoft.com/wiki/contents/articles/2980.ldap-over-ssl-ldaps-certificate.aspx
It suggests putting the certificate from the local computer\Personal certificate store to the Active Directory Domain Service\Personal store. We followed the steps outlined but we found the same results.
Upon further investigation, it was suggested to use a tool called ldp or adsiedit. We then proceeded to use these tools and spoofed the local machine's host file we were doing the test from, to point the domain (test.corp) to the ip's of one of the DC's that are giving us trouble. After a restart to clear any cache we tested the "ldp" and "adsiedit" tools to connect to test.corp. These systems did not report any errors.
We found this odd, we then ran the openssl command to see what certificate it was serving from this same system and we found it was still serving the incorrect certificate.
Upon further research, it appears that the "ldp" upon selecting the SSL checkbox and "adsiedit" tools were not compliant with RFC6125, specifically B.3
https://www.rfc-editor.org/rfc/rfc6125#appendix-B.3
, which basically states the identity of the certificate must match the identity of the request otherwise the handshake would fail. This identity verification is done by using the certificate common name (CN) or the SAN.
Based on this appears the tools "ldp" and "adsiedit" are not conforming to the RFC6125 standard.
All this to say, we need to first fix the handful of domain controllers that are serving the correct certificate. We are open to suggestions since we have been working on this problem for the past few months. Second, is there a way to get the MS tools in question to work to the RFC6125 standard?
This has been moved to:
https://serverfault.com/questions/939515/ldaps-microsoft-active-directory-multiple-certificates-rfc6125
RFC6125 specifically states that it does not supersede existing RFCs. LDAP cert handling is defined in RFC4513. Outside of that, RFC6125 has significant flaws. See also https://bugzilla.redhat.com/show_bug.cgi?id=1740070#c26
LDP will supposedly validate the SSL against the client store if you toggle the ssl checkbox on the connection screen.
That said, I'm not surprised that neither it nor ADSI edit enforce that part of the standard given they are often used to configure or repair broken configurations. Out of the box and without Certificate Services they use self signed certs on LDAPS. I would wager 80% of DCs never get a proper certificate for LDAP. If they enforced it most wouldn't be able to connect. A better design decision would have been to toggle off the validation.
I use a similar openssl command to verify my own systems. I think it's superior to LDP even if LDP were to validate the certificate. To save you some effort, I would suggest using this variant of the openssl command:
echo | openssl s_client -connect .test.corp:636 2>/dev/null | openssl x509 -noout -dates -issuer -subject -text
That should save you having to output to a file and having to read it with other tools.
I've found LDAPS on AD to be a huge pain for the exact reasons you describe. It just seems to pick up the first valid cert it can find. If you've already added it to the AD DS personal store, I'm not sure where else to suggest you go other than removing some of tother certs from the DCs computer store.

leiningen: How do I turn off ssl verification?

I'm a first-time leiningen user on Windows. When I run lein run I get the following error:
C:\Users\me\clojure-app>lein run
Could not transfer artifact org.clojure:clojure:pom:1.7.0 from/to central (https://repo1.maven.org/maven2/): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Could not transfer artifact org.clojure:tools.nrepl:pom:0.2.10 from/to central (https://repo1.maven.org/maven2/): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Could not transfer artifact clojure-complete:clojure-complete:pom:0.2.3 from/to central (https://repo1.maven.org/maven2/): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
This could be due to a typo in :dependencies or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
My http_proxy and https_proxy environment variables are indeed set properly.
I'm behind a corporate firewall that re-signs web traffic with its own SSL certificates, which I suspected could be the root of my issues. However, I set my HTTP_CLIENT environment variable to:
curl --insecure -f -L -o
...to avoid SSL verification (as suggested by this note in the installation help) but that did not change the error message.
So, my root question, I suppose is: what steps must a user take to get lein run to successfully bring down dependencies on a Windows machine that is behind a corporate firewall that re-signs SSL traffic? :o)
Here are some options in inverse order of crazyness (least crazy first)
Add you companies proxy to your trust store, and don't do anything special in Leiningen that you will have to remember to do again the next time you change projects or computers. You may also need to add it to the Java JVM's certificate store in addition to the systems (this is very likely your problem)
Add you companies proxy certificate to the project's project.clj's :certificate section This way if the certificate needs to be changed than only one person needs to change it and the whole team will get the benefit.
Many companies have an internal caching maven proxy such as Nexus that will automatically fetch and cache dependencies and then make them quickly available to people inside the network. Find out if you have one of these by asking around or looking in .pom file on Java projects for the config.
Go home, or to a local coffee shop, download the dependencies, and then come back to the office. A walk and some fresh air is always good after dealing with TLS certs anyway.
Download the file manually, with your browser and put them in the .m2 directory yourself.
I'm really trying to not be snooty, by omitting an answer to your actual question. I do realize that there is not an option to disable security on this list. That's on purpose because one of there options will surely work and will make your life much better for knowing how to use these. If it still comes across as pretentious then please accept my most sincere apology along with the answer.
To elaborate on Arthur's answer and save a trip to google for the command:
To add the certificate to the JRE's truststore, use this keytool command:
keytool -import -trustcacerts -file CompanyMitmProxyCertificate.crt -alias ZScaler -keystore cacerts
Where: "CompanyMitmProxyCertificate.crt" is the certificate for your company's man-in-the-middle-attack cert and 'cacerts' is the keystore for your jre located under "\lib\security". The default password for the keystore is 'changeit'.

soapui WSDL error when adding

I keep getting this error when adding this. Any ideas. I worked on other WSDL links and they are fine except this.
org.apache.xmlbeans.XmlException: 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
The WSDL is on https, so you need to add the domain certificate to your cacerts on JRE which comes with SOAPUI installation (also could be probably that wsdl is published also on http so you can try to change the url for wsdl to http, first try this if not try steps below).
You have to download the server certificate (you can connect with the browser to the url of wsdl and save the certificate as an archive).
Then you can import this cert to your cacerts with keytool:
keytool -import -alias somealias -file serverCertificate.cer -keystore SOAPUI_HOME/jre/lib/security/cacerts
(default password for cacerts is "changeit").
With this steps you can use the WSDL and avoid the "PKIX path building failed" exception.
Hope this helps,
The Problem with the SOAP UI is it's using it's won JRE to execute programs...
To resolve the above exception follow the below steps.
Export the certificate from the key store or browser (which contain the public key)
Go to the SOAPUI installed directory and locate following directory \SmartBear\soapUI-4.0.1\jre\lib\security
Import the certificate in to cacerts trust store (Which is the default trust store)
Restart the SOAP UI and load the WSDL...
This appears to be a bug in SoapUI (at least as of 4.6.4). I just ran into the same issue and after making sure I had all of the CA certificates imported everywhere I found this post that mentions the same problem.
I installed the nightly build as mentioned in the post and I was able to get past the SSL handshake issue.
There is a sly detail here:
The SOAPui calls wsimport command with an OS system call to wsimport program. It does not load internal class com.sun.tools.internal.ws.WsImportto do the WSDL import.
If you are running SOAPui with the default JRE that comes with it but you also have a different JDK installed, then when using SOAPui tools to generate code, the wsimport command used is the one the OS knows better from the PATH and not the com.sun.tools.internal.ws.WsImport that comes with SOAPui.
In this case the called wsimport will not references the embedded cacerts in SOAPUI_HOME\jre\lib\security .
Instead it utilizes the default cacerts of the JDK the wsimport belongs.
SOAPui uses wsimport from a JDK as this picture shows
In that case the steps you have to follow are:
Download and save the serverĀ“s certificate to a file, say srv-certificate.txt
Import this certificate to the cacerts of the JDK used by the SOAPui tools:
C:\>keytool -import -alias somealias -file cmq-certificates.txt -keystore C:\software\jdk1.8.0.65\jre\lib\security\cacerts
where jdk1.8.0.65 is the JDK used by the SOAPui tools.
Hope it helps!
I've had the same problem (working with profesionnal computer behind a corporate proxy) :
It appeared that I just had to set proxy in SoapUI to None to solve it (neither manual - cntlm, in my case - nor automatic - windows settings, corporate proxy - did work :-/) !...

Coldfusion: CFHTTP with SSL encrypted Page (https://) - got an error

I'm making an cfhttp to connect to an encrypted page. Seems to work fine for some sites.
I/O Exception: Name in certificate `pro.test.com' does not match host name `go.test.com'
Is there a workaround to trust this certificate even if the host name doesn't match?
Think this is more Java question, and workaround should be affecting the JRE.
Not sure if this will work in your case, but possible solution is to import this certificate into the JRE keystore.
Generic description can be found at Sun website. Though process is pretty simple.
First you should navigate the needed HTTPS URL with your browser and export the cert using SSL properties (don't remember how it is done in IE, but in Firefox something like Security > View cert > Details > Save as -- still not sure because using non-English licalization), any X.509 type should work.
Next you should import it using keytool. Navigate to the current CF JRE's bin, execute the following command (replace arguments with your values) and restart CF:
keytool -keystore <path to keystore> -import -file <path to certificate> -alias <alias>
BTW, there is a UI tool for this, but I haven't used it so can't say if it works fine.
The sites that are probably working have a valid SSL Certificate from a trusted authority.
If you have control of pro.test.com, the preferred answer would be to get a valid cert for pro.test.com installed. But if that is not possible for some reason, I see two other options:
1) Do a try/catch where you try to connect via https, and fall back on http in the event of an SSL error. Obviously this would eliminate encryption for the failed connection.
or
2) Use Sergii's solution to import the key for that site into the Java keystore.
If go.test.com is just a development server, in that case you can create a self-signed certificate and import it into Java keystore. That way you can save up on cost by not paying to CA and get a quicker turnaround to resolve the issue