// --- BEGIN COPYRIGHT BLOCK ---
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// (C) 2007 Red Hat, Inc.
// All rights reserved.
// --- END COPYRIGHT BLOCK ---
package com.netscape.cms.servlet.cert;
import java.io.IOException;
import java.util.Locale;
import java.math.BigInteger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import netscape.security.extensions.NSCertTypeExtension;
import netscape.security.x509.CertificateExtensions;
import netscape.security.x509.Extension;
import netscape.security.x509.KeyUsageExtension;
import netscape.security.x509.X509CertImpl;
import netscape.security.x509.X509CertInfo;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.authority.IAuthority;
import com.netscape.certsrv.authorization.AuthzToken;
import com.netscape.certsrv.authorization.EAuthzAccessDenied;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IArgBlock;
import com.netscape.certsrv.logging.ILogger;
import com.netscape.certsrv.profile.IEnrollProfile;
import com.netscape.certsrv.ra.IRegistrationAuthority;
import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IRequestQueue;
import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestStatus;
import com.netscape.cms.servlet.base.CMSServlet;
import com.netscape.cms.servlet.common.CMSRequest;
import com.netscape.cms.servlet.common.CMSTemplateParams;
import com.netscape.cms.servlet.common.ECMSGWException;
import com.netscape.cms.servlet.common.ICMSTemplateFiller;
/**
* Gets a issued certificate from a request id.
*
* @version $Revision$, $Date$
*/
public class GetCertFromRequest extends CMSServlet {
/**
*
*/
private static final long serialVersionUID = 5310646832256611066L;
private final static String PROP_IMPORT = "importCert";
protected static final String GET_CERT_FROM_REQUEST_TEMPLATE = "ImportCert.template";
protected static final String DISPLAY_CERT_FROM_REQUEST_TEMPLATE = "displayCertFromRequest.template";
protected static final String REQUEST_ID = "requestId";
protected static final String CERT_TYPE = "certtype";
protected String mCertFrReqSuccessTemplate = null;
protected ICMSTemplateFiller mCertFrReqFiller = null;
protected IRequestQueue mQueue = null;
protected boolean mImportCert = true;
public GetCertFromRequest() {
super();
}
/**
* initialize the servlet. This servlet uses the template files
* "displayCertFromRequest.template" and "ImportCert.template"
*
* @param sc servlet configuration, read from the web.xml file
*/
public void init(ServletConfig sc) throws ServletException {
super.init(sc);
mTemplates.remove(CMSRequest.SUCCESS);
mQueue = mAuthority.getRequestQueue();
try {
String tmp = sc.getInitParameter(
PROP_IMPORT);
if (tmp != null && tmp.trim().equalsIgnoreCase("false"))
mImportCert = false;
String defTemplate = null;
if (mImportCert)
defTemplate = GET_CERT_FROM_REQUEST_TEMPLATE;
else
defTemplate = DISPLAY_CERT_FROM_REQUEST_TEMPLATE;
if (mAuthority instanceof IRegistrationAuthority)
defTemplate = "/ra/" + defTemplate;
else
defTemplate = "/ca/" + defTemplate;
mCertFrReqSuccessTemplate = sc.getInitParameter(
PROP_SUCCESS_TEMPLATE);
if (mCertFrReqSuccessTemplate == null)
mCertFrReqSuccessTemplate = defTemplate;
String fillername =
sc.getInitParameter(PROP_SUCCESS_TEMPLATE_FILLER);
if (fillername != null) {
ICMSTemplateFiller filler = newFillerObject(fillername);
if (filler != null)
mCertFrReqFiller = filler;
} else {
mCertFrReqFiller = new CertFrRequestFiller();
}
} catch (Exception e) {
// should never happen.
log(ILogger.LL_FAILURE,
CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(),
mId));
}
}
/**
* Process the HTTP request.
*
* - http.param requestId The request ID to search on
*
*
* @param cmsReq the object holding the request and response information
*/
protected void process(CMSRequest cmsReq)
throws EBaseException {
IArgBlock httpParams = cmsReq.getHttpParams();
HttpServletRequest httpReq = cmsReq.getHttpReq();
IAuthToken authToken = authenticate(cmsReq);
AuthzToken authzToken = null;
try {
authzToken = authorize(mAclMethod, authToken,
mAuthzResourceName, "read");
} catch (EAuthzAccessDenied e) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
} catch (Exception e) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
}
if (authzToken == null) {
cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
return;
}
String requestId = httpParams.getValueAsString(REQUEST_ID, null);
if (requestId == null) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_REQUEST_ID_PROVIDED"));
throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_REQUEST_ID_PROVIDED"));
}
// check if request Id is valid.
try {
new BigInteger(requestId);
} catch (NumberFormatException e) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_REQ_ID_FORMAT", requestId));
throw new EBaseException(
CMS.getUserMessage(getLocale(httpReq), "CMS_BASE_INVALID_NUMBER_FORMAT_1", requestId));
}
IRequest r = mQueue.findRequest(new RequestId(requestId));
if (r == null) {
log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REQUEST_ID_NOT_FOUND", requestId));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_REQUEST_ID_NOT_FOUND", requestId));
}
if (authToken != null) {
//if RA, group and requestOwner must match
String group = authToken.getInString("group");
if ((group != null) && (group != "") &&
group.equals("Registration Manager Agents")) {
boolean groupMatched = false;
String reqOwner = r.getRequestOwner();
if (reqOwner != null) {
CMS.debug("GetCertFromRequest process: req owner=" + reqOwner);
if (reqOwner.equals(group))
groupMatched = true;
}
if (groupMatched == false) {
CMS.debug("RA group unmatched");
log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REQUEST_ID_NOT_FOUND", requestId));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_REQUEST_ID_NOT_FOUND", requestId));
}
}
}
if (!((r.getRequestType().equals(IRequest.ENROLLMENT_REQUEST)) ||
(r.getRequestType().equals(IRequest.RENEWAL_REQUEST)))) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("CMSGW_REQUEST_NOT_ENROLLMENT_1", requestId));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_REQUEST_NOT_ENROLLMENT", requestId));
}
RequestStatus status = r.getRequestStatus();
if (!status.equals(RequestStatus.COMPLETE)) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("CMSGW_REQUEST_NOT_COMPLETED_1", requestId));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_REQUEST_NOT_COMPLETED", requestId));
}
Integer result = r.getExtDataInInteger(IRequest.RESULT);
if (result != null && !result.equals(IRequest.RES_SUCCESS)) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("CMSGW_REQUEST_HAD_ERROR_1", requestId));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_REQUEST_HAD_ERROR", requestId));
}
Object o = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
if (r.getExtDataInString("profile") != null) {
// handle profile-based request
X509CertImpl cert = r.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
X509CertImpl certs[] = new X509CertImpl[1];
certs[0] = cert;
o = certs;
}
if (o == null || !(o instanceof X509CertImpl[])) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("CMSGW_REQUEST_HAD_NO_CERTS_1", requestId));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_REQUEST_HAD_NO_CERTS", requestId));
}
if (o instanceof X509CertImpl[]) {
X509CertImpl[] certs = (X509CertImpl[]) o;
if (certs == null || certs.length == 0 || certs[0] == null) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("CMSGW_REQUEST_HAD_NO_CERTS_1", requestId));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_REQUEST_HAD_NO_CERTS", requestId));
}
// for importsCert to get the crmf_reqid.
cmsReq.setIRequest(r);
cmsReq.setStatus(CMSRequest.SUCCESS);
if (mImportCert &&
checkImportCertToNav(cmsReq.getHttpResp(), httpParams, certs[0])) {
return;
}
try {
cmsReq.setResult(certs);
renderTemplate(cmsReq, mCertFrReqSuccessTemplate, mCertFrReqFiller);
} catch (IOException e) {
log(ILogger.LL_FAILURE,
CMS.getLogMessage("CMSGE_ERROR_DISPLAY_TEMPLATE_1",
mCertFrReqSuccessTemplate, e.toString()));
throw new ECMSGWException(
CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
}
}
return;
}
}
class CertFrRequestFiller extends ImportCertsTemplateFiller {
public CertFrRequestFiller() {
}
public CMSTemplateParams getTemplateParams(
CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
throws Exception {
CMSTemplateParams tparams =
super.getTemplateParams(cmsReq, authority, locale, e);
String reqId = cmsReq.getHttpParams().getValueAsString(
GetCertFromRequest.REQUEST_ID);
tparams.getHeader().addStringValue(GetCertFromRequest.REQUEST_ID, reqId);
if (reqId != null) {
IRequest r = authority.getRequestQueue().findRequest(new RequestId(reqId));
if (r != null) {
boolean noCertImport = true;
String certType = r.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
if (certType != null && certType.equals(IRequest.CLIENT_CERT)) {
noCertImport = false;
}
tparams.getHeader().addBooleanValue("noCertImport", noCertImport);
X509CertImpl[] certs = r.getExtDataInCertArray(IRequest.ISSUED_CERTS);
if (certs != null) {
X509CertInfo info = (X509CertInfo) certs[0].get(X509CertImpl.NAME + "." + X509CertImpl.INFO);
CertificateExtensions extensions = (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS);
tparams.getHeader().addStringValue(GetCertFromRequest.CERT_TYPE, "x509");
boolean emailCert = false;
if (extensions != null) {
for (int i = 0; i < extensions.size(); i++) {
Extension ext = (Extension) extensions.elementAt(i);
if (ext instanceof NSCertTypeExtension) {
NSCertTypeExtension type = (NSCertTypeExtension) ext;
if (((Boolean) type.get(NSCertTypeExtension.EMAIL)).booleanValue())
emailCert = true;
}
if (ext instanceof KeyUsageExtension) {
KeyUsageExtension usage =
(KeyUsageExtension) ext;
try {
if (((Boolean) usage.get(KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue() ||
((Boolean) usage.get(KeyUsageExtension.DATA_ENCIPHERMENT)).booleanValue())
emailCert = true;
} catch (ArrayIndexOutOfBoundsException e0) {
// bug356108:
// In case there is only DIGITAL_SIGNATURE,
// don't report error
}
}
}
}
tparams.getHeader().addBooleanValue("emailCert", emailCert);
}
}
}
return tparams;
}
}