|
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"); 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!! |
begin:vcard fn:Javier Aparicio Conesa n:Aparicio Conesa;Javier email;internet:[EMAIL PROTECTED] tel;work:96 1961168 version:2.1 end:vcard
------------------------------------------------------------------------- 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
