Skip to content

Instantly share code, notes, and snippets.

@jstedfast
Created November 13, 2020 01:12
Show Gist options
  • Save jstedfast/7cd36a51cee740ed84b18435106eaea5 to your computer and use it in GitHub Desktop.
Save jstedfast/7cd36a51cee740ed84b18435106eaea5 to your computer and use it in GitHub Desktop.
using System;
using System.Net.Security;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using MailKit;
using MailKit.Net.Imap;
using MailKit.Net.Pop3;
using MailKit.Net.Smtp;
using MailKit.Security;
namespace CommonMailServerCerts
{
class Program
{
static readonly string[] MailServers = new string[] {
"imap://imap.gmail.com:993",
"pop://pop.gmail.com:995",
"smtp://smtp.gmail.com:587",
"imap://imap-mail.outlook.com:993",
"pop://pop-mail.outlook.com:995",
"smtp://smtp-mail.outlook.com:587",
"imap://outlook.office365.com:993",
"pop://outlook.office365.com:995",
"smtp://smtp.office365.com:587",
"imap://imap.mail.me.com:993",
"smtp://smtp.mail.me.com:587",
"imap://imap.mail.yahoo.com:993",
"pop://pop.mail.yahoo.com:995",
"smtp://smtp.mail.yahoo.com:587",
"imap://imap.gmx.com:993",
"pop://pop.gmx.com:995",
"smtp://mail.gmx.com:465",
"imap://imap.gmx.de:993",
"pop://pop.gmx.de:995",
"smtp://mail.gmx.de:465"
};
class CertificateInfo
{
public string CommonName { get; private set; }
public string Issuer { get; private set; }
public string SerialNumber { get; private set; }
public string Fingerprint { get; private set; }
public DateTime Expires { get; private set; }
public CertificateInfo (X509Certificate2 certificate)
{
CommonName = certificate.GetNameInfo (X509NameType.SimpleName, false);
SerialNumber = certificate.SerialNumber;
Fingerprint = certificate.Thumbprint;
Issuer = certificate.Issuer;
Expires = certificate.NotAfter;
}
}
static void Main (string[] args)
{
var certificates = new Dictionary<string, CertificateInfo> ();
foreach (var server in MailServers) {
var uri = new Uri (server);
MailService client;
switch (uri.Scheme) {
case "imap": client = new ImapClient (); break;
case "pop": client = new Pop3Client (); break;
case "smtp": client = new SmtpClient (); break;
default: throw new Exception ("Unsupported protocol");
}
using (client) {
client.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
var info = new CertificateInfo ((X509Certificate2) certificate);
if (!certificates.ContainsKey (info.CommonName))
certificates.Add (info.CommonName, info);
return true;
};
Console.Write ("Connecting to {0}...", uri);
client.Connect (uri.Host, uri.Port, SecureSocketOptions.Auto);
client.Disconnect (true);
Console.WriteLine ("done");
}
}
Console.WriteLine ("static bool IsKnownMailServerCertificate (X509Certificate2 certificate)");
Console.WriteLine ("{");
Console.WriteLine ("\tvar cn = certificate.GetNameInfo (X509NameType.SimpleName, false);");
Console.WriteLine ("\tvar fingerprint = certificate.Thumbprint;");
Console.WriteLine ("\tvar serial = certificate.SerialNumber;");
Console.WriteLine ("\tvar issuer = certificate.Issuer;");
Console.WriteLine ();
Console.WriteLine ("\tswitch (cn) {");
foreach (var kvp in certificates) {
var info = kvp.Value;
Console.WriteLine ("\tcase \"{0}\":", info.CommonName);
Console.WriteLine ("\t\treturn issuer == \"{0}\" && serial == \"{1}\" && fingerprint == \"{2}\"; // Expires {3}", info.Issuer, info.SerialNumber, info.Fingerprint, info.Expires);
}
Console.WriteLine ("\tdefault:");
Console.WriteLine ("\t\treturn false;");
Console.WriteLine ("\t}");
Console.WriteLine ("}");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment