Digital signatures - chapter 5

This is a code example of iText PDF, discover more.

1st November 2015
admin-marketing

These examples were written in the context of the white paper Digital Signatures for PDF documents.

C5_01_SignatureIntegrity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package signatures.chapter5;
 
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.util.ArrayList;
 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.PdfPKCS7;
 
public class C5_01_SignatureIntegrity {
    public static final String EXAMPLE1 = "results/chapter2/hello_level_1_annotated_wrong.pdf";
    public static final String EXAMPLE2 = "results/chapter2/step_4_signed_by_alice_bob_carol_and_dave.pdf";
    public static final String EXAMPLE3 = "results/chapter2/step_6_signed_by_dave_broken_by_chuck.pdf";
 
    public PdfPKCS7 verifySignature(AcroFields fields, String name) throws GeneralSecurityException, IOException {
        System.out.println("Signature covers whole document: " + fields.signatureCoversWholeDocument(name));
        System.out.println("Document revision: " + fields.getRevision(name) + " of " + fields.getTotalRevisions());
        PdfPKCS7 pkcs7 = fields.verifySignature(name);
        System.out.println("Integrity check OK? " + pkcs7.verify());
        return pkcs7;
    }
    
    public void verifySignatures(String path) throws IOException, GeneralSecurityException {
        System.out.println(path);
        PdfReader reader = new PdfReader(path);
        AcroFields fields = reader.getAcroFields();
        ArrayList<String> names = fields.getSignatureNames();
        for (String name : names) {
            System.out.println("===== " + name + " =====");
            verifySignature(fields, name);
        }
        System.out.println();
    }
    
    public static void main(String[] args) throws IOException, GeneralSecurityException {
        LoggerFactory.getInstance().setLogger(new SysoLogger());
        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        C5_01_SignatureIntegrity app = new C5_01_SignatureIntegrity();
        app.verifySignatures(EXAMPLE1);
        app.verifySignatures(EXAMPLE2);
        app.verifySignatures(EXAMPLE3);
    }
}
C5_02_SignatureInfo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package signatures.chapter5;
 
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.tsp.TimeStampToken;
 
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.AcroFields.FieldPosition;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.security.CertificateInfo;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import com.itextpdf.text.pdf.security.SignaturePermissions;
import com.itextpdf.text.pdf.security.SignaturePermissions.FieldLock;
 
public class C5_02_SignatureInfo extends C5_01_SignatureIntegrity {
    public static final String EXAMPLE1 = "results/chapter2/step_4_signed_by_alice_bob_carol_and_dave.pdf";
    public static final String EXAMPLE2 = "results/chapter3/hello_cacert_ocsp_ts.pdf";
    public static final String EXAMPLE3 = "results/chapter3/hello_token.pdf";
    public static final String EXAMPLE4 = "results/chapter2/hello_signed4.pdf";
    public static final String EXAMPLE5 = "results/chapter4/hello_smartcard_Signature.pdf";
    public static final String EXAMPLE6 = "results/chapter2/field_metadata.pdf";
 
    public SignaturePermissions inspectSignature(AcroFields fields, String name, SignaturePermissions perms) throws GeneralSecurityException, IOException {
        List<FieldPosition> fps = fields.getFieldPositions(name);
        if (fps != null && fps.size() > 0) {
            FieldPosition fp = fps.get(0);
            Rectangle pos = fp.position;
            if (pos.getWidth() == 0 || pos.getHeight() == 0) {
                System.out.println("Invisible signature");
            }
            else {
                System.out.println(String.format("Field on page %s; llx: %s, lly: %s, urx: %s; ury: %s",
                    fp.page, pos.getLeft(), pos.getBottom(), pos.getRight(), pos.getTop()));
            }
        }
        
        PdfPKCS7 pkcs7 = super.verifySignature(fields, name);
        System.out.println("Digest algorithm: " + pkcs7.getHashAlgorithm());
        System.out.println("Encryption algorithm: " + pkcs7.getEncryptionAlgorithm());
        System.out.println("Filter subtype: " + pkcs7.getFilterSubtype());
        X509Certificate cert = (X509Certificate) pkcs7.getSigningCertificate();
            System.out.println("Name of the signer: " + CertificateInfo.getSubjectFields(cert).getField("CN"));
        if (pkcs7.getSignName() != null)
            System.out.println("Alternative name of the signer: " + pkcs7.getSignName());
        SimpleDateFormat date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
        System.out.println("Signed on: " + date_format.format(pkcs7.getSignDate().getTime()));
        if (pkcs7.getTimeStampDate() != null) {
            System.out.println("TimeStamp: " + date_format.format(pkcs7.getTimeStampDate().getTime()));
            TimeStampToken ts = pkcs7.getTimeStampToken();
            System.out.println("TimeStamp service: " + ts.getTimeStampInfo().getTsa());
            System.out.println("Timestamp verified? " + pkcs7.verifyTimestampImprint());
        }
        System.out.println("Location: " + pkcs7.getLocation());
        System.out.println("Reason: " + pkcs7.getReason());
        PdfDictionary sigDict = fields.getSignatureDictionary(name);
        PdfString contact = sigDict.getAsString(PdfName.CONTACTINFO);
        if (contact != null)
            System.out.println("Contact info: " + contact);
        perms = new SignaturePermissions(sigDict, perms);
        System.out.println("Signature type: " + (perms.isCertification() ? "certification" : "approval"));
        System.out.println("Filling out fields allowed: " + perms.isFillInAllowed());
        System.out.println("Adding annotations allowed: " + perms.isAnnotationsAllowed());
        for (FieldLock lock : perms.getFieldLocks()) {
            System.out.println("Lock: " + lock.toString());
        }
        return perms;
    }
    
