You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2452 lines
66 KiB
2452 lines
66 KiB
1 year ago
|
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
|
||
|
#pragma warning disable
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Globalization;
|
||
|
using System.IO;
|
||
|
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Date;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
|
||
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
|
||
|
|
||
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
|
||
|
{
|
||
|
public class Rfc3280CertPathUtilities
|
||
|
{
|
||
|
private static readonly PkixCrlUtilities CrlUtilities = new PkixCrlUtilities();
|
||
|
|
||
|
internal static readonly string ANY_POLICY = "2.5.29.32.0";
|
||
|
|
||
|
// key usage bits
|
||
|
internal static readonly int KEY_CERT_SIGN = 5;
|
||
|
internal static readonly int CRL_SIGN = 6;
|
||
|
|
||
|
/**
|
||
|
* If the complete CRL includes an issuing distribution point (IDP) CRL
|
||
|
* extension check the following:
|
||
|
* <p>
|
||
|
* (i) If the distribution point name is present in the IDP CRL extension
|
||
|
* and the distribution field is present in the DP, then verify that one of
|
||
|
* the names in the IDP matches one of the names in the DP. If the
|
||
|
* distribution point name is present in the IDP CRL extension and the
|
||
|
* distribution field is omitted from the DP, then verify that one of the
|
||
|
* names in the IDP matches one of the names in the cRLIssuer field of the
|
||
|
* DP.
|
||
|
* </p>
|
||
|
* <p>
|
||
|
* (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL
|
||
|
* extension, verify that the certificate does not include the basic
|
||
|
* constraints extension with the cA boolean asserted.
|
||
|
* </p>
|
||
|
* <p>
|
||
|
* (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL
|
||
|
* extension, verify that the certificate includes the basic constraints
|
||
|
* extension with the cA boolean asserted.
|
||
|
* </p>
|
||
|
* <p>
|
||
|
* (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted.
|
||
|
* </p>
|
||
|
*
|
||
|
* @param dp The distribution point.
|
||
|
* @param cert The certificate.
|
||
|
* @param crl The CRL.
|
||
|
* @throws AnnotatedException if one of the conditions is not met or an error occurs.
|
||
|
*/
|
||
|
internal static void ProcessCrlB2(
|
||
|
DistributionPoint dp,
|
||
|
object cert,
|
||
|
X509Crl crl)
|
||
|
{
|
||
|
IssuingDistributionPoint idp = null;
|
||
|
try
|
||
|
{
|
||
|
idp = IssuingDistributionPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.IssuingDistributionPoint));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("0 Issuing distribution point extension could not be decoded.", e);
|
||
|
}
|
||
|
// (b) (2) (i)
|
||
|
// distribution point name is present
|
||
|
if (idp != null)
|
||
|
{
|
||
|
if (idp.DistributionPoint != null)
|
||
|
{
|
||
|
// make list of names
|
||
|
DistributionPointName dpName = IssuingDistributionPoint.GetInstance(idp).DistributionPoint;
|
||
|
IList names = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
|
||
|
if (dpName.PointType == DistributionPointName.FullName)
|
||
|
{
|
||
|
GeneralName[] genNames = GeneralNames.GetInstance(dpName.Name).GetNames();
|
||
|
for (int j = 0; j < genNames.Length; j++)
|
||
|
{
|
||
|
names.Add(genNames[j]);
|
||
|
}
|
||
|
}
|
||
|
if (dpName.PointType == DistributionPointName.NameRelativeToCrlIssuer)
|
||
|
{
|
||
|
Asn1EncodableVector vec = new Asn1EncodableVector();
|
||
|
try
|
||
|
{
|
||
|
IEnumerator e = Asn1Sequence.GetInstance(
|
||
|
Asn1Sequence.FromByteArray(crl.IssuerDN.GetEncoded())).GetEnumerator();
|
||
|
while (e.MoveNext())
|
||
|
{
|
||
|
vec.Add((Asn1Encodable)e.Current);
|
||
|
}
|
||
|
}
|
||
|
catch (IOException e)
|
||
|
{
|
||
|
throw new Exception("Could not read CRL issuer.", e);
|
||
|
}
|
||
|
vec.Add(dpName.Name);
|
||
|
names.Add(new GeneralName(X509Name.GetInstance(new DerSequence(vec))));
|
||
|
}
|
||
|
bool matches = false;
|
||
|
// verify that one of the names in the IDP matches one
|
||
|
// of the names in the DP.
|
||
|
if (dp.DistributionPointName != null)
|
||
|
{
|
||
|
dpName = dp.DistributionPointName;
|
||
|
GeneralName[] genNames = null;
|
||
|
if (dpName.PointType == DistributionPointName.FullName)
|
||
|
{
|
||
|
genNames = GeneralNames.GetInstance(dpName.Name).GetNames();
|
||
|
}
|
||
|
if (dpName.PointType == DistributionPointName.NameRelativeToCrlIssuer)
|
||
|
{
|
||
|
if (dp.CrlIssuer != null)
|
||
|
{
|
||
|
genNames = dp.CrlIssuer.GetNames();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
genNames = new GeneralName[1];
|
||
|
try
|
||
|
{
|
||
|
genNames[0] = new GeneralName(
|
||
|
PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert));
|
||
|
}
|
||
|
catch (IOException e)
|
||
|
{
|
||
|
throw new Exception("Could not read certificate issuer.", e);
|
||
|
}
|
||
|
}
|
||
|
for (int j = 0; j < genNames.Length; j++)
|
||
|
{
|
||
|
IEnumerator e = Asn1Sequence.GetInstance(genNames[j].Name.ToAsn1Object()).GetEnumerator();
|
||
|
Asn1EncodableVector vec = new Asn1EncodableVector();
|
||
|
while (e.MoveNext())
|
||
|
{
|
||
|
vec.Add((Asn1Encodable)e.Current);
|
||
|
}
|
||
|
vec.Add(dpName.Name);
|
||
|
genNames[j] = new GeneralName(X509Name.GetInstance(new DerSequence(vec)));
|
||
|
}
|
||
|
}
|
||
|
if (genNames != null)
|
||
|
{
|
||
|
for (int j = 0; j < genNames.Length; j++)
|
||
|
{
|
||
|
if (names.Contains(genNames[j]))
|
||
|
{
|
||
|
matches = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!matches)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
|
||
|
}
|
||
|
}
|
||
|
// verify that one of the names in
|
||
|
// the IDP matches one of the names in the cRLIssuer field of
|
||
|
// the DP
|
||
|
else
|
||
|
{
|
||
|
if (dp.CrlIssuer == null)
|
||
|
{
|
||
|
throw new Exception("Either the cRLIssuer or the distributionPoint field must "
|
||
|
+ "be contained in DistributionPoint.");
|
||
|
}
|
||
|
GeneralName[] genNames = dp.CrlIssuer.GetNames();
|
||
|
for (int j = 0; j < genNames.Length; j++)
|
||
|
{
|
||
|
if (names.Contains(genNames[j]))
|
||
|
{
|
||
|
matches = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!matches)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
BasicConstraints bc = null;
|
||
|
try
|
||
|
{
|
||
|
bc = BasicConstraints.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(
|
||
|
(IX509Extension)cert, X509Extensions.BasicConstraints));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Basic constraints extension could not be decoded.", e);
|
||
|
}
|
||
|
|
||
|
//if (cert is X509Certificate)
|
||
|
{
|
||
|
// (b) (2) (ii)
|
||
|
if (idp.OnlyContainsUserCerts && ((bc != null) && bc.IsCA()))
|
||
|
{
|
||
|
throw new Exception("CA Cert CRL only contains user certificates.");
|
||
|
}
|
||
|
|
||
|
// (b) (2) (iii)
|
||
|
if (idp.OnlyContainsCACerts && (bc == null || !bc.IsCA()))
|
||
|
{
|
||
|
throw new Exception("End CRL only contains CA certificates.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// (b) (2) (iv)
|
||
|
if (idp.OnlyContainsAttributeCerts)
|
||
|
{
|
||
|
throw new Exception("onlyContainsAttributeCerts boolean is asserted.");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void ProcessCertBC(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
PkixNameConstraintValidator nameConstraintValidator)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
int n = certs.Count;
|
||
|
// i as defined in the algorithm description
|
||
|
int i = n - index;
|
||
|
//
|
||
|
// (b), (c) permitted and excluded subtree checking.
|
||
|
//
|
||
|
if (!(PkixCertPathValidatorUtilities.IsSelfIssued(cert) && (i < n)))
|
||
|
{
|
||
|
X509Name principal = cert.SubjectDN;
|
||
|
Asn1Sequence dns;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
dns = Asn1Sequence.GetInstance(principal.GetEncoded());
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Exception extracting subject name when checking subtrees.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
nameConstraintValidator.CheckPermittedDN(dns);
|
||
|
nameConstraintValidator.CheckExcludedDN(dns);
|
||
|
}
|
||
|
catch (PkixNameConstraintValidatorException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Subtree check for certificate subject failed.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
GeneralNames altName = null;
|
||
|
try
|
||
|
{
|
||
|
altName = GeneralNames.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.SubjectAlternativeName));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Subject alternative name extension could not be decoded.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
IList emails = X509Name.GetInstance(dns).GetValueList(X509Name.EmailAddress);
|
||
|
foreach (string email in emails)
|
||
|
{
|
||
|
GeneralName emailAsGeneralName = new GeneralName(GeneralName.Rfc822Name, email);
|
||
|
try
|
||
|
{
|
||
|
nameConstraintValidator.checkPermitted(emailAsGeneralName);
|
||
|
nameConstraintValidator.checkExcluded(emailAsGeneralName);
|
||
|
}
|
||
|
catch (PkixNameConstraintValidatorException ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Subtree check for certificate subject alternative email failed.", ex, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
if (altName != null)
|
||
|
{
|
||
|
GeneralName[] genNames = null;
|
||
|
try
|
||
|
{
|
||
|
genNames = altName.GetNames();
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Subject alternative name contents could not be decoded.", e, certPath, index);
|
||
|
}
|
||
|
foreach (GeneralName genName in genNames)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
nameConstraintValidator.checkPermitted(genName);
|
||
|
nameConstraintValidator.checkExcluded(genName);
|
||
|
}
|
||
|
catch (PkixNameConstraintValidatorException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Subtree check for certificate subject alternative name failed.", e, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void PrepareNextCertA(
|
||
|
PkixCertPath certPath,
|
||
|
int index)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
//
|
||
|
//
|
||
|
// (a) check the policy mappings
|
||
|
//
|
||
|
Asn1Sequence pm = null;
|
||
|
try
|
||
|
{
|
||
|
pm = Asn1Sequence.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyMappings));
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy mappings extension could not be decoded.", ex, certPath, index);
|
||
|
}
|
||
|
if (pm != null)
|
||
|
{
|
||
|
Asn1Sequence mappings = pm;
|
||
|
|
||
|
for (int j = 0; j < mappings.Count; j++)
|
||
|
{
|
||
|
DerObjectIdentifier issuerDomainPolicy = null;
|
||
|
DerObjectIdentifier subjectDomainPolicy = null;
|
||
|
try
|
||
|
{
|
||
|
Asn1Sequence mapping = Asn1Sequence.GetInstance(mappings[j]);
|
||
|
|
||
|
issuerDomainPolicy = DerObjectIdentifier.GetInstance(mapping[0]);
|
||
|
subjectDomainPolicy = DerObjectIdentifier.GetInstance(mapping[1]);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy mappings extension contents could not be decoded.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(issuerDomainPolicy.Id))
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"IssuerDomainPolicy is anyPolicy", null, certPath, index);
|
||
|
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(subjectDomainPolicy.Id))
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"SubjectDomainPolicy is anyPolicy,", null, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static PkixPolicyNode ProcessCertD(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
ISet acceptablePolicies,
|
||
|
PkixPolicyNode validPolicyTree,
|
||
|
IList[] policyNodes,
|
||
|
int inhibitAnyPolicy)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
int n = certs.Count;
|
||
|
// i as defined in the algorithm description
|
||
|
int i = n - index;
|
||
|
//
|
||
|
// (d) policy Information checking against initial policy and
|
||
|
// policy mapping
|
||
|
//
|
||
|
Asn1Sequence certPolicies = null;
|
||
|
try
|
||
|
{
|
||
|
certPolicies = Asn1Sequence.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CertificatePolicies));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Could not read certificate policies extension from certificate.", e, certPath, index);
|
||
|
}
|
||
|
if (certPolicies != null && validPolicyTree != null)
|
||
|
{
|
||
|
//
|
||
|
// (d) (1)
|
||
|
//
|
||
|
ISet pols = new HashSet();
|
||
|
|
||
|
foreach (Asn1Encodable ae in certPolicies)
|
||
|
{
|
||
|
PolicyInformation pInfo = PolicyInformation.GetInstance(ae.ToAsn1Object());
|
||
|
DerObjectIdentifier pOid = pInfo.PolicyIdentifier;
|
||
|
|
||
|
pols.Add(pOid.Id);
|
||
|
|
||
|
if (!Rfc3280CertPathUtilities.ANY_POLICY.Equals(pOid.Id))
|
||
|
{
|
||
|
ISet pq = null;
|
||
|
try
|
||
|
{
|
||
|
pq = PkixCertPathValidatorUtilities.GetQualifierSet(pInfo.PolicyQualifiers);
|
||
|
}
|
||
|
catch (PkixCertPathValidatorException ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy qualifier info set could not be build.", ex, certPath, index);
|
||
|
}
|
||
|
|
||
|
bool match = PkixCertPathValidatorUtilities.ProcessCertD1i(i, policyNodes, pOid, pq);
|
||
|
|
||
|
if (!match)
|
||
|
{
|
||
|
PkixCertPathValidatorUtilities.ProcessCertD1ii(i, policyNodes, pOid, pq);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (acceptablePolicies.IsEmpty || acceptablePolicies.Contains(Rfc3280CertPathUtilities.ANY_POLICY))
|
||
|
{
|
||
|
acceptablePolicies.Clear();
|
||
|
acceptablePolicies.AddAll(pols);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ISet t1 = new HashSet();
|
||
|
|
||
|
foreach (object o in acceptablePolicies)
|
||
|
{
|
||
|
if (pols.Contains(o))
|
||
|
{
|
||
|
t1.Add(o);
|
||
|
}
|
||
|
}
|
||
|
acceptablePolicies.Clear();
|
||
|
acceptablePolicies.AddAll(t1);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// (d) (2)
|
||
|
//
|
||
|
if ((inhibitAnyPolicy > 0) || ((i < n) && PkixCertPathValidatorUtilities.IsSelfIssued(cert)))
|
||
|
{
|
||
|
foreach (Asn1Encodable ae in certPolicies)
|
||
|
{
|
||
|
PolicyInformation pInfo = PolicyInformation.GetInstance(ae.ToAsn1Object());
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(pInfo.PolicyIdentifier.Id))
|
||
|
{
|
||
|
ISet _apq = PkixCertPathValidatorUtilities.GetQualifierSet(pInfo.PolicyQualifiers);
|
||
|
IList _nodes = policyNodes[i - 1];
|
||
|
|
||
|
for (int k = 0; k < _nodes.Count; k++)
|
||
|
{
|
||
|
PkixPolicyNode _node = (PkixPolicyNode)_nodes[k];
|
||
|
|
||
|
IEnumerator _policySetIter = _node.ExpectedPolicies.GetEnumerator();
|
||
|
while (_policySetIter.MoveNext())
|
||
|
{
|
||
|
object _tmp = _policySetIter.Current;
|
||
|
|
||
|
string _policy;
|
||
|
if (_tmp is string)
|
||
|
{
|
||
|
_policy = (string)_tmp;
|
||
|
}
|
||
|
else if (_tmp is DerObjectIdentifier)
|
||
|
{
|
||
|
_policy = ((DerObjectIdentifier)_tmp).Id;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
bool _found = false;
|
||
|
|
||
|
foreach (PkixPolicyNode _child in _node.Children)
|
||
|
{
|
||
|
if (_policy.Equals(_child.ValidPolicy))
|
||
|
{
|
||
|
_found = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!_found)
|
||
|
{
|
||
|
ISet _newChildExpectedPolicies = new HashSet();
|
||
|
_newChildExpectedPolicies.Add(_policy);
|
||
|
|
||
|
PkixPolicyNode _newChild = new PkixPolicyNode(BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList(), i,
|
||
|
_newChildExpectedPolicies, _node, _apq, _policy, false);
|
||
|
_node.AddChild(_newChild);
|
||
|
policyNodes[i].Add(_newChild);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PkixPolicyNode _validPolicyTree = validPolicyTree;
|
||
|
//
|
||
|
// (d) (3)
|
||
|
//
|
||
|
for (int j = (i - 1); j >= 0; j--)
|
||
|
{
|
||
|
IList nodes = policyNodes[j];
|
||
|
|
||
|
for (int k = 0; k < nodes.Count; k++)
|
||
|
{
|
||
|
PkixPolicyNode node = (PkixPolicyNode)nodes[k];
|
||
|
if (!node.HasChildren)
|
||
|
{
|
||
|
_validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(_validPolicyTree, policyNodes,
|
||
|
node);
|
||
|
if (_validPolicyTree == null)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// d (4)
|
||
|
//
|
||
|
ISet criticalExtensionOids = cert.GetCriticalExtensionOids();
|
||
|
|
||
|
if (criticalExtensionOids != null)
|
||
|
{
|
||
|
bool critical = criticalExtensionOids.Contains(X509Extensions.CertificatePolicies.Id);
|
||
|
|
||
|
IList nodes = policyNodes[i];
|
||
|
for (int j = 0; j < nodes.Count; j++)
|
||
|
{
|
||
|
PkixPolicyNode node = (PkixPolicyNode)nodes[j];
|
||
|
node.IsCritical = critical;
|
||
|
}
|
||
|
}
|
||
|
return _validPolicyTree;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* If the DP includes cRLIssuer, then verify that the issuer field in the
|
||
|
* complete CRL matches cRLIssuer in the DP and that the complete CRL
|
||
|
* contains an
|
||
|
* g distribution point extension with the indirectCRL
|
||
|
* boolean asserted. Otherwise, verify that the CRL issuer matches the
|
||
|
* certificate issuer.
|
||
|
*
|
||
|
* @param dp The distribution point.
|
||
|
* @param cert The certificate ot attribute certificate.
|
||
|
* @param crl The CRL for <code>cert</code>.
|
||
|
* @throws AnnotatedException if one of the above conditions does not apply or an error
|
||
|
* occurs.
|
||
|
*/
|
||
|
internal static void ProcessCrlB1(
|
||
|
DistributionPoint dp,
|
||
|
object cert,
|
||
|
X509Crl crl)
|
||
|
{
|
||
|
Asn1Object idp = PkixCertPathValidatorUtilities.GetExtensionValue(
|
||
|
crl, X509Extensions.IssuingDistributionPoint);
|
||
|
|
||
|
bool isIndirect = false;
|
||
|
if (idp != null)
|
||
|
{
|
||
|
if (IssuingDistributionPoint.GetInstance(idp).IsIndirectCrl)
|
||
|
{
|
||
|
isIndirect = true;
|
||
|
}
|
||
|
}
|
||
|
byte[] issuerBytes = crl.IssuerDN.GetEncoded();
|
||
|
|
||
|
bool matchIssuer = false;
|
||
|
if (dp.CrlIssuer != null)
|
||
|
{
|
||
|
GeneralName[] genNames = dp.CrlIssuer.GetNames();
|
||
|
for (int j = 0; j < genNames.Length; j++)
|
||
|
{
|
||
|
if (genNames[j].TagNo == GeneralName.DirectoryName)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Arrays.AreEqual(genNames[j].Name.ToAsn1Object().GetEncoded(), issuerBytes))
|
||
|
{
|
||
|
matchIssuer = true;
|
||
|
}
|
||
|
}
|
||
|
catch (IOException e)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"CRL issuer information from distribution point cannot be decoded.", e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (matchIssuer && !isIndirect)
|
||
|
{
|
||
|
throw new Exception("Distribution point contains cRLIssuer field but CRL is not indirect.");
|
||
|
}
|
||
|
if (!matchIssuer)
|
||
|
{
|
||
|
throw new Exception("CRL issuer of CRL does not match CRL issuer of distribution point.");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (crl.IssuerDN.Equivalent(PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert), true))
|
||
|
{
|
||
|
matchIssuer = true;
|
||
|
}
|
||
|
}
|
||
|
if (!matchIssuer)
|
||
|
{
|
||
|
throw new Exception("Cannot find matching CRL issuer for certificate.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static ReasonsMask ProcessCrlD(
|
||
|
X509Crl crl,
|
||
|
DistributionPoint dp)
|
||
|
//throws AnnotatedException
|
||
|
{
|
||
|
IssuingDistributionPoint idp = null;
|
||
|
try
|
||
|
{
|
||
|
idp = IssuingDistributionPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.IssuingDistributionPoint));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("issuing distribution point extension could not be decoded.", e);
|
||
|
}
|
||
|
|
||
|
// (d) (1)
|
||
|
if (idp != null && idp.OnlySomeReasons != null && dp.Reasons != null)
|
||
|
{
|
||
|
return new ReasonsMask(dp.Reasons.IntValue).Intersect(new ReasonsMask(idp.OnlySomeReasons
|
||
|
.IntValue));
|
||
|
}
|
||
|
// (d) (4)
|
||
|
if ((idp == null || idp.OnlySomeReasons == null) && dp.Reasons == null)
|
||
|
{
|
||
|
return ReasonsMask.AllReasons;
|
||
|
}
|
||
|
|
||
|
// (d) (2) and (d)(3)
|
||
|
|
||
|
ReasonsMask dpReasons = null;
|
||
|
|
||
|
if (dp.Reasons == null)
|
||
|
{
|
||
|
dpReasons = ReasonsMask.AllReasons;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dpReasons = new ReasonsMask(dp.Reasons.IntValue);
|
||
|
}
|
||
|
|
||
|
ReasonsMask idpReasons = null;
|
||
|
|
||
|
if (idp == null)
|
||
|
{
|
||
|
idpReasons = ReasonsMask.AllReasons;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
idpReasons = new ReasonsMask(idp.OnlySomeReasons.IntValue);
|
||
|
}
|
||
|
|
||
|
return dpReasons.Intersect(idpReasons);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Obtain and validate the certification path for the complete CRL issuer.
|
||
|
* If a key usage extension is present in the CRL issuer's certificate,
|
||
|
* verify that the cRLSign bit is set.
|
||
|
*
|
||
|
* @param crl CRL which contains revocation information for the certificate
|
||
|
* <code>cert</code>.
|
||
|
* @param cert The attribute certificate or certificate to check if it is
|
||
|
* revoked.
|
||
|
* @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
|
||
|
* @param defaultCRLSignKey The public key of the issuer certificate
|
||
|
* <code>defaultCRLSignCert</code>.
|
||
|
* @param paramsPKIX paramsPKIX PKIX parameters.
|
||
|
* @param certPathCerts The certificates on the certification path.
|
||
|
* @return A <code>Set</code> with all keys of possible CRL issuer
|
||
|
* certificates.
|
||
|
* @throws AnnotatedException if the CRL is not valid or the status cannot be checked or
|
||
|
* some error occurs.
|
||
|
*/
|
||
|
internal static ISet ProcessCrlF(
|
||
|
X509Crl crl,
|
||
|
object cert,
|
||
|
X509Certificate defaultCRLSignCert,
|
||
|
AsymmetricKeyParameter defaultCRLSignKey,
|
||
|
PkixParameters paramsPKIX,
|
||
|
IList certPathCerts)
|
||
|
{
|
||
|
// (f)
|
||
|
|
||
|
// get issuer from CRL
|
||
|
X509CertStoreSelector selector = new X509CertStoreSelector();
|
||
|
try
|
||
|
{
|
||
|
selector.Subject = crl.IssuerDN;
|
||
|
}
|
||
|
catch (IOException e)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e);
|
||
|
}
|
||
|
|
||
|
// get CRL signing certs
|
||
|
IList coll = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
|
||
|
try
|
||
|
{
|
||
|
CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetStores()));
|
||
|
CollectionUtilities.AddRange(coll, PkixCertPathValidatorUtilities.FindCertificates(selector, paramsPKIX.GetAdditionalStores()));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Issuer certificate for CRL cannot be searched.", e);
|
||
|
}
|
||
|
|
||
|
coll.Add(defaultCRLSignCert);
|
||
|
|
||
|
IEnumerator cert_it = coll.GetEnumerator();
|
||
|
|
||
|
IList validCerts = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
IList validKeys = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
|
||
|
while (cert_it.MoveNext())
|
||
|
{
|
||
|
X509Certificate signingCert = (X509Certificate)cert_it.Current;
|
||
|
|
||
|
/*
|
||
|
* CA of the certificate, for which this CRL is checked, has also
|
||
|
* signed CRL, so skip the path validation, because is already done
|
||
|
*/
|
||
|
if (signingCert.Equals(defaultCRLSignCert))
|
||
|
{
|
||
|
validCerts.Add(signingCert);
|
||
|
validKeys.Add(defaultCRLSignKey);
|
||
|
continue;
|
||
|
}
|
||
|
try
|
||
|
{
|
||
|
// CertPathBuilder builder = CertPathBuilder.GetInstance("PKIX");
|
||
|
PkixCertPathBuilder builder = new PkixCertPathBuilder();
|
||
|
selector = new X509CertStoreSelector();
|
||
|
selector.Certificate = signingCert;
|
||
|
|
||
|
PkixParameters temp = (PkixParameters)paramsPKIX.Clone();
|
||
|
temp.SetTargetCertConstraints(selector);
|
||
|
|
||
|
PkixBuilderParameters parameters = (PkixBuilderParameters)
|
||
|
PkixBuilderParameters.GetInstance(temp);
|
||
|
|
||
|
/*
|
||
|
* if signingCert is placed not higher on the cert path a
|
||
|
* dependency loop results. CRL for cert is checked, but
|
||
|
* signingCert is needed for checking the CRL which is dependent
|
||
|
* on checking cert because it is higher in the cert path and so
|
||
|
* signing signingCert transitively. so, revocation is disabled,
|
||
|
* forgery attacks of the CRL are detected in this outer loop
|
||
|
* for all other it must be enabled to prevent forgery attacks
|
||
|
*/
|
||
|
if (certPathCerts.Contains(signingCert))
|
||
|
{
|
||
|
parameters.IsRevocationEnabled = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
parameters.IsRevocationEnabled = true;
|
||
|
}
|
||
|
IList certs = builder.Build(parameters).CertPath.Certificates;
|
||
|
validCerts.Add(signingCert);
|
||
|
validKeys.Add(PkixCertPathValidatorUtilities.GetNextWorkingKey(certs, 0));
|
||
|
}
|
||
|
catch (PkixCertPathBuilderException e)
|
||
|
{
|
||
|
throw new Exception("CertPath for CRL signer failed to validate.", e);
|
||
|
}
|
||
|
catch (PkixCertPathValidatorException e)
|
||
|
{
|
||
|
throw new Exception("Public key of issuer certificate of CRL could not be retrieved.", e);
|
||
|
}
|
||
|
//catch (Exception e)
|
||
|
//{
|
||
|
// throw new Exception(e.Message);
|
||
|
//}
|
||
|
}
|
||
|
|
||
|
ISet checkKeys = new HashSet();
|
||
|
|
||
|
Exception lastException = null;
|
||
|
for (int i = 0; i < validCerts.Count; i++)
|
||
|
{
|
||
|
X509Certificate signCert = (X509Certificate)validCerts[i];
|
||
|
bool[] keyusage = signCert.GetKeyUsage();
|
||
|
|
||
|
if (keyusage != null && (keyusage.Length < 7 || !keyusage[CRL_SIGN]))
|
||
|
{
|
||
|
lastException = new Exception(
|
||
|
"Issuer certificate key usage extension does not permit CRL signing.");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
checkKeys.Add(validKeys[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((checkKeys.Count == 0) && lastException == null)
|
||
|
{
|
||
|
throw new Exception("Cannot find a valid issuer certificate.");
|
||
|
}
|
||
|
if ((checkKeys.Count == 0) && lastException != null)
|
||
|
{
|
||
|
throw lastException;
|
||
|
}
|
||
|
|
||
|
return checkKeys;
|
||
|
}
|
||
|
|
||
|
internal static AsymmetricKeyParameter ProcessCrlG(
|
||
|
X509Crl crl,
|
||
|
ISet keys)
|
||
|
{
|
||
|
Exception lastException = null;
|
||
|
foreach (AsymmetricKeyParameter key in keys)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
crl.Verify(key);
|
||
|
return key;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
lastException = e;
|
||
|
}
|
||
|
}
|
||
|
throw new Exception("Cannot verify CRL.", lastException);
|
||
|
}
|
||
|
|
||
|
internal static X509Crl ProcessCrlH(
|
||
|
ISet deltaCrls,
|
||
|
AsymmetricKeyParameter key)
|
||
|
{
|
||
|
Exception lastException = null;
|
||
|
foreach (X509Crl crl in deltaCrls)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
crl.Verify(key);
|
||
|
return crl;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
lastException = e;
|
||
|
}
|
||
|
}
|
||
|
if (lastException != null)
|
||
|
{
|
||
|
throw new Exception("Cannot verify delta CRL.", lastException);
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks a distribution point for revocation information for the
|
||
|
* certificate <code>cert</code>.
|
||
|
*
|
||
|
* @param dp The distribution point to consider.
|
||
|
* @param paramsPKIX PKIX parameters.
|
||
|
* @param cert Certificate to check if it is revoked.
|
||
|
* @param validDate The date when the certificate revocation status should be
|
||
|
* checked.
|
||
|
* @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
|
||
|
* @param defaultCRLSignKey The public key of the issuer certificate
|
||
|
* <code>defaultCRLSignCert</code>.
|
||
|
* @param certStatus The current certificate revocation status.
|
||
|
* @param reasonMask The reasons mask which is already checked.
|
||
|
* @param certPathCerts The certificates of the certification path.
|
||
|
* @throws AnnotatedException if the certificate is revoked or the status cannot be checked
|
||
|
* or some error occurs.
|
||
|
*/
|
||
|
private static void CheckCrl(
|
||
|
DistributionPoint dp,
|
||
|
PkixParameters paramsPKIX,
|
||
|
X509Certificate cert,
|
||
|
DateTime validDate,
|
||
|
X509Certificate defaultCRLSignCert,
|
||
|
AsymmetricKeyParameter defaultCRLSignKey,
|
||
|
CertStatus certStatus,
|
||
|
ReasonsMask reasonMask,
|
||
|
IList certPathCerts)
|
||
|
//throws AnnotatedException
|
||
|
{
|
||
|
DateTime currentDate = DateTime.UtcNow;
|
||
|
|
||
|
if (validDate.Ticks > currentDate.Ticks)
|
||
|
{
|
||
|
throw new Exception("Validation time is in future.");
|
||
|
}
|
||
|
|
||
|
// (a)
|
||
|
/*
|
||
|
* We always get timely valid CRLs, so there is no step (a) (1).
|
||
|
* "locally cached" CRLs are assumed to be in getStore(), additional
|
||
|
* CRLs must be enabled in the ExtendedPKIXParameters and are in
|
||
|
* getAdditionalStore()
|
||
|
*/
|
||
|
|
||
|
ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, cert, currentDate, paramsPKIX);
|
||
|
bool validCrlFound = false;
|
||
|
Exception lastException = null;
|
||
|
|
||
|
IEnumerator crl_iter = crls.GetEnumerator();
|
||
|
|
||
|
while (crl_iter.MoveNext() && certStatus.Status == CertStatus.Unrevoked && !reasonMask.IsAllReasons)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
X509Crl crl = (X509Crl)crl_iter.Current;
|
||
|
|
||
|
// (d)
|
||
|
ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp);
|
||
|
|
||
|
// (e)
|
||
|
/*
|
||
|
* The reasons mask is updated at the end, so only valid CRLs
|
||
|
* can update it. If this CRL does not contain new reasons it
|
||
|
* must be ignored.
|
||
|
*/
|
||
|
if (!interimReasonsMask.HasNewReasons(reasonMask))
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// (f)
|
||
|
ISet keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, cert, defaultCRLSignCert, defaultCRLSignKey,
|
||
|
paramsPKIX, certPathCerts);
|
||
|
// (g)
|
||
|
AsymmetricKeyParameter key = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys);
|
||
|
|
||
|
X509Crl deltaCRL = null;
|
||
|
|
||
|
if (paramsPKIX.IsUseDeltasEnabled)
|
||
|
{
|
||
|
// get delta CRLs
|
||
|
ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl);
|
||
|
// we only want one valid delta CRL
|
||
|
// (h)
|
||
|
deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, key);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* CRL must be be valid at the current time, not the validation
|
||
|
* time. If a certificate is revoked with reason keyCompromise,
|
||
|
* cACompromise, it can be used for forgery, also for the past.
|
||
|
* This reason may not be contained in older CRLs.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* in the chain model signatures stay valid also after the
|
||
|
* certificate has been expired, so they do not have to be in
|
||
|
* the CRL validity time
|
||
|
*/
|
||
|
|
||
|
if (paramsPKIX.ValidityModel != PkixParameters.ChainValidityModel)
|
||
|
{
|
||
|
/*
|
||
|
* if a certificate has expired, but was revoked, it is not
|
||
|
* more in the CRL, so it would be regarded as valid if the
|
||
|
* first check is not done
|
||
|
*/
|
||
|
if (cert.NotAfter.Ticks < crl.ThisUpdate.Ticks)
|
||
|
{
|
||
|
throw new Exception("No valid CRL for current time found.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Rfc3280CertPathUtilities.ProcessCrlB1(dp, cert, crl);
|
||
|
|
||
|
// (b) (2)
|
||
|
Rfc3280CertPathUtilities.ProcessCrlB2(dp, cert, crl);
|
||
|
|
||
|
// (c)
|
||
|
Rfc3280CertPathUtilities.ProcessCrlC(deltaCRL, crl, paramsPKIX);
|
||
|
|
||
|
// (i)
|
||
|
Rfc3280CertPathUtilities.ProcessCrlI(validDate, deltaCRL, cert, certStatus, paramsPKIX);
|
||
|
|
||
|
// (j)
|
||
|
Rfc3280CertPathUtilities.ProcessCrlJ(validDate, crl, cert, certStatus);
|
||
|
|
||
|
// (k)
|
||
|
if (certStatus.Status == CrlReason.RemoveFromCrl)
|
||
|
{
|
||
|
certStatus.Status = CertStatus.Unrevoked;
|
||
|
}
|
||
|
|
||
|
// update reasons mask
|
||
|
reasonMask.AddReasons(interimReasonsMask);
|
||
|
|
||
|
ISet criticalExtensions = crl.GetCriticalExtensionOids();
|
||
|
|
||
|
if (criticalExtensions != null)
|
||
|
{
|
||
|
criticalExtensions = new HashSet(criticalExtensions);
|
||
|
criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id);
|
||
|
criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id);
|
||
|
|
||
|
if (!criticalExtensions.IsEmpty)
|
||
|
throw new Exception("CRL contains unsupported critical extensions.");
|
||
|
}
|
||
|
|
||
|
if (deltaCRL != null)
|
||
|
{
|
||
|
criticalExtensions = deltaCRL.GetCriticalExtensionOids();
|
||
|
if (criticalExtensions != null)
|
||
|
{
|
||
|
criticalExtensions = new HashSet(criticalExtensions);
|
||
|
criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id);
|
||
|
criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id);
|
||
|
|
||
|
if (!criticalExtensions.IsEmpty)
|
||
|
throw new Exception("Delta CRL contains unsupported critical extension.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
validCrlFound = true;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
lastException = e;
|
||
|
}
|
||
|
}
|
||
|
if (!validCrlFound)
|
||
|
{
|
||
|
throw lastException;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks a certificate if it is revoked.
|
||
|
*
|
||
|
* @param paramsPKIX PKIX parameters.
|
||
|
* @param cert Certificate to check if it is revoked.
|
||
|
* @param validDate The date when the certificate revocation status should be
|
||
|
* checked.
|
||
|
* @param sign The issuer certificate of the certificate <code>cert</code>.
|
||
|
* @param workingPublicKey The public key of the issuer certificate <code>sign</code>.
|
||
|
* @param certPathCerts The certificates of the certification path.
|
||
|
* @throws AnnotatedException if the certificate is revoked or the status cannot be checked
|
||
|
* or some error occurs.
|
||
|
*/
|
||
|
protected static void CheckCrls(
|
||
|
PkixParameters paramsPKIX,
|
||
|
X509Certificate cert,
|
||
|
DateTime validDate,
|
||
|
X509Certificate sign,
|
||
|
AsymmetricKeyParameter workingPublicKey,
|
||
|
IList certPathCerts)
|
||
|
{
|
||
|
Exception lastException = null;
|
||
|
CrlDistPoint crldp = null;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
crldp = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CrlDistributionPoints));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("CRL distribution point extension could not be read.", e);
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"No additional CRL locations could be decoded from CRL distribution point extension.", e);
|
||
|
}
|
||
|
CertStatus certStatus = new CertStatus();
|
||
|
ReasonsMask reasonsMask = new ReasonsMask();
|
||
|
|
||
|
bool validCrlFound = false;
|
||
|
|
||
|
// for each distribution point
|
||
|
if (crldp != null)
|
||
|
{
|
||
|
DistributionPoint[] dps = null;
|
||
|
try
|
||
|
{
|
||
|
dps = crldp.GetDistributionPoints();
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Distribution points could not be read.", e);
|
||
|
}
|
||
|
if (dps != null)
|
||
|
{
|
||
|
for (int i = 0; i < dps.Length && certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons; i++)
|
||
|
{
|
||
|
PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone();
|
||
|
try
|
||
|
{
|
||
|
CheckCrl(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts);
|
||
|
validCrlFound = true;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
lastException = e;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* If the revocation status has not been determined, repeat the process
|
||
|
* above with any available CRLs not specified in a distribution point
|
||
|
* but issued by the certificate issuer.
|
||
|
*/
|
||
|
|
||
|
if (certStatus.Status == CertStatus.Unrevoked && !reasonsMask.IsAllReasons)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
/*
|
||
|
* assume a DP with both the reasons and the cRLIssuer fields
|
||
|
* omitted and a distribution point name of the certificate
|
||
|
* issuer.
|
||
|
*/
|
||
|
X509Name issuer;
|
||
|
try
|
||
|
{
|
||
|
issuer = X509Name.GetInstance(cert.IssuerDN.GetEncoded());
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Issuer from certificate for CRL could not be reencoded.", e);
|
||
|
}
|
||
|
DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(
|
||
|
new GeneralName(GeneralName.DirectoryName, issuer))), null, null);
|
||
|
PkixParameters paramsPKIXClone = (PkixParameters)paramsPKIX.Clone();
|
||
|
|
||
|
CheckCrl(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask,
|
||
|
certPathCerts);
|
||
|
|
||
|
validCrlFound = true;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
lastException = e;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!validCrlFound)
|
||
|
{
|
||
|
throw lastException;
|
||
|
}
|
||
|
if (certStatus.Status != CertStatus.Unrevoked)
|
||
|
{
|
||
|
// This format is enforced by the NistCertPath tests
|
||
|
string formattedDate = certStatus.RevocationDate.Value.ToString(
|
||
|
"ddd MMM dd HH:mm:ss K yyyy");
|
||
|
string message = "Certificate revocation after " + formattedDate;
|
||
|
message += ", reason: " + CrlReasons[certStatus.Status];
|
||
|
throw new Exception(message);
|
||
|
}
|
||
|
|
||
|
if (!reasonsMask.IsAllReasons && certStatus.Status == CertStatus.Unrevoked)
|
||
|
{
|
||
|
certStatus.Status = CertStatus.Undetermined;
|
||
|
}
|
||
|
|
||
|
if (certStatus.Status == CertStatus.Undetermined)
|
||
|
{
|
||
|
throw new Exception("Certificate status could not be determined.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static PkixPolicyNode PrepareCertB(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
IList[] policyNodes,
|
||
|
PkixPolicyNode validPolicyTree,
|
||
|
int policyMapping)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
int n = certs.Count;
|
||
|
// i as defined in the algorithm description
|
||
|
int i = n - index;
|
||
|
// (b)
|
||
|
//
|
||
|
Asn1Sequence pm = null;
|
||
|
try
|
||
|
{
|
||
|
pm = (Asn1Sequence)Asn1Sequence.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyMappings));
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy mappings extension could not be decoded.", ex, certPath, index);
|
||
|
}
|
||
|
PkixPolicyNode _validPolicyTree = validPolicyTree;
|
||
|
if (pm != null)
|
||
|
{
|
||
|
Asn1Sequence mappings = (Asn1Sequence)pm;
|
||
|
IDictionary m_idp = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
|
||
|
ISet s_idp = new HashSet();
|
||
|
|
||
|
for (int j = 0; j < mappings.Count; j++)
|
||
|
{
|
||
|
Asn1Sequence mapping = (Asn1Sequence) mappings[j];
|
||
|
string id_p = ((DerObjectIdentifier) mapping[0]).Id;
|
||
|
string sd_p = ((DerObjectIdentifier) mapping[1]).Id;
|
||
|
ISet tmp;
|
||
|
|
||
|
if (!m_idp.Contains(id_p))
|
||
|
{
|
||
|
tmp = new HashSet();
|
||
|
tmp.Add(sd_p);
|
||
|
m_idp[id_p] = tmp;
|
||
|
s_idp.Add(id_p);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tmp = (ISet)m_idp[id_p];
|
||
|
tmp.Add(sd_p);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IEnumerator it_idp = s_idp.GetEnumerator();
|
||
|
while (it_idp.MoveNext())
|
||
|
{
|
||
|
string id_p = (string)it_idp.Current;
|
||
|
|
||
|
//
|
||
|
// (1)
|
||
|
//
|
||
|
if (policyMapping > 0)
|
||
|
{
|
||
|
bool idp_found = false;
|
||
|
IEnumerator nodes_i = policyNodes[i].GetEnumerator();
|
||
|
|
||
|
while (nodes_i.MoveNext())
|
||
|
{
|
||
|
PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current;
|
||
|
if (node.ValidPolicy.Equals(id_p))
|
||
|
{
|
||
|
idp_found = true;
|
||
|
node.ExpectedPolicies = (ISet)m_idp[id_p];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!idp_found)
|
||
|
{
|
||
|
nodes_i = policyNodes[i].GetEnumerator();
|
||
|
while (nodes_i.MoveNext())
|
||
|
{
|
||
|
PkixPolicyNode node = (PkixPolicyNode)nodes_i.Current;
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(node.ValidPolicy))
|
||
|
{
|
||
|
ISet pq = null;
|
||
|
Asn1Sequence policies = null;
|
||
|
try
|
||
|
{
|
||
|
policies = (Asn1Sequence)PkixCertPathValidatorUtilities.GetExtensionValue(cert,
|
||
|
X509Extensions.CertificatePolicies);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Certificate policies extension could not be decoded.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
foreach (Asn1Encodable ae in policies)
|
||
|
{
|
||
|
PolicyInformation pinfo = null;
|
||
|
try
|
||
|
{
|
||
|
pinfo = PolicyInformation.GetInstance(ae.ToAsn1Object());
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy information could not be decoded.", ex, certPath, index);
|
||
|
}
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(pinfo.PolicyIdentifier.Id))
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
pq = PkixCertPathValidatorUtilities
|
||
|
.GetQualifierSet(pinfo.PolicyQualifiers);
|
||
|
}
|
||
|
catch (PkixCertPathValidatorException ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy qualifier info set could not be decoded.", ex, certPath,
|
||
|
index);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
bool ci = false;
|
||
|
ISet critExtOids = cert.GetCriticalExtensionOids();
|
||
|
if (critExtOids != null)
|
||
|
{
|
||
|
ci = critExtOids.Contains(X509Extensions.CertificatePolicies.Id);
|
||
|
}
|
||
|
|
||
|
PkixPolicyNode p_node = (PkixPolicyNode)node.Parent;
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(p_node.ValidPolicy))
|
||
|
{
|
||
|
PkixPolicyNode c_node = new PkixPolicyNode(BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList(), i,
|
||
|
(ISet)m_idp[id_p], p_node, pq, id_p, ci);
|
||
|
p_node.AddChild(c_node);
|
||
|
policyNodes[i].Add(c_node);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// (2)
|
||
|
//
|
||
|
}
|
||
|
else if (policyMapping <= 0)
|
||
|
{
|
||
|
foreach (PkixPolicyNode node in BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList(policyNodes[i]))
|
||
|
{
|
||
|
if (node.ValidPolicy.Equals(id_p))
|
||
|
{
|
||
|
node.Parent.RemoveChild(node);
|
||
|
|
||
|
for (int k = i - 1; k >= 0; k--)
|
||
|
{
|
||
|
foreach (PkixPolicyNode node2 in BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList(policyNodes[k]))
|
||
|
{
|
||
|
if (!node2.HasChildren)
|
||
|
{
|
||
|
_validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(
|
||
|
_validPolicyTree, policyNodes, node2);
|
||
|
|
||
|
if (_validPolicyTree == null)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return _validPolicyTree;
|
||
|
}
|
||
|
|
||
|
internal static ISet[] ProcessCrlA1ii(
|
||
|
DateTime currentDate,
|
||
|
PkixParameters paramsPKIX,
|
||
|
X509Certificate cert,
|
||
|
X509Crl crl)
|
||
|
{
|
||
|
ISet deltaSet = new HashSet();
|
||
|
X509CrlStoreSelector crlselect = new X509CrlStoreSelector();
|
||
|
crlselect.CertificateChecking = cert;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
IList issuer = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
|
||
|
issuer.Add(crl.IssuerDN);
|
||
|
crlselect.Issuers = issuer;
|
||
|
}
|
||
|
catch (IOException e)
|
||
|
{
|
||
|
throw new Exception("Cannot extract issuer from CRL." + e, e);
|
||
|
}
|
||
|
|
||
|
crlselect.CompleteCrlEnabled = true;
|
||
|
ISet completeSet = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate);
|
||
|
|
||
|
if (paramsPKIX.IsUseDeltasEnabled)
|
||
|
{
|
||
|
// get delta CRL(s)
|
||
|
try
|
||
|
{
|
||
|
deltaSet.AddAll(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Exception obtaining delta CRLs.", e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return new ISet[]{ completeSet, deltaSet };
|
||
|
}
|
||
|
|
||
|
internal static ISet ProcessCrlA1i(
|
||
|
DateTime currentDate,
|
||
|
PkixParameters paramsPKIX,
|
||
|
X509Certificate cert,
|
||
|
X509Crl crl)
|
||
|
{
|
||
|
ISet deltaSet = new HashSet();
|
||
|
if (paramsPKIX.IsUseDeltasEnabled)
|
||
|
{
|
||
|
CrlDistPoint freshestCRL = null;
|
||
|
try
|
||
|
{
|
||
|
freshestCRL = CrlDistPoint.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.FreshestCrl));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Freshest CRL extension could not be decoded from certificate.", e);
|
||
|
}
|
||
|
|
||
|
if (freshestCRL == null)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
freshestCRL = CrlDistPoint.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(crl, X509Extensions.FreshestCrl));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Freshest CRL extension could not be decoded from CRL.", e);
|
||
|
}
|
||
|
}
|
||
|
if (freshestCRL != null)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
PkixCertPathValidatorUtilities.AddAdditionalStoresFromCrlDistributionPoint(freshestCRL, paramsPKIX);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"No new delta CRL locations could be added from Freshest CRL extension.", e);
|
||
|
}
|
||
|
// get delta CRL(s)
|
||
|
try
|
||
|
{
|
||
|
deltaSet.AddAll(PkixCertPathValidatorUtilities.GetDeltaCrls(currentDate, paramsPKIX, crl));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("Exception obtaining delta CRLs.", e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return deltaSet;
|
||
|
}
|
||
|
|
||
|
internal static void ProcessCertF(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
PkixPolicyNode validPolicyTree,
|
||
|
int explicitPolicy)
|
||
|
{
|
||
|
//
|
||
|
// (f)
|
||
|
//
|
||
|
if (explicitPolicy <= 0 && validPolicyTree == null)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"No valid policy tree found when one expected.", null, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void ProcessCertA(
|
||
|
PkixCertPath certPath,
|
||
|
PkixParameters paramsPKIX,
|
||
|
int index,
|
||
|
AsymmetricKeyParameter workingPublicKey,
|
||
|
X509Name workingIssuerName,
|
||
|
X509Certificate sign)
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
//
|
||
|
// (a) verify
|
||
|
//
|
||
|
try
|
||
|
{
|
||
|
// (a) (1)
|
||
|
//
|
||
|
cert.Verify(workingPublicKey);
|
||
|
}
|
||
|
catch (GeneralSecurityException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Could not validate certificate signature.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// (a) (2)
|
||
|
//
|
||
|
cert.CheckValidity(PkixCertPathValidatorUtilities
|
||
|
.GetValidCertDateFromValidityModel(paramsPKIX, certPath, index));
|
||
|
}
|
||
|
catch (CertificateExpiredException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, certPath, index);
|
||
|
}
|
||
|
catch (CertificateNotYetValidException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Could not validate certificate: " + e.Message, e, certPath, index);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// (a) (3)
|
||
|
//
|
||
|
if (paramsPKIX.IsRevocationEnabled)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
CheckCrls(paramsPKIX, cert, PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(paramsPKIX,
|
||
|
certPath, index), sign, workingPublicKey, certs);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
Exception cause = e.InnerException;
|
||
|
if (cause == null)
|
||
|
{
|
||
|
cause = e;
|
||
|
}
|
||
|
throw new PkixCertPathValidatorException(e.Message, cause, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// (a) (4) name chaining
|
||
|
//
|
||
|
X509Name issuer = PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert);
|
||
|
if (!issuer.Equivalent(workingIssuerName, true))
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("IssuerName(" + issuer
|
||
|
+ ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null,
|
||
|
certPath, index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static int PrepareNextCertI1(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int explicitPolicy)
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
//
|
||
|
// (i)
|
||
|
//
|
||
|
Asn1Sequence pc = null;
|
||
|
try
|
||
|
{
|
||
|
pc = Asn1Sequence.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyConstraints));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy constraints extension cannot be decoded.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
int tmpInt;
|
||
|
|
||
|
if (pc != null)
|
||
|
{
|
||
|
IEnumerator policyConstraints = pc.GetEnumerator();
|
||
|
|
||
|
while (policyConstraints.MoveNext())
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current);
|
||
|
if (constraint.TagNo == 0)
|
||
|
{
|
||
|
tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
|
||
|
if (tmpInt < explicitPolicy)
|
||
|
{
|
||
|
return tmpInt;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
catch (ArgumentException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy constraints extension contents cannot be decoded.", e, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return explicitPolicy;
|
||
|
}
|
||
|
|
||
|
internal static int PrepareNextCertI2(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int policyMapping)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (i)
|
||
|
//
|
||
|
Asn1Sequence pc = null;
|
||
|
try
|
||
|
{
|
||
|
pc = Asn1Sequence.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyConstraints));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy constraints extension cannot be decoded.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
int tmpInt;
|
||
|
|
||
|
if (pc != null)
|
||
|
{
|
||
|
IEnumerator policyConstraints = pc.GetEnumerator();
|
||
|
|
||
|
while (policyConstraints.MoveNext())
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
Asn1TaggedObject constraint = Asn1TaggedObject.GetInstance(policyConstraints.Current);
|
||
|
if (constraint.TagNo == 1)
|
||
|
{
|
||
|
tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
|
||
|
if (tmpInt < policyMapping)
|
||
|
{
|
||
|
return tmpInt;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
catch (ArgumentException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy constraints extension contents cannot be decoded.", e, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return policyMapping;
|
||
|
}
|
||
|
|
||
|
internal static void PrepareNextCertG(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
PkixNameConstraintValidator nameConstraintValidator)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (g) handle the name constraints extension
|
||
|
//
|
||
|
NameConstraints nc = null;
|
||
|
try
|
||
|
{
|
||
|
Asn1Sequence ncSeq = Asn1Sequence.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.NameConstraints));
|
||
|
if (ncSeq != null)
|
||
|
{
|
||
|
nc = new NameConstraints(ncSeq);
|
||
|
}
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Name constraints extension could not be decoded.", e, certPath, index);
|
||
|
}
|
||
|
if (nc != null)
|
||
|
{
|
||
|
//
|
||
|
// (g) (1) permitted subtrees
|
||
|
//
|
||
|
Asn1Sequence permitted = nc.PermittedSubtrees;
|
||
|
if (permitted != null)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
nameConstraintValidator.IntersectPermittedSubtree(permitted);
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// (g) (2) excluded subtrees
|
||
|
//
|
||
|
Asn1Sequence excluded = nc.ExcludedSubtrees;
|
||
|
if (excluded != null)
|
||
|
{
|
||
|
IEnumerator e = excluded.GetEnumerator();
|
||
|
try
|
||
|
{
|
||
|
while (e.MoveNext())
|
||
|
{
|
||
|
GeneralSubtree subtree = GeneralSubtree.GetInstance(e.Current);
|
||
|
nameConstraintValidator.AddExcludedSubtree(subtree);
|
||
|
}
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static int PrepareNextCertJ(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int inhibitAnyPolicy)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (j)
|
||
|
//
|
||
|
DerInteger iap = null;
|
||
|
try
|
||
|
{
|
||
|
iap = DerInteger.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.InhibitAnyPolicy));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Inhibit any-policy extension cannot be decoded.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
if (iap != null)
|
||
|
{
|
||
|
int _inhibitAnyPolicy = iap.IntValueExact;
|
||
|
|
||
|
if (_inhibitAnyPolicy < inhibitAnyPolicy)
|
||
|
return _inhibitAnyPolicy;
|
||
|
}
|
||
|
return inhibitAnyPolicy;
|
||
|
}
|
||
|
|
||
|
internal static void PrepareNextCertK(
|
||
|
PkixCertPath certPath,
|
||
|
int index)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
//
|
||
|
// (k)
|
||
|
//
|
||
|
BasicConstraints bc = null;
|
||
|
try
|
||
|
{
|
||
|
bc = BasicConstraints.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.BasicConstraints));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
|
||
|
index);
|
||
|
}
|
||
|
if (bc != null)
|
||
|
{
|
||
|
if (!(bc.IsCA()))
|
||
|
throw new PkixCertPathValidatorException("Not a CA certificate");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Intermediate certificate lacks BasicConstraints");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static int PrepareNextCertL(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int maxPathLength)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
//
|
||
|
// (l)
|
||
|
//
|
||
|
if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert))
|
||
|
{
|
||
|
if (maxPathLength <= 0)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Max path length not greater than zero", null, certPath, index);
|
||
|
}
|
||
|
|
||
|
return maxPathLength - 1;
|
||
|
}
|
||
|
return maxPathLength;
|
||
|
}
|
||
|
|
||
|
internal static int PrepareNextCertM(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int maxPathLength)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (m)
|
||
|
//
|
||
|
BasicConstraints bc = null;
|
||
|
try
|
||
|
{
|
||
|
bc = BasicConstraints.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.BasicConstraints));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
|
||
|
index);
|
||
|
}
|
||
|
if (bc != null)
|
||
|
{
|
||
|
BigInteger _pathLengthConstraint = bc.PathLenConstraint;
|
||
|
|
||
|
if (_pathLengthConstraint != null)
|
||
|
{
|
||
|
int _plc = _pathLengthConstraint.IntValue;
|
||
|
|
||
|
if (_plc < maxPathLength)
|
||
|
{
|
||
|
return _plc;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return maxPathLength;
|
||
|
}
|
||
|
|
||
|
internal static void PrepareNextCertN(
|
||
|
PkixCertPath certPath,
|
||
|
int index)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (n)
|
||
|
//
|
||
|
bool[] _usage = cert.GetKeyUsage();
|
||
|
|
||
|
if ((_usage != null) && !_usage[Rfc3280CertPathUtilities.KEY_CERT_SIGN])
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Issuer certificate keyusage extension is critical and does not permit key signing.", null,
|
||
|
certPath, index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void PrepareNextCertO(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
ISet criticalExtensions,
|
||
|
IList pathCheckers)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (o)
|
||
|
//
|
||
|
IEnumerator tmpIter = pathCheckers.GetEnumerator();
|
||
|
while (tmpIter.MoveNext())
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
((PkixCertPathChecker)tmpIter.Current).Check(cert, criticalExtensions);
|
||
|
}
|
||
|
catch (PkixCertPathValidatorException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(e.Message, e.InnerException, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
if (!criticalExtensions.IsEmpty)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Certificate has unsupported critical extension.", null, certPath,
|
||
|
index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static int PrepareNextCertH1(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int explicitPolicy)
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (h)
|
||
|
//
|
||
|
if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert))
|
||
|
{
|
||
|
//
|
||
|
// (1)
|
||
|
//
|
||
|
if (explicitPolicy != 0)
|
||
|
return explicitPolicy - 1;
|
||
|
}
|
||
|
return explicitPolicy;
|
||
|
}
|
||
|
|
||
|
internal static int PrepareNextCertH2(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int policyMapping)
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (h)
|
||
|
//
|
||
|
if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert))
|
||
|
{
|
||
|
//
|
||
|
// (2)
|
||
|
//
|
||
|
if (policyMapping != 0)
|
||
|
return policyMapping - 1;
|
||
|
}
|
||
|
return policyMapping;
|
||
|
}
|
||
|
|
||
|
|
||
|
internal static int PrepareNextCertH3(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int inhibitAnyPolicy)
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (h)
|
||
|
//
|
||
|
if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert))
|
||
|
{
|
||
|
//
|
||
|
// (3)
|
||
|
//
|
||
|
if (inhibitAnyPolicy != 0)
|
||
|
return inhibitAnyPolicy - 1;
|
||
|
}
|
||
|
return inhibitAnyPolicy;
|
||
|
}
|
||
|
|
||
|
internal static int WrapupCertA(
|
||
|
int explicitPolicy,
|
||
|
X509Certificate cert)
|
||
|
{
|
||
|
//
|
||
|
// (a)
|
||
|
//
|
||
|
if (!PkixCertPathValidatorUtilities.IsSelfIssued(cert) && (explicitPolicy != 0))
|
||
|
{
|
||
|
explicitPolicy--;
|
||
|
}
|
||
|
return explicitPolicy;
|
||
|
}
|
||
|
|
||
|
internal static int WrapupCertB(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
int explicitPolicy)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (b)
|
||
|
//
|
||
|
int tmpInt;
|
||
|
Asn1Sequence pc = null;
|
||
|
try
|
||
|
{
|
||
|
pc = Asn1Sequence.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.PolicyConstraints));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index);
|
||
|
}
|
||
|
|
||
|
if (pc != null)
|
||
|
{
|
||
|
IEnumerator policyConstraints = pc.GetEnumerator();
|
||
|
|
||
|
while (policyConstraints.MoveNext())
|
||
|
{
|
||
|
Asn1TaggedObject constraint = (Asn1TaggedObject)policyConstraints.Current;
|
||
|
switch (constraint.TagNo)
|
||
|
{
|
||
|
case 0:
|
||
|
try
|
||
|
{
|
||
|
tmpInt = DerInteger.GetInstance(constraint, false).IntValueExact;
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath,
|
||
|
index);
|
||
|
}
|
||
|
if (tmpInt == 0)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return explicitPolicy;
|
||
|
}
|
||
|
|
||
|
internal static void WrapupCertF(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
IList pathCheckers,
|
||
|
ISet criticalExtensions)
|
||
|
//throws CertPathValidatorException
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
IEnumerator tmpIter = pathCheckers.GetEnumerator();
|
||
|
|
||
|
while (tmpIter.MoveNext())
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
((PkixCertPathChecker)tmpIter.Current).Check(cert, criticalExtensions);
|
||
|
}
|
||
|
catch (PkixCertPathValidatorException e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Additional certificate path checker failed.", e, certPath,
|
||
|
index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!criticalExtensions.IsEmpty)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Certificate has unsupported critical extension",
|
||
|
null, certPath, index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static PkixPolicyNode WrapupCertG(
|
||
|
PkixCertPath certPath,
|
||
|
PkixParameters paramsPKIX,
|
||
|
ISet userInitialPolicySet,
|
||
|
int index,
|
||
|
IList[] policyNodes,
|
||
|
PkixPolicyNode validPolicyTree,
|
||
|
ISet acceptablePolicies)
|
||
|
{
|
||
|
int n = certPath.Certificates.Count;
|
||
|
|
||
|
//
|
||
|
// (g)
|
||
|
//
|
||
|
PkixPolicyNode intersection;
|
||
|
|
||
|
//
|
||
|
// (g) (i)
|
||
|
//
|
||
|
if (validPolicyTree == null)
|
||
|
{
|
||
|
if (paramsPKIX.IsExplicitPolicyRequired)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Explicit policy requested but none available.", null, certPath, index);
|
||
|
}
|
||
|
intersection = null;
|
||
|
}
|
||
|
else if (PkixCertPathValidatorUtilities.IsAnyPolicy(userInitialPolicySet)) // (g)
|
||
|
// (ii)
|
||
|
{
|
||
|
if (paramsPKIX.IsExplicitPolicyRequired)
|
||
|
{
|
||
|
if (acceptablePolicies.IsEmpty)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException(
|
||
|
"Explicit policy requested but none available.", null, certPath, index);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ISet _validPolicyNodeSet = new HashSet();
|
||
|
|
||
|
for (int j = 0; j < policyNodes.Length; j++)
|
||
|
{
|
||
|
IList _nodeDepth = policyNodes[j];
|
||
|
|
||
|
for (int k = 0; k < _nodeDepth.Count; k++)
|
||
|
{
|
||
|
PkixPolicyNode _node = (PkixPolicyNode)_nodeDepth[k];
|
||
|
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(_node.ValidPolicy))
|
||
|
{
|
||
|
foreach (object o in _node.Children)
|
||
|
{
|
||
|
_validPolicyNodeSet.Add(o);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
foreach (PkixPolicyNode _node in _validPolicyNodeSet)
|
||
|
{
|
||
|
string _validPolicy = _node.ValidPolicy;
|
||
|
|
||
|
if (!acceptablePolicies.Contains(_validPolicy))
|
||
|
{
|
||
|
// TODO?
|
||
|
// validPolicyTree =
|
||
|
// removePolicyNode(validPolicyTree, policyNodes,
|
||
|
// _node);
|
||
|
}
|
||
|
}
|
||
|
if (validPolicyTree != null)
|
||
|
{
|
||
|
for (int j = (n - 1); j >= 0; j--)
|
||
|
{
|
||
|
IList nodes = policyNodes[j];
|
||
|
|
||
|
for (int k = 0; k < nodes.Count; k++)
|
||
|
{
|
||
|
PkixPolicyNode node = (PkixPolicyNode)nodes[k];
|
||
|
if (!node.HasChildren)
|
||
|
{
|
||
|
validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree,
|
||
|
policyNodes, node);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
intersection = validPolicyTree;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// (g) (iii)
|
||
|
//
|
||
|
// This implementation is not exactly same as the one described in
|
||
|
// RFC3280.
|
||
|
// However, as far as the validation result is concerned, both
|
||
|
// produce
|
||
|
// adequate result. The only difference is whether AnyPolicy is
|
||
|
// remain
|
||
|
// in the policy tree or not.
|
||
|
//
|
||
|
// (g) (iii) 1
|
||
|
//
|
||
|
ISet _validPolicyNodeSet = new HashSet();
|
||
|
|
||
|
for (int j = 0; j < policyNodes.Length; j++)
|
||
|
{
|
||
|
IList _nodeDepth = policyNodes[j];
|
||
|
|
||
|
for (int k = 0; k < _nodeDepth.Count; k++)
|
||
|
{
|
||
|
PkixPolicyNode _node = (PkixPolicyNode)_nodeDepth[k];
|
||
|
|
||
|
if (Rfc3280CertPathUtilities.ANY_POLICY.Equals(_node.ValidPolicy))
|
||
|
{
|
||
|
foreach (PkixPolicyNode _c_node in _node.Children)
|
||
|
{
|
||
|
if (!Rfc3280CertPathUtilities.ANY_POLICY.Equals(_c_node.ValidPolicy))
|
||
|
{
|
||
|
_validPolicyNodeSet.Add(_c_node);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// (g) (iii) 2
|
||
|
//
|
||
|
IEnumerator _vpnsIter = _validPolicyNodeSet.GetEnumerator();
|
||
|
while (_vpnsIter.MoveNext())
|
||
|
{
|
||
|
PkixPolicyNode _node = (PkixPolicyNode)_vpnsIter.Current;
|
||
|
string _validPolicy = _node.ValidPolicy;
|
||
|
|
||
|
if (!userInitialPolicySet.Contains(_validPolicy))
|
||
|
{
|
||
|
validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, policyNodes, _node);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// (g) (iii) 4
|
||
|
//
|
||
|
if (validPolicyTree != null)
|
||
|
{
|
||
|
for (int j = (n - 1); j >= 0; j--)
|
||
|
{
|
||
|
IList nodes = policyNodes[j];
|
||
|
|
||
|
for (int k = 0; k < nodes.Count; k++)
|
||
|
{
|
||
|
PkixPolicyNode node = (PkixPolicyNode)nodes[k];
|
||
|
if (!node.HasChildren)
|
||
|
{
|
||
|
validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode(validPolicyTree, policyNodes,
|
||
|
node);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
intersection = validPolicyTree;
|
||
|
}
|
||
|
return intersection;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* If use-deltas is set, verify the issuer and scope of the delta CRL.
|
||
|
*
|
||
|
* @param deltaCRL The delta CRL.
|
||
|
* @param completeCRL The complete CRL.
|
||
|
* @param pkixParams The PKIX paramaters.
|
||
|
* @throws AnnotatedException if an exception occurs.
|
||
|
*/
|
||
|
internal static void ProcessCrlC(
|
||
|
X509Crl deltaCRL,
|
||
|
X509Crl completeCRL,
|
||
|
PkixParameters pkixParams)
|
||
|
{
|
||
|
if (deltaCRL == null)
|
||
|
return;
|
||
|
|
||
|
IssuingDistributionPoint completeidp = null;
|
||
|
try
|
||
|
{
|
||
|
completeidp = IssuingDistributionPoint.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception("000 Issuing distribution point extension could not be decoded.", e);
|
||
|
}
|
||
|
|
||
|
if (pkixParams.IsUseDeltasEnabled)
|
||
|
{
|
||
|
// (c) (1)
|
||
|
if (!deltaCRL.IssuerDN.Equivalent(completeCRL.IssuerDN, true))
|
||
|
throw new Exception("Complete CRL issuer does not match delta CRL issuer.");
|
||
|
|
||
|
// (c) (2)
|
||
|
IssuingDistributionPoint deltaidp = null;
|
||
|
try
|
||
|
{
|
||
|
deltaidp = IssuingDistributionPoint.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(deltaCRL, X509Extensions.IssuingDistributionPoint));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"Issuing distribution point extension from delta CRL could not be decoded.", e);
|
||
|
}
|
||
|
|
||
|
if (!BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.Equals(completeidp, deltaidp))
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"Issuing distribution point extension from delta CRL and complete CRL does not match.");
|
||
|
}
|
||
|
|
||
|
// (c) (3)
|
||
|
Asn1Object completeKeyIdentifier = null;
|
||
|
try
|
||
|
{
|
||
|
completeKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue(
|
||
|
completeCRL, X509Extensions.AuthorityKeyIdentifier);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"Authority key identifier extension could not be extracted from complete CRL.", e);
|
||
|
}
|
||
|
|
||
|
Asn1Object deltaKeyIdentifier = null;
|
||
|
try
|
||
|
{
|
||
|
deltaKeyIdentifier = PkixCertPathValidatorUtilities.GetExtensionValue(
|
||
|
deltaCRL, X509Extensions.AuthorityKeyIdentifier);
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"Authority key identifier extension could not be extracted from delta CRL.", e);
|
||
|
}
|
||
|
|
||
|
if (completeKeyIdentifier == null)
|
||
|
throw new Exception("CRL authority key identifier is null.");
|
||
|
|
||
|
if (deltaKeyIdentifier == null)
|
||
|
throw new Exception("Delta CRL authority key identifier is null.");
|
||
|
|
||
|
if (!completeKeyIdentifier.Equals(deltaKeyIdentifier))
|
||
|
{
|
||
|
throw new Exception(
|
||
|
"Delta CRL authority key identifier does not match complete CRL authority key identifier.");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void ProcessCrlI(
|
||
|
DateTime validDate,
|
||
|
X509Crl deltacrl,
|
||
|
object cert,
|
||
|
CertStatus certStatus,
|
||
|
PkixParameters pkixParams)
|
||
|
{
|
||
|
if (pkixParams.IsUseDeltasEnabled && deltacrl != null)
|
||
|
{
|
||
|
PkixCertPathValidatorUtilities.GetCertStatus(validDate, deltacrl, cert, certStatus);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static void ProcessCrlJ(
|
||
|
DateTime validDate,
|
||
|
X509Crl completecrl,
|
||
|
object cert,
|
||
|
CertStatus certStatus)
|
||
|
{
|
||
|
if (certStatus.Status == CertStatus.Unrevoked)
|
||
|
{
|
||
|
PkixCertPathValidatorUtilities.GetCertStatus(validDate, completecrl, cert, certStatus);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal static PkixPolicyNode ProcessCertE(
|
||
|
PkixCertPath certPath,
|
||
|
int index,
|
||
|
PkixPolicyNode validPolicyTree)
|
||
|
{
|
||
|
IList certs = certPath.Certificates;
|
||
|
X509Certificate cert = (X509Certificate)certs[index];
|
||
|
|
||
|
//
|
||
|
// (e)
|
||
|
//
|
||
|
Asn1Sequence certPolicies = null;
|
||
|
try
|
||
|
{
|
||
|
certPolicies = Asn1Sequence.GetInstance(
|
||
|
PkixCertPathValidatorUtilities.GetExtensionValue(cert, X509Extensions.CertificatePolicies));
|
||
|
}
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
throw new PkixCertPathValidatorException("Could not read certificate policies extension from certificate.",
|
||
|
e, certPath, index);
|
||
|
}
|
||
|
if (certPolicies == null)
|
||
|
{
|
||
|
validPolicyTree = null;
|
||
|
}
|
||
|
return validPolicyTree;
|
||
|
}
|
||
|
|
||
|
internal static readonly string[] CrlReasons = new string[]
|
||
|
{
|
||
|
"unspecified",
|
||
|
"keyCompromise",
|
||
|
"cACompromise",
|
||
|
"affiliationChanged",
|
||
|
"superseded",
|
||
|
"cessationOfOperation",
|
||
|
"certificateHold",
|
||
|
"unknown",
|
||
|
"removeFromCRL",
|
||
|
"privilegeWithdrawn",
|
||
|
"aACompromise"
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
#pragma warning restore
|
||
|
#endif
|