MailKit: Dotnet 3.0.0 Linux image doesnt seem to use ServerCertificateValidationCallback

Describe the bug We have been using this code in production for a while. Post an image upgrade from dotnet 2.1.300 to 3.0.0 it is not hitting the ServerCertificateValidationCallback function any more for IMAP providers with self certificates. When I run on my windows machine or in a windows based image it works fine.

public override Task<DefaultResponse> Initialize(MailBox mailBox)
{
    var response = base.Initialize(mailBox);

    MailClient = new ImapClient();
    MailClient.CheckCertificateRevocation = false;
    MailClient.ServerCertificateValidationCallback = MailClientServerCertificateValidationCallback;

    return response;
}

private bool MailClientServerCertificateValidationCallback(
    object sender,
    X509Certificate certificate,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors
)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
        return true;

    Logger.Warning(
        nameof(Initialize),
        "Invalid Cert",
        sender,
        certificate,
        chain,
        sslPolicyErrors
    );

    // 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)
            {
                Logger.Warning(
                    nameof(Initialize),
                    "Chain Status {Status}",
                    status.Status,
                    certificate.Subject,
                    certificate.Issuer
                );

                if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown)
                {
                    Logger.Warning(
                        nameof(Initialize),
                        "Chain Status {status} cant tell if revoked correctly allowing connection",
                        status.Status
                    );

                    continue;
                }

                if (status.Status == X509ChainStatusFlags.PartialChain)
                {
                    Logger.Warning(
                        nameof(Initialize),
                        "PartialChain {status} allowing connection",
                        status.Status
                    );

                    continue;
                }

                if ((certificate.Subject == certificate.Issuer) && (status.Status == X509ChainStatusFlags.UntrustedRoot))
                {
                    Logger.Warning(
                        nameof(Initialize),
                        "PartialChain {status} " +
                        "The only errors in the certificate chain are untrusted root errors for self-signed certificates",
                        status.Status
                    );
                    // 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;
                }
            }
        }
        return true;
    }

    return false;
}

It throws this error.

An unknown error has occurred Exception: An error occurred while attempting to establish an SSL or TLS connection. One possibility is that you are trying to connect to a port which does not support SSL/TLS. The other possibility is that the SSL certificate presented by the server is not trusted by the system for one or more of the following reasons: 1. The server is using a self-signed certificate which cannot be verified. 2. The local system is missing a Root or Intermediate certificate needed to verify the server’s certificate. 3. The certificate presented by the server is expired or invalid. See https://github.com/jstedfast/MailKit/blob/master/FAQ.md#InvalidSslCertificate for possible solutions. Authentication failed because the remote party has closed the transport stream. Data: Source: MailKit Help Link: https://github.com/jstedfast/MailKit/blob/master/FAQ.md#InvalidSslCertificate StackTrace: at MailKit.Net.Imap.ImapClient.ConnectAsync(String host, Int32 port, SecureSocketOptions options, Boolean doAsync, CancellationToken cancellationToken at REDACTED.Core.Comms.Services.ServiceBase1.ConnectAsync(IMailService client, MailServer mailBox, CancellationToken cancellationToken) Source: MailKit BaseException: System.IO.IOException: Authentication failed because the remote party has closed the transport stream. at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest) --- End of stack trace from previous location where exception was thrown --- at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult at System.Net.Security.SslStream.<>c.b__64_2(IAsyncResult iar at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task`1 promise, Boolean requiresSynchronization) — End of stack trace from previous location where exception was thrown — at MailKit.Net.Imap.ImapClient.ConnectAsync(String host, Int32 port, SecureSocketOptions options, Boolean doAsync, CancellationToken cancellationToken)

Expected behavior I expect the method to be hit on ssl exception.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 28 (9 by maintainers)

Most upvoted comments

@Spaceman1861 I think @lukos is referring to doing:

client.CheckCertificateRevocation = false;

I should probably add that as a possibility in the docs/FAQ and maybe even the SslHandshakeException message.