示例#1
0
        /// <summary>
        /// Shorter implementation of TimestampVerifier.IsValidAfterRevocation method for testing purposes.
        /// </summary>
        public static bool IsValidAfterRevocationFake(X509Crl crl, X509Certificate cert, DateTime timestampGenTime)
        {
            if (crl.IsRevoked(cert))
            {
                X509CrlEntry revokedEntry   = crl.GetRevokedCertificate(cert.SerialNumber);
                DateTime     revocationDate = revokedEntry.RevocationDate;

                /* All timestamps created after revocation date are invalid */
                if (DateTime.Compare(timestampGenTime, revocationDate) > 0)
                {
                    return(false);
                }

                DerEnumerated reasonCode = DerEnumerated.GetInstance(GetExtensionValue(revokedEntry, X509Extensions.ReasonCode));

                /* If the revocation reason is not present, the timestamp is considered invalid */
                if (reasonCode == null)
                {
                    return(false);
                }

                int reason = reasonCode.Value.IntValue;

                /* If the revocation reason is any other value, the timestamp is considered invalid */
                if (!(reason == CrlReason.Unspecified ||
                      reason == CrlReason.AffiliationChanged ||
                      reason == CrlReason.Superseded ||
                      reason == CrlReason.CessationOfOperation))
                {
                    return(false);
                }
            }
            return(true);
        }
        public ValidationError ValidationHandler1(XmlDocument xmlDoc, string xmlFileName)
        {
            ValidationError validationError = new ValidationError(xmlFileName, null);

            X509Certificate signerCert = GetSignerCertificate(xmlDoc);

            if (signerCert == null)
            {
                return(validationError.AppendErrorMessage("Timestamp signer certificate missing."));
            }

            if (!signerCert.IsValidNow)
            {
                return(validationError.AppendErrorMessage("Timestamp signer certificate is not valid to current date."));
            }

            X509CrlEntry crlEntry = CrlHelper.GetRevokedCertificateEntry(signerCert.SerialNumber);

            if (crlEntry != null)
            {
                return(validationError.AppendErrorMessage("Timestamp signer certificate is revoked."));
            }

            return(validationError);
        }
        /// <summary>
        /// Determines whether timestamp, signed by given certificate, can be considered valid, even after said certificate has been revoked.
        /// It follows rules discribed in RFC3161 section 4.1.
        /// </summary>
        /// <param name="certificate">The certificate.</param>
        /// <param name="timestampGenTime">The timestamp time.</param>
        /// <returns>
        ///   <c>true</c> if [is valid after revocation] [the specified certificate]; otherwise, <c>false</c>.
        /// </returns>
        private static bool IsValidAfterRevocation(X509Certificate2 certificate, DateTime timestampGenTime)
        {
            try
            {
                /* Get CRL url from certificate */
                Org.BouncyCastle.X509.X509Certificate cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate);
                X509Extension revocationExtension          = (from X509Extension extension in certificate.Extensions where extension.Oid.Value.Equals("2.5.29.31") select extension).Single();
                Regex         rx = new Regex("http://.*?\\.crl");
                foreach (Match match in rx.Matches(new AsnEncodedData(revocationExtension.Oid, revocationExtension.RawData).Format(false)))
                {
                    string    crlUrl = match.Value;
                    WebClient client = new WebClient();

                    X509CrlParser crlParser = new X509CrlParser();
                    X509Crl       crl       = crlParser.ReadCrl(client.DownloadData(crlUrl));

                    if (crl.IsRevoked(cert))
                    {
                        X509CrlEntry revokedEntry   = crl.GetRevokedCertificate(cert.SerialNumber);
                        DateTime     revocationDate = revokedEntry.RevocationDate;

                        /* All timestamps created after revocation date are invalid */
                        if (DateTime.Compare(timestampGenTime, revocationDate) > 0)
                        {
                            return(false);
                        }

                        DerEnumerated reasonCode = DerEnumerated.GetInstance(GetExtensionValue(revokedEntry, Org.BouncyCastle.Asn1.X509.X509Extensions.ReasonCode));

                        /* If the revocation reason is not present, the timestamp is considered invalid */
                        if (reasonCode == null)
                        {
                            return(false);
                        }

                        int reason = reasonCode.Value.IntValue;

                        /* If the revocation reason is any other value, the timestamp is considered invalid */
                        if (!(reason == Org.BouncyCastle.Asn1.X509.CrlReason.Unspecified ||
                              reason == Org.BouncyCastle.Asn1.X509.CrlReason.AffiliationChanged ||
                              reason == Org.BouncyCastle.Asn1.X509.CrlReason.Superseded ||
                              reason == Org.BouncyCastle.Asn1.X509.CrlReason.CessationOfOperation))
                        {
                            return(false);
                        }
                    }
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
示例#4
0
        public X509CrlEntry GetCrlEntry(BigInteger serial)
        {
            X509CrlEntry result = null;

            _crlLock.EnterReadLock();
            try{
                result = _crl.GetRevokedCertificate(serial);
            }catch (Exception) {
            }finally{
                _crlLock.ExitReadLock();
            }
            return(result);
        }
示例#5
0
        internal static void GetCertStatus(global::System.DateTime validDate, X509Crl crl, object cert, CertStatus certStatus)
        {
            X509Crl x509Crl = null;

            try
            {
                x509Crl = new X509Crl(CertificateList.GetInstance((Asn1Sequence)Asn1Object.FromByteArray(crl.GetEncoded())));
            }
            catch (global::System.Exception ex)
            {
                throw new global::System.Exception("Bouncy Castle X509Crl could not be created.", ex);
            }
            X509CrlEntry revokedCertificate = x509Crl.GetRevokedCertificate(GetSerialNumber(cert));

            if (revokedCertificate == null)
            {
                return;
            }
            X509Name issuerPrincipal = GetIssuerPrincipal(cert);

            if (!issuerPrincipal.Equivalent(revokedCertificate.GetCertificateIssuer(), inOrder: true) && !issuerPrincipal.Equivalent(crl.IssuerDN, inOrder: true))
            {
                return;
            }
            DerEnumerated derEnumerated = null;

            if (revokedCertificate.HasExtensions)
            {
                try
                {
                    derEnumerated = DerEnumerated.GetInstance(GetExtensionValue(revokedCertificate, X509Extensions.ReasonCode));
                }
                catch (global::System.Exception ex2)
                {
                    throw new global::System.Exception("Reason code CRL entry extension could not be decoded.", ex2);
                }
            }
            if (validDate.get_Ticks() >= revokedCertificate.RevocationDate.get_Ticks() || derEnumerated == null || derEnumerated.Value.TestBit(0) || derEnumerated.Value.TestBit(1) || derEnumerated.Value.TestBit(2) || derEnumerated.Value.TestBit(8))
            {
                if (derEnumerated != null)
                {
                    certStatus.Status = derEnumerated.Value.SignValue;
                }
                else
                {
                    certStatus.Status = 0;
                }
                certStatus.RevocationDate = new DateTimeObject(revokedCertificate.RevocationDate);
            }
        }
示例#6
0
    private ISet LoadCrlEntries()
    {
        ISet        set = new HashSet();
        IEnumerable revokedCertificateEnumeration = c.GetRevokedCertificateEnumeration();
        X509Name    previousCertificateIssuer     = IssuerDN;

        foreach (CrlEntry item in revokedCertificateEnumeration)
        {
            X509CrlEntry x509CrlEntry = new X509CrlEntry(item, isIndirect, previousCertificateIssuer);
            set.Add(x509CrlEntry);
            previousCertificateIssuer = x509CrlEntry.GetCertificateIssuer();
        }
        return(set);
    }
示例#7
0
        internal static void GetCertStatus(DateTime validDate, X509Crl crl, object cert, CertStatus certStatus)
        {
            X509Crl x509Crl = null;

            try
            {
                x509Crl = new X509Crl(CertificateList.GetInstance((Asn1Sequence)Asn1Object.FromByteArray(crl.GetEncoded())));
            }
            catch (Exception innerException)
            {
                throw new Exception("Bouncy Castle X509Crl could not be created.", innerException);
            }
            X509CrlEntry revokedCertificate = x509Crl.GetRevokedCertificate(PkixCertPathValidatorUtilities.GetSerialNumber(cert));

            if (revokedCertificate == null)
            {
                return;
            }
            X509Name issuerPrincipal = PkixCertPathValidatorUtilities.GetIssuerPrincipal(cert);

            if (issuerPrincipal.Equivalent(revokedCertificate.GetCertificateIssuer(), true) || issuerPrincipal.Equivalent(crl.IssuerDN, true))
            {
                DerEnumerated derEnumerated = null;
                if (revokedCertificate.HasExtensions)
                {
                    try
                    {
                        derEnumerated = DerEnumerated.GetInstance(PkixCertPathValidatorUtilities.GetExtensionValue(revokedCertificate, X509Extensions.ReasonCode));
                    }
                    catch (Exception innerException2)
                    {
                        throw new Exception("Reason code CRL entry extension could not be decoded.", innerException2);
                    }
                }
                if (validDate.Ticks >= revokedCertificate.RevocationDate.Ticks || derEnumerated == null || derEnumerated.Value.TestBit(0) || derEnumerated.Value.TestBit(1) || derEnumerated.Value.TestBit(2) || derEnumerated.Value.TestBit(8))
                {
                    if (derEnumerated != null)
                    {
                        certStatus.Status = derEnumerated.Value.SignValue;
                    }
                    else
                    {
                        certStatus.Status = 0;
                    }
                    certStatus.RevocationDate = new DateTimeObject(revokedCertificate.RevocationDate);
                }
            }
        }
示例#8
0
 public X509CrlEntry GetCrlEntry(byte[] serialNumber)
 {
     if (serialNumber == null)
     {
         throw new ArgumentNullException("serialNumber");
     }
     for (int i = 0; i < entries.Count; i++)
     {
         X509CrlEntry x509CrlEntry = (X509CrlEntry)entries[i];
         if (Compare(serialNumber, x509CrlEntry.SerialNumber))
         {
             return(x509CrlEntry);
         }
     }
     return(null);
 }
示例#9
0
    public virtual X509CrlEntry GetRevokedCertificate(BigInteger serialNumber)
    {
        IEnumerable revokedCertificateEnumeration = c.GetRevokedCertificateEnumeration();
        X509Name    previousCertificateIssuer     = IssuerDN;

        foreach (CrlEntry item in revokedCertificateEnumeration)
        {
            X509CrlEntry x509CrlEntry = new X509CrlEntry(item, isIndirect, previousCertificateIssuer);
            if (serialNumber.Equals(item.UserCertificate.Value))
            {
                return(x509CrlEntry);
            }
            previousCertificateIssuer = x509CrlEntry.GetCertificateIssuer();
        }
        return(null);
    }
        public ValidationError ValidationHandler1(XmlDocument xmlDoc, string xmlFileName)
        {
            ValidationError validationError = new ValidationError(xmlFileName, null);

            TimeStampToken token = XmlNodeHelper.GetTimeStampToken(xmlDoc);

            Org.BouncyCastle.X509.X509Certificate certificate = XmlNodeHelper.GetX509Certificate(xmlDoc);

            if (certificate == null)
            {
                return(validationError.AppendErrorMessage("Nepodarilo sa nájsť certifikát"));
            }

            if (token == null)
            {
                return(validationError.AppendErrorMessage("Nepodarilo sa nájsť token"));
            }

            // Check certificate validity against timestamp token time
            try
            {
                certificate.CheckValidity(token.TimeStampInfo.GenTime);
            }
            catch (Exception ex)
            {
                return(validationError.AppendErrorMessage("Platnosť podpisového certifikátu neodpovedá času z časovej pečiatky. ErrorMessage ->" + ex.Message));
            }

            // Check certificate validity against crl
            X509CrlEntry entry = CrlHelper.GetRevokedCertificateEntry(certificate.SerialNumber);

            if (entry == null)
            {
                return(validationError);
            }

            if (entry.RevocationDate < token.TimeStampInfo.GenTime)
            {
                return(validationError.AppendErrorMessage("Platnosť certifikátu vypršala"));
            }

            return(validationError);
        }
示例#11
0
        public void AddRevokedResponse(CertificateID cert_id, X509CrlEntry crl_entry)
        {
            int reason;
            var crl_reason_oid = X509Extensions.ReasonCode;
            var ext_reason     = crl_entry.GetExtensionValue(crl_reason_oid);

            if (ext_reason != null)
            {
                var asn1_reason = new DerEnumerated(ext_reason.GetEncoded());
                reason = asn1_reason.Value.IntValue;
            }
            else
            {
                reason = (int)CrlReason.unspecified;
            }
            CertificateStatus status = new RevokedStatus(crl_entry.RevocationDate, reason);

            _builder.AddResponse(cert_id, status, DateTime.UtcNow.AddMinutes(_nextupdate), null);
        }
示例#12
0
        public ValidationResponse ValidateCertificate(X509Certificate2 certificate, String urlCRL)
        {
            try
            {
                byte[]  crl     = transferHttpDataService.GetFile(urlCRL);
                X509Crl x509crl = new X509CrlParser().ReadCrl(crl);
                Org.BouncyCastle.X509.X509Certificate certificateBC = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(certificate);
                X509CrlEntry crlEntry = x509crl.GetRevokedCertificate(certificateBC.SerialNumber);
                if (crlEntry != null)
                {
                    return(new ValidationResponse(CertificateStatus.REVOKED, crlEntry.RevocationDate));
                }

                return(new ValidationResponse(CertificateStatus.VALID));
            }
            catch (CommunicationException)
            {
                return(new ValidationResponse(CertificateStatus.UNKNOWN));
            }
        }
示例#13
0
 public bool IsRevoked(CertificateID id, ref DerGeneralizedTime dt, ref CrlReason reason)
 {
     if (Crl == null)
     {
         return(false);
     }
     else
     {
         X509CrlEntry ent = Crl.GetRevokedCertificate(id.SerialNumber);
         if (ent == null)
         {
             return(false);
         }
         else
         {
             dt     = new DerGeneralizedTime(ent.RevocationDate);
             reason = new CrlReason(CrlReason.CessationOfOperation);
             return(true);
         }
     }
 }
示例#14
0
 public virtual CertificateStatus Check(X509Certificate childCertificate, X509Certificate
                                        certificate, DateTime validationDate)
 {
     try
     {
         CertificateStatus report = new CertificateStatus();
         report.Certificate       = childCertificate;
         report.ValidationDate    = validationDate;
         report.IssuerCertificate = certificate;
         if (crlSource == null)
         {
             LOG.Warn("CRLSource null");
             return(null);
         }
         X509Crl x509crl = crlSource.FindCrl(childCertificate, certificate);
         if (x509crl == null)
         {
             LOG.Info("No CRL found for certificate " + childCertificate.SubjectDN);
             return(null);
         }
         if (!IsCRLValid(x509crl, certificate, validationDate))
         {
             LOG.Warn("The CRL is not valid !");
             return(null);
         }
         report.StatusSource     = x509crl;
         report.Validity         = CertificateValidity.UNKNOWN;
         report.Certificate      = childCertificate;
         report.StatusSourceType = ValidatorSourceType.CRL;
         report.ValidationDate   = validationDate;
         X509CrlEntry crlEntry = x509crl.GetRevokedCertificate(childCertificate.SerialNumber);
         if (null == crlEntry)
         {
             LOG.Info("CRL OK for: " + childCertificate.SubjectDN);
             report.Validity = CertificateValidity.VALID;
         }
         else
         {
             if (crlEntry.RevocationDate.CompareTo(validationDate) > 0)                     //jbonilla - After
             {
                 LOG.Info("CRL OK for: " + childCertificate.SubjectDN + " at " + validationDate
                          );
                 report.Validity = CertificateValidity.VALID;
                 report.RevocationObjectIssuingTime = x509crl.ThisUpdate;
             }
             else
             {
                 LOG.Info("CRL reports certificate: " + childCertificate.SubjectDN
                          + " as revoked since " + crlEntry.RevocationDate);
                 report.Validity = CertificateValidity.REVOKED;
                 report.RevocationObjectIssuingTime = x509crl.ThisUpdate;
                 report.RevocationDate = crlEntry.RevocationDate;
             }
         }
         return(report);
     }
     catch (IOException e)
     {
         LOG.Error("IOException when accessing CRL for " + childCertificate.SubjectDN.ToString() + " " + e.Message);
         return(null);
     }
 }
        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);
                }
            }
        }
