These examples were written in the context of the white paper Digital Signatures for PDF documents.
Files:
packagesignatures.chapter5; importjava.io.IOException;importjava.security.GeneralSecurityException;importjava.security.Security;importjava.util.ArrayList; importorg.bouncycastle.jce.provider.BouncyCastleProvider; importcom.itextpdf.text.log.LoggerFactory;importcom.itextpdf.text.log.SysoLogger;importcom.itextpdf.text.pdf.AcroFields;importcom.itextpdf.text.pdf.PdfReader;importcom.itextpdf.text.pdf.security.PdfPKCS7; publicclass C5_01_SignatureIntegrity {publicstaticfinalString EXAMPLE1 ="results/chapter2/hello_level_1_annotated_wrong.pdf";publicstaticfinalString EXAMPLE2 ="results/chapter2/step_4_signed_by_alice_bob_carol_and_dave.pdf";publicstaticfinalString EXAMPLE3 ="results/chapter2/step_6_signed_by_dave_broken_by_chuck.pdf"; publicPdfPKCS7 verifySignature(AcroFields fields, String name)throwsGeneralSecurityException, 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;} publicvoid verifySignatures(String path)throwsIOException, GeneralSecurityException{System.out.println(path);PdfReader reader =newPdfReader(path);AcroFields fields = reader.getAcroFields(); ArrayList<String> names = fields.getSignatureNames();for(String name : names){System.out.println("===== "+ name +" ====="); verifySignature(fields, name);}System.out.println();} publicstaticvoid main(String[] args)throwsIOException, GeneralSecurityException{LoggerFactory.getInstance().setLogger(newSysoLogger()); BouncyCastleProvider provider =new BouncyCastleProvider();Security.addProvider(provider); C5_01_SignatureIntegrity app =new C5_01_SignatureIntegrity(); app.verifySignatures(EXAMPLE1); app.verifySignatures(EXAMPLE2); app.verifySignatures(EXAMPLE3);}}
packagesignatures.chapter5; importjava.io.IOException;importjava.security.GeneralSecurityException;importjava.security.Security;importjava.security.cert.X509Certificate;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.List; importorg.bouncycastle.jce.provider.BouncyCastleProvider;importorg.bouncycastle.tsp.TimeStampToken; importcom.itextpdf.text.Rectangle;importcom.itextpdf.text.log.LoggerFactory;importcom.itextpdf.text.log.SysoLogger;importcom.itextpdf.text.pdf.AcroFields;importcom.itextpdf.text.pdf.AcroFields.FieldPosition;importcom.itextpdf.text.pdf.PdfDictionary;importcom.itextpdf.text.pdf.PdfName;importcom.itextpdf.text.pdf.PdfReader;importcom.itextpdf.text.pdf.PdfString;importcom.itextpdf.text.pdf.security.CertificateInfo;importcom.itextpdf.text.pdf.security.PdfPKCS7;importcom.itextpdf.text.pdf.security.SignaturePermissions;importcom.itextpdf.text.pdf.security.SignaturePermissions.FieldLock; publicclass C5_02_SignatureInfo extends C5_01_SignatureIntegrity {publicstaticfinalString EXAMPLE1 ="results/chapter2/step_4_signed_by_alice_bob_carol_and_dave.pdf";publicstaticfinalString EXAMPLE2 ="results/chapter3/hello_cacert_ocsp_ts.pdf";publicstaticfinalString EXAMPLE3 ="results/chapter3/hello_token.pdf";publicstaticfinalString EXAMPLE4 ="results/chapter2/hello_signed4.pdf";publicstaticfinalString EXAMPLE5 ="results/chapter4/hello_smartcard_Signature.pdf";publicstaticfinalString EXAMPLE6 ="results/chapter2/field_metadata.pdf"; publicSignaturePermissions inspectSignature(AcroFields fields, String name, SignaturePermissions perms)throwsGeneralSecurityException, 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 =newSimpleDateFormat("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 =newSignaturePermissions(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;} publicvoid inspectSignatures(String path)throwsIOException, GeneralSecurityException{System.out.println(path);PdfReader reader =newPdfReader(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();} publicstaticvoid main(String[] args)throwsIOException, GeneralSecurityException{LoggerFactory.getInstance().setLogger(newSysoLogger()); 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);}}
packagesignatures.chapter5; importjava.io.FileInputStream;importjava.io.IOException;importjava.security.GeneralSecurityException;importjava.security.KeyStore;importjava.security.Security;importjava.security.cert.CRL;importjava.security.cert.Certificate;importjava.security.cert.CertificateExpiredException;importjava.security.cert.CertificateFactory;importjava.security.cert.CertificateNotYetValidException;importjava.security.cert.X509CRL;importjava.security.cert.X509Certificate;importjava.text.SimpleDateFormat;importjava.util.ArrayList;importjava.util.Calendar;importjava.util.Date;importjava.util.List; importorg.bouncycastle.cert.ocsp.BasicOCSPResp;importorg.bouncycastle.jce.provider.BouncyCastleProvider; importcom.itextpdf.text.log.LoggerFactory;importcom.itextpdf.text.log.SysoLogger;importcom.itextpdf.text.pdf.AcroFields;importcom.itextpdf.text.pdf.security.CRLVerifier;importcom.itextpdf.text.pdf.security.CertificateVerification;importcom.itextpdf.text.pdf.security.OCSPVerifier;importcom.itextpdf.text.pdf.security.PdfPKCS7;importcom.itextpdf.text.pdf.security.VerificationException;importcom.itextpdf.text.pdf.security.VerificationOK; publicclass C5_03_CertificateValidation extends C5_01_SignatureIntegrity {publicstaticfinalString ADOBE ="src/main/resources/adobeRootCA.cer";publicstaticfinalString CACERT ="src/main/resources/CACertSigningAuthority.crt";publicstaticfinalString BRUNO ="src/main/resources/bruno.crt"; publicstaticfinalString EXAMPLE1 ="results/chapter3/hello_cacert_ocsp_ts.pdf";publicstaticfinalString EXAMPLE2 ="results/chapter3/hello_token.pdf";publicstaticfinalString EXAMPLE3 ="results/chapter2/hello_signed1.pdf";publicstaticfinalString EXAMPLE4 ="results/chapter4/hello_smartcard_Signature.pdf"; KeyStore ks; publicPdfPKCS7 verifySignature(AcroFields fields, String name)throwsGeneralSecurityException, 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");elseSystem.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, newDate());return pkcs7;} publicstaticvoid checkRevocation(PdfPKCS7 pkcs7, X509Certificate signCert, X509Certificate issuerCert, Date date)throwsGeneralSecurityException, IOException{ List<BasicOCSPResp> ocsps =new ArrayList<BasicOCSPResp>();if(pkcs7.getOcsp()!=null) ocsps.add(pkcs7.getOcsp());OCSPVerifier ocspVerifier =newOCSPVerifier(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 =newCRLVerifier(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);}} publicvoid showCertificateInfo(X509Certificate cert, Date signDate){System.out.println("Issuer: "+ cert.getIssuerDN());System.out.println("Subject: "+ cert.getSubjectDN());SimpleDateFormat date_format =newSimpleDateFormat("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.");}} privatevoid setKeyStore(KeyStore ks){this.ks= ks;} publicstaticvoid main(String[] args)throwsIOException, GeneralSecurityException{LoggerFactory.getInstance().setLogger(newSysoLogger()); 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(newFileInputStream(ADOBE))); ks.setCertificateEntry("cacert", cf.generateCertificate(newFileInputStream(CACERT))); ks.setCertificateEntry("bruno", cf.generateCertificate(newFileInputStream(BRUNO))); app.setKeyStore(ks); app.verifySignatures(EXAMPLE1); app.verifySignatures(EXAMPLE2); app.verifySignatures(EXAMPLE3); app.verifySignatures(EXAMPLE4);}}
packagesignatures.chapter5; importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.security.GeneralSecurityException;importjava.security.Security;importjava.util.List;importjava.util.Properties; importorg.bouncycastle.jce.provider.BouncyCastleProvider; importcom.itextpdf.text.DocumentException;importcom.itextpdf.text.log.LoggerFactory;importcom.itextpdf.text.log.SysoLogger;importcom.itextpdf.text.pdf.AcroFields;importcom.itextpdf.text.pdf.PdfReader;importcom.itextpdf.text.pdf.PdfSignatureAppearance;importcom.itextpdf.text.pdf.PdfStamper;importcom.itextpdf.text.pdf.security.CrlClient;importcom.itextpdf.text.pdf.security.CrlClientOnline;importcom.itextpdf.text.pdf.security.LtvTimestamp;importcom.itextpdf.text.pdf.security.LtvVerification;importcom.itextpdf.text.pdf.security.OcspClient;importcom.itextpdf.text.pdf.security.OcspClientBouncyCastle;importcom.itextpdf.text.pdf.security.PdfPKCS7;importcom.itextpdf.text.pdf.security.TSAClient;importcom.itextpdf.text.pdf.security.TSAClientBouncyCastle; publicclass C5_04_LTV { publicstaticfinalString EXAMPLE1 ="results/chapter3/hello_token.pdf";publicstaticfinalString EXAMPLE2 ="results/chapter4/hello_smartcard_Signature.pdf";publicstaticfinalString EXAMPLE3 ="results/chapter3/hello_cacert_ocsp_ts.pdf";publicstaticfinalString DEST ="results/chapter5/ltv_%s.pdf"; publicstaticvoid main(String[] args)throwsIOException, DocumentException, GeneralSecurityException{Security.addProvider(new BouncyCastleProvider());LoggerFactory.getInstance().setLogger(newSysoLogger());Properties properties =newProperties(); properties.load(newFileInputStream("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 =newTSAClientBouncyCastle(tsaUrl, tsaUser, tsaPass, 6500, "SHA512");OcspClient ocsp =newOcspClientBouncyCastle(); app.addLtv(EXAMPLE1, String.format(DEST, 1), ocsp, newCrlClientOnline(), tsa);System.out.println(); app.addLtv(EXAMPLE2, String.format(DEST, 2), ocsp, newCrlClientOnline(), tsa);System.out.println(); app.addLtv(EXAMPLE3, String.format(DEST, 3), ocsp, newCrlClientOnline(), tsa);System.out.println(); app.addLtv(String.format(DEST, 1), String.format(DEST, 4), null, newCrlClientOnline(), tsa);} publicvoid addLtv(String src, String dest, OcspClient ocsp, CrlClient crl, TSAClient tsa)throwsIOException, DocumentException, GeneralSecurityException{PdfReader r =newPdfReader(src);FileOutputStream fos =newFileOutputStream(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);}}
packagesignatures.chapter5; importjava.io.IOException;importjava.security.GeneralSecurityException;importjava.security.Security;importjava.security.cert.X509Certificate;importjava.util.ArrayList; importorg.bouncycastle.jce.provider.BouncyCastleProvider; importcom.itextpdf.text.log.LoggerFactory;importcom.itextpdf.text.log.SysoLogger;importcom.itextpdf.text.pdf.AcroFields;importcom.itextpdf.text.pdf.PdfReader;importcom.itextpdf.text.pdf.security.CertificateInfo;importcom.itextpdf.text.pdf.security.PdfPKCS7; publicclass C5_05_CheckLTV {publicstaticfinalString EXAMPLE1 ="results/chapter5/ltv_1.pdf";publicstaticfinalString EXAMPLE2 ="results/chapter5/ltv_2.pdf";publicstaticfinalString EXAMPLE3 ="results/chapter5/ltv_3.pdf";publicstaticfinalString EXAMPLE4 ="results/chapter5/ltv_4.pdf"; publicPdfPKCS7 verifySignature(AcroFields fields, String name)throwsGeneralSecurityException, 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;} publicvoid verifySignatures(String path)throwsIOException, GeneralSecurityException{System.out.println(path);PdfReader reader =newPdfReader(path);AcroFields fields = reader.getAcroFields(); ArrayList<String> names = fields.getSignatureNames();for(String name : names){System.out.println("===== "+ name +" ====="); verifySignature(fields, name);}System.out.println();} publicstaticvoid main(String[] args)throwsIOException, GeneralSecurityException{LoggerFactory.getInstance().setLogger(newSysoLogger()); 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);}}
packagesignatures.chapter5; importjava.io.FileInputStream;importjava.io.IOException;importjava.security.GeneralSecurityException;importjava.security.KeyStore;importjava.security.Security;importjava.security.cert.CertificateFactory;importjava.security.cert.X509Certificate;importjava.util.ArrayList;importjava.util.Date;importjava.util.List; importorg.bouncycastle.jce.provider.BouncyCastleProvider; importcom.itextpdf.text.pdf.PdfReader;importcom.itextpdf.text.pdf.security.CertificateVerifier;importcom.itextpdf.text.pdf.security.LtvVerifier;importcom.itextpdf.text.pdf.security.LtvVerification.CertificateOption;importcom.itextpdf.text.pdf.security.VerificationOK; publicclass C5_06_ValidateLTV {publicstaticfinalString ADOBE ="src/main/resources/adobeRootCA.cer";publicstaticfinalString EXAMPLE1 ="results/chapter5/ltv_1.pdf";publicstaticfinalString EXAMPLE2 ="results/chapter5/ltv_2.pdf";publicstaticfinalString EXAMPLE3 ="results/chapter5/ltv_3.pdf";publicstaticfinalString EXAMPLE4 ="results/chapter5/ltv_4.pdf"; publicstaticvoid main(String[] args)throwsIOException, GeneralSecurityException{ BouncyCastleProvider provider =new BouncyCastleProvider();Security.addProvider(provider); C5_06_ValidateLTV app =new C5_06_ValidateLTV();System.out.println(EXAMPLE1); app.validate(newPdfReader(EXAMPLE1));System.out.println();System.out.println(EXAMPLE2); app.validate(newPdfReader(EXAMPLE2));System.out.println();System.out.println(EXAMPLE3); app.validate(newPdfReader(EXAMPLE3));System.out.println();System.out.println(EXAMPLE4); app.validate(newPdfReader(EXAMPLE4));} publicvoid validate(PdfReader reader)throwsIOException, GeneralSecurityException{KeyStore ks =KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(null, null);CertificateFactory cf =CertificateFactory.getInstance("X.509"); ks.setCertificateEntry("adobe", cf.generateCertificate(newFileInputStream(ADOBE))); CertificateVerifier custom =newCertificateVerifier(null){public List<VerificationOK> verify(X509Certificate signCert, X509Certificate issuerCert, Date signDate)throwsGeneralSecurityException, IOException{System.out.println(signCert.getSubjectDN().getName()+": ALL VERIFICATIONS DONE");returnnew ArrayList<VerificationOK>();}}; LtvVerifier data =newLtvVerifier(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());}}
File name | Raw URL | Updated |
---|---|---|
C5_01_SignatureIntegrity.java | C5_01_SignatureIntegrity.java | 2015-11-01 5:15 pm |
C5_02_SignatureInfo.java | C5_02_SignatureInfo.java | 2015-11-01 5:15 pm |
C5_03_CertificateValidation.java | C5_03_CertificateValidation.java | 2015-11-01 5:15 pm |
C5_04_LTV.java | C5_04_LTV.java | 2015-11-01 5:15 pm |
C5_05_CheckLTV.java | C5_05_CheckLTV.java | 2015-11-01 5:15 pm |
C5_06_ValidateLTV.java | C5_06_ValidateLTV.java | 2015-11-01 5:15 pm |
C# port:
File name | Raw URL | Updated |
---|---|---|
C5_01_SignatureIntegrity.cs | C5_01_SignatureIntegrity.cs | 2015-11-01 5:18 pm |
C5_02_SignatureInfo.cs | C5_02_SignatureInfo.cs | 2015-11-01 5:18 pm |
C5_03_CertificateValidation.cs | C5_03_CertificateValidation.cs | 2015-11-01 5:18 pm |
C5_04_LTV.cs | C5_04_LTV.cs | 2015-11-01 5:18 pm |
C5_05_CheckLTV.cs | C5_05_CheckLTV.cs | 2015-11-01 5:19 pm |
C5_06_ValidateLTV.cs | C5_06_ValidateLTV.cs | 2015-11-01 5:19 pm |