Error: SSL certificate problem: unable to get local issuer certificate

One of the most common issue with TFS/GIT users come across is the issue caused by self-signed certificates or the corporate certificates.
Error: SSL certificate problem: unable to get local issuer certificate

This Applied to:
TFS 2015 update 3Git 2.10.0Android studio 2.1.2Java 1.7.45

We used Android studio and VSTS/TFS plugin to clone a GIT repository, we faced issues in retrieving the local issuer certificate. These are certificates that have not been signed by a known trusted certificate authority. The problem is that GIT/JAVA will not accept this certificate automatically. We need to force GIT/JAVA to accept the self-signed certificates.

Let’s now consider how to go about with the resolution,

Initially, we faced issues with TFS authentication,

Unable to authenticate to TFS 'https://server:8080/tfs". verify access to the server URL and try 'Connect...' again. 2016-12-12_20h08_38

Very often this error can be interpreted to be the result of self-signed certificate.  If the certificate in use is Self-signed or any other certificate that is private to the internal network. Java doesn’t trust such certificates and for which, we can import the cert into the trust store and make it to work.

The link explains how the certificate import works in a Linux machine (which is also applicable for Windows).

the “keytool” is under “ <JAVA_HOME>\bin\keytool.exe”, and

the “cacerts” trust store is under “ <JAVA_HOME>\jre\lib\security\cacerts”.

<JAVA_HOME> should be the jre/jdk installation used by IntelliJ.

This should have resolved the above TFS connectivity failure.

Note:

If you are using self-signed certificate, you may not be able to connect to TFS from the plugin

Error message: Caused by: javax.net.ssl.SSLPeerUnverifiedException: Host name 'server' does not match the certificate subject provided by the peer (CN=server.corp.fabricam.com)

Providing the complete FQDN(https://server.corp.fabricam.com/tfs) instead of the server or the machine name (https://server/tfs) is mandatory as the canonical name is set to map to the FQDN.

After getting past the connectivity issue, there are instances in which we get error like the one below:

SSL certificate problem: unable to get local issuer certificate

In the android logs,

#git4idea.commands.GitHandler - fatal: unable to access ' https://server/tfs/DefaultCollection/_git/gitRepo/ ': SSL certificate problem: unable to get local issuer certificate

Exception : javax.ws.rs.ProcessingException: 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

at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:498)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:225)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:655)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:652)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:423)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:652)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:387)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:291)
at com.microsoft.alm.plugin.context.rest.VstsHttpClient.sendRequest(VstsHttpClient.java:30)
at com.microsoft.alm.plugin.context.ServerContextManager.checkTfsVersionAndConnection(ServerContextManager.java:257)
atcom.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:206)              at com.microsoft.alm.plugin.context.ServerContextManager.validateServerConnection(ServerContextManager.java:171)
at com.microsoft.alm.plugin.idea.common.services.CredentialsPromptImpl.validateCredentials(CredentialsPromptImpl.java:68)
atcom.microsoft.alm.plugin.authentication.TfsAuthenticationProvider$TfsAuthenticator.run(TfsAuthenticationProvider.java:100)

There are 2 methods of dealing with this issue.

1.Disable SSL verification using below command,

git config --global http.sslVerify false

NOTE:
If you disable SSL certificates verification, then you are susceptible to Man in middle attacks.

2.The preferred method is import certificate authority (CA) to trusted certificate authority store.
If we can verify that disabling SSL verification works, then this article may help:

https://blogs.msdn.microsoft.com/phkelley/2014/01/20/adding-a-corporate-or-self-signed-certificate-authority-to-git-exes-store/

But, in case if the article doesn’t help,
Try exporting the certificate in all the levels again, following the instructions on the blog.

Test certificates with curl.exe, to check if the SSL handshake is successful.

"c:\Program Files\Git\mingw64\bin\curl.exe" -v https://server-name -cacert c:\path\to\cert\file.cer

Now, import the certificate into the Git.exe cert store as we did before (also from blog). After importing the certificate, GIT clone’s files from the master branch.

For the complete encryption and the decryption, import the certificate into the Java cert store for Android Studio.

JRE that is now packaged with Android Studio 2.2. You can find it at the root of the Android Studio folder. “C:\program files\Android\Android Studio\jre”

Hope this helps!

Content: Ramandeep Singh
Review: Romit Gulati