I know, but DigiStamp's (sample) source code is licensed such that using it in a commercial application is not allowed, hence I didn't even take a look at it; I prefer MPL-licensed code, even if that means an extra day's work to figure out how it works.
Also, using DigiStamp's TSA service apparently requires account creation, whereas the TSAs I listed are hassle-free.
Bouncycastle and and their TSA account. They also have a free test server.
>
> For those who like to use timestamping (without OCSP, I haven't figured
> that one out yet), are frustrated about the lack of examples, and who
> don't want to spend a day digging in code and specifications, here's some
> sample code.
>
> The following code was tested with Sun Java 1.6.0_07, with a third party
> source PDF (apparently generated by Neevia docuPrinter Pro v5.2), and
> verified in Adobe Acrobat 7.0.8
> The sample requires iText 2.1.6 and BouncyCastle (I used v1.4.1).
>
> Tested with (free) TSAs:
> -
https://tsa.aloaha.com/tsa.asp> -
http://dse200.ncipher.com/TSS/HttpTspServer>
> -----8<-----8<-----8<-----8<-----8<-----
> static void signAndTimestamp(final InputStream originalPdf, final
> OutputStream targetPdf, final PrivateKey pk, final X509Certificate[]
> certChain, final CRL[] revoked, final String tsaAddress) throws
> IOException, DocumentException, NoSuchAlgorithmException,
> InvalidKeyException, SignatureException
> {
> // only an estimate, depends on the certificates returned by the TSA
> final int timestampSize = 4400;
> Security.addProvider(new BouncyCastleProvider());
>
> final PdfReader reader = new PdfReader(originalPdf);
> final PdfStamper stamper = PdfStamper.createSignature(reader, targetPdf,
> '\0');
> final PdfSignatureAppearance sap = stamper.getSignatureAppearance();
>
> // comment next lines to have an invisible signature
> sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
> sap.setLayer2Text("This is some custom made text.\n\nDate: some date");
>
> final PdfSigGenericPKCS sig = new PdfSigGenericPKCS.PPKMS("BC");
> final HashMap<PdfName, Integer> exclusionSizes = new HashMap<PdfName,
> Integer>();
>
> // some informational fields
> sig.setReason("Because I like iText's ability to sign PDFs");
> sig.setLocation("Multiverse command center");
> sig.setContact("
supreme.ruler@...");
> sig.setName(PdfPKCS7.getSubjectFields(certChain[0]).getField("CN"));
> sig.setDate(new PdfDate(Calendar.getInstance()));
>
> // signing stuff
> final byte[] digest = new byte[256];
> final byte[] rsaData = new byte[20];
> sig.setExternalDigest(digest, rsaData, "RSA");
> sig.setSignInfo(pk, certChain, revoked);
> final PdfString contents = (PdfString)sig.get(PdfName.CONTENTS);
> // *2 to get hex size, +2 for delimiters
> PdfLiteral contentsLit = new PdfLiteral((contents.toString().length() +
> timestampSize) * 2 + 2);
> exclusionSizes.put(PdfName.CONTENTS, new
> Integer(contentsLit.getPosLength()));
> sig.put(PdfName.CONTENTS, contentsLit);
>
> // certification; will display dialog or blue bar in Acrobat Reader
>
> sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
>
> // process all the information set above
> sap.setCryptoDictionary(sig);
> sap.preClose(exclusionSizes);
>
> // calculate digest (hash)
> final MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
> final byte[] buf = new byte[8192];
> int n;
> final InputStream inp = sap.getRangeStream();
> while ((n = inp.read(buf)) != -1)
> {
> messageDigest.update(buf, 0, n);
> }
> final byte[] hash = messageDigest.digest();
>
> // make signature (SHA1 the hash, prepend algorithm ID, pad, and encrypt
> with RSA)
> final Signature sign = Signature.getInstance("SHA1withRSA");
> sign.initSign(pk);
> sign.update(hash);
> final byte[] signature = sign.sign();
>
> // prepare the location of the signature in the target PDF
> contentsLit = (PdfLiteral)sig.get(PdfName.CONTENTS);
> final byte[] outc = new byte[(contentsLit.getPosLength() - 2) / 2];
> final PdfPKCS7 pkcs7 = sig.getSigner();
> pkcs7.setExternalDigest(signature, hash, "RSA");
> final PdfDictionary dic = new PdfDictionary();
>
> // retrieve a timestamp and combine it with our signature into a single
> blob of data, formatted as PKCS7 signed message
> final byte[] ssig = pkcs7.getEncodedPKCS7(null, null, new
> TSAClientBouncyCastle(tsaAddress), null);
> System.arraycopy(ssig, 0, outc, 0, ssig.length);
>
> // add the timestamped signature
> dic.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
>
> // finish up
> sap.close(dic);
> }
> -----8<-----8<-----8<-----8<-----8<-----
>
> Regards,
>
> Bert Vingerhoets - Research & Development
> Inventive Designers NV
>
> Phone: +32 3 821 01 70
> Fax: +32 3 821 01 71
> Email: Bert_Vingerhoets at inventivegroup dot com
>
http://www.inventivegroup.com/>
>
> -----Original Message-----
> From: Paulo Soares [mailto:
psoares@...]
> Sent: Thursday 2 July 2009 13:32
> To: Post all your questions about iText here
> Subject: Re: [iText-questions] TSA in iText 2.1.6
>
> TSA in iText is oriented to be used inside an external signature with
> signed attributes to also support OCSP. The main objective was to make it
> work, now we'll have to improve on the details.
>
> Paulo
>
>> -----Original Message-----
>> From: Bert Vingerhoets [mailto:
Bert_Vingerhoets@...]
>> Sent: Thursday, July 02, 2009 12:01 PM
>> To:
itext-questions@...
>> Subject: [iText-questions] TSA in iText 2.1.6
>>
>> Hi,
>>
>> I was checking out the new functionality of iText 2.1.6, especially
>> the added TSA support.
>>
>> In absence of documentation or examples, I took a look at the code to
>> determine how to use the timestamping functionality.
>> However, all I could find about the subject were the interface
>> TSAClient and class TSAClientBouncyCastle. Neither of which are
>> instantiated anywhere, the only references of TSAClient I could find
>> were in one PdfPKCS7#getEncodedPKCS7 method that isn't used by the
>> rest of iText (except for filling the TSAClient argument with null).
>>
>> When following the examples for PDF signing using external signatures,
>> one of the getEncodedPKCS7() methods does get called outside of iText
>> (for setting the CONTENTS key in the dictionary passed to the final
>> PdfSignatureAppearance#close() invocation). However, When I replace
>> this getEncodedPKCS7() call by the overload that accepts a TSAClient,
>> the resulting array is too large to fit in the allocated buffer.
>> Checking where this buffer gets allocated leads to an internal
>> invocation of getEncodedPKCS7() (without TSAClient argument).
>>
>> As far as I can see, being able to use TSA in iText requires me to
>> patch the library (luckily we're using the MPL license) or try to
>> externalize the entire contents of the 'if (cryptoDictionary ==
>> null)'-branch from
>> PdfSignatureAppearance#preClose() where the CONTENTS buffer is
>> allocated with the first call (through
>> sigStandard.setSignInfo) to getEncodedPKCS7.
>> Patching iText to allow specifying a TSAClient externally seems the
>> easiest option to me.
>>
>> Is this correct? Or is there another way to use TSA in iText?
>>
>>
>> On a brighter note, once I hacked the library to effectively use a
>> TSAClient, a correct PDF was indeed produced and recognized by Acrobat
>> Reader; so the code does, in fact, work.
>>
>>
>> Regards,
>>
>> Bert Vingerhoets - Research & Development Inventive Designers NV
>>
>> Phone: +32 3 821 01 70
>> Fax: +32 3 821 01 71
>> Email: Bert_Vingerhoets at inventivegroup dot com
>>
http://www.inventivegroup.com/>>
>>
>> Inventive Designers' Email Disclaimer:
>>
http://www.inventivedesigners.com/email-disclaimer>
>
> Aviso Legal: Esta mensagem ? destinada exclusivamente ao destinat?rio.
> Pode conter informa??o confidencial ou legalmente protegida. A incorrecta
> transmiss?o desta mensagem n?o significa a perca de confidencialidade. Se
> esta mensagem for recebida por engano, por favor envie-a de volta para o
> remetente e apague-a do seu sistema de imediato. ? proibido a qualquer
> pessoa que n?o o destinat?rio de usar, revelar ou distribuir qualquer
> parte desta mensagem. Disclaimer: This message is destined exclusively
> to the intended receiver. It may contain confidential or legally protected
> information. The incorrect transmission of this message does not mean the
> loss of its confidentiality. If this message is received by mistake,
> please send it back to the sender and delete it from your system
> immediately. It is forbidden to any person who is not the intended
> receiver to use, distribute or copy any part of this message.
>
>
> --
> This message has been scanned for viruses and dangerous content by
> MailScanner, and is believed to be clean.
> --
>
>
>
> Inventive Designers' Email Disclaimer:
>
http://www.inventivedesigners.com/email-disclaimer>
> --
> This message has been scanned for viruses and
> dangerous content by MailScanner, and is
> believed to be clean.
> --
>
>
>
> ------------------------------------------------------------------------------
> _______________________________________________
> iText-questions mailing list
>
iText-questions@...
>
https://lists.sourceforge.net/lists/listinfo/itext-questions>
> Buy the iText book:
http://www.1t3xt.com/docs/book.php> Check the site with examples before you ask questions:
>
http://www.1t3xt.info/examples/> You can also search the keywords list:
>
http://1t3xt.info/tutorials/keywords/>
>