/*
 * Copyright 2012 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.SignatureException;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CRL;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.crypto.Cipher;
import javax.naming.ldap.LdapName;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509v2CRLBuilder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.PrincipalUtil;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.openssl.PEMEncryptor;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.Constants;

/**
 * Utility class to generate X509 certificates, keystores, and truststores.
 *
 * @author James Moger
 *
 */
public class X509Utils {

	public static final String SERVER_KEY_STORE = "serverKeyStore.jks";

	public static final String SERVER_TRUST_STORE = "serverTrustStore.jks";

	public static final String CERTS = "certs";

	public static final String CA_KEY_STORE = "certs/caKeyStore.p12";

	public static final String CA_REVOCATION_LIST = "certs/caRevocationList.crl";

	public static final String CA_CONFIG = "certs/authority.conf";

	public static final String CA_CN = "Gitblit Certificate Authority";

	public static final String CA_ALIAS = CA_CN;

	private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;

	private static final int KEY_LENGTH = 2048;

	private static final String KEY_ALGORITHM = "RSA";

	private static final String SIGNING_ALGORITHM = "SHA512withRSA";

	public static final boolean unlimitedStrength;

	private static final Logger logger = LoggerFactory.getLogger(X509Utils.class);

	static {
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

		// check for JCE Unlimited Strength
		int maxKeyLen = 0;
		try {
			maxKeyLen = Cipher.getMaxAllowedKeyLength("AES");
		} catch (NoSuchAlgorithmException e) {
		}

		unlimitedStrength = maxKeyLen > 128;
		if (unlimitedStrength) {
			logger.info("Using JCE Unlimited Strength Jurisdiction Policy files");
		} else {
			logger.info("Using JCE Standard Encryption Policy files, encryption key lengths will be limited");
		}
	}

	public static enum RevocationReason {
		// https://en.wikipedia.org/wiki/Revocation_list
		 unspecified, keyCompromise, caCompromise, affiliationChanged, superseded,
		 cessationOfOperation, certificateHold, unused, removeFromCRL, privilegeWithdrawn,
		 ACompromise;

		 public static RevocationReason [] reasons = {
			 	unspecified, keyCompromise, caCompromise,
				 affiliationChanged, superseded, cessationOfOperation,
				 privilegeWithdrawn };

		 @Override
		 public String toString() {
			 return name() +  " (" + ordinal() + ")";
		 }
	}

	public interface X509Log {
		void log(String message);
	}

	public static class X509Metadata {

		// map for distinguished name OIDs
		public final Map<String, String> oids;

		// CN in distingiushed name
		public final String commonName;

		// password for store
		public final String password;

		// password hint for README in bundle
		public String passwordHint;

		// E or EMAILADDRESS in distinguished name
		public String emailAddress;

		// start date of generated certificate
		public Date notBefore;

		// expiraiton date of generated certificate
		public Date notAfter;

		// hostname of server for which certificate is generated
		public String serverHostname;

		// displayname of user for README in bundle
		public String userDisplayname;

		// serialnumber of generated or read certificate
		public String serialNumber;

		public X509Metadata(String cn, String pwd) {
			if (StringUtils.isEmpty(cn)) {
				throw new RuntimeException("Common name required!");
			}
			if (StringUtils.isEmpty(pwd)) {
				throw new RuntimeException("Password required!");
			}

			commonName = cn;
			password = pwd;
			Calendar c = Calendar.getInstance(TimeZone.getDefault());
			c.set(Calendar.SECOND, 0);
			c.set(Calendar.MILLISECOND, 0);
			notBefore = c.getTime();
			c.add(Calendar.YEAR, 1);
			c.add(Calendar.DATE, 1);
			notAfter = c.getTime();
			oids = new HashMap<String, String>();
		}

		public X509Metadata clone(String commonName, String password) {
			X509Metadata clone = new X509Metadata(commonName, password);
			clone.emailAddress = emailAddress;
			clone.notBefore = notBefore;
			clone.notAfter = notAfter;
			clone.oids.putAll(oids);
			clone.passwordHint = passwordHint;
			clone.serverHostname = serverHostname;
			clone.userDisplayname = userDisplayname;
			return clone;
		}

		public String getOID(String oid, String defaultValue) {
			if (oids.containsKey(oid)) {
				return oids.get(oid);
			}
			return defaultValue;
		}

		public void setOID(String oid, String value) {
			if (StringUtils.isEmpty(value)) {
				oids.remove(oid);
			} else {
				oids.put(oid, value);
			}
		}
	}

