private async Task<CertificateIdentifier> GetIssuer(
X509Certificate2 certificate,
CertificateIdentifierCollection explicitList,
CertificateStoreIdentifier certificateStore,
bool checkRecovationStatus)
{
string subjectName = certificate.IssuerName.Name;
string keyId = null;
string serialNumber = null;
// find the authority key identifier.
X509AuthorityKeyIdentifierExtension authority = FindAuthorityKeyIdentifier(certificate);
if (authority != null)
{
keyId = authority.KeyId;
serialNumber = authority.SerialNumber;
}
// check in explicit list.
if (explicitList != null)
{
for (int ii = 0; ii < explicitList.Count; ii++)
{
X509Certificate2 issuer = await explicitList[ii].Find(false);
if (issuer != null)
{
if (!IsIssuerAllowed(issuer))
{
continue;
}
if (Match(issuer, subjectName, serialNumber, keyId))
{
// can't check revocation.
return new CertificateIdentifier(issuer, CertificateValidationOptions.SuppressRevocationStatusUnknown);
}
}
}
}
// check in certificate store.
if (certificateStore != null)
{
ICertificateStore store = certificateStore.OpenStore();
try
{
X509Certificate2Collection certificates = await store.Enumerate();
for (int ii = 0; ii < certificates.Count; ii++)
{
X509Certificate2 issuer = certificates[ii];
if (issuer != null)
{
if (!IsIssuerAllowed(issuer))
{
continue;
}
if (Match(issuer, subjectName, serialNumber, keyId))
{
CertificateValidationOptions options = certificateStore.ValidationOptions;
// already checked revocation for file based stores. windows based stores always suppress.
options |= CertificateValidationOptions.SuppressRevocationStatusUnknown;
if (checkRecovationStatus)
{
StatusCode status = store.IsRevoked(issuer, certificate);
if (StatusCode.IsBad(status))
{
if (status != StatusCodes.BadNotSupported && status != StatusCodes.BadCertificateRevocationUnknown)
{
throw new ServiceResultException(status);
}
}
}
return new CertificateIdentifier(certificates[ii], options);
}
}
}
}
finally
{
store.Close();
}
}
// not a trusted issuer.
return null;
}