示例#16
0
        private async Task <RevocationResult> GetCrlResponse(string url, string host, BcX509Certificate peerCertificate)
        {
            int    maxAttemptCount = 2;
            int    attemptCount    = 0;
            string error           = null;

            while (maxAttemptCount > attemptCount)
            {
                try
                {
                    _log.LogInformation("Attempt {Attempt}: Getting crl info for host {Host} certificate {Certificate} from url {Url}",
                                        attemptCount, host, peerCertificate.SubjectDN, url);

                    HttpResponseMessage httpResponseMessage = await url
                                                              .WithTimeout(TimeSpan.FromSeconds(20))
                                                              .GetAsync();

                    if (httpResponseMessage.IsSuccessStatusCode)
                    {
                        X509Crl x509Crl = _x509CrlParser.ReadCrl(await httpResponseMessage.Content.ReadAsStreamAsync());

                        bool revoked = x509Crl.IsRevoked(peerCertificate);

                        List <RevocationInfo> revocationInfos = new List <RevocationInfo>();
                        if (revoked)
                        {
                            X509CrlEntry crlEntry         = x509Crl.GetRevokedCertificate(peerCertificate.SerialNumber);
                            string       revocationReason = "unknown";
                            if (crlEntry.HasExtensions)
                            {
                                revocationReason = crlEntry.GetExtensionValue(X509Extensions.ReasonCode)?.ToString() ?? "unknown";
                            }
                            revocationInfos.Add(new RevocationInfo(crlEntry.RevocationDate, revocationReason));

                            _log.LogInformation("Certificate {Certificate} for host {Host} is was revoked on {RevocationDate} with reason {RevocationReason}.",
                                                peerCertificate.SubjectDN, host, crlEntry.RevocationDate, revocationReason);
                        }
                        else
                        {
                            _log.LogInformation("Certificate {Certificate} for host {Host} is not revoked.",
                                                peerCertificate.SubjectDN, host);
                        }

                        return(new RevocationResult(revoked, revocationInfos));
                    }

                    _log.LogWarning("Failed to get crl info for host {Host} certificate {Certificate} from url {Url} with http status code {StatusCode}",
                                    host, peerCertificate.SubjectDN.ToString(), url, httpResponseMessage.StatusCode);

                    error = $"Failed call to {url} with http status code {httpResponseMessage.StatusCode}.";
                }
                catch (Exception e)
                {
                    _log.LogError("Failed to get crl revocation info for host {Host} certificate {Certificate} from url {Url} with exception {ExceptionMessage}{StackTrace}",
                                  host, peerCertificate.SubjectDN.ToString(), url, e.Message, e.StackTrace);

                    error = e.Message;
                }

                attemptCount++;
            }
            return(new RevocationResult(error));
        }
