I've search far and long and can't find the answer.
I'm using Glassfish and want to send an email via our smtp server.
I've obtained the server's certificate:
openssl s_client -connect mail.example.com:587 -starttls smtp > our.cer
I've cleaned up the cer file to only contain the certificate data.
I've import it everywhere:
keytool -import -alias mail.example.com -file our.cer -keystore c:\Progra~1\Java\jre7\lib\security\cacerts
keytool -import -alias mail.example.com -file our.cer -keystore c:\Progra~1\Java\JDK17~1.0_4\jre\lib\security\cacerts
keytool -import -alias mail.example.com -file our.cer -keystore c:\PROGRA~1\GLASSF~1.0\GLASSF~1\domains\domain1\config\cacerts.jks
But I get the following error:
javax.mail.MessagingException: Could not convert socket to TLS;
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
...
Caused by...
...
Caused by...
...
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
My code snippet:
...
Properties properties = System.getProperties();
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", "mail.example.com");
properties.put("mail.smtp.user", "[email protected]");
properties.put("mail.smtp.password", "some.password");
properties.put("mail.smtp.port", "587"));
properties.put("mail.smtp.auth", "true"));
properties.put("mail.smtp.from", "[email protected]"));
properties.put("mail.transport", "smtp"));
...
Authenticator mailAuthenticator = new Authenticator()
{
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(properties.getProperty("mail.smtp.user"),
properties.getProperty("mail.smtp.password"));
}
};
try
{
// Get the default Session object.
Session session = Session.getDefaultInstance(properties, mailAuthenticator);
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setSubject("Hallo world!");
mimeMessage.setFrom(new InternetAddress(properties.getProperty("mail.smtp.from")));
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("[email protected]"));
mimeMessage.setText("Some text message...");
Transport transport = session.getTransport(properties.getProperty("mail.transport"));//"smtp"
int port = Integer.parseInt(properties.getProperty("mail.smtp.port"));//587
transport.connect(properties.getProperty("mail.smtp.host"),//"mail.example.com"
port,
properties.getProperty("mail.smtp.user"),//"[email protected]"
properties.getProperty("mail.smtp.password"));//Clear text password
transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
LOG.info("...done sending email");
}
catch (AddressException e)
{
LOG.log(Level.SEVERE, "Error while sending email", e);
}
catch (MessagingException e)
{
LOG.log(Level.SEVERE, "Error while sending email", e);
}
catch (Exception e)
{
LOG.log(Level.SEVERE, "Error while sending email", e);
}
I've also tried Mkyong's suggestion to run InstallCert (source) against the mail server but I get:
javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
UPDATE 1
I've loaded the certificate in the following additional places:
keytool -import -alias mail.example.com -file our.cer -keystore c:\PROGRA~1\GLASSF~1.0\GLASSF~1\domains\domain1\config\keystore.jks
keytool -import -alias mail.example.com -file our.cer -keystore c:\GLASSFISH\config\keystore.jks
keytool -import -alias mail.example.com -file our.cer -keystore c:\GLASSFISH\config\cacerts.jks
I've also set these properties:
System.setProperty("javax.net.ssl.keyStore", "c:\\GLASSFISH\\config\\keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStore", "c:\\GLASSFISH\\config\\cacerts.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
I've also switched on debugging for ssl (Glassfish console, server, properties) javax.net.debug=ssl.
It works in a standalone test application (Java SE) but not in Glassfish.
UPDATE 2
Using the javax.net.debug=ssl and examining the log out put I can see that even-though I've loaded the certificate "everywhere" or if I point Glassfish to the java keystore, Glassfish is missing this certificate. The stand alone test app has it:
adding as trusted cert:
Subject: CN=avast! Web/Mail Shield Root, O=avast! Web/Mail Shield, OU=generated by avast! antivirus for SSL/TLS scanning
Issuer: CN=avast! Web/Mail Shield Root, O=avast! Web/Mail Shield, OU=generated by avast! antivirus for SSL/TLS scanning
Algorithm: RSA; Serial number: 0x14128fa09c50b64ba6d5c99875872673
Valid from Wed Feb 04 08:56:17 CAT 2015 until Sat Feb 01 08:56:17 CAT 2025
(Note the Serial number...)
It seems to be the certificate missing from Glassfish; because the stand alone test app finds it:
Found trusted certificate:
[
[
Version: V3
Subject: CN=avast! Web/Mail Shield Root, O=avast! Web/Mail Shield, OU=generated by avast! antivirus for SSL/TLS scanning
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 2048 bits
modulus: ---8<---
public exponent: 65537
Validity: [From: Wed Feb 04 08:56:17 CAT 2015, : Sat Feb 01 08:56:17 CAT 2025]
Issuer: CN=avast! Web/Mail Shield Root, O=avast! Web/Mail Shield, OU=generated by avast! antivirus for SSL/TLS scanning
SerialNumber: [ 14128fa0 9c50b64b a6d5c998 75872673]
...
(Look at the SerialNumber...)
Please help
Okey dokey! I've figured it out. Here is how my 5 day journey ended today, in brief...
First I dumped all the certificates from the Java keystore, as it was working using that keystore:
keytool -list -v -keystore c:\Progra~1\Java\jre7\lib\security\cacerts > allJavaCerts.txt
Then I dumped all the certificates from the Glassfish keystore, to see if the certificate was correctly imported:
keytool -list -v -keystore c:\WORKSP~1\GLASS\config\cacerts.jks > allGFCerts.txt
In the Java keystore list I notice that the mail server's certificate was issued by Avast... weird, right?
Issuer: CN=avast! Web/Mail Shield Root, O=avast! Web/Mail Shield, OU=generated by avast! antivirus for SSL/TLS scanning
And in the Java keystore list there is a certificate for Alias name: avastsslscannerroot but not in the Glassfish keystore list - Thank you Beyond Compare v3
So I exported the avastsslscannerroot certificate from the Java keystore and import it into the Glassfish keystore:
keytool -export -keystore c:\Progra~1\Java\jre7\lib\security\cacerts -alias avastsslscannerroot -file avastsslscannerroot.cer
keytool -import -alias avastsslscannerroot -file avastsslscannerroot.cer -keystore c:\WORKSP~1\GLASS\config\keystore.jks
keytool -import -alias avastsslscannerroot -file avastsslscannerroot.cer -keystore c:\WORKSP~1\GLASS\config\cacerts.jks
And now it works...
And then it didn't on the server... After some search I came across this:
mail.smtp.ssl.trust="*"
Property and it works for us as we are connection from our web server to our mail server...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With