From 0040210c8290bf60b8b08437d18b6cc05e863f32 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Fri, 23 Nov 2012 11:56:04 -0500
Subject: [PATCH] Generate empty CRL on startup to make Jetty happy

---
 src/com/gitblit/utils/X509Utils.java |   56 ++++++++++++++++++++++++++++
 src/com/gitblit/build/Build.java     |   30 +++++++++++++++
 2 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/src/com/gitblit/build/Build.java b/src/com/gitblit/build/Build.java
index c74c6cb..4c5fa19 100644
--- a/src/com/gitblit/build/Build.java
+++ b/src/com/gitblit/build/Build.java
@@ -69,6 +69,11 @@
 		runtime();
 		compiletime();
 		buildSettingKeys();
+		delete(
+				"bcmail-jdk16-1.46.jar",
+				"bcprov-jdk16-1.46.jar",
+				"src/bcmail-jdk16-1.46-sources.jar",
+				"src/bcprov-jdk16-1.46-sources.jar");
 	}
 
 	public static void runtime() {
@@ -145,6 +150,15 @@
 		// needed for site publishing
 		downloadFromApache(MavenObject.COMMONSNET, BuildType.RUNTIME);
 	}
+	
+	private static void delete(String... files) {
+		for (String name : files) {
+			File file = new File("ext", name);
+			if (file.exists()) {
+				file.delete();
+			}
+		}
+	}
 
 	public static void federationClient() {
 		downloadFromApache(MavenObject.JCOMMANDER, BuildType.RUNTIME);
@@ -173,6 +187,22 @@
 
 		downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME);
 	}
+	
+	public static void authority(DownloadListener listener) {
+		downloadListener = listener;
+		downloadFromApache(MavenObject.JCOMMANDER, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.JSCH, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.SLF4JAPI, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.SLF4LOG4J, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.LOG4J, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.BOUNCYCASTLE, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.BOUNCYCASTLE_MAIL, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.BOUNCYCASTLE_PKIX, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.JCALENDAR, BuildType.RUNTIME);
+		downloadFromApache(MavenObject.MAIL, BuildType.RUNTIME);
+
+		downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME);
+	}
 
 	/**
 	 * Builds the Keys class based on the gitblit.properties file and inserts
diff --git a/src/com/gitblit/utils/X509Utils.java b/src/com/gitblit/utils/X509Utils.java
index e6ffec1..e27d7bc 100644
--- a/src/com/gitblit/utils/X509Utils.java
+++ b/src/com/gitblit/utils/X509Utils.java
@@ -232,6 +232,13 @@
 			saveCertificate(caCert, new File(caKeyStore.getParentFile(), "ca.cer"));
 		}
 
+		// Gitblit CRL
+		File caRevocationList = new File(folder, CA_REVOCATION_LIST);			
+		if (!caRevocationList.exists()) {
+			logger.info(MessageFormat.format("Generating {0} CRL ({1})", CA_CN, caRevocationList.getAbsolutePath()));
+			newCertificateRevocationList(caRevocationList, caKeyStore, metadata.password);			
+		}
+
 		// rename the old keystore to the new name
 		File oldKeyStore = new File(folder, "keystore");
 		if (oldKeyStore.exists()) {
@@ -602,6 +609,55 @@
 	}
 	
 	/**
+	 * Creates a new certificate revocation list (CRL).  This function will
+	 * destroy any existing CRL file.
+	 * 
+	 * @param caRevocationList
+	 * @param storeFile
+	 * @param keystorePassword
+	 * @return
+	 */
+	public static void newCertificateRevocationList(File caRevocationList, File caKeystoreFile, String caKeystorePassword) {
+		try {
+			// read the Gitblit CA key and certificate
+			KeyStore store = openKeyStore(caKeystoreFile, caKeystorePassword);
+			PrivateKey caPrivateKey = (PrivateKey) store.getKey(CA_FN, caKeystorePassword.toCharArray());
+			X509Certificate caCert = (X509Certificate) store.getCertificate(CA_FN);
+
+			X500Name issuerDN = new X500Name(PrincipalUtil.getIssuerX509Principal(caCert).getName());
+			X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(issuerDN, new Date());
+			
+			// build and sign CRL with CA private key
+			ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(caPrivateKey);
+			X509CRLHolder crl = crlBuilder.build(signer);
+
+			File tmpFile = new File(caRevocationList.getParentFile(), Long.toHexString(System.currentTimeMillis()) + ".tmp");
+			FileOutputStream fos = null;
+			try {
+				fos = new FileOutputStream(tmpFile);
+				fos.write(crl.getEncoded());
+				fos.flush();
+				fos.close();
+				if (caRevocationList.exists()) {
+					caRevocationList.delete();
+				}
+				tmpFile.renameTo(caRevocationList);
+
+				log(caRevocationList.getParentFile(), "new certificate revocation list created");
+			} finally {
+				if (fos != null) {
+					fos.close();
+				}
+				if (tmpFile.exists()) {
+					tmpFile.delete();
+				}
+			}
+		} catch (Exception e) {
+			throw new RuntimeException("Failed to create new certificate revocation list " + caRevocationList, e);
+		}
+	}
+	
+	/**
 	 * Imports a certificate into the trust store.
 	 * 
 	 * @param alias

--
Gitblit v1.9.1