package dave;
import java.io.*;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.*;

import org.bouncycastle.cms.*;
import org.bouncycastle.cms.jcajce.*;
import org.bouncycastle.operator.*;
import org.bouncycastle.operator.jcajce.*;
import org.bouncycastle.cert.jcajce.*;

public class CMS_Sign {
	public static void main (String [] args) throws Exception {
		// CMS_Sign inputfile keyalias outputfile

		// enable Bouncy (must be in jre/lib/ext or otherwise available)
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		// input from file for test
		FileInputStream in = new FileInputStream (args[0]);
		byte [] buff = new byte[99999]; int n = in.read(buff); in.close();

		CMSTypedData data = new CMSProcessableByteArray (Arrays.copyOfRange(buff,0,n));

		// need key & cert(s?) -- just use handy test keystore
		KeyStore ks = KeyStore.getInstance("JKS");
		FileInputStream kf = new FileInputStream ("testkeys");
		ks.load(kf, "passphrase".toCharArray()); kf.close();
		PrivateKey pkey = (PrivateKey)ks.getKey(args[1], "passphrase".toCharArray());
		X509Certificate cert = (X509Certificate)ks.getCertificate(args[1]);
		ArrayList<X509Certificate> certs = new ArrayList<X509Certificate>(); 
		certs.add(cert);

		// create CMS Signed Data
		CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
		ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA")
				.setProvider("BC").build(pkey);
		JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(
				new JcaDigestCalculatorProviderBuilder().setProvider("BC").build() );
		gen.addSignerInfoGenerator(builder.build(signer, cert));
		gen.addCertificates(new JcaCertStore (certs));
		CMSSignedData signed = gen.generate(data,true);
		byte[] der = signed.getEncoded();

		// output data to file for test
		FileOutputStream out = new FileOutputStream (args[2]);
		out.write(der); out.close();

	}
}
