123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.Collections;
- using System.Globalization;
- using System.IO;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
- {
- internal class Rfc3281CertPathUtilities
- {
- 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);
- }
- }
- /**
- * Checks if an attribute certificate is revoked.
- *
- * @param attrCert Attribute certificate to check if it is revoked.
- * @param paramsPKIX PKIX parameters.
- * @param issuerCert The issuer certificate of the attribute certificate
- * <code>attrCert</code>.
- * @param validDate The date when the certificate revocation status should
- * be checked.
- * @param certPathCerts The certificates of the certification path to be
- * checked.
- *
- * @throws CertPathValidatorException if the certificate is revoked or the
- * status cannot be checked or some error occurs.
- */
- internal static void CheckCrls(
- IX509AttributeCertificate attrCert,
- PkixParameters paramsPKIX,
- X509Certificate issuerCert,
- DateTime validDate,
- IList certPathCerts)
- {
- if (!paramsPKIX.IsRevocationEnabled)
- {
- return;
- }
- // check if revocation is available
- if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
- {
- if (attrCert.GetExtensionValue(X509Extensions.CrlDistributionPoints) != null
- || attrCert.GetExtensionValue(X509Extensions.AuthorityInfoAccess) != null)
- {
- throw new PkixCertPathValidatorException(
- "No rev avail extension is set, but also an AC revocation pointer.");
- }
- return;
- }
- CrlDistPoint crldp = null;
- try
- {
- crldp = CrlDistPoint.GetInstance(
- PkixCertPathValidatorUtilities.GetExtensionValue(
- attrCert, X509Extensions.CrlDistributionPoints));
- }
- catch (Exception e)
- {
- throw new PkixCertPathValidatorException(
- "CRL distribution point extension could not be read.", e);
- }
- try
- {
- PkixCertPathValidatorUtilities
- .AddAdditionalStoresFromCrlDistributionPoint(crldp, paramsPKIX);
- }
- catch (Exception e)
- {
- throw new PkixCertPathValidatorException(
- "No additional CRL locations could be decoded from CRL distribution point extension.", e);
- }
- CertStatus certStatus = new CertStatus();
- ReasonsMask reasonsMask = new ReasonsMask();
- Exception lastException = null;
- bool validCrlFound = false;
- // for each distribution point
- if (crldp != null)
- {
- DistributionPoint[] dps = null;
- try
- {
- dps = crldp.GetDistributionPoints();
- }
- catch (Exception e)
- {
- throw new PkixCertPathValidatorException(
- "Distribution points could not be read.", e);
- }
- try
- {
- for (int i = 0; i < dps.Length
- && certStatus.Status == CertStatus.Unrevoked
- && !reasonsMask.IsAllReasons; i++)
- {
- PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX
- .Clone();
- CheckCrl(dps[i], attrCert, paramsPKIXClone,
- validDate, issuerCert, certStatus, reasonsMask,
- certPathCerts);
- validCrlFound = true;
- }
- }
- catch (Exception e)
- {
- lastException = new Exception(
- "No valid CRL for distribution point found.", e);
- }
- }
- /*
- * If the revocation status has not been determined, repeat the
- * process above with any available CRLs not specified in a
- * distribution point but issued by the certificate issuer.
- */
- if (certStatus.Status == CertStatus.Unrevoked
- && !reasonsMask.IsAllReasons)
- {
- try
- {
- /*
- * assume a DP with both the reasons and the cRLIssuer
- * fields omitted and a distribution point name of the
- * certificate issuer.
- */
- X509Name issuer;
- try
- {
- issuer = X509Name.GetInstance(attrCert.Issuer.GetPrincipals()[0].GetEncoded());
- }
- catch (Exception e)
- {
- throw new Exception(
- "Issuer from certificate for CRL could not be reencoded.",
- e);
- }
- DistributionPoint dp = new DistributionPoint(
- new DistributionPointName(0, new GeneralNames(
- new GeneralName(GeneralName.DirectoryName, issuer))), null, null);
- PkixParameters paramsPKIXClone = (PkixParameters) paramsPKIX.Clone();
- CheckCrl(dp, attrCert, paramsPKIXClone, validDate,
- issuerCert, certStatus, reasonsMask, certPathCerts);
- validCrlFound = true;
- }
- catch (Exception e)
- {
- lastException = new Exception(
- "No valid CRL for distribution point found.", e);
- }
- }
- if (!validCrlFound)
- {
- throw new PkixCertPathValidatorException(
- "No valid CRL found.", lastException);
- }
- if (certStatus.Status != CertStatus.Unrevoked)
- {
- // This format is enforced by the NistCertPath tests
- string formattedDate = certStatus.RevocationDate.Value.ToString(
- "ddd MMM dd HH:mm:ss K yyyy");
- string message = "Attribute certificate revocation after "
- + formattedDate;
- message += ", reason: "
- + Rfc3280CertPathUtilities.CrlReasons[certStatus.Status];
- throw new PkixCertPathValidatorException(message);
- }
- if (!reasonsMask.IsAllReasons
- && certStatus.Status == CertStatus.Unrevoked)
- {
- certStatus.Status = CertStatus.Undetermined;
- }
- if (certStatus.Status == CertStatus.Undetermined)
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate status could not be determined.");
- }
- }
- internal static void AdditionalChecks(
- IX509AttributeCertificate attrCert,
- PkixParameters pkixParams)
- {
- // 1
- foreach (string oid in pkixParams.GetProhibitedACAttributes())
- {
- if (attrCert.GetAttributes(oid) != null)
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate contains prohibited attribute: "
- + oid + ".");
- }
- }
- foreach (string oid in pkixParams.GetNecessaryACAttributes())
- {
- if (attrCert.GetAttributes(oid) == null)
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate does not contain necessary attribute: "
- + oid + ".");
- }
- }
- }
- internal static void ProcessAttrCert5(
- IX509AttributeCertificate attrCert,
- PkixParameters pkixParams)
- {
- try
- {
- attrCert.CheckValidity(PkixCertPathValidatorUtilities.GetValidDate(pkixParams));
- }
- catch (CertificateExpiredException e)
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate is not valid.", e);
- }
- catch (CertificateNotYetValidException e)
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate is not valid.", e);
- }
- }
- internal static void ProcessAttrCert4(
- X509Certificate acIssuerCert,
- PkixParameters pkixParams)
- {
- ISet set = pkixParams.GetTrustedACIssuers();
- bool trusted = false;
- foreach (TrustAnchor anchor in set)
- {
- IDictionary symbols = X509Name.RFC2253Symbols;
- if (acIssuerCert.SubjectDN.ToString(false, symbols).Equals(anchor.CAName)
- || acIssuerCert.Equals(anchor.TrustedCert))
- {
- trusted = true;
- }
- }
- if (!trusted)
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate issuer is not directly trusted.");
- }
- }
- internal static void ProcessAttrCert3(
- X509Certificate acIssuerCert,
- PkixParameters pkixParams)
- {
- if (acIssuerCert.GetKeyUsage() != null
- && (!acIssuerCert.GetKeyUsage()[0] && !acIssuerCert.GetKeyUsage()[1]))
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate issuer public key cannot be used to validate digital signatures.");
- }
- if (acIssuerCert.GetBasicConstraints() != -1)
- {
- throw new PkixCertPathValidatorException(
- "Attribute certificate issuer is also a public key certificate issuer.");
- }
- }
- 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);
- }
- }
- /**
- * Searches for a holder public key certificate and verifies its
- * certification path.
- *
- * @param attrCert the attribute certificate.
- * @param pkixParams The PKIX parameters.
- * @return The certificate path of the holder certificate.
- * @throws Exception if
- * <ul>
- * <li>no public key certificate can be found although holder
- * information is given by an entity name or a base certificate
- * ID</li>
- * <li>support classes cannot be created</li>
- * <li>no certification path for the public key certificate can
- * be built</li>
- * </ul>
- */
- internal static PkixCertPath ProcessAttrCert1(
- IX509AttributeCertificate attrCert,
- PkixParameters pkixParams)
- {
- PkixCertPathBuilderResult result = null;
- // find holder PKCs
- ISet holderPKCs = new HashSet();
- if (attrCert.Holder.GetIssuer() != null)
- {
- X509CertStoreSelector selector = new X509CertStoreSelector();
- selector.SerialNumber = attrCert.Holder.SerialNumber;
- X509Name[] principals = attrCert.Holder.GetIssuer();
- for (int i = 0; i < principals.Length; i++)
- {
- try
- {
- // if (principals[i] is X500Principal)
- {
- selector.Issuer = principals[i];
- }
- holderPKCs.AddAll(PkixCertPathValidatorUtilities
- .FindCertificates(selector, pkixParams.GetStores()));
- }
- catch (Exception e)
- {
- throw new PkixCertPathValidatorException(
- "Public key certificate for attribute certificate cannot be searched.",
- e);
- }
- }
- if (holderPKCs.IsEmpty)
- {
- throw new PkixCertPathValidatorException(
- "Public key certificate specified in base certificate ID for attribute certificate cannot be found.");
- }
- }
- if (attrCert.Holder.GetEntityNames() != null)
- {
- X509CertStoreSelector selector = new X509CertStoreSelector();
- X509Name[] principals = attrCert.Holder.GetEntityNames();
- for (int i = 0; i < principals.Length; i++)
- {
- try
- {
- // if (principals[i] is X500Principal)
- {
- selector.Issuer = principals[i];
- }
- holderPKCs.AddAll(PkixCertPathValidatorUtilities
- .FindCertificates(selector, pkixParams.GetStores()));
- }
- catch (Exception e)
- {
- throw new PkixCertPathValidatorException(
- "Public key certificate for attribute certificate cannot be searched.",
- e);
- }
- }
- if (holderPKCs.IsEmpty)
- {
- throw new PkixCertPathValidatorException(
- "Public key certificate specified in entity name for attribute certificate cannot be found.");
- }
- }
- // verify cert paths for PKCs
- PkixBuilderParameters parameters = (PkixBuilderParameters)
- PkixBuilderParameters.GetInstance(pkixParams);
- PkixCertPathValidatorException lastException = null;
- foreach (X509Certificate cert in holderPKCs)
- {
- X509CertStoreSelector selector = new X509CertStoreSelector();
- selector.Certificate = cert;
- parameters.SetTargetConstraints(selector);
- PkixCertPathBuilder builder = new PkixCertPathBuilder();
- try
- {
- result = builder.Build(PkixBuilderParameters.GetInstance(parameters));
- }
- catch (PkixCertPathBuilderException e)
- {
- lastException = new PkixCertPathValidatorException(
- "Certification path for public key certificate of attribute certificate could not be build.",
- e);
- }
- }
- if (lastException != null)
- {
- throw lastException;
- }
- return result.CertPath;
- }
- /**
- *
- * Checks a distribution point for revocation information for the
- * certificate <code>attrCert</code>.
- *
- * @param dp The distribution point to consider.
- * @param attrCert The attribute certificate which should be checked.
- * @param paramsPKIX PKIX parameters.
- * @param validDate The date when the certificate revocation status should
- * be checked.
- * @param issuerCert Certificate to check if it is revoked.
- * @param reasonMask The reasons mask which is already checked.
- * @param certPathCerts The certificates of the certification path to be
- * checked.
- * @throws Exception if the certificate is revoked or the status
- * cannot be checked or some error occurs.
- */
- private static void CheckCrl(
- DistributionPoint dp,
- IX509AttributeCertificate attrCert,
- PkixParameters paramsPKIX,
- DateTime validDate,
- X509Certificate issuerCert,
- CertStatus certStatus,
- ReasonsMask reasonMask,
- IList certPathCerts)
- {
- /*
- * 4.3.6 No Revocation Available
- *
- * The noRevAvail extension, defined in [X.509-2000], allows an AC
- * issuer to indicate that no revocation information will be made
- * available for this AC.
- */
- if (attrCert.GetExtensionValue(X509Extensions.NoRevAvail) != null)
- {
- return;
- }
- DateTime currentDate = DateTime.UtcNow;
- if (validDate.CompareTo(currentDate) > 0)
- {
- throw new Exception("Validation time is in future.");
- }
- // (a)
- /*
- * We always get timely valid CRLs, so there is no step (a) (1).
- * "locally cached" CRLs are assumed to be in getStore(), additional
- * CRLs must be enabled in the ExtendedPkixParameters and are in
- * getAdditionalStore()
- */
- ISet crls = PkixCertPathValidatorUtilities.GetCompleteCrls(dp, attrCert,
- currentDate, paramsPKIX);
- bool validCrlFound = false;
- Exception lastException = null;
- IEnumerator crl_iter = crls.GetEnumerator();
- while (crl_iter.MoveNext()
- && certStatus.Status == CertStatus.Unrevoked
- && !reasonMask.IsAllReasons)
- {
- try
- {
- X509Crl crl = (X509Crl) crl_iter.Current;
- // (d)
- ReasonsMask interimReasonsMask = Rfc3280CertPathUtilities.ProcessCrlD(crl, dp);
- // (e)
- /*
- * The reasons mask is updated at the end, so only valid CRLs
- * can update it. If this CRL does not contain new reasons it
- * must be ignored.
- */
- if (!interimReasonsMask.HasNewReasons(reasonMask))
- {
- continue;
- }
- // (f)
- ISet keys = Rfc3280CertPathUtilities.ProcessCrlF(crl, attrCert,
- null, null, paramsPKIX, certPathCerts);
- // (g)
- AsymmetricKeyParameter pubKey = Rfc3280CertPathUtilities.ProcessCrlG(crl, keys);
- X509Crl deltaCRL = null;
- if (paramsPKIX.IsUseDeltasEnabled)
- {
- // get delta CRLs
- ISet deltaCRLs = PkixCertPathValidatorUtilities.GetDeltaCrls(
- currentDate, paramsPKIX, crl);
- // we only want one valid delta CRL
- // (h)
- deltaCRL = Rfc3280CertPathUtilities.ProcessCrlH(deltaCRLs, pubKey);
- }
- /*
- * CRL must be be valid at the current time, not the validation
- * time. If a certificate is revoked with reason keyCompromise,
- * cACompromise, it can be used for forgery, also for the past.
- * This reason may not be contained in older CRLs.
- */
- /*
- * in the chain model signatures stay valid also after the
- * certificate has been expired, so they do not have to be in
- * the CRL vality time
- */
- if (paramsPKIX.ValidityModel != PkixParameters.ChainValidityModel)
- {
- /*
- * if a certificate has expired, but was revoked, it is not
- * more in the CRL, so it would be regarded as valid if the
- * first check is not done
- */
- if (attrCert.NotAfter.CompareTo(crl.ThisUpdate) < 0)
- {
- throw new Exception(
- "No valid CRL for current time found.");
- }
- }
- Rfc3280CertPathUtilities.ProcessCrlB1(dp, attrCert, crl);
- // (b) (2)
- Rfc3280CertPathUtilities.ProcessCrlB2(dp, attrCert, crl);
- // (c)
- Rfc3280CertPathUtilities.ProcessCrlC(deltaCRL, crl, paramsPKIX);
- // (i)
- Rfc3280CertPathUtilities.ProcessCrlI(validDate, deltaCRL,
- attrCert, certStatus, paramsPKIX);
- // (j)
- Rfc3280CertPathUtilities.ProcessCrlJ(validDate, crl, attrCert,
- certStatus);
- // (k)
- if (certStatus.Status == CrlReason.RemoveFromCrl)
- {
- certStatus.Status = CertStatus.Unrevoked;
- }
- // update reasons mask
- reasonMask.AddReasons(interimReasonsMask);
- validCrlFound = true;
- }
- catch (Exception e)
- {
- lastException = e;
- }
- }
- if (!validCrlFound)
- {
- throw lastException;
- }
- }
- }
- }
- #pragma warning restore
- #endif
|