diff --git a/browsermob-core/pom.xml b/browsermob-core/pom.xml
index b6ab59b31..35fefc957 100644
--- a/browsermob-core/pom.xml
+++ b/browsermob-core/pom.xml
@@ -144,12 +144,6 @@
2.5
-
- org.bouncycastle
- bcprov-jdk15on
- 1.47
-
-
dnsjava
dnsjava
@@ -183,20 +177,6 @@
net.lightbody.bmp
mitm
${project.version}
-
-
- net.lightbody.bmp
- littleproxy
-
-
- org.bouncycastle
- bcprov-jdk15on
-
-
- org.bouncycastle
- bcpkix-jdk15on
-
-
diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/CertificateCreator.java b/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/CertificateCreator.java
deleted file mode 100644
index 53b7aaa63..000000000
--- a/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/CertificateCreator.java
+++ /dev/null
@@ -1,411 +0,0 @@
-package net.lightbody.bmp.proxy.selenium;
-
-import org.bouncycastle.asn1.DEREncodableVector;
-import org.bouncycastle.asn1.DERObjectIdentifier;
-import org.bouncycastle.asn1.DERSequence;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.KeyUsage;
-import org.bouncycastle.asn1.x509.X509Extensions;
-import org.bouncycastle.jce.X509Principal;
-import org.bouncycastle.x509.X509V3CertificateGenerator;
-import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
-import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
-
-import javax.security.auth.x500.X500Principal;
-import java.math.BigInteger;
-import java.security.*;
-import java.security.cert.*;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Methods for creating certificates.
- *
- * ***************************************************************************************
- * Copyright (c) 2007, Information Security Partners, LLC
- * All rights reserved.
- *
- * In a special exception, Selenium/OpenQA is allowed to use this code under the Apache License 2.0.
- *
- * @author Brad Hill
- *
- */
-public class CertificateCreator {
-
-
- private static final HashSet clientCertOidsNeverToCopy = new HashSet();
- private static final HashSet clientCertDefaultOidsNotToCopy = new HashSet();
-
- /**
- * The default key generation algorithm for this package is RSA.
- */
- public static final String KEYGEN_ALGO = "RSA";
-
- /**
- * The default sign algorithm for this package is SHA1 with RSA.
- */
- public static final String SIGN_ALGO = "SHA1withRSA";
-
-
- /**
- * X.509 OID for Subject Key Identifier Extension - Replaced when duplicating a cert.
- */
- public static final String OID_SUBJECT_KEY_IDENTIFIER = "2.5.29.14";
-
- /**
- * X.509 OID for Subject Authority Key Identifier - Replaced when duplicating a cert.
- */
- public static final String OID_AUTHORITY_KEY_IDENTIFIER = "2.5.29.35";
-
- /**
- * X.509 OID for Issuer Alternative Name - Omitted when duplicating a cert by default.
- */
- public static final String OID_ISSUER_ALTERNATIVE_NAME = "2.5.29.8";
-
- /**
- * X.509 OID for Issuer Alternative Name 2 - Omitted when duplicating a cert by default.
- */
- public static final String OID_ISSUER_ALTERNATIVE_NAME_2 = "2.5.29.18";
-
- /**
- * X.509 OID for Certificate Revocation List Distribution Point - Omitted when duplicating a cert by default.
- */
- public static final String OID_CRL_DISTRIBUTION_POINT = "2.5.28.31";
-
- /**
- * X.509 OID for Authority Information Access - Omitted when duplicating a cert by default.
- */
- public static final String OID_AUTHORITY_INFO_ACCESS = "1.3.6.1.5.5.7.1.1";
-
- /**
- * X.509 OID for Additional CA Issuers for AIA - Omitted when duplicating a cert by default.
- */
- public static final String OID_ID_AD_CAISSUERS = "1.3.6.1.5.5.7.48.2";
-
-
- static
- {
- clientCertOidsNeverToCopy.add(OID_SUBJECT_KEY_IDENTIFIER);
- clientCertOidsNeverToCopy.add(OID_AUTHORITY_KEY_IDENTIFIER);
-
- clientCertDefaultOidsNotToCopy.add(OID_ISSUER_ALTERNATIVE_NAME);
- clientCertDefaultOidsNotToCopy.add(OID_ISSUER_ALTERNATIVE_NAME_2);
- clientCertDefaultOidsNotToCopy.add(OID_CRL_DISTRIBUTION_POINT);
- clientCertDefaultOidsNotToCopy.add(OID_AUTHORITY_INFO_ACCESS);
- }
-
-
- /**
- * Utility method for generating a "standard" server certificate. Recognized by most
- * browsers as valid for SSL/TLS. These certificates are generated de novo, not from
- * a template, so they will not retain the structure of the original certificate and may
- * not be suitable for applications that require Extended Validation/High Assurance SSL
- * or other distinct extensions or EKU.
- *
- * @param newPubKey
- * @param caCert
- * @param caPrivateKey
- * @param hostname
- * @return
- * @throws CertificateParsingException
- * @throws SignatureException
- * @throws InvalidKeyException
- * @throws CertificateExpiredException
- * @throws CertificateNotYetValidException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- */
- @SuppressWarnings({ "deprecation", "unused" })
- public static X509Certificate generateStdSSLServerCertificate(
- final PublicKey newPubKey,
- final X509Certificate caCert,
- final PrivateKey caPrivateKey,
- final String subject)
- throws CertificateParsingException,
- SignatureException,
- InvalidKeyException,
- CertificateExpiredException,
- CertificateNotYetValidException,
- CertificateException,
- NoSuchAlgorithmException,
- NoSuchProviderException
- {
- X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
-
- v3CertGen.setSubjectDN(new X500Principal(subject));
- v3CertGen.setSignatureAlgorithm(CertificateCreator.SIGN_ALGO);
- v3CertGen.setPublicKey(newPubKey);
- v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + 30L * 60 * 60 * 24 * 30 * 12));
- v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30 *12));
- v3CertGen.setIssuerDN(caCert.getSubjectX500Principal());
-
- // Firefox actually tracks serial numbers within a CA and refuses to validate if it sees duplicates
- // This is not a secure serial number generator, (duh!) but it's good enough for our purposes.
- v3CertGen.setSerialNumber(new BigInteger(Long.toString(System.currentTimeMillis())));
-
- v3CertGen.addExtension(
- X509Extensions.BasicConstraints,
- true,
- new BasicConstraints(false) );
-
- v3CertGen.addExtension(
- X509Extensions.SubjectKeyIdentifier,
- false,
- new SubjectKeyIdentifierStructure(newPubKey));
-
-
- v3CertGen.addExtension(
- X509Extensions.AuthorityKeyIdentifier,
- false,
- new AuthorityKeyIdentifierStructure(caCert.getPublicKey()));
-
-// Firefox 2 disallows these extensions in an SSL server cert. IE7 doesn't care.
-// v3CertGen.addExtension(
-// X509Extensions.KeyUsage,
-// false,
-// new KeyUsage(KeyUsage.dataEncipherment | KeyUsage.digitalSignature ) );
-
-
- DEREncodableVector typicalSSLServerExtendedKeyUsages = new DEREncodableVector();
-
- typicalSSLServerExtendedKeyUsages.add(new DERObjectIdentifier(ExtendedKeyUsageConstants.serverAuth));
- typicalSSLServerExtendedKeyUsages.add(new DERObjectIdentifier(ExtendedKeyUsageConstants.clientAuth));
- typicalSSLServerExtendedKeyUsages.add(new DERObjectIdentifier(ExtendedKeyUsageConstants.netscapeServerGatedCrypto));
- typicalSSLServerExtendedKeyUsages.add(new DERObjectIdentifier(ExtendedKeyUsageConstants.msServerGatedCrypto));
-
- v3CertGen.addExtension(
- X509Extensions.ExtendedKeyUsage,
- false,
- new DERSequence(typicalSSLServerExtendedKeyUsages));
-
-// Disabled by default. Left in comments in case this is desired.
-//
-// v3CertGen.addExtension(
-// X509Extensions.AuthorityInfoAccess,
-// false,
-// new AuthorityInformationAccess(new DERObjectIdentifier(OID_ID_AD_CAISSUERS),
-// new GeneralName(GeneralName.uniformResourceIdentifier, "http://" + subject + "/aia")));
-
-// v3CertGen.addExtension(
-// X509Extensions.CRLDistributionPoints,
-// false,
-// new CRLDistPoint(new DistributionPoint[] {}));
-
-
-
- X509Certificate cert = v3CertGen.generate(caPrivateKey, "BC");
-
- return cert;
- }
-
- /**
- * This method creates an X509v3 certificate based on an an existing certificate.
- * It attempts to create as faithful a copy of the existing certificate as possible
- * by duplicating all certificate extensions.
- *
- * If you are testing an application that makes use of additional certificate
- * extensions (e.g. logotype, S/MIME capabilities) this method will preserve those
- * fields.
- *
- * You may optionally include a set of OIDs not to copy from the original certificate.
- * The most common reason to do this would be to remove fields that would cause inconsistency,
- * such as Authority Info Access or Issuer Alternative Name where these are not defined for
- * the MITM authority certificate.
- *
- * OIDs 2.5.29.14 : Subject Key Identifier and 2.5.29.35 : Authority Key Identifier,
- * are never copied, but generated directly based on the input keys and certificates.
- *
- * You may also optionally include maps of custom extensions which will be added to or replace
- * extensions with the same OID on the original certificate for the the MITM certificate.
- *
- * FUTURE WORK: JDK 1.5 is very strict in parsing extensions. In particular, known extensions
- * that include URIs must parse to valid URIs (including URL encoding all non-valid URI characters)
- * or the extension will be rejected and not available to copy to the MITM certificate. Will need
- * to directly extract these as ASN.1 fields and re-insert (hopefully BouncyCastle will handle them)
- *
- *
- * @param originalCert The original certificate to duplicate.
- * @param newPubKey The new public key for the MITM certificate.
- * @param caCert The certificate of the signing authority fot the MITM certificate.
- * @param caPrivateKey The private key of the signing authority.
- * @param extensionOidsNotToCopy An optional list of certificate extension OIDs not to copy to the MITM certificate.
- * @return The new MITM certificate.
- * @throws CertificateParsingException
- * @throws SignatureException
- * @throws InvalidKeyException
- * @throws CertificateExpiredException
- * @throws CertificateNotYetValidException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- */
- public static X509Certificate mitmDuplicateCertificate(final X509Certificate originalCert,
- final PublicKey newPubKey,
- final X509Certificate caCert,
- final PrivateKey caPrivateKey,
- Set extensionOidsNotToCopy)
- throws CertificateParsingException,
- SignatureException,
- InvalidKeyException,
- CertificateException,
- NoSuchAlgorithmException,
- NoSuchProviderException
- {
- if(extensionOidsNotToCopy == null)
- {
- extensionOidsNotToCopy = new HashSet();
- }
-
- X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
-
- v3CertGen.setSubjectDN(originalCert.getSubjectX500Principal());
- v3CertGen.setSignatureAlgorithm(CertificateCreator.SIGN_ALGO); // needs to be the same as the signing cert, not the copied cert
- v3CertGen.setPublicKey(newPubKey);
- v3CertGen.setNotAfter(originalCert.getNotAfter());
- v3CertGen.setNotBefore(originalCert.getNotBefore());
- v3CertGen.setIssuerDN(caCert.getSubjectX500Principal());
- v3CertGen.setSerialNumber(originalCert.getSerialNumber());
-
- // copy other extensions:
- Set critExts = originalCert.getCriticalExtensionOIDs();
-
- // get extensions returns null, not an empty set!
- if(critExts != null) {
- for (String oid : critExts) {
- if(!clientCertOidsNeverToCopy.contains(oid)
- && !extensionOidsNotToCopy.contains(oid)) {
- v3CertGen.copyAndAddExtension(new DERObjectIdentifier(oid), true, originalCert);
- }
- }
- }
- Set nonCritExs = originalCert.getNonCriticalExtensionOIDs();
-
- if(nonCritExs != null) {
- for(String oid: nonCritExs) {
-
- if(!clientCertOidsNeverToCopy.contains(oid)
- && !extensionOidsNotToCopy.contains(oid)){
- v3CertGen.copyAndAddExtension(new DERObjectIdentifier(oid), false, originalCert);
- }
- }
- }
-
- v3CertGen.addExtension(
- X509Extensions.SubjectKeyIdentifier,
- false,
- new SubjectKeyIdentifierStructure(newPubKey));
-
-
- v3CertGen.addExtension(
- X509Extensions.AuthorityKeyIdentifier,
- false,
- new AuthorityKeyIdentifierStructure(caCert.getPublicKey()));
-
- X509Certificate cert = v3CertGen.generate(caPrivateKey, "BC");
-
- // For debugging purposes.
- //cert.checkValidity(new Date());
- //cert.verify(caCert.getPublicKey());
-
- return cert;
- }
-
- /**
- * Convenience method for the most common case of certificate duplication.
- *
- * This method will not add any custom extensions and won't copy the extensions 2.5.29.8 : Issuer Alternative Name,
- * 2.5.29.18 : Issuer Alternative Name 2, 2.5.29.31 : CRL Distribution Point or 1.3.6.1.5.5.7.1.1 : Authority Info Access, if they are present.
- *
- * @param originalCert
- * @param newPubKey
- * @param caCert
- * @param caPrivateKey
- * @return
- * @throws CertificateParsingException
- * @throws SignatureException
- * @throws InvalidKeyException
- * @throws CertificateExpiredException
- * @throws CertificateNotYetValidException
- * @throws CertificateException
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- */
- public static X509Certificate mitmDuplicateCertificate(final X509Certificate originalCert,
- final PublicKey newPubKey,
- final X509Certificate caCert,
- final PrivateKey caPrivateKey)
- throws CertificateParsingException, SignatureException, InvalidKeyException, CertificateExpiredException, CertificateNotYetValidException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException
- {
- return mitmDuplicateCertificate(originalCert, newPubKey, caCert, caPrivateKey, clientCertDefaultOidsNotToCopy);
- }
-
- /**
- * Creates a typical Certification Authority (CA) certificate.
- * @param keyPair
- * @throws SecurityException
- * @throws InvalidKeyException
- * @throws NoSuchProviderException
- * @throws NoSuchAlgorithmException
- * @throws CertificateException
- */
- @SuppressWarnings("deprecation")
- public static X509Certificate createTypicalMasterCert(final KeyPair keyPair)
- throws SignatureException, InvalidKeyException, SecurityException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException
- {
-
- X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();
-
- X509Principal issuer=new X509Principal("O=CyberVillians.com,OU=CyberVillians Certification Authority,C=US");
-
- // Create
- v3CertGen.setSerialNumber(BigInteger.valueOf(1));
- v3CertGen.setIssuerDN(issuer);
- v3CertGen.setSubjectDN(issuer);
-
- //Set validity period
- v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 12 /* months */ *(1000L * 60 * 60 * 24 * 30)));
- v3CertGen.setNotAfter (new Date(System.currentTimeMillis() + 240 /* months */ *(1000L * 60 * 60 * 24 * 30)));
-
- //Set signature algorithm & public key
- v3CertGen.setPublicKey(keyPair.getPublic());
- v3CertGen.setSignatureAlgorithm(CertificateCreator.SIGN_ALGO);
-
- // Add typical extensions for signing cert
- v3CertGen.addExtension(
- X509Extensions.SubjectKeyIdentifier,
- false,
- new SubjectKeyIdentifierStructure(keyPair.getPublic()));
-
- v3CertGen.addExtension(
- X509Extensions.BasicConstraints,
- true,
- new BasicConstraints(0));
-
- v3CertGen.addExtension(
- X509Extensions.KeyUsage,
- false,
- new KeyUsage(KeyUsage.cRLSign | KeyUsage.keyCertSign) );
-
- DEREncodableVector typicalCAExtendedKeyUsages = new DEREncodableVector();
-
- typicalCAExtendedKeyUsages.add(new DERObjectIdentifier(ExtendedKeyUsageConstants.serverAuth));
- typicalCAExtendedKeyUsages.add(new DERObjectIdentifier(ExtendedKeyUsageConstants.OCSPSigning));
- typicalCAExtendedKeyUsages.add(new DERObjectIdentifier(ExtendedKeyUsageConstants.verisignUnknown));
-
- v3CertGen.addExtension(
- X509Extensions.ExtendedKeyUsage,
- false,
- new DERSequence(typicalCAExtendedKeyUsages));
-
- X509Certificate cert = v3CertGen.generate(keyPair.getPrivate(), "BC");
-
- cert.checkValidity(new Date());
-
- cert.verify(keyPair.getPublic());
-
- return cert;
- }
-
-}
diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/KeyStoreManager.java b/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/KeyStoreManager.java
index 96c332969..06871d5bf 100644
--- a/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/KeyStoreManager.java
+++ b/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/KeyStoreManager.java
@@ -1,12 +1,35 @@
package net.lightbody.bmp.proxy.selenium;
+import net.lightbody.bmp.mitm.keys.RSAKeyGenerator;
import net.lightbody.bmp.proxy.jetty.log.LogFactory;
import org.apache.commons.logging.Log;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import java.io.*;
-import java.security.*;
-import java.security.cert.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.UnrecoverableEntryException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
import java.util.HashMap;
/**
@@ -49,20 +72,13 @@ public class KeyStoreManager {
private HashMap _rememberedPrivateKeys;
private HashMap _mappedPublicKeys;
private HashMap _certMap;
- private HashMap _subjectMap;
+ private HashMap hostnameThumbprintMap;
private final String KEYMAP_SER_FILE = "keymap.ser";
private final String PUB_KEYMAP_SER_FILE = "pubkeymap.ser";
public final String RSA_KEYGEN_ALGO = "RSA";
public final String DSA_KEYGEN_ALGO = "DSA";
- public final KeyPairGenerator _rsaKpg;
- public final KeyPairGenerator _dsaKpg;
-
- private SecureRandom _sr;
-
-
-
private boolean persistImmediately = true;
private File root;
@@ -71,20 +87,6 @@ public class KeyStoreManager {
public KeyStoreManager(File root) {
this.root = root;
- Security.insertProviderAt(new BouncyCastleProvider(), 2);
-
- _sr = new SecureRandom();
-
- try
- {
- _rsaKpg = KeyPairGenerator.getInstance(RSA_KEYGEN_ALGO);
- _dsaKpg = KeyPairGenerator.getInstance(DSA_KEYGEN_ALGO);
- }
- catch(Throwable t)
- {
- throw new Error(t);
- }
-
try {
File privKeys = new File(root, KEYMAP_SER_FILE);
@@ -132,15 +134,9 @@ public KeyStoreManager(File root) {
throw new Error(e);
}
-
-
- _rsaKpg.initialize(1024, _sr);
- _dsaKpg.initialize(1024, _sr);
-
-
try
{
- _ks = KeyStore.getInstance("PKCS12", "SunJSSE");
+ _ks = KeyStore.getInstance("PKCS12");
reloadKeystore();
}
@@ -197,13 +193,13 @@ public KeyStoreManager(File root) {
if(!file.exists())
{
- _subjectMap = new HashMap();
+ hostnameThumbprintMap = new HashMap();
}
else
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
// Deserialize the object
- _subjectMap = (HashMap)in.readObject();
+ hostnameThumbprintMap = (HashMap)in.readObject();
in.close();
}
@@ -237,43 +233,9 @@ private void reloadKeystore() throws FileNotFoundException, IOException, NoSuchA
* Creates, writes and loads a new keystore and CA root certificate.
*/
protected void createKeystore() {
-
- java.security.cert.Certificate signingCert = null;
- PrivateKey caPrivKey = null;
-
if(_caCert == null || _caPrivKey == null)
{
- try
- {
- log.debug("Keystore or signing cert & keypair not found. Generating...");
-
- KeyPair caKeypair = getRSAKeyPair();
- caPrivKey = caKeypair.getPrivate();
- signingCert = CertificateCreator.createTypicalMasterCert(caKeypair);
-
- log.debug("Done generating signing cert");
- log.debug(signingCert);
-
- _ks.load(null, _keystorepass);
-
- _ks.setKeyEntry(_caPrivKeyAlias, caPrivKey, _keypassword, new java.security.cert.Certificate[] {signingCert});
-
- File caKsFile = new File(root, _caPrivateKeystore);
-
- OutputStream os = new FileOutputStream(caKsFile);
- _ks.store(os, _keystorepass);
-
- log.debug("Wrote keystore to: " +
- caKsFile.getAbsolutePath());
-
- _caCert = (X509Certificate)signingCert;
- _caPrivKey = caPrivKey;
- }
- catch(Exception e)
- {
- log.error("Fatal error creating/storing keystore or signing cert.", e);
- throw new Error(e);
- }
+ throw new RuntimeException("Legacy ProxyServer implementation does not support dynamic CA generation");
}
else
{
@@ -348,7 +310,6 @@ public synchronized X509Certificate getCertificateByAlias(final String alias) th
/**
* Returns the aliased certificate. Certificates are aliased by their hostname.
* @see ThumbprintUtil
- * @param alias
* @return
* @throws KeyStoreException
* @throws UnrecoverableKeyException
@@ -363,7 +324,7 @@ public synchronized X509Certificate getCertificateByAlias(final String alias) th
*/
public synchronized X509Certificate getCertificateByHostname(final String hostname) throws KeyStoreException, CertificateParsingException, InvalidKeyException, CertificateExpiredException, CertificateNotYetValidException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, UnrecoverableKeyException{
- String alias = _subjectMap.get(getSubjectForHostname(hostname));
+ String alias = hostnameThumbprintMap.get(hostname);
if(alias != null) {
return (X509Certificate)_ks.getCertificate(alias);
@@ -409,99 +370,6 @@ public void setPersistImmediately(final boolean persistImmediately) {
this.persistImmediately = persistImmediately;
}
- /**
- * This method returns the duplicated certificate mapped to the passed in cert, or
- * creates and returns one if no mapping has yet been performed. If a naked public
- * key has already been mapped that matches the key in the cert, the already mapped
- * keypair will be reused for the mapped cert.
- * @param cert
- * @return
- * @throws CertificateEncodingException
- * @throws InvalidKeyException
- * @throws CertificateException
- * @throws CertificateNotYetValidException
- * @throws NoSuchAlgorithmException
- * @throws NoSuchProviderException
- * @throws SignatureException
- * @throws KeyStoreException
- * @throws UnrecoverableKeyException
- */
- public synchronized X509Certificate getMappedCertificate(final X509Certificate cert)
- throws CertificateEncodingException,
- InvalidKeyException,
- CertificateException,
- CertificateNotYetValidException,
- NoSuchAlgorithmException,
- NoSuchProviderException,
- SignatureException,
- KeyStoreException,
- UnrecoverableKeyException
- {
-
- String thumbprint = ThumbprintUtil.getThumbprint(cert);
-
- String mappedCertThumbprint = _certMap.get(thumbprint);
-
- if(mappedCertThumbprint == null)
- {
-
- // Check if we've already mapped this public key from a KeyValue
- PublicKey mappedPk = getMappedPublicKey(cert.getPublicKey());
- PrivateKey privKey;
-
- if(mappedPk == null)
- {
- PublicKey pk = cert.getPublicKey();
-
- String algo = pk.getAlgorithm();
-
- KeyPair kp;
-
- if(algo.equals("RSA")) {
- kp = getRSAKeyPair();
- }
- else if(algo.equals("DSA")) {
- kp = getDSAKeyPair();
- }
- else
- {
- throw new InvalidKeyException("Key algorithm " + algo + " not supported.");
- }
- mappedPk = kp.getPublic();
- privKey = kp.getPrivate();
-
- mapPublicKeys(cert.getPublicKey(), mappedPk);
- }
- else
- {
- privKey = getPrivateKey(mappedPk);
- }
-
-
- X509Certificate replacementCert =
- CertificateCreator.mitmDuplicateCertificate(
- cert,
- mappedPk,
- getSigningCert(),
- getSigningPrivateKey());
-
- addCertAndPrivateKey(null, replacementCert, privKey);
-
- mappedCertThumbprint = ThumbprintUtil.getThumbprint(replacementCert);
-
- _certMap.put(thumbprint, mappedCertThumbprint);
- _certMap.put(mappedCertThumbprint, thumbprint);
- _subjectMap.put(replacementCert.getSubjectX500Principal().getName(), thumbprint);
-
- if(persistImmediately) {
- persist();
- }
- return replacementCert;
- }
- return getCertificateByAlias(mappedCertThumbprint);
-
- }
-
/**
* This method returns the mapped certificate for a hostname, or generates a "standard"
* SSL server certificate issued by the CA to the supplied subject if no mapping has been
@@ -523,24 +391,22 @@ else if(algo.equals("DSA")) {
*/
public X509Certificate getMappedCertificateForHostname(String hostname) throws CertificateParsingException, InvalidKeyException, CertificateExpiredException, CertificateNotYetValidException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, KeyStoreException, UnrecoverableKeyException
{
- String subject = getSubjectForHostname(hostname);
-
- String thumbprint = _subjectMap.get(subject);
+ String thumbprint = hostnameThumbprintMap.get(hostname);
if(thumbprint == null) {
- KeyPair kp = getRSAKeyPair();
+ KeyPair kp = new RSAKeyGenerator().generate();
- X509Certificate newCert = CertificateCreator.generateStdSSLServerCertificate(kp.getPublic(),
+ X509Certificate newCert = ServerCertificateCreator.generateStdSSLServerCertificate(kp,
getSigningCert(),
getSigningPrivateKey(),
- subject);
+ hostname);
addCertAndPrivateKey(hostname, newCert, kp.getPrivate());
thumbprint = ThumbprintUtil.getThumbprint(newCert);
- _subjectMap.put(subject, thumbprint);
+ hostnameThumbprintMap.put(hostname, thumbprint);
if(persistImmediately) {
persist();
@@ -554,11 +420,6 @@ public X509Certificate getMappedCertificateForHostname(String hostname) throws C
}
- private String getSubjectForHostname(String hostname) {
- String subject = "CN=" + hostname + ", OU=BrowserMob Proxy, O=Impersonated Certificate, L=Seattle, S=Washington, C=US";
- return subject;
- }
-
private synchronized void persistCertMap() {
try {
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(root, CERTMAP_SER_FILE)));
@@ -580,7 +441,7 @@ private synchronized void persistCertMap() {
private synchronized void persistSubjectMap() {
try {
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(root, SUBJMAP_SER_FILE)));
- out.writeObject(_subjectMap);
+ out.writeObject(hostnameThumbprintMap);
out.flush();
out.close();
} catch (FileNotFoundException e) {
@@ -612,31 +473,6 @@ public synchronized PrivateKey getPrivateKeyForLocalCert(final X509Certificate c
return (PrivateKey)_ks.getKey(thumbprint, _keypassword);
}
-
- /**
- * Generate an RSA Key Pair
- * @return
- */
- public KeyPair getRSAKeyPair()
- {
- KeyPair kp = _rsaKpg.generateKeyPair();
- rememberKeyPair(kp);
- return kp;
-
- }
-
- /**
- * Generate a DSA Key Pair
- * @return
- */
- public KeyPair getDSAKeyPair()
- {
- KeyPair kp = _dsaKpg.generateKeyPair();
- rememberKeyPair(kp);
- return kp;
- }
-
-
private synchronized void persistPublicKeyMap() {
try {
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(new File(root, PUB_KEYMAP_SER_FILE)));
@@ -691,7 +527,6 @@ public synchronized void mapPublicKeys(final PublicKey original, final PublicKey
* later see an X509Data with the same public key, we shouldn't split this
* in our MITM impl. So when creating a new cert, we should check if we've already
* assigned a substitute key and re-use it, and vice-versa.
- * @param pk
* @return
*/
public synchronized PublicKey getMappedPublicKey(final PublicKey original)
diff --git a/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/ServerCertificateCreator.java b/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/ServerCertificateCreator.java
new file mode 100644
index 000000000..de5dd0358
--- /dev/null
+++ b/browsermob-core/src/main/java/net/lightbody/bmp/proxy/selenium/ServerCertificateCreator.java
@@ -0,0 +1,46 @@
+package net.lightbody.bmp.proxy.selenium;
+
+import net.lightbody.bmp.mitm.CertificateAndKey;
+import net.lightbody.bmp.mitm.CertificateInfo;
+import net.lightbody.bmp.mitm.CertificateInfoGenerator;
+import net.lightbody.bmp.mitm.HostnameCertificateInfoGenerator;
+import net.lightbody.bmp.mitm.tools.DefaultSecurityProviderTool;
+import net.lightbody.bmp.mitm.tools.SecurityProviderTool;
+import net.lightbody.bmp.mitm.util.MitmConstants;
+
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
+
+/**
+ * Utility to create server certificates for legacy {@link net.lightbody.bmp.proxy.ProxyServer} MITM.
+ */
+public class ServerCertificateCreator {
+ /**
+ * Use the default hostname-impersonating certificate info generator that the MITM module provides.
+ */
+ private static final CertificateInfoGenerator CERT_INFO_GENERATOR = new HostnameCertificateInfoGenerator();
+
+ /**
+ * Use the default (JDK where available, otherwise BC) security provider to generate certificates.
+ */
+ private static final SecurityProviderTool SECURITY_PROVIDER = new DefaultSecurityProviderTool();
+
+ public static X509Certificate generateStdSSLServerCertificate(
+ KeyPair newPublicAndPrivateKey,
+ X509Certificate caCert,
+ PrivateKey caPrivateKey,
+ String hostname) {
+ CertificateInfo certificateInfo = CERT_INFO_GENERATOR.generate(Collections.singletonList(hostname), null);
+
+ CertificateAndKey newServerCert = SECURITY_PROVIDER.createServerCertificate(
+ certificateInfo,
+ caCert,
+ caPrivateKey,
+ newPublicAndPrivateKey,
+ MitmConstants.DEFAULT_MESSAGE_DIGEST);
+
+ return newServerCert.getCertificate();
+ }
+}
diff --git a/mitm/src/main/java/net/lightbody/bmp/mitm/RootCertificateGenerator.java b/mitm/src/main/java/net/lightbody/bmp/mitm/RootCertificateGenerator.java
index 5f1877c4c..b7baa8e0c 100644
--- a/mitm/src/main/java/net/lightbody/bmp/mitm/RootCertificateGenerator.java
+++ b/mitm/src/main/java/net/lightbody/bmp/mitm/RootCertificateGenerator.java
@@ -2,9 +2,9 @@
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
-import net.lightbody.bmp.mitm.tools.DefaultSecurityProviderTool;
import net.lightbody.bmp.mitm.keys.KeyGenerator;
import net.lightbody.bmp.mitm.keys.RSAKeyGenerator;
+import net.lightbody.bmp.mitm.tools.DefaultSecurityProviderTool;
import net.lightbody.bmp.mitm.tools.SecurityProviderTool;
import net.lightbody.bmp.mitm.util.EncryptionUtil;
import net.lightbody.bmp.mitm.util.MitmConstants;