0

On my application, the org.springframework.mail.javamail.JavaMailSenderImpl is not configured to send SSL emails (The default value as per https://javamail.java.net/nonav/docs/api/com/sun/mail/smtp/package-summary.html is false).

That being said, I have two types of emails being sent through this JavaMail API, one is prepared a multipart/relative and the other is plain text. Both the emails are successfully sent when deployed on our dev server. But the multipart email fails to be sent on another dev server (A stage server).

The application is deployed on Tomcat6 and runs on JDK 1.6.

I debugged all the private keys and certificates available in the keystore configured for the tomcat server (The web application runs on HTTPS). This looks good (I explored the option of replacing the keystore too).

Now when I send the email, The mail that fails has the below debug from java mail API

DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "8570-5cb30915t8.tb.bbossyyy.com", port 25, isSSL     false
220 8570-5CB30915T8.TB.bbossyyy.com ESMTP SubEthaSMTP null
DEBUG SMTP: connected to host "8570-5cb30915t8.tb.bbossyyy.com", port: 25

EHLO hqarchs01
250-8570-5CB30915T8.TB.bbossyyy.com
250-8BITMIME
250-AUTH LOGIN
250 Ok
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN"
DEBUG SMTP: Found extension "Ok", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<dfn@bbossyyy.com>
250 Ok
DEBUG SMTP: sendPartial set
RCPT TO:<rp@bbossyyy.com>
250 Ok
RCPT TO:<rp@bbossyyy.com>
250 Ok
RCPT TO:<archo@bbossyyy.com>
250 Ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   RP <rp@bbossyyy.com>
DEBUG SMTP:   RP <rp@bbossyyy.com>
DEBUG SMTP:   archo@bbossyyy.com
DATA
354 End data with <CR><LF>.<CR><LF>
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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)

Now for a successful send, below is are the debug statements

DEBUG: getProvider() returning    javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "8570-5cb30915t8.tb.bbossyyy.com", port 25, isSSL     false
220 8570-5CB30915T8.TB.bbossyyy.com ESMTP SubEthaSMTP null
DEBUG SMTP: connected to host "8570-5cb30915t8.tb.bbossyyy.com", port: 25

EHLO hqarchs01
250-8570-5CB30915T8.TB.bbossyyy.com
250-8BITMIME
250-AUTH LOGIN
250 Ok
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN"
DEBUG SMTP: Found extension "Ok", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<archo@bbossyyy.com>
250 Ok
DEBUG SMTP: sendPartial set
RCPT TO:<jmi@bbossyyy.com>
250 Ok
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   John Mirabile <jmirabile@bbossyyy.com>
DATA
354 End data with <CR><LF>.<CR><LF>
Date: Wed, 4 Jun 2014 18:06:15 -0400 (EDT)
From: ArchO <archo@bbossyyy.com>
To: JM <jm@bbossyyy.com>
Message-ID: <1680495420.11401919575021.JavaMail.svcaoadmin@hqarchs01>
Subject: PO # 88636 Approval
MIME-Version: 1.0
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<html>
  <head>
  <title>PO Approval</title>
  <style>
  * {
      font-family:Tahoma,Arial,Verdana,Helvetica,sans-serif;
      font-size:10pt;
  }
  </style>
  </head>
  <body>
    ------------------------------
  </body>
</html>
.
250 Ok
QUIT
221 Bye

Further, the exception being thrown is a org.springframework.mail.MailSendException and the nested cause is the usual SSL handshake exception stuff

    Caused by: 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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
        at java.net.URL.openStream(Unknown Source)
        at javax.activation.URLDataSource.getInputStream(Unknown Source)
        at javax.activation.DataHandler.writeTo(Unknown Source)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:845)
        at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:361)
        at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:85)
        at javax.activation.ObjectDataContentHandler.writeTo(Unknown Source)
        at javax.activation.DataHandler.writeTo(Unknown Source)
        at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
        at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1683)
        at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:585)
        ... 77 more
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target    
        at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
        at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
        at sun.security.validator.Validator.validate(Unknown Source)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
        ... 101 more
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target  
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
        at java.security.cert.CertPathBuilder.build(Unknown Source)
        ... 107 more

