in WindowsDevicePortalWrapper/WindowsDevicePortalWrapper/CertificateHandling.cs [75:128]
private bool ServerCertificateValidation(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (this.manualCertificate != null)
{
chain.ChainPolicy.ExtraStore.Add(this.manualCertificate);
}
X509Certificate2 certv2 = new X509Certificate2(certificate);
bool isValid = chain.Build(certv2);
// If chain validation failed but we have a manual cert, we can still
// check the chain to see if the server cert chains up to our manual cert
// (or matches it) in which case this is valid.
if (!isValid && this.manualCertificate != null)
{
foreach (X509ChainElement element in chain.ChainElements)
{
foreach (X509ChainStatus status in element.ChainElementStatus)
{
// Check if this is a failure that should cause the chain to be rejected
if (status.Status != X509ChainStatusFlags.NoError &&
status.Status != X509ChainStatusFlags.UntrustedRoot &&
status.Status != X509ChainStatusFlags.RevocationStatusUnknown)
{
return false;
}
}
// This cert chained to our provided cert. Continue walking
// the chain to ensure we don't hit a failure that would
// cause our chain to be rejected.
if (element.Certificate.Issuer == this.manualCertificate.Issuer &&
element.Certificate.Thumbprint == this.manualCertificate.Thumbprint)
{
isValid = true;
break;
}
}
}
// If this still appears invalid, we give the app a chance via a handler
// to override the trust decision.
if (!isValid)
{
bool? overridenIsValid = this.UnvalidatedCert?.Invoke(this, certificate, chain, sslPolicyErrors);
if (overridenIsValid != null && overridenIsValid == true)
{
isValid = true;
}
}
return isValid;
}