Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Gmail (or a secure website) without getting a PKIX certification path error

Sending an e-mail via gmail resulted in getting a PKIX certification path error. The same applied to sending an e-mail from Tomcat.

After solving the issue, I hope you find this post useful. This post provides you with a step by step diagnosis for these kinds of errors.

Step 1: I tried to solve the problem using this post and another post, but that did not help me. In most cases this will be sufficient. You can use the keytool to list the certificates via 'keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"'

I added the certificate by clicking the lock-icon of the gmail URL and exporting/importing the certificate to the cacert file of my used JDK version. I could see with keytool -list that the certificate was added. This process is described well in the (linked) posts.

Step 2A: Was I using the right truststore? I added the JVM arguments to direct the certificate search, like -Djavax.net.ssl.trustStore="..../jre/lib/security/cacerts" -Djavax.net.ssl.trustStorePassword="changeit".

Step 2B: When I change the value of the cacerts file to cacertsXYZ I get the error. So, this proofed that the 'cacert' was used.

Caused by: javax.mail.MessagingException: Can't send command to SMTP host; nested exception is: javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

Step 2C: Was this also the case for my Tomcat webserver? I verified that in the cacerts of my JRE_HOME that the certificate was there. In Tomcat my JRE_HOME is "C:\Program Files\Java\jdk1.8.0_144\jre". My JAVA_HOME = C:\Program Files\Java\jdk1.8.0_144.

Step 3: I tried with publicly available 'SSLPoke' Java class to see whether I could connect with Google and or smtp.gmail.com. The results are in the listing: I could connect with SSL to google.com AND mail.google.com via port 443.

try {
            SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            // **Fail** TLS - SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("smtp.gmail.com", 587);
            // **Fail** SSL - SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("smtp.gmail.com", 465);
            // **OK**
            SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("google.com", 443);
            // OK
            SSLSocket sslsocket2 = (SSLSocket) sslsocketfactory.createSocket("mail.google.com", 443);

            InputStream in = sslsocket.getInputStream();
            OutputStream out = sslsocket.getOutputStream();
            out.write(1); // write test byte to get reaction.
            while (in.available() > 0) {
                System.out.print(in.read());
            }
            System.out.println("Successfully connected");
        } catch (Exception exception) {
            exception.printStackTrace();
        }

Step 4: The trusted store could be corrupt? I installed a newer version of the JDK1.8 being v152. I restarted the application without any success. Had this to do with the difference between JDK and JRE? Only the JRE has a lib\security\cacerts file. I tried both the SSL (465) and TLS (587) ports. Nope.

Step 5: Running openssl (with s_client -connect smtp.gmail.com:587 -starttls smtp) showed that my virus scanner (Avast) was prohibiting the sending of secure mail. So, for a moment I disabled this email-shield. That gave the following error:

java.lang.RuntimeException: javax.mail.AuthenticationFailedException

Step 6: After releasing the virusscanner web shield, using the openssl gave the following error: CN = Google Internet Authority G3 verify error:num=20:unable to get local issuer certificate.

OpenSSL> s_client -connect smtp.gmail.com:587 -starttls smtp CONNECTED(00000280) depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3 verify error:num=20:unable to get local issuer certificate ....

Allowing the 'gmail account to be accessable from weakly authenticated apps', a setting in your google account, that finally yielded in correctly sending the e-mail. This is the link to the security settings of your Google account.

Step 7: Sending e-mail from another server may be a problem. Authentication errors are (still) the result. To overcome these errors, you can do:

  • Check whether a two-step verification is turned OFF (Google settings).
  • Allow access to the Google account from https://accounts.google.com/b/0/DisplayUnlockCaptcha

Notice: The mkyong example is the base of my simple test application.

like image 657
tm1701 Avatar asked Dec 02 '17 16:12

tm1701


1 Answers

Finally I found the answer.

1 - Of course the google/gmail certifcates were ok ;-) Step 1 was performing these kinds of checks. Trying to add the certificate CA by hand, etc. See above.

2 - Step 2 was checking whether the known 'SSLPoke' Java class Java class could get contact with the secure website.

3 - After checking all above checks, executing 'openssl' showed that my virus scanner email-shield blocked the traffic. Stopping this defence for some time was step 3.

4 - Then I got the 'not authenticated' error from Gmail. Allowing the 'gmail account accessable from weakly authenticated apps', that finally gave a correctly sent e-mail. This is an Google account security setting

like image 85
tm1701 Avatar answered Dec 28 '22 06:12

tm1701