Search code examples
c#sslsmtp

SMTP - SSL Certificate Issue - C# - Why this code works?


Now, this question has several versions in Stack Overflow like this most viewed question in which most of the answers advise the users to turn off SSL as a method to bypass the code.

I was getting the same exception while trying to send email.

System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

This was my code

private void sendAMail(String toAddress, String messageBody)
        {
            String msg = "Sending mail to : " + toAddress;

            MailMessage mail = new MailMessage();
            mail.To.Add(toAddress);
            mail.From = new MailAddress("from@mydomain.com");
            mail.Subject = "Subject: Test Mail";
            mail.Body = messageBody;
            mail.IsBodyHtml = true;            

            SmtpClient smtp = new SmtpClient();

            smtp.Host = "myhostname.com";            
            smtp.Credentials = new System.Net.NetworkCredential("sender@sample.com", "");
            smtp.EnableSsl = true;
            smtp.Port = 587;            
            smtp.Send(mail);            
        }

While trying several things, finally I tried to print the SSL certificate from the server as mentioned here.Print SSL Cert

Then, the exception is gone.!!! I am not able to figure out why.

This is the code that worked

private void sendAMail(String toAddress, String messageBody)
        {
            String msg = "Sending mail to : " + toAddress;

            MailMessage mail = new MailMessage();
            mail.To.Add(toAddress);
            mail.From = new MailAddress("from@mydomain.com");
            mail.Subject = "Subject: Test Mail";
            mail.Body = messageBody;
            mail.IsBodyHtml = true;            

            //Added this line here
            System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(RemoteServerCertificateValidationCallback);
            SmtpClient smtp = new SmtpClient();

            smtp.Host = "myhostname.com";            
            smtp.Credentials = new System.Net.NetworkCredential("sender@sample.com", "");
            smtp.EnableSsl = true;
            smtp.Port = 587;            
            smtp.Send(mail);            
        }


private bool RemoteServerCertificateValidationCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    //Console.WriteLine(certificate);
    return true;
}

Please explain me the reason it works while the original code is still throwing exception.


Solution

  • The following code is telling your application to trust all certificates, even if they are not valid.

    It is best not to do this.

    private bool RemoteServerCertificateValidationCallback(object sender,
        System.Security.Cryptography.X509Certificates.X509Certificate certificate, 
        System.Security.Cryptography.X509Certificates.X509Chain chain,
        System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
        //Console.WriteLine(certificate);
        return true;
    }