001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.console.keystores; 018 019 import java.io.ByteArrayInputStream; 020 import java.io.InputStream; 021 import java.io.Serializable; 022 import java.security.cert.Certificate; 023 import java.security.cert.CertificateFactory; 024 import java.security.cert.X509Certificate; 025 import java.util.Collection; 026 import java.util.HashMap; 027 import java.util.Map; 028 029 import javax.portlet.ActionResponse; 030 import javax.portlet.PortletRequest; 031 import javax.portlet.PortletSession; 032 033 import org.apache.commons.logging.Log; 034 import org.apache.commons.logging.LogFactory; 035 import org.apache.geronimo.console.MultiPageAbstractHandler; 036 import org.apache.geronimo.console.MultiPageModel; 037 import org.apache.geronimo.management.geronimo.KeystoreException; 038 import org.apache.geronimo.management.geronimo.KeystoreInstance; 039 import org.apache.geronimo.util.CertificateUtil; 040 041 /** 042 * The base class for all handlers for this portlet 043 * 044 * @version $Rev: 477134 $ $Date: 2006-11-20 05:19:42 -0500 (Mon, 20 Nov 2006) $ 045 */ 046 public abstract class BaseKeystoreHandler extends MultiPageAbstractHandler { 047 private final static Log log = LogFactory.getLog(BaseKeystoreHandler.class); 048 protected static final String KEYSTORE_DATA_PREFIX="org.apache.geronimo.keystore."; 049 protected static final String LIST_MODE = "list"; 050 protected static final String UNLOCK_KEYSTORE_FOR_EDITING = "unlockEdit"; 051 protected static final String UNLOCK_KEYSTORE_FOR_USAGE = "unlockKeystore"; 052 protected static final String UNLOCK_KEY = "unlockKey"; 053 protected static final String LOCK_KEYSTORE_FOR_EDITING = "lockEdit"; 054 protected static final String LOCK_KEYSTORE_FOR_USAGE = "lockKeystore"; 055 protected static final String CREATE_KEYSTORE = "createKeystore"; 056 protected static final String VIEW_KEYSTORE = "viewKeystore"; 057 protected static final String UPLOAD_CERTIFICATE = "uploadCertificate"; 058 protected static final String CONFIRM_CERTIFICATE = "confirmCertificate"; 059 protected static final String CONFIGURE_KEY = "configureKey"; 060 protected static final String CONFIRM_KEY = "confirmKey"; 061 protected static final String CERTIFICATE_DETAILS = "certificateDetails"; 062 protected static final String GENERATE_CSR = "generateCSR"; 063 protected static final String IMPORT_CA_REPLY = "importCAReply"; 064 protected static final String DELETE_ENTRY = "deleteEntry"; 065 066 // Name of the attribute for error message to be displayed in a page 067 protected static final String ERROR_MSG = "errorMsg"; 068 // Name of the attribute for information message to be displayed in a page 069 protected static final String INFO_MSG = "infoMsg"; 070 071 072 protected BaseKeystoreHandler(String mode, String viewName) { 073 super(mode, viewName); 074 } 075 076 public final static class KeystoreModel implements MultiPageModel { 077 public KeystoreModel(PortletRequest request) { 078 } 079 080 public void save(ActionResponse response, PortletSession session) { 081 } 082 } 083 084 public final static class KeystoreData implements Serializable { 085 private transient KeystoreInstance instance; 086 private char[] password; 087 private String[] certificates; 088 private String[] keys; 089 private Map fingerprints; 090 private Map keyPasswords; 091 092 public String getName() { 093 return instance.getKeystoreName(); 094 } 095 096 public KeystoreInstance getInstance() { 097 return instance; 098 } 099 100 public void setInstance(KeystoreInstance instance) { 101 this.instance = instance; 102 } 103 104 public boolean isLockedEdit() { 105 return password == null; 106 } 107 108 public boolean isLockedUse() { 109 return instance.isKeystoreLocked(); 110 } 111 112 public String[] getCertificates() { 113 return certificates; 114 } 115 116 public String[] getKeys() { 117 return keys; 118 } 119 120 public Map getFingerprints() throws KeystoreException { 121 if(fingerprints == null) { 122 fingerprints = new HashMap(); 123 for (int i = 0; i < certificates.length; i++) { 124 String alias = certificates[i]; 125 try { 126 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 127 } catch (Exception e) { 128 log.error("Unable to generate certificate fingerprint", e); 129 } 130 } 131 for (int i = 0; i < keys.length; i++) { 132 String alias = keys[i]; 133 try { 134 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 135 } catch (Exception e) { 136 log.error("Unable to generate certificate fingerprint", e); 137 } 138 } 139 } 140 return fingerprints; 141 } 142 143 public void importTrustCert(String fileName, String alias) throws KeystoreException { 144 try { 145 // Uploading certificate using a disk file fails on Windows. Certificate text is used instead. 146 //InputStream is = new FileInputStream(fileName); 147 InputStream is = new ByteArrayInputStream(fileName.getBytes()); 148 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 149 Collection certs = cf.generateCertificates(is); 150 X509Certificate cert = (X509Certificate) certs.iterator().next(); 151 instance.importTrustCertificate(cert, alias, password); 152 String[] update = new String[certificates.length+1]; 153 System.arraycopy(certificates, 0, update, 0, certificates.length); 154 update[certificates.length] = alias; 155 certificates = update; 156 if (fingerprints != null) { 157 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 158 } 159 } catch (KeystoreException e) { 160 throw e; 161 } catch (Exception e) { 162 throw new KeystoreException("Unable to import trust certificate", e); 163 } 164 } 165 166 public void createKeyPair(String alias, String keyPassword, String keyAlgorithm, int keySize, 167 String signatureAlgorithm, int validity, String commonName, String orgUnit, 168 String organization, String locality, String state, String country) throws KeystoreException { 169 try { 170 instance.generateKeyPair(alias, password, keyPassword.toCharArray(), keyAlgorithm, keySize, 171 signatureAlgorithm, validity, commonName, orgUnit, organization, locality, state, country); 172 String[] update = new String[keys.length+1]; 173 System.arraycopy(keys, 0, update, 0, keys.length); 174 update[keys.length] = alias; 175 keys = update; 176 if (fingerprints != null) { 177 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 178 } 179 } catch (KeystoreException e) { 180 throw e; 181 } catch (Exception e) { 182 throw new KeystoreException("Unable to create key pair", e); 183 } 184 } 185 186 public Certificate getCertificate(String alias) throws KeystoreException { 187 return instance.getCertificate(alias, password); 188 } 189 190 public void unlockPrivateKey(String alias, char[] keyPassword) throws KeystoreException { 191 if(keyPasswords == null) { 192 keyPasswords = new HashMap(); 193 } 194 instance.unlockPrivateKey(alias, password, keyPassword); 195 keyPasswords.put(alias, keyPassword); 196 } 197 198 public void deleteEntry(String alias) throws KeystoreException { 199 for(int i = 0; i < keys.length; ++i) { 200 if(keys[i].equals(alias)) { 201 String[] temp = new String[keys.length-1]; 202 for(int j = 0; j < i; ++j) { 203 temp[j] = keys[j]; 204 } 205 for(int j = i+1; j < keys.length; ++j) { 206 temp[j-1] = keys[j]; 207 } 208 keys = temp; 209 break; 210 } 211 } 212 213 for(int i = 0; i < certificates.length; ++i) { 214 if(certificates[i].equals(alias)) { 215 String[] temp = new String[certificates.length-1]; 216 for(int j = 0; j < i; ++j) { 217 temp[j] = certificates[j]; 218 } 219 for(int j = i+1; j < certificates.length; ++j) { 220 temp[j-1] = certificates[j]; 221 } 222 certificates = temp; 223 break; 224 } 225 } 226 instance.deleteEntry(alias, password); 227 if(keyPasswords != null) 228 keyPasswords.remove(alias); 229 if(fingerprints != null) 230 fingerprints.remove(alias); 231 } 232 233 public void importPKCS7Certificate(String alias, String pkcs7cert) throws KeystoreException { 234 try { 235 instance.importPKCS7Certificate(alias, pkcs7cert, password); 236 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 237 } catch (KeystoreException e) { 238 throw e; 239 } catch (Exception e) { 240 throw new KeystoreException("Unable to import PKCS7 certificate", e); 241 } 242 } 243 244 public String generateCSR(String alias) throws KeystoreException { 245 return instance.generateCSR(alias, password); 246 } 247 248 public void unlockEdit(char[] password) throws KeystoreException { 249 this.certificates = instance.listTrustCertificates(password); 250 this.keys = instance.listPrivateKeys(password); 251 // Set password last, so that if an error occurs, the keystore 252 // still appears locked (lockedEdit == false) 253 this.password = password; 254 this.fingerprints = null; 255 } 256 257 public void lockEdit() { 258 this.password = null; 259 this.certificates = null; 260 this.keyPasswords = null; 261 this.keys = null; 262 this.fingerprints = null; 263 } 264 265 public void lockUse() throws KeystoreException { 266 instance.lockKeystore(password); 267 } 268 269 public void unlockUse(char[] password) throws KeystoreException { 270 instance.unlockKeystore(password); 271 } 272 273 } 274 }