3-15 2011

The different flavors of secure SMTP and SSL

I recently needed to set up some C# code that would send out password reset emails using an external SMTP server. I was familiar with using the built in .NET framework MailMessage class, introduced in .NET 2.0, along with it’s buddy the SmtpClient. You can easily set the port and host of the SMTP server, and send messages, including HTML mail, attachments and al the other basic necessities of emailing. You can also set the SmtpClient.EnableSSL property to use SSL for your communication with the SMTP server, which is exactly what I needed to do.

Now, since the service sending the email was running in the Windows Azure cloud, I wanted to go with a third part secure SMTP system, using a custom domain, so that my emails wouldn’t be flagged as Spam for coming out of that big bucket in the sky that lots of spam also emanates from. It so happens we had an account that uses secureserver.net, and that service has SSL on port 465. So, I just set the port and host, EnableSSL=true, and off I went. Not.

Much to my surprise, the call to my SmtpClient.Send hung for a while, and then threw a Timeout exception! Weird. I tried testing the service using a web page that enables the use of SSL with the same credentials and port, no problems. So I searched a little more, and found a lot of people having this same problem.

Long story short, it turns out there are two ways of doing SSL: Explicit and Implicit.

With Explicit SSL, the communication (which basically is a sockets connection) starts unencrypted on port 25 as a regular SMTP conversation, then switches to TLS (encrypted channel) using the SMTP STARTTLS command, after which it authenticates and starts sending the email. This is the kind of SSL that the .NET SmtpClient understands, and the only kind it understands. It is described in this RFC (which actually talks about FTP, but the thing at issue here is the actual SSL connection, not the protocol – FTP or SMTP – running on top of it).

With Implicit SSL, the connection starts out the whole conversation over SSL, i.e. it is encrypted from the get go. Commonly, port 465 is used for this. Implicit SSL is NOT covered by any RFC, it is NOT a standard, and the .NET SmtpClient does NOT understand it. That is why my send timed out. It was waiting for the server to respond to it’s STARTTLS command, while the server was waiting for the client to start a secure sockets connection.

Here is an image that illustrates the difference in the context of an FTP connection (similar to the SMTP case), courtesy of globalscape.com:

So what did I do?

Well, there are a few choices, luckily. I could have switched to a SMTP service that does Explicit SSL. I could have rolled my own SMTP client (ugh!). I could have reverted to the older System.Web.Mail.SmtpMail client, which did understand Implicit SSL. I could wait for Microsoft to add support support for Implicit SSL…which many people have done for years, and it hasn’t happened yet (cast you vote!). Not wanting to waste any more time, I bit the bullet and purchased an off the shelf component that can do either (I got the EASendMail component, which is reasonably priced and I have used before, but there are others). This component can autodetect what flavor of SSL to use, and it can actually do a whole lot of other fancy things too.

Even though Implicit SSL is not standardized, you may as well get used to it. Yahoo mail uses it on port 465, as does Google gmail. But both these servers also provide Explicit  SSL support on port 587, so you can chose what fits your needs. Our server did not have a choice.

Hopefully this will save you some time next time you search for timeout problems sending SMTP messages!

1 Comment

  1. 1 email@gmail.com 06 Apr
    gApZzP Wow, great blog post.Thanks Again. Really Cool.

Comment

  1.