001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.geronimo.console.ca;
019    
020    import java.io.IOException;
021    import java.math.BigInteger;
022    import java.net.URI;
023    import java.text.DateFormat;
024    import java.text.SimpleDateFormat;
025    import java.util.Date;
026    
027    import javax.portlet.ActionRequest;
028    import javax.portlet.ActionResponse;
029    import javax.portlet.PortletException;
030    import javax.portlet.PortletRequest;
031    import javax.portlet.RenderRequest;
032    import javax.portlet.RenderResponse;
033    
034    import org.apache.commons.logging.Log;
035    import org.apache.commons.logging.LogFactory;
036    import org.apache.geronimo.console.MultiPageModel;
037    import org.apache.geronimo.console.util.PortletManager;
038    import org.apache.geronimo.gbean.AbstractName;
039    import org.apache.geronimo.gbean.GBeanData;
040    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
041    import org.apache.geronimo.kernel.Naming;
042    import org.apache.geronimo.kernel.proxy.GeronimoManagedBean;
043    import org.apache.geronimo.kernel.repository.Artifact;
044    import org.apache.geronimo.management.geronimo.CertificationAuthority;
045    import org.apache.geronimo.management.geronimo.KeystoreInstance;
046    import org.apache.geronimo.security.ca.FileCertificateRequestStore;
047    import org.apache.geronimo.security.ca.FileCertificateStore;
048    import org.apache.geronimo.security.ca.GeronimoCertificationAuthority;
049    import org.apache.geronimo.system.serverinfo.ServerInfo;
050    import org.apache.geronimo.crypto.KeystoreUtil;
051    
052    /**
053     * Handler for the CA confirmation screen.
054     *
055     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
056     */
057    public class ConfirmCAHandler extends BaseCAHandler {
058        private final static Log log = LogFactory.getLog(ConfirmCAHandler.class);
059        public ConfirmCAHandler() {
060            super(CONFIRM_CA_MODE, "/WEB-INF/view/ca/confirmCA.jsp");
061        }
062    
063        public String actionBeforeView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
064            String[] params = {ERROR_MSG, INFO_MSG, "caCN", "caOU", "caO", "caL", "caST", "caC", "alias", "keyAlgorithm", "keySize", "algorithm", "validFrom", "validTo", "sNo", "password"};
065            for(int i = 0; i < params.length; ++i) {
066                String value = request.getParameter(params[i]);
067                if(value != null) response.setRenderParameter(params[i], value);
068            }
069            return getMode();
070        }
071    
072        public void renderView(RenderRequest request, RenderResponse response, MultiPageModel model) throws PortletException, IOException {
073            String[] params = {ERROR_MSG, INFO_MSG, "caCN", "caOU", "caO", "caL", "caST", "caC", "alias", "keyAlgorithm", "keySize", "algorithm", "validFrom", "validTo", "sNo", "password"};
074            for(int i = 0; i < params.length; ++i) {
075                String value = request.getParameter(params[i]);
076                if(value != null) request.setAttribute(params[i], value);
077            }
078        }
079    
080        public String actionAfterView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
081            String caCN = request.getParameter("caCN");
082            String caOU = request.getParameter("caOU");
083            String caO = request.getParameter("caO");
084            String caL = request.getParameter("caL");
085            String caST = request.getParameter("caST");
086            String caC = request.getParameter("caC");
087            String alias = request.getParameter("alias");
088            String password = request.getParameter("password");
089            String keyAlgorithm = request.getParameter("keyAlgorithm");
090            String keySize = request.getParameter("keySize");
091            String algorithm = request.getParameter("algorithm");
092            String validFrom = request.getParameter("validFrom");
093            String validTo = request.getParameter("validTo");
094            String sNo = request.getParameter("sNo");
095            String errorMsg = null;
096            
097            try {
098                // Generate keypair
099                // Check if the key algorithm is same as defaultKeyAlgorithm (which is "RSA")
100                if(!defaultKeyAlgorithm.equalsIgnoreCase(keyAlgorithm)) {
101                    throw new Exception("Key Algorithm '"+keyAlgorithm+"' is not supported.");
102                }
103                // Create a KeystoreInstance and generate keypair
104                KeystoreInstance caKeystore = createCAKeystoreInstance(request, password, KeystoreUtil.defaultType);
105                caKeystore.unlockKeystore(password.toCharArray());
106                caKeystore.generateKeyPair(alias, password.toCharArray(), password.toCharArray(), keyAlgorithm, Integer.parseInt(keySize),
107                        algorithm, 365, caCN, caOU, caO, caL, caST, caC);
108                caKeystore.unlockPrivateKey(alias, password.toCharArray(), password.toCharArray());
109                
110                // Create CertificationAuthority, CertificateStore and CertificateRequestStore GBeans
111                createCARelatedGBeans(request, (GeronimoManagedBean)caKeystore, defaultCAStoreDir, defaultCSRStoreDir);
112    
113                CertificationAuthority ca = getCertificationAuthority(request);
114                ca.unlock(password.toCharArray());
115    
116                // Certificate validity and serial number.
117                // Validity of these have been checked before loading the confirmation page.
118                Date validFromDate = null, validToDate = null;
119                DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
120                validFromDate = df.parse(validFrom);
121                validToDate = df.parse(validTo);
122                BigInteger serialNum = new BigInteger(sNo);
123                
124                // Instruct the CA to issue a self-signed certificate.
125                ca.issueOwnCertificate(serialNum, validFromDate, validToDate, algorithm);
126                // Publish the CA's certificate to CertificateStore.
127                getCertificateStore(request).storeCACertificate(ca.getCertificate());
128                
129                // CA Setup is succeessful.
130                // Load a page to show CA details.
131                response.setRenderParameter(INFO_MSG, "CA Setup is successful!");
132                log.info("CA Setup is successful.");
133                
134                return CADETAILS_MODE+BEFORE_ACTION;
135            } catch(Exception e) {
136                errorMsg = e.toString();
137                log.error("Errors in CA Setup process.", e);
138            }
139            
140            // An error occurred.  Go back to CA details entry page so that user can correct the errors.
141            if(errorMsg != null) response.setRenderParameter(ERROR_MSG, errorMsg);
142            return SETUPCA_MODE+BEFORE_ACTION;
143        }
144        
145        /**
146         * This method creates CerificationAuthority, CertificateStore and CertificateRequestStore GBeans.  The GBeans are
147         * created and added to the same configuration containing the caKeystore GBean.
148         * @param request PortletRequest to execute any kernel api's
149         * @param caKeystore Keystore to be used by the CA
150         * @param certStorePath Path for CertificateStore directory.  Note: This CA uses FileCertificateStore
151         * @param certReqStorePath Path for CertificateRequestStore directory: Note: This CA uses FileCertificateRequestStore
152         */
153        private void createCARelatedGBeans(PortletRequest request, GeronimoManagedBean caKeystore, String certStorePath, String certReqStorePath) {
154            // Get hold of configuration containing caKeystore GBean
155            AbstractName caKeystoreName = PortletManager.getNameFor(request, caKeystore);
156            Artifact configurationId =  PortletManager.getConfigurationFor(request, caKeystoreName);
157            ServerInfo serverInfo = PortletManager.getCurrentServer(request).getServerInfo();
158            AbstractName serverInfoName = PortletManager.getNameFor(request, serverInfo);
159            Naming naming = PortletManager.getManagementHelper(request).getNaming();
160            
161            // Add a CertificateStore GBean
162            AbstractName certStoreName = naming.createSiblingName(caKeystoreName, "geronimo-ca-cert-store", NameFactory.CERTIFICATE_STORE);
163            GBeanData certStore = new GBeanData(certStoreName, FileCertificateStore.GBEAN_INFO);
164            certStore.setAttribute("directoryPath", URI.create(certStorePath));
165            certStore.setReferencePattern("ServerInfo", serverInfoName);
166            PortletManager.addGBeanToConfiguration(request, configurationId, certStore, true);
167            
168            // Add a CertificateRequestStore GBean
169            AbstractName certReqStoreName = naming.createSiblingName(caKeystoreName, "geronimo-ca-cert-req-store", NameFactory.CERTIFICATE_REQUEST_STORE);
170            GBeanData certReqStore = new GBeanData(certReqStoreName, FileCertificateRequestStore.GBEAN_INFO);
171            certReqStore.setAttribute("directoryPath", URI.create(certReqStorePath));
172            certReqStore.setReferencePattern("ServerInfo", serverInfoName);
173            PortletManager.addGBeanToConfiguration(request, configurationId, certReqStore, true);
174            
175            // Add a CertificationAuthority GBean
176            AbstractName caName = naming.createSiblingName(caKeystoreName, "geronimo-ca", NameFactory.CERTIFICATION_AUTHORITY);
177            GBeanData ca = new GBeanData(caName, GeronimoCertificationAuthority.GBEAN_INFO);
178            ca.setReferencePattern("ServerInfo", serverInfoName);
179            ca.setReferencePattern("KeystoreInstance", caKeystoreName);
180            ca.setReferencePattern("CertificateStore", certStoreName);
181            ca.setReferencePattern("CertificateRequestStore", certReqStoreName);
182            PortletManager.addGBeanToConfiguration(request, configurationId, ca, true);
183        }
184    }