    public void inspectSignatures(String path) throws IOException, GeneralSecurityException {
        System.out.println(path);
        PdfReader reader = new PdfReader(path);
        AcroFields fields = reader.getAcroFields();
        ArrayList<String> names = fields.getSignatureNames();
        SignaturePermissions perms = null;
        for (String name : names) {
            System.out.println("===== " + name + " =====");
            perms = inspectSignature(fields, name, perms);
        }
        System.out.println();
    }
    
    public static void main(String[] args) throws IOException, GeneralSecurityException {
        LoggerFactory.getInstance().setLogger(new SysoLogger());
        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        C5_02_SignatureInfo app = new C5_02_SignatureInfo();
        app.inspectSignatures(EXAMPLE1);
        app.inspectSignatures(EXAMPLE2);
        app.inspectSignatures(EXAMPLE3);
        app.inspectSignatures(EXAMPLE4);
        app.inspectSignatures(EXAMPLE5);
        app.inspectSignatures(EXAMPLE6);
    }
}
C5_03_CertificateValidation.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package signatures.chapter5;
 
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.CRL;
import java.security.cert.Certificate;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
 
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.security.CRLVerifier;
import com.itextpdf.text.pdf.security.CertificateVerification;
import com.itextpdf.text.pdf.security.OCSPVerifier;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import com.itextpdf.text.pdf.security.VerificationException;
import com.itextpdf.text.pdf.security.VerificationOK;
 
public class C5_03_CertificateValidation extends C5_01_SignatureIntegrity {
    public static final String ADOBE = "src/main/resources/adobeRootCA.cer";
    public static final String CACERT = "src/main/resources/CACertSigningAuthority.crt";
    public static final String BRUNO = "src/main/resources/bruno.crt";
 
    public static final String EXAMPLE1 = "results/chapter3/hello_cacert_ocsp_ts.pdf";
    public static final String EXAMPLE2 = "results/chapter3/hello_token.pdf";
    public static final String EXAMPLE3 = "results/chapter2/hello_signed1.pdf";
    public static final String EXAMPLE4 = "results/chapter4/hello_smartcard_Signature.pdf";
 
    KeyStore ks;
 
    public PdfPKCS7 verifySignature(AcroFields fields, String name)
            throws GeneralSecurityException, IOException {
        PdfPKCS7 pkcs7 = super.verifySignature(fields, name);
        Certificate[] certs = pkcs7.getSignCertificateChain();
        Calendar cal = pkcs7.getSignDate();
        List<VerificationException> errors = CertificateVerification.verifyCertificates(certs, ks, cal);
        if (errors.size() == 0)
            System.out.println("Certificates verified against the KeyStore");
        else
            System.out.println(errors);
        for (int i = 0; i < certs.length; i++) {
            X509Certificate cert = (X509Certificate) certs[i];
            System.out.println("=== Certificate " + i + " ===");
            showCertificateInfo(cert, cal.getTime());
        }
        X509Certificate signCert = (X509Certificate)certs[0];
        X509Certificate issuerCert = (certs.length > 1 ? (X509Certificate)certs[1] : null);
        System.out.println("=== Checking validity of the document at the time of signing ===");
        checkRevocation(pkcs7, signCert, issuerCert, cal.getTime());
        System.out.println("=== Checking validity of the document today ===");
        checkRevocation(pkcs7, signCert, issuerCert, new Date());
        return pkcs7;
    }
    
    public static void checkRevocation(PdfPKCS7 pkcs7, X509Certificate signCert, X509Certificate issuerCert, Date date) throws GeneralSecurityException, IOException {
        List<BasicOCSPResp> ocsps = new ArrayList<BasicOCSPResp>();
        if (pkcs7.getOcsp() != null)
            ocsps.add(pkcs7.getOcsp());
        OCSPVerifier ocspVerifier = new OCSPVerifier(null, ocsps);
        List<VerificationOK> verification =
            ocspVerifier.verify(signCert, issuerCert, date);
        if (verification.size() == 0) {
            List<X509CRL> crls = new ArrayList<X509CRL>();
            if (pkcs7.getCRLs() != null) {
                for (CRL crl : pkcs7.getCRLs())
                    crls.add((X509CRL)crl);
            }
            CRLVerifier crlVerifier = new CRLVerifier(null, crls);
            verification.addAll(crlVerifier.verify(signCert, issuerCert, date));
        }
        if (verification.size() == 0) {
            System.out.println("The signing certificate couldn't be verified");
        }
        else {
            for (VerificationOK v : verification)
                System.out.println(v);
        }
    }
 
