Пример #1
0
 /// <summary>
 /// The default constructor for ValidationContextV2.
 /// </summary>
 /// <param>
 /// The certificate that will be validated.
 /// </param>
 public ValidationContext(X509Certificate certificate, DateTime validationDate, ICAdESLogger cadesLogger, IOcspSource ocspSource, ICrlSource crlSource, ICertificateSource certificateSource, Func <IOcspSource, ICrlSource, ICertificateStatusVerifier> certificateVerifierFactory, Func <CertificateAndContext, CertificateToken> certificateTokenFactory)
 {
     this.certificateTokenFactory = certificateTokenFactory;
     OcspSource = ocspSource;
     CrlSource  = crlSource;
     TrustedListCertificatesSource = certificateSource;
     logger = cadesLogger;
     if (certificate != null)
     {
         logger?.Info("New context for " + certificate.SubjectDN);
         var trustedCert = TrustedListCertificatesSource?.GetCertificateBySubjectName(certificate.SubjectDN)?.FirstOrDefault();
         Certificate = certificate;
         AddNotYetVerifiedToken(certificateTokenFactory(trustedCert ?? new CertificateAndContext(certificate)));
     }
     ValidationDate = validationDate;
     this.certificateVerifierFactory = certificateVerifierFactory;
 }
Пример #2
0
 protected internal virtual SignatureLevelA VerifyLevelA(IAdvancedSignature signature, DateTime referenceTime, IValidationContext ctx, ICAdESLogger logger, Document externalContent)
 {
     try
     {
         SignatureValidationResult           levelReached = new SignatureValidationResult();
         IList <TimestampVerificationResult> verifs       = null;
         try
         {
             IList <TimestampToken> timestamps = signature.ArchiveTimestamps;
             verifs = VerifyTimestamps(signature, referenceTime, ctx, timestamps, signature.GetArchiveTimestampData(0, externalContent));
         }
         catch (IOException e)
         {
             logger.Error("Error verifyind level A " + e.Message);
             levelReached.SetStatus(ResultStatus.UNDETERMINED, "$UI_Signatures_ValidationText_ExceptionWhileVerifying");
         }
         return(new SignatureLevelA(ResultForTimestamps(verifs, levelReached), verifs));
     }
     catch (Exception)
     {
         return(new SignatureLevelA(new SignatureValidationResult(ResultStatus.INVALID, "$UI_Signatures_ValidationText_ExceptionWhileVerifying"), null));
     }
 }
Пример #3
0
        /// <summary>
        /// Main method for validating a signature
        /// </summary>
        /// <param name="signature"></param>
        /// <param name="referenceTime"></param>
        /// <returns>
        /// the report part pertaining to the signature
        /// </returns>
        protected internal virtual SignatureInformation ValidateSignature(IAdvancedSignature signature, DateTime referenceTime, ICAdESLogger logger, SignatureValidationContext signatureValidationContext, bool checkIntegrity, Document externalContent)
        {
            if (signature is null)
            {
                throw new ArgumentNullException(nameof(signature));
            }

            if (signature.SigningCertificate == null)
            {
                logger.Error("There is no signing certificate");
                return(null);
            }



            var signatureVerification               = new SignatureVerification(new SignatureValidationResult(checkIntegrity ? signature.CheckIntegrity(externalContent) : true), signature.SignatureAlgorithm);
            IValidationContext            ctx       = signatureValidationContext.GetExisted(signature.SigningCertificate, referenceTime);
            IList <CertificateAndContext> usedCerts = new List <CertificateAndContext>();

            if (ctx == null)
            {
                ctx = CertificateVerifier.ValidateCertificate(signature.SigningCertificate, referenceTime, signature.CertificateSource, usedCerts, signature.CRLSource, signature.OCSPSource, logger);
                signatureValidationContext.Contexts.Add(ctx);
            }

            var qcStatementInformation     = VerifyQStatement(signature.SigningCertificate);
            var qualificationsVerification = VerifyQualificationsElement(signature, referenceTime, ctx);

            // TODO: serviceinfo is never set, so invalid everytime - hack added  - ?? new ServiceInfo()
            var info = new TrustedListInformation(ctx.GetRelevantServiceInfo() ?? new ServiceInfo());
            var path = new CertPathRevocationAnalysis(ctx, info);


            var signatureLevelXL = VerifyLevelXL(signature, referenceTime, ctx, logger);
            // order matters
            var signatureLevelC        = VerifyLevelC(signature, referenceTime, ctx, signatureLevelXL?.LevelReached.IsValid ?? false, logger);
            var signatureLevelAnalysis = new SignatureLevelAnalysis(
                signature,
                VerifyLevelBES(signature, referenceTime, ctx, externalContent),
                VerifyLevelEPES(signature, referenceTime, ctx),
                VerifyLevelT(signature, referenceTime, ctx),
                signatureLevelC,
                VerifyLevelX(signature, referenceTime, ctx),
                signatureLevelXL,
                VerifyLevelA(signature, referenceTime, ctx, logger, externalContent));


            var signatureInformation = new SignatureInformation(signatureVerification, path, signatureLevelAnalysis, qualificationsVerification, qcStatementInformation, ctx.NeededCertificates.Select(cert => new CertificateVerification(cert, ctx)), ctx);

            return(signatureInformation);
        }
