Title: ACCV
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!!



--

Autoridad de Certificación de la Comunidad Valenciana

      Javier Aparicio

      c/Colón, 66 1ª Planta - 46004 Valencia

      [EMAIL PROTECTED]

      Tel: 961961168

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

Reply via email to