示例#17
0
        EsitoVerifica controllaCrlCert(X509Certificate cert, string cachePath, bool force = false)
        {
            //usiamo l'ev solo per i dati di revoca
            EsitoVerifica  ev = new EsitoVerifica();
            string         CN = cert.SubjectDN.GetValues(X509Name.CN).Cast <string>().FirstOrDefault();
            string         SN = cert.SubjectDN.GetValues(X509Name.SerialNumber).Cast <string>().FirstOrDefault();
            X509Extensions ex = X509Extensions.GetInstance(cert.CertificateStructure.TbsCertificate.Extensions);
            X509Extension  e  = ex.GetExtension(X509Extensions.CrlDistributionPoints);

            if (e == null)
            {
                string msg = "CRL distribution points NOT PRESENT in certificate structure";
                logger.Debug(msg);
                ev.status    = EsitoVerificaStatus.ErroreGenerico;
                ev.errorCode = "1411";//nonposso scaricare la CRL
                ev.message   = msg;
                return(ev);
            }
            var           crldp        = CrlDistPoint.GetInstance(e.GetParsedValue());
            List <String> certDpUrlLst = GetCrlDistribtionPoints(crldp);

            ev.status    = EsitoVerificaStatus.Valid;
            ev.SubjectCN = CN;
            ev.SubjectDN = SN;
            int downloadsTrials = 0;

            List <String> errorLst = new List <string>();

            foreach (string url in certDpUrlLst)
            {
                try
                {
                    Uri tryUri = new Uri(url);
                }
                catch
                {
                    logger.ErrorFormat("Unable to download/process CRL  URL : {0}", url);
                    continue;
                }

                try
                {
                    X509Crl rootCrl = retreiveCrlUrl(url, cachePath, force);
                    downloadsTrials++;
                    if (rootCrl.IsRevoked(cert))
                    {
                        X509CrlEntry entry = rootCrl.GetRevokedCertificate(cert.CertificateStructure.SerialNumber.Value);
                        ev.dataRevocaCertificato = entry.RevocationDate;
                        logger.DebugFormat("Certificate {0} : {1} with serial {2}  is Revoked on {3}", CN, SN, BitConverter.ToString(entry.SerialNumber.ToByteArray()), ev.dataRevocaCertificato);
                        ev.content   = entry.SerialNumber.ToByteArray();
                        ev.errorCode = "1408";
                        ev.status    = EsitoVerificaStatus.Revoked;

                        break;
                    }
                }
                catch (Exception exc)
                {
                    logger.ErrorFormat("Unable to download/process CRL message {0} stack {1} on Download Trial {2}", exc.Message, exc.StackTrace, downloadsTrials);
                    errorLst.Add(exc.Message);
                }
            }

            string ErrorMessage = string.Empty;

            if ((errorLst.Count > 0) && downloadsTrials == 0)
            {
                foreach (string s in errorLst)
                {
                    ErrorMessage += s + " | ";
                }
            }


            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ev.status    = EsitoVerificaStatus.ErroreGenerico;
                ev.errorCode = "1411";//nonposso scaricare la CRL
                ev.message   = "Unable to download/process CRL message:" + ErrorMessage;
            }


            return(ev);
        }
