using System; using System.Collections; using System.IO; using System.Text; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.IsisMtt; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.Date; using Org.BouncyCastle.X509; using Org.BouncyCastle.X509.Extension; using Org.BouncyCastle.X509.Store; namespace Org.BouncyCastle.Pkix { /// /// Summary description for PkixCertPathValidatorUtilities. /// public class PkixCertPathValidatorUtilities { private static readonly PkixCrlUtilities CrlUtilities = new PkixCrlUtilities(); internal static readonly string ANY_POLICY = "2.5.29.32.0"; internal static readonly string CRL_NUMBER = X509Extensions.CrlNumber.Id; /// /// key usage bits /// internal static readonly int KEY_CERT_SIGN = 5; internal static readonly int CRL_SIGN = 6; internal static readonly string[] crlReasons = new string[] { "unspecified", "keyCompromise", "cACompromise", "affiliationChanged", "superseded", "cessationOfOperation", "certificateHold", "unknown", "removeFromCRL", "privilegeWithdrawn", "aACompromise" }; /// /// Search the given Set of TrustAnchor's for one that is the /// issuer of the given X509 certificate. /// /// the X509 certificate /// a Set of TrustAnchor's /// the TrustAnchor object if found or /// null if not. /// /// @exception internal static TrustAnchor FindTrustAnchor( X509Certificate cert, ISet trustAnchors) { IEnumerator iter = trustAnchors.GetEnumerator(); TrustAnchor trust = null; AsymmetricKeyParameter trustPublicKey = null; Exception invalidKeyEx = null; X509CertStoreSelector certSelectX509 = new X509CertStoreSelector(); try { certSelectX509.Subject = GetIssuerPrincipal(cert); } catch (IOException ex) { throw new Exception("Cannot set subject search criteria for trust anchor.", ex); } while (iter.MoveNext() && trust == null) { trust = (TrustAnchor) iter.Current; if (trust.TrustedCert != null) { if (certSelectX509.Match(trust.TrustedCert)) { trustPublicKey = trust.TrustedCert.GetPublicKey(); } else { trust = null; } } else if (trust.CAName != null && trust.CAPublicKey != null) { try { X509Name certIssuer = GetIssuerPrincipal(cert); X509Name caName = new X509Name(trust.CAName); if (certIssuer.Equivalent(caName, true)) { trustPublicKey = trust.CAPublicKey; } else { trust = null; } } catch (InvalidParameterException) { trust = null; } } else { trust = null; } if (trustPublicKey != null) { try { cert.Verify(trustPublicKey); } catch (Exception ex) { invalidKeyEx = ex; trust = null; } } } if (trust == null && invalidKeyEx != null) { throw new Exception("TrustAnchor found but certificate validation failed.", invalidKeyEx); } return trust; } internal static bool IsIssuerTrustAnchor( X509Certificate cert, ISet trustAnchors) { try { return FindTrustAnchor(cert, trustAnchors) != null; } catch (Exception e) { return false; } } internal static void AddAdditionalStoresFromAltNames( X509Certificate cert, PkixParameters pkixParams) { // if in the IssuerAltName extension an URI // is given, add an additinal X.509 store if (cert.GetIssuerAlternativeNames() != null) { IEnumerator it = cert.GetIssuerAlternativeNames().GetEnumerator(); while (it.MoveNext()) { // look for URI IList list = (IList)it.Current; //if (list[0].Equals(new Integer(GeneralName.UniformResourceIdentifier))) if (list[0].Equals(GeneralName.UniformResourceIdentifier)) { // found string temp = (string)list[1]; PkixCertPathValidatorUtilities.AddAdditionalStoreFromLocation(temp, pkixParams); } } } } internal static DateTime GetValidDate(PkixParameters paramsPKIX) { DateTimeObject validDate = paramsPKIX.Date; if (validDate == null) return DateTime.UtcNow; return validDate.Value; } /// /// Returns the issuer of an attribute certificate or certificate. /// /// The attribute certificate or certificate. /// The issuer as X500Principal. internal static X509Name GetIssuerPrincipal( object cert) { if (cert is X509Certificate) { return ((X509Certificate)cert).IssuerDN; } else { return ((IX509AttributeCertificate)cert).Issuer.GetPrincipals()[0]; } } internal static bool IsSelfIssued( X509Certificate cert) { return cert.SubjectDN.Equivalent(cert.IssuerDN, true); } internal static AlgorithmIdentifier GetAlgorithmIdentifier( AsymmetricKeyParameter key) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key); return info.AlgorithmID; } catch (Exception e) { throw new PkixCertPathValidatorException("Subject public key cannot be decoded.", e); } } internal static bool IsAnyPolicy( ISet policySet) { return policySet == null || policySet.Contains(ANY_POLICY) || policySet.Count == 0; } internal static void AddAdditionalStoreFromLocation( string location, PkixParameters pkixParams) { if (pkixParams.IsAdditionalLocationsEnabled) { try { if (Platform.StartsWith(location, "ldap://")) { // ldap://directory.d-trust.net/CN=D-TRUST // Qualified CA 2003 1:PN,O=D-Trust GmbH,C=DE // skip "ldap://" location = location.Substring(7); // after first / baseDN starts string url;//, baseDN; int slashPos = location.IndexOf('/'); if (slashPos != -1) { url = "ldap://" + location.Substring(0, slashPos); // baseDN = location.Substring(slashPos); } else { url = "ldap://" + location; // baseDN = nsull; } throw Platform.CreateNotImplementedException("LDAP cert/CRL stores"); // use all purpose parameters //X509LDAPCertStoreParameters ldapParams = new X509LDAPCertStoreParameters.Builder( // url, baseDN).build(); //pkixParams.AddAdditionalStore(X509Store.getInstance( // "CERTIFICATE/LDAP", ldapParams)); //pkixParams.AddAdditionalStore(X509Store.getInstance( // "CRL/LDAP", ldapParams)); //pkixParams.AddAdditionalStore(X509Store.getInstance( // "ATTRIBUTECERTIFICATE/LDAP", ldapParams)); //pkixParams.AddAdditionalStore(X509Store.getInstance( // "CERTIFICATEPAIR/LDAP", ldapParams)); } } catch (Exception) { // cannot happen throw new Exception("Exception adding X.509 stores."); } } } private static BigInteger GetSerialNumber( object cert) { if (cert is X509Certificate) { return ((X509Certificate)cert).SerialNumber; } else { return ((X509V2AttributeCertificate)cert).SerialNumber; } } // // policy checking // internal static ISet GetQualifierSet(Asn1Sequence qualifiers) { ISet pq = new HashSet(); if (qualifiers == null) { return pq; } foreach (Asn1Encodable ae in qualifiers) { try { // pq.Add(PolicyQualifierInfo.GetInstance(Asn1Object.FromByteArray(ae.GetEncoded()))); pq.Add(PolicyQualifierInfo.GetInstance(ae.ToAsn1Object())); } catch (IOException ex) { throw new PkixCertPathValidatorException("Policy qualifier info cannot be decoded.", ex); } } return pq; } internal static PkixPolicyNode RemovePolicyNode( PkixPolicyNode validPolicyTree, IList[] policyNodes, PkixPolicyNode _node) { PkixPolicyNode _parent = (PkixPolicyNode)_node.Parent; if (validPolicyTree == null) { return null; } if (_parent == null) { for (int j = 0; j < policyNodes.Length; j++) { policyNodes[j] = Platform.CreateArrayList(); } return null; } else { _parent.RemoveChild(_node); RemovePolicyNodeRecurse(policyNodes, _node); return validPolicyTree; } } private static void RemovePolicyNodeRecurse(IList[] policyNodes, PkixPolicyNode _node) { policyNodes[_node.Depth].Remove(_node); if (_node.HasChildren) { foreach (PkixPolicyNode _child in _node.Children) { RemovePolicyNodeRecurse(policyNodes, _child); } } } internal static void PrepareNextCertB1( int i, IList[] policyNodes, string id_p, IDictionary m_idp, X509Certificate cert) { 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 (ANY_POLICY.Equals(node.ValidPolicy)) { ISet pq = null; Asn1Sequence policies = null; try { policies = DerSequence.GetInstance(GetExtensionValue(cert, X509Extensions.CertificatePolicies)); } catch (Exception e) { throw new Exception("Certificate policies cannot be decoded.", e); } IEnumerator enm = policies.GetEnumerator(); while (enm.MoveNext()) { PolicyInformation pinfo = null; try { pinfo = PolicyInformation.GetInstance(enm.Current); } catch (Exception ex) { throw new Exception("Policy information cannot be decoded.", ex); } if (ANY_POLICY.Equals(pinfo.PolicyIdentifier.Id)) { try { pq = GetQualifierSet(pinfo.PolicyQualifiers); } catch (PkixCertPathValidatorException ex) { throw new PkixCertPathValidatorException( "Policy qualifier info set could not be built.", ex); } break; } } bool ci = false; ISet critExtOids = cert.GetCriticalExtensionOids(); if (critExtOids != null) { ci = critExtOids.Contains(X509Extensions.CertificatePolicies.Id); } PkixPolicyNode p_node = (PkixPolicyNode)node.Parent; if (ANY_POLICY.Equals(p_node.ValidPolicy)) { PkixPolicyNode c_node = new PkixPolicyNode( 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; } } } } internal static PkixPolicyNode PrepareNextCertB2( int i, IList[] policyNodes, string id_p, PkixPolicyNode validPolicyTree) { int pos = 0; // Copy to avoid RemoveAt calls interfering with enumeration foreach (PkixPolicyNode node in Platform.CreateArrayList(policyNodes[i])) { if (node.ValidPolicy.Equals(id_p)) { PkixPolicyNode p_node = (PkixPolicyNode)node.Parent; p_node.RemoveChild(node); // Removal of element at current iterator position not supported in C# //nodes_i.remove(); policyNodes[i].RemoveAt(pos); for (int k = (i - 1); k >= 0; k--) { IList nodes = policyNodes[k]; for (int l = 0; l < nodes.Count; l++) { PkixPolicyNode node2 = (PkixPolicyNode)nodes[l]; if (!node2.HasChildren) { validPolicyTree = RemovePolicyNode(validPolicyTree, policyNodes, node2); if (validPolicyTree == null) break; } } } } else { ++pos; } } return validPolicyTree; } internal static void GetCertStatus( DateTime validDate, X509Crl crl, Object cert, CertStatus certStatus) { X509Crl bcCRL = null; try { bcCRL = new X509Crl(CertificateList.GetInstance((Asn1Sequence)Asn1Sequence.FromByteArray(crl.GetEncoded()))); } catch (Exception exception) { throw new Exception("Bouncy Castle 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)) { DerEnumerated reasonCode = null; if (crl_entry.HasExtensions) { try { reasonCode = DerEnumerated.GetInstance( GetExtensionValue(crl_entry, X509Extensions.ReasonCode)); } catch (Exception e) { throw new Exception( "Reason code CRL entry extension could not be decoded.", e); } } // for reason keyCompromise, caCompromise, aACompromise or // unspecified if (!(validDate.Ticks < crl_entry.RevocationDate.Ticks) || reasonCode == null || reasonCode.Value.TestBit(0) || reasonCode.Value.TestBit(1) || reasonCode.Value.TestBit(2) || reasonCode.Value.TestBit(8)) { if (reasonCode != null) // (i) or (j) (1) { certStatus.Status = reasonCode.Value.SignValue; } else // (i) or (j) (2) { certStatus.Status = CrlReason.Unspecified; } certStatus.RevocationDate = new DateTimeObject(crl_entry.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) { //Only X509Certificate X509Certificate cert = (X509Certificate)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 = (X509Certificate)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 PkixCertPathValidatorUtilities.GetValidDate(paramsPkix); // else use time when previous cert was created } if (index - 1 == 0) { DerGeneralizedTime dateOfCertgen = null; try { X509Certificate cert = (X509Certificate)certPath.Certificates[index - 1]; Asn1OctetString extVal = cert.GetExtensionValue( IsisMttObjectIdentifiers.IdIsisMttATDateOfCertGen); dateOfCertgen = DerGeneralizedTime.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 ((X509Certificate)certPath.Certificates[index - 1]).NotBefore; } /// /// Return a Collection of all certificates or attribute certificates found /// in the X509Store's that are matching the certSelect criteriums. /// /// a {@link Selector} object that will be used to select /// the certificates /// a List containing only X509Store objects. These /// are used to search for certificates. /// a Collection of all found or /// objects. /// May be empty but never null. /// internal static ICollection FindCertificates( X509CertStoreSelector certSelect, IList certStores) { ISet certs = new HashSet(); foreach (IX509Store certStore in certStores) { try { // certs.AddAll(certStore.GetMatches(certSelect)); foreach (X509Certificate c in certStore.GetMatches(certSelect)) { certs.Add(c); } } catch (Exception e) { throw new Exception("Problem while picking certificates from X.509 store.", e); } } return certs; } /** * 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 X509Certificates. 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 X500Principals. */ internal static void GetCrlIssuersFromDistributionPoint( DistributionPoint dp, ICollection issuerPrincipals, X509CrlStoreSelector selector, PkixParameters pkixParams) { IList issuers = Platform.CreateArrayList(); // 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 for (IEnumerator it = issuerPrincipals.GetEnumerator(); it.MoveNext(); ) { issuers.Add((X509Name)it.Current); } } // 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 X509CRLs 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 cert, DateTime currentDate, PkixParameters paramsPKIX) { X509CrlStoreSelector crlselect = new X509CrlStoreSelector(); try { ISet issuers = new HashSet(); if (cert is X509V2AttributeCertificate) { issuers.Add(((X509V2AttributeCertificate)cert) .Issuer.GetPrincipals()[0]); } else { issuers.Add(GetIssuerPrincipal(cert)); } PkixCertPathValidatorUtilities.GetCrlIssuersFromDistributionPoint(dp, issuers, crlselect, paramsPKIX); } catch (Exception e) { throw new Exception("Could not get issuer information from distribution point.", e); } if (cert is X509Certificate) { crlselect.CertificateChecking = (X509Certificate)cert; } else if (cert is X509V2AttributeCertificate) { crlselect.AttrCertChecking = (IX509AttributeCertificate)cert; } crlselect.CompleteCrlEnabled = true; ISet crls = CrlUtilities.FindCrls(crlselect, paramsPKIX, currentDate); if (crls.IsEmpty) { if (cert is IX509AttributeCertificate) { IX509AttributeCertificate aCert = (IX509AttributeCertificate)cert; throw new Exception("No CRLs found for issuer \"" + aCert.Issuer.GetPrincipals()[0] + "\""); } else { X509Certificate xCert = (X509Certificate)cert; throw new Exception("No CRLs found for issuer \"" + xCert.IssuerDN + "\""); } } 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 X509CRLs 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 { IList deltaSelectIssuer = Platform.CreateArrayList(); 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); ISet result = new HashSet(); foreach (X509Crl crl in temp) { if (isDeltaCrl(crl)) { result.Add(crl); } } return result; } private static bool isDeltaCrl( X509Crl crl) { ISet critical = crl.GetCriticalExtensionOids(); return critical.Contains(X509Extensions.DeltaCrlIndicator.Id); } internal static ICollection FindCertificates( X509AttrCertStoreSelector certSelect, IList certStores) { ISet certs = new HashSet(); foreach (IX509Store certStore in certStores) { try { // certs.AddAll(certStore.GetMatches(certSelect)); foreach (X509V2AttributeCertificate ac in certStore.GetMatches(certSelect)) { certs.Add(ac); } } catch (Exception e) { throw new Exception( "Problem while picking certificates from X.509 store.", e); } } return certs; } 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(); PkixCertPathValidatorUtilities.AddAdditionalStoreFromLocation( location, pkixParams); } } } } } } } internal static bool ProcessCertD1i( int index, IList[] policyNodes, DerObjectIdentifier pOid, ISet pq) { IList policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.Count; j++) { PkixPolicyNode node = (PkixPolicyNode)policyNodeVec[j]; ISet expectedPolicies = node.ExpectedPolicies; if (expectedPolicies.Contains(pOid.Id)) { ISet childExpectedPolicies = new HashSet(); childExpectedPolicies.Add(pOid.Id); PkixPolicyNode child = new PkixPolicyNode(Platform.CreateArrayList(), 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) { IList policyNodeVec = policyNodes[index - 1]; for (int j = 0; j < policyNodeVec.Count; j++) { PkixPolicyNode _node = (PkixPolicyNode)policyNodeVec[j]; if (ANY_POLICY.Equals(_node.ValidPolicy)) { ISet _childExpectedPolicies = new HashSet(); _childExpectedPolicies.Add(_poid.Id); PkixPolicyNode _child = new PkixPolicyNode(Platform.CreateArrayList(), 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 * X509Certificates. Never null. * * @exception Exception * if an error occurs. */ internal static ICollection FindIssuerCerts( X509Certificate cert, PkixBuilderParameters pkixParams) { X509CertStoreSelector certSelect = new X509CertStoreSelector(); ISet certs = new HashSet(); try { certSelect.Subject = cert.IssuerDN; } catch (IOException ex) { throw new Exception( "Subject criteria for certificate selector to find issuer certificate could not be set.", ex); } try { certs.AddAll(PkixCertPathValidatorUtilities.FindCertificates(certSelect, pkixParams.GetStores())); certs.AddAll(PkixCertPathValidatorUtilities.FindCertificates(certSelect, pkixParams.GetAdditionalStores())); } catch (Exception e) { throw new Exception("Issuer certificate cannot be searched.", e); } return certs; } /// /// Extract the value of the given extension, if it exists. /// /// The extension object. /// The object identifier to obtain. /// Asn1Object /// if the extension cannot be read. internal static Asn1Object GetExtensionValue( IX509Extension ext, DerObjectIdentifier oid) { Asn1OctetString bytes = ext.GetExtensionValue(oid); if (bytes == null) return null; return X509ExtensionUtilities.FromExtensionValue(bytes); } } }