Look at http://prdownloads.sourceforge.net/opensignature/opensignpdf_0.0.2.tar.gz for inspiration.
Paulo > -----Original Message----- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On > Behalf Of Javier Aparicio Conesa > Sent: Wednesday, September 20, 2006 12:14 PM > To: [email protected] > Subject: [iText-questions] Help with PDF timestamp > > Hi guys! > > I'm trying to timestamp a signed PDF document with the itext > 1.4.4 library. I had read the "nCipher DSE 200" example but I > haven't classes like "DataImprint" and methods like > "setDataImprint()" of other classes of bouncycastle. > > Someone can send me an full example of timestamping? > > And when I have got an CMSSignedData... what is the correct > way to add it to the PDF document? > > > I'm trying to do all this with this code: > > > > X509Certificate cert = > PKCS11Util.getCertificate(kac.getCertificate()); > Certificate[] chain = new Certificate[] { cert }; > > PdfReader reader = new PdfReader(pdfFileName); > FileOutputStream fout = new FileOutputStream(signedPdfFileName); > > PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0'); > > PdfSignatureAppearance sap = stp.getSignatureAppearance(); > sap.setCrypto(null, chain, null, > PdfSignatureAppearance.WINCER_SIGNED); > sap.setReason(motivo); > > > sap.setVisibleSignature(new Rectangle(100, 100, 200, > 200), 1, null); > sap.setExternalDigest(new byte[128], new byte[20], "RSA"); > sap.preClose(); > > MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); > byte buf[] = new byte[8192]; > int n; > InputStream inp = sap.getRangeStream(); > while ((n = inp.read(buf)) > 0) { > messageDigest.update(buf, 0, n); > } > byte hash[] = messageDigest.digest(); > > > PdfSigGenericPKCS sg = sap.getSigStandard(); > PdfLiteral slit = (PdfLiteral) sg.get(PdfName.CONTENTS); > byte[] outc = new byte[(slit.getPosLength() - 2) / 2]; > > PdfPKCS7 sig = sg.getSigner(); > > byte[] signatureBytes = SignUtil.generateSignature(ses, > key, hash); > sig.setExternalDigest(signatureBytes, hash, "RSA"); > > PdfDictionary dic = new PdfDictionary(); > byte[] ssig = sig.getEncodedPKCS7(); > > CMSSignedData cmssd = new CMSSignedData(ssig); > cmssd = Signer.addTimestamp(cmssd, hash, -1); > System.arraycopy(cmssd.getEncoded(), 0, outc, 0, > cmssd.getEncoded().length); > > dic.put(PdfName.CONTENTS, new > PdfString(outc).setHexWriting(true)); > > > I borrowed the code for Signer class from the Tomek > Maćkowski's example: > > package es.accv.pdf; > > > import iaik.pkcs.pkcs11.Session; > import iaik.pkcs.pkcs11.objects.RSAPrivateKey; > > import java.io.ByteArrayInputStream; > import java.io.ByteArrayOutputStream; > import java.io.FileInputStream; > import java.io.FileOutputStream; > import java.io.InputStream; > import java.math.BigInteger; > import java.security.KeyStore; > import java.security.PrivateKey; > import java.security.PublicKey; > import java.security.Security; > import java.security.cert.CertStore; > import java.security.cert.Certificate; > import java.security.cert.CollectionCertStoreParameters; > import java.security.cert.X509Certificate; > import java.util.ArrayList; > import java.util.Collection; > import java.util.Date; > import java.util.HashMap; > import java.util.Iterator; > import java.util.List; > import java.util.Random; > > import org.apache.commons.httpclient.HttpClient; > import org.apache.commons.httpclient.methods.PostMethod; > import org.apache.log4j.Logger; > import org.bouncycastle.asn1.ASN1InputStream; > import org.bouncycastle.asn1.DEREncodableVector; > import org.bouncycastle.asn1.DERObject; > import org.bouncycastle.asn1.DERObjectIdentifier; > import org.bouncycastle.asn1.DERSet; > import org.bouncycastle.asn1.cms.Attribute; > import org.bouncycastle.asn1.cms.AttributeTable; > import org.bouncycastle.asn1.util.ASN1Dump; > import org.bouncycastle.cms.CMSProcessable; > import org.bouncycastle.cms.CMSProcessableByteArray; > import org.bouncycastle.cms.CMSSignedData; > import org.bouncycastle.cms.CMSSignedDataGenerator; > import org.bouncycastle.cms.SignerId; > import org.bouncycastle.cms.SignerInformation; > import org.bouncycastle.cms.SignerInformationStore; > import org.bouncycastle.jce.provider.BouncyCastleProvider; > import org.bouncycastle.tsp.TSPAlgorithms; > import org.bouncycastle.tsp.TimeStampRequest; > import org.bouncycastle.tsp.TimeStampRequestGenerator; > import org.bouncycastle.tsp.TimeStampResponse; > import org.bouncycastle.tsp.TimeStampToken; > > import com.lowagie.text.pdf.PdfDictionary; > import com.lowagie.text.pdf.PdfName; > import com.lowagie.text.pdf.PdfReader; > import com.lowagie.text.pdf.PdfSignatureAppearance; > import com.lowagie.text.pdf.PdfStamper; > import com.lowagie.text.pdf.PdfString; > > import es.accv.pki.iaik.KeyAndCertificateBean; > import es.accv.pki.iaik.PKCS11Util; > import es.accv.pki.keys.TokenPrivateKey; > > public class Signer { > > /** > * Loggger de clase > */ > private static Logger logger = Logger.getLogger(Signer.class); > > > > /** > * Modyfy PKCS#7 data by adding timestamp > * > * @param signedData > * @throws Exception > */ > > public static CMSSignedData addTimestamp(CMSSignedData > signedData, byte[] hash, long nonce) throws Exception { > > Collection ss = signedData.getSignerInfos().getSigners(); > SignerInformation si = (SignerInformation) ss.iterator().next(); > > TimeStampToken tok = getTimeStampToken(hash, nonce); > > ASN1InputStream asn1InputStream = new > ASN1InputStream(tok.getEncoded()); > > DERObject tstDER = asn1InputStream.readObject(); > DERSet ds = new DERSet(tstDER); > > Attribute a = new Attribute(new > DERObjectIdentifier("1.2.840.113549.1.9.16.2.14"), ds); > > DEREncodableVector dv = new DEREncodableVector(); > dv.add(a); > AttributeTable at = new AttributeTable(dv); > si = SignerInformation.replaceUnsignedAttributes(si, at); > ss.clear(); > ss.add(si); > SignerInformationStore sis = new SignerInformationStore(ss); > > signedData = CMSSignedData.replaceSigners(signedData, sis); > logger.debug("[addTimestamp]:: " + > ASN1Dump.dumpAsString(signedData) ); > > return signedData; > } > > > private static TimeStampToken getTimeStampToken( byte[] > hash, long nonce ) throws Exception { > > Security.addProvider(new > org.bouncycastle.jce.provider.BouncyCastleProvider()); > > PostMethod post = new > PostMethod("http://www.edelweb.fr/cgi-bin/service-tsp" > <http://www.edelweb.fr/cgi-bin/service-tsp> ); > > TimeStampRequestGenerator reqGen = new > TimeStampRequestGenerator(); > > // request TSA to return certificate > reqGen.setCertReq(false); > > if ( hash == null ){ > hash = new byte[20]; > } > > if ( nonce < 0 ){ > Random rand = new Random(new Date().getTime()); > nonce = rand.nextLong(); > } > > // make a TSP request > TimeStampRequest request = > reqGen.generate(TSPAlgorithms.SHA1, hash, BigInteger.valueOf(nonce)); > > byte[] enc_req = request.getEncoded(); > ByteArrayInputStream bais = new ByteArrayInputStream(enc_req); > > post.setRequestBody(bais); > > post.setRequestContentLength(enc_req.length); > post.setRequestHeader("Content-type", > "application/timestamp-query"); > > HttpClient http_client = new HttpClient(); > http_client.executeMethod(post); > InputStream in = post.getResponseBodyAsStream(); > > // read TSP response > TimeStampResponse resp = new TimeStampResponse(in); > > resp.validate(request); > System.out.println("Timestamp validated"); > > TimeStampToken tsToken = resp.getTimeStampToken(); > ASN1InputStream asn1is = new > ASN1InputStream(tsToken.getEncoded()); > > logger.debug("[getTimeStampToken]:: \n" + > ASN1Dump.dumpAsString(asn1is.readObject())); > > SignerId signer_id = tsToken.getSID(); > > BigInteger cert_serial_number = signer_id.getSerialNumber(); > > > System.out.println("Signer ID serial " + > signer_id.getSerialNumber()); > System.out.println("Signer ID issuer " + > signer_id.getIssuerAsString()); > > CertStore cs = tsToken.getCertificatesAndCRLs("Collection", "BC"); > Collection certs = cs.getCertificates(null); > > logger.debug("[getTimeStampToken]:: Nº Certs: " + certs.size()); > > Iterator iter = certs.iterator(); > X509Certificate certificate = null; > while (iter.hasNext()) { > X509Certificate cert = (X509Certificate) iter.next(); > > if (cert_serial_number != null) { > if (cert.getSerialNumber().equals(cert_serial_number)) { > > logger.debug("using certificate with serial: " + > cert.getSerialNumber()); > certificate = cert; > > } > > } else { > if (certificate == null) { > certificate = cert; > } > } > > logger.debug("Certificate subject dn " + cert.getSubjectDN()); > logger.debug("Certificate serial " + cert.getSerialNumber()); > > } > > > logger.debug("[getTimeStampToken]:: Certificate:\n" + > ASN1Dump.dumpAsString(certificate)); > > tsToken.validate(certificate, "BC"); > > logger.debug("TS info " + > tsToken.getTimeStampInfo().getGenTime()); > logger.debug("TS info " + tsToken.getTimeStampInfo()); > logger.debug("TS info " + > tsToken.getTimeStampInfo().getAccuracy()); > logger.debug("TS info " + tsToken.getTimeStampInfo().getNonce()); > return tsToken; > > } > > } > > > Very thanks in advance!! > > > > > -- > > > Autoridad de Certificación de la Comunidad Valenciana > <http://www.accv.es> > > Javier Aparicio > > c/Colón, 66 1ª Planta - 46004 Valencia > > [EMAIL PROTECTED] > > Tel: 961961168 > > 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. ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ iText-questions mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/itext-questions