    public void showCertificateInfo(X509Certificate cert, Date signDate) {
        System.out.println("Issuer: " + cert.getIssuerDN());
        System.out.println("Subject: " + cert.getSubjectDN());
        SimpleDateFormat date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
        System.out.println("Valid from: " + date_format.format(cert.getNotBefore()));
        System.out.println("Valid to: " + date_format.format(cert.getNotAfter()));
        try {
            cert.checkValidity(signDate);
            System.out
                    .println("The certificate was valid at the time of signing.");
        } catch (CertificateExpiredException e) {
            System.out
                    .println("The certificate was expired at the time of signing.");
        } catch (CertificateNotYetValidException e) {
            System.out
                    .println("The certificate wasn't valid yet at the time of signing.");
        }
        try {
            cert.checkValidity();
            System.out.println("The certificate is still valid.");
        } catch (CertificateExpiredException e) {
            System.out.println("The certificate has expired.");
        } catch (CertificateNotYetValidException e) {
            System.out.println("The certificate isn't valid yet.");
        }
    }
    
    private void setKeyStore(KeyStore ks) {
        this.ks = ks;
    }
 
    public static void main(String[] args) throws IOException,
            GeneralSecurityException {
        LoggerFactory.getInstance().setLogger(new SysoLogger());
        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        C5_03_CertificateValidation app = new C5_03_CertificateValidation();
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
 
        ks.load(null, null);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        ks.setCertificateEntry("adobe",
                cf.generateCertificate(new FileInputStream(ADOBE)));
        ks.setCertificateEntry("cacert",
                cf.generateCertificate(new FileInputStream(CACERT)));
        ks.setCertificateEntry("bruno",
                cf.generateCertificate(new FileInputStream(BRUNO)));
        app.setKeyStore(ks);
        app.verifySignatures(EXAMPLE1);
        app.verifySignatures(EXAMPLE2);
        app.verifySignatures(EXAMPLE3);
        app.verifySignatures(EXAMPLE4);
    }
}
C5_04_LTV.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package signatures.chapter5;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.util.List;
import java.util.Properties;
 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.security.CrlClient;
import com.itextpdf.text.pdf.security.CrlClientOnline;
import com.itextpdf.text.pdf.security.LtvTimestamp;
import com.itextpdf.text.pdf.security.LtvVerification;
import com.itextpdf.text.pdf.security.OcspClient;
import com.itextpdf.text.pdf.security.OcspClientBouncyCastle;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import com.itextpdf.text.pdf.security.TSAClient;
import com.itextpdf.text.pdf.security.TSAClientBouncyCastle;
 
public class C5_04_LTV {
 
    public static final String EXAMPLE1 = "results/chapter3/hello_token.pdf";
    public static final String EXAMPLE2 = "results/chapter4/hello_smartcard_Signature.pdf";
    public static final String EXAMPLE3 = "results/chapter3/hello_cacert_ocsp_ts.pdf";
    public static final String DEST = "results/chapter5/ltv_%s.pdf";
    
    public static void main(String[] args) throws IOException, DocumentException, GeneralSecurityException {
        Security.addProvider(new BouncyCastleProvider());
        LoggerFactory.getInstance().setLogger(new SysoLogger());
        Properties properties = new Properties();
        properties.load(new FileInputStream("c:/home/blowagie/key.properties"));
        String tsaUrl = properties.getProperty("TSAURL");
        String tsaUser = properties.getProperty("TSAUSERNAME");
        String tsaPass = properties.getProperty("TSAPASSWORD");
        C5_04_LTV app = new C5_04_LTV();
        TSAClient tsa = new TSAClientBouncyCastle(tsaUrl, tsaUser, tsaPass, 6500, "SHA512");
        OcspClient ocsp = new OcspClientBouncyCastle();
        app.addLtv(EXAMPLE1, String.format(DEST, 1), ocsp, new CrlClientOnline(), tsa);
        System.out.println();
        app.addLtv(EXAMPLE2, String.format(DEST, 2), ocsp, new CrlClientOnline(), tsa);
        System.out.println();
        app.addLtv(EXAMPLE3, String.format(DEST, 3), ocsp, new CrlClientOnline(), tsa);
        System.out.println();
        app.addLtv(String.format(DEST, 1), String.format(DEST, 4), null, new CrlClientOnline(), tsa);
    }
    
    public void addLtv(String src, String dest, OcspClient ocsp, CrlClient crl, TSAClient tsa) throws IOException, DocumentException, GeneralSecurityException {
        PdfReader r = new PdfReader(src);
        FileOutputStream fos = new FileOutputStream(dest);
        PdfStamper stp = PdfStamper.createSignature(r, fos, '\0', null, true);
        LtvVerification v = stp.getLtvVerification();
        AcroFields fields = stp.getAcroFields();
        List<String> names = fields.getSignatureNames();
        String sigName = names.get(names.size() - 1);
        PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
        if (pkcs7.isTsp())
            System.out.println("TIMESTAMP!");
        for (String name : names) {
            v.addVerification(name, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
        }
        PdfSignatureAppearance sap = stp.getSignatureAppearance();
        LtvTimestamp.timestamp(sap, tsa, null); 
    }
}
C5_05_CheckLTV.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package signatures.chapter5;
 
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.log.SysoLogger;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.CertificateInfo;
import com.itextpdf.text.pdf.security.PdfPKCS7;
 
public class C5_05_CheckLTV {
    public static final String EXAMPLE1 = "results/chapter5/ltv_1.pdf";
    public static final String EXAMPLE2 = "results/chapter5/ltv_2.pdf";
    public static final String EXAMPLE3 = "results/chapter5/ltv_3.pdf";
    public static final String EXAMPLE4 = "results/chapter5/ltv_4.pdf";
 
