Hi,

I have discovered a serious bug in the iText 5.1.1 signature validation
process and I have provided a patch that I would suggest you implement in
your next release.

The problem is in the class "PdfPKCS7" in the method verify().

The original code compares the digest of the document with the digest stored
in encapsulated content info, if present. So far so good.
If signed attributes are present, the signature is checked against the
signed attributes data, which is correct.

What is incorrect is that the hash in the messageDigest signed attribute is
byte compared with the data in encapsulated content info.
This is a violation of CMS. The messageDigest signed attribute holds the
HASH of the data in encapsulated content info, not a byte copy of it.

The consequence is that iText fails validation of perfectly valid signed PDF
documents containing encapsulated content info (as when using the
adbe.pkcs7.sha1 subfilter).

I have done the following patch of the problem.

1) A new class field:

    private MessageDigest encContDigest;


2) In the PdfPKCS7 constructor I expanded the following (added code in
bold):

            if (RSAdata != null || digestAttr != null) {
                if (provider == null || provider.startsWith("SunPKCS11")) {
                    messageDigest =
MessageDigest.getInstance(getHashAlgorithm());
                    //added by 3xA Security ­ Stefan Santesson
                    encContDigest =
MessageDigest.getInstance(getHashAlgorithm());
                } else {
                    messageDigest =
MessageDigest.getInstance(getHashAlgorithm(), provider);
                    //added by 3xA Security ­ Stefan Santesson
                    encContDigest =
MessageDigest.getInstance(getHashAlgorithm(), provider);
                }
            }


3) Updated the verify() method (added/modified code on bold):

    public boolean verify() throws SignatureException {
        if (verified) {
            return verifyResult;
        }
        if (sigAttr != null) {
            final byte[] msgDigestBytes = messageDigest.digest();
            boolean verifyRSAdata = true;
            sig.update(sigAttr);
            // Carrying the fixed CMS compliant digest comparison result for
digest hold in
            // the messageDigest signed attribute
            boolean encContDigestCompare = false;
            if (RSAdata != null) {
                verifyRSAdata = Arrays.equals(msgDigestBytes, RSAdata);
                encContDigest.update(RSAdata);
                encContDigestCompare = Arrays.equals(encContDigest.digest(),
digestAttr);
            }
            boolean absentEncContDigestCompare =
Arrays.equals(msgDigestBytes, digestAttr);

            // Below is a backwards compatibility merge of the two checks.
It is not entirely correct, but is
            // backwards compatible with iText 5.1.1. A fully standards
compliant implementation should
            // only accept "encContDigestCompare" if RSAData is present and
only "absentEncContDigestCompare"
            // if RSAData is absent.
            boolean concludingDigestCompare = absentEncContDigestCompare ||
encContDigestCompare;
            boolean sigVerify = sig.verify(digest);
            verifyResult = concludingDigestCompare && sigVerify &&
verifyRSAdata;
        } else {
            if (RSAdata != null) {
                sig.update(messageDigest.digest());
            }
            verifyResult = sig.verify(digest);
        }
        verified = true;
        return verifyResult;
    }


These changes are tested and works like a charm.

/Stefan Santesson, 3xA Security





------------------------------------------------------------------------------
uberSVN's rich system and user administration capabilities and model 
configuration take the hassle out of deploying and managing Subversion and 
the tools developers use with it. Learn more about uberSVN and get a free 
download at:  http://p.sf.net/sfu/wandisco-dev2dev
_______________________________________________
iText-questions mailing list
iText-questions@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/itext-questions

iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference 
to the iText book: http://www.itextpdf.com/book/
Please check the keywords list before you ask for examples: 
http://itextpdf.com/themes/keywords.php

Reply via email to