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.crypto.CertificateUtil; 040 041 /** 042 * The base class for all handlers for this portlet 043 * 044 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 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 protected static final String CHANGE_PASSWORD = "changePassword"; 066 067 // Name of the attribute for error message to be displayed in a page 068 protected static final String ERROR_MSG = "errorMsg"; 069 // Name of the attribute for information message to be displayed in a page 070 protected static final String INFO_MSG = "infoMsg"; 071 072 073 protected BaseKeystoreHandler(String mode, String viewName) { 074 super(mode, viewName); 075 } 076 077 public final static class KeystoreModel implements MultiPageModel { 078 public KeystoreModel(PortletRequest request) { 079 } 080 081 public void save(ActionResponse response, PortletSession session) { 082 } 083 } 084 085 public final static class KeystoreData implements Serializable { 086 private transient KeystoreInstance instance; 087 private char[] password; 088 private String[] certificates; 089 private String[] keys; 090 private Map fingerprints; 091 private Map keyPasswords; 092 093 public String getName() { 094 return instance.getKeystoreName(); 095 } 096 097 public String getType() { 098 return instance.getKeystoreType(); 099 } 100 101 public KeystoreInstance getInstance() { 102 return instance; 103 } 104 105 public void setInstance(KeystoreInstance instance) { 106 this.instance = instance; 107 } 108 109 public boolean isLockedEdit() { 110 return password == null; 111 } 112 113 public boolean isLockedUse() { 114 return instance.isKeystoreLocked(); 115 } 116 117 public String[] getCertificates() { 118 return certificates; 119 } 120 121 public String[] getKeys() { 122 return keys; 123 } 124 125 public Map getFingerprints() throws KeystoreException { 126 if(fingerprints == null) { 127 fingerprints = new HashMap(); 128 for (int i = 0; i < certificates.length; i++) { 129 String alias = certificates[i]; 130 try { 131 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 132 } catch (Exception e) { 133 log.error("Unable to generate certificate fingerprint", e); 134 } 135 } 136 for (int i = 0; i < keys.length; i++) { 137 String alias = keys[i]; 138 try { 139 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 140 } catch (Exception e) { 141 log.error("Unable to generate certificate fingerprint", e); 142 } 143 } 144 } 145 return fingerprints; 146 } 147 148 public void importTrustCert(String fileName, String alias) throws KeystoreException { 149 try { 150 // Uploading certificate using a disk file fails on Windows. Certificate text is used instead. 151 //InputStream is = new FileInputStream(fileName); 152 InputStream is = new ByteArrayInputStream(fileName.getBytes()); 153 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 154 Collection certs = cf.generateCertificates(is); 155 X509Certificate cert = (X509Certificate) certs.iterator().next(); 156 instance.importTrustCertificate(cert, alias, password); 157 String[] update = new String[certificates.length+1]; 158 System.arraycopy(certificates, 0, update, 0, certificates.length); 159 update[certificates.length] = alias; 160 certificates = update; 161 if (fingerprints != null) { 162 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 163 } 164 } catch (KeystoreException e) { 165 throw e; 166 } catch (Exception e) { 167 throw new KeystoreException("Unable to import trust certificate", e); 168 } 169 } 170 171 public void createKeyPair(String alias, String keyPassword, String keyAlgorithm, int keySize, 172 String signatureAlgorithm, int validity, String commonName, String orgUnit, 173 String organization, String locality, String state, String country) throws KeystoreException { 174 try { 175 instance.generateKeyPair(alias, password, keyPassword.toCharArray(), keyAlgorithm, keySize, 176 signatureAlgorithm, validity, commonName, orgUnit, organization, locality, state, country); 177 String[] update = new String[keys.length+1]; 178 System.arraycopy(keys, 0, update, 0, keys.length); 179 update[keys.length] = alias; 180 keys = update; 181 if (fingerprints != null) { 182 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 183 } 184 } catch (KeystoreException e) { 185 throw e; 186 } catch (Exception e) { 187 throw new KeystoreException("Unable to create key pair", e); 188 } 189 } 190 191 public Certificate getCertificate(String alias) throws KeystoreException { 192 return instance.getCertificate(alias, password); 193 } 194 195 public void unlockPrivateKey(String alias, char[] keyPassword) throws KeystoreException { 196 if(keyPasswords == null) { 197 keyPasswords = new HashMap(); 198 } 199 instance.unlockPrivateKey(alias, password, keyPassword); 200 keyPasswords.put(alias, keyPassword); 201 } 202 203 public void deleteEntry(String alias) throws KeystoreException { 204 for(int i = 0; i < keys.length; ++i) { 205 if(keys[i].equals(alias)) { 206 String[] temp = new String[keys.length-1]; 207 for(int j = 0; j < i; ++j) { 208 temp[j] = keys[j]; 209 } 210 for(int j = i+1; j < keys.length; ++j) { 211 temp[j-1] = keys[j]; 212 } 213 keys = temp; 214 break; 215 } 216 } 217 218 for(int i = 0; i < certificates.length; ++i) { 219 if(certificates[i].equals(alias)) { 220 String[] temp = new String[certificates.length-1]; 221 for(int j = 0; j < i; ++j) { 222 temp[j] = certificates[j]; 223 } 224 for(int j = i+1; j < certificates.length; ++j) { 225 temp[j-1] = certificates[j]; 226 } 227 certificates = temp; 228 break; 229 } 230 } 231 instance.deleteEntry(alias, password); 232 if(keyPasswords != null) 233 keyPasswords.remove(alias); 234 if(fingerprints != null) 235 fingerprints.remove(alias); 236 } 237 238 public void importPKCS7Certificate(String alias, String pkcs7cert) throws KeystoreException { 239 try { 240 instance.importPKCS7Certificate(alias, pkcs7cert, password); 241 fingerprints.put(alias, CertificateUtil.generateFingerprint(instance.getCertificate(alias, password), "MD5")); 242 } catch (KeystoreException e) { 243 throw e; 244 } catch (Exception e) { 245 throw new KeystoreException("Unable to import PKCS7 certificate", e); 246 } 247 } 248 249 public String generateCSR(String alias) throws KeystoreException { 250 return instance.generateCSR(alias, password); 251 } 252 253 public void unlockEdit(char[] password) throws KeystoreException { 254 this.certificates = instance.listTrustCertificates(password); 255 this.keys = instance.listPrivateKeys(password); 256 // Set password last, so that if an error occurs, the keystore 257 // still appears locked (lockedEdit == false) 258 this.password = password; 259 this.fingerprints = null; 260 } 261 262 public void lockEdit() { 263 this.password = null; 264 this.certificates = null; 265 this.keyPasswords = null; 266 this.keys = null; 267 this.fingerprints = null; 268 } 269 270 public void lockUse() throws KeystoreException { 271 instance.lockKeystore(password); 272 } 273 274 public void unlockUse(char[] password) throws KeystoreException { 275 instance.unlockKeystore(password); 276 } 277 278 public void changeKeystorePassword(char[] oldPassword, char[] newPassword) throws KeystoreException { 279 instance.changeKeystorePassword(oldPassword, newPassword); 280 this.password = newPassword; 281 } 282 283 public void changeKeyPassword(String alias, char[] keyPassword, char[] newKeyPassword) throws KeystoreException { 284 instance.changeKeyPassword(alias, password, keyPassword, newKeyPassword); 285 if(keyPasswords != null && keyPasswords.containsKey(alias)) { 286 keyPasswords.put(alias, newKeyPassword); 287 } 288 } 289 } 290 }