diff options
Diffstat (limited to 'base/server/cms/src/com/netscape/cms/servlet/cert/DoRevoke.java')
-rw-r--r-- | base/server/cms/src/com/netscape/cms/servlet/cert/DoRevoke.java | 812 |
1 files changed, 812 insertions, 0 deletions
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/DoRevoke.java b/base/server/cms/src/com/netscape/cms/servlet/cert/DoRevoke.java new file mode 100644 index 000000000..64a9856fc --- /dev/null +++ b/base/server/cms/src/com/netscape/cms/servlet/cert/DoRevoke.java @@ -0,0 +1,812 @@ +// --- 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.math.BigInteger; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Locale; +import java.util.Vector; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import netscape.security.x509.RevocationReason; +import netscape.security.x509.X509CertImpl; + +import org.apache.commons.lang.StringUtils; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; +import com.netscape.certsrv.authentication.IAuthSubsystem; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.authority.ICertAuthority; +import com.netscape.certsrv.authorization.AuthzToken; +import com.netscape.certsrv.authorization.EAuthzAccessDenied; +import com.netscape.certsrv.authorization.EAuthzException; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.ForbiddenException; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.base.PKIException; +import com.netscape.certsrv.ca.ICRLIssuingPoint; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.common.ICMSRequest; +import com.netscape.certsrv.dbs.certdb.CertId; +import com.netscape.certsrv.dbs.certdb.ICertRecord; +import com.netscape.certsrv.dbs.certdb.ICertificateRepository; +import com.netscape.certsrv.logging.AuditFormat; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.publish.IPublisherProcessor; +import com.netscape.certsrv.ra.IRegistrationAuthority; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; +import com.netscape.certsrv.usrgrp.ICertUserLocator; +import com.netscape.certsrv.usrgrp.IUGSubsystem; +import com.netscape.cms.servlet.base.CMSServlet; +import com.netscape.cms.servlet.common.CMSRequest; +import com.netscape.cms.servlet.common.CMSTemplate; +import com.netscape.cms.servlet.common.CMSTemplateParams; +import com.netscape.cms.servlet.common.ECMSGWException; + +/** + * Revoke a Certificate + * + * @version $Revision$, $Date$ + */ +public class DoRevoke extends CMSServlet { + + /** + * + */ + private static final long serialVersionUID = 1693115906265904238L; + private final static String TPL_FILE = "revocationResult.template"; + + private ICertificateRepository mCertDB = null; + private String mFormPath = null; + private IPublisherProcessor mPublisherProcessor = null; + private int mTimeLimits = 30; /* in seconds */ + private IUGSubsystem mUG = null; + private ICertUserLocator mUL = null; + + public DoRevoke() { + super(); + } + + /** + * initialize the servlet. This servlet uses the template + * file "revocationResult.template" to render the result + * + * @param sc servlet configuration, read from the web.xml file + */ + public void init(ServletConfig sc) throws ServletException { + super.init(sc); + mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE; + + mUG = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG); + mUL = mUG.getCertUserLocator(); + + if (mAuthority instanceof ICertificateAuthority) { + mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository(); + } + if (mAuthority instanceof ICertAuthority) { + mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor(); + } + + mTemplates.remove(ICMSRequest.SUCCESS); + if (mOutputTemplatePath != null) + mFormPath = mOutputTemplatePath; + + /* Server-Side time limit */ + try { + mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits")); + } catch (Exception e) { + /* do nothing, just use the default if integer parsing failed */ + } + } + + /** + * Serves HTTP request. The http parameters used by this request are as follows: + * + * <pre> + * serialNumber Serial number of certificate to revoke (in HEX) + * revocationReason Revocation reason (Described below) + * totalRecordCount [number] + * verifiedRecordCount [number] + * invalidityDate [number of seconds in Jan 1,1970] + * + * </pre> + * + * revocationReason can be one of these values: + * + * <pre> + * 0 = Unspecified (default) + * 1 = Key compromised + * 2 = CA key compromised + * 3 = Affiliation changed + * 4 = Certificate superseded + * 5 = Cessation of operation + * 6 = Certificate is on hold + * </pre> + */ + public void process(CMSRequest cmsReq) throws EBaseException { + HttpServletRequest req = cmsReq.getHttpReq(); + HttpServletResponse resp = cmsReq.getHttpResp(); + + IAuthToken authToken = authenticate(cmsReq); + + String revokeAll = null; + int totalRecordCount = -1; + int verifiedRecordCount = -1; + EBaseException error = null; + int reason = -1; + boolean authorized = true; + Date invalidityDate = null; + CMSTemplate form = null; + Locale[] locale = new Locale[1]; + + try { + form = getTemplate(mFormPath, req, locale); + } catch (IOException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString())); + throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")); + } + + IArgBlock header = CMS.createArgBlock(); + IArgBlock ctx = CMS.createArgBlock(); + CMSTemplateParams argSet = new CMSTemplateParams(header, ctx); + + try { + if (req.getParameter("revocationReason") != null) { + reason = Integer.parseInt(req.getParameter( + "revocationReason")); + } + if (req.getParameter("totalRecordCount") != null) { + totalRecordCount = Integer.parseInt(req.getParameter( + "totalRecordCount")); + } + if (req.getParameter("verifiedRecordCount") != null) { + verifiedRecordCount = Integer.parseInt( + req.getParameter( + "verifiedRecordCount")); + } + if (req.getParameter("invalidityDate") != null) { + long l = Long.parseLong(req.getParameter( + "invalidityDate")); + + if (l > 0) { + invalidityDate = new Date(l); + } + } + revokeAll = req.getParameter("revokeAll"); + + String comments = req.getParameter(IRequest.REQUESTOR_COMMENTS); + String eeSubjectDN = null; + String eeSerialNumber = null; + + //for audit log. + String initiative = null; + + String authMgr = AuditFormat.NOAUTH; + + authToken = authenticate(req); + + AuthzToken authzToken = null; + + try { + authzToken = authorize(mAclMethod, authToken, + mAuthzResourceName, "revoke"); + } 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(ICMSRequest.UNAUTHORIZED); + return; + } + + if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) { + if (authToken != null) { + // Request is from agent. + + String serialNumber = req.getParameter("serialNumber"); + getSSLClientCertificate(req); // throw exception on error + + if (serialNumber != null) { + // Agent has null subject DN. + eeSerialNumber = serialNumber; + } + + authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME); + String agentID = authToken.getInString("userid"); + + initiative = AuditFormat.FROMAGENT + " agentID: " + agentID + + " authenticated by " + authMgr; + } + } else { + // Request is from user. + initiative = AuditFormat.FROMUSER; + + String serialNumber = req.getParameter("serialNumber"); + X509CertImpl sslCert = (X509CertImpl) getSSLClientCertificate(req); + + if (serialNumber == null || sslCert == null || + !(serialNumber.equals(sslCert.getSerialNumber().toString(16)))) { + throw new ForbiddenException("Invalid serial number."); + + } else { + eeSubjectDN = sslCert.getSubjectDN().toString(); + eeSerialNumber = sslCert.getSerialNumber().toString(); + } + + } + + BigInteger serialNumber = parseSerialNumber(eeSerialNumber); + + process(argSet, header, reason, invalidityDate, initiative, + req, resp, verifiedRecordCount, revokeAll, + totalRecordCount, serialNumber, eeSubjectDN, + comments, locale[0]); + + } catch (NumberFormatException e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT")); + error = new EBaseException(CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT")); + + } catch (ForbiddenException e) { + authorized = false; + + } catch (EBaseException e) { + error = e; + } + + /* + catch (Exception e) { + noError = false; + header.addStringValue(OUT_ERROR, + MessageFormatter.getLocalizedString( + errorlocale[0], + BaseResources.class.getName(), + BaseResources.INTERNAL_ERROR_1, + e.toString())); + } + */ + + try { + ServletOutputStream out = resp.getOutputStream(); + + if (error == null && authorized) { + String xmlOutput = req.getParameter("xml"); + if (xmlOutput != null && xmlOutput.equals("true")) { + outputXML(resp, argSet); + } else { + resp.setContentType("text/html"); + form.renderOutput(out, argSet); + cmsReq.setStatus(ICMSRequest.SUCCESS); + } + } else if (!authorized) { + cmsReq.setStatus(ICMSRequest.UNAUTHORIZED); + } else { + cmsReq.setStatus(ICMSRequest.ERROR); + cmsReq.setError(error); + } + } catch (IOException e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString())); + throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")); + } + } + + /** + * Process cert status change request + * <P> + * + * (Certificate Request - either an "agent" cert status change request, or an "EE" cert status change request) + * <P> + * + * (Certificate Request Processed - either an "agent" cert status change request, or an "EE" cert status change + * request) + * <P> + * + * <ul> + * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST used when a cert status change request (e. g. - + * "revocation") is made (before approval process) + * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED used when a certificate status is + * changed (revoked, expired, on-hold, off-hold) + * </ul> + * + * @param argSet CMS template parameters + * @param header argument block + * @param reason revocation reason (0 - Unspecified, 1 - Key compromised, + * 2 - CA key compromised; should not be used, 3 - Affiliation changed, + * 4 - Certificate superceded, 5 - Cessation of operation, or + * 6 - Certificate is on hold) + * @param invalidityDate certificate validity date + * @param initiative string containing the audit format + * @param req HTTP servlet request + * @param resp HTTP servlet response + * @param verifiedRecordCount number of verified records + * @param revokeAll string containing information on all of the + * certificates to be revoked + * @param totalRecordCount total number of records (verified and unverified) + * @param eeSerialNumber BigInteger containing the end-entity certificate + * serial number + * @param eeSubjectDN string containing the end-entity certificate subject + * distinguished name (DN) + * @param comments string containing certificate comments + * @param locale the system locale + * @exception EBaseException an error has occurred + */ + private void process(CMSTemplateParams argSet, IArgBlock header, + int reason, Date invalidityDate, + String initiative, + HttpServletRequest req, + HttpServletResponse resp, + int verifiedRecordCount, + String revokeAll, + int totalRecordCount, + BigInteger eeSerialNumber, + String eeSubjectDN, + String comments, + Locale locale) + throws EBaseException { + + CMS.debug("DoRevoke: eeSerialNumber: " + eeSerialNumber); + long startTime = CMS.getCurrentDate().getTime(); + + RevocationProcessor processor = + new RevocationProcessor(servletConfig.getServletName(), getLocale(req)); + + processor.setStartTime(startTime); + processor.setInitiative(initiative); + processor.setSerialNumber(eeSerialNumber == null ? null : new CertId(eeSerialNumber)); + processor.setRequestID(auditRequesterID(req)); + + RevocationReason revReason = RevocationReason.fromInt(reason); + processor.setRevocationReason(revReason); + processor.setRequestType( + processor.getRevocationReason() == RevocationReason.CERTIFICATE_HOLD + ? RevocationProcessor.ON_HOLD : RevocationProcessor.REVOKE); + + processor.setInvalidityDate(invalidityDate); + processor.setComments(comments); + + Hashtable<BigInteger, Long> nonceMap = new Hashtable<BigInteger, Long>(); + X509Certificate clientCert = getSSLClientCertificate(req); + + if (mAuthority instanceof ICertificateAuthority) { + processor.setAuthority(certAuthority); + + if (certAuthority.noncesEnabled()) { + String nonces = req.getParameter("nonce"); + if (nonces == null) { + throw new ForbiddenException("Missing nonce."); + } + + // parse serial numbers and nonces + for (String s : nonces.split(",")) { + String[] elements = s.split(":"); + BigInteger serialNumber = new BigInteger(elements[0].trim()); + Long nonce = new Long(elements[1].trim()); + nonceMap.put(serialNumber, nonce); + } + } + } + + try { + processor.createCRLExtension(); + + if (mAuthority instanceof ICertificateAuthority) { + + Enumeration<ICertRecord> e = mCertDB.searchCertificates(revokeAll, totalRecordCount, mTimeLimits); + + while (e != null && e.hasMoreElements()) { + ICertRecord targetRecord = e.nextElement(); + X509CertImpl targetCert = targetRecord.getCertificate(); + + // Verify end-entity cert is not revoked. + // TODO: This should be checked during authentication. + if (eeSerialNumber != null && + eeSerialNumber.equals(targetCert.getSerialNumber()) && + targetRecord.getStatus().equals(ICertRecord.STATUS_REVOKED)) { + processor.log(ILogger.LL_FAILURE, + CMS.getLogMessage("CA_CERTIFICATE_ALREADY_REVOKED_1", + targetRecord.getSerialNumber().toString(16))); + + throw new ECMSGWException(CMS.getLogMessage("CMSGW_UNAUTHORIZED")); + } + + IArgBlock rarg = CMS.createArgBlock(); + rarg.addStringValue("serialNumber", targetCert.getSerialNumber().toString(16)); + + try { + if (mAuthority instanceof ICertificateAuthority && + certAuthority.noncesEnabled() && + !processor.isMemberOfSubsystemGroup(clientCert)) { + // validate nonce for each certificate + Long nonce = nonceMap.get(targetRecord.getSerialNumber()); + processor.validateNonce(req, "cert-revoke", targetRecord.getSerialNumber(), nonce); + } + + processor.validateCertificateToRevoke(eeSubjectDN, targetRecord, false); + processor.addCertificateToRevoke(targetCert); + rarg.addStringValue("error", null); + + } catch (PKIException ex) { + rarg.addStringValue("error", ex.getMessage()); + } + + argSet.addRepeatRecord(rarg); + } + + } else if (mAuthority instanceof IRegistrationAuthority) { + String reqIdStr = req.getParameter("requestId"); + Collection<CertId> certSerialNumbers = new ArrayList<CertId>(); + + if (revokeAll != null && revokeAll.length() > 0) { + for (int i = revokeAll.indexOf('='); i > -1; i = revokeAll.indexOf('=', i)) { + i++; + // skip spaces + while (i < revokeAll.length() && revokeAll.charAt(i) == ' ') { + i++; + } + // xxxx decimal serial number? + String legalDigits = "0123456789"; + int j = i; + + // find legal digits + while (j < revokeAll.length() && legalDigits.indexOf(revokeAll.charAt(j)) != -1) { + j++; + } + if (j > i) { + certSerialNumbers.add(new CertId(revokeAll.substring(i, j))); + } + } + } + + if (reqIdStr != null && reqIdStr.length() > 0 && certSerialNumbers.size() > 0) { + IRequest certReq = mRequestQueue.findRequest(new RequestId(reqIdStr)); + X509CertImpl[] certs = certReq.getExtDataInCertArray(IRequest.OLD_CERTS); + boolean authorized = false; + + for (int i = 0; i < certs.length; i++) { + boolean addToList = false; + + for (CertId certSerialNumber : certSerialNumbers) { + //xxxxx serial number in decimal? + if (certs[i].getSerialNumber().equals(certSerialNumber.toBigInteger()) && + eeSubjectDN != null && eeSubjectDN.equals(certs[i].getSubjectDN().toString())) { + addToList = true; + break; + } + } + + if (eeSerialNumber != null && eeSerialNumber.equals(certs[i].getSerialNumber())) { + authorized = true; + } + + if (addToList) { + IArgBlock rarg = CMS.createArgBlock(); + + rarg.addStringValue("serialNumber", certs[i].getSerialNumber().toString(16)); + + processor.addCertificateToRevoke(certs[i]); + + rarg.addStringValue("error", null); + argSet.addRepeatRecord(rarg); + } + } + + if (!authorized) { + processor.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REQ_AUTH_REVOKED_CERT")); + throw new ECMSGWException(CMS.getLogMessage("CMSGW_UNAUTHORIZED")); + } + + } else { + String b64eCert = req.getParameter("b64eCertificate"); + + if (b64eCert != null) { + // BASE64Decoder decoder = new BASE64Decoder(); + // byte[] certBytes = decoder.decodeBuffer(b64eCert); + byte[] certBytes = CMS.AtoB(b64eCert); + X509CertImpl cert = new X509CertImpl(certBytes); + IArgBlock rarg = CMS.createArgBlock(); + + rarg.addStringValue("serialNumber", cert.getSerialNumber().toString(16)); + + processor.addCertificateToRevoke(cert); + + rarg.addStringValue("error", null); + argSet.addRepeatRecord(rarg); + } + } + } + + int count = processor.getCertificates().size(); + if (count == 0) { + processor.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REV_CERTS_ZERO")); + throw new ECMSGWException(CMS.getLogMessage("CMSGW_REVOCATION_ERROR_CERT_NOT_FOUND")); + } + + header.addIntegerValue("totalRecordCount", count); + + processor.createRevocationRequest(); + + processor.auditChangeRequest(ILogger.SUCCESS); + + } catch (ForbiddenException e) { + throw new EAuthzException(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR")); + + } catch (CertificateException e) { + processor.log(ILogger.LL_FAILURE, "Error " + e); + processor.auditChangeRequest(ILogger.FAILURE); + + // TODO: throw exception or return? + // throw new EBaseException(e.getMessage()); + return; + + } catch (EBaseException e) { + processor.log(ILogger.LL_FAILURE, "Error " + e); + processor.auditChangeRequest(ILogger.FAILURE); + + throw e; + + } catch (IOException e) { + processor.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED_1", e.toString())); + processor.auditChangeRequest(ILogger.FAILURE); + + throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED")); + } + + // change audit processing from "REQUEST" to "REQUEST_PROCESSED" + // to distinguish which type of signed audit log message to save + // as a failure outcome in case an exception occurs + + try { + processor.processRevocationRequest(); + IRequest revReq = processor.getRequest(); + + // retrieve the request status + RequestStatus status = revReq.getRequestStatus(); + processor.setRequestStatus(status); + + String type = revReq.getRequestType(); + + // The SVC_PENDING check has been added for the Cloned CA request + // that is meant for the Master CA. From Clone's point of view + // the request is complete + + if (status == RequestStatus.COMPLETE + || status == RequestStatus.SVC_PENDING + && type.equals(IRequest.CLA_CERT4CRL_REQUEST)) { + + header.addStringValue("revoked", "yes"); + + Integer updateCRLResult = revReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS); + + if (updateCRLResult != null) { + header.addStringValue("updateCRL", "yes"); + if (updateCRLResult.equals(IRequest.RES_SUCCESS)) { + header.addStringValue("updateCRLSuccess", "yes"); + } else { + header.addStringValue("updateCRLSuccess", "no"); + String crlError = revReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR); + + if (crlError != null) + header.addStringValue("updateCRLError", crlError); + } + + // let known crl publishing status too. + Integer publishCRLResult = revReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS); + + if (publishCRLResult != null) { + if (publishCRLResult.equals(IRequest.RES_SUCCESS)) { + header.addStringValue("publishCRLSuccess", "yes"); + } else { + header.addStringValue("publishCRLSuccess", "no"); + String publError = revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR); + + if (publError != null) + header.addStringValue("publishCRLError", publError); + } + } + } + + if (mAuthority instanceof ICertificateAuthority) { + // let known update and publish status of all crls. + Enumeration<ICRLIssuingPoint> otherCRLs = + ((ICertificateAuthority) mAuthority).getCRLIssuingPoints(); + + while (otherCRLs.hasMoreElements()) { + ICRLIssuingPoint crl = otherCRLs.nextElement(); + String crlId = crl.getId(); + + if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL)) + continue; + + String updateStatusStr = crl.getCrlUpdateStatusStr(); + Integer updateResult = revReq.getExtDataInInteger(updateStatusStr); + + if (updateResult != null) { + if (updateResult.equals(IRequest.RES_SUCCESS)) { + CMS.debug("DoRevoke: " + + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER", updateStatusStr)); + header.addStringValue(updateStatusStr, "yes"); + + } else { + String updateErrorStr = crl.getCrlUpdateErrorStr(); + + CMS.debug("DoRevoke: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER_NO", + updateStatusStr)); + header.addStringValue(updateStatusStr, "no"); + String error = revReq.getExtDataInString(updateErrorStr); + + if (error != null) + header.addStringValue(updateErrorStr, error); + } + + String publishStatusStr = crl.getCrlPublishStatusStr(); + Integer publishResult = revReq.getExtDataInInteger(publishStatusStr); + + if (publishResult == null) + continue; + + if (publishResult.equals(IRequest.RES_SUCCESS)) { + header.addStringValue(publishStatusStr, "yes"); + + } else { + String publishErrorStr = crl.getCrlPublishErrorStr(); + header.addStringValue(publishStatusStr, "no"); + String error = revReq.getExtDataInString(publishErrorStr); + + if (error != null) + header.addStringValue(publishErrorStr, error); + } + } + } + } + + if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) { + header.addStringValue("dirEnabled", "yes"); + Integer[] ldapPublishStatus = revReq.getExtDataInIntegerArray("ldapPublishStatus"); + int certsToUpdate = 0; + int certsUpdated = 0; + + if (ldapPublishStatus != null) { + certsToUpdate = ldapPublishStatus.length; + for (int i = 0; i < certsToUpdate; i++) { + if (ldapPublishStatus[i] == IRequest.RES_SUCCESS) { + certsUpdated++; + } + } + } + + header.addIntegerValue("certsUpdated", certsUpdated); + header.addIntegerValue("certsToUpdate", certsToUpdate); + + // add crl publishing status. + String publError = revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR); + + if (publError != null) { + header.addStringValue("crlPublishError", publError); + } + + } else { + header.addStringValue("dirEnabled", "no"); + } + + header.addStringValue("error", null); + + } else { + if (status == RequestStatus.PENDING || status == RequestStatus.REJECTED) { + header.addStringValue("revoked", status.toString()); + } else { + header.addStringValue("revoked", "no"); + } + + Vector<String> errors = revReq.getExtDataInStringVector(IRequest.ERRORS); + if (errors != null) { + StringBuilder errInfo = new StringBuilder(); + for (int i = 0; i < errors.size(); i++) { + errInfo.append(errors.elementAt(i)); + errInfo.append("\n"); + } + header.addStringValue("error", errInfo.toString()); + + } else if (status == RequestStatus.PENDING) { + header.addStringValue("error", "Request Pending"); + + } else { + header.addStringValue("error", null); + } + } + + processor.auditChangeRequestProcessed(ILogger.SUCCESS); + + } catch (EBaseException e) { + processor.log(ILogger.LL_FAILURE, "Error " + e); + processor.auditChangeRequestProcessed(ILogger.FAILURE); + + throw e; + } + } + + /** + * Signed Audit Log Requester ID + * + * This method is called to obtain the "RequesterID" for + * a signed audit log message. + * <P> + * + * @param req HTTP request + * @return id string containing the signed audit log message RequesterID + */ + private RequestId auditRequesterID(HttpServletRequest req) { + String requesterID = req.getParameter("requestId"); + + if (requesterID != null) { + return new RequestId(requesterID.trim()); + } else { + return null; + } + } + + /** + * This method parses a String serial number into BigInteger. + * + * @param serialNumber a String containing the un-normalized serial number + * @return a BigInteger containing the serial number + */ + private BigInteger parseSerialNumber(String serialNumber) { + + if (StringUtils.isEmpty(serialNumber)) return null; + + // Normalize the serialNumber + serialNumber = serialNumber.trim(); + + // find out if the value is hex or decimal + + //try decimal + try { + return new BigInteger(serialNumber, 10); + } catch (NumberFormatException e) { + } + + //try hex + try { + return new BigInteger(serialNumber, 16); + } catch (NumberFormatException e) { + } + + // give up if it isn't hex or dec + throw new NumberFormatException("Invalid serial number: "+serialNumber); + } +} |