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.ByteArrayInputStream;
021 import java.io.IOException;
022 import java.math.BigInteger;
023 import java.security.PublicKey;
024 import java.text.DateFormat;
025 import java.text.SimpleDateFormat;
026 import java.util.Date;
027 import java.util.Map;
028 import java.util.Properties;
029
030 import javax.portlet.ActionRequest;
031 import javax.portlet.ActionResponse;
032 import javax.portlet.PortletException;
033 import javax.portlet.RenderRequest;
034 import javax.portlet.RenderResponse;
035 import javax.security.auth.x500.X500Principal;
036
037 import org.apache.commons.logging.Log;
038 import org.apache.commons.logging.LogFactory;
039 import org.apache.geronimo.console.MultiPageModel;
040 import org.apache.geronimo.management.geronimo.CertificationAuthority;
041 import org.apache.geronimo.util.CaUtils;
042 import org.apache.geronimo.util.asn1.x509.X509Name;
043
044 /**
045 * Handler for Confirm Client Certificate Issue screen.
046 *
047 * @version $Rev: 514091 $ $Date: 2007-03-03 01:26:39 -0500 (Sat, 03 Mar 2007) $
048 */
049 public class ConfirmClientCertHandler extends BaseCAHandler {
050 private final static Log log = LogFactory.getLog(ConfirmClientCertHandler.class);
051 public ConfirmClientCertHandler() {
052 super(CONFIRM_CLIENT_CERT_MODE, "/WEB-INF/view/ca/confirmClientCert.jsp");
053 }
054
055 public String actionBeforeView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
056 String[] params = {ERROR_MSG, INFO_MSG, "subject", "publickey", "algorithm", "validFrom", "validTo", "sNo", "pkcs10certreq", "requestId"};
057 for(int i = 0; i < params.length; ++i) {
058 String value = request.getParameter(params[i]);
059 if(value != null) response.setRenderParameter(params[i], value);
060 }
061 return getMode();
062 }
063
064 public void renderView(RenderRequest request, RenderResponse response, MultiPageModel model) throws PortletException, IOException {
065 String[] params = {ERROR_MSG, INFO_MSG, "subject", "publickey", "algorithm", "validFrom", "validTo", "sNo", "pkcs10certreq", "requestId"};
066 for(int i = 0; i < params.length; ++i) {
067 String value = request.getParameter(params[i]);
068 if(value != null) request.setAttribute(params[i], value);
069 }
070 }
071
072 public String actionAfterView(ActionRequest request, ActionResponse response, MultiPageModel model) throws PortletException, IOException {
073 String errorMsg = null;
074 try {
075 CertificationAuthority ca = getCertificationAuthority(request);
076 if(ca == null) {
077 throw new Exception("CA is not running. CA may not have been initialized!!");
078 }
079 BigInteger sNo = new BigInteger(request.getParameter("sNo"));
080 if(ca.isCertificateIssued(sNo)) {
081 // A certificate with the serial number has already been issued.
082 // This may happen if the user clicks on "Issue Certificate" button a second time
083 log.warn("Second request to issue certificate with serial number'"+sNo+"'. A certificate has already been issued.");
084 response.setRenderParameter("sNo", sNo.toString());
085 response.setRenderParameter(INFO_MSG, "A certificate with the serial number '"+sNo+"' has already been issued. "
086 +"You may be seeing this message since you have clicked on 'Issue Certificate' button a second time.");
087 return VIEW_CERT_MODE;
088 }
089
090 X509Name subject = null;
091 PublicKey publickey = null;
092 // Process the CSR text to get subject details
093 String pkcs10certreq = null, certreq = null;
094 String challenge = null;
095 String requestId = request.getParameter("requestId");
096 if(requestId != null && !requestId.equals("")) {
097 // Certificate request is being processed using a previously stored request in CertificateRequestStore
098 String certreqText = getCertificateRequestStore(request).getRequest(requestId);
099 if(certreqText.startsWith(CaUtils.CERT_REQ_HEADER)) {
100 // A PKCS 10 Certificate Request
101 pkcs10certreq = certreqText;
102 } else {
103 // Possibly a CSR received through web browser
104 certreq = certreqText;
105 }
106 } else {
107 // No request id is found. Get the PKCS10 request submitted through form input
108 pkcs10certreq = request.getParameter("pkcs10certreq");
109 }
110
111 if(pkcs10certreq != null && !"".equals(pkcs10certreq)) {
112 // Process PKCS 10 Certificate Request text to get Subject name and public-key
113 Map certReqMap = CaUtils.processPKCS10Request(pkcs10certreq);
114 subject = (X509Name) certReqMap.get(CaUtils.CERT_REQ_SUBJECT);
115 publickey = (PublicKey) certReqMap.get(CaUtils.CERT_REQ_PUBLICKEY_OBJ);
116 } else {
117 // This is a custom request containing SPKAC and X509Name attributes received through web browser
118 Properties csrProps = new Properties();
119 csrProps.load(new ByteArrayInputStream(certreq.getBytes()));
120 String spkac = csrProps.getProperty("SPKAC");
121 String cn = csrProps.getProperty("CN");
122 String ou = csrProps.getProperty("OU");
123 String o = csrProps.getProperty("O");
124 String l = csrProps.getProperty("L");
125 String st = csrProps.getProperty("ST");
126 String c = csrProps.getProperty("C");
127 subject = CaUtils.getX509Name(cn, ou, o, l, st, c);
128 Map certReqMap = CaUtils.processSPKAC(spkac);
129 publickey = (PublicKey) certReqMap.get(CaUtils.CERT_REQ_PUBLICKEY_OBJ);
130 challenge = (String) certReqMap.get(CaUtils.PKAC_CHALLENGE);
131 }
132
133 // Dates have already been validated in the previous screen
134 String validFrom = request.getParameter("validFrom");
135 String validTo = request.getParameter("validTo");
136 DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
137 Date validFromDate = df.parse(validFrom);
138 Date validToDate = df.parse(validTo);
139 String algorithm = request.getParameter("algorithm");
140 // Issue certificate
141 ca.issueCertificate(new X500Principal(subject.getEncoded()), publickey, sNo, validFromDate, validToDate, algorithm);
142 // Store the challenge phrase against the issued certificate serial number
143 if(challenge != null && !challenge.equals("")) {
144 getCertificateStore(request).setCertificateChallenge(sNo, challenge);
145 }
146
147 if(requestId != null && !requestId.equals("")) {
148 // This request was processed using a requestId from CertificateRequestStore. Delete the fulfilled request.
149 getCertificateRequestStore(request).setRequestFulfilled(requestId, sNo);
150 // The confirmation page will show a link to the "Requests to be fulfilled" page.
151 response.setRenderParameter("linkToListRequests", "true");
152 }
153
154 // Set the serial number and forward to view certificate page
155 response.setRenderParameter("sNo", sNo.toString());
156 response.setRenderParameter(INFO_MSG, "Certificate Issued successfully. This Certificate details can also be viewed using the serial number '"
157 +sNo+"' with the 'View Issued Certificate' link provided in the CA home screen.");
158 log.info("Certificate with serial number '"+sNo+"' issued to "+subject);
159 return VIEW_CERT_MODE;
160 } catch(Exception e) {
161 errorMsg = e.toString();
162 log.error("Errors in issuing certificate.", e);
163 }
164 // An error occurred. Go back to previous screen to let the user correct the errors.
165 response.setRenderParameter(ERROR_MSG, errorMsg);
166 return CERT_REQ_DETAILS_MODE+BEFORE_ACTION;
167 }
168 }