Verifying Pades LTV in iTextSharp throws A public key that is not provided for signing a certificate for a CA root certificate

I get Org.BouncyCastle.Security.InvalidKeyExceptionan error message. Public key not provided for signing a certificate during pdf verification c LtvVerifier.

This issue occurred after bypassing the issue with the LDAP CRL URI . The code used to perform the check matches the previous message:

   public static bool Validate(byte[] pdfIn, X509Certificate2 cert)
    {
        using (var reader = new PdfReader(pdfIn))
        {
            var fields = reader.AcroFields;
            var signames = fields.GetSignatureNames();

            if (!signames.Any(n => fields.SignatureCoversWholeDocument(n)))
                throw new Exception("None signature covers all document");

            var verifications = signames.Select(n => fields.VerifySignature(n));

            var invalidSignature = verifications.Where(v => !v.Verify());
            var invalidTimeStamp = verifications.Where(v => !v.VerifyTimestampImprint());

            if (invalidSignature.Any())
                throw new Exception("Invalid signature found");
        }

        using (var reader = new PdfReader(pdfIn))
        {
            var ltvVerifier = new LtvVerifier(reader)
            {
                OnlineCheckingAllowed = false,
                CertificateOption = LtvVerification.CertificateOption.WHOLE_CHAIN,
                Certificates = GetChain(cert).ToList(),
                VerifyRootCertificate = false,
                Verifier = new MyVerifier(null)
            };

            var ltvResult = new List<VerificationOK> { };
            ltvVerifier.Verify(ltvResult);

            if (!ltvResult.Any())
                throw new Exception("Ltv verification failed");
        }
        return true;
   }

A helper function that builds an X509 certificate list from a certificate chain:

    private static X509.X509Certificate[] GetChain(X509Certificate2 myCert)
    {
        var x509Chain = new X509Chain();
        x509Chain.Build(myCert);

        var chain = new List<X509.X509Certificate>();
        foreach(var cert in x509Chain.ChainElements)
        {
            chain.Add(
                DotNetUtilities.FromX509Certificate(cert.Certificate)
                );
        }

        return chain.ToArray();
    }

A custom verifier simply copied from a sample:

 class MyVerifier : CertificateVerifier
{
    public MyVerifier(CertificateVerifier verifier) : base(verifier) { }

    override public List<VerificationOK> Verify(
        X509.X509Certificate signCert, X509.X509Certificate issuerCert, DateTime signDate)
    {
        Console.WriteLine(signCert.SubjectDN + ": ALL VERIFICATIONS DONE");
        return new List<VerificationOK>();
    }
}

I re-executed LtvVerifierand CrlVerifieras described in the previous question. The CRL check is done in order.

, PDF CA. CrlVerifier.Verify :

 if (verifier != null)
                result.AddRange(verifier.Verify(signCert, issuerCert, signDate));
            // verify using the previous verifier in the chain (if any)
            return result;

Org.BouncyCastle.Security.InvalidKeyException:

   in Org.BouncyCastle.X509.X509Certificate.CheckSignature(AsymmetricKeyParameter publicKey, ISigner signature)
   in Org.BouncyCastle.X509.X509Certificate.Verify(AsymmetricKeyParameter key)
   in iTextSharp.text.pdf.security.CertificateVerifier.Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime signDate)
   in iTextSharp.text.pdf.security.RootStoreVerifier.Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime signDate)
   in PdfCommon.CrlVerifierSkippingLdap.Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime signDate) in c:\Projects\digit\Fuentes\PdfCommon\CrlVerifierSkippingLdap.cs:line 76
   in iTextSharp.text.pdf.security.OcspVerifier.Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime signDate)
   in PdfCommon.LtvVerifierSkippingLdap.Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime sigDate) in c:\Projects\digit\Fuentes\PdfCommon\LtvVerifierSkippingLdap.cs:line 221
   in PdfCommon.LtvVerifierSkippingLdap.VerifySignature() in c:\Projects\digit\Fuentes\PdfCommon\LtvVerifierSkippingLdap.cs:line 148
   in PdfCommon.LtvVerifierSkippingLdap.Verify(List`1 result) in c:\Projects\digit\Fuentes\PdfCommon\LtvVerifierSkippingLdap.cs:line 112

pdf,

+4
1

,

iText (Sharp) 5.5.10 LtvVerifier , .

: LtvVerifier Verifier (OcspVerifier, CrlVerifier, RootStoreVerifier, CertificateVerifier), ). Verifier , ; null .

, Verifier, CertificateVerifier, null , :

// Check if the signature is valid
if (issuerCert != null) {
    signCert.Verify(issuerCert.GetPublicKey());
}
// Also in case, the certificate is self-signed
else {
    signCert.Verify(signCert.GetPublicKey());
} 

( CertificateVerifier Verify)

, LtvVerifier ,

Org.BouncyCastle.Security.InvalidKeyException ,

OP

,

cn = AUTORIDAD DE SELLADO DE TIEMPO FNMT-RCM, ou = CERES, o = FNMT-RCM, c = ES

cn = AC Administración Pública, serialNumber = Q2826004J, ou = CERES, o = FNMT-RCM, c = ES

ou = AC RAIZ FNMT-RCM, o = FNMT-RCM, c = ES

.

AC Administración Pública (. TL , " ", "Fábrica Nacional de Moneda y Timbre - Real Casa de la Moneda (FNMT-RCM)", "Trust Service", " su uso en el ámbito de...", "Digital Identity",).

, , , . , LtvVerifier, .

- LtvVerifier.

?

, , .

RootStoreVerifier. Verify :

override public List<VerificationOK> Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime signDate) {
    LOGGER.Info("Root store verification: " + signCert.SubjectDN);
    // verify using the CertificateVerifier if root store is missing
    if (certificates == null)
        return base.Verify(signCert, issuerCert, signDate);
    try {
        List<VerificationOK> result = new List<VerificationOK>();
        // loop over the trusted anchors in the root store
        foreach (X509Certificate anchor in certificates) {
            try {
                signCert.Verify(anchor.GetPublicKey());
                LOGGER.Info("Certificate verified against root store");
                result.Add(new VerificationOK(signCert, this, "Certificate verified against root store."));
                result.AddRange(base.Verify(signCert, issuerCert, signDate));
                return result;
            } catch (GeneralSecurityException) {}
        }
        result.AddRange(base.Verify(signCert, issuerCert, signDate));
        return result;
    } catch (GeneralSecurityException) {
        return base.Verify(signCert, issuerCert, signDate);
    }
}

                signCert.Verify(anchor.GetPublicKey());
                LOGGER.Info("Certificate verified against root store");
                result.Add(new VerificationOK(signCert, this, "Certificate verified against root store."));
                // vvv remove
                result.AddRange(base.Verify(signCert, issuerCert, signDate));
                // ^^^ remove
                return result;

try. , signCert , base.Verify.

+2

Source: https://habr.com/ru/post/1666250/


All Articles