package org.owasp.webscarab.httpclient; import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; import org.owasp.webscarab.util.Encoding; /** * * @author Frank Cornelis */ public abstract class AbstractCertificateRepository implements CertificateRepository { protected Logger _logger = Logger.getLogger(getClass().getName()); private String _defaultKey = null; private Map _aliasPasswords = new HashMap(); protected List _keyStores = new ArrayList(); protected Map _keyStoreDescriptions = new HashMap(); public int getKeyStoreCount() { return _keyStores.size(); } public String getKeyStoreDescription(int keystoreIndex) { return (String) _keyStoreDescriptions.get(_keyStores.get(keystoreIndex)); } public int getAliasCount(int keystoreIndex) { return getAliases((KeyStore) _keyStores.get(keystoreIndex)).length; } public String getAliasAt(int keystoreIndex, int aliasIndex) { return getAliases((KeyStore) _keyStores.get(keystoreIndex))[aliasIndex]; } private String[] getAliases(KeyStore ks) { List aliases = new ArrayList(); try { Enumeration en = ks.aliases(); while (en.hasMoreElements()) { String alias = (String) en.nextElement(); if (ks.isKeyEntry(alias)) { aliases.add(alias); } } } catch (KeyStoreException kse) { kse.printStackTrace(); } return (String[]) aliases.toArray(new String[0]); } public Certificate getCertificate(int keystoreIndex, int aliasIndex) { try { KeyStore ks = (KeyStore) _keyStores.get(keystoreIndex); String alias = getAliasAt(keystoreIndex, aliasIndex); return ks.getCertificate(alias); } catch (Exception e) { return null; } } public String getFingerPrint(Certificate cert) throws KeyStoreException { if (!(cert instanceof X509Certificate)) { return null; } StringBuffer buff = new StringBuffer(); X509Certificate x509 = (X509Certificate) cert; try { String fingerprint = Encoding.hashMD5(cert.getEncoded()); for (int i = 0; i < fingerprint.length(); i += 2) { buff.append(fingerprint.substring(i, i + 1)).append(":"); } buff.deleteCharAt(buff.length() - 1); } catch (CertificateEncodingException e) { throw new KeyStoreException(e.getMessage()); } String dn = x509.getSubjectDN().getName(); _logger.info("Fingerprint is " + buff.toString().toUpperCase()); return buff.toString().toUpperCase() + " " + dn; } public boolean isProviderAvailable(String type) { try { if (type.equals("PKCS11")) { Class.forName("sun.security.pkcs11.SunPKCS11"); } } catch (Throwable t) { return false; } return true; } public boolean isKeyUnlocked(int keystoreIndex, int aliasIndex) { KeyStore ks = (KeyStore) _keyStores.get(keystoreIndex); String alias = getAliasAt(keystoreIndex, aliasIndex); Map pwmap = (Map) _aliasPasswords.get(ks); if (pwmap == null) { return false; } return pwmap.containsKey(alias); } public void setDefaultKey(String fingerprint) { _defaultKey = fingerprint; } public String getDefaultKey() { return _defaultKey; } private int addKeyStore(KeyStore ks, String description) { int index = _keyStores.indexOf(ks); if (index == -1) { _keyStores.add(ks); index = _keyStores.size() - 1; } _keyStoreDescriptions.put(ks, description); return index; } public int initPKCS11(String name, String library, int slotListIndex, String kspassword) { try { if (!isProviderAvailable("PKCS11")) { return -1; } // Set up a virtual config file StringBuffer cardConfig = new StringBuffer(); cardConfig.append("name = ").append(name).append("\n"); cardConfig.append("library = ").append(library).append("\n"); cardConfig.append("slotListIndex = ").append(Integer.toString(slotListIndex)).append("\n"); InputStream is = new ByteArrayInputStream(cardConfig.toString().getBytes()); // create the provider Class pkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11"); Constructor c = pkcs11Class.getConstructor(new Class[]{InputStream.class}); Provider pkcs11 = (Provider) c.newInstance(new Object[]{is}); Security.addProvider(pkcs11); // init the key store KeyStore ks = KeyStore.getInstance("PKCS11"); ks.load(null, kspassword == null ? null : kspassword.toCharArray()); return addKeyStore(ks, name); } catch (Exception e) { System.err.println("Error instantiating the PKCS11 provider"); e.printStackTrace(); return -1; } } public int loadPKCS12Certificate(String filename, String ksPassword) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException { // Open the file InputStream is = new FileInputStream(filename); // create the keystore KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(is, ksPassword == null ? null : ksPassword.toCharArray()); return addKeyStore(ks, "PKCS#12 - " + filename); } }