Пример #4
0
 /// <summary>
 /// For level -XL, every X509Crl values contained in the IValidationContext must be in the RevocationValues of the
 /// signature
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="refs"></param>
 /// <param name="signingCert"></param>
 /// <returns></returns>
 protected internal virtual bool EveryCRLValueOrRefAreThere <_T0>(IValidationContext ctx, IList <_T0> crlValuesOrRef, ICAdESLogger logger)
 {
     foreach (X509Crl crl in ctx.NeededCRL)
     {
         logger.Info("Looking for CRL ref issued by " + crl.IssuerDN);
         bool found = false;
         foreach (object valueOrRef in crlValuesOrRef)
         {
             if (valueOrRef is X509Crl)
             {
                 X509Crl sigCRL = (X509Crl)valueOrRef;
                 if (sigCRL.Equals(crl))
                 {
                     found = true;
                     break;
                 }
             }
             if (valueOrRef is CRLRef)
             {
                 CRLRef @ref = (CRLRef)valueOrRef;
                 if (@ref.Match(crl))
                 {
                     found = true;
                     break;
                 }
             }
         }
         logger.Info("Ref " + (found ? " found" : " not found"));
         if (!found)
         {
             return(false);
         }
     }
     return(true);
 }
Пример #5
0
 protected internal virtual SignatureLevelXL VerifyLevelXL(IAdvancedSignature signature, DateTime referenceTime, IValidationContext ctx, ICAdESLogger logger)
 {
     try
     {
         SignatureValidationResult levelReached = new SignatureValidationResult();
         SignatureValidationResult everyNeededCertAreInSignature = new SignatureValidationResult();
         everyNeededCertAreInSignature.SetStatus(ResultStatus.VALID, null);
         SignatureValidationResult everyNeededRevocationData = new SignatureValidationResult();
         everyNeededRevocationData.SetStatus(ResultStatus.VALID, null);
         IList <X509Certificate> refs = signature.Certificates;
         if (!refs.Any())
         {
             logger.Info("There is no certificate refs in the signature");
             everyNeededCertAreInSignature.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoCertificateValue");
         }
         else
         {
             if (!EveryCertificateValueAreThere(ctx, refs, signature.SigningCertificate, logger))
             {
                 everyNeededCertAreInSignature.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoAllNeededCertificateValues");
             }
         }
         logger.Info("Every certificate found " + everyNeededCertAreInSignature);
         int valueCount = 0;
         IList <BasicOcspResp> ocspValues = signature.OCSPs;
         if (ocspValues != null)
         {
             valueCount += ocspValues.Count;
             if (!EveryOCSPValueOrRefAreThere(ctx, ocspValues, logger))
             {
                 everyNeededRevocationData.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoAllNeededOCSPValues");
             }
         }
         IList <X509Crl> crlValues = signature.CRLs;
         if (crlValues != null)
         {
             valueCount += crlValues.Count;
             if (!EveryCRLValueOrRefAreThere(ctx, crlValues, logger))
             {
                 everyNeededRevocationData.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoAllNeededCRLValues");
             }
         }
         if (valueCount == 0)
         {
             everyNeededRevocationData.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoRevocationDataValue");
         }
         levelReached.SetStatus((everyNeededCertAreInSignature.Status == ResultStatus.VALID && everyNeededRevocationData.Status == ResultStatus.VALID) ?
                                ResultStatus.VALID : ResultStatus.INVALID, null);
         return(new SignatureLevelXL(levelReached, everyNeededCertAreInSignature, everyNeededRevocationData));
     }
     catch (Exception)
     {
         return(new SignatureLevelXL(new SignatureValidationResult(ResultStatus.INVALID, "$UI_Signatures_ValidationText_ExceptionWhileVerifying"), new SignatureValidationResult(ResultStatus.INVALID, "$UI_Signatures_ValidationText_ExceptionWhileVerifying"), new SignatureValidationResult(ResultStatus.INVALID, "$UI_Signatures_ValidationText_ExceptionWhileVerifying")));
     }
 }
