(policyNodes[i]))
{
if (!node.ValidPolicy.Equals(id_p))
{
++pos;
continue;
}
node.Parent.RemoveChild(node);
policyNodes[i].RemoveAt(pos);
for (int k = i - 1; k >= 0; k--)
{
var nodes = policyNodes[k];
for (int l = 0; l < nodes.Count; l++)
{
var node2 = nodes[l];
if (!node2.HasChildren)
{
validPolicyTree = RemovePolicyNode(validPolicyTree, policyNodes, node2);
if (validPolicyTree == null)
break;
}
}
}
}
return validPolicyTree;
}
internal static void GetCertStatus(
DateTime validDate,
X509Crl crl,
object cert,
CertStatus certStatus)
{
X509Crl bcCRL;
try
{
bcCRL = new X509Crl(CertificateList.GetInstance((Asn1Sequence)Asn1Sequence.FromByteArray(crl.GetEncoded())));
}
catch (Exception exception)
{
throw new Exception("X509Crl could not be created.", exception);
}
X509CrlEntry crl_entry = (X509CrlEntry)bcCRL.GetRevokedCertificate(GetSerialNumber(cert));
if (crl_entry == null)
return;
X509Name issuer = GetIssuerPrincipal(cert);
if (!issuer.Equivalent(crl_entry.GetCertificateIssuer(), true)
&& !issuer.Equivalent(crl.IssuerDN, true))
{
return;
}
int reasonCodeValue = CrlReason.Unspecified;
if (crl_entry.HasExtensions)
{
try
{
Asn1Object extValue = GetExtensionValue(crl_entry, X509Extensions.ReasonCode);
DerEnumerated reasonCode = DerEnumerated.GetInstance(extValue);
if (null != reasonCode)
{
reasonCodeValue = reasonCode.IntValueExact;
}
}
catch (Exception e)
{
throw new Exception("Reason code CRL entry extension could not be decoded.", e);
}
}
DateTime revocationDate = crl_entry.RevocationDate;
if (validDate.Ticks < revocationDate.Ticks)
{
switch (reasonCodeValue)
{
case CrlReason.Unspecified:
case CrlReason.KeyCompromise:
case CrlReason.CACompromise:
case CrlReason.AACompromise:
break;
default:
return;
}
}
// (i) or (j)
certStatus.Status = reasonCodeValue;
certStatus.RevocationDate = revocationDate;
}
/**
* Return the next working key inheriting DSA parameters if necessary.
*
* This methods inherits DSA parameters from the indexed certificate or
* previous certificates in the certificate chain to the returned
* PublicKey
. The list is searched upwards, meaning the end
* certificate is at position 0 and previous certificates are following.
*
*
* If the indexed certificate does not contain a DSA key this method simply
* returns the public key. If the DSA key already contains DSA parameters
* the key is also only returned.
*
*
* @param certs The certification path.
* @param index The index of the certificate which contains the public key
* which should be extended with DSA parameters.
* @return The public key of the certificate in list position
* index
extended with DSA parameters if applicable.
* @throws Exception if DSA parameters cannot be inherited.
*/
internal static AsymmetricKeyParameter GetNextWorkingKey(IList certs, int index)
{
X509Certificate cert = certs[index];
AsymmetricKeyParameter pubKey = cert.GetPublicKey();
if (!(pubKey is DsaPublicKeyParameters))
return pubKey;
DsaPublicKeyParameters dsaPubKey = (DsaPublicKeyParameters)pubKey;
if (dsaPubKey.Parameters != null)
return dsaPubKey;
for (int i = index + 1; i < certs.Count; i++)
{
X509Certificate parentCert = certs[i];
pubKey = parentCert.GetPublicKey();
if (!(pubKey is DsaPublicKeyParameters))
{
throw new PkixCertPathValidatorException(
"DSA parameters cannot be inherited from previous certificate.");
}
DsaPublicKeyParameters prevDSAPubKey = (DsaPublicKeyParameters)pubKey;
if (prevDSAPubKey.Parameters == null)
continue;
DsaParameters dsaParams = prevDSAPubKey.Parameters;
try
{
return new DsaPublicKeyParameters(dsaPubKey.Y, dsaParams);
}
catch (Exception exception)
{
throw new Exception(exception.Message);
}
}
throw new PkixCertPathValidatorException("DSA parameters cannot be inherited from previous certificate.");
}
internal static DateTime GetValidCertDateFromValidityModel(
PkixParameters paramsPkix,
PkixCertPath certPath,
int index)
{
if (paramsPkix.ValidityModel != PkixParameters.ChainValidityModel)
{
return GetValidDate(paramsPkix);
}
// if end cert use given signing/encryption/... time
if (index <= 0)
{
return GetValidDate(paramsPkix);
// else use time when previous cert was created
}
var cert = certPath.Certificates[index - 1];
if (index - 1 == 0)
{
Asn1GeneralizedTime dateOfCertgen;
try
{
Asn1OctetString extVal = cert.GetExtensionValue(IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen);
dateOfCertgen = Asn1GeneralizedTime.GetInstance(extVal);
}
catch (ArgumentException)
{
throw new Exception(
"Date of cert gen extension could not be read.");
}
if (dateOfCertgen != null)
{
try
{
return dateOfCertgen.ToDateTime();
}
catch (ArgumentException e)
{
throw new Exception(
"Date from date of cert gen extension could not be parsed.",
e);
}
}
}
return cert.NotBefore;
}
/**
* Add the CRL issuers from the cRLIssuer field of the distribution point or
* from the certificate if not given to the issuer criterion of the
* selector
.
*
* The issuerPrincipals
are a collection with a single
* X500Principal
for X509Certificate
s. For
* {@link X509AttributeCertificate}s the issuer may contain more than one
* X500Principal
.
*
*
* @param dp The distribution point.
* @param issuerPrincipals The issuers of the certificate or attribute
* certificate which contains the distribution point.
* @param selector The CRL selector.
* @param pkixParams The PKIX parameters containing the cert stores.
* @throws Exception if an exception occurs while processing.
* @throws ClassCastException if issuerPrincipals
does not
* contain only X500Principal
s.
*/
internal static void GetCrlIssuersFromDistributionPoint(
DistributionPoint dp,
ICollection issuerPrincipals,
X509CrlStoreSelector selector,
PkixParameters pkixParams)
{
var issuers = new List();
// indirect CRL
if (dp.CrlIssuer != null)
{
GeneralName[] genNames = dp.CrlIssuer.GetNames();
// look for a DN
for (int j = 0; j < genNames.Length; j++)
{
if (genNames[j].TagNo == GeneralName.DirectoryName)
{
try
{
issuers.Add(X509Name.GetInstance(genNames[j].Name.ToAsn1Object()));
}
catch (IOException e)
{
throw new Exception("CRL issuer information from distribution point cannot be decoded.", e);
}
}
}
}
else
{
/*
* certificate issuer is CRL issuer, distributionPoint field MUST be
* present.
*/
if (dp.DistributionPointName == null)
{
throw new Exception(
"CRL issuer is omitted from distribution point but no distributionPoint field present.");
}
// add and check issuer principals
issuers.AddRange(issuerPrincipals);
}
// TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid
// distributionPoint
// if (dp.getDistributionPoint() != null)
// {
// // look for nameRelativeToCRLIssuer
// if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
// {
// // append fragment to issuer, only one
// // issuer can be there, if this is given
// if (issuers.size() != 1)
// {
// throw new AnnotatedException(
// "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given.");
// }
// DEREncodable relName = dp.getDistributionPoint().getName();
// Iterator it = issuers.iterator();
// List issuersTemp = new ArrayList(issuers.size());
// while (it.hasNext())
// {
// Enumeration e = null;
// try
// {
// e = ASN1Sequence.getInstance(
// new ASN1InputStream(((X500Principal) it.next())
// .getEncoded()).readObject()).getObjects();
// }
// catch (IOException ex)
// {
// throw new AnnotatedException(
// "Cannot decode CRL issuer information.", ex);
// }
// ASN1EncodableVector v = new ASN1EncodableVector();
// while (e.hasMoreElements())
// {
// v.add((DEREncodable) e.nextElement());
// }
// v.add(relName);
// issuersTemp.add(new X500Principal(new DERSequence(v)
// .getDEREncoded()));
// }
// issuers.clear();
// issuers.addAll(issuersTemp);
// }
// }
selector.Issuers = issuers;
}
/**
* Fetches complete CRLs according to RFC 3280.
*
* @param dp The distribution point for which the complete CRL
* @param cert The X509Certificate
or
* {@link org.bouncycastle.x509.X509AttributeCertificate} for
* which the CRL should be searched.
* @param currentDate The date for which the delta CRLs must be valid.
* @param paramsPKIX The extended PKIX parameters.
* @return A Set
of X509CRL
s with complete
* CRLs.
* @throws Exception if an exception occurs while picking the CRLs
* or no CRLs are found.
*/
internal static ISet GetCompleteCrls(DistributionPoint dp, object certObj, DateTime currentDate,
PkixParameters paramsPKIX)
{
var certObjIssuer = GetIssuerPrincipal(certObj);
X509CrlStoreSelector crlselect = new X509CrlStoreSelector();
try
{
var issuers = new HashSet();
issuers.Add(certObjIssuer);
GetCrlIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX);
}
catch (Exception e)
{
throw new Exception("Could not get issuer information from distribution point.", e);
}
{
if (certObj is X509Certificate cert)
{
crlselect.CertificateChecking = cert;
}
else if (certObj is X509V2AttributeCertificate attrCert)
{
crlselect.AttrCertChecking = attrCert;
}
}
crlselect.CompleteCrlEnabled = true;
ISet crls = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate);
if (crls.Count < 1)
throw new Exception("No CRLs found for issuer \"" + certObjIssuer + "\"");
return crls;
}
/**
* Fetches delta CRLs according to RFC 3280 section 5.2.4.
*
* @param currentDate The date for which the delta CRLs must be valid.
* @param paramsPKIX The extended PKIX parameters.
* @param completeCRL The complete CRL the delta CRL is for.
* @return A Set
of X509CRL
s with delta CRLs.
* @throws Exception if an exception occurs while picking the delta
* CRLs.
*/
internal static ISet GetDeltaCrls(
DateTime currentDate,
PkixParameters paramsPKIX,
X509Crl completeCRL)
{
X509CrlStoreSelector deltaSelect = new X509CrlStoreSelector();
// 5.2.4 (a)
try
{
var deltaSelectIssuer = new List();
deltaSelectIssuer.Add(completeCRL.IssuerDN);
deltaSelect.Issuers = deltaSelectIssuer;
}
catch (IOException e)
{
throw new Exception("Cannot extract issuer from CRL.", e);
}
BigInteger completeCRLNumber = null;
try
{
Asn1Object asn1Object = GetExtensionValue(completeCRL, X509Extensions.CrlNumber);
if (asn1Object != null)
{
completeCRLNumber = CrlNumber.GetInstance(asn1Object).PositiveValue;
}
}
catch (Exception e)
{
throw new Exception(
"CRL number extension could not be extracted from CRL.", e);
}
// 5.2.4 (b)
byte[] idp = null;
try
{
Asn1Object obj = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint);
if (obj != null)
{
idp = obj.GetDerEncoded();
}
}
catch (Exception e)
{
throw new Exception(
"Issuing distribution point extension value could not be read.",
e);
}
// 5.2.4 (d)
deltaSelect.MinCrlNumber = (completeCRLNumber == null)
? null
: completeCRLNumber.Add(BigInteger.One);
deltaSelect.IssuingDistributionPoint = idp;
deltaSelect.IssuingDistributionPointEnabled = true;
// 5.2.4 (c)
deltaSelect.MaxBaseCrlNumber = completeCRLNumber;
// find delta CRLs
ISet temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate);
var result = new HashSet();
foreach (X509Crl crl in temp)
{
if (IsDeltaCrl(crl))
{
result.Add(crl);
}
}
return result;
}
private static bool IsDeltaCrl(X509Crl crl)
{
var critical = crl.GetCriticalExtensionOids();
return critical.Contains(X509Extensions.DeltaCrlIndicator.Id);
}
internal static void AddAdditionalStoresFromCrlDistributionPoint(
CrlDistPoint crldp,
PkixParameters pkixParams)
{
if (crldp != null)
{
DistributionPoint[] dps = null;
try
{
dps = crldp.GetDistributionPoints();
}
catch (Exception e)
{
throw new Exception(
"Distribution points could not be read.", e);
}
for (int i = 0; i < dps.Length; i++)
{
DistributionPointName dpn = dps[i].DistributionPointName;
// look for URIs in fullName
if (dpn != null)
{
if (dpn.PointType == DistributionPointName.FullName)
{
GeneralName[] genNames = GeneralNames.GetInstance(
dpn.Name).GetNames();
// look for an URI
for (int j = 0; j < genNames.Length; j++)
{
if (genNames[j].TagNo == GeneralName.UniformResourceIdentifier)
{
string location = DerIA5String.GetInstance(genNames[j].Name).GetString();
AddAdditionalStoreFromLocation(location, pkixParams);
}
}
}
}
}
}
}
internal static bool ProcessCertD1i(int index, IList[] policyNodes, DerObjectIdentifier pOid,
ISet pq)
{
foreach (var node in policyNodes[index - 1])
{
if (node.ExpectedPolicies.Contains(pOid.Id))
{
var childExpectedPolicies = new HashSet();
childExpectedPolicies.Add(pOid.Id);
var child = new PkixPolicyNode(new List(), index, childExpectedPolicies, node, pq,
pOid.Id, false);
node.AddChild(child);
policyNodes[index].Add(child);
return true;
}
}
return false;
}
internal static void ProcessCertD1ii(int index, IList[] policyNodes,
DerObjectIdentifier _poid, ISet _pq)
{
foreach (var _node in policyNodes[index - 1])
{
if (ANY_POLICY.Equals(_node.ValidPolicy))
{
var _childExpectedPolicies = new HashSet();
_childExpectedPolicies.Add(_poid.Id);
var _child = new PkixPolicyNode(new List(), index, _childExpectedPolicies, _node,
_pq, _poid.Id, false);
_node.AddChild(_child);
policyNodes[index].Add(_child);
return;
}
}
}
/**
* Find the issuer certificates of a given certificate.
*
* @param cert
* The certificate for which an issuer should be found.
* @param pkixParams
* @return A Collection
object containing the issuer
* X509Certificate
s. Never null
.
*
* @exception Exception
* if an error occurs.
*/
internal static HashSet FindIssuerCerts(
X509Certificate cert,
PkixBuilderParameters pkixParams)
{
X509CertStoreSelector certSelector = new X509CertStoreSelector();
try
{
certSelector.Subject = cert.IssuerDN;
}
catch (IOException ex)
{
throw new Exception(
"Subject criteria for certificate selector to find issuer certificate could not be set.", ex);
}
var certs = new HashSet();
try
{
CollectionUtilities.CollectMatches(certs, certSelector, pkixParams.GetStoresCert());
}
catch (Exception e)
{
throw new Exception("Issuer certificate cannot be searched.", e);
}
return certs;
}
internal static Asn1Object GetExtensionValue(IX509Extension extensions, DerObjectIdentifier oid)
{
return X509ExtensionUtilities.FromExtensionValue(extensions, oid);
}
}
}