	/**
	 * Prepare all the certificates and stores necessary for a Gitblit GO server.
	 *
	 * @param metadata
	 * @param folder
	 * @param x509log
	 */
	public static void prepareX509Infrastructure(X509Metadata metadata, File folder, X509Log x509log) {
		// make the specified folder, if necessary
		folder.mkdirs();

		// Gitblit CA certificate
		File caKeyStore = new File(folder, CA_KEY_STORE);
		if (!caKeyStore.exists()) {
			logger.info(MessageFormat.format("Generating {0} ({1})", CA_CN, caKeyStore.getAbsolutePath()));
			X509Certificate caCert = newCertificateAuthority(metadata, caKeyStore, x509log);
			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);
			x509log.log("new certificate revocation list created");
		}

		// rename the old keystore to the new name
		File oldKeyStore = new File(folder, "keystore");
		if (oldKeyStore.exists()) {
			oldKeyStore.renameTo(new File(folder, SERVER_KEY_STORE));
			logger.info(MessageFormat.format("Renaming {0} to {1}", oldKeyStore.getName(), SERVER_KEY_STORE));
		}

		// create web SSL certificate signed by CA
		File serverKeyStore = new File(folder, SERVER_KEY_STORE);
		if (!serverKeyStore.exists()) {
			logger.info(MessageFormat.format("Generating SSL certificate for {0} signed by {1} ({2})", metadata.commonName, CA_CN, serverKeyStore.getAbsolutePath()));
			PrivateKey caPrivateKey = getPrivateKey(CA_ALIAS, caKeyStore, metadata.password);
			X509Certificate caCert = getCertificate(CA_ALIAS, caKeyStore, metadata.password);
			newSSLCertificate(metadata, caPrivateKey, caCert, serverKeyStore, x509log);
		}

