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.ServiceBase
1.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.TaskFactory
1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action
1 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)
@Spaceman1861 I think @lukos is referring to doing:
I should probably add that as a possibility in the docs/FAQ and maybe even the SslHandshakeException message.