Skip to content

Commit bf6f21f

Browse files
committed
Stop maintaining a list of valid SSL certificates for common mail servers
MailService.DefaultServerCertificateValidationCallback will no longer maintain a list of known SSL certificate fingerprints for common mail servers such as gmail.com, outlook.com, office365.com, mail.me.com, yahoo.com, gmx.clom or gmx.net. This no longer seems needed and was only ever really needed for clients running on Mono on Linux/MacOS (which has been obsoleted for years by the official dotnet runtime).
1 parent 4b5659f commit bf6f21f

File tree

1 file changed

+2
-120
lines changed

1 file changed

+2
-120
lines changed

MailKit/MailService.cs

Lines changed: 2 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -443,114 +443,11 @@ public abstract int Timeout {
443443
get; set;
444444
}
445445

446-
const string AppleCertificateIssuer = "C=US, S=California, O=Apple Inc., CN=Apple Public Server RSA CA 11 - G1";
447-
const string GMailCertificateIssuer = "CN=WR2, O=Google Trust Services, C=US";
448-
const string OutlookCertificateIssuer = "CN=DigiCert Cloud Services CA-1, O=DigiCert Inc, C=US";
449-
const string YahooCertificateIssuer = "CN=DigiCert SHA2 High Assurance Server CA, OU=www.digicert.com, O=DigiCert Inc, C=US";
450-
const string GmxDotComCertificateIssuer = "CN=Sectigo RSA Organization Validation Secure Server CA, O=Sectigo Limited, L=Salford, S=Greater Manchester, C=GB";
451-
const string GmxDotNetCertificateIssuer = "CN=Telekom Security ServerID OV Class 2 CA, O=Deutsche Telekom Security GmbH, C=DE";
452-
453-
// Note: This method auto-generated by https://gist.github.com/jstedfast/7cd36a51cee740ed84b18435106eaea5
454-
internal static bool IsKnownMailServerCertificate (X509Certificate2 certificate)
455-
{
456-
var cn = certificate.GetNameInfo (X509NameType.SimpleName, false);
457-
var fingerprint = certificate.Thumbprint;
458-
var serial = certificate.SerialNumber;
459-
var issuer = certificate.Issuer;
460-
461-
switch (cn) {
462-
case "imap.gmail.com":
463-
switch (issuer) {
464-
case GMailCertificateIssuer:
465-
return (serial == "00EBD9C1E819C5E8210A9042A1DB68CA4A" && fingerprint == "F782C958321514486235A43F048B1BF322E028B0"); // Expires 4/20/2026 4:40:51 AM
466-
default:
467-
return false;
468-
}
469-
case "pop.gmail.com":
470-
switch (issuer) {
471-
case GMailCertificateIssuer:
472-
return (serial == "00DF09248D5E6774CC10620F198E408025" && fingerprint == "2B12A6D5C26D8359A3ABD88B37779A12CB3FA72A"); // Expires 4/20/2026 4:40:52 AM
473-
default:
474-
return false;
475-
}
476-
case "smtp.gmail.com":
477-
switch (issuer) {
478-
case GMailCertificateIssuer:
479-
return (serial == "0085E25FC8F0D6B36312BF7499A3EE174D" && fingerprint == "4147F8A9DC5208A32F7C4B212942443C267D094E"); // Expires 4/20/2026 4:40:53 AM
480-
default:
481-
return false;
482-
}
483-
case "outlook.com":
484-
switch (issuer) {
485-
case OutlookCertificateIssuer:
486-
return (serial == "07ECFAB580E06830E3EC580E3C1D4765" && fingerprint == "A6F7ECFB2BF631B3A84FEBB09FFDBB4E3B0F4211") // Expires 3/28/2026 7:59:59 PM
487-
|| (serial == "05A8E2577A9AC3107AC04CAC3D282AF2" && fingerprint == "49EB381366CB543F6C6235F2D33C667DEDFA206F"); // Expires 11/9/2026 6:59:59 PM
488-
default:
489-
return false;
490-
}
491-
case "imap.mail.me.com":
492-
switch (issuer) {
493-
case AppleCertificateIssuer:
494-
return (serial == "0FEE8FBB49AC97EC86D7ED21EFC51897" && fingerprint == "165176380DCFC6A132F525FDE4CF18F4442FCC0C"); // Expires 4/29/2026 3:21:15 PM
495-
default:
496-
return false;
497-
}
498-
case "smtp.mail.me.com":
499-
switch (issuer) {
500-
case AppleCertificateIssuer:
501-
return (serial == "7250507B5C1C895E323A3A5B023B20C0" && fingerprint == "160053F7CF49B1C29393A837C4F0A56240677F03"); // Expires 4/1/2026 1:30:06 PM
502-
default:
503-
return false;
504-
}
505-
case "*.imap.mail.yahoo.com":
506-
switch (issuer) {
507-
case YahooCertificateIssuer:
508-
return (serial == "085C2B88669F6FA216C9B13834BF9030" && fingerprint == "7FEC1E5DB496FE90CEA033EEAF58A140688391AD"); // Expires 3/25/2026 7:59:59 PM
509-
default:
510-
return false;
511-
}
512-
case "legacy.pop.mail.yahoo.com":
513-
switch (issuer) {
514-
case YahooCertificateIssuer:
515-
return (serial == "02D30096956F2F636E4F8C8A428B8B7A" && fingerprint == "BA185970AD9E15E8D21EFC8F691E1D18711EEE56"); // Expires 4/8/2026 7:59:59 PM
516-
default:
517-
return false;
518-
}
519-
case "smtp.mail.yahoo.com":
520-
switch (issuer) {
521-
case YahooCertificateIssuer:
522-
return (serial == "06C9D3C60F0F318236412975B3A7A2BC" && fingerprint == "15B8788B67B16595E596F042779C79640D9F2181"); // Expires 4/8/2026 7:59:59 PM
523-
default:
524-
return false;
525-
}
526-
case "mout.gmx.com":
527-
return issuer == GmxDotComCertificateIssuer && serial == "49F9B6205B93B1A9DCEC50C54192A0A5" && fingerprint == "34DC8F699802DC1FAE824560C27E985020ACCFCC"; // Expires 5/5/2026 7:59:59 PM
528-
case "mail.gmx.net":
529-
return issuer == GmxDotNetCertificateIssuer && serial == "27AA0BBE1A29991EFFA8D799F4473004" && fingerprint == "53738E6CBB6B7EEA1E6CC77BC1A8867B0FB20331"; // Expires 11/22/2026 6:59:59 PM
530-
default:
531-
return false;
532-
}
533-
}
534-
535-
static bool IsUntrustedRoot (X509Chain chain)
536-
{
537-
foreach (var status in chain.ChainStatus) {
538-
if (status.Status == X509ChainStatusFlags.NoError || status.Status == X509ChainStatusFlags.UntrustedRoot)
539-
continue;
540-
541-
return false;
542-
}
543-
544-
return true;
545-
}
546-
547446
/// <summary>
548447
/// The default server certificate validation callback used when connecting via SSL or TLS.
549448
/// </summary>
550449
/// <remarks>
551-
/// <para>The default server certificate validation callback recognizes and accepts the certificates
552-
/// for a list of commonly used mail servers such as gmail.com, outlook.com, mail.me.com, yahoo.com,
553-
/// and gmx.net.</para>
450+
/// The default server certificate validation callback only succeeds if there are no SSL/TLS certificate validation errors.
554451
/// </remarks>
555452
/// <returns><see langword="true" /> if the certificate is deemed valid; otherwise, <see langword="false" />.</returns>
556453
/// <param name="sender">The object that is connecting via SSL or TLS.</param>
@@ -559,22 +456,7 @@ static bool IsUntrustedRoot (X509Chain chain)
559456
/// <param name="sslPolicyErrors">The SSL policy errors.</param>
560457
protected static bool DefaultServerCertificateValidationCallback (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
561458
{
562-
const SslPolicyErrors mask = SslPolicyErrors.RemoteCertificateNotAvailable | SslPolicyErrors.RemoteCertificateNameMismatch;
563-
564-
if (sslPolicyErrors == SslPolicyErrors.None)
565-
return true;
566-
567-
if ((sslPolicyErrors & mask) == 0) {
568-
// At this point, all that is left is SslPolicyErrors.RemoteCertificateChainErrors
569-
570-
// If the problem is an untrusted root, then compare the certificate to a list of known mail server certificates.
571-
if (IsUntrustedRoot (chain) && certificate is X509Certificate2 certificate2) {
572-
if (IsKnownMailServerCertificate (certificate2) && DateTime.Now <= certificate2.NotAfter)
573-
return true;
574-
}
575-
}
576-
577-
return false;
459+
return sslPolicyErrors == SslPolicyErrors.None;
578460
}
579461

580462
#if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER

0 commit comments

Comments
 (0)