    public PdfPKCS7 verifySignature(AcroFields fields, String name) throws GeneralSecurityException, IOException {
        System.out.println("Signature covers whole document: " + fields.signatureCoversWholeDocument(name));
        System.out.println("Document revision: " + fields.getRevision(name) + " of " + fields.getTotalRevisions());
        PdfPKCS7 pkcs7 = fields.verifySignature(name);
        System.out.println("Integrity check OK? " + pkcs7.verify());
        System.out.println("Digest algorithm: " + pkcs7.getHashAlgorithm());
        System.out.println("Encryption algorithm: " + pkcs7.getEncryptionAlgorithm());
        System.out.println("Filter subtype: " + pkcs7.getFilterSubtype());
        X509Certificate cert = (X509Certificate) pkcs7.getSigningCertificate();
        System.out.println("Name of the signer: " + CertificateInfo.getSubjectFields(cert).getField("CN"));
        return pkcs7;
    }
    
    public void verifySignatures(String path) throws IOException, GeneralSecurityException {
        System.out.println(path);
        PdfReader reader = new PdfReader(path);
        AcroFields fields = reader.getAcroFields();
        ArrayList<String> names = fields.getSignatureNames();
        for (String name : names) {
            System.out.println("===== " + name + " =====");
            verifySignature(fields, name);
        }
        System.out.println();
    }
    
    public static void main(String[] args) throws IOException, GeneralSecurityException {
        LoggerFactory.getInstance().setLogger(new SysoLogger());
        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        C5_05_CheckLTV app = new C5_05_CheckLTV();
        app.verifySignatures(EXAMPLE1);
        app.verifySignatures(EXAMPLE2);
        app.verifySignatures(EXAMPLE3);
        app.verifySignatures(EXAMPLE4);
    }
}
C5_06_ValidateLTV.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package signatures.chapter5;
 
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.CertificateVerifier;
import com.itextpdf.text.pdf.security.LtvVerifier;
import com.itextpdf.text.pdf.security.LtvVerification.CertificateOption;
import com.itextpdf.text.pdf.security.VerificationOK;
 
public class C5_06_ValidateLTV {
    public static final String ADOBE = "src/main/resources/adobeRootCA.cer";
    public static final String EXAMPLE1 = "results/chapter5/ltv_1.pdf";
    public static final String EXAMPLE2 = "results/chapter5/ltv_2.pdf";
    public static final String EXAMPLE3 = "results/chapter5/ltv_3.pdf";
    public static final String EXAMPLE4 = "results/chapter5/ltv_4.pdf";
    
    public static void main(String[] args) throws IOException, GeneralSecurityException {
        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        C5_06_ValidateLTV app = new C5_06_ValidateLTV();
        System.out.println(EXAMPLE1);
        app.validate(new PdfReader(EXAMPLE1));
        System.out.println();
        System.out.println(EXAMPLE2);
        app.validate(new PdfReader(EXAMPLE2));
        System.out.println();
        System.out.println(EXAMPLE3);
        app.validate(new PdfReader(EXAMPLE3));
        System.out.println();
        System.out.println(EXAMPLE4);
        app.validate(new PdfReader(EXAMPLE4));
    }
    
    public void validate(PdfReader reader) throws IOException, GeneralSecurityException {
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        ks.setCertificateEntry("adobe",
                cf.generateCertificate(new FileInputStream(ADOBE)));
        
        CertificateVerifier custom = new CertificateVerifier(null) {
            public List<VerificationOK> verify(X509Certificate signCert,
                    X509Certificate issuerCert, Date signDate)
                    throws GeneralSecurityException, IOException {
                System.out.println(signCert.getSubjectDN().getName() + ": ALL VERIFICATIONS DONE");
                return new ArrayList<VerificationOK>();
            }
        };
        
        LtvVerifier data = new LtvVerifier(reader);
        data.setRootStore(ks);
        data.setCertificateOption(CertificateOption.WHOLE_CHAIN);
        data.setVerifier(custom);
        data.setOnlineCheckingAllowed(false);
        data.setVerifyRootCertificate(false);
        List<VerificationOK> list = new ArrayList<VerificationOK>();
        try {
            data.verify(list);
        }
        catch(GeneralSecurityException e) {
            System.err.println(e.getMessage());
        }
        System.out.println();
        if (list.size() == 0) {
            System.out.println("The document can't be verified");
        }
        for (VerificationOK v : list)
            System.out.println(v.toString());
    }
}
C5_01_SignatureIntegrity.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
 
using System;
using System.Collections.Generic;
using iTextSharp.text.log;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
 
namespace signatures.chapter5 {
    public class C5_01_SignatureIntegrity {
        public const String EXAMPLE1 = "../../../../results/chapter2/hello_level_1_annotated_wrong.pdf";
        public const String EXAMPLE2 = "../../../../results/chapter2/step_4_signed_by_alice_bob_carol_and_dave.pdf";
        public const String EXAMPLE3 = "../../../../results/chapter2/step_6_signed_by_dave_broken_by_chuck.pdf";
 
