diff options
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java')
-rw-r--r-- | base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java | 904 |
1 files changed, 904 insertions, 0 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java new file mode 100644 index 000000000..16451f6dd --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java @@ -0,0 +1,904 @@ +// --- 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.profile; + +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.CertificateEncodingException; +import java.util.Enumeration; +import java.util.Locale; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import netscape.security.x509.X509CertImpl; + +import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.INTEGER; +import org.mozilla.jss.asn1.InvalidBERException; +import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; +import org.mozilla.jss.asn1.SEQUENCE; +import org.mozilla.jss.asn1.SET; +import org.mozilla.jss.asn1.UTF8String; +import org.mozilla.jss.pkix.cmc.LraPopWitness; +import org.mozilla.jss.pkix.cmc.OtherInfo; +import org.mozilla.jss.pkix.cmc.TaggedAttribute; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.authorization.AuthzToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.SessionContext; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.profile.EDeferException; +import com.netscape.certsrv.profile.EProfileException; +import com.netscape.certsrv.profile.ERejectException; +import com.netscape.certsrv.profile.IEnrollProfile; +import com.netscape.certsrv.profile.IProfile; +import com.netscape.certsrv.profile.IProfileAuthenticator; +import com.netscape.certsrv.profile.IProfileContext; +import com.netscape.certsrv.profile.IProfileInput; +import com.netscape.certsrv.profile.IProfileSubsystem; +import com.netscape.certsrv.request.INotify; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.RequestStatus; +import com.netscape.cms.servlet.common.AuthCredentials; +import com.netscape.cms.servlet.common.CMCOutputTemplate; +import com.netscape.cms.servlet.common.CMSRequest; +import com.netscape.cmsutil.util.Utils; + +/** + * This servlet submits end-user request into the profile framework. + * + * @version $Revision$, $Date$ + */ +public class ProfileSubmitCMCServlet extends ProfileServlet { + + /** + * + */ + private static final long serialVersionUID = -8017841111435988197L; + private static final String ARG_AUTH_TOKEN = "auth_token"; + private static final String PROP_PROFILE_ID = "profileId"; + private static final String PROP_AUTHORITY_ID = "authorityId"; + + private String mOutputTemplateClassName = null; + private String mProfileId = null; + private String mProfileSubId = null; + private String mReqType = null; + private String mAuthorityId = null; + private String requestBinary = null; + private String requestB64 = null; + + private final static String[] SIGNED_AUDIT_AUTOMATED_REJECTION_REASON = new String[] { + + /* 0 */"automated profile cert request rejection: " + + "indeterminate reason for inability to process " + + "cert request due to an EBaseException" + }; + private final static String LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED = + "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5"; + + public ProfileSubmitCMCServlet() { + } + + /** + * initialize the servlet. And instance of this servlet can + * be set up to always issue certificates against a certain profile + * by setting the 'profileId' configuration in the servletConfig + * If not, the user must specify the profileID when submitting the request + * + * "ImportCert.template" to process the response. + * + * @param sc servlet configuration, read from the web.xml file + */ + public void init(ServletConfig sc) throws ServletException { + super.init(sc); + mAuthorityId = sc.getInitParameter(PROP_AUTHORITY_ID); + mProfileId = sc.getInitParameter(PROP_PROFILE_ID); + mOutputTemplateClassName = sc.getInitParameter("outputTemplateClass"); + mRenderResult = false; + } + + private void setInputsIntoContext(HttpServletRequest request, IProfile profile, IProfileContext ctx) { + + // passing inputs into context + Enumeration<String> inputIds = profile.getProfileInputIds(); + + if (inputIds != null) { + while (inputIds.hasMoreElements()) { + String inputId = inputIds.nextElement(); + IProfileInput profileInput = profile.getProfileInput(inputId); + Enumeration<String> inputNames = profileInput.getValueNames(); + + while (inputNames.hasMoreElements()) { + String inputName = inputNames.nextElement(); + + if (request.getParameter(inputName) != null) { + ctx.set(inputName, request.getParameter(inputName)); + } + } + } + } + + } + + private void setCredentialsIntoContext(HttpServletRequest request, IProfileAuthenticator authenticator, + IProfileContext ctx) { + Enumeration<String> authIds = authenticator.getValueNames(); + + if (authIds != null) { + while (authIds.hasMoreElements()) { + String authName = authIds.nextElement(); + + if (request.getParameter(authName) != null) { + ctx.set(authName, request.getParameter(authName)); + } + } + } + } + + public IAuthToken authenticate(IProfileAuthenticator authenticator, + HttpServletRequest request) throws EBaseException { + AuthCredentials credentials = new AuthCredentials(); + + // build credential + Enumeration<String> authNames = authenticator.getValueNames(); + + if (authNames != null) { + while (authNames.hasMoreElements()) { + String authName = authNames.nextElement(); + + if (authName.equals("cert_request")) + credentials.set(authName, requestB64); + else + credentials.set(authName, request.getParameter(authName)); + } + } + IAuthToken authToken = authenticator.authenticate(credentials); + + SessionContext sc = SessionContext.getContext(); + if (sc != null) { + sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName()); + String userid = authToken.getInString(IAuthToken.USER_ID); + if (userid != null) { + sc.put(SessionContext.USER_ID, userid); + } + } + + return authToken; + } + + private void setInputsIntoRequest(HttpServletRequest request, IProfile + profile, IRequest req) { + Enumeration<String> inputIds = profile.getProfileInputIds(); + + if (inputIds != null) { + while (inputIds.hasMoreElements()) { + String inputId = inputIds.nextElement(); + IProfileInput profileInput = profile.getProfileInput(inputId); + Enumeration<String> inputNames = profileInput.getValueNames(); + + if (inputNames != null) { + while (inputNames.hasMoreElements()) { + String inputName = inputNames.nextElement(); + + if (request.getParameter(inputName) != null) { + req.setExtData(inputName, request.getParameter(inputName)); + } + } + } + } + } + } + + /** + * Process the HTTP request + * <P> + * + * (Certificate Request Processed - either an automated "EE" profile based cert acceptance, or an automated "EE" + * profile based cert rejection) + * <P> + * + * <ul> + * <li>http.param profileId ID of profile to use to process request + * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been + * through the approval process + * </ul> + * + * @param cmsReq the object holding the request and response information + * @exception EBaseException an error has occurred + */ + public void process(CMSRequest cmsReq) throws EBaseException { + HttpServletRequest request = cmsReq.getHttpReq(); + HttpServletResponse response = cmsReq.getHttpResp(); + + Locale locale = getLocale(request); + String cert_request_type = + mServletConfig.getInitParameter("cert_request_type"); + String outputFormat = mServletConfig.getInitParameter("outputFormat"); + + int reqlen = request.getContentLength(); + InputStream is = null; + try { + is = request.getInputStream(); + } catch (Exception ee) { + } + byte reqbuf[] = new byte[reqlen]; + int bytesread = 0; + boolean partial = false; + + while (bytesread < reqlen) { + try { + bytesread += is.read(reqbuf, bytesread, reqlen - bytesread); + } catch (Exception ee) { + } + + if (partial == false) { + if (bytesread < reqlen) + partial = true; + } + } + + requestB64 = Utils.base64encode(reqbuf); + + if (CMS.debugOn()) { + CMS.debug("Start of ProfileSubmitCMCServlet Input Parameters"); + @SuppressWarnings("unchecked") + Enumeration<String> paramNames = request.getParameterNames(); + + while (paramNames.hasMoreElements()) { + String paramName = paramNames.nextElement(); + // added this facility so that password can be hidden, + // all sensitive parameters should be prefixed with + // __ (double underscores); however, in the event that + // a security parameter slips through, we perform multiple + // additional checks to insure that it is NOT displayed + if (paramName.startsWith("__") || + paramName.endsWith("password") || + paramName.endsWith("passwd") || + paramName.endsWith("pwd") || + paramName.equalsIgnoreCase("admin_password_again") || + paramName.equalsIgnoreCase("directoryManagerPwd") || + paramName.equalsIgnoreCase("bindpassword") || + paramName.equalsIgnoreCase("bindpwd") || + paramName.equalsIgnoreCase("passwd") || + paramName.equalsIgnoreCase("password") || + paramName.equalsIgnoreCase("pin") || + paramName.equalsIgnoreCase("pwd") || + paramName.equalsIgnoreCase("pwdagain") || + paramName.equalsIgnoreCase("uPasswd")) { + CMS.debug("ProfileSubmitCMCServlet Input Parameter " + + paramName + "='(sensitive)'"); + } else { + CMS.debug("ProfileSubmitCMCServlet Input Parameter " + + paramName + "='" + + request.getParameter(paramName) + "'"); + } + } + CMS.debug("End of ProfileSubmitCMCServlet Input Parameters"); + } + + CMS.debug("ProfileSubmitCMCServlet: start serving"); + + if (mProfileSubId == null || mProfileSubId.equals("")) { + mProfileSubId = IProfileSubsystem.ID; + } + CMS.debug("ProfileSubmitCMCServlet: SubId=" + mProfileSubId); + IProfileSubsystem ps = (IProfileSubsystem) + CMS.getSubsystem(mProfileSubId); + + if (ps == null) { + CMS.debug("ProfileSubmitCMCServlet: ProfileSubsystem not found"); + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR")); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.INTERNAL_CA_ERROR, s); + return; + } + + // if we did not configure profileId in xml file, + // then accept the user-provided one + String profileId = null; + + if (mProfileId == null) { + profileId = request.getParameter("profileId"); + } else { + profileId = mProfileId; + } + + IProfile profile = null; + + try { + CMS.debug("ProfileSubmitCMCServlet: profileId " + profileId); + profile = ps.getProfile(profileId); + } catch (EProfileException e) { + CMS.debug("ProfileSubmitCMCServlet: profile not found profileId " + + profileId + " " + e.toString()); + } + if (profile == null) { + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId)); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.INTERNAL_CA_ERROR, s); + return; + } + + if (!ps.isProfileEnable(profileId)) { + CMS.debug("ProfileSubmitCMCServlet: Profile " + profileId + + " not enabled"); + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId)); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.INTERNAL_CA_ERROR, s); + return; + } + + IProfileContext ctx = profile.createContext(); + if (requestB64 != null) { + ctx.set("cert_request_type", cert_request_type); + ctx.set("cert_request", requestB64); + } + // passing auths into context + IProfileAuthenticator authenticator = null; + + try { + authenticator = profile.getAuthenticator(); + } catch (EProfileException e) { + // authenticator not installed correctly + } + if (authenticator == null) { + CMS.debug("ProfileSubmitCMCServlet: authenticator not found"); + } else { + CMS.debug("ProfileSubmitCMCServlet: authenticator " + + authenticator.getName() + " found"); + setCredentialsIntoContext(request, authenticator, ctx); + } + + setInputsIntoContext(request, profile, ctx); + CMS.debug("ProfileSubmistServlet: set Inputs into Context"); + + // before creating the request, authenticate the request + + IAuthToken authToken = null; + + // for ssl authentication; pass in servlet for retrieving + // ssl client certificates + SessionContext context = SessionContext.getContext(); + + // insert profile context so that input parameter can be retrieved + context.put("profileContext", ctx); + context.put("sslClientCertProvider", + new SSLClientCertProvider(request)); + CMS.debug("ProfileSubmitCMCServlet: set sslClientCertProvider"); + if (authenticator != null) { + try { + authToken = authenticate(authenticator, request); + // authentication success + } catch (EBaseException e) { + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(e.toString()); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.BAD_REQUEST, s); + CMS.debug("ProfileSubmitCMCServlet: authentication error " + + e.toString()); + return; + } + + //authorization only makes sense when request is authenticated + AuthzToken authzToken = null; + if (authToken != null) { + CMS.debug("ProfileSubmitCMCServlet authToken not null"); + try { + authzToken = authorize(mAclMethod, authToken, + mAuthzResourceName, "submit"); + } catch (Exception e) { + CMS.debug("ProfileSubmitCMCServlet authorization failure: " + e.toString()); + } + } + + if (authzToken == null) { + CMS.debug("ProfileSubmitCMCServlet authorization failure: authzToken is null"); + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String("ProfileSubmitCMCServlet authorization failure"); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.BAD_REQUEST, s); + return; + } + } + + IRequest reqs[] = null; + + /////////////////////////////////////////////// + // create request + /////////////////////////////////////////////// + try { + reqs = profile.createRequests(ctx, locale); + } catch (EProfileException e) { + CMS.debug("ProfileSubmitCMCServlet: createRequests " + e.toString()); + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(e.toString()); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.INTERNAL_CA_ERROR, s); + return; + } catch (Throwable e) { + CMS.debug("ProfileSubmitCMCServlet: createRequests " + e.toString()); + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR")); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.INTERNAL_CA_ERROR, s); + return; + } + + TaggedAttribute attr = + (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_lraPOPWitness)); + if (attr != null) { + boolean verifyAllow = true; + try { + verifyAllow = CMS.getConfigStore().getBoolean( + "cmc.lraPopWitness.verify.allow", true); + } catch (EBaseException ee) { + } + + if (!verifyAllow) { + LraPopWitness lraPop = null; + SET vals = attr.getValues(); + if (vals.size() > 0) { + try { + lraPop = (LraPopWitness) (ASN1Util.decode(LraPopWitness.getTemplate(), + ASN1Util.encode(vals.elementAt(0)))); + } catch (InvalidBERException e) { + CMS.debug( + CMS.getUserMessage(locale, "CMS_PROFILE_ENCODING_ERROR")); + } + + SEQUENCE bodyIds = lraPop.getBodyIds(); + + CMCOutputTemplate template = new CMCOutputTemplate(); + template.createFullResponseWithFailedStatus(response, bodyIds, + OtherInfo.POP_FAILED, null); + return; + } + } + } + + // for CMC, requests may be zero. Then check if controls exist. + if (reqs == null) { + Integer nums = (Integer) (context.get("numOfControls")); + CMCOutputTemplate template = new CMCOutputTemplate(); + // if there is only one control GetCert, then simple response + // must be returned. + if (nums != null && nums.intValue() == 1) { + TaggedAttribute attr1 = (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_getCert)); + if (attr1 != null) { + template.createSimpleResponse(response, reqs); + } else + template.createFullResponse(response, reqs, + cert_request_type, null); + } else + template.createFullResponse(response, reqs, + cert_request_type, null); + return; + } + + String errorCode = null; + String errorReason = null; + + /////////////////////////////////////////////// + // populate request + /////////////////////////////////////////////// + for (int k = 0; k < reqs.length; k++) { + // adding parameters to request + setInputsIntoRequest(request, profile, reqs[k]); + + // serial auth token into request + if (authToken != null) { + Enumeration<String> tokenNames = authToken.getElements(); + while (tokenNames.hasMoreElements()) { + String tokenName = tokenNames.nextElement(); + String[] vals = authToken.getInStringArray(tokenName); + if (vals != null) { + for (int i = 0; i < vals.length; i++) { + reqs[k].setExtData(ARG_AUTH_TOKEN + "." + + tokenName + "[" + i + "]", vals[i]); + } + } else { + String val = authToken.getInString(tokenName); + if (val != null) { + reqs[k].setExtData(ARG_AUTH_TOKEN + "." + tokenName, + val); + } + } + } + } + + // put profile framework parameters into the request + reqs[k].setExtData(ARG_PROFILE, "true"); + reqs[k].setExtData(ARG_PROFILE_ID, profileId); + reqs[k].setExtData(ARG_PROFILE_APPROVED_BY, profile.getApprovedBy()); + String setId = profile.getPolicySetId(reqs[k]); + + if (setId == null) { + // no profile set found + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(CMS.getUserMessage("CMS_PROFILE_NO_POLICY_SET_FOUND")); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.INTERNAL_CA_ERROR, s); + return; + } + + CMS.debug("ProfileSubmitCMCServlet profileSetid=" + setId); + reqs[k].setExtData(ARG_PROFILE_SET_ID, setId); + reqs[k].setExtData(ARG_PROFILE_REMOTE_HOST, request.getRemoteHost()); + reqs[k].setExtData(ARG_PROFILE_REMOTE_ADDR, request.getRemoteAddr()); + + CMS.debug("ProfileSubmitCMCServlet: request " + + reqs[k].getRequestId().toString()); + + try { + CMS.debug("ProfileSubmitCMCServlet: populating request inputs"); + // give authenticator a chance to populate the request + if (authenticator != null) { + authenticator.populate(authToken, reqs[k]); + } + profile.populateInput(ctx, reqs[k]); + profile.populate(reqs[k]); + } catch (EProfileException e) { + CMS.debug("ProfileSubmitCMCServlet: populate " + e.toString()); + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(e.toString()); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.BAD_REQUEST, s); + return; + } catch (Throwable e) { + CMS.debug("ProfileSubmitCMCServlet: populate " + e.toString()); + // throw new IOException("Profile " + profileId + + // " cannot populate"); + CMCOutputTemplate template = new CMCOutputTemplate(); + SEQUENCE seq = new SEQUENCE(); + seq.addElement(new INTEGER(0)); + UTF8String s = null; + try { + s = new UTF8String(e.toString()); + } catch (Exception ee) { + } + template.createFullResponseWithFailedStatus(response, seq, + OtherInfo.INTERNAL_CA_ERROR, s); + return; + } + } + + String auditMessage = null; + String auditSubjectID = auditSubjectID(); + String auditRequesterID = ILogger.UNIDENTIFIED; + String auditInfoCertValue = ILogger.SIGNED_AUDIT_EMPTY_VALUE; + + try { + /////////////////////////////////////////////// + // submit request + /////////////////////////////////////////////// + int error_codes[] = null; + if (reqs != null && reqs.length > 0) + error_codes = new int[reqs.length]; + for (int k = 0; k < reqs.length; k++) { + try { + // reset the "auditRequesterID" + auditRequesterID = auditRequesterID(reqs[k]); + + // print request debug + if (reqs[k] != null) { + Enumeration<String> reqKeys = reqs[k].getExtDataKeys(); + while (reqKeys.hasMoreElements()) { + String reqKey = reqKeys.nextElement(); + String reqVal = reqs[k].getExtDataInString(reqKey); + if (reqVal != null) { + CMS.debug("ProfileSubmitCMCServlet: key=$request." + reqKey + "$ value=" + reqVal); + } + } + } + + profile.submit(authToken, reqs[k]); + reqs[k].setRequestStatus(RequestStatus.COMPLETE); + + // reset the "auditInfoCertValue" + auditInfoCertValue = auditInfoCertValue(reqs[k]); + + if (auditInfoCertValue != null) { + if (!(auditInfoCertValue.equals( + ILogger.SIGNED_AUDIT_EMPTY_VALUE))) { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, + auditSubjectID, + ILogger.SUCCESS, + auditRequesterID, + ILogger.SIGNED_AUDIT_ACCEPTANCE, + auditInfoCertValue); + + audit(auditMessage); + } + } + } catch (EDeferException e) { + // return defer message to the user + reqs[k].setRequestStatus(RequestStatus.PENDING); + // need to notify + INotify notify = profile.getRequestQueue().getPendingNotify(); + if (notify != null) { + notify.notify(reqs[k]); + } + + CMS.debug("ProfileSubmitCMCServlet: submit " + e.toString()); + errorCode = "2"; + errorReason = CMS.getUserMessage(locale, + "CMS_PROFILE_DEFERRED", + e.toString()); + } catch (ERejectException e) { + // return error to the user + reqs[k].setRequestStatus(RequestStatus.REJECTED); + CMS.debug("ProfileSubmitCMCServlet: submit " + e.toString()); + errorCode = "3"; + errorReason = CMS.getUserMessage(locale, + "CMS_PROFILE_REJECTED", + e.toString()); + } catch (Throwable e) { + // return error to the user + CMS.debug("ProfileSubmitCMCServlet: submit " + e.toString()); + errorCode = "1"; + errorReason = CMS.getUserMessage(locale, + "CMS_INTERNAL_ERROR"); + } + + try { + if (errorCode == null) { + profile.getRequestQueue().markAsServiced(reqs[k]); + } else { + profile.getRequestQueue().updateRequest(reqs[k]); + } + } catch (EBaseException e) { + CMS.debug("ProfileSubmitCMCServlet: updateRequest " + + e.toString()); + } + + if (errorCode != null) { + if (errorCode.equals("1")) { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, + auditSubjectID, + ILogger.FAILURE, + auditRequesterID, + ILogger.SIGNED_AUDIT_REJECTION, + errorReason); + + audit(auditMessage); + } else if (errorCode.equals("2")) { + // do NOT store a message in the signed audit log file + // as this errorCode indicates that a process has been + // deferred for manual acceptance/cancellation/rejection + } else if (errorCode.equals("3")) { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, + auditSubjectID, + ILogger.FAILURE, + auditRequesterID, + ILogger.SIGNED_AUDIT_REJECTION, + errorReason); + + audit(auditMessage); + } + error_codes[k] = Integer.parseInt(errorCode); + } else + error_codes[k] = 0; + } + + if (errorCode != null) { + // create the CMC full enrollment response + CMCOutputTemplate template = new CMCOutputTemplate(); + template.createFullResponse(response, reqs, cert_request_type, error_codes); + + return; + } + + /////////////////////////////////////////////// + // output output list + /////////////////////////////////////////////// + + CMS.debug("ProfileSubmitCMCServlet: done serving"); + CMCOutputTemplate template = new CMCOutputTemplate(); + if (cert_request_type.equals("pkcs10") || cert_request_type.equals("crmf")) { + + if (outputFormat != null && outputFormat.equals("pkcs7")) { + byte[] pkcs7 = CMS.getPKCS7(locale, reqs[0]); + response.setContentType("application/pkcs7-mime"); + response.setContentLength(pkcs7.length); + try { + OutputStream os = response.getOutputStream(); + os.write(pkcs7); + os.flush(); + } catch (Exception ee) { + } + return; + } + template.createSimpleResponse(response, reqs); + } else if (cert_request_type.equals("cmc")) { + Integer nums = (Integer) (context.get("numOfControls")); + if (nums != null && nums.intValue() == 1) { + TaggedAttribute attr1 = + (TaggedAttribute) (context.get(OBJECT_IDENTIFIER.id_cmc_getCert)); + if (attr1 != null) { + template.createSimpleResponse(response, reqs); + return; + } + } + template.createFullResponse(response, reqs, cert_request_type, + error_codes); + } + } finally { + SessionContext.releaseContext(); + } + } + + /** + * Signed Audit Log Requester ID + * + * This method is called to obtain the "RequesterID" for + * a signed audit log message. + * <P> + * + * @param request the actual request + * @return id string containing the signed audit log message RequesterID + */ + private String auditRequesterID(IRequest request) { + // if no signed audit object exists, bail + if (mSignedAuditLogger == null) { + return null; + } + + String requesterID = ILogger.UNIDENTIFIED; + + if (request != null) { + // overwrite "requesterID" if and only if "id" != null + String id = request.getRequestId().toString(); + + if (id != null) { + requesterID = id.trim(); + } + } + + return requesterID; + } + + /** + * Signed Audit Log Info Certificate Value + * + * This method is called to obtain the certificate from the passed in + * "X509CertImpl" for a signed audit log message. + * <P> + * + * @param request request containing an X509CertImpl + * @return cert string containing the certificate + */ + private String auditInfoCertValue(IRequest request) { + // if no signed audit object exists, bail + if (mSignedAuditLogger == null) { + return null; + } + + X509CertImpl x509cert = request.getExtDataInCert( + IEnrollProfile.REQUEST_ISSUED_CERT); + + if (x509cert == null) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + byte rawData[] = null; + + try { + rawData = x509cert.getEncoded(); + } catch (CertificateEncodingException e) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + String cert = null; + + // convert "rawData" into "base64Data" + if (rawData != null) { + String base64Data = null; + + base64Data = Utils.base64encode(rawData).trim(); + + // extract all line separators from the "base64Data" + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < base64Data.length(); i++) { + if (!Character.isWhitespace(base64Data.charAt(i))) { + sb.append(base64Data.charAt(i)); + } + } + cert = sb.toString(); + } + + if (cert != null) { + cert = cert.trim(); + + if (cert.equals("")) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } else { + return cert; + } + } else { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + } +} |