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