Пример #6
0
        /// <summary>
        /// For level -XL or C, every BasicOcspResponse values contained in the IValidationContext must be in the
        /// RevocationValues or the RevocationRef of the signature
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="refs"></param>
        /// <param name="signingCert"></param>
        /// <returns></returns>
        protected internal virtual bool EveryOCSPValueOrRefAreThere <_T0>(IValidationContext ctx, IList <_T0> ocspValuesOrRef, ICAdESLogger logger)
        {
            if (ctx is null)
            {
                throw new ArgumentNullException(nameof(ctx));
            }

            if (ocspValuesOrRef is null)
            {
                throw new ArgumentNullException(nameof(ocspValuesOrRef));
            }

            foreach (BasicOcspResp ocspResp in ctx.NeededOCSPResp)
            {
                logger.Info("Looking for the OcspResp produced at " + ocspResp.ProducedAt);
                bool found = false;
                foreach (object valueOrRef in ocspValuesOrRef)
                {
                    if (valueOrRef is BasicOcspResp)
                    {
                        BasicOcspResp sigResp = (BasicOcspResp)valueOrRef;
                        if (sigResp.Equals(ocspResp))
                        {
                            found = true;
                            break;
                        }
                    }
                    if (valueOrRef is OCSPRef)
                    {
                        OCSPRef @ref = (OCSPRef)valueOrRef;
                        if (@ref.Match(ocspResp))
                        {
                            found = true;
                            break;
                        }
                    }
                }
                logger.Info("Ref " + (found ? " found" : " not found"));
                if (!found)
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #7
0
 /// <summary>
 /// For level -XL, every certificates values contained in the IValidationContext (except the SigningCertificate) must
 /// be in the CertificatesValues of the signature
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="certificates"></param>
 /// <param name="signingCert"></param>
 /// <returns></returns>
 protected internal virtual bool EveryCertificateValueAreThere(IValidationContext ctx, IList <X509Certificate> certificates, X509Certificate signingCert, ICAdESLogger logger)
 {
     foreach (CertificateAndContext neededCert in ctx.NeededCertificates)
     {
         if (neededCert.Certificate.Equals(signingCert))
         {
             continue;
         }
         logger.Info("Looking for the certificate ref of " + neededCert);
         bool found = false;
         foreach (X509Certificate referencedCert in certificates)
         {
             logger.Info("Compare to " + referencedCert.SubjectDN);
             if (referencedCert.Equals(neededCert.Certificate))
             {
                 found = true;
                 break;
             }
         }
         logger.Info("Cert " + (found ? " found" : " not found"));
         if (!found)
         {
             return(false);
         }
     }
     return(true);
 }
Пример #8
0
        protected internal virtual SignatureLevelC VerifyLevelC(IAdvancedSignature signature, DateTime referenceTime, IValidationContext ctx, bool rehashValues, ICAdESLogger logger)
        {
            if (signature is null)
            {
                throw new ArgumentNullException(nameof(signature));
            }

            try
            {
                IList <CertificateRef>    refs = signature.CertificateRefs;
                SignatureValidationResult everyNeededCertAreInSignature = new SignatureValidationResult();
                if (refs == null || !refs.Any())
                {
                    everyNeededCertAreInSignature.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoCertificateRef");
                }
                else
                {
                    if (EveryCertificateRefAreThere(ctx, refs, signature.SigningCertificate, logger))
                    {
                        everyNeededCertAreInSignature.SetStatus(ResultStatus.VALID, null);
                    }
                    else
                    {
                        everyNeededCertAreInSignature.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoAllNeededcertificateRef");
                    }
                }
                logger.Info("Every CertificateRef found " + everyNeededCertAreInSignature);
                IList <OCSPRef>           ocspRefs = signature.OCSPRefs;
                IList <CRLRef>            crlRefs  = signature.CRLRefs;
                int                       refCount = 0;
                SignatureValidationResult everyNeededRevocationData = new SignatureValidationResult(ResultStatus.VALID, null);
                refCount += ocspRefs.Count;
                refCount += crlRefs.Count;
                SignatureValidationResult thereIsRevocationData = null;
                SignatureValidationResult levelCReached         = null;
                if (rehashValues)
                {
                    if (!EveryOCSPValueOrRefAreThere(ctx, ocspRefs, logger))
                    {
                        everyNeededRevocationData.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoAllNeededOCSPRef");
                    }
                    if (!EveryCRLValueOrRefAreThere(ctx, crlRefs, logger))
                    {
                        everyNeededRevocationData.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoAllNeededCRLRef");
                    }
                    levelCReached = new SignatureValidationResult(
                        everyNeededCertAreInSignature.Status == ResultStatus.VALID && everyNeededRevocationData.Status == ResultStatus.VALID);
                    return(new SignatureLevelC(levelCReached, everyNeededCertAreInSignature, everyNeededRevocationData));
                }
                else
                {
                    thereIsRevocationData = new SignatureValidationResult();
                    if (refCount == 0)
                    {
                        thereIsRevocationData.SetStatus(ResultStatus.INVALID, "$UI_Signatures_ValidationText_NoRevocationDataRefs");
                    }
                    else
                    {
                        thereIsRevocationData.SetStatus(ResultStatus.VALID, "$UI_Signatures_ValidationText_AtLeastOneRef");
                    }
                    levelCReached = new SignatureValidationResult(everyNeededCertAreInSignature.Status == ResultStatus.VALID && thereIsRevocationData.Status == ResultStatus.VALID);
                    return(new SignatureLevelC(levelCReached, everyNeededCertAreInSignature, thereIsRevocationData));
                }
            }
            catch (Exception)
            {
                return(new SignatureLevelC(
                           new SignatureValidationResult(ResultStatus.INVALID, "$UI_Signatures_ValidationText_ExceptionWhileVerifying"),
                           new SignatureValidationResult(ResultStatus.INVALID, "$UI_Signatures_ValidationText_ExceptionWhileVerifying"),
                           new SignatureValidationResult(ResultStatus.INVALID, "$UI_Signatures_ValidationText_ExceptionWhileVerifying")
                           ));
            }
        }
Пример #9
0
 private bool EveryCertificateRefAreThere(IValidationContext ctx, IList <CertificateRef> refs, X509Certificate signingCert, ICAdESLogger logger)
 {
     foreach (CertificateAndContext neededCert in ctx.NeededCertificates)
     {
         if (neededCert.Certificate.Equals(ctx.Certificate))
         {
             logger.Info("Don't check for the signing certificate");
             continue;
         }
         logger.Info("Looking for the CertificateRef of " + neededCert);
         bool found = false;
         foreach (CertificateRef referencedCert in refs)
         {
             logger.Info("Compare to " + referencedCert);
             byte[] hash = DigestUtilities.CalculateDigest(referencedCert.DigestAlgorithm, neededCert.Certificate.GetEncoded());
             if (hash.SequenceEqual(referencedCert.DigestValue))
             {
                 found = true;
                 break;
             }
         }
         logger.Info("Ref " + (found ? " found" : " not found"));
         if (!found)
         {
             return(false);
         }
     }
     return(true);
 }
        public virtual IValidationContext ValidateCertificate(
            X509Certificate cert, DateTime validationDate, ICertificateSource optionalCertificateSource, IList <CertificateAndContext> usedCerts, ICrlSource optionalCRLSource = null, IOcspSource optionalOCSPSource = null, ICAdESLogger CadesLogger = null)
        {
            if (cert == null || validationDate == null)
            {
                throw new ArgumentNullException("A validation context must contains a cert and a validation date");
            }

            var alreadyUsed = cache.FirstOrDefault(x => x.Certificate == cert && x.ValidationDate == validationDate);

            if (alreadyUsed != null)
            {
                return(alreadyUsed);
            }

            var context = validationContextFactory(cert, validationDate, CadesLogger);

            context.Validate(validationDate, optionalCertificateSource, optionalCRLSource, optionalOCSPSource, usedCerts);
            cache.Add(context);

            return(context);
        }