		// server certificate trust store holds trusted public certificates
		File serverTrustStore = new File(folder, X509Utils.SERVER_TRUST_STORE);
		if (!serverTrustStore.exists()) {
			logger.info(MessageFormat.format("Importing {0} into trust store ({1})", CA_ALIAS, serverTrustStore.getAbsolutePath()));
			X509Certificate caCert = getCertificate(CA_ALIAS, caKeyStore, metadata.password);
			addTrustedCertificate(CA_ALIAS, caCert, serverTrustStore, metadata.password);
		}
	}

	/**
	 * Open a keystore.  Store type is determined by file extension of name. If
	 * undetermined, JKS is assumed.  The keystore does not need to exist.
	 *
	 * @param storeFile
	 * @param storePassword
	 * @return a KeyStore
	 */
	public static KeyStore openKeyStore(File storeFile, String storePassword) {
		String lc = storeFile.getName().toLowerCase();
		String type = "JKS";
		String provider = null;
		if (lc.endsWith(".p12") || lc.endsWith(".pfx")) {
			type = "PKCS12";
			provider = BC;
		}

		try {
			KeyStore store;
			if (provider == null) {
				store = KeyStore.getInstance(type);
			} else {
				store = KeyStore.getInstance(type, provider);
			}
			if (storeFile.exists()) {
				FileInputStream fis = null;
				try {
					fis = new FileInputStream(storeFile);
					store.load(fis, storePassword.toCharArray());
				} finally {
					if (fis != null) {
						fis.close();
					}
				}
			} else {
				store.load(null);
			}
			return store;
		} catch (Exception e) {
			throw new RuntimeException("Could not open keystore " + storeFile, e);
		}
	}

	/**
	 * Saves the keystore to the specified file.
	 *
	 * @param targetStoreFile
	 * @param store
	 * @param password
	 */
	public static void saveKeyStore(File targetStoreFile, KeyStore store, String password) {
		File folder = targetStoreFile.getAbsoluteFile().getParentFile();
		if (!folder.exists()) {
			folder.mkdirs();
		}
		File tmpFile = new File(folder, Long.toHexString(System.currentTimeMillis()) + ".tmp");
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(tmpFile);
			store.store(fos, password.toCharArray());
			fos.flush();
			fos.close();
			if (targetStoreFile.exists()) {
				targetStoreFile.delete();
			}
			tmpFile.renameTo(targetStoreFile);
		} catch (IOException e) {
			String message = e.getMessage().toLowerCase();
			if (message.contains("illegal key size")) {
				throw new RuntimeException("Illegal Key Size! You might consider installing the JCE Unlimited Strength Jurisdiction Policy files for your JVM.");
			} else {
				throw new RuntimeException("Could not save keystore " + targetStoreFile, e);
			}
		} catch (Exception e) {
			throw new RuntimeException("Could not save keystore " + targetStoreFile, e);
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
				}
			}

			if (tmpFile.exists()) {
				tmpFile.delete();
			}
		}
	}

	/**
	 * Retrieves the X509 certificate with the specified alias from the certificate
	 * store.
	 *
	 * @param alias
	 * @param storeFile
	 * @param storePassword
	 * @return the certificate
	 */
	public static X509Certificate getCertificate(String alias, File storeFile, String storePassword) {
		try {
			KeyStore store = openKeyStore(storeFile, storePassword);
			X509Certificate caCert = (X509Certificate) store.getCertificate(alias);
			return caCert;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Retrieves the private key for the specified alias from the certificate
	 * store.
	 *
	 * @param alias
	 * @param storeFile
	 * @param storePassword
	 * @return the private key
	 */
	public static PrivateKey getPrivateKey(String alias, File storeFile, String storePassword) {
		try {
			KeyStore store = openKeyStore(storeFile, storePassword);
			PrivateKey key = (PrivateKey) store.getKey(alias, storePassword.toCharArray());
			return key;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * Saves the certificate to the file system.  If the destination filename
	 * ends with the pem extension, the certificate is written in the PEM format,
	 * otherwise the certificate is written in the DER format.
	 *
	 * @param cert
	 * @param targetFile
	 */
	public static void saveCertificate(X509Certificate cert, File targetFile) {
		File folder = targetFile.getAbsoluteFile().getParentFile();
		if (!folder.exists()) {
			folder.mkdirs();
		}
		File tmpFile = new File(folder, Long.toHexString(System.currentTimeMillis()) + ".tmp");
		try {
			boolean asPem = targetFile.getName().toLowerCase().endsWith(".pem");
			if (asPem) {
				// PEM encoded X509
				PEMWriter pemWriter = null;
				try {
					pemWriter = new PEMWriter(new FileWriter(tmpFile));
					pemWriter.writeObject(cert);
					pemWriter.flush();
				} finally {
					if (pemWriter != null) {
						pemWriter.close();
					}
				}
			} else {
				// DER encoded X509
				FileOutputStream fos = null;
				try {
					fos = new FileOutputStream(tmpFile);
					fos.write(cert.getEncoded());
					fos.flush();
				} finally {
					if (fos != null) {
						fos.close();
					}
				}
			}

			// rename tmp file to target
			if (targetFile.exists()) {
				targetFile.delete();
			}
			tmpFile.renameTo(targetFile);
		} catch (Exception e) {
			if (tmpFile.exists()) {
				tmpFile.delete();
			}
			throw new RuntimeException("Failed to save certificate " + cert.getSubjectX500Principal().getName(), e);
		}
	}

	/**
	 * Generate a new keypair.
	 *
	 * @return a keypair
	 * @throws Exception
	 */
	private static KeyPair newKeyPair() throws Exception {
		KeyPairGenerator kpGen = KeyPairGenerator.getInstance(KEY_ALGORITHM, BC);
		kpGen.initialize(KEY_LENGTH, new SecureRandom());
		return kpGen.generateKeyPair();
	}

	/**
	 * Builds a distinguished name from the X509Metadata.
	 *
	 * @return a DN
	 */
	private static X500Name buildDistinguishedName(X509Metadata metadata) {
		X500NameBuilder dnBuilder = new X500NameBuilder(BCStyle.INSTANCE);
		setOID(dnBuilder, metadata, "C", null);
		setOID(dnBuilder, metadata, "ST", null);
		setOID(dnBuilder, metadata, "L", null);
		setOID(dnBuilder, metadata, "O", Constants.NAME);
		setOID(dnBuilder, metadata, "OU", Constants.NAME);
		setOID(dnBuilder, metadata, "E", metadata.emailAddress);
		setOID(dnBuilder, metadata, "CN", metadata.commonName);
		X500Name dn = dnBuilder.build();
		return dn;
	}

	private static void setOID(X500NameBuilder dnBuilder, X509Metadata metadata,
			String oid, String defaultValue) {

		String value = null;
		if (metadata.oids != null && metadata.oids.containsKey(oid)) {
			value = metadata.oids.get(oid);
		}
		if (StringUtils.isEmpty(value)) {
			value = defaultValue;
		}

		if (!StringUtils.isEmpty(value)) {
			try {
				Field field = BCStyle.class.getField(oid);
				ASN1ObjectIdentifier objectId = (ASN1ObjectIdentifier) field.get(null);
				dnBuilder.addRDN(objectId, value);
			} catch (Exception e) {
				logger.error(MessageFormat.format("Failed to set OID \"{0}\"!", oid) ,e);
			}
		}
	}

	/**
	 * Creates a new SSL certificate signed by the CA private key and stored in
	 * keyStore.
	 *
	 * @param sslMetadata
	 * @param caPrivateKey
	 * @param caCert
	 * @param targetStoreFile
	 * @param x509log
	 */
	public static X509Certificate newSSLCertificate(X509Metadata sslMetadata, PrivateKey caPrivateKey, X509Certificate caCert, File targetStoreFile, X509Log x509log) {
		try {
			KeyPair pair = newKeyPair();

			X500Name webDN = buildDistinguishedName(sslMetadata);
			X500Name issuerDN = new X500Name(PrincipalUtil.getIssuerX509Principal(caCert).getName());

			X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
					issuerDN,
					BigInteger.valueOf(System.currentTimeMillis()),
					sslMetadata.notBefore,
					sslMetadata.notAfter,
					webDN,
					pair.getPublic());

			JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
			certBuilder.addExtension(X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
			certBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
			certBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));

			// support alternateSubjectNames for SSL certificates
			List<GeneralName> altNames = new ArrayList<GeneralName>();
			if (HttpUtils.isIpAddress(sslMetadata.commonName)) {
				altNames.add(new GeneralName(GeneralName.iPAddress, sslMetadata.commonName));
			}
			if (altNames.size() > 0) {
				GeneralNames subjectAltName = new GeneralNames(altNames.toArray(new GeneralName [altNames.size()]));
				certBuilder.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName);
			}

			ContentSigner caSigner = new JcaContentSignerBuilder(SIGNING_ALGORITHM)
					.setProvider(BC).build(caPrivateKey);
			X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC)
					.getCertificate(certBuilder.build(caSigner));

			cert.checkValidity(new Date());
			cert.verify(caCert.getPublicKey());

			// Save to keystore
			KeyStore serverStore = openKeyStore(targetStoreFile, sslMetadata.password);
			serverStore.setKeyEntry(sslMetadata.commonName, pair.getPrivate(), sslMetadata.password.toCharArray(),
					new Certificate[] { cert, caCert });
			saveKeyStore(targetStoreFile, serverStore, sslMetadata.password);

	        x509log.log(MessageFormat.format("New SSL certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getSubjectDN().getName()));

	        // update serial number in metadata object
	        sslMetadata.serialNumber = cert.getSerialNumber().toString();

			return cert;
		} catch (Throwable t) {
			throw new RuntimeException("Failed to generate SSL certificate!", t);
		}
	}

	/**
	 * Creates a new certificate authority PKCS#12 store.  This function will
	 * destroy any existing CA store.
	 *
	 * @param metadata
	 * @param storeFile
	 * @param keystorePassword
	 * @param x509log
	 * @return
	 */
	public static X509Certificate newCertificateAuthority(X509Metadata metadata, File storeFile, X509Log x509log) {
		try {
			KeyPair caPair = newKeyPair();

			ContentSigner caSigner = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPair.getPrivate());

			// clone metadata
			X509Metadata caMetadata = metadata.clone(CA_CN, metadata.password);
			X500Name issuerDN = buildDistinguishedName(caMetadata);

			// Generate self-signed certificate
			X509v3CertificateBuilder caBuilder = new JcaX509v3CertificateBuilder(
					issuerDN,
					BigInteger.valueOf(System.currentTimeMillis()),
					caMetadata.notBefore,
					caMetadata.notAfter,
					issuerDN,
					caPair.getPublic());

			JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
			caBuilder.addExtension(X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(caPair.getPublic()));
			caBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caPair.getPublic()));
			caBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(true));
			caBuilder.addExtension(X509Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyCertSign | KeyUsage.cRLSign));

			JcaX509CertificateConverter converter = new JcaX509CertificateConverter().setProvider(BC);
			X509Certificate cert = converter.getCertificate(caBuilder.build(caSigner));

			// confirm the validity of the CA certificate
			cert.checkValidity(new Date());
			cert.verify(cert.getPublicKey());

			// Delete existing keystore
			if (storeFile.exists()) {
				storeFile.delete();
			}

			// Save private key and certificate to new keystore
			KeyStore store = openKeyStore(storeFile, caMetadata.password);
			store.setKeyEntry(CA_ALIAS, caPair.getPrivate(), caMetadata.password.toCharArray(),
					new Certificate[] { cert });
			saveKeyStore(storeFile, store, caMetadata.password);

			x509log.log(MessageFormat.format("New CA certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getIssuerDN().getName()));

	        // update serial number in metadata object
	        caMetadata.serialNumber = cert.getSerialNumber().toString();

			return cert;
		} catch (Throwable t) {
			throw new RuntimeException("Failed to generate Gitblit CA certificate!", t);
		}
	}

	/**
	 * 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_ALIAS, caKeystorePassword.toCharArray());
			X509Certificate caCert = (X509Certificate) store.getCertificate(CA_ALIAS);

			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(SIGNING_ALGORITHM).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);
			} 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
	 * @param cert
	 * @param storeFile
	 * @param storePassword
	 */
	public static void addTrustedCertificate(String alias, X509Certificate cert, File storeFile, String storePassword) {
		try {
			KeyStore store = openKeyStore(storeFile, storePassword);
			store.setCertificateEntry(alias, cert);
			saveKeyStore(storeFile, store, storePassword);
		} catch (Exception e) {
			throw new RuntimeException("Failed to import certificate into trust store " + storeFile, e);
		}
	}

	/**
	 * Creates a new client certificate PKCS#12 and PEM store.  Any existing
	 * stores are destroyed.  After generation, the certificates are bundled
	 * into a zip file with a personalized README file.
	 *
	 * The zip file reference is returned.
	 *
	 * @param clientMetadata a container for dynamic parameters needed for generation
	 * @param caKeystoreFile
	 * @param caKeystorePassword
	 * @param x509log
	 * @return a zip file containing the P12, PEM, and personalized README
	 */
	public static File newClientBundle(X509Metadata clientMetadata, File caKeystoreFile,
			String caKeystorePassword, X509Log x509log) {
		return newClientBundle(null,clientMetadata,caKeystoreFile,caKeystorePassword,x509log);
	}

	/**
	 * Creates a new client certificate PKCS#12 and PEM store.  Any existing
	 * stores are destroyed.  After generation, the certificates are bundled
	 * into a zip file with a personalized README file.
	 *
	 * The zip file reference is returned.
	 *
	 * @param user 
	 * @param clientMetadata a container for dynamic parameters needed for generation
	 * @param caKeystoreFile
	 * @param caKeystorePassword
	 * @param x509log
	 * @return a zip file containing the P12, PEM, and personalized README
	 */
	public static File newClientBundle(com.gitblit.models.UserModel user,X509Metadata clientMetadata, File caKeystoreFile,
				String caKeystorePassword, X509Log x509log) {		
		try {
			// read the Gitblit CA key and certificate
			KeyStore store = openKeyStore(caKeystoreFile, caKeystorePassword);
			PrivateKey caPrivateKey = (PrivateKey) store.getKey(CA_ALIAS, caKeystorePassword.toCharArray());
			X509Certificate caCert = (X509Certificate) store.getCertificate(CA_ALIAS);

			// generate the P12 and PEM files
			File targetFolder = new File(caKeystoreFile.getParentFile(), clientMetadata.commonName);
			X509Certificate cert = newClientCertificate(clientMetadata, caPrivateKey, caCert, targetFolder);
	        x509log.log(MessageFormat.format("New client certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getSubjectDN().getName()));

	        // process template message
	        String readme = null;
	        String sInstructionsFileName = "instructions.tmpl";
	        if( user == null )
	        	readme = processTemplate(new File(caKeystoreFile.getParentFile(),sInstructionsFileName), clientMetadata);
	        else{
	        	File fileInstructionsTmp = null;
	        	if( (fileInstructionsTmp = new File(caKeystoreFile.getParentFile(),sInstructionsFileName+"_"+user.getPreferences().getLocale())).exists() )
	        		readme = processTemplate(fileInstructionsTmp,clientMetadata);
	        	else
	        		readme = processTemplate(new File(caKeystoreFile.getParentFile(),sInstructionsFileName),clientMetadata);
	        }
	        // Create a zip bundle with the p12, pem, and a personalized readme
	        File zipFile = new File(targetFolder, clientMetadata.commonName + ".zip");
	        if (zipFile.exists()) {
	        	zipFile.delete();
	        }
	        ZipOutputStream zos = null;
	        try {
	        	zos = new ZipOutputStream(new FileOutputStream(zipFile));
	        	File p12File = new File(targetFolder, clientMetadata.commonName + ".p12");
	        	if (p12File.exists()) {
	        		zos.putNextEntry(new ZipEntry(p12File.getName()));
	        		zos.write(FileUtils.readContent(p12File));
	        		zos.closeEntry();
	        	}
	        	File pemFile = new File(targetFolder, clientMetadata.commonName + ".pem");
	        	if (pemFile.exists()) {
	        		zos.putNextEntry(new ZipEntry(pemFile.getName()));
	        		zos.write(FileUtils.readContent(pemFile));
	        		zos.closeEntry();
	        	}

	        	// include user's public certificate
	        	zos.putNextEntry(new ZipEntry(clientMetadata.commonName + ".cer"));
        		zos.write(cert.getEncoded());
        		zos.closeEntry();

	        	// include CA public certificate
	        	zos.putNextEntry(new ZipEntry("ca.cer"));
        		zos.write(caCert.getEncoded());
        		zos.closeEntry();

	        	if (readme != null) {
	        		zos.putNextEntry(new ZipEntry("README.TXT"));
	        		zos.write(readme.getBytes("UTF-8"));
	        		zos.closeEntry();
	        	}
	        	zos.flush();
	        } finally {
	        	if (zos != null) {
	        		zos.close();
	        	}
	        }

			return zipFile;
		} catch (Throwable t) {
			throw new RuntimeException("Failed to generate client bundle!", t);
		}
	}

	/**
	 * Creates a new client certificate PKCS#12 and PEM store.  Any existing
	 * stores are destroyed.
	 *
	 * @param clientMetadata a container for dynamic parameters needed for generation
	 * @param caKeystoreFile
	 * @param caKeystorePassword
	 * @param targetFolder
	 * @return
	 */
	public static X509Certificate newClientCertificate(X509Metadata clientMetadata,
			PrivateKey caPrivateKey, X509Certificate caCert, File targetFolder) {
		try {
			KeyPair pair = newKeyPair();

			X500Name userDN = buildDistinguishedName(clientMetadata);
			X500Name issuerDN = new X500Name(PrincipalUtil.getIssuerX509Principal(caCert).getName());

			// create a new certificate signed by the Gitblit CA certificate
			X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
					issuerDN,
					BigInteger.valueOf(System.currentTimeMillis()),
					clientMetadata.notBefore,
					clientMetadata.notAfter,
					userDN,
					pair.getPublic());

			JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
			certBuilder.addExtension(X509Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(pair.getPublic()));
			certBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
			certBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));
			certBuilder.addExtension(X509Extension.keyUsage, true, new KeyUsage(KeyUsage.keyEncipherment | KeyUsage.digitalSignature));
			if (!StringUtils.isEmpty(clientMetadata.emailAddress)) {
				GeneralNames subjectAltName = new GeneralNames(
                    new GeneralName(GeneralName.rfc822Name, clientMetadata.emailAddress));
				certBuilder.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName);
			}

			ContentSigner signer = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPrivateKey);

			X509Certificate userCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certBuilder.build(signer));
			PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)pair.getPrivate();
			bagAttr.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
					extUtils.createSubjectKeyIdentifier(pair.getPublic()));

			// confirm the validity of the user certificate
			userCert.checkValidity();
			userCert.verify(caCert.getPublicKey());
			userCert.getIssuerDN().equals(caCert.getSubjectDN());

	        // verify user certificate chain
	        verifyChain(userCert, caCert);

	        targetFolder.mkdirs();

	        // save certificate, stamped with unique name
	        String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
	        String id = date;
	        File certFile = new File(targetFolder, id + ".cer");
	        int count = 0;
	        while (certFile.exists()) {
	        	id = date + "_" + Character.toString((char) (0x61 + count));
	        	certFile = new File(targetFolder, id + ".cer");
	        	count++;
	        }

	        // save user private key, user certificate and CA certificate to a PKCS#12 store
	        File p12File = new File(targetFolder, clientMetadata.commonName + ".p12");
	        if (p12File.exists()) {
	        	p12File.delete();
	        }
	        KeyStore userStore = openKeyStore(p12File, clientMetadata.password);
	        userStore.setKeyEntry(MessageFormat.format("Gitblit ({0}) {1} {2}", clientMetadata.serverHostname, clientMetadata.userDisplayname, id), pair.getPrivate(), null, new Certificate [] { userCert });
	        userStore.setCertificateEntry(MessageFormat.format("Gitblit ({0}) Certificate Authority", clientMetadata.serverHostname), caCert);
	        saveKeyStore(p12File, userStore, clientMetadata.password);

	        // save user private key, user certificate, and CA certificate to a PEM store
	        File pemFile = new File(targetFolder, clientMetadata.commonName + ".pem");
	        if (pemFile.exists()) {
	        	pemFile.delete();
	        }
	        JcePEMEncryptorBuilder builder = new JcePEMEncryptorBuilder("DES-EDE3-CBC");
	        builder.setSecureRandom(new SecureRandom());
	        PEMEncryptor pemEncryptor = builder.build(clientMetadata.password.toCharArray());
	        JcaPEMWriter pemWriter = new JcaPEMWriter(new FileWriter(pemFile));
	        pemWriter.writeObject(pair.getPrivate(), pemEncryptor);
	        pemWriter.writeObject(userCert);
	        pemWriter.writeObject(caCert);
	        pemWriter.flush();
	        pemWriter.close();

	        // save certificate after successfully creating the key stores
	        saveCertificate(userCert, certFile);

	        // update serial number in metadata object
	        clientMetadata.serialNumber = userCert.getSerialNumber().toString();

	        return userCert;
		} catch (Throwable t) {
			throw new RuntimeException("Failed to generate client certificate!", t);
		}
	}

	/**
	 * Verifies a certificate's chain to ensure that it will function properly.
	 *
	 * @param testCert
	 * @param additionalCerts
	 * @return
	 */
	public static PKIXCertPathBuilderResult verifyChain(X509Certificate testCert, X509Certificate... additionalCerts) {
		try {
			// Check for self-signed certificate
			if (isSelfSigned(testCert)) {
				throw new RuntimeException("The certificate is self-signed.  Nothing to verify.");
			}

			// Prepare a set of all certificates
			// chain builder must have all certs, including cert to validate
			// http://stackoverflow.com/a/10788392
			Set<X509Certificate> certs = new HashSet<X509Certificate>();
			certs.add(testCert);
			certs.addAll(Arrays.asList(additionalCerts));

			// Attempt to build the certification chain and verify it
			// Create the selector that specifies the starting certificate
			X509CertSelector selector = new X509CertSelector();
		    selector.setCertificate(testCert);

		    // Create the trust anchors (set of root CA certificates)
		    Set<TrustAnchor> trustAnchors = new HashSet<TrustAnchor>();
		    for (X509Certificate cert : additionalCerts) {
		    	if (isSelfSigned(cert)) {
		    		trustAnchors.add(new TrustAnchor(cert, null));
		    	}
		    }

		    // Configure the PKIX certificate builder
		    PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(trustAnchors, selector);
			pkixParams.setRevocationEnabled(false);
			pkixParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certs), BC));

			// Build and verify the certification chain
			CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", BC);
			PKIXCertPathBuilderResult verifiedCertChain = (PKIXCertPathBuilderResult) builder.build(pkixParams);

			// The chain is built and verified
			return verifiedCertChain;
		} catch (CertPathBuilderException e) {
			throw new RuntimeException("Error building certification path: " + testCert.getSubjectX500Principal(), e);
		} catch (Exception e) {
			throw new RuntimeException("Error verifying the certificate: " + testCert.getSubjectX500Principal(), e);
		}
	}

	/**
	 * Checks whether given X.509 certificate is self-signed.
	 *
	 * @param cert
	 * @return true if the certificate is self-signed
	 */
	public static boolean isSelfSigned(X509Certificate cert) {
		try {
			cert.verify(cert.getPublicKey());
			return true;
		} catch (SignatureException e) {
			return false;
		} catch (InvalidKeyException e) {
			return false;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String processTemplate(File template, X509Metadata metadata) {
		String content = null;
		if (template.exists()) {
			String message = FileUtils.readContent(template, "\n");
			if (!StringUtils.isEmpty(message)) {
				content = message;
				if (!StringUtils.isEmpty(metadata.serverHostname)) {
					content = content.replace("$serverHostname", metadata.serverHostname);
				}
				if (!StringUtils.isEmpty(metadata.commonName)) {
					content = content.replace("$username", metadata.commonName);
				}
				if (!StringUtils.isEmpty(metadata.userDisplayname)) {
					content = content.replace("$userDisplayname", metadata.userDisplayname);
				}
				if (!StringUtils.isEmpty(metadata.passwordHint)) {
					content = content.replace("$storePasswordHint", metadata.passwordHint);
				}
			}
		}
		return content;
	}

	/**
	 * Revoke a certificate.
	 *
	 * @param cert
	 * @param reason
	 * @param caRevocationList
	 * @param caKeystoreFile
	 * @param caKeystorePassword
	 * @param x509log
	 * @return true if the certificate has been revoked
	 */
	public static boolean revoke(X509Certificate cert, RevocationReason reason,
			File caRevocationList, File caKeystoreFile, String caKeystorePassword,
			X509Log x509log) {
		try {
			// read the Gitblit CA key and certificate
			KeyStore store = openKeyStore(caKeystoreFile, caKeystorePassword);
			PrivateKey caPrivateKey = (PrivateKey) store.getKey(CA_ALIAS, caKeystorePassword.toCharArray());
			return revoke(cert, reason, caRevocationList, caPrivateKey, x509log);
		} catch (Exception e) {
			logger.error(MessageFormat.format("Failed to revoke certificate {0,number,0} [{1}] in {2}",
					cert.getSerialNumber(), cert.getSubjectDN().getName(), caRevocationList));
		}
		return false;
	}

	/**
	 * Revoke a certificate.
	 *
	 * @param cert
	 * @param reason
	 * @param caRevocationList
	 * @param caPrivateKey
	 * @param x509log
	 * @return true if the certificate has been revoked
	 */
	public static boolean revoke(X509Certificate cert, RevocationReason reason,
			 File caRevocationList, PrivateKey caPrivateKey, X509Log x509log) {
		try {
			X500Name issuerDN = new X500Name(PrincipalUtil.getIssuerX509Principal(cert).getName());
			X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(issuerDN, new Date());
			if (caRevocationList.exists()) {
				byte [] data = FileUtils.readContent(caRevocationList);
				X509CRLHolder crl = new X509CRLHolder(data);
				crlBuilder.addCRL(crl);
			}
			crlBuilder.addCRLEntry(cert.getSerialNumber(), new Date(), reason.ordinal());

			// 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);

			} finally {
				if (fos != null) {
					fos.close();
				}
				if (tmpFile.exists()) {
					tmpFile.delete();
				}
			}

			x509log.log(MessageFormat.format("Revoked certificate {0,number,0} reason: {1} [{2}]",
					cert.getSerialNumber(), reason.toString(), cert.getSubjectDN().getName()));
			return true;
		} catch (IOException | OperatorCreationException | CertificateEncodingException e) {
			logger.error(MessageFormat.format("Failed to revoke certificate {0,number,0} [{1}] in {2}",
					cert.getSerialNumber(), cert.getSubjectDN().getName(), caRevocationList));
		}
		return false;
	}

	/**
	 * Returns true if the certificate has been revoked.
	 *
	 * @param cert
	 * @param caRevocationList
	 * @return true if the certificate is revoked
	 */
	public static boolean isRevoked(X509Certificate cert, File caRevocationList) {
		if (!caRevocationList.exists()) {
			return false;
		}
		InputStream inStream = null;
		try {
			inStream = new FileInputStream(caRevocationList);
			CertificateFactory cf = CertificateFactory.getInstance("X.509");
			X509CRL crl = (X509CRL)cf.generateCRL(inStream);
			return crl.isRevoked(cert);
		} catch (Exception e) {
			logger.error(MessageFormat.format("Failed to check revocation status for certificate {0,number,0} [{1}] in {2}",
					cert.getSerialNumber(), cert.getSubjectDN().getName(), caRevocationList));
		} finally {
			if (inStream != null) {
				try {
					inStream.close();
				} catch (Exception e) {
				}
			}
		}
		return false;
	}

	public static X509Metadata getMetadata(X509Certificate cert) {
		Map<String, String> oids = new HashMap<String, String>();
		try {
			String dn = cert.getSubjectDN().getName();
			LdapName ldapName = new LdapName(dn);
			for (int i = 0; i < ldapName.size(); i++) {
				String [] val = ldapName.get(i).trim().split("=", 2);
				String oid = val[0].toUpperCase().trim();
				String data = val[1].trim();
				oids.put(oid, data);
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		X509Metadata metadata = new X509Metadata(oids.get("CN"), "whocares");
		metadata.oids.putAll(oids);
		metadata.serialNumber = cert.getSerialNumber().toString();
		metadata.notAfter = cert.getNotAfter();
		metadata.notBefore = cert.getNotBefore();
		metadata.emailAddress = metadata.getOID("E", null);
		if (metadata.emailAddress == null) {
			metadata.emailAddress = metadata.getOID("EMAILADDRESS", null);
		}
		return metadata;
	}
}
