From 976e26486636e5478275071be30364ef7c2c30ae Mon Sep 17 00:00:00 2001
From: Martin Paljak <martin@martinpaljak.net>
Date: Tue, 12 Apr 2016 09:00:22 +0300
Subject: [PATCH] Dump CA certificats, fix signature algorithms

---
 src/org/esteid/hacker/CLI.java          | 13 ++++++++++++
 src/org/esteid/hacker/FakeEstEIDCA.java | 28 ++++++++++++++-----------
 2 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/src/org/esteid/hacker/CLI.java b/src/org/esteid/hacker/CLI.java
index 455711f..f8db772 100644
--- a/src/org/esteid/hacker/CLI.java
+++ b/src/org/esteid/hacker/CLI.java
@@ -26,6 +26,7 @@
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.nio.charset.Charset;
+import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.security.interfaces.RSAPublicKey;
 import java.util.Arrays;
@@ -74,6 +75,8 @@ public class CLI {
 	private static final String OPT_INFO = "info";
 
 	private static final String OPT_CA = "ca";
+	private static final String OPT_DUMP = "dump";
+
 	private static final String OPT_RESIGN = "resign";
 	private static final String OPT_GENAUTH = "genauth";
 	private static final String OPT_GENSIGN = "gensign";
@@ -126,6 +129,8 @@ private static OptionSet parseArguments(String argv[]) throws IOException {
 
 		// FakeEstEIDManagerCA interface
 		parser.accepts(OPT_CA, "Use or generate a CA").withRequiredArg().ofType(File.class);
+		parser.accepts(OPT_DUMP, "Dump CA keys");
+
 		parser.accepts(OPT_RESIGN, "Re-sign cert with CA").withRequiredArg().ofType(File.class);
 
 		// Generate and load keys/certificates
@@ -229,6 +234,10 @@ public static void main(String argv[]) throws Exception {
 			} else {
 				ca.loadFromFile(f);
 			}
+			if (args.has(OPT_DUMP)) {
+				System.out.println(crt2pem(ca.getRootCert()));
+				System.out.println(crt2pem(ca.getIntermediateCert()));
+			}
 		} else if (args.has(OPT_EMULATE)) {
 			ca.generate();
 		} else if (args.has(OPT_NEW) || args.has(OPT_RESIGN)) {
@@ -561,4 +570,8 @@ else if (args.has(OPT_T1))
 	static String pub2pem(RSAPublicKey p) {
 		return "-----BEGIN PUBLIC KEY-----\n" + Base64.getMimeEncoder().encodeToString(p.getEncoded()) + "\n-----END PUBLIC KEY-----";
 	}
+	static String crt2pem(X509Certificate c) throws CertificateEncodingException {
+		return "-----BEGIN CERTIFICATE-----\n" + Base64.getMimeEncoder().encodeToString(c.getEncoded()) + "\n-----END CERTIFICATE-----";
+	}
+
 }
diff --git a/src/org/esteid/hacker/FakeEstEIDCA.java b/src/org/esteid/hacker/FakeEstEIDCA.java
index b9955cd..1464d63 100644
--- a/src/org/esteid/hacker/FakeEstEIDCA.java
+++ b/src/org/esteid/hacker/FakeEstEIDCA.java
@@ -76,8 +76,9 @@ public class FakeEstEIDCA {
 
 	public FakeEstEIDCA() throws NoSuchAlgorithmException {
 		// Add BouncyCastle if not present
-		if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
+		if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
 			Security.insertProviderAt(new BouncyCastleProvider(), 1);
+		}
 	}
 
 	public void generate() throws NoSuchAlgorithmException, InvalidKeyException, IllegalStateException, NoSuchProviderException,
@@ -87,20 +88,25 @@ public void generate() throws NoSuchAlgorithmException, InvalidKeyException, Ill
 		keyGen.initialize(2048);
 		// Generate keys
 		KeyPair root = keyGen.generateKeyPair();
+		keyGen.initialize(4096);
 		KeyPair esteid = keyGen.generateKeyPair();
 		rootCert = makeRootCert(root);
 		esteidCert = makeEsteidCert(esteid, root);
-
 		rootKey = (RSAPrivateCrtKey) root.getPrivate();
 		esteidKey = (RSAPrivateCrtKey) esteid.getPrivate();
-		System.out.println("Done.");
 	}
 
+	public X509Certificate getIntermediateCert() {
+		return esteidCert;
+	}
+	public X509Certificate getRootCert() {
+		return rootCert;
+	}
 	private X509CertificateHolder getRealCert(String path) throws IOException {
-		PEMParser pem = new PEMParser(new InputStreamReader(getClass().getResourceAsStream(path)));
-		X509CertificateHolder crt = (X509CertificateHolder) pem.readObject();
-		pem.close();
-		return crt;
+		try (PEMParser pem = new PEMParser(new InputStreamReader(getClass().getResourceAsStream(path)))) {
+			X509CertificateHolder crt = (X509CertificateHolder) pem.readObject();
+			return crt;
+		}
 	}
 
 	private X509Certificate makeRootCert(KeyPair kp) throws InvalidKeyException, IllegalStateException, NoSuchProviderException,
@@ -109,7 +115,7 @@ private X509Certificate makeRootCert(KeyPair kp) throws InvalidKeyException, Ill
 		// Load real root certificate
 		X509CertificateHolder real = getRealCert("/resources/sk-root.pem");
 		// Use values from real certificate
-		// TODO/FIXME: GeneralizedTime instead of UTCTime for root
+		// FIXME: GeneralizedTime instead of UTCTime for root
 		JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(real.getIssuer(), real.getSerialNumber(),
 				real.getNotBefore(), real.getNotAfter(), real.getSubject(), kp.getPublic());
 
@@ -127,7 +133,6 @@ private X509Certificate makeRootCert(KeyPair kp) throws InvalidKeyException, Ill
 
 		X509CertificateHolder cert = builder.build(sigGen);
 		return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(cert);
-
 	}
 
 	private X509Certificate makeEsteidCert(KeyPair esteid, KeyPair root) throws InvalidKeyException, IllegalStateException,
@@ -151,11 +156,10 @@ private X509Certificate makeEsteidCert(KeyPair esteid, KeyPair root) throws Inva
 		}
 
 		// Generate cert
-		ContentSigner sigGen = new JcaContentSignerBuilder("SHA1withRSA").setProvider(BouncyCastleProvider.PROVIDER_NAME).build(root.getPrivate());
+		ContentSigner sigGen = new JcaContentSignerBuilder("SHA384withRSA").setProvider(BouncyCastleProvider.PROVIDER_NAME).build(root.getPrivate());
 
 		X509CertificateHolder cert = builder.build(sigGen);
 		return new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(cert);
-
 	}
 
 	public X509Certificate cloneUserCertificate(RSAPublicKey pubkey, X509Certificate cert) throws OperatorCreationException, CertificateException, IOException {
@@ -179,7 +183,7 @@ public X509Certificate cloneUserCertificate(RSAPublicKey pubkey, X509Certificate
 	}
 	public X509Certificate generateUserCertificate(RSAPublicKey pubkey, boolean signature, String firstname, String lastname,
 			String idcode, String email) throws InvalidKeyException, ParseException, IOException, IllegalStateException,
-			NoSuchProviderException, NoSuchAlgorithmException, SignatureException, CertificateException, OperatorCreationException {
+	NoSuchProviderException, NoSuchAlgorithmException, SignatureException, CertificateException, OperatorCreationException {
 		Date startDate = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2016-01-01");
 		Date endDate = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse("2016-12-31");