        virtual public PdfPKCS7 VerifySignature(AcroFields fields, String name) {
            Console.WriteLine("Signature covers whole document: " + fields.SignatureCoversWholeDocument(name));
            Console.WriteLine("Document revision: " + fields.GetRevision(name) + " of " + fields.TotalRevisions);
            PdfPKCS7 pkcs7 = fields.VerifySignature(name);
            Console.WriteLine("Integrity check OK? " + pkcs7.Verify());
            return pkcs7;
        }
        
        public void VerifySignatures(String path) {
            Console.WriteLine(path);
            PdfReader reader = new PdfReader(path);
            AcroFields fields = reader.AcroFields;
            List<String> names = fields.GetSignatureNames();
            foreach (string name in names) {
                Console.WriteLine("===== " + name + " =====");
                VerifySignature(fields, name);
            }
            Console.WriteLine();
        }
        
        public static void Main(String[] args) {
            LoggerFactory.GetInstance().SetLogger(new SysoLogger());
            C5_01_SignatureIntegrity app = new C5_01_SignatureIntegrity();
            app.VerifySignatures(EXAMPLE1);
            app.VerifySignatures(EXAMPLE2);
            app.VerifySignatures(EXAMPLE3);
        }
    }
}
C5_02_SignatureInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
 
using System;
using System.Collections.Generic;
using Org.BouncyCastle.Tsp;
using Org.BouncyCastle.X509;
using iTextSharp.text;
using iTextSharp.text.log;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
 
namespace signatures.chapter5 {
    class C5_02_SignatureInfo : C5_01_SignatureIntegrity {
        public const String EXAMPLE1 = "../../../../results/chapter2/step_4_signed_by_alice_bob_carol_and_dave.pdf";
        public const String EXAMPLE2 = "../../../../results/chapter3/hello_cacert_ocsp_ts.pdf";
        public const String EXAMPLE3 = "../../../../results/chapter3/hello_token.pdf";
        public const String EXAMPLE4 = "../../../../results/chapter2/hello_signed4.pdf";
        public const String EXAMPLE5 = "../../../../results/chapter4/hello_smartcard_Signature.pdf";
        public const String EXAMPLE6 = "../../../../results/chapter2/field_metadata.pdf";
 
        public SignaturePermissions InspectSignature(AcroFields fields, String name, SignaturePermissions perms) {
            IList<AcroFields.FieldPosition> fps = fields.GetFieldPositions(name);
            if (fps != null && fps.Count > 0) {
                AcroFields.FieldPosition fp = fps[0];
                Rectangle pos = fp.position;
                if (pos.Width == 0 || pos.Height == 0) {
                    Console.WriteLine("Invisible signature");
                }
                else {
                    Console.WriteLine("Field on page {0}; llx: {1}, lly: {2}, urx: {3}; ury: {4}",
                        fp.page, pos.Left, pos.Bottom, pos.Right, pos.Top);
                }
            }
            
            PdfPKCS7 pkcs7 = VerifySignature(fields, name);
            Console.WriteLine("Digest algorithm: " + pkcs7.GetHashAlgorithm());
            Console.WriteLine("Encryption algorithm: " + pkcs7.GetEncryptionAlgorithm());
            Console.WriteLine("Filter subtype: " + pkcs7.GetFilterSubtype());
            X509Certificate cert = pkcs7.SigningCertificate;
                Console.WriteLine("Name of the signer: " + CertificateInfo.GetSubjectFields(cert).GetField("CN"));
            if (pkcs7.SignName != null)
                Console.WriteLine("Alternative name of the signer: " + pkcs7.SignName);
            
            Console.WriteLine("Signed on: " + pkcs7.SignDate.ToString("yyyy-MM-dd HH:mm:ss.ff"));
            if (!pkcs7.TimeStampDate.Equals(DateTime.MaxValue)) {
                Console.WriteLine("TimeStamp: " + pkcs7.TimeStampDate.ToString("yyyy-MM-dd HH:mm:ss.ff"));
                TimeStampToken ts = pkcs7.TimeStampToken;
                Console.WriteLine("TimeStamp service: " + ts.TimeStampInfo.Tsa);
                Console.WriteLine("Timestamp verified? " + pkcs7.VerifyTimestampImprint());
            }
            Console.WriteLine("Location: " + pkcs7.Location);
            Console.WriteLine("Reason: " + pkcs7.Reason);
            PdfDictionary sigDict = fields.GetSignatureDictionary(name);
            PdfString contact = sigDict.GetAsString(PdfName.CONTACTINFO);
            if (contact != null)
                Console.WriteLine("Contact info: " + contact);
            perms = new SignaturePermissions(sigDict, perms);
            Console.WriteLine("Signature type: " + (perms.Certification ? "certification" : "approval"));
            Console.WriteLine("Filling out fields allowed: " + perms.FillInAllowed);
            Console.WriteLine("Adding annotations allowed: " + perms.AnnotationsAllowed);
            foreach (SignaturePermissions.FieldLock Lock in perms.FieldLocks) {
                Console.WriteLine("Lock: " + Lock);
            }
            return perms;
        }
        
