You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by am...@apache.org on 2006/03/23 20:20:27 UTC

svn commit: r388236 [3/3] - in /geronimo/trunk: applications/console-core/src/java/org/apache/geronimo/console/util/ applications/console-framework/src/webapp/WEB-INF/data/ applications/console-standard/ applications/console-standard/src/java/org/apach...

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreInstance.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreInstance.java?rev=388236&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreInstance.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreInstance.java Thu Mar 23 11:20:22 2006
@@ -0,0 +1,374 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  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 org.apache.geronimo.security.keystore;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.gbean.DynamicGBean;
+import org.apache.geronimo.gbean.GBeanInfo;
+import org.apache.geronimo.gbean.GBeanInfoBuilder;
+import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.util.jce.X509Principal;
+import org.apache.geronimo.util.jce.X509V1CertificateGenerator;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+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.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * Implementation of KeystoreInstance that accesses a keystore file on the
+ * local filesystem, identified by the file's name (the last component of
+ * the name only, not the full path).
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class FileKeystoreInstance implements KeystoreInstance, DynamicGBean {
+    private static final Log log = LogFactory.getLog(FileKeystoreInstance.class);
+    private final static String MAGIC_KEYSTORE_PWD_KEY = "#KeystorePW";
+    final static String JKS = "JKS";
+    private File keystoreFile;
+    private String keystoreName;
+    private Map unlockKeyPasswords = new HashMap();
+    private Kernel kernel;
+    private ObjectName objectName;
+    private char[] openPassword;
+    // The following variables are the state of the keystore, which should be chucked if the file on disk changes
+    private List privateKeys = new ArrayList();
+    private List trustCerts = new ArrayList();
+    private KeyStore keystore;
+    private long keystoreReadDate = Long.MIN_VALUE;
+
+    public FileKeystoreInstance(File keystoreFile, String keystoreName, Kernel kernel, String objectName) throws MalformedObjectNameException {
+        this.keystoreFile = keystoreFile;
+        this.keystoreName = keystoreName;
+        this.kernel = kernel;
+        this.objectName = ObjectName.getInstance(objectName);
+    }
+
+    public String getKeystoreName() {
+        return keystoreName;
+    }
+
+    public boolean unlockKeystore(char[] password) {
+        //todo: test whether password is correct and if not return false
+        try {
+            kernel.setAttribute(objectName, MAGIC_KEYSTORE_PWD_KEY, password);
+        } catch (Exception e) {
+            log.error("Unable to save keystore password for keystore '"+keystoreName+"'", e);
+            return false;
+        }
+        return true;
+    }
+
+    public void lockKeystore() {
+        try {
+            kernel.setAttribute(objectName, MAGIC_KEYSTORE_PWD_KEY, null);
+        } catch (Exception e) {
+            log.error("Unable to clear keystore password for keystore '"+keystoreName+"'", e);
+        }
+    }
+
+    public boolean isKeystoreLocked() {
+        return unlockKeyPasswords.get(MAGIC_KEYSTORE_PWD_KEY) == null;
+    }
+
+    public String[] listPrivateKeys(char[] storePassword) {
+        if(!isLoaded(storePassword)) {
+            if(!loadKeystoreData(storePassword)) {
+                return null;
+            }
+        }
+        return (String[]) privateKeys.toArray(new String[privateKeys.size()]);
+    }
+
+    public boolean unlockPrivateKey(String alias, char[] password) throws KeystoreIsLocked {
+        if(isKeystoreLocked()) {
+            throw new KeystoreIsLocked("Keystore '"+keystoreName+"' is locked!");
+        }
+        //todo: test whether password is correct and if not return false
+        try {
+            kernel.setAttribute(objectName, alias, password);
+        } catch (Exception e) {
+            log.error("Unable to save key password for key '"+alias+"' in keystore '"+keystoreName+"'", e);
+            return false;
+        }
+        return true;
+    }
+
+    public void lockPrivateKey(String alias) {
+        try {
+            kernel.setAttribute(objectName, alias, null);
+        } catch (Exception e) {
+            log.error("Unable to clear keystore password for keystore '"+keystoreName+"'", e);
+        }
+    }
+
+    public boolean isKeyUnlocked(String alias) {
+        return unlockKeyPasswords.get(alias) == null;
+    }
+
+    public String[] listTrustCertificates(char[] storePassword) {
+        if(!isLoaded(storePassword)) {
+            if(!loadKeystoreData(storePassword)) {
+                return null;
+            }
+        }
+        return (String[]) trustCerts.toArray(new String[trustCerts.size()]);
+    }
+
+    public Certificate getCertificate(String alias, char[] storePassword) {
+        if(!isLoaded(storePassword)) {
+            if(!loadKeystoreData(storePassword)) {
+                return null;
+            }
+        }
+        try {
+            return keystore.getCertificate(alias);
+        } catch (KeyStoreException e) {
+            log.error("Unable to read certificate from keystore", e);
+        }
+        return null;
+    }
+
+    public boolean importTrustCertificate(Certificate cert, String alias, char[] storePassword) {
+        if(!isLoaded(storePassword)) {
+            if(!loadKeystoreData(storePassword)) {
+                return false;
+            }
+        }
+        try {
+            keystore.setCertificateEntry(alias, cert);
+            trustCerts.add(alias);
+            return saveKeystore(storePassword);
+        } catch (KeyStoreException e) {
+            log.error("Unable to import certificate", e);
+        }
+        return false;
+    }
+
+    public boolean generateKeyPair(String alias, char[] storePassword, char[] keyPassword, String keyAlgorithm, int keySize, String signatureAlgorithm, int validity, String commonName, String orgUnit, String organization, String locality, String state, String country) {
+        try {
+            KeyPairGenerator kpgen = KeyPairGenerator.getInstance(keyAlgorithm);
+            kpgen.initialize(keySize);
+            KeyPair keyPair = kpgen.generateKeyPair();
+            X509Certificate cert = generateCertificate(keyPair.getPublic(), keyPair.getPrivate(), signatureAlgorithm,
+                    validity, commonName, orgUnit, organization, locality, state, country);
+
+            keystore.setKeyEntry(alias, keyPair.getPrivate(), keyPassword, new Certificate[] { cert });
+            privateKeys.add(alias);
+            return saveKeystore(storePassword);
+        } catch (SignatureException e) {
+            log.error("Unable to generate key pair", e);
+        } catch (InvalidKeyException e) {
+            log.error("Unable to generate key pair", e);
+        } catch (KeyStoreException e) {
+            log.error("Unable to generate key pair", e);
+        } catch (NoSuchAlgorithmException e) {
+            log.error("Unable to generate key pair", e);
+        }
+        return false;
+    }
+
+
+    private boolean saveKeystore(char[] password) {
+        try {
+            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(keystoreFile));
+            keystore.store(out, password);
+            out.flush();
+            out.close();
+            keystoreReadDate = System.currentTimeMillis();
+            return true;
+        } catch (KeyStoreException e) {
+            log.error("Unable to save keystore", e);
+        } catch (IOException e) {
+            log.error("Unable to save keystore", e);
+        } catch (NoSuchAlgorithmException e) {
+            log.error("Unable to save keystore", e);
+        } catch (CertificateException e) {
+            log.error("Unable to save keystore", e);
+        }
+        return false;
+    }
+
+    // ==================== Should only be accessed by the Kernel =================
+
+    public Object getAttribute(String name) throws Exception {
+        return unlockKeyPasswords.get(name);
+    }
+
+    public void setAttribute(String name, Object value) throws Exception {
+        unlockKeyPasswords.put(name, value);
+    }
+
+    public Object invoke(String name, Object[] arguments, String[] types) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    public static final GBeanInfo GBEAN_INFO;
+
+    static {
+        GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(FileKeystoreInstance.class, NameFactory.KEYSTORE_INSTANCE);
+        infoFactory.addAttribute("keystoreFile", File.class, true, false);
+        infoFactory.addAttribute("keystoreName", String.class, true, false);
+        infoFactory.addAttribute("kernel", Kernel.class, false);
+        infoFactory.addAttribute("objectName", String.class, false);
+        infoFactory.addInterface(KeystoreInstance.class);
+        infoFactory.setConstructor(new String[]{"keystoreFile", "keystoreName", "kernel", "objectName"});
+
+        GBEAN_INFO = infoFactory.getBeanInfo();
+    }
+
+    public static GBeanInfo getGBeanInfo() {
+        return GBEAN_INFO;
+    }
+
+    // ==================== Internals =====================
+
+    private boolean loadKeystoreData(char[] password) {
+        try {
+            keystoreReadDate = System.currentTimeMillis();
+            privateKeys.clear();
+            trustCerts.clear();
+            if(keystore == null) {
+                keystore = KeyStore.getInstance(JKS);
+            }
+            InputStream in = new BufferedInputStream(new FileInputStream(keystoreFile));
+            keystore.load(in, password);
+            in.close();
+            openPassword = password;
+            Enumeration aliases = keystore.aliases();
+            while (aliases.hasMoreElements()) {
+                String alias = (String) aliases.nextElement();
+                if(keystore.isKeyEntry(alias)) {
+                    privateKeys.add(alias);
+                } else if(keystore.isCertificateEntry(alias)) {
+                    trustCerts.add(alias);
+                }
+            }
+            return true;
+        } catch (KeyStoreException e) {
+            log.error("Unable to open keystore with provided password", e);
+        } catch (IOException e) {
+            log.error("Unable to open keystore with provided password", e);
+        } catch (NoSuchAlgorithmException e) {
+            log.error("Unable to open keystore with provided password", e);
+        } catch (CertificateException e) {
+            log.error("Unable to open keystore with provided password", e);
+        }
+        return false;
+    }
+
+    private char[] getKeystorePassword() {
+        return (char[])unlockKeyPasswords.get(MAGIC_KEYSTORE_PWD_KEY);
+    }
+
+    private boolean isLoaded(char[] password) {
+        if(openPassword == null || openPassword.length != password.length) {
+            return false;
+        }
+        if(keystoreReadDate < keystoreFile.lastModified()) {
+            return false;
+        }
+        for (int i = 0; i < password.length; i++) {
+            if(password[i] != openPassword[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private X509Certificate generateCertificate(PublicKey publicKey, PrivateKey privateKey, String algorithm, int validity, String commonName, String orgUnit, String organization, String locality, String state, String country) throws SignatureException, InvalidKeyException {
+        X509V1CertificateGenerator certgen = new X509V1CertificateGenerator();
+        Vector order = new Vector();
+        Hashtable attrmap = new Hashtable();
+
+        if (commonName != null) {
+            attrmap.put(X509Principal.CN, commonName);
+            order.add(X509Principal.CN);
+        }
+
+        if (orgUnit != null) {
+            attrmap.put(X509Principal.OU, orgUnit);
+            order.add(X509Principal.OU);
+        }
+
+        if (organization != null) {
+            attrmap.put(X509Principal.O, organization);
+            order.add(X509Principal.O);
+        }
+
+        if (locality != null) {
+            attrmap.put(X509Principal.L, locality);
+            order.add(X509Principal.L);
+        }
+
+        if (state != null) {
+            attrmap.put(X509Principal.ST, state);
+            order.add(X509Principal.ST);
+        }
+
+        if (country != null) {
+            attrmap.put(X509Principal.C, country);
+            order.add(X509Principal.C);
+        }
+
+        X509Principal issuerDN = new X509Principal(order, attrmap);
+
+        // validity
+        long curr = System.currentTimeMillis();
+        long untill = curr + (long) validity * 24 * 60 * 60 * 1000;
+
+        certgen.setNotBefore(new Date(curr));
+        certgen.setNotAfter(new Date(untill));
+        certgen.setIssuerDN(issuerDN);
+        certgen.setSubjectDN(issuerDN);
+        certgen.setPublicKey(publicKey);
+        certgen.setSignatureAlgorithm(algorithm);
+        certgen.setSerialNumber(new BigInteger(String.valueOf(curr)));
+
+        // make certificate
+        return certgen.generateX509Certificate(privateKey);
+    }
+}

Propchange: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreInstance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreManager.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreManager.java?rev=388236&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreManager.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreManager.java Thu Mar 23 11:20:22 2006
@@ -0,0 +1,287 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  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 org.apache.geronimo.security.keystore;
+
+import org.apache.geronimo.system.serverinfo.ServerInfo;
+import org.apache.geronimo.gbean.GBeanInfo;
+import org.apache.geronimo.gbean.GBeanInfoBuilder;
+import org.apache.geronimo.gbean.GBeanLifecycle;
+import org.apache.geronimo.gbean.GBeanData;
+import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
+import org.apache.geronimo.j2ee.management.impl.Util;
+import org.apache.geronimo.kernel.config.EditableConfigurationManager;
+import org.apache.geronimo.kernel.config.ConfigurationUtil;
+import org.apache.geronimo.kernel.config.Configuration;
+import org.apache.geronimo.kernel.config.InvalidConfigException;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.util.jce.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.net.ServerSocketFactory;
+import javax.management.ObjectName;
+import javax.management.MalformedObjectNameException;
+import java.io.File;
+import java.io.OutputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Date;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.KeyPairGenerator;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.security.PrivateKey;
+import java.security.SignatureException;
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.security.cert.Certificate;
+import java.math.BigInteger;
+
+/**
+ * An implementation of KeystoreManager that assumes every file in a specified
+ * directory is a keystore.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class FileKeystoreManager implements KeystoreManager, GBeanLifecycle {
+    private static final Log log = LogFactory.getLog(FileKeystoreManager.class);
+    private File directory;
+    private ServerInfo serverInfo;
+    private URI configuredDir;
+    private Collection keystores;
+    private ObjectName mine;
+    private Kernel kernel;
+
+    public FileKeystoreManager(URI keystoreDir, ServerInfo serverInfo, Collection keystores, String objectName, Kernel kernel) throws MalformedObjectNameException {
+        configuredDir = keystoreDir;
+        this.serverInfo = serverInfo;
+        this.keystores = keystores;
+        mine = ObjectName.getInstance(objectName);
+        this.kernel = kernel;
+    }
+
+    public void doStart() throws Exception {
+        URI rootURI;
+        if (serverInfo != null) {
+            rootURI = serverInfo.resolve(configuredDir);
+        } else {
+            rootURI = configuredDir;
+        }
+        if (!rootURI.getScheme().equals("file")) {
+            throw new IllegalStateException("FileKeystoreManager must have a root that's a local directory (not " + rootURI + ")");
+        }
+        directory = new File(rootURI);
+        if (!directory.exists() || !directory.isDirectory() || !directory.canRead()) {
+            throw new IllegalStateException("FileKeystoreManager must have a root that's a valid readable directory (not " + directory.getAbsolutePath() + ")");
+        }
+        log.debug("Keystore directory is " + directory.getAbsolutePath());
+    }
+
+    public void doStop() throws Exception {
+    }
+
+    public void doFail() {
+    }
+
+    public String[] listKeystores() {
+        File[] files = directory.listFiles();
+        List list = new ArrayList();
+        for (int i = 0; i < files.length; i++) {
+            File file = files[i];
+            if(file.canRead() && !file.isDirectory()) {
+                list.add(file.getName());
+            }
+        }
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+
+    public KeystoreInstance getKeystore(String name) {
+        for (Iterator it = keystores.iterator(); it.hasNext();) {
+            KeystoreInstance instance = (KeystoreInstance) it.next();
+            if(instance.getKeystoreName().equals(name)) {
+                return instance;
+            }
+        }
+        File test = new File(directory, name);
+        if(!test.exists() || !test.canRead()) {
+            throw new IllegalArgumentException("Cannot access keystore "+test.getAbsolutePath()+"!");
+        }
+        ObjectName oName;
+        Map props = mine.getKeyPropertyList();
+        Hashtable revised = new Hashtable(props);
+        revised.put(NameFactory.J2EE_NAME, name);
+        revised.put(NameFactory.J2EE_TYPE, NameFactory.KEYSTORE_INSTANCE);
+        try {
+            oName = ObjectName.getInstance(mine.getDomain(), revised);
+        } catch (MalformedObjectNameException e) {
+            throw new IllegalArgumentException("Invalid keystore name '"+name+"' ("+e.getMessage()+")");
+        }
+        GBeanData data = new GBeanData(oName, FileKeystoreInstance.getGBeanInfo());
+        data.setAttribute("keystoreFile", test);
+        data.setAttribute("keystoreName", name);
+        EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
+        if(mgr != null) {
+            try {
+                ObjectName config = Util.getConfiguration(kernel, mine);
+                mgr.addGBeanToConfiguration(Configuration.getConfigurationID(config), data, true);
+                return (KeystoreInstance) kernel.getProxyManager().createProxy(oName, KeystoreInstance.class);
+            } catch (InvalidConfigException e) {
+                log.error("Should never happen", e);
+                throw new IllegalStateException("Unable to add Keystore GBean ("+e.getMessage()+")");
+            } catch (URISyntaxException e) {
+                log.error("Should never happen", e);
+                throw new IllegalStateException("Unable to add Keystore GBean ("+e.getMessage()+")");
+            } finally {
+                ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
+            }
+        } else {
+            log.warn("The ConfigurationManager in the kernel does not allow changes at runtime");
+            return null;
+        }
+    }
+
+    public ServerSocketFactory createSSLFactory(String keyStore, String keyAlias, String trustStore) throws KeystoreIsLocked, KeyIsLocked {
+        throw new UnsupportedOperationException();
+    }
+
+    public KeystoreInstance createKeystore(String name, char[] password) {
+        File test = new File(directory, name);
+        if(test.exists()) {
+            throw new IllegalArgumentException("Keystore already exists "+test.getAbsolutePath()+"!");
+        }
+        try {
+            KeyStore keystore = KeyStore.getInstance(FileKeystoreInstance.JKS);
+            keystore.load(null, password);
+            OutputStream out = new BufferedOutputStream(new FileOutputStream(test));
+            keystore.store(out, password);
+            out.flush();
+            out.close();
+            return getKeystore(name);
+        } catch (KeyStoreException e) {
+            log.error("Unable to create keystore", e);
+        } catch (IOException e) {
+            log.error("Unable to create keystore", e);
+        } catch (NoSuchAlgorithmException e) {
+            log.error("Unable to create keystore", e);
+        } catch (CertificateException e) {
+            log.error("Unable to create keystore", e);
+        }
+        return null;
+    }
+
+    public static final GBeanInfo GBEAN_INFO;
+
+    static {
+        GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(FileKeystoreManager.class);
+        infoFactory.addAttribute("keystoreDir", URI.class, true);
+        infoFactory.addAttribute("objectName", String.class, false);
+        infoFactory.addAttribute("kernel", Kernel.class, false);
+        infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean");
+        infoFactory.addReference("KeystoreInstances", KeystoreInstance.class, NameFactory.KEYSTORE_INSTANCE);
+        infoFactory.addInterface(KeystoreManager.class);
+        infoFactory.setConstructor(new String[]{"keystoreDir", "ServerInfo", "KeystoreInstances", "objectName", "kernel"});
+
+        GBEAN_INFO = infoFactory.getBeanInfo();
+    }
+
+    public static GBeanInfo getGBeanInfo() {
+        return GBEAN_INFO;
+    }
+
+    // ===================== Move this to a unitiy class or something ====================
+
+    public X509Certificate generateCert(PublicKey publicKey,
+                                        PrivateKey privateKey, String sigalg, int validity, String cn,
+                                        String ou, String o, String l, String st, String c)
+            throws java.security.SignatureException,
+            java.security.InvalidKeyException {
+        X509V1CertificateGenerator certgen = new X509V1CertificateGenerator();
+
+        // issuer dn
+        Vector order = new Vector();
+        Hashtable attrmap = new Hashtable();
+
+        if (cn != null) {
+            attrmap.put(X509Principal.CN, cn);
+            order.add(X509Principal.CN);
+        }
+
+        if (ou != null) {
+            attrmap.put(X509Principal.OU, ou);
+            order.add(X509Principal.OU);
+        }
+
+        if (o != null) {
+            attrmap.put(X509Principal.O, o);
+            order.add(X509Principal.O);
+        }
+
+        if (l != null) {
+            attrmap.put(X509Principal.L, l);
+            order.add(X509Principal.L);
+        }
+
+        if (st != null) {
+            attrmap.put(X509Principal.ST, st);
+            order.add(X509Principal.ST);
+        }
+
+        if (c != null) {
+            attrmap.put(X509Principal.C, c);
+            order.add(X509Principal.C);
+        }
+
+        X509Principal issuerDN = new X509Principal(order, attrmap);
+        certgen.setIssuerDN(issuerDN);
+
+        // validity
+        long curr = System.currentTimeMillis();
+        long untill = curr + (long) validity * 24 * 60 * 60 * 1000;
+
+        certgen.setNotBefore(new Date(curr));
+        certgen.setNotAfter(new Date(untill));
+
+        // subject dn
+        certgen.setSubjectDN(issuerDN);
+
+        // public key
+        certgen.setPublicKey(publicKey);
+
+        // signature alg
+        certgen.setSignatureAlgorithm(sigalg);
+
+        // serial number
+        certgen.setSerialNumber(new BigInteger(String.valueOf(curr)));
+
+        // make certificate
+        X509Certificate cert = certgen.generateX509Certificate(privateKey);
+        return cert;
+    }
+}

Propchange: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/FileKeystoreManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeyIsLocked.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeyIsLocked.java?rev=388236&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeyIsLocked.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeyIsLocked.java Thu Mar 23 11:20:22 2006
@@ -0,0 +1,33 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  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 org.apache.geronimo.security.keystore;
+
+/**
+ * Exception indicating that the private key you tried to do something with is
+ * locked.  It must be unlocked before it can be used in this way.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class KeyIsLocked extends Exception {
+    public KeyIsLocked(String message) {
+        super(message);
+    }
+
+    public KeyIsLocked(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Propchange: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeyIsLocked.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreInstance.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreInstance.java?rev=388236&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreInstance.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreInstance.java Thu Mar 23 11:20:22 2006
@@ -0,0 +1,133 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  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 org.apache.geronimo.security.keystore;
+
+import java.security.cert.Certificate;
+
+/**
+ * Management interface for dealing with a specific Keystore
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public interface KeystoreInstance {
+    /**
+     * Returns the name of the keystore as known to the keystore manager.
+     */
+    public String getKeystoreName();
+
+    /**
+     * Saves a password to access the keystore as a whole.  This means that any
+     * other server component can use this keystore to create a socket factory.
+     * However, the relevant private key in the keystore must also be unlocked.
+     *
+     * @return True if the keystore was unlocked successfully
+     */
+    public boolean unlockKeystore(char[] password);
+
+    /**
+     * Clears any saved password, meaning this keystore cannot be used by other
+     * server components.  You can still query and update it by passing the
+     * password to other functions,
+     */
+    public void lockKeystore();
+
+    /**
+     * Checks whether this keystore is unlocked, which is to say, available for
+     * other components to use to generate socket factories.
+     * Does not check whether the unlock password is actually correct.
+     */
+    public boolean isKeystoreLocked();
+
+    /**
+     * Gets the aliases of all private key entries in the keystore
+     *
+     * @param storePassword Used to open the keystore.
+     */
+    public String[] listPrivateKeys(char[] storePassword);
+
+    /**
+     * Saves a password to access a private key.  This means that if the
+     * keystore is also unlocked, any server component can create an SSL
+     * socket factory using this private key.  Note that the keystore
+     * must be unlocked before this can be called.
+     *
+     * @param password The password to save.
+     * @return True if the key was unlocked successfully
+     */
+    public boolean unlockPrivateKey(String alias, char[] password) throws KeystoreIsLocked;
+
+    /**
+     * Clears any saved password for the specified private key, meaning this
+     * key cannot be used for a socket factory by other server components.
+     * You can still query and update it by passing the password to other
+     * functions,
+     */
+    public void lockPrivateKey(String alias);
+
+    /**
+     * Checks whether the specified private key is unlocked, which is to say,
+     * available for other components to use to generate socket factories.
+     * Does not check whether the unlock password is actually correct.
+     */
+    public boolean isKeyUnlocked(String alias);
+
+    /**
+     * Gets the aliases of all trusted certificate entries in the keystore.
+     *
+     * @param storePassword Used to open the keystore.
+     */
+    public String[] listTrustCertificates(char[] storePassword);
+
+    /**
+     * Gets a particular certificate from the keystore.  This may be a trust
+     * certificate or the certificate corresponding to a particular private
+     * key.
+     * @param alias The certificate to look at
+     * @param storePassword The password to use to access the keystore
+     */
+    public Certificate getCertificate(String alias, char[] storePassword);
+
+    /**
+     * Adds a certificate to this keystore as a trusted certificate.
+     * @param cert The certificate to add
+     * @param alias The alias to list the certificate under
+     * @param storePassword The password for the keystore
+     * @return True if the certificate was imported successfully
+     */
+    public boolean importTrustCertificate(Certificate cert, String alias, char[] storePassword);
+
+    /**
+     * Generates a new private key and certificate pair in this keystore.
+     * @param alias The alias to store the new key pair under
+     * @param storePassword The password used to access the keystore
+     * @param keyPassword The password to use to protect the new key
+     * @param keyAlgorithm The algorithm used for the key (e.g. RSA)
+     * @param keySize The number of bits in the key (e.g. 1024)
+     * @param signatureAlgorithm The algorithm used to sign the key (e.g. MD5withRSA)
+     * @param validity The number of days the certificate should be valid for
+     * @param commonName The CN portion of the identity on the certificate
+     * @param orgUnit The OU portion of the identity on the certificate
+     * @param organization The O portion of the identity on the certificate
+     * @param locality The L portion of the identity on the certificate
+     * @param state The ST portion of the identity on the certificate
+     * @param country The C portion of the identity on the certificate
+     * @return True if the key was generated successfully
+     */
+    public boolean generateKeyPair(String alias, char[] storePassword, char[] keyPassword, String keyAlgorithm, int keySize,
+                                   String signatureAlgorithm, int validity, String commonName, String orgUnit,
+                                   String organization, String locality, String state, String country);
+}

Propchange: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreInstance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreIsLocked.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreIsLocked.java?rev=388236&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreIsLocked.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreIsLocked.java Thu Mar 23 11:20:22 2006
@@ -0,0 +1,33 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  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 org.apache.geronimo.security.keystore;
+
+/**
+ * Exception indicating that the keystore you tried to do something with is
+ * locked.  It must be unlocked before it can be used in this way.
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class KeystoreIsLocked extends Exception {
+    public KeystoreIsLocked(String message) {
+        super(message);
+    }
+
+    public KeystoreIsLocked(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

Propchange: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreIsLocked.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreManager.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreManager.java?rev=388236&view=auto
==============================================================================
--- geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreManager.java (added)
+++ geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreManager.java Thu Mar 23 11:20:22 2006
@@ -0,0 +1,70 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  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 org.apache.geronimo.security.keystore;
+
+import javax.net.ServerSocketFactory;
+
+/**
+ * Management interface for working with keystores.  Mostly this is used to
+ * identify KeystoreInstances to work with individual keystores.
+ *
+ * @see KeystoreInstance
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public interface KeystoreManager {
+    /**
+     * Gets the names of the keystores available in the server.
+     */
+    public String[] listKeystores();
+
+    /**
+     * Gets a specific keystore instance by name
+     * @param name The name as provided by listKeystores
+     */
+    public KeystoreInstance getKeystore(String name);
+
+    /**
+     * Gets a ServerSocketFactory using one Keystore to access the private key
+     * and another to provide the list of trusted certificate authorities.
+     * @param keyStore The key keystore name as provided by listKeystores.  The
+     *                 KeystoreInstance for this keystore must be unlocked.
+     * @param keyAlias The name of the private key in the keystore.  The
+     *                 KeystoreInstance for this keystore must have unlocked
+     *                 this key.
+     * @param trustStore The trust keystore name as provided by listKeystores.
+     *                   The KeystoreInstance for this keystore must have
+     *                   unlocked this key.
+     *
+     * @throws KeystoreIsLocked Occurs when the requested key keystore cannot
+     *                          be used because it has not been unlocked.
+     * @throws KeyIsLocked Occurs when the requested private key in the key
+     *                     keystore cannot be used because it has not been
+     *                     unlocked.
+     */
+    public ServerSocketFactory createSSLFactory(String keyStore, String keyAlias, String trustStore)
+            throws KeystoreIsLocked, KeyIsLocked;
+
+    /**
+     * Creates a new, empty keystore.  The name should be a valid file name
+     * with no path separator characters.
+     *
+     * @param name The name of the keystore to create
+     * @param password The password to use to protect the new keystore
+     */
+    public KeystoreInstance createKeystore(String name, char[] password);
+}

Propchange: geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/keystore/KeystoreManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: geronimo/trunk/modules/util/src/java/org/apache/geronimo/util/CertificateUtil.java
URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/util/src/java/org/apache/geronimo/util/CertificateUtil.java?rev=388236&view=auto
==============================================================================
--- geronimo/trunk/modules/util/src/java/org/apache/geronimo/util/CertificateUtil.java (added)
+++ geronimo/trunk/modules/util/src/java/org/apache/geronimo/util/CertificateUtil.java Thu Mar 23 11:20:22 2006
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  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 org.apache.geronimo.util;
+
+import org.apache.geronimo.util.encoders.HexEncoder;
+
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Various utility functions for dealing with X.509 certificates
+ *
+ * @version $Rev: 46019 $ $Date: 2004-09-14 05:56:06 -0400 (Tue, 14 Sep 2004) $
+ */
+public class CertificateUtil {
+    public static String generateFingerprint(Certificate cert, String digestAlgorithm) throws NoSuchAlgorithmException, CertificateEncodingException, IOException {
+        MessageDigest md = MessageDigest.getInstance(digestAlgorithm);
+        byte[] digest = md.digest(cert.getEncoded());
+        ByteArrayOutputStream out = new ByteArrayOutputStream(digest.length*2);
+        new HexEncoder().encode(digest, 0, digest.length, out);
+        String all = new String(out.toByteArray(), "US-ASCII").toUpperCase();
+        Matcher matcher = Pattern.compile("..").matcher(all);
+        StringBuffer buf = new StringBuffer();
+        while(matcher.find()) {
+            if(buf.length() > 0) {
+                buf.append(":");
+            }
+            buf.append(matcher.group());
+        }
+        return buf.toString();
+    }
+}

Propchange: geronimo/trunk/modules/util/src/java/org/apache/geronimo/util/CertificateUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native