/**
 * Written by Bruno Lowagie.
 * This code uses LGPL'ed and GPL'ed software,
 * and is therefore also available under the GPL.
 */

package test;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;

import be.godot.sc.engine.BelpicCard;
import be.godot.sc.exceptions.InvalidResponse;
import be.godot.sc.exceptions.NoReadersAvailable;
import be.godot.sc.exceptions.NoSuchFeature;
import be.godot.sc.exceptions.SignatureGenerationException;
import be.godot.sc.exceptions.SmartCardReaderException;
import be.godot.sc.exceptions.UnknownCardException;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfDictionary;
import com.lowagie.text.pdf.PdfName;
import com.lowagie.text.pdf.PdfPKCS7;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfSignatureAppearance;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfString;

public class EIDFormRecipient2 {
	public static void main(String[] args) {
		try {
			BelpicCard scd = new BelpicCard("");
			Certificate[] certs = new Certificate[1];
			certs[0] = scd.getNonRepudiationCertificate();
			
			PdfReader reader = new PdfReader("EIDFormSigned1.pdf");
			FileOutputStream fout = new FileOutputStream("EIDFormSigned2.pdf");
			PdfStamper stamper = PdfStamper.createSignature(reader, fout, '\0', null, true);
			PdfSignatureAppearance sap = stamper.getSignatureAppearance();
			sap.setCrypto(null, certs, null, PdfSignatureAppearance.SELF_SIGNED);
			sap.setReason("GovCamp example: eID and PDF (second recipient)");
			sap.setLocation("Belgium");
			sap.setVisibleSignature("Signature2");
			sap.setExternalDigest(new byte[128], new byte[20], "RSA");
			sap.preClose();
			PdfPKCS7 sig = sap.getSigStandard().getSigner();
			byte[] content = streamToByteArray(sap.getRangeStream());
			byte[] hash= MessageDigest.getInstance("SHA-1").digest(content);
			byte[] signatureBytes = scd.generateNonRepudiationSignature(hash);
			sig.setExternalDigest(signatureBytes, null, "RSA");
			PdfDictionary dic = new PdfDictionary();
			dic.put(PdfName.CONTENTS, new PdfString(sig.getEncodedPKCS1()).setHexWriting(true));
			sap.close(dic);
		} catch(DocumentException de) {
			de.printStackTrace();
		} catch(IOException ioe) {
			ioe.printStackTrace();
		} catch (UnknownCardException uce) {
			uce.printStackTrace();
		} catch (SmartCardReaderException scre) {
			scre.printStackTrace();
		} catch (NoSuchFeature nsf) {
			nsf.printStackTrace();
		} catch (NoSuchAlgorithmException nse) {
			nse.printStackTrace();
		} catch (SignatureGenerationException sge) {
			sge.printStackTrace();
		} catch (NoReadersAvailable nra) {
			nra.printStackTrace();
		} catch (InvalidResponse ir) {
			ir.printStackTrace();
		}
	}
	
	public static byte[] streamToByteArray(InputStream stream) throws IOException {
		if (stream == null) {
			return null;
		}
		else {
			ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
			byte buffer[] = new byte[1024];
			int c = 0;
			while ( (c = stream.read(buffer)) > 0) {
				byteArray.write(buffer, 0, c);
			}
			byteArray.flush();
			return byteArray.toByteArray();
		}
	}
}