        public void InspectSignatures(String path) {
            Console.WriteLine(path);
            PdfReader reader = new PdfReader(path);
            AcroFields fields = reader.AcroFields;
            List<String> names = fields.GetSignatureNames();
            SignaturePermissions perms = null;
            foreach (String name in names) {
                Console.WriteLine("===== " + name + " =====");
                perms = InspectSignature(fields, name, perms);
            }
            Console.WriteLine();
        }
        
        static void Main(String[] args) {
            LoggerFactory.GetInstance().SetLogger(new SysoLogger());
            C5_02_SignatureInfo app = new C5_02_SignatureInfo();
            app.InspectSignatures(EXAMPLE1);
            app.InspectSignatures(EXAMPLE2);
            app.InspectSignatures(EXAMPLE3);
            app.InspectSignatures(EXAMPLE4);
            app.InspectSignatures(EXAMPLE5);
            app.InspectSignatures(EXAMPLE6);
        }
    }
}
C5_03_CertificateValidation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
 
using System;
using System.Collections.Generic;
using System.IO;
using Org.BouncyCastle.Ocsp;
using Org.BouncyCastle.Security.Certificates;
using Org.BouncyCastle.X509;
using iTextSharp.text.log;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using X509Certificate = Org.BouncyCastle.X509.X509Certificate;
 
namespace signatures.chapter5 {
    class C5_03_CertificateValidation : C5_01_SignatureIntegrity {
        public const String ADOBE = "../../../../resources/adobeRootCA.cer";
        public const String CACERT = "../../../../resources/CACertSigningAuthority.crt";
        public const String BRUNO = "../../../../resources/bruno.crt";
 
        public const String EXAMPLE1 = "../../../../results/chapter3/hello_cacert_ocsp_ts.pdf";
        public const String EXAMPLE2 = "../../../../results/chapter3/hello_token.pdf";
        public const String EXAMPLE3 = "../../../../results/chapter2/hello_signed1.pdf";
        public const String EXAMPLE4 = "../../../../results/chapter4/hello_smartcard_Signature.pdf";
 
        readonly private List<X509Certificate> certificates = new List<X509Certificate>();
 
        override public PdfPKCS7 VerifySignature(AcroFields fields, String name) {
            PdfPKCS7 pkcs7 = base.VerifySignature(fields, name);
            X509Certificate[] certs = pkcs7.SignCertificateChain;
            DateTime cal = pkcs7.SignDate;
            
            Object[] errors = CertificateVerification.VerifyCertificates(certs, certificates, null, cal);
            if (errors == null)
                Console.WriteLine("Certificates verified against the KeyStore");
            else
                foreach (object error in errors)
                    Console.WriteLine(error);
            for (int i = 0; i < certs.Length; ++i) {
                X509Certificate cert = certs[i];
                Console.WriteLine("=== Certificate " + i + " ===");
                ShowCertificateInfo(cert, cal.ToLocalTime());
            }
            X509Certificate signCert = certs[0];
            X509Certificate issuerCert = (certs.Length > 1 ? certs[1] : null);
            Console.WriteLine("=== Checking validity of the document at the time of signing ===");
            CheckRevocation(pkcs7, signCert, issuerCert, cal);
            Console.WriteLine("=== Checking validity of the document today ===");
            CheckRevocation(pkcs7, signCert, issuerCert, DateTime.Now);
            return pkcs7;
        }
        
        public static void CheckRevocation(PdfPKCS7 pkcs7, X509Certificate signCert, X509Certificate issuerCert, DateTime date) {
            List<BasicOcspResp> ocsps = new List<BasicOcspResp>();
            if (pkcs7.Ocsp != null)
                ocsps.Add(pkcs7.Ocsp);
            OcspVerifier ocspVerifier = new OcspVerifier(null, ocsps);
            List<VerificationOK> verification =
                ocspVerifier.Verify(signCert, issuerCert, date);
            if (verification.Count == 0) {
                List<X509Crl> crls = new List<X509Crl>();
                if (pkcs7.CRLs != null)
                    foreach (X509Crl crl in pkcs7.CRLs)
                        crls.Add(crl);
                CrlVerifier crlVerifier = new CrlVerifier(null, crls);
                verification.AddRange(crlVerifier.Verify(signCert, issuerCert, date));
            }
            if (verification.Count == 0)
                Console.WriteLine("The signing certificate couldn't be verified");
            else
                foreach (VerificationOK v in verification)
                    Console.WriteLine(v);
        }
 