I also retrieved the AdjacencyList from sun.security.provider.certpath.SunCertPathBuilderException to retrieve the sun.security.provider.certpath.BuildStep and printed the certificate details using getCertificate() method. The certificate was a valid one as per the keystore configured with Apache Tomcat server. below are some details from the debug

    DEBUG :BS getFullString  :Certificate to be tried.
    Issuer:     CN=bbossyyyIssuingCA, DC=bbossyyy, DC=bbosstest, DC=com
    Subject:    
    SerialNum:  152a754f000000001177
    Expires:    Fri Apr 22 11:23:39 EDT 2016
    SubjKeyID:  KeyIdentifier [
    0000: 6D E0 32 B3 9E 7C 14 C3   14 B6 63 55 7F C7 4C CB  m.2.......cU..L.
    0010: 2C 48 F6 DC                                        ,H..
    ]
    AuthKeyID:  KeyIdentifier [
    0000: B8 21 48 97 A2 7B 0A A2   03 6F 35 4C 9D DB 38 AE  .!H......o5L..8.
    0010: 6E 3A 6B B6                                        n:k.
    ]
    Exception:  null
    Index:      1

    DEBUG :BS getIssuerName : CN=bbossyyyIssuingCA, DC=bbossyyy, DC=bbosstest, DC=com
    DEBUG :BS verboseToString : Certificate to be tried.
    Certificate contains:
    Issuer:     CN=bbossyyyIssuingCA, DC=bbossyyy, DC=bbosstest, DC=com
    Subject:    
    SerialNum:  152a754f000000001177
    Expires:    Fri Apr 22 11:23:39 EDT 2016
    SubjKeyID:  KeyIdentifier [
    0000: 6D E0 32 B3 9E 7C 14 C3   14 B6 63 55 7F C7 4C CB  m.2.......cU..L.
    0010: 2C 48 F6 DC                                        ,H..
    ]
    AuthKeyID:  KeyIdentifier [
    0000: B8 21 48 97 A2 7B 0A A2   03 6F 35 4C 9D DB 38 AE  .!H......o5L..8.
    0010: 6E 3A 6B B6                                        n:k.
    ]

    DEBUG :BS getSigAlgName : SHA256withRSA
    DEBUG :BS getSigAlgOID : 1.2.840.113549.1.1.11
    DEBUG :BS getType : X.509
    DEBUG :BS getIssuerAlternativeNames : null
    DEBUG :BS getNonCriticalExtensionOIDs : [2.5.29.14, 1.3.6.1.4.1.311.21.10, 1.3.6.1.4.1.311.21.7, 1.3.6.1.5.5.7.1.1, 2.5.29.31, 2.5.29.37, 2.5.29.35]
    DEBUG :BS getNotAfter : Fri Apr 22 11:23:39 EDT 2016
    DEBUG :BS getNotBefore : Wed Jun 04 16:34:29 EDT 2014
    DEBUG :BS getVersion : 3

I need your help in beating this issue. Request your thoughts on this.

EDIT..............

Due to further learning and comments, re-posting as below Im attempting to send emails with INLINE images from a Apache Tomcat server 6.0 configured for HTTPS. The target SMTP server doesnt have a valid certificate from a trusted CA.

Now, Im able to send the emails WITHOUT attachments successfully to the server and I'm also able to send the emails with attachments when running on HTTP (non secure). But, Im unable to send emails from HTTPS configuration of tomcat to the smtp server.

I'm using Spring's JavaMailSenderImpl for sending the emails. The bean configuration of Mailsender is as below

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
  <property name="host"><value>${smtp.server}</value></property>
  <property name="javaMailProperties">
      <props>
          <prop key="mail.smtp.sendpartial">true</prop>
          <prop key="mail.debug">true</prop>
      </props>
  </property>
</bean>

