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    }