/** * Validates an attribute certificate with the given certificate path. * * <p> * <code>params</code> must be an instance of * <code>ExtendedPkixParameters</code>. * </p><p> * The target constraints in the <code>params</code> must be an * <code>X509AttrCertStoreSelector</code> with at least the attribute * certificate criterion set. Obey that also target informations may be * necessary to correctly validate this attribute certificate. * </p><p> * The attribute certificate issuer must be added to the trusted attribute * issuers with {@link ExtendedPkixParameters#setTrustedACIssuers(Set)}. * </p> * @param certPath The certificate path which belongs to the attribute * certificate issuer public key certificate. * @param params The PKIX parameters. * @return A <code>PKIXCertPathValidatorResult</code> of the result of * validating the <code>certPath</code>. * @throws InvalidAlgorithmParameterException if <code>params</code> is * inappropriate for this validator. * @throws CertPathValidatorException if the verification fails. */ public virtual PkixCertPathValidatorResult Validate( PkixCertPath certPath, PkixParameters pkixParams) { IX509Selector certSelect = pkixParams.GetTargetConstraints(); if (!(certSelect is X509AttrCertStoreSelector)) { throw new ArgumentException( "TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName, "pkixParams"); } IX509AttributeCertificate attrCert = ((X509AttrCertStoreSelector) certSelect).AttributeCert; PkixCertPath holderCertPath = Rfc3281CertPathUtilities.ProcessAttrCert1(attrCert, pkixParams); PkixCertPathValidatorResult result = Rfc3281CertPathUtilities.ProcessAttrCert2(certPath, pkixParams); X509Certificate issuerCert = (X509Certificate)certPath.Certificates[0]; Rfc3281CertPathUtilities.ProcessAttrCert3(issuerCert, pkixParams); Rfc3281CertPathUtilities.ProcessAttrCert4(issuerCert, pkixParams); Rfc3281CertPathUtilities.ProcessAttrCert5(attrCert, pkixParams); // 6 already done in X509AttrCertStoreSelector Rfc3281CertPathUtilities.ProcessAttrCert7(attrCert, certPath, holderCertPath, pkixParams); Rfc3281CertPathUtilities.AdditionalChecks(attrCert, pkixParams); DateTime date; try { date = PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(pkixParams, null, -1); } catch (Exception e) { throw new PkixCertPathValidatorException( "Could not get validity date from attribute certificate.", e); } Rfc3281CertPathUtilities.CheckCrls(attrCert, pkixParams, issuerCert, date, certPath.Certificates); return result; }
public PkixCertPathBuilderResult( PkixCertPath certPath, TrustAnchor trustAnchor, PkixPolicyNode policyTree, AsymmetricKeyParameter subjectPublicKey) : base(trustAnchor, policyTree, subjectPublicKey) { if (certPath == null) throw new ArgumentNullException("certPath"); this.certPath = certPath; }
public PkixCertPathBuilderResult( PkixCertPath certPath, TrustAnchor trustAnchor, PkixPolicyNode policyTree, AsymmetricKeyParameter subjectPublicKey) : base(trustAnchor, policyTree, subjectPublicKey) { if (certPath == null) { throw new ArgumentNullException("certPath"); } this.certPath = certPath; }
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); }
internal static PkixCertPathValidatorResult ProcessAttrCert2( PkixCertPath certPath, PkixParameters pkixParams) { PkixCertPathValidator validator = new PkixCertPathValidator(); try { return(validator.Validate(certPath, pkixParams)); } catch (PkixCertPathValidatorException e) { throw new PkixCertPathValidatorException( "Certification path for issuer certificate of attribute certificate could not be validated.", e); } }
/** * Compares this certification path for equality with the specified object. * Two CertPaths are equal if and only if their types are equal and their * certificate Lists (and by implication the Certificates in those Lists) * are equal. A CertPath is never equal to an object that is not a CertPath.<br /> * <br /> * This algorithm is implemented by this method. If it is overridden, the * behavior specified here must be maintained. * * @param other * the object to test for equality with this certification path * * @return true if the specified object is equal to this certification path, * false otherwise * * @see Object#hashCode() Object.hashCode() */ public override bool Equals( object obj) { if (this == obj) { return(true); } PkixCertPath other = obj as PkixCertPath; if (other == null) { return(false); } // if (!this.Type.Equals(other.Type)) // return false; //return this.Certificates.Equals(other.Certificates); // TODO Extract this to a utility class IList thisCerts = this.Certificates; IList otherCerts = other.Certificates; if (thisCerts.Count != otherCerts.Count) { return(false); } IEnumerator e1 = thisCerts.GetEnumerator(); IEnumerator e2 = thisCerts.GetEnumerator(); while (e1.MoveNext()) { e2.MoveNext(); if (!Platform.Equals(e1.Current, e2.Current)) { return(false); } } return(true); }
internal static void ProcessAttrCert7( IX509AttributeCertificate attrCert, PkixCertPath certPath, PkixCertPath holderCertPath, PkixParameters pkixParams) { // TODO: // AA Controls // Attribute encryption // Proxy ISet critExtOids = attrCert.GetCriticalExtensionOids(); // 7.1 // process extensions // target information checked in step 6 / X509AttributeCertStoreSelector if (critExtOids.Contains(X509Extensions.TargetInformation.Id)) { try { TargetInformation.GetInstance(PkixCertPathValidatorUtilities .GetExtensionValue(attrCert, X509Extensions.TargetInformation)); } catch (Exception e) { throw new PkixCertPathValidatorException( "Target information extension could not be read.", e); } } critExtOids.Remove(X509Extensions.TargetInformation.Id); foreach (PkixAttrCertChecker checker in pkixParams.GetAttrCertCheckers()) { checker.Check(attrCert, certPath, holderCertPath, critExtOids); } if (!critExtOids.IsEmpty) { throw new PkixCertPathValidatorException( "Attribute certificate contains unsupported critical extensions: " + critExtOids); } }
/** * Validates an attribute certificate with the given certificate path. * * <p> * <code>params</code> must be an instance of * <code>ExtendedPkixParameters</code>. * </p><p> * The target constraints in the <code>params</code> must be an * <code>X509AttrCertStoreSelector</code> with at least the attribute * certificate criterion set. Obey that also target informations may be * necessary to correctly validate this attribute certificate. * </p><p> * The attribute certificate issuer must be added to the trusted attribute * issuers with {@link ExtendedPkixParameters#setTrustedACIssuers(Set)}. * </p> * @param certPath The certificate path which belongs to the attribute * certificate issuer public key certificate. * @param params The PKIX parameters. * @return A <code>PKIXCertPathValidatorResult</code> of the result of * validating the <code>certPath</code>. * @throws InvalidAlgorithmParameterException if <code>params</code> is * inappropriate for this validator. * @throws CertPathValidatorException if the verification fails. */ public virtual PkixCertPathValidatorResult Validate( PkixCertPath certPath, PkixParameters pkixParams) { IX509Selector certSelect = pkixParams.GetTargetConstraints(); if (!(certSelect is X509AttrCertStoreSelector)) { throw new ArgumentException( "TargetConstraints must be an instance of " + typeof(X509AttrCertStoreSelector).FullName, "pkixParams"); } IX509AttributeCertificate attrCert = ((X509AttrCertStoreSelector)certSelect).AttributeCert; PkixCertPath holderCertPath = Rfc3281CertPathUtilities.ProcessAttrCert1(attrCert, pkixParams); PkixCertPathValidatorResult result = Rfc3281CertPathUtilities.ProcessAttrCert2(certPath, pkixParams); X509Certificate issuerCert = (X509Certificate)certPath.Certificates[0]; Rfc3281CertPathUtilities.ProcessAttrCert3(issuerCert, pkixParams); Rfc3281CertPathUtilities.ProcessAttrCert4(issuerCert, pkixParams); Rfc3281CertPathUtilities.ProcessAttrCert5(attrCert, pkixParams); // 6 already done in X509AttrCertStoreSelector Rfc3281CertPathUtilities.ProcessAttrCert7(attrCert, certPath, holderCertPath, pkixParams); Rfc3281CertPathUtilities.AdditionalChecks(attrCert, pkixParams); DateTime date; try { date = PkixCertPathValidatorUtilities.GetValidCertDateFromValidityModel(pkixParams, null, -1); } catch (Exception e) { throw new PkixCertPathValidatorException( "Could not get validity date from attribute certificate.", e); } Rfc3281CertPathUtilities.CheckCrls(attrCert, pkixParams, issuerCert, date, certPath.Certificates); return(result); }
/// <summary> /// Creates a <code>PkixCertPathValidatorException</code> with the specified /// detail message, cause, certification path, and index. /// </summary> /// <param name="message">the detail message (or <code>null</code> if none)</param> /// <param name="cause">the cause (or <code>null</code> if none)</param> /// <param name="certPath">the certification path that was in the process of being /// validated when the error was encountered</param> /// <param name="index">the index of the certificate in the certification path that</param> * public PkixCertPathValidatorException( string message, Exception cause, PkixCertPath certPath, int index) : base(message) { if (certPath == null && index != -1) { throw new ArgumentNullException( "certPath = null and index != -1"); } if (index < -1 || (certPath != null && index >= certPath.Certificates.Count)) { throw new IndexOutOfRangeException( " index < -1 or out of bound of certPath.getCertificates()"); } this.cause = cause; this.certPath = certPath; this.index = index; }
public virtual PkixCertPathValidatorResult Validate( PkixCertPath certPath, PkixParameters paramsPkix) { if (paramsPkix.GetTrustAnchors() == null) { throw new ArgumentException( "trustAnchors is null, this is not allowed for certification path validation.", "parameters"); } // // 6.1.1 - inputs // // // (a) // IList certs = certPath.Certificates; int n = certs.Count; if (certs.Count == 0) throw new PkixCertPathValidatorException("Certification path is empty.", null, certPath, 0); // // (b) // // DateTime validDate = PkixCertPathValidatorUtilities.GetValidDate(paramsPkix); // // (c) // ISet userInitialPolicySet = paramsPkix.GetInitialPolicies(); // // (d) // TrustAnchor trust; try { trust = PkixCertPathValidatorUtilities.FindTrustAnchor( (X509Certificate)certs[certs.Count - 1], paramsPkix.GetTrustAnchors()); } catch (Exception e) { throw new PkixCertPathValidatorException(e.Message, e, certPath, certs.Count - 1); } if (trust == null) throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1); // // (e), (f), (g) are part of the paramsPkix object. // IEnumerator certIter; int index = 0; int i; // Certificate for each interation of the validation loop // Signature information for each iteration of the validation loop // // 6.1.2 - setup // // // (a) // IList[] policyNodes = new IList[n + 1]; for (int j = 0; j < policyNodes.Length; j++) { policyNodes[j] = Platform.CreateArrayList(); } ISet policySet = new HashSet(); policySet.Add(Rfc3280CertPathUtilities.ANY_POLICY); PkixPolicyNode validPolicyTree = new PkixPolicyNode(Platform.CreateArrayList(), 0, policySet, null, new HashSet(), Rfc3280CertPathUtilities.ANY_POLICY, false); policyNodes[0].Add(validPolicyTree); // // (b) and (c) // PkixNameConstraintValidator nameConstraintValidator = new PkixNameConstraintValidator(); // (d) // int explicitPolicy; ISet acceptablePolicies = new HashSet(); if (paramsPkix.IsExplicitPolicyRequired) { explicitPolicy = 0; } else { explicitPolicy = n + 1; } // // (e) // int inhibitAnyPolicy; if (paramsPkix.IsAnyPolicyInhibited) { inhibitAnyPolicy = 0; } else { inhibitAnyPolicy = n + 1; } // // (f) // int policyMapping; if (paramsPkix.IsPolicyMappingInhibited) { policyMapping = 0; } else { policyMapping = n + 1; } // // (g), (h), (i), (j) // AsymmetricKeyParameter workingPublicKey; X509Name workingIssuerName; X509Certificate sign = trust.TrustedCert; try { if (sign != null) { workingIssuerName = sign.SubjectDN; workingPublicKey = sign.GetPublicKey(); } else { workingIssuerName = new X509Name(trust.CAName); workingPublicKey = trust.CAPublicKey; } } catch (ArgumentException ex) { throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath, -1); } AlgorithmIdentifier workingAlgId = null; try { workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey); } catch (PkixCertPathValidatorException e) { throw new PkixCertPathValidatorException( "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1); } // DerObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.ObjectID; // Asn1Encodable workingPublicKeyParameters = workingAlgId.Parameters; // // (k) // int maxPathLength = n; // // 6.1.3 // X509CertStoreSelector certConstraints = paramsPkix.GetTargetCertConstraints(); if (certConstraints != null && !certConstraints.Match((X509Certificate)certs[0])) { throw new PkixCertPathValidatorException( "Target certificate in certification path does not match targetConstraints.", null, certPath, 0); } // // initialize CertPathChecker's // IList pathCheckers = paramsPkix.GetCertPathCheckers(); certIter = pathCheckers.GetEnumerator(); while (certIter.MoveNext()) { ((PkixCertPathChecker)certIter.Current).Init(false); } X509Certificate cert = null; for (index = certs.Count - 1; index >= 0; index--) { // try // { // // i as defined in the algorithm description // i = n - index; // // set certificate to be checked in this round // sign and workingPublicKey and workingIssuerName are set // at the end of the for loop and initialized the // first time from the TrustAnchor // cert = (X509Certificate)certs[index]; // // 6.1.3 // Rfc3280CertPathUtilities.ProcessCertA(certPath, paramsPkix, index, workingPublicKey, workingIssuerName, sign); Rfc3280CertPathUtilities.ProcessCertBC(certPath, index, nameConstraintValidator); validPolicyTree = Rfc3280CertPathUtilities.ProcessCertD(certPath, index, acceptablePolicies, validPolicyTree, policyNodes, inhibitAnyPolicy); validPolicyTree = Rfc3280CertPathUtilities.ProcessCertE(certPath, index, validPolicyTree); Rfc3280CertPathUtilities.ProcessCertF(certPath, index, validPolicyTree, explicitPolicy); // // 6.1.4 // if (i != n) { if (cert != null && cert.Version == 1) { throw new PkixCertPathValidatorException( "Version 1 certificates can't be used as CA ones.", null, certPath, index); } Rfc3280CertPathUtilities.PrepareNextCertA(certPath, index); validPolicyTree = Rfc3280CertPathUtilities.PrepareCertB(certPath, index, policyNodes, validPolicyTree, policyMapping); Rfc3280CertPathUtilities.PrepareNextCertG(certPath, index, nameConstraintValidator); // (h) explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertH1(certPath, index, explicitPolicy); policyMapping = Rfc3280CertPathUtilities.PrepareNextCertH2(certPath, index, policyMapping); inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertH3(certPath, index, inhibitAnyPolicy); // // (i) // explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertI1(certPath, index, explicitPolicy); policyMapping = Rfc3280CertPathUtilities.PrepareNextCertI2(certPath, index, policyMapping); // (j) inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertJ(certPath, index, inhibitAnyPolicy); // (k) Rfc3280CertPathUtilities.PrepareNextCertK(certPath, index); // (l) maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertL(certPath, index, maxPathLength); // (m) maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertM(certPath, index, maxPathLength); // (n) Rfc3280CertPathUtilities.PrepareNextCertN(certPath, index); ISet criticalExtensions1 = cert.GetCriticalExtensionOids(); if (criticalExtensions1 != null) { criticalExtensions1 = new HashSet(criticalExtensions1); // these extensions are handled by the algorithm criticalExtensions1.Remove(X509Extensions.KeyUsage.Id); criticalExtensions1.Remove(X509Extensions.CertificatePolicies.Id); criticalExtensions1.Remove(X509Extensions.PolicyMappings.Id); criticalExtensions1.Remove(X509Extensions.InhibitAnyPolicy.Id); criticalExtensions1.Remove(X509Extensions.IssuingDistributionPoint.Id); criticalExtensions1.Remove(X509Extensions.DeltaCrlIndicator.Id); criticalExtensions1.Remove(X509Extensions.PolicyConstraints.Id); criticalExtensions1.Remove(X509Extensions.BasicConstraints.Id); criticalExtensions1.Remove(X509Extensions.SubjectAlternativeName.Id); criticalExtensions1.Remove(X509Extensions.NameConstraints.Id); } else { criticalExtensions1 = new HashSet(); } // (o) Rfc3280CertPathUtilities.PrepareNextCertO(certPath, index, criticalExtensions1, pathCheckers); // set signing certificate for next round sign = cert; // (c) workingIssuerName = sign.SubjectDN; // (d) try { workingPublicKey = PkixCertPathValidatorUtilities.GetNextWorkingKey(certPath.Certificates, index); } catch (PkixCertPathValidatorException e) { throw new PkixCertPathValidatorException("Next working key could not be retrieved.", e, certPath, index); } workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey); // (f) // workingPublicKeyAlgorithm = workingAlgId.ObjectID; // (e) // workingPublicKeyParameters = workingAlgId.Parameters; } } // // 6.1.5 Wrap-up procedure // explicitPolicy = Rfc3280CertPathUtilities.WrapupCertA(explicitPolicy, cert); explicitPolicy = Rfc3280CertPathUtilities.WrapupCertB(certPath, index + 1, explicitPolicy); // // (c) (d) and (e) are already done // // // (f) // ISet criticalExtensions = cert.GetCriticalExtensionOids(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); // Requires .Id // these extensions are handled by the algorithm criticalExtensions.Remove(X509Extensions.KeyUsage.Id); criticalExtensions.Remove(X509Extensions.CertificatePolicies.Id); criticalExtensions.Remove(X509Extensions.PolicyMappings.Id); criticalExtensions.Remove(X509Extensions.InhibitAnyPolicy.Id); criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id); criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id); criticalExtensions.Remove(X509Extensions.PolicyConstraints.Id); criticalExtensions.Remove(X509Extensions.BasicConstraints.Id); criticalExtensions.Remove(X509Extensions.SubjectAlternativeName.Id); criticalExtensions.Remove(X509Extensions.NameConstraints.Id); criticalExtensions.Remove(X509Extensions.CrlDistributionPoints.Id); } else { criticalExtensions = new HashSet(); } Rfc3280CertPathUtilities.WrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions); PkixPolicyNode intersection = Rfc3280CertPathUtilities.WrapupCertG(certPath, paramsPkix, userInitialPolicySet, index + 1, policyNodes, validPolicyTree, acceptablePolicies); if ((explicitPolicy > 0) || (intersection != null)) { return new PkixCertPathValidatorResult(trust, intersection, cert.GetPublicKey()); } throw new PkixCertPathValidatorException("Path processing failed on policy.", null, certPath, index); }
private PkixCertPathBuilderResult Build( IX509AttributeCertificate attrCert, X509Certificate tbvCert, PkixBuilderParameters pkixParams, IList tbvPath) { // If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the // PKI graph. if (tbvPath.Contains(tbvCert)) return null; // step out, the certificate is not allowed to appear in a certification // chain if (pkixParams.GetExcludedCerts().Contains(tbvCert)) return null; // test if certificate path exceeds maximum length if (pkixParams.MaxPathLength != -1) { if (tbvPath.Count - 1 > pkixParams.MaxPathLength) return null; } tbvPath.Add(tbvCert); PkixCertPathBuilderResult builderResult = null; // X509CertificateParser certParser = new X509CertificateParser(); PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator(); try { // check whether the issuer of <tbvCert> is a TrustAnchor if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null) { PkixCertPath certPath = new PkixCertPath(tbvPath); PkixCertPathValidatorResult result; try { result = validator.Validate(certPath, pkixParams); } catch (Exception e) { throw new Exception("Certification path could not be validated.", e); } return new PkixCertPathBuilderResult(certPath, result.TrustAnchor, result.PolicyTree, result.SubjectPublicKey); } else { // add additional X.509 stores from locations in certificate try { PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams); } catch (CertificateParsingException e) { throw new Exception("No additional X.509 stores can be added from certificate locations.", e); } // try to get the issuer certificate from one of the stores ISet issuers = new HashSet(); try { issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams)); } catch (Exception e) { throw new Exception("Cannot find issuer certificate for certificate in certification path.", e); } if (issuers.IsEmpty) throw new Exception("No issuer certificate for certificate in certification path found."); foreach (X509Certificate issuer in issuers) { // if untrusted self signed certificate continue if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer)) continue; builderResult = Build(attrCert, issuer, pkixParams, tbvPath); if (builderResult != null) break; } } } catch (Exception e) { certPathException = new Exception("No valid certification path could be build.", e); } if (builderResult == null) { tbvPath.Remove(tbvCert); } return builderResult; }
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; }
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 = DerSequence.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 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; Asn1InputStream aIn = new Asn1InputStream(principal.GetEncoded()); Asn1Sequence dns; try { dns = DerSequence.GetInstance(aIn.ReadObject()); } 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 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 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 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 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 PkixCertPathValidatorResult ProcessAttrCert2( PkixCertPath certPath, PkixParameters pkixParams) { PkixCertPathValidator validator = new PkixCertPathValidator(); try { return validator.Validate(certPath, pkixParams); } catch (PkixCertPathValidatorException e) { throw new PkixCertPathValidatorException( "Certification path for issuer certificate of attribute certificate could not be validated.", e); } }
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 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 = 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(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 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 Platform.CreateArrayList(policyNodes[k])) { if (!node2.HasChildren) { _validPolicyTree = PkixCertPathValidatorUtilities.RemovePolicyNode( _validPolicyTree, policyNodes, node2); if (_validPolicyTree == null) break; } } } } } } } } return _validPolicyTree; }
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 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 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 = DerSequence.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).Value.IntValue; } 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 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 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; }
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 = DerSequence.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).Value.IntValue; 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 PkixPolicyNode ProcessCertE( PkixCertPath certPath, int index, PkixPolicyNode validPolicyTree) { IList certs = certPath.Certificates; X509Certificate cert = (X509Certificate)certs[index]; // // (e) // Asn1Sequence certPolicies = null; try { certPolicies = DerSequence.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 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 = DerSequence.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 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 = DerSequence.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(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; }
/** * Performs checks on the specified attribute certificate. Every handled * extension is rmeoved from the <code>unresolvedCritExts</code> * collection. * * @param attrCert The attribute certificate to be checked. * @param certPath The certificate path which belongs to the attribute * certificate issuer public key certificate. * @param holderCertPath The certificate path which belongs to the holder * certificate. * @param unresolvedCritExts a <code>Collection</code> of OID strings * representing the current set of unresolved critical extensions * @throws CertPathValidatorException if the specified attribute certificate * does not pass the check. */ public abstract void Check(IX509AttributeCertificate attrCert, PkixCertPath certPath, PkixCertPath holderCertPath, ICollection unresolvedCritExts);
private PkixCertPathBuilderResult Build( IX509AttributeCertificate attrCert, X509Certificate tbvCert, PkixBuilderParameters pkixParams, IList tbvPath) { // If tbvCert is readily present in tbvPath, it indicates having run // into a cycle in the // PKI graph. if (tbvPath.Contains(tbvCert)) { return(null); } // step out, the certificate is not allowed to appear in a certification // chain if (pkixParams.GetExcludedCerts().Contains(tbvCert)) { return(null); } // test if certificate path exceeds maximum length if (pkixParams.MaxPathLength != -1) { if (tbvPath.Count - 1 > pkixParams.MaxPathLength) { return(null); } } tbvPath.Add(tbvCert); PkixCertPathBuilderResult builderResult = null; // X509CertificateParser certParser = new X509CertificateParser(); PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator(); try { // check whether the issuer of <tbvCert> is a TrustAnchor if (PkixCertPathValidatorUtilities.FindTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()) != null) { PkixCertPath certPath = new PkixCertPath(tbvPath); PkixCertPathValidatorResult result; try { result = validator.Validate(certPath, pkixParams); } catch (Exception e) { throw new Exception("Certification path could not be validated.", e); } return(new PkixCertPathBuilderResult(certPath, result.TrustAnchor, result.PolicyTree, result.SubjectPublicKey)); } else { // add additional X.509 stores from locations in certificate try { PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams); } catch (CertificateParsingException e) { throw new Exception("No additional X.509 stores can be added from certificate locations.", e); } // try to get the issuer certificate from one of the stores ISet issuers = new HashSet(); try { issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams)); } catch (Exception e) { throw new Exception("Cannot find issuer certificate for certificate in certification path.", e); } if (issuers.IsEmpty) { throw new Exception("No issuer certificate for certificate in certification path found."); } foreach (X509Certificate issuer in issuers) { // if untrusted self signed certificate continue if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer)) { continue; } builderResult = Build(attrCert, issuer, pkixParams, tbvPath); if (builderResult != null) { break; } } } } catch (Exception e) { certPathException = new Exception("No valid certification path could be build.", e); } if (builderResult == null) { tbvPath.Remove(tbvCert); } return(builderResult); }
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.Value.IntValue; if (_inhibitAnyPolicy < inhibitAnyPolicy) return _inhibitAnyPolicy; } return inhibitAnyPolicy; }
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; }
public virtual PkixCertPathValidatorResult Validate( PkixCertPath certPath, PkixParameters paramsPkix) { if (paramsPkix.GetTrustAnchors() == null) { throw new ArgumentException( "trustAnchors is null, this is not allowed for certification path validation.", "parameters"); } // // 6.1.1 - inputs // // // (a) // IList certs = certPath.Certificates; int n = certs.Count; if (certs.Count == 0) { throw new PkixCertPathValidatorException("Certification path is empty.", null, certPath, 0); } // // (b) // // DateTime validDate = PkixCertPathValidatorUtilities.GetValidDate(paramsPkix); // // (c) // ISet userInitialPolicySet = paramsPkix.GetInitialPolicies(); // // (d) // TrustAnchor trust; try { trust = PkixCertPathValidatorUtilities.FindTrustAnchor( (X509Certificate)certs[certs.Count - 1], paramsPkix.GetTrustAnchors()); } catch (Exception e) { throw new PkixCertPathValidatorException(e.Message, e, certPath, certs.Count - 1); } if (trust == null) { throw new PkixCertPathValidatorException("Trust anchor for certification path not found.", null, certPath, -1); } // // (e), (f), (g) are part of the paramsPkix object. // IEnumerator certIter; int index = 0; int i; // Certificate for each interation of the validation loop // Signature information for each iteration of the validation loop // // 6.1.2 - setup // // // (a) // IList[] policyNodes = new IList[n + 1]; for (int j = 0; j < policyNodes.Length; j++) { policyNodes[j] = Platform.CreateArrayList(); } ISet policySet = new HashSet(); policySet.Add(Rfc3280CertPathUtilities.ANY_POLICY); PkixPolicyNode validPolicyTree = new PkixPolicyNode(Platform.CreateArrayList(), 0, policySet, null, new HashSet(), Rfc3280CertPathUtilities.ANY_POLICY, false); policyNodes[0].Add(validPolicyTree); // // (b) and (c) // PkixNameConstraintValidator nameConstraintValidator = new PkixNameConstraintValidator(); // (d) // int explicitPolicy; ISet acceptablePolicies = new HashSet(); if (paramsPkix.IsExplicitPolicyRequired) { explicitPolicy = 0; } else { explicitPolicy = n + 1; } // // (e) // int inhibitAnyPolicy; if (paramsPkix.IsAnyPolicyInhibited) { inhibitAnyPolicy = 0; } else { inhibitAnyPolicy = n + 1; } // // (f) // int policyMapping; if (paramsPkix.IsPolicyMappingInhibited) { policyMapping = 0; } else { policyMapping = n + 1; } // // (g), (h), (i), (j) // AsymmetricKeyParameter workingPublicKey; X509Name workingIssuerName; X509Certificate sign = trust.TrustedCert; try { if (sign != null) { workingIssuerName = sign.SubjectDN; workingPublicKey = sign.GetPublicKey(); } else { workingIssuerName = new X509Name(trust.CAName); workingPublicKey = trust.CAPublicKey; } } catch (ArgumentException ex) { throw new PkixCertPathValidatorException("Subject of trust anchor could not be (re)encoded.", ex, certPath, -1); } AlgorithmIdentifier workingAlgId = null; try { workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey); } catch (PkixCertPathValidatorException e) { throw new PkixCertPathValidatorException( "Algorithm identifier of public key of trust anchor could not be read.", e, certPath, -1); } // DerObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.ObjectID; // Asn1Encodable workingPublicKeyParameters = workingAlgId.Parameters; // // (k) // int maxPathLength = n; // // 6.1.3 // X509CertStoreSelector certConstraints = paramsPkix.GetTargetCertConstraints(); if (certConstraints != null && !certConstraints.Match((X509Certificate)certs[0])) { throw new PkixCertPathValidatorException( "Target certificate in certification path does not match targetConstraints.", null, certPath, 0); } // // initialize CertPathChecker's // IList pathCheckers = paramsPkix.GetCertPathCheckers(); certIter = pathCheckers.GetEnumerator(); while (certIter.MoveNext()) { ((PkixCertPathChecker)certIter.Current).Init(false); } X509Certificate cert = null; for (index = certs.Count - 1; index >= 0; index--) { // try // { // // i as defined in the algorithm description // i = n - index; // // set certificate to be checked in this round // sign and workingPublicKey and workingIssuerName are set // at the end of the for loop and initialized the // first time from the TrustAnchor // cert = (X509Certificate)certs[index]; // // 6.1.3 // Rfc3280CertPathUtilities.ProcessCertA(certPath, paramsPkix, index, workingPublicKey, workingIssuerName, sign); Rfc3280CertPathUtilities.ProcessCertBC(certPath, index, nameConstraintValidator); validPolicyTree = Rfc3280CertPathUtilities.ProcessCertD(certPath, index, acceptablePolicies, validPolicyTree, policyNodes, inhibitAnyPolicy); validPolicyTree = Rfc3280CertPathUtilities.ProcessCertE(certPath, index, validPolicyTree); Rfc3280CertPathUtilities.ProcessCertF(certPath, index, validPolicyTree, explicitPolicy); // // 6.1.4 // if (i != n) { if (cert != null && cert.Version == 1) { throw new PkixCertPathValidatorException( "Version 1 certificates can't be used as CA ones.", null, certPath, index); } Rfc3280CertPathUtilities.PrepareNextCertA(certPath, index); validPolicyTree = Rfc3280CertPathUtilities.PrepareCertB(certPath, index, policyNodes, validPolicyTree, policyMapping); Rfc3280CertPathUtilities.PrepareNextCertG(certPath, index, nameConstraintValidator); // (h) explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertH1(certPath, index, explicitPolicy); policyMapping = Rfc3280CertPathUtilities.PrepareNextCertH2(certPath, index, policyMapping); inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertH3(certPath, index, inhibitAnyPolicy); // // (i) // explicitPolicy = Rfc3280CertPathUtilities.PrepareNextCertI1(certPath, index, explicitPolicy); policyMapping = Rfc3280CertPathUtilities.PrepareNextCertI2(certPath, index, policyMapping); // (j) inhibitAnyPolicy = Rfc3280CertPathUtilities.PrepareNextCertJ(certPath, index, inhibitAnyPolicy); // (k) Rfc3280CertPathUtilities.PrepareNextCertK(certPath, index); // (l) maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertL(certPath, index, maxPathLength); // (m) maxPathLength = Rfc3280CertPathUtilities.PrepareNextCertM(certPath, index, maxPathLength); // (n) Rfc3280CertPathUtilities.PrepareNextCertN(certPath, index); ISet criticalExtensions1 = cert.GetCriticalExtensionOids(); if (criticalExtensions1 != null) { criticalExtensions1 = new HashSet(criticalExtensions1); // these extensions are handled by the algorithm criticalExtensions1.Remove(X509Extensions.KeyUsage.Id); criticalExtensions1.Remove(X509Extensions.CertificatePolicies.Id); criticalExtensions1.Remove(X509Extensions.PolicyMappings.Id); criticalExtensions1.Remove(X509Extensions.InhibitAnyPolicy.Id); criticalExtensions1.Remove(X509Extensions.IssuingDistributionPoint.Id); criticalExtensions1.Remove(X509Extensions.DeltaCrlIndicator.Id); criticalExtensions1.Remove(X509Extensions.PolicyConstraints.Id); criticalExtensions1.Remove(X509Extensions.BasicConstraints.Id); criticalExtensions1.Remove(X509Extensions.SubjectAlternativeName.Id); criticalExtensions1.Remove(X509Extensions.NameConstraints.Id); } else { criticalExtensions1 = new HashSet(); } // (o) Rfc3280CertPathUtilities.PrepareNextCertO(certPath, index, criticalExtensions1, pathCheckers); // set signing certificate for next round sign = cert; // (c) workingIssuerName = sign.SubjectDN; // (d) try { workingPublicKey = PkixCertPathValidatorUtilities.GetNextWorkingKey(certPath.Certificates, index); } catch (PkixCertPathValidatorException e) { throw new PkixCertPathValidatorException("Next working key could not be retrieved.", e, certPath, index); } workingAlgId = PkixCertPathValidatorUtilities.GetAlgorithmIdentifier(workingPublicKey); // (f) // workingPublicKeyAlgorithm = workingAlgId.ObjectID; // (e) // workingPublicKeyParameters = workingAlgId.Parameters; } } // // 6.1.5 Wrap-up procedure // explicitPolicy = Rfc3280CertPathUtilities.WrapupCertA(explicitPolicy, cert); explicitPolicy = Rfc3280CertPathUtilities.WrapupCertB(certPath, index + 1, explicitPolicy); // // (c) (d) and (e) are already done // // // (f) // ISet criticalExtensions = cert.GetCriticalExtensionOids(); if (criticalExtensions != null) { criticalExtensions = new HashSet(criticalExtensions); // Requires .Id // these extensions are handled by the algorithm criticalExtensions.Remove(X509Extensions.KeyUsage.Id); criticalExtensions.Remove(X509Extensions.CertificatePolicies.Id); criticalExtensions.Remove(X509Extensions.PolicyMappings.Id); criticalExtensions.Remove(X509Extensions.InhibitAnyPolicy.Id); criticalExtensions.Remove(X509Extensions.IssuingDistributionPoint.Id); criticalExtensions.Remove(X509Extensions.DeltaCrlIndicator.Id); criticalExtensions.Remove(X509Extensions.PolicyConstraints.Id); criticalExtensions.Remove(X509Extensions.BasicConstraints.Id); criticalExtensions.Remove(X509Extensions.SubjectAlternativeName.Id); criticalExtensions.Remove(X509Extensions.NameConstraints.Id); criticalExtensions.Remove(X509Extensions.CrlDistributionPoints.Id); } else { criticalExtensions = new HashSet(); } Rfc3280CertPathUtilities.WrapupCertF(certPath, index + 1, pathCheckers, criticalExtensions); PkixPolicyNode intersection = Rfc3280CertPathUtilities.WrapupCertG(certPath, paramsPkix, userInitialPolicySet, index + 1, policyNodes, validPolicyTree, acceptablePolicies); if ((explicitPolicy > 0) || (intersection != null)) { return(new PkixCertPathValidatorResult(trust, intersection, cert.GetPublicKey())); } throw new PkixCertPathValidatorException("Path processing failed on policy.", null, certPath, index); }
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"); } }