/// <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); }
/// <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); }
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); }
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"))); } }
/// <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); }
/// <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; }
internal virtual ISignedToken GetOneNotYetVerifiedToken() { foreach (KeyValuePair <ISignedToken, RevocationData> e in RevocationInfo) { if (e.Value == null) { logger?.Info("=== Get token to validate " + e.Key); return(e.Key); } } return(null); }
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") )); } }