As you can see below, the exception is created as soon as the client starts sending data to the server

    DEBUG: JavaMail version 1.4ea   
    DEBUG: java.io.FileNotFoundException: C:\Program Files\Java\jre6\lib\javamail.providers (The system cannot find the file specified) 
    DEBUG: !anyLoaded   
    DEBUG: not loading resource: /META-INF/javamail.providers   
    DEBUG: successfully loaded resource: /META-INF/javamail.default.providers   
    DEBUG: Tables of loaded providers   
    DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc]}  
    DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun Microsystems, Inc], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun Microsystems, Inc], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun Microsystems, Inc], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]}    
    DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map 
    DEBUG: !anyLoaded   
    DEBUG: not loading resource: /META-INF/javamail.address.map 
    DEBUG: java.io.FileNotFoundException: C:\Program Files\Java\jre6\lib\javamail.address.map (The system cannot find the file specified)   
    DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]    
    DEBUG SMTP: useEhlo true, useAuth false 
    DEBUG SMTP: trying to connect to host "appsmtp.bobbsincyyy.com", port 25, isSSL false   
    220 hqxhubp15.fb.bobbsincyyy.com Microsoft ESMTP MAIL Service ready at Thu, 5 Jun 2014 13:47:10 -0400   
    DEBUG SMTP: connected to host "appsmtp.bobbsincyyy.com", port: 25   

    EHLO hqarchd01  
    250-hqxhubp15.fb.bobbsincyyy.com Hello [172.25.14.13]   
    250-SIZE 219901952  
    250-PIPELINING  
    250-DSN 
    250-ENHANCEDSTATUSCODES 
    250-AUTH    
    250-8BITMIME    
    250-BINARYMIME  
    250-CHUNKING    
    250-XEXCH50 
    250 XSHADOW 
    DEBUG SMTP: Found extension "SIZE", arg "219901952" 
    DEBUG SMTP: Found extension "PIPELINING", arg ""    
    DEBUG SMTP: Found extension "DSN", arg ""   
    DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""   
    DEBUG SMTP: Found extension "AUTH", arg ""  
    DEBUG SMTP: Found extension "8BITMIME", arg ""  
    DEBUG SMTP: Found extension "BINARYMIME", arg ""    
    DEBUG SMTP: Found extension "CHUNKING", arg ""  
    DEBUG SMTP: Found extension "XEXCH50", arg ""   
    DEBUG SMTP: Found extension "XSHADOW", arg ""   
    DEBUG SMTP: use8bit false   
    MAIL FROM:<df@bobbsincyyy.com>  
    250 2.1.0 Sender OK 
    DEBUG SMTP: sendPartial set 
    RCPT TO:<rp@bobbsincyyy.com>    
    250 2.1.5 Recipient OK  
    RCPT TO:<rp@bobbsincyyy.com>    
    250 2.1.5 Recipient OK  
    RCPT TO:<archo@bobbsincyyy.com> 
    250 2.1.5 Recipient OK  
    DEBUG SMTP: Verified Addresses  
    DEBUG SMTP:   RB <rp@bobbsincyyy.com>   
    DEBUG SMTP:   RB <rp@bobbsincyyy.com>   
    DEBUG SMTP:   archo@bobbsincyyy.com 
    DATA    
    354 Start mail input; end with <CRLF>.<CRLF>    
    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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)

There is a pretty good description available in http://springinpractice.com/2012/04/29/fixing-pkix-path-building-issues-when-using-javamail-and-smtp . But, this did not work too (Im not sure if the self signed certificate from the smtp server could cause an issue).

I also tried to enable STARTTLS on the javamail properties with a Truststore configuration. That did not work either.

The SMTP server is an intranet server and not exposed to outside world. So, basically Im ok to trust this SMTP even with a self signed certificate.

How to achieve this?

rakpan
  • 2,773
  • 4
  • 26
  • 36
  • Where's the STARTTLS? You're connecting to port 25, which normally doesn't support encryption (but _may_ support upgrading from plain to TLS via STARTTLS). Usually an SSL connection is on port 465 and an upgradable (via STARTTLS) connection is on 587. It is quite rare for port 25 to support encryption. – Jim Garrison Jun 04 '14 at 22:56

3 Answers3

0

I strongly suspect this is because you're connecting on port 25 and the server does not support TLS on that port. Notice that STARTTLS support is not advertised by the server at connection time (the 250 connection messages).

You should probably be using either 465 (SSL) or 587 (STARTTLS).

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • Im not seeing any STARTTLS commands in the debug messages. Probably the debug doesnt say that? Im not sure. Also, im still unable to understand on why one way works without encryption and the other with encryption. Stumbling across the internet doesnt support a theory that attachments over MIME requires an SSL. – rakpan Jun 05 '14 at 02:02
0

With no STARTTLS command being issued, I don't understand why you're ever getting an SSL exception.

Is it possible that the server that fails is running some sort of firewall or anti-virus that's intercepting your request, and perhaps behaving differently when the content of your message is other than plain text?

Bill Shannon
  • 29,579
  • 6
  • 38
  • 40
0

When adding images, I was using URLDataSource linking to a HTTPS site (An image residing on the server's Images folder).

Since the server did not trust itself, SSLHandShakeException was created. using FileDataSource Instead resolved the issue.

The problem was never with SMTP.

My stupid Learning: If there is a HandShake exception, analyze the stack trace first!

rakpan
  • 2,773
  • 4
  • 26
  • 36