        public void ShowCertificateInfo(X509Certificate cert, DateTime signDate) {
            Console.WriteLine("Issuer: " + cert.IssuerDN);
            Console.WriteLine("Subject: " + cert.SubjectDN);
            Console.WriteLine("Valid from: " + cert.NotBefore.ToString("yyyy-MM-dd HH:mm:ss.ff"));
            Console.WriteLine("Valid to: " + cert.NotAfter.ToString("yyyy-MM-dd HH:mm:ss.ff"));
            try {
                cert.CheckValidity(signDate);
                Console.WriteLine("The certificate was valid at the time of signing.");
            } catch (CertificateExpiredException e) {
                Console.WriteLine("The certificate was expired at the time of signing.");
            } catch (CertificateNotYetValidException e) {
                Console.WriteLine("The certificate wasn't valid yet at the time of signing.");
            }
            try {
                cert.CheckValidity();
                Console.WriteLine("The certificate is still valid.");
            } catch (CertificateExpiredException e) {
                Console.WriteLine("The certificate has expired.");
            } catch (CertificateNotYetValidException e) {
                Console.WriteLine("The certificate isn't valid yet.");
            }
        }
 
        static void Main(String[] args) {
            LoggerFactory.GetInstance().SetLogger(new SysoLogger());
            C5_03_CertificateValidation app = new C5_03_CertificateValidation();
            
            X509CertificateParser parser = new X509CertificateParser();
            app.certificates.Add(parser.ReadCertificate(new FileStream(ADOBE, FileMode.Open)));
            app.certificates.Add(parser.ReadCertificate(new FileStream(CACERT, FileMode.Open)));
            app.certificates.Add(parser.ReadCertificate(new FileStream(BRUNO, FileMode.Open)));
            app.VerifySignatures(EXAMPLE1);
            app.VerifySignatures(EXAMPLE2);
            app.VerifySignatures(EXAMPLE3);
            app.VerifySignatures(EXAMPLE4);
        }
    }
}
C5_04_LTV.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
 
using System;
using System.Collections.Generic;
using System.IO;
using System.util;
using iTextSharp.text.log;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
 
namespace signatures.chapter5 {
    class C5_04_LTV {
        public const String EXAMPLE1 = "../../../../results/chapter3/hello_token.pdf";
        public const String EXAMPLE2 = "../../../../results/chapter4/hello_smartcard_Signature.pdf";
        public const String EXAMPLE3 = "../../../../results/chapter3/hello_cacert_ocsp_ts.pdf";
        public const String DEST = "../../../../results/chapter5/ltv_{0}.pdf";
        
        public static void Main(String[] args) {
            LoggerFactory.GetInstance().SetLogger(new SysoLogger());
            Properties properties = new Properties();
            properties.Load(new FileStream("c:/home/blowagie/key.properties", FileMode.Open));
            String tsaUrl = properties["TSAURL"];
            String tsaUser = properties["TSAUSERNAME"];
            String tsaPass = properties["TSAPASSWORD"];
            C5_04_LTV app = new C5_04_LTV();
            ITSAClient tsa = new TSAClientBouncyCastle(tsaUrl, tsaUser, tsaPass, 6500, "SHA512");
            IOcspClient ocsp = new OcspClientBouncyCastle();
            app.AddLtv(EXAMPLE1, String.Format(DEST, 1), ocsp, new CrlClientOnline(), tsa);
            Console.WriteLine();
            app.AddLtv(EXAMPLE2, String.Format(DEST, 2), ocsp, new CrlClientOnline(), tsa);
            Console.WriteLine();
            app.AddLtv(EXAMPLE3, String.Format(DEST, 3), ocsp, new CrlClientOnline(), tsa);
            Console.WriteLine();
            app.AddLtv(String.Format(DEST, 1), String.Format(DEST, 4), null, new CrlClientOnline(), tsa);
        }
        
        public void AddLtv(String src, String dest, IOcspClient ocsp, ICrlClient crl, ITSAClient tsa) {
            PdfReader r = new PdfReader(src);
            FileStream fos = new FileStream(dest, FileMode.Create);
            PdfStamper stp = PdfStamper.CreateSignature(r, fos, '\0', null, true);
            LtvVerification v = stp.LtvVerification;
            AcroFields fields = stp.AcroFields;
            List<String> names = fields.GetSignatureNames();
            String sigName = names[names.Count - 1];
            PdfPKCS7 pkcs7 = fields.VerifySignature(sigName);
            if (pkcs7.IsTsp) 
                v.AddVerification(sigName, ocsp, crl, LtvVerification.CertificateOption.SIGNING_CERTIFICATE, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
            else foreach (String name in names)
                v.AddVerification(name, ocsp, crl, LtvVerification.CertificateOption.WHOLE_CHAIN, LtvVerification.Level.OCSP_CRL, LtvVerification.CertificateInclusion.NO);
            PdfSignatureAppearance sap = stp.SignatureAppearance;
            LtvTimestamp.Timestamp(sap, tsa, null); 
        }
    }
}
C5_05_CheckLTV.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
 
using System;
using System.Collections.Generic;
using Org.BouncyCastle.X509;
using iTextSharp.text.log;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
 
namespace signatures.chapter5 {
    class C5_05_CheckLTV {
        public const String EXAMPLE1 = "../../../../results/chapter5/ltv_1.pdf";
        public const String EXAMPLE2 = "../../../../results/chapter5/ltv_2.pdf";
        public const String EXAMPLE3 = "../../../../results/chapter5/ltv_3.pdf";
        public const String EXAMPLE4 = "../../../../results/chapter5/ltv_4.pdf";
 
