-
-
Notifications
You must be signed in to change notification settings - Fork 834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The remote certificate is invalid according to the validation procedure. #307
Comments
In MailKit prior to 1.2.20, I made the default certificate validation callback always return "valid", mostly to avoid this type of question for the multitude of mail servers that have self-signed certificates and I figured that anyone serious about security would override the I don't think GMail's certificate is self-signed, but I have also noticed that on Mac and Linux, this now fails, but on Windows it seems to continue to work. Are you on Mac or Linux? Either way, the solution is to do something like this: client.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => {
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
// if there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) != 0) {
if (chain != null && chain.ChainStatus != null) {
foreach (var status in chain.ChainStatus) {
if ((certificate.Subject == certificate.Issuer) && (status.Status == X509ChainStatusFlags.UntrustedRoot)) {
// self-signed certificates with an untrusted root are valid.
continue;
} else if (status.Status != X509ChainStatusFlags.NoError) {
// if there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
return false;
}
}
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
return true;
}
return false;
}; |
I've just added this logic as a public static method called I've also made it the default callback for all SMTP, POP3 and IMAP client instances. Hopefully this will not bite me in the butt :( |
Thank you for information. It really helped for me. |
One way to make this more secure is that you could get the Thumbprint of the X509Certificate you know is Google's GMail server and hardcode that into the callback so that you can compare the Thumbprint values. if (certificate is X509Certificate2 && ((X509Certificate2) certificate).Thumbprint == "71DFBE124D89ED9218F539A82D4127FBB4BC9997")
return true; |
Hi mate, |
I missed this change when you made it on March 3rd (I use my own validation function, so it doesn't affect me), and like you I tend to waffle on security checks like this. The more paranoid in me would prefer the more rigorous check, failing on self-signed certs (partly to raise awareness of the evilness of using self-signed certs for a public server like this, because MitM attacks), and if someone wants a less secure setting, they should override the more secure check. That being said, I answer a lot of certificate questions ("Why doesn't your app connect to my self-signed-certificate-server?!"), and it gets tedious after a while, so it's hard to argue with your change. Note that there's now a free way of getting actual (non-self-signed) certs: https://letsencrypt.org |
Hey Jeffrey,
I will be very glad if you could help? |
Further to this, if I check Capabilities, I get this error while sending emails
And on capability check, server has SmtpCapabilities.EightBitMime and size restriction of 20971520 |
This error means that your SMTP server does not support authentication, so... just don't authenticate (i.e. skip calling the
This error means that one of the email addresses (aka mailboxes) that you are sending the message to does not exist. |
Hey Jeff, if I skip authenticate it throws this mailbox error and its just a normal valid hotmail email. Stuck |
The error is from the server, so I'd be fairly confident that the error is accurate. Maybe the mailbox is full? |
No, I have tried sending to different emails, same error, and I have tried a different email from the same server but same result. |
Sure, give that a try. You could also try getting a log (see the FAQ) to see what capabilities the server supports. |
That being said: SMTP:
IMAP:
|
@atiqi36 make sure to connect using |
Guys, I think I may have been unclear. It's not the hotmail server I am using. The smtp server I am using to send email is mail.cosgroup.com and the email is of the same domain like email@cosgroup.com |
The server might not support authentication until you have toggled into TLS mode. So what you need to do is connect on port 25 or 587 (which ever one you are using) and pass using (var client = new SmtpClient (new ProtocolLogger ("smtp.log"))) {
client.Connect ("mail.cosgroup.com", 587, SecureSocketOptions.StartTls);
client.Authenticate ("username", "password");
client.Send (message);
client.Disconnect (true);
} |
Now getting this error |
Have you tried contacting your network administrator and asking him/her what settings to use for connecting via SMTP? |
Dear Jeffrey, I try to use MailKit Imap Client with a self-signed certificate in vb.net. As I don't have any experience with certificates I have some problems to get this running. Kind regards |
Here's an example in C# (I don't know VB): bool CustomCertificateValidationCallback (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return certificate.Thumbprint == "<hardcoded thumbprint of your imap server goes here>";
} using (var client = new ImapClient ()) {
client.ServerCertificateValidationCallback = CustomCertificateValidationCallback;
client.Connect ("imap.server.com", 993, true);
// ...
} If you don't know what the thumbprint is, you can use this custom callback to print it out for you and then just copy & paste it into the custom callback I pasted above: bool CustomCertificateValidationCallback (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine ("Thumbprint = {0}", certificate.Thumbprint);
return false;
} |
Dear Jeffrey, thank you very much for your quick response. Unfortunately I have some more questions:
Kind regards |
client.ServerCertificateValidationCallback is a function delegate, it is not a boolean property. You need to assign a method to it. Then, when the SSL connection is made, the client will call that method with the certificate and such. |
I can only urge folks to NOT use self-signed certificates. There's really no need to make the NSA's (and CIA's and FBI's) job easier. You can get FREE certificates from https://letsencrypt.org. For a linux server, it's almost trivial to set up, and you get a real (as in 'signed by a trusted CA') certificate. Certificate pinning is a decent thing to do (which is what putting the thumb/fingerprint into the code is), but isn't entirely flexible, since you'd have to recompile (and redistribute) your code/app every time you need to change the certificate. It would be better to create your own CA certificate, save the CA-certificate's fingerprint in the code, and the CAREFULLY issue your own certificates from that CA; that would be more flexible, but a bit of work, that letsencrypt.org basically does for you. |
100% agreed. 👍 |
I'm getting the same error (The remote certificate is invalid according to the validation procedure), but only on a Mac. On windows works fine. This is the line that is throwing the exception on Mac client.Connect(options.SmtpHost, 465, true); |
You need to assign your own callback to Most likely the issue you are running into is that your Windows certificate store has a copy of the server's certificate (or the Root CA that signed it) while your Mac does not. |
You need ignore this validation if you had problemas with certificate. client.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { |
@gustavodenis - Well, that's one option, though the errors are generally legitimate. The whole point of callback is to validate the SSL cert being presented by the SMTP server. Returning true will ignore the validation, yes, but if it's a self-signed cert you can resolve this without removing validation by either adding the remote cert/chain to the MailKit server's certstore (if intranet, this can be more easily resolved using a corp-wide internal CA), or getting a real cert on the SMTP server. |
Hello. After updating MailKit to version 1.2.20 When I try to connect by using MailKit.ImapClient to gmail with default settings(Host = "imap.gmail.com", Port = 993, UseSSL = true), then the error appears "System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure." at
MailKit.Net.Imap.ImapClient.Connect(String host, Int32 port, SecureSocketOptions options, CancellationToken cancellationToken). If I set SecureSocketOptions.None to connection settings, MailKit.ImapClient return Unexpectedly disconnected. What's wrong?
The text was updated successfully, but these errors were encountered: