<commit_before>package cybervillains.ca;

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.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
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.SecureRandom;
import java.security.Security;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
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;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * This is the main entry point into the Cybervillains CA.
 * 
 * This class handles generation, storage and the persistent
 * mapping of input to duplicated certificates and mapped public 
 * keys.
 * 
 * Default setting is to immediately persist changes to the store
 * by writing out the keystore and mapping file every time a new 
 * certificate is added.  This behavior can be disabled if desired,
 * to enhance performance or allow temporary testing without modifying
 * the certificate store.
 * 
 ***************************************************************************************
 * Copyright (c) 2007, Information Security Partners, LLC
 * All rights reserved.
 *
 * This software licensed under the GPLv2, available in LICENSE.txt and at
 * http://www.gnu.org/licenses/gpl.txt
 *
 * @author <NAME>
 *
 */
public class KeyStoreManager {
	
	private final String CERTMAP_SER_FILE = "certmap.ser";
	private final String SUBJMAP_SER_FILE = "subjmap.ser";
	
	private final String EXPORTED_CERT_NAME = "cybervillainsCA.cer";
	
	private final char[] _keypassword = "password".toCharArray();
	private final char[] _keystorepass = "password".toCharArray();
	private final String _caPrivateKeystore = "cybervillainsCA.jks";
	private final String _caCertAlias = "signingCert";
	public static final String _caPrivKeyAlias = "signingCertPrivKey";

	X509Certificate _caCert;
	PrivateKey _caPrivKey;
	KeyStore _ks;
	
	private HashMap<PublicKey, PrivateKey> _rememberedPrivateKeys;
	private HashMap<PublicKey, PublicKey>  _mappedPublicKeys;
	private HashMap<String, String>        _certMap;
	private HashMap<String, String>		  _subjectMap;
	
	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;

    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);
			
			
			if(!privKeys.exists())
			{
				_rememberedPrivateKeys = new HashMap<PublicKey,PrivateKey>();
			}
			else
			{
				ObjectInputStream in = new ObjectInputStream(new FileInputStream(privKeys));
				// Deserialize the object
				_rememberedPrivateKeys = (HashMap<PublicKey,PrivateKey>)in.readObject();
				in.close();
			}
			
		
			File pubKeys = new File(root, PUB_KEYMAP_SER_FILE);
			
			if(!pubKeys.exists())
			{
				_mappedPublicKeys = new HashMap<PublicKey,PublicKey>();
			}
			else
			{
				ObjectInputStream in = new ObjectInputStream(new FileInputStream(pubKeys));
				// Deserialize the object
				_mappedPublicKeys = (HashMap<PublicKey,PublicKey>)in.readObject();
				in.close();
			}
			
		} catch (FileNotFoundException e) {
			// check for file exists, won't happen.
			e.printStackTrace();
		} catch (IOException e) {
			// we could correct, but this probably indicates a corruption
			// of the serialized file that we want to know about; likely
			// synchronization problems during serialization.
			e.printStackTrace();
			throw new Error(e);
		} catch (ClassNotFoundException e) {
			// serious problem.
			e.printStackTrace();
			throw new Error(e);
		}
		
		
		
		_rsaKpg.initialize(1024, _sr);
		_dsaKpg.initialize(1024, _sr);
		
		
		try
		{
			_ks = KeyStore.getInstance("JKS");
			
			reloadKeystore();
		}
		catch(FileNotFoundException fnfe)
		{
			try 
			{
				createKeystore();
			}
			catch(Exception e)
			{
				throw new Error(e);
			}
		}
		catch(Exception e)
		{
			throw new Error(e);
		}
		
		
		try {
			
			File file = new File(root, CERTMAP_SER_FILE);
			
			if(!file.exists())<commit_msg>let's use a 2048 keysize for both RSA and DSA key generation to see if that gets around the strange opera error message we're seeing on the VMs (but not locally)<commit_after>package cybervillains.ca;

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.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
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.SecureRandom;
import java.security.Security;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
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;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * This is the main entry point into the Cybervillains CA.
 * 
 * This class handles generation, storage and the persistent
 * mapping of input to duplicated certificates and mapped public 
 * keys.
 * 
 * Default setting is to immediately persist changes to the store
 * by writing out the keystore and mapping file every time a new 
 * certificate is added.  This behavior can be disabled if desired,
 * to enhance performance or allow temporary testing without modifying
 * the certificate store.
 * 
 ***************************************************************************************
 * Copyright (c) 2007, Information Security Partners, LLC
 * All rights reserved.
 *
 * This software licensed under the GPLv2, available in LICENSE.txt and at
 * http://www.gnu.org/licenses/gpl.txt
 *
 * @author <NAME>
 *
 */
public class KeyStoreManager {
	
	private final String CERTMAP_SER_FILE = "certmap.ser";
	private final String SUBJMAP_SER_FILE = "subjmap.ser";
	
	private final String EXPORTED_CERT_NAME = "cybervillainsCA.cer";
	
	private final char[] _keypassword = "password".toCharArray();
	private final char[] _keystorepass = "password".toCharArray();
	private final String _caPrivateKeystore = "cybervillainsCA.jks";
	private final String _caCertAlias = "signingCert";
	public static final String _caPrivKeyAlias = "signingCertPrivKey";

	X509Certificate _caCert;
	PrivateKey _caPrivKey;
	KeyStore _ks;
	
	private HashMap<PublicKey, PrivateKey> _rememberedPrivateKeys;
	private HashMap<PublicKey, PublicKey>  _mappedPublicKeys;
	private HashMap<String, String>        _certMap;
	private HashMap<String, String>		  _subjectMap;
	
	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;

    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);
			
			
			if(!privKeys.exists())
			{
				_rememberedPrivateKeys = new HashMap<PublicKey,PrivateKey>();
			}
			else
			{
				ObjectInputStream in = new ObjectInputStream(new FileInputStream(privKeys));
				// Deserialize the object
				_rememberedPrivateKeys = (HashMap<PublicKey,PrivateKey>)in.readObject();
				in.close();
			}
			
		
			File pubKeys = new File(root, PUB_KEYMAP_SER_FILE);
			
			if(!pubKeys.exists())
			{
				_mappedPublicKeys = new HashMap<PublicKey,PublicKey>();
			}
			else
			{
				ObjectInputStream in = new ObjectInputStream(new FileInputStream(pubKeys));
				// Deserialize the object
				_mappedPublicKeys = (HashMap<PublicKey,PublicKey>)in.readObject();
				in.close();
			}
			
		} catch (FileNotFoundException e) {
			// check for file exists, won't happen.
			e.printStackTrace();
		} catch (IOException e) {
			// we could correct, but this probably indicates a corruption
			// of the serialized file that we want to know about; likely
			// synchronization problems during serialization.
			e.printStackTrace();
			throw new Error(e);
		} catch (ClassNotFoundException e) {
			// serious problem.
			e.printStackTrace();
			throw new Error(e);
		}
		
		
		
		_rsaKpg.initialize(2048, _sr);
		_dsaKpg.initialize(2048, _sr);
		
		
		try
		{
			_ks = KeyStore.getInstance("JKS");
			
			reloadKeystore();
		}
		catch(FileNotFoundException fnfe)
		{
			try 
			{
				createKeystore();
			}
			catch(Exception e)
			{
				throw new Error(e);
			}
		}
		catch(Exception e)
		{
			throw new Error(e);
		}
		
		
		try {
			
			File file = new File(root, CERTMAP_SER_FILE);
			
			if(!file.exists())
{'fraction_non_alphanumeric': 0.10408649441084845, 'fraction_numerical': 0.004031519149715961, 'mean_word_length': 4.265315967197298, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6987946', 'n_tokens_mistral': 3695, 'n_tokens_neox': 3179, 'n_words': 847}