        public PdfPKCS7 VerifySignature(AcroFields fields, String name) {
            Console.WriteLine("Signature covers whole document: " + fields.SignatureCoversWholeDocument(name));
            Console.WriteLine("Document revision: " + fields.GetRevision(name) + " of " + fields.TotalRevisions);
            PdfPKCS7 pkcs7 = fields.VerifySignature(name);
            Console.WriteLine("Integrity check OK? " + pkcs7.Verify());
            Console.WriteLine("Digest algorithm: " + pkcs7.GetHashAlgorithm());
            Console.WriteLine("Encryption algorithm: " + pkcs7.GetEncryptionAlgorithm());
            Console.WriteLine("Filter subtype: " + pkcs7.GetFilterSubtype());
            X509Certificate cert = pkcs7.SigningCertificate;
            Console.WriteLine("Name of the signer: " + CertificateInfo.GetSubjectFields(cert).GetField("CN"));
            return pkcs7;
        }
        
        public void VerifySignatures(String path) {
            Console.WriteLine(path);
            PdfReader reader = new PdfReader(path);
            AcroFields fields = reader.AcroFields;
            List<String> names = fields.GetSignatureNames();
            foreach (String name in names) {
                Console.WriteLine("===== " + name + " =====");
                VerifySignature(fields, name);
            }
            Console.WriteLine();
        }
        
        public static void Main(String[] args) {
            LoggerFactory.GetInstance().SetLogger(new SysoLogger());
            C5_05_CheckLTV app = new C5_05_CheckLTV();
            app.VerifySignatures(EXAMPLE1);
            app.VerifySignatures(EXAMPLE2);
            app.VerifySignatures(EXAMPLE3);
            app.VerifySignatures(EXAMPLE4);
        }
    }
}
C5_06_ValidateLTV.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * This class is part of the white paper entitled
 * "Digital Signatures for PDF documents"
 * written by Bruno Lowagie
 * 
 * For more info, go to: http://itextpdf.com/learn
 */
 
using System;
using System.Collections.Generic;
using System.IO;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
 
namespace signatures.chapter5 {
    class C5_06_ValidateLTV {
        public const String ADOBE = "../../../../resources/adobeRootCA.cer";
        public const String EXAMPLE1 = "../../../../results/chapter5/ltv_1.pdf";
        public const String EXAMPLE2 = "../../../../results/chapter5/ltv_2.pdf";
        public const String EXAMPLE3 = "../../../../results/chapter5/ltv_3.pdf";
        public const String EXAMPLE4 = "../../../../results/chapter5/ltv_4.pdf";
        
        static void Main(String[] args) {
            C5_06_ValidateLTV app = new C5_06_ValidateLTV();
            Console.WriteLine(EXAMPLE1);
            app.Validate(new PdfReader(EXAMPLE1));
            Console.WriteLine();
            Console.WriteLine(EXAMPLE2);
            app.Validate(new PdfReader(EXAMPLE2));
            Console.WriteLine();
            Console.WriteLine(EXAMPLE3);
            app.Validate(new PdfReader(EXAMPLE3));
            Console.WriteLine();
            Console.WriteLine(EXAMPLE4);
            app.Validate(new PdfReader(EXAMPLE4));
        }
 
        class MyVerifier : CertificateVerifier {
            public MyVerifier(CertificateVerifier verifier) : base(verifier) {}
 
            override public List<VerificationOK> Verify(X509Certificate signCert, X509Certificate issuerCert, DateTime signDate) {
                Console.WriteLine(signCert.SubjectDN + ": ALL VERIFICATIONS DONE");
                return new List<VerificationOK>();
            }
        }
        
        public void Validate(PdfReader reader) {
            List<X509Certificate> certificates = new List<X509Certificate>();
            X509CertificateParser parser = new X509CertificateParser();
            FileStream file = new FileStream(ADOBE, FileMode.Open);
            certificates.Add(parser.ReadCertificate(file));
            
            MyVerifier custom = new MyVerifier(null);
            
            LtvVerifier data = new LtvVerifier(reader);
            data.Certificates = certificates;
            data.CertificateOption = LtvVerification.CertificateOption.WHOLE_CHAIN;
            data.Verifier = custom;
            data.OnlineCheckingAllowed = false;
            data.VerifyRootCertificate = false;
            List<VerificationOK> list = new List<VerificationOK>();
            try {
                data.Verify(list);
            }
            catch (GeneralSecurityException e) {
                Console.WriteLine(e.ToString());
            }
            Console.WriteLine();
            if (list.Count == 0)
                Console.WriteLine("The document can't be verified");
            foreach (VerificationOK v in list)
                Console.WriteLine(v.ToString());
            file.Close();
        }
    }
}


Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now