示例#18
0
/*
 *  private void verifyTimestamp(TimeStampToken token, X509CRL crl) throws SignVerificationException, XPathExpressionException {
 *              // Read timestamp signature certificate
 *              X509CertificateHolder signCert = getTimestampSignatureCertificate(token);
 *              if (signCert == null) {
 *                      throw new SignVerificationException("Cannot retrieve timestamp signature certificate (Rule 26).");
 *              }
 *
 *              // Rule 26 - Validity
 *              // Check current certificate validity
 *              if (!signCert.isValidOn(new Date())) {
 *                      throw new SignVerificationException("Timestamp signature certificate is not valid now (Rule 26).");
 *              }
 *
 *              // Check against CRL
 *              X509CRLEntry entry = crl.getRevokedCertificate(signCert.getSerialNumber());
 *              if (entry != null) {
 *                      throw new SignVerificationException("Timestamp signature certificate is revoked (Rule 26).");
 *              }
 *
 *              // Rule 27 - Message imprint
 *              byte[] timestampDigest = token.getTimeStampInfo().getMessageImprintDigest();
 *              String hashAlgorithm = token.getTimeStampInfo().getHashAlgorithm().getAlgorithm().getId();
 *
 *              Element signature = querySelector("//ds:Signature/ds:SignatureValue", "Cannot find element 'ds:SignatureValue' (Rule 27).");
 *              byte[] signatureValue = Base64.decode(signature.getTextContent().getBytes());
 *
 *              MessageDigest messageDigest = null;
 *              try {
 *                      messageDigest = MessageDigest.getInstance(hashAlgorithm, "BC");
 *              } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
 *                      throw new SignVerificationException("Unsupported digest type (Rule 27).");
 *              }
 *
 *              byte[] signatureDigest = messageDigest.digest(signatureValue);
 *              if (!Arrays.equals(timestampDigest, signatureDigest)) {
 *                      throw new SignVerificationException("Timestamp MessageImprint check failure (Rule 27).");
 *              }
 * }*/
        private bool validateTimestamp()
        {
            TimeStampToken      token = null;
            X509Crl             ss    = null;
            XmlNamespaceManager mn    = new XmlNamespaceManager(doc.NameTable);
            X509CrlParser       xx    = new X509CrlParser();

            mn.AddNamespace("xades", "http://uri.etsi.org/01903/v1.3.2#");
            string crlUrl = "http://test.ditec.sk/DTCCACrl/DTCCACrl.crl";

            Org.BouncyCastle.X509.X509Certificate signerCert = null;

            try
            {
                var timestamp = this.doc.SelectSingleNode($"//xades:EncapsulatedTimeStamp", mn);

                var    webClient = new WebClient();
                byte[] crlBytes  = webClient.DownloadData(crlUrl);

                token = new TimeStampToken(new CmsSignedData(Convert.FromBase64String(timestamp.InnerText)));

                ss = xx.ReadCrl(crlBytes);

                if (timestamp == null || crlBytes == null || token == null || ss == null)
                {
                    generalException(new Exception());
                    return(false);
                }

                var store = token.GetCertificates("Collection");

                var certs = new ArrayList(store.GetMatches(null));

                foreach (Org.BouncyCastle.X509.X509Certificate cert in certs)
                {
                    string cerIssuer  = cert.IssuerDN.ToString(true, new Hashtable());
                    string signIssuer = token.SignerID.Issuer.ToString(true, new Hashtable());

                    if (cerIssuer == signIssuer && cert.SerialNumber.Equals(token.SignerID.SerialNumber))
                    {
                        signerCert = cert;
                        if (signerCert == null)
                        {
                            generalException(new Exception());
                            return(false);
                        }
                        break;
                    }
                }
                if (!signerCert.IsValidNow)
                {
                    return(false);
                }

                X509CrlEntry revokeCheck = ss.GetRevokedCertificate(signerCert.SerialNumber);
                if (revokeCheck == null)
                {
                    generalException(new Exception());
                    return(false);
                }
            }
            catch (Exception e)
            {
                generalException(e);
            }


            return(false);
        }
        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))
            {
                return;
            }

            int reasonCodeValue = CrlReason.Unspecified;

            if (crl_entry.HasExtensions)
            {
                try
                {
                    Asn1Object    extValue   = GetExtensionValue(crl_entry, X509Extensions.ReasonCode);
                    DerEnumerated reasonCode = DerEnumerated.GetInstance(extValue);
                    if (null != reasonCode)
                    {
                        reasonCodeValue = reasonCode.IntValueExact;
                    }
                }
                catch (Exception e)
                {
                    throw new Exception("Reason code CRL entry extension could not be decoded.", e);
                }
            }

            DateTime revocationDate = crl_entry.RevocationDate;

            if (validDate.Ticks < revocationDate.Ticks)
            {
                switch (reasonCodeValue)
                {
                case CrlReason.Unspecified:
                case CrlReason.KeyCompromise:
                case CrlReason.CACompromise:
                case CrlReason.AACompromise:
                    break;

                default:
                    return;
                }
            }

            // (i) or (j)
            certStatus.Status         = reasonCodeValue;
            certStatus.RevocationDate = new DateTimeObject(revocationDate);
        }