summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cms/servlet/cert
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cms/servlet/cert')
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java1141
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java701
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java160
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java242
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java173
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java465
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java469
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java231
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java1156
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java911
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java659
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java613
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java183
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java1831
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java292
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java405
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java468
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java338
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java174
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java368
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java1241
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java372
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java733
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java389
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java281
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java607
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java517
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java386
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java101
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java758
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java512
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java734
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java2126
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java142
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java187
35 files changed, 20066 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
new file mode 100644
index 000000000..9ed435c07
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
@@ -0,0 +1,1141 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Locale;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.*;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.request.*;
+
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Revoke a certificate with a CMC-formatted revocation request
+ *
+ * @version $Revision$, $Date$
+ */
+public class CMCRevReqServlet extends CMSServlet {
+ public final static String GETCERTS_FOR_CHALLENGE_REQUEST = "getCertsForChallenge";
+ public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke";
+ // revocation templates.
+ private final static String TPL_FILE = "revocationResult.template";
+ public static final String CRED_CMC = "cmcRequest";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String mRequestID = null;
+ private final static String REVOKE = "revoke";
+ private final static String ON_HOLD = "on-hold";
+ private final static int ON_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ // http params
+ public static final String SERIAL_NO = TOKEN_CERT_SERIAL;
+ public static final String REASON_CODE = "reasonCode";
+ public static final String CHALLENGE_PHRASE = "challengePhrase";
+
+ // request attributes
+ public static final String SERIALNO_ARRAY = "serialNoArray";
+
+ public CMCRevReqServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+
+ super.init(sc);
+
+ String authorityId = mAuthority.getId();
+
+ mFormPath = "/" + authorityId + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * <ul>
+ * <li>http.param cmcRequest the base-64 encoded CMC request
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq) throws EBaseException {
+
+ String cmcAgentSerialNumber = null;
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+CMS.debug("**** mFormPath = "+mFormPath);
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+
+ String cmc = (String) httpParams.get(CRED_CMC);
+ if (cmc == null) {
+ throw new EMissingCredential(
+ CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CMC));
+ }
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+ try {
+ authzToken = authorize(mAclMethod, authToken, mAuthzResourceName, "revoke");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ //IAuthToken authToken = getAuthToken(cmsReq);
+ //Object subject = authToken.get(CMCAuth.TOKEN_CERT_SERIAL);
+ //Object uid = authToken.get("uid");
+ //===========================
+ String authMgr = AuditFormat.NOAUTH;
+ BigInteger[] serialNoArray = null;
+
+ if (authToken != null) {
+ serialNoArray = authToken.getInBigIntegerArray(TOKEN_CERT_SERIAL);
+ }
+
+ Integer reasonCode = Integer.valueOf(0);
+ if (authToken != null) {
+ reasonCode = authToken.getInInteger(REASON_CODE);
+ }
+ RevocationReason reason = RevocationReason.fromInt(reasonCode.intValue());
+
+ String comments = "";
+ Date invalidityDate = null;
+ String revokeAll = null;
+ int verifiedRecordCount = 0;
+ int totalRecordCount = 0;
+
+ if (serialNoArray != null) {
+ totalRecordCount = serialNoArray.length;
+ verifiedRecordCount = serialNoArray.length;
+ }
+
+ X509CertImpl[] certs = null;
+
+ //for audit log.
+ String initiative = null;
+
+ if (mAuthMgr != null && mAuthMgr.equals("CMCAuth")) {
+ // request is from agent
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ initiative = AuditFormat.FROMUSER;
+ }
+
+ if ((serialNoArray != null) && (serialNoArray.length > 0)) {
+ if (mAuthority instanceof ICertificateAuthority) {
+ certs = new X509CertImpl[serialNoArray.length];
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ certs[i] = ((ICertificateAuthority) mAuthority).getCertificateRepository().getX509Certificate(serialNoArray[i]);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ IRequest getCertsChallengeReq = null;
+
+ getCertsChallengeReq = mQueue.newRequest(
+ GETCERTS_FOR_CHALLENGE_REQUEST);
+ getCertsChallengeReq.setExtData(SERIALNO_ARRAY, serialNoArray);
+ mQueue.processRequest(getCertsChallengeReq);
+ RequestStatus status = getCertsChallengeReq.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ certs = getCertsChallengeReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+ header.addStringValue("request", getCertsChallengeReq.getRequestId().toString());
+ mRequestID = getCertsChallengeReq.getRequestId().toString();
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_FAIL_GET_CERT_CHALL_PWRD"));
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", serialNoArray.length);
+ header.addIntegerValue("verifiedRecordCount", serialNoArray.length);
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ serialNoArray[i], 16);
+ rarg.addStringValue("subject",
+ certs[i].getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ certs[i].getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ certs[i].getNotAfter().getTime() / 1000);
+ //argSet.addRepeatRecord(rarg);
+ }
+
+ revokeAll = "(|(certRecordId=" + serialNoArray[0].toString() + "))";
+ cmcAgentSerialNumber= authToken.getInString(IAuthManager.CRED_SSL_CLIENT_CERT);
+ process(argSet, header, reasonCode.intValue(), invalidityDate, initiative, req, resp,
+ verifiedRecordCount, revokeAll, totalRecordCount,
+ comments, locale[0],cmcAgentSerialNumber);
+
+ } else {
+ header.addIntegerValue("totalRecordCount", 0);
+ header.addIntegerValue("verifiedRecordCount", 0);
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if ((serialNoArray== null) || (serialNoArray.length == 0)) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ EBaseException ee = new EBaseException("No matched certificate is found");
+
+ cmsReq.setError(ee);
+ } else if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * get cert to revoke from agent.
+ */
+ private BigInteger getCertFromAgent(
+ IArgBlock httpParams, X509Certificate[] certContainer)
+ throws EBaseException {
+ BigInteger serialno = null;
+ X509Certificate cert = null;
+
+ // get serial no
+ serialno = httpParams.getValueAsBigInteger(SERIAL_NO, null);
+ if (serialno == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_REVOKE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SERIALNO_FOR_REVOKE"));
+ }
+
+ // get cert from db if we're cert authority.
+ if (mAuthority instanceof ICertificateAuthority) {
+ cert = getX509Certificate(serialno);
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ }
+ certContainer[0] = cert;
+ return serialno;
+ }
+
+ /**
+ * Revoke the specified certificate
+ */
+ private BigInteger getCertFromAuthMgr(
+ AuthToken authToken, X509Certificate[] certContainer)
+ throws EBaseException {
+ X509CertImpl cert =
+ authToken.getInCert(AuthToken.TOKEN_CERT);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ certContainer[0] = cert;
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ return serialno;
+ }
+
+ /**
+ * get cert to revoke from ssl
+ */
+ private BigInteger getCertFromSSL(
+ HttpServletRequest req, X509CertImpl[] certContainer)
+ throws EBaseException {
+ X509Certificate cert = getSSLClientCertificate(req);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_REVOKE_FROM_SSL"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_REVOKE_FROM_SSL"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION", ""));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ certContainer[0] = (X509CertImpl) cert;
+
+ return serialno;
+ }
+
+ /**
+ * Process cert status change request using the Certificate Management
+ * protocol using CMS (CMC)
+ * <P>
+ *
+ * (Certificate Request - an "EE" cert status change request)
+ * <P>
+ *
+ * (Certificate Request Processed - 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 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,
+ String comments,
+ Locale locale,String cmcAgentSerialNumber)
+ throws EBaseException {
+ String eeSerialNumber = null;
+ if(cmcAgentSerialNumber!=null) {
+ eeSerialNumber = cmcAgentSerialNumber;
+ }else{
+ X509CertImpl sslCert = ( X509CertImpl ) getSSLClientCertificate( req );
+ if( sslCert != null ) {
+ eeSerialNumber = sslCert.getSerialNumber().toString();
+ }
+ }
+
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID( req );
+ String auditSerialNumber = auditSerialNumber( eeSerialNumber );
+ String auditRequestType = auditRequestType( reason );
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf( reason );
+
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertRecordList list = (ICertRecordList) mCertDB.findCertRecordsInList(
+ revokeAll, null, totalRecordCount);
+ Enumeration e = list.getCertRecords(0, totalRecordCount - 1);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ rarg.addStringValue("error", "Certificate " +
+ cert.getSerialNumber().toString() +
+ " is already revoked.");
+ } else {
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ String reqIdStr = null;
+
+ if (mRequestID != null && mRequestID.length() > 0)
+ reqIdStr = mRequestID;
+ Vector serialNumbers = new Vector();
+
+ if (revokeAll != null && revokeAll.length() > 0) {
+ for (int i = revokeAll.indexOf('=');
+ i < revokeAll.length() && i > -1;
+ i = revokeAll.indexOf('=', i)) {
+ if (i > -1) {
+ i++;
+ while (i < revokeAll.length() && revokeAll.charAt(i) == ' ') {
+ i++;
+ }
+ String legalDigits = "0123456789";
+ int j = i;
+
+ while (j < revokeAll.length() &&
+ legalDigits.indexOf(revokeAll.charAt(j)) != -1) {
+ j++;
+ }
+ if (j > i) {
+ serialNumbers.addElement(revokeAll.substring(i, j));
+ }
+ }
+ }
+ }
+ if (reqIdStr != null && reqIdStr.length() > 0 && serialNumbers.size() > 0) {
+ IRequest certReq = mRequestQueue.findRequest(new RequestId(reqIdStr));
+ X509CertImpl[] certs = certReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ for (int i = 0; i < certs.length; i++) {
+ boolean addToList = false;
+
+ for (int j = 0; j < serialNumbers.size(); j++) {
+ if (certs[i].getSerialNumber().toString().equals(
+ (String) serialNumbers.elementAt(j))) {
+ addToList = true;
+ break;
+ }
+ }
+ if (addToList) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ certs[i].getSerialNumber(), 16);
+ oldCertsV.addElement(certs[i]);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(certs[i].getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } else {
+ String b64eCert = req.getParameter("b64eCertificate");
+
+ if (b64eCert != null) {
+ byte[] certBytes = com.netscape.osutil.OSUtil.AtoB(b64eCert);
+ X509CertImpl cert = new X509CertImpl(certBytes);
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", count);
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+ revReq.setExtData(IRequest.REVOKED_REASON, reason);
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+
+ // 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
+ auditRequest = false;
+
+ mQueue.processRequest(revReq);
+
+ // retrieve the request status
+ auditApprovalStatus = revReq.getRequestStatus().toString();
+
+ RequestStatus stat = revReq.getRequestStatus();
+
+ if (stat == RequestStatus.COMPLETE) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ 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 otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ 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("CMCRevReqServlet: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER",
+ updateStatusStr));
+ header.addStringValue(updateStatusStr, "yes");
+ } else {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("CMCRevReqServlet: " + 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 (stat == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ header.addStringValue("revoked", "pending");
+ // audit log the pending
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "pending",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ } else {
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ StringBuffer errorStr = new StringBuffer();
+
+ if (errors != null && errors.size() > 0) {
+ for (int ii = 0; ii < errors.size(); ii++) {
+ errorStr.append(errors.elementAt(ii));;
+ }
+ }
+ header.addStringValue("error", errorStr.toString());
+ header.addStringValue("revoked", "no");
+ // audit log the error
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (CertificateException e) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ log(ILogger.LL_FAILURE, "error " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED", e.toString()));
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ } catch (Exception e) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING)))
+ {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ e.printStackTrace();
+ }
+
+ return;
+ }
+
+ /**
+ * 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 String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+
+ /**
+ * Signed Audit Log Request Type
+ *
+ * This method is called to obtain the "Request Type" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param reason an integer denoting the revocation reason
+ * @return string containing REVOKE or ON_HOLD
+ */
+ private String auditRequestType(int reason) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requestType = null;
+
+ // Determine the revocation type based upon the revocation reason
+ if (reason == ON_HOLD_REASON) {
+ requestType = ON_HOLD;
+ } else {
+ requestType = REVOKE;
+ }
+
+ return requestType;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java
new file mode 100644
index 000000000..d3e7a5a32
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ChallengeRevocationServlet1.java
@@ -0,0 +1,701 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.util.Locale;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.*;
+
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.publish.*;
+
+
+/**
+ * Takes the certificate info (serial number) and optional challenge phrase, creates a
+ * revocation request and submits it to the authority subsystem for processing
+ *
+ * @version $Revision$, $Date$
+ */
+public class ChallengeRevocationServlet1 extends CMSServlet {
+ public final static String GETCERTS_FOR_CHALLENGE_REQUEST = "getCertsForChallenge";
+ public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke";
+ // revocation templates.
+ private final static String TPL_FILE = "revocationResult.template";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String mRequestID = null;
+
+ // http params
+ public static final String SERIAL_NO = TOKEN_CERT_SERIAL;
+ public static final String REASON_CODE = "reasonCode";
+ public static final String CHALLENGE_PHRASE = "challengePhrase";
+
+ // request attributes
+ public static final String SERIALNO_ARRAY = "serialNoArray";
+
+ public ChallengeRevocationServlet1() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the file
+ * revocationResult.template for the response
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ String authorityId = mAuthority.getId();
+
+ mFormPath = "/" + authorityId + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param REASON_CODE the revocation reason
+ * <li>http.param b64eCertificate the base-64 encoded certificate to revoke
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ // for audit log
+ IAuthToken authToken = authenticate(cmsReq);
+ String authMgr = AuditFormat.NOAUTH;
+
+ BigInteger[] serialNoArray = null;
+
+ if (authToken != null) {
+ serialNoArray = authToken.getInBigIntegerArray(SERIAL_NO);
+ }
+ // set revocation reason, default to unspecified if not set.
+ int reasonCode =
+ httpParams.getValueAsInt(REASON_CODE, 0);
+ // header.addIntegerValue("reason", reasonCode);
+ RevocationReason reason = RevocationReason.fromInt(reasonCode);
+
+ String comments = req.getParameter(IRequest.REQUESTOR_COMMENTS);
+ Date invalidityDate = null;
+ String revokeAll = null;
+ int totalRecordCount = (serialNoArray != null)? serialNoArray.length:0;
+ int verifiedRecordCount = (serialNoArray != null)? serialNoArray.length:0;
+
+ X509CertImpl[] certs = null;
+
+ //for audit log.
+ String initiative = null;
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ // request is from agent
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ initiative = AuditFormat.FROMUSER;
+ }
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "revoke");
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ if (serialNoArray != null && serialNoArray.length > 0) {
+ if (mAuthority instanceof ICertificateAuthority) {
+ certs = new X509CertImpl[serialNoArray.length];
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ certs[i] = ((ICertificateAuthority) mAuthority).getCertificateRepository().getX509Certificate(serialNoArray[i]);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ IRequest getCertsChallengeReq = null;
+
+ getCertsChallengeReq = mQueue.newRequest(
+ GETCERTS_FOR_CHALLENGE_REQUEST);
+ getCertsChallengeReq.setExtData(SERIALNO_ARRAY, serialNoArray);
+ mQueue.processRequest(getCertsChallengeReq);
+ RequestStatus status = getCertsChallengeReq.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ certs = getCertsChallengeReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+ header.addStringValue("request", getCertsChallengeReq.getRequestId().toString());
+ mRequestID = getCertsChallengeReq.getRequestId().toString();
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_FAIL_GET_CERT_CHALL_PWRD"));
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", serialNoArray.length);
+ header.addIntegerValue("verifiedRecordCount", serialNoArray.length);
+
+ for (int i = 0; i < serialNoArray.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ serialNoArray[i], 16);
+ rarg.addStringValue("subject",
+ certs[i].getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ certs[i].getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ certs[i].getNotAfter().getTime() / 1000);
+ //argSet.addRepeatRecord(rarg);
+ }
+
+ revokeAll = "(|(certRecordId=" + serialNoArray[0].toString() + "))";
+ process(argSet, header, reasonCode, invalidityDate, initiative, req, resp,
+ verifiedRecordCount, revokeAll, totalRecordCount,
+ comments, locale[0]);
+ } else {
+ header.addIntegerValue("totalRecordCount", 0);
+ header.addIntegerValue("verifiedRecordCount", 0);
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if( serialNoArray == null ) {
+ CMS.debug( "ChallengeRevcationServlet1::process() - " +
+ " serialNoArray is null!" );
+ EBaseException ee = new EBaseException( "No matched certificate is found" );
+
+ cmsReq.setError(ee);
+ return;
+ }
+
+ if (serialNoArray.length == 0) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ EBaseException ee = new EBaseException("No matched certificate is found");
+
+ cmsReq.setError(ee);
+ } else if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int reason, Date invalidityDate,
+ String initiative,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ int verifiedRecordCount,
+ String revokeAll,
+ int totalRecordCount,
+ String comments,
+ Locale locale)
+ throws EBaseException {
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertRecordList list = (ICertRecordList) mCertDB.findCertRecordsInList(
+ revokeAll, null, totalRecordCount);
+ Enumeration e = list.getCertRecords(0, totalRecordCount - 1);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+ X509CertImpl cert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ rarg.addStringValue("error", "Certificate " +
+ cert.getSerialNumber().toString() +
+ " is already revoked.");
+ } else {
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ String reqIdStr = null;
+
+ if (mRequestID != null && mRequestID.length() > 0)
+ reqIdStr = mRequestID;
+ Vector serialNumbers = new Vector();
+
+ if (revokeAll != null && revokeAll.length() > 0) {
+ for (int i = revokeAll.indexOf('=');
+ i < revokeAll.length() && i > -1;
+ i = revokeAll.indexOf('=', i)) {
+ if (i > -1) {
+ i++;
+ while (i < revokeAll.length() && revokeAll.charAt(i) == ' ') {
+ i++;
+ }
+ String legalDigits = "0123456789";
+ int j = i;
+
+ while (j < revokeAll.length() &&
+ legalDigits.indexOf(revokeAll.charAt(j)) != -1) {
+ j++;
+ }
+ if (j > i) {
+ serialNumbers.addElement(revokeAll.substring(i, j));
+ }
+ }
+ }
+ }
+ if (reqIdStr != null && reqIdStr.length() > 0 && serialNumbers.size() > 0) {
+ IRequest certReq = mRequestQueue.findRequest(new RequestId(reqIdStr));
+ X509CertImpl[] certs = certReq.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ for (int i = 0; i < certs.length; i++) {
+ boolean addToList = false;
+
+ for (int j = 0; j < serialNumbers.size(); j++) {
+ if (certs[i].getSerialNumber().toString().equals(
+ (String) serialNumbers.elementAt(j))) {
+ addToList = true;
+ break;
+ }
+ }
+ if (addToList) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ certs[i].getSerialNumber(), 16);
+ oldCertsV.addElement(certs[i]);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(certs[i].getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } else {
+ String b64eCert = req.getParameter("b64eCertificate");
+
+ if (b64eCert != null) {
+ byte[] certBytes = com.netscape.osutil.OSUtil.AtoB(b64eCert);
+ X509CertImpl cert = new X509CertImpl(certBytes);
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addBigIntegerValue("serialNumber",
+ cert.getSerialNumber(), 16);
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", count);
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+
+ mQueue.processRequest(revReq);
+ RequestStatus stat = revReq.getRequestStatus();
+
+ if (stat == RequestStatus.COMPLETE) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ 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 otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ 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("ChallengeRevcationServlet1: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER",
+ updateStatusStr));
+ header.addStringValue(updateStatusStr, "yes");
+ } else {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("ChallengeRevcationServlet1: " + 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 (stat == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ header.addStringValue("revoked", "pending");
+ // audit log the pending
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "pending",
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+
+ } else {
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ StringBuffer errorStr = new StringBuffer();
+
+ if (errors != null && errors.size() > 0) {
+ for (int ii = 0; ii < errors.size(); ii++) {
+ errorStr.append(errors.elementAt(ii));
+ }
+ }
+ header.addStringValue("error", errorStr.toString());
+ header.addStringValue("revoked", "no");
+ // audit log the error
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ oldCerts[j].getSubjectDN(),
+ oldCerts[j].getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java b/pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java
new file mode 100644
index 000000000..59ee9a4ec
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/CloneRedirect.java
@@ -0,0 +1,160 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Redirect a request to the Master. This servlet is used in
+ * a clone when a requested service (such as CRL) is not available.
+ * It redirects the user to the master.
+ *
+ * @version $Revision$, $Date$
+ */
+public class CloneRedirect extends CMSServlet {
+
+ private final static String PROP_REDIRECT_URL = "masterURL";
+ private final static String TPL_FILE = "cloneRedirect.template";
+
+ private String mNewUrl = null;
+ private String mFormPath = null;
+
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs CloneRedirect servlet.
+ */
+ public CloneRedirect() {
+ super();
+
+ }
+
+ /**
+ * Initialize the servlet.
+ * @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;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ IConfigStore authConfig = mCA.getConfigStore();
+
+ if (authConfig != null) {
+ try {
+ mNewUrl = authConfig.getString(PROP_REDIRECT_URL,
+ "*** master URL unavailable, check your configuration ***");
+ } catch (EBaseException e) {
+ // do nothing
+ }
+ }
+ }
+
+ if (mAuthority instanceof ICertificateAuthority)
+ mCA = (ICertificateAuthority) mAuthority;
+
+ // override success to do output with our own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Serves HTTP request.
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ CMS.debug("CloneRedirect: " + CMS.getLogMessage("ADMIN_SRVLT_ADD_MASTER_URL", mNewUrl));
+ header.addStringValue("masterURL", mNewUrl);
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * Display information about redirecting to the master's URL info
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String signatureAlgorithm,
+ Locale locale)
+ throws EBaseException {
+
+ CMS.debug("CloneRedirect: " + CMS.getLogMessage("ADMIN_SRVLT_ADD_MASTER_URL", mNewUrl));
+ header.addStringValue("masterURL", mNewUrl);
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java
new file mode 100644
index 000000000..5e4309494
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DirAuthServlet.java
@@ -0,0 +1,242 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * 'Face-to-face' certificate enrollment.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DirAuthServlet extends CMSServlet {
+ private final static String TPL_FILE = "/ra/hashEnrollmentSubmit.template";
+ private final static String TPL_ERROR_FILE = "/ra/GenErrorHashDirEnroll.template";
+ private String mFormPath = null;
+
+ public DirAuthServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ try {
+ mFormPath = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mFormPath == null)
+ mFormPath = TPL_FILE;
+ } catch (Exception e) {
+ }
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+
+ /**
+ * Process the HTTP request. This servlet reads configuration information
+ * from the hashDirEnrollment configuration substore
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ String reqHost = httpReq.getRemoteHost();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ Date date = new Date();
+ long currTime = date.getTime();
+ long timeout = mgr.getTimeout(reqHost);
+ long lastlogin = mgr.getLastLogin(reqHost);
+ long diff = currTime - lastlogin;
+
+ boolean enable = mgr.isEnable(reqHost);
+
+ if (!enable) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+ if (lastlogin == 0)
+ mgr.setLastLogin(reqHost, currTime);
+ else if (diff > timeout) {
+ mgr.disable(reqHost);
+ printError(cmsReq, "2");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ mgr.setLastLogin(reqHost, currTime);
+
+ String uid = args.getValueAsString("uid");
+ long pageid = mgr.getPageID();
+ String pageID = pageid + "";
+
+ mgr.addAuthToken(pageID, authToken);
+
+ header.addStringValue("pageID", pageID);
+ header.addStringValue("uid", uid);
+ header.addStringValue("fingerprint", mgr.hashFingerprint(reqHost, pageID, uid));
+ header.addStringValue("hostname", reqHost);
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ private void printError(CMSRequest cmsReq, String errorCode)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ header.addStringValue("authority", "Registration Manager");
+ header.addStringValue("errorCode", errorCode);
+ String formPath = TPL_ERROR_FILE;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(formPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", formPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java
new file mode 100644
index 000000000..d75844d2a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisableEnrollResult.java
@@ -0,0 +1,173 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * For Face-to-face enrollment, disable EE enrollment feature
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.cms.servlet.cert.EnableEnrollResult
+ */
+public class DisableEnrollResult extends CMSServlet {
+ private final static String TPL_FILE = "enableEnrollResult.template";
+ private String mFormPath = null;
+
+ public DisableEnrollResult() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Services the request
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken token = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, token,
+ mAuthzResourceName, "disable");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ X509Certificate sslClientCert = null;
+
+ sslClientCert = getSSLClientCertificate(httpReq);
+ String dn = (String) sslClientCert.getSubjectDN().toString();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getLogMessage("CMSGW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ String host = args.getValueAsString("hosts", null);
+ String name = mgr.getAgentName(host);
+
+ if (name == null) {
+ header.addStringValue("code", "2");
+ } else if (name.equals(dn)) {
+ mgr.disable(host);
+ header.addStringValue("code", "2");
+ } else {
+ header.addStringValue("code", "3");
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java
new file mode 100644
index 000000000..3a0c48a94
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayBySerial.java
@@ -0,0 +1,465 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Display detailed information about a certificate
+ *
+ * The template 'displayBySerial.template' is used to
+ * render the response for this servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerial extends CMSServlet {
+
+ private final static String INFO = "DisplayBySerial";
+ private final static String TPL_FILE1 = "displayBySerial.template";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private ICertificateRepository mCertDB = null;
+ private String mForm1Path = null;
+ private X509Certificate mCACerts[] = null;
+
+ /**
+ * Constructs DisplayBySerial servlet.
+ */
+ public DisplayBySerial() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ try {
+ mCACerts = ((ICertAuthority) mAuthority).getCACertChain().getChain();
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CA_CHAIN_NOT_AVAILABLE"));
+ }
+ // coming from ee
+ mForm1Path = "/" + mAuthority.getId() + "/" + TPL_FILE1;
+
+ if (mOutputTemplatePath != null)
+ mForm1Path = mOutputTemplatePath;
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Serves HTTP request. The format of this request is as follows:
+ * <ul>
+ * <li>http.param serialNumber Decimal serial number of certificate to display
+ * (or hex if serialNumber preceded by 0x)
+ * </ul>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ BigInteger serialNumber = MINUS_ONE;
+ EBaseException error = null;
+ String certType[] = new String[1];
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString()));
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ serialNumber = getSerialNumber(req);
+ ICertRecord rec = getCertRecord(serialNumber, certType);
+
+ if (certType[0].equalsIgnoreCase("x509")) {
+ form = getTemplate(mForm1Path, req, locale);
+ }
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT_1", String.valueOf(serialNumber)));
+
+ error = new ECMSGWException(CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mForm1Path, e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ } catch (EDBRecordNotFoundException e) {
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_CERT_SERIAL_NOT_FOUND_1", "0x" + serialNumber.toString(16)));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ try {
+ if (serialNumber.compareTo(MINUS_ONE) > 0) {
+ process(argSet, header, serialNumber,
+ req, resp, locale[0]);
+ } else {
+ error = new ECMSGWException(
+ CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUMBER"));
+ }
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ }
+
+ /**
+ * Display information about a particular certificate
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ BigInteger seq, HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ String certType[] = new String[1];
+
+ try {
+ ICertRecord rec = getCertRecord(seq, certType);
+
+ if (certType[0].equalsIgnoreCase("x509")) {
+ processX509(argSet, header, seq, req, resp, locale);
+ return;
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_DISP_BY_SERIAL", e.toString()));
+ throw e;
+ }
+
+ return;
+ }
+
+ private void processX509(CMSTemplateParams argSet, IArgBlock header,
+ BigInteger seq, HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ try {
+ ICertRecord rec = (ICertRecord) mCertDB.readCertificateRecord(seq);
+ if (rec == null) {
+ CMS.debug("DisplayBySerial: failed to read record");
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+ X509CertImpl cert = rec.getCertificate();
+ if (cert == null) {
+ CMS.debug("DisplayBySerial: no certificate in record");
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+
+ try {
+ X509CertInfo info = (X509CertInfo) cert.get(X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ if (info == null) {
+ CMS.debug("DisplayBySerial: no info found");
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+ CertificateExtensions extensions = (CertificateExtensions) info.get(X509CertInfo.EXTENSIONS);
+
+ 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 e) {
+ // bug356108:
+ // In case there is only DIGITAL_SIGNATURE,
+ // don't report error
+ }
+ }
+ }
+ }
+ header.addBooleanValue("emailCert", emailCert);
+
+ boolean noCertImport = true;
+ MetaInfo metaInfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO);
+
+ if (metaInfo != null) {
+ String rid = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+
+ if (rid != null && mAuthority instanceof ICertificateAuthority) {
+ IRequest r = ((ICertificateAuthority) mAuthority).getRequestQueue().findRequest(new RequestId(rid));
+ String certType = r.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (certType != null && certType.equals(IRequest.CLIENT_CERT)) {
+ noCertImport = false;
+ }
+ }
+ }
+ header.addBooleanValue("noCertImport", noCertImport);
+
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_PARSING_EXTENS", e.toString()));
+ }
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration enumx = crlExts.getElements();
+ int reason = 0;
+
+ while (enumx.hasMoreElements()) {
+ Extension ext = (Extension) enumx.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ }
+ }
+ header.addIntegerValue("revocationReason", reason);
+ }
+ }
+
+ ICertPrettyPrint certDetails = CMS.getCertPrettyPrint(cert);
+
+ header.addStringValue("certPrettyPrint",
+ certDetails.toString(locale));
+
+ /*
+ String scheme = req.getScheme();
+ if (scheme.equals("http") && connectionIsSSL(req))
+ scheme = "https";
+ String requestURI = req.getRequestURI();
+ int i = requestURI.indexOf('?');
+ String newRequestURI =
+ (i > -1)? requestURI.substring(0, i): requestURI;
+ header.addStringValue("serviceURL", scheme +"://"+
+ req.getServerName() + ":"+
+ req.getServerPort() + newRequestURI);
+ */
+ header.addStringValue("authorityid", mAuthority.getId());
+
+ String certFingerprints = "";
+
+ try {
+ certFingerprints = CMS.getFingerPrints(cert);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_DIGESTING_CERT", e.toString()));
+ }
+ if (certFingerprints.length() > 0)
+ header.addStringValue("certFingerprint", certFingerprints);
+
+ byte[] ba = cert.getEncoded();
+ // Do base 64 encoding
+
+ header.addStringValue("certChainBase64", com.netscape.osutil.OSUtil.BtoA(ba));
+ header.addStringValue("serialNumber", seq.toString(16));
+
+ /*
+ String userAgent = req.getHeader("user-agent");
+ String agent =
+ (userAgent != null)? UserInfo.getUserAgent(userAgent): "";
+ */
+ // Now formulate a PKCS#7 blob
+ X509CertImpl[] certsInChain = new X509CertImpl[1];;
+ if (mCACerts != null) {
+ for (int i = 0; i < mCACerts.length; i++) {
+ if (cert.equals(mCACerts[i])) {
+ certsInChain = new
+ X509CertImpl[mCACerts.length];
+ break;
+ }
+ certsInChain = new X509CertImpl[mCACerts.length + 1];
+ }
+ }
+
+ // Set the EE cert
+ certsInChain[0] = cert;
+
+ // Set the Ca certificate chain
+ if (mCACerts != null) {
+ for (int i = 0; i < mCACerts.length; i++) {
+ if (!cert.equals(mCACerts[i]))
+ certsInChain[i + 1] = (X509CertImpl) mCACerts[i];
+ }
+ }
+
+ // Wrap the chain into a degenerate P7 object
+ String p7Str;
+
+ try {
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ certsInChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos,false);
+ byte[] p7Bytes = bos.toByteArray();
+
+ p7Str = com.netscape.osutil.OSUtil.BtoA(p7Bytes);
+ header.addStringValue("pkcs7ChainBase64", p7Str);
+ } catch (Exception e) {
+ //p7Str = "PKCS#7 B64 Encoding error - " + e.toString()
+ //+ "; Please contact your administrator";
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_FORMING_PKCS7_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_FORMING_PKCS7"));
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("MSGW_ERR_DISP_BY_SERIAL", e.toString()));
+ throw e;
+ } catch (CertificateEncodingException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_ENCODE_CERT", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+
+ return;
+ }
+
+ private ICertRecord getCertRecord(BigInteger seq, String certtype[])
+ throws EBaseException {
+ ICertRecord rec = null;
+
+ try {
+ rec = (ICertRecord) mCertDB.readCertificateRecord(seq);
+ X509CertImpl x509cert = rec.getCertificate();
+
+ if (x509cert != null) {
+ certtype[0] = "x509";
+ return rec;
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_DISP_BY_SERIAL", e.toString()));
+ throw e;
+ }
+
+ return rec;
+ }
+
+ private BigInteger getSerialNumber(HttpServletRequest req)
+ throws NumberFormatException {
+ String serialNumString = req.getParameter("serialNumber");
+
+ if (serialNumString != null) {
+ serialNumString = serialNumString.trim();
+ if (serialNumString.startsWith("0x") || serialNumString.startsWith("0X")) {
+ return new BigInteger(serialNumString.substring(2), 16);
+ } else {
+ return new BigInteger(serialNumString);
+ }
+ } else {
+ throw new NumberFormatException();
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java
new file mode 100644
index 000000000..9c7b022dd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayCRL.java
@@ -0,0 +1,469 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import java.security.cert.CRLException;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Decode the CRL and display it to the requester.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayCRL extends CMSServlet {
+
+ private final static String INFO = "DisplayCRL";
+ private final static String TPL_FILE = "displayCRL.template";
+ //private final static String E_TPL_FILE = "error.template";
+ //private final static String OUT_ERROR = "errorDetails";
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs DisplayCRL servlet.
+ */
+ public DisplayCRL() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the 'displayCRL.template' file to
+ * to render the response to the client.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ }
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Process the HTTP request
+ * <ul>
+ * <li>http.param crlIssuingPoint number
+ * <li>http.param crlDisplayType entireCRL or crlHeader or base64Encoded or deltaCRL
+ * <li>http.param pageStart which page to start displaying from
+ * <li>http.param pageSize number of entries to show per page
+ * </ul>
+ * @param cmsReq the Request to service.
+
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ 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_1", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // Note error is covered in the same template as success.
+ EBaseException error = null;
+
+ String crlIssuingPointId = req.getParameter("crlIssuingPoint");
+
+ process(argSet, header, req, resp, crlIssuingPointId,
+ locale[0]);
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", e.toString()));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+ }
+
+ /**
+ * Display information about a particular CRL.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String crlIssuingPointId,
+ Locale locale) {
+ boolean updateStatus = true;
+ EBaseException error = null;
+ ICRLIssuingPoint crlIP = null;
+ X509CRLImpl crl = null;
+ boolean clonedCA = false;
+ boolean isCRLCacheEnabled = false;
+ String masterHost = null;
+ String masterPort = null;
+ Vector ipNames = null;
+ String ipId = crlIssuingPointId;
+ ICRLRepository crlRepository = mCA.getCRLRepository();
+
+ try {
+ masterHost = CMS.getConfigStore().getString("master.ca.agent.host", "");
+ masterPort = CMS.getConfigStore().getString("master.ca.agent.port", "");
+ if (masterHost != null && masterHost.length() > 0 &&
+ masterPort != null && masterPort.length() > 0) {
+ clonedCA = true;
+ ipNames = crlRepository.getIssuingPointsNames();
+ }
+ } catch (EBaseException e) {
+ }
+
+ if (clonedCA) {
+ if (crlIssuingPointId != null) {
+ if (ipNames != null && ipNames.size() > 0) {
+ int i;
+ for (i = 0; i < ipNames.size(); i++) {
+ String ipName = (String)ipNames.elementAt(i);
+ if (crlIssuingPointId.equals(ipName)) {
+ break;
+ }
+ }
+ if (i >= ipNames.size()) crlIssuingPointId = null;
+ } else {
+ crlIssuingPointId = null;
+ }
+ }
+ } else {
+ if (crlIssuingPointId != null) {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (crlIssuingPointId.equals(ip.getId())) {
+ crlIP = ip;
+ isCRLCacheEnabled = ip.isCRLCacheEnabled();
+ break;
+ }
+ if (!ips.hasMoreElements()) crlIssuingPointId = null;
+ }
+ }
+ }
+ if (crlIssuingPointId == null) {
+ header.addStringValue("error",
+ "Request to unspecified or non-existing CRL issuing point: "+ipId);
+ return;
+ }
+
+ ICRLIssuingPointRecord crlRecord = null;
+
+ String crlDisplayType = req.getParameter("crlDisplayType");
+
+ if (crlDisplayType == null) crlDisplayType = "cachedCRL";
+ header.addStringValue("crlDisplayType", crlDisplayType);
+
+ try {
+ crlRecord =
+ (ICRLIssuingPointRecord) mCA.getCRLRepository().readCRLIssuingPointRecord(crlIssuingPointId);
+ } catch (EBaseException e) {
+ header.addStringValue("error", e.toString(locale));
+ return;
+ }
+ if (crlRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlIssuingPointId));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ return;
+ }
+
+ header.addStringValue("crlIssuingPoint", crlIssuingPointId);
+ if (crlDisplayType.equals("deltaCRL")) {
+ if (clonedCA) {
+ header.addStringValue("crlNumber", crlRecord.getDeltaCRLNumber().toString());
+ } else {
+ header.addStringValue("crlNumber", crlIP.getDeltaCRLNumber().toString());
+ }
+ } else {
+ if (clonedCA) {
+ header.addStringValue("crlNumber", crlRecord.getCRLNumber().toString());
+ } else {
+ header.addStringValue("crlNumber", crlIP.getCRLNumber().toString());
+ }
+ }
+ long lCRLSize = crlRecord.getCRLSize().longValue();
+ header.addLongValue("crlSize", lCRLSize);
+
+ if (crlIP != null) {
+ header.addStringValue("crlDescription", crlIP.getDescription());
+ }
+
+ if (!crlDisplayType.equals("cachedCRL")) {
+ byte[] crlbytes = crlRecord.getCRL();
+
+ if (crlbytes == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlIssuingPointId));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ return;
+ }
+
+ try {
+ if (crlDisplayType.equals("crlHeader")) {
+ crl = new X509CRLImpl(crlbytes, false);
+ } else {
+ crl = new X509CRLImpl(crlbytes);
+ }
+
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_CRL", e.toString()));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ }
+ }
+
+ if (crl != null || (isCRLCacheEnabled && crlDisplayType.equals("cachedCRL"))) {
+ if (crlDisplayType.equals("entireCRL") || crlDisplayType.equals("cachedCRL")) {
+ ICRLPrettyPrint crlDetails = null;
+ if (crlDisplayType.equals("entireCRL")) {
+ crlDetails = CMS.getCRLPrettyPrint(crl);
+ } else {
+ crlDetails = CMS.getCRLCachePrettyPrint(crlIP);
+ }
+
+ String pageStart = req.getParameter("pageStart");
+ String pageSize = req.getParameter("pageSize");
+
+ if (pageStart != null && pageSize != null) {
+ long lPageStart = new Long(pageStart).longValue();
+ long lPageSize = new Long(pageSize).longValue();
+
+ if (lPageStart < 1) lPageStart = 1;
+ // if (lPageStart + lPageSize - lCRLSize > 1)
+ // lPageStart = lCRLSize - lPageSize + 1;
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale,
+ lCRLSize, lPageStart, lPageSize));
+ header.addLongValue("pageStart", lPageStart);
+ header.addLongValue("pageSize", lPageSize);
+ } else {
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale));
+ }
+ } else if (crlDisplayType.equals("crlHeader")) {
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(crl);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale, lCRLSize, 0, 0));
+ } else if (crlDisplayType.equals("base64Encoded")) {
+ try {
+ byte[] ba = crl.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ if (i >= length) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ argSet.addRepeatRecord(rarg);
+ }
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ } else if (crlDisplayType.equals("deltaCRL")) {
+ if ((clonedCA && crlRecord.getDeltaCRLSize() != null &&
+ crlRecord.getDeltaCRLSize().longValue() > -1) ||
+ (crlIP != null && crlIP.isDeltaCRLEnabled())) {
+ byte[] deltaCRLBytes = crlRecord.getDeltaCRL();
+
+ if (deltaCRLBytes == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_NO_DELTA_CRL", crlIssuingPointId));
+ header.addStringValue("error", "Delta CRL is not available");
+ } else {
+ X509CRLImpl deltaCRL = null;
+
+ try {
+ deltaCRL = new X509CRLImpl(deltaCRLBytes);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_DELTA_CRL", e.toString()));
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ }
+ if (deltaCRL != null) {
+ BigInteger crlNumber = crlRecord.getCRLNumber();
+ BigInteger deltaNumber = crlRecord.getDeltaCRLNumber();
+ if ((clonedCA && crlNumber != null && deltaNumber != null &&
+ deltaNumber.compareTo(crlNumber) >= 0) ||
+ (crlIP != null && crlIP.isThisCurrentDeltaCRL(deltaCRL))) {
+
+ header.addIntegerValue("deltaCRLSize",
+ deltaCRL.getNumberOfRevokedCertificates());
+
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(deltaCRL);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale, 0, 0, 0));
+
+ try {
+ byte[] ba = deltaCRL.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ if (i >= length) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ argSet.addRepeatRecord(rarg);
+ }
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ } else {
+ header.addStringValue("error", "Current Delta CRL is not available.");
+ }
+ }
+ }
+ } else {
+ header.addStringValue("error", "Delta CRL is not enabled for " +
+ crlIssuingPointId +
+ " issuing point");
+ }
+ }
+
+ } else if (!isCRLCacheEnabled && crlDisplayType.equals("cachedCRL")) {
+ header.addStringValue("error", CMS.getUserMessage(locale, "CMS_GW_CRL_CACHE_IS_NOT_ENABLED", crlIssuingPointId));
+ header.addStringValue("crlPrettyPrint", CMS.getUserMessage(locale, "CMS_GW_CRL_CACHE_IS_NOT_ENABLED", crlIssuingPointId));
+ } else {
+ header.addStringValue("error",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ header.addStringValue("crlPrettyPrint",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_DECODE_CRL_FAILED")).toString());
+ }
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java
new file mode 100644
index 000000000..0062a4e7e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DisplayHashUserEnroll.java
@@ -0,0 +1,231 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Servlet to report the status, ie, the agent-initiated user
+ * enrollment is enabled or disabled.
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayHashUserEnroll extends CMSServlet {
+ private final static String TPL_FILE = "/ra/hashDirUserEnroll.template";
+ private final static String TPL_ERROR_FILE = "/ra/GenErrorHashDirEnroll.template";
+ private String mFormPath = null;
+
+ public DisplayHashUserEnroll() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ try {
+ mFormPath = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mFormPath == null)
+ mFormPath = TPL_FILE;
+ } catch (Exception e) {
+ }
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Services the request
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String reqHost = httpReq.getRemoteHost();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+ boolean isEnable = mgr.isEnable(reqHost);
+
+ if (!isEnable) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ Date date = new Date();
+ long currTime = date.getTime();
+ long timeout = mgr.getTimeout(reqHost);
+ long lastlogin = mgr.getLastLogin(reqHost);
+ long diff = currTime - lastlogin;
+
+ if (lastlogin == 0)
+ mgr.setLastLogin(reqHost, currTime);
+ else if (diff > timeout) {
+ mgr.disable(reqHost);
+ printError(cmsReq, "2");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ mgr.setLastLogin(reqHost, currTime);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ private void printError(CMSRequest cmsReq, String errorCode)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ header.addStringValue("authority", "Registration Manager");
+ header.addStringValue("errorCode", errorCode);
+ String formPath = TPL_ERROR_FILE;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(formPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_GET_TEMPLATE", formPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", e.toString()));
+
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
new file mode 100644
index 000000000..6c66f49e5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevoke.java
@@ -0,0 +1,1156 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * Revoke a Certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoRevoke extends CMSServlet {
+
+ private final static String INFO = "DoRevoke";
+ private final static String TPL_FILE = "revocationResult.template";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private Nonces mNonces = null;
+ private int mTimeLimits = 30; /* in seconds */
+ private IUGSubsystem mUG = null;
+ private ICertUserLocator mUL = null;
+
+ private final static String REVOKE = "revoke";
+ private final static String ON_HOLD = "on-hold";
+ private final static int ON_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ 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 (((ICertificateAuthority) mAuthority).noncesEnabled()) {
+ mNonces = ((ICertificateAuthority) mAuthority).getNonces();
+ }
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.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");
+
+ if (mNonces != null) {
+ boolean nonceVerified = false;
+ boolean skipNonceVerification = false;
+
+ X509Certificate cert2 = getSSLClientCertificate(req);
+ if (cert2 != null) {
+ X509Certificate certChain[] = new X509Certificate[1];
+ certChain[0] = cert2;
+ IUser user = null;
+ try {
+ user = (IUser) mUL.locateUser(new Certificates(certChain));
+ } catch (Exception e) {
+ CMS.debug("DoRevoke: Failed to map certificate '"+
+ cert2.getSubjectDN().getName()+"' to user.");
+ }
+ if (mUG.isMemberOf(user, "Subsystem Group")) {
+ skipNonceVerification = true;
+ }
+ }
+
+ String nonceStr = req.getParameter("nonce");
+ if (nonceStr != null) {
+ long nonce = Long.parseLong(nonceStr.trim());
+ X509Certificate cert1 = mNonces.getCertificate(nonce);
+ if (cert1 == null) {
+ CMS.debug("DoRevoke: Unknown nonce");
+ } else if (cert1 != null && cert2 != null && cert1.equals(cert2)) {
+ nonceVerified = true;
+ mNonces.removeNonce(nonce);
+ }
+ } else {
+ CMS.debug("DoRevoke: Missing nonce");
+ }
+ CMS.debug("DoRevoke: nonceVerified="+nonceVerified);
+ CMS.debug("DoRevoke: skipNonceVerification="+skipNonceVerification);
+ if ((!nonceVerified) && (!skipNonceVerification)) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+ }
+
+ 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(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ // request is fromUser.
+ initiative = AuditFormat.FROMUSER;
+
+ String serialNumber = req.getParameter("serialNumber");
+ X509CertImpl sslCert = (X509CertImpl) getSSLClientCertificate(req);
+
+ if (serialNumber == null || sslCert == null ||
+ !(serialNumber.equals(sslCert.getSerialNumber().toString(16)))) {
+ authorized = false;
+ } else {
+ eeSubjectDN = sslCert.getSubjectDN().toString();
+ eeSerialNumber = sslCert.getSerialNumber().toString();
+ }
+ }
+
+ if (authorized) {
+ process(argSet, header, reason, invalidityDate, initiative,
+ req, resp, verifiedRecordCount, revokeAll,
+ totalRecordCount, eeSerialNumber, 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 (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(CMSRequest.SUCCESS);
+ }
+ } else if (!authorized) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ } else {
+ cmsReq.setStatus(CMSRequest.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 string 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,
+ String eeSerialNumber,
+ String eeSubjectDN,
+ String comments,
+ Locale locale)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(eeSerialNumber);
+ String auditRequestType = auditRequestType(reason);
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(reason);
+
+ long startTime = CMS.getCurrentDate().getTime();
+
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+
+ Enumeration e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null)
+ continue;
+ X509CertImpl xcert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ // we do not want to revoke the CA certificate accidentially
+ if (xcert != null && isSystemCertificate(xcert.getSerialNumber())) {
+ CMS.debug("DoRevoke: skipped revocation request for system certificate " + xcert.getSerialNumber());
+ continue;
+ }
+
+ if (xcert != null) {
+ rarg.addStringValue("serialNumber",
+ xcert.getSerialNumber().toString(16));
+
+ if (eeSerialNumber != null &&
+ (eeSerialNumber.equals(xcert.getSerialNumber().toString())) &&
+ rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERTIFICATE_ALREADY_REVOKED_1", xcert.getSerialNumber().toString(16)));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_UNAUTHORIZED"));
+ } else if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ rarg.addStringValue("error", "Certificate 0x" +
+ xcert.getSerialNumber().toString(16) +
+ " is already revoked.");
+ } else if (eeSubjectDN != null &&
+ (!eeSubjectDN.equals(xcert.getSubjectDN().toString()))) {
+ rarg.addStringValue("error", "Certificate 0x" +
+ xcert.getSerialNumber().toString(16) +
+ " belongs to different subject.");
+ } else {
+ oldCertsV.addElement(xcert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(xcert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ String reqIdStr = req.getParameter("requestId");
+ Vector serialNumbers = new Vector();
+
+ if (revokeAll != null && revokeAll.length() > 0) {
+ for (int i = revokeAll.indexOf('=');
+ i < revokeAll.length() && i > -1;
+ i = revokeAll.indexOf('=', i)) {
+ if (i > -1) {
+ i++;
+ while (i < revokeAll.length() && revokeAll.charAt(i) == ' ') {
+ i++;
+ }
+ // xxxx decimal serial number?
+ String legalDigits = "0123456789";
+ int j = i;
+
+ while (j < revokeAll.length() && legalDigits.indexOf(revokeAll.charAt(j)) != -1) {
+ j++;
+ }
+ if (j > i) {
+ serialNumbers.addElement(revokeAll.substring(i, j));
+ }
+ }
+ }
+ }
+ if (reqIdStr != null && reqIdStr.length() > 0 && serialNumbers.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 (int j = 0; j < serialNumbers.size();
+ j++) {
+ //xxxxx serial number in decimal?
+ if (certs[i].getSerialNumber().toString().equals((String) serialNumbers.elementAt(j)) &&
+ eeSubjectDN != null && eeSubjectDN.equals(certs[i].getSubjectDN().toString())) {
+ addToList = true;
+ break;
+ }
+ }
+ if (eeSerialNumber != null &&
+ eeSerialNumber.equals(certs[i].getSerialNumber().toString())) {
+ authorized = true;
+ }
+ if (addToList) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("serialNumber",
+ certs[i].getSerialNumber().toString(16));
+ oldCertsV.addElement(certs[i]);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(certs[i].getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ if (!authorized) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_REQ_AUTH_REVOKED_CERT"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ 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));
+ oldCertsV.addElement(cert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(cert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ count++;
+ rarg.addStringValue("error", null);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+ if (count == 0) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REV_CERTS_ZERO"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_REVOCATION_ERROR_CERT_NOT_FOUND"));
+ }
+
+ header.addIntegerValue("totalRecordCount", count);
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ //Certificate[] oldCerts = new Certificate[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ if(initiative.equals(AuditFormat.FROMUSER))
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_EE);
+ else
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+ revReq.setExtData(IRequest.REVOKED_REASON,
+ Integer.valueOf(reason));
+
+ // 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
+ auditRequest = false;
+
+ mQueue.processRequest(revReq);
+
+ // retrieve the request status
+ auditApprovalStatus = revReq.getRequestStatus().toString();
+
+ RequestStatus stat = revReq.getRequestStatus();
+ 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 ((stat == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_CERT4CRL_REQUEST)) && (stat == RequestStatus.SVC_PENDING))) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ long endTime = CMS.getCurrentDate().getTime();
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString() + " time: " + (endTime - startTime)}
+ );
+ }
+ }
+ }
+
+ 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 otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ 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 (stat == RequestStatus.PENDING || stat == RequestStatus.REJECTED) {
+ header.addStringValue("revoked", stat.toString());
+ } else {
+ header.addStringValue("revoked", "no");
+ }
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ if (errors != null) {
+ StringBuffer errInfo = new StringBuffer();
+ for (int i = 0; i < errors.size(); i++) {
+ errInfo.append(errors.elementAt(i));
+ errInfo.append("\n");
+ }
+ header.addStringValue("error", errInfo.toString());
+
+ } else if (stat == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ } else {
+ header.addStringValue("error", null);
+ }
+
+ // audit log the pending, revoked and rest
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (CertificateException e) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ log(ILogger.LL_FAILURE, "error " + e);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED_1", e.toString()));
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ }
+
+ return;
+ }
+
+ /**
+ * 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 String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+
+ /**
+ * Signed Audit Log Request Type
+ *
+ * This method is called to obtain the "Request Type" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param reason an integer denoting the revocation reason
+ * @return string containing REVOKE or ON_HOLD
+ */
+ private String auditRequestType(int reason) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requestType = null;
+
+ // Determine the revocation type based upon the revocation reason
+ if (reason == ON_HOLD_REASON) {
+ requestType = ON_HOLD;
+ } else {
+ requestType = REVOKE;
+ }
+
+ return requestType;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
new file mode 100644
index 000000000..08756a5ba
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
@@ -0,0 +1,911 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * Revoke a Certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoRevokeTPS extends CMSServlet {
+
+ private final static String INFO = "DoRevoke";
+ private final static String TPL_FILE = "revocationResult.template";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String errorString = "error=";
+ private String o_status = "status=0";
+ private int mTimeLimits = 30; /* in seconds */
+
+ private final static String REVOKE = "revoke";
+ private final static String ON_HOLD = "on-hold";
+ private final static int ON_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ public DoRevokeTPS() {
+ 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;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ mRenderResult = false;
+
+ /* 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);
+ CMS.debug("DoRevokeTPS after authenticate");
+
+ String revokeAll = null;
+ int totalRecordCount = -1;
+ EBaseException error = null;
+ int reason = -1;
+ boolean authorized = true;
+ Date invalidityDate = null;
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ CMS.debug("DoRevokeTPS before getTemplate");
+ 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"));
+ } catch (Exception e) {
+ CMS.debug("DoRevokeTPS getTemplate failed");
+ throw new EBaseException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ CMS.debug("DoRevokeTPS after getTemplate");
+ 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("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);
+
+ //for audit log.
+ String initiative = null;
+
+ String authMgr = AuditFormat.NOAUTH;
+
+ 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(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ String agentID = authToken.getInString("userid");
+
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID +
+ " authenticated by " + authMgr;
+ }
+ } else {
+ CMS.debug("DoRevokeTPS: Missing authentication manager");
+ o_status = "status=1";
+ errorString = "errorString=Missing authentication manager.";
+ }
+
+ if (authorized) {
+ process(argSet, header, reason, invalidityDate, initiative, req,
+ resp, revokeAll, totalRecordCount, 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 (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (!authorized) {
+ o_status = "status=3";
+ errorString = "error=unauthorized";
+ } else if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error.toString();
+ }
+
+ String pp = o_status+"\n"+errorString;
+ byte[] b = pp.getBytes();
+ resp.setContentType("text/html");
+ resp.setContentLength(b.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(b);
+ os.flush();
+ } 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 revokeAll string containing information on all of the
+ * certificates to be revoked
+ * @param totalRecordCount total number of records (verified and unverified)
+ * @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,
+ String revokeAll,
+ int totalRecordCount,
+ String comments,
+ Locale locale)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(null);
+ String auditRequestType = auditRequestType(reason);
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(reason);
+
+ long startTime = CMS.getCurrentDate().getTime();
+
+ try {
+ int count = 0;
+ Vector oldCertsV = new Vector();
+ Vector revCertImplsV = new Vector();
+
+ // Construct a CRL reason code extension.
+ RevocationReason revReason = RevocationReason.fromInt(reason);
+ CRLReasonExtension crlReasonExtn = new CRLReasonExtension(revReason);
+
+ // Construct a CRL invalidity date extension.
+ InvalidityDateExtension invalidityDateExtn = null;
+
+ if (invalidityDate != null) {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ }
+
+ // Construct a CRL extension for this request.
+ CRLExtensions entryExtn = new CRLExtensions();
+
+ if (crlReasonExtn != null) {
+ entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
+ }
+ if (invalidityDateExtn != null) {
+ entryExtn.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ }
+
+ Enumeration e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ boolean alreadyRevokedCertFound = false;
+ boolean badCertsRequested = false;
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null) {
+ badCertsRequested = true;
+ continue;
+ }
+ X509CertImpl xcert = rec.getCertificate();
+ IArgBlock rarg = CMS.createArgBlock();
+
+ // we do not want to revoke the CA certificate accidentially
+ if (xcert != null && isSystemCertificate(xcert.getSerialNumber())) {
+ CMS.debug("DoRevokeTPS: skipped revocation request for system certificate " + xcert.getSerialNumber());
+ badCertsRequested = true;
+ continue;
+ }
+
+ if (xcert != null) {
+ rarg.addStringValue("serialNumber",
+ xcert.getSerialNumber().toString(16));
+
+ if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)) {
+ alreadyRevokedCertFound = true;
+ CMS.debug("Certificate 0x"+xcert.getSerialNumber().toString(16) + " has been revoked.");
+ } else {
+ oldCertsV.addElement(xcert);
+
+ RevokedCertImpl revCertImpl =
+ new RevokedCertImpl(xcert.getSerialNumber(),
+ CMS.getCurrentDate(), entryExtn);
+
+ revCertImplsV.addElement(revCertImpl);
+ CMS.debug("Certificate 0x"+xcert.getSerialNumber().toString(16)+" is going to be revoked.");
+ count++;
+ }
+ } else {
+ badCertsRequested = true;
+ }
+ }
+
+ if (count == 0) {
+ // Situation where no certs were reoked here, but some certs
+ // requested happened to be already revoked. Don't return error.
+ if (alreadyRevokedCertFound == true && badCertsRequested == false) {
+ CMS.debug("Only have previously revoked certs in the list.");
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ return;
+ }
+
+ errorString = "error=No certificates are revoked.";
+ o_status = "status=2";
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_REV_CERTS_ZERO"));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ }
+
+ X509CertImpl[] oldCerts = new X509CertImpl[count];
+ RevokedCertImpl[] revCertImpls = new RevokedCertImpl[count];
+
+ for (int i = 0; i < count; i++) {
+ oldCerts[i] = (X509CertImpl) oldCertsV.elementAt(i);
+ revCertImpls[i] = (RevokedCertImpl) revCertImplsV.elementAt(i);
+ }
+
+ IRequest revReq =
+ mQueue.newRequest(IRequest.REVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ revReq.setExtData(IRequest.CERT_INFO, revCertImpls);
+ revReq.setExtData(IRequest.REQ_TYPE, IRequest.REVOCATION_REQUEST);
+ if(initiative.equals(AuditFormat.FROMUSER)) {
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_EE);
+ } else {
+ revReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+ }
+ revReq.setExtData(IRequest.OLD_CERTS, oldCerts);
+ if (comments != null) {
+ revReq.setExtData(IRequest.REQUESTOR_COMMENTS, comments);
+ }
+ revReq.setExtData(IRequest.REVOKED_REASON,
+ Integer.valueOf(reason));
+
+ // 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
+ auditRequest = false;
+
+ mQueue.processRequest(revReq);
+
+ // retrieve the request status
+ auditApprovalStatus = revReq.getRequestStatus().toString();
+
+ RequestStatus stat = revReq.getRequestStatus();
+ 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 ((stat == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_CERT4CRL_REQUEST)) && (stat == RequestStatus.SVC_PENDING))) {
+ // audit log the error
+ Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+ String[] svcErrors =
+ revReq.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //cmsReq.setErrorDescription(err);
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ if (oldCerts[j] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ err,
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ long endTime = CMS.getCurrentDate().getTime();
+
+ // audit log the success.
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ "completed",
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString() + " time: " + (endTime - startTime)}
+ );
+ }
+ }
+ }
+
+ header.addStringValue("revoked", "yes");
+
+ Integer updateCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ if (!updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+
+ o_status = "status=3";
+ if (revReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR) != null) {
+ errorString = "error=Update CRL Error.";
+ // 3 means miscellaneous
+ }
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ revReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (!publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ o_status = "status=3";
+ if (publError != null) {
+ errorString = "error="+publError;
+ }
+ }
+ }
+ }
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ 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)) {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("DoRevoke: " + CMS.getLogMessage("ADMIN_SRVLT_ADDING_HEADER_NO",
+ updateStatusStr));
+ String error =
+ revReq.getExtDataInString(updateErrorStr);
+
+ o_status = "status=3";
+ if (error != null) {
+ errorString = "error="+error;
+ }
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ revReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (!publishResult.equals(IRequest.RES_SUCCESS)) {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ String error =
+ revReq.getExtDataInString(publishErrorStr);
+
+ o_status = "status=3";
+ if (error != null) {
+ errorString = "error=Publish CRL Status 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++;
+ }
+ }
+ }
+
+ // add crl publishing status.
+ String publError =
+ revReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null) {
+ errorString = "error="+publError;
+ o_status = "status=3";
+ }
+ } else if (mPublisherProcessor == null && mPublisherProcessor.ldapEnabled()) {
+ errorString = "error=LDAP publishing not enabled.";
+ o_status = "status=3";
+ }
+ } else {
+ if (stat == RequestStatus.PENDING || stat == RequestStatus.REJECTED) {
+ o_status = "status=2";
+ errorString = "error="+stat.toString();
+ } else {
+ o_status = "status=2";
+ errorString = "error=Undefined request status";
+ }
+ Vector errors = revReq.getExtDataInStringVector(IRequest.ERRORS);
+ if (errors != null) {
+ StringBuffer errInfo = new StringBuffer();
+
+ for (int i = 0; i < errors.size(); i++) {
+ errInfo.append(errors.elementAt(i));
+ errInfo.append("\n");
+ }
+ o_status = "status=2";
+ errorString = "error=" + errInfo.toString();
+
+ } else if (stat == RequestStatus.PENDING) {
+ o_status = "status=2";
+ errorString = "error=Request pending";
+ } else {
+ o_status = "status=2";
+ errorString = "error=Undefined request status";
+ }
+
+ // audit log the pending, revoked and rest
+ for (int j = 0; j < count; j++) {
+ if (oldCerts[j] != null) {
+ if (oldCerts[j] instanceof X509CertImpl) {
+ X509CertImpl cert = (X509CertImpl) oldCerts[j];
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOREVOKEFORMAT,
+ new Object[] {
+ revReq.getRequestId(),
+ initiative,
+ stat.toString(),
+ cert.getSubjectDN(),
+ cert.getSerialNumber().toString(16),
+ RevocationReason.fromInt(reason).toString()}
+ );
+ }
+ }
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "error " + e);
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw e;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED_1", e.toString()));
+
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_MARKING_CERT_REVOKED"));
+ }
+
+ return;
+ }
+
+ /**
+ * 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 String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+
+ /**
+ * Signed Audit Log Request Type
+ *
+ * This method is called to obtain the "Request Type" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param reason an integer denoting the revocation reason
+ * @return string containing REVOKE or ON_HOLD
+ */
+ private String auditRequestType(int reason) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requestType = null;
+
+ // Determine the revocation type based upon the revocation reason
+ if (reason == ON_HOLD_REASON) {
+ requestType = ON_HOLD;
+ } else {
+ requestType = REVOKE;
+ }
+
+ return requestType;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java
new file mode 100644
index 000000000..2f125beb7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevoke.java
@@ -0,0 +1,659 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.lang.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * 'Unrevoke' a certificate. (For certificates that are on-hold only,
+ * take them off-hold)
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoUnrevoke extends CMSServlet {
+
+ private final static String INFO = "DoUnrevoke";
+ private final static String TPL_FILE = "unrevocationResult.template";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+
+ private final static String OFF_HOLD = "off-hold";
+ private final static int OFF_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ public DoUnrevoke() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @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;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber Decimal serial number of certificate to unrevoke. The
+ * certificate must be revoked with a revovcation reason 'on hold' for this
+ * operation to succeed. The serial number may be expressed as a hex number by
+ * prefixing '0x' to the serialNumber string
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ BigInteger[] serialNumber;
+ EBaseException error = 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", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ try {
+ serialNumber = getSerialNumbers(req);
+
+ //for audit log.
+ IAuthToken authToken = authenticate(cmsReq);
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ } else {
+ CMS.debug( "DoUnrevoke::process() - authToken is null!" );
+ return;
+ }
+ String agentID = authToken.getInString("userid");
+ String initiative = AuditFormat.FROMAGENT + " agentID: " + agentID
+ + " authenticated by " + authMgr;
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "unrevoke");
+ } 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;
+ }
+
+ process(argSet, header, serialNumber, req, resp, locale[0], initiative);
+
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUM_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+
+ /**
+ * Process X509 cert status change request
+ * <P>
+ *
+ * (Certificate Request - an "agent" cert status change request to take
+ * a certificate off-hold)
+ * <P>
+ *
+ * (Certificate Request Processed - an "agent" cert status change request
+ * to take a certificate off-hold)
+ * <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 (taken off-hold)
+ * </ul>
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param serialNumbers the serial number of the certificate
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ * @param initiative string containing the audit format
+ * @exception EBaseException an error has occurred
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ BigInteger[] serialNumbers,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale, String initiative)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(serialNumbers[0].toString());
+ String auditRequestType = OFF_HOLD;
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(OFF_HOLD_REASON);
+
+ try {
+ StringBuffer snList = new StringBuffer();
+
+ // certs are for old cloning and they should be removed as soon as possible
+ X509CertImpl[] certs = new X509CertImpl[serialNumbers.length];
+ for (int i = 0; i < serialNumbers.length; i++) {
+ certs[i] = (X509CertImpl)getX509Certificate(serialNumbers[i]);
+ if (snList.length() > 0) snList.append(", ");
+ snList.append("0x");
+ snList.append(serialNumbers[i].toString(16));
+ }
+ header.addStringValue("serialNumber", snList.toString());
+
+ IRequest unrevReq = mQueue.newRequest(IRequest.UNREVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ unrevReq.setExtData(IRequest.REQ_TYPE, IRequest.UNREVOCATION_REQUEST);
+ unrevReq.setExtData(IRequest.OLD_SERIALS, serialNumbers);
+ unrevReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+
+ // 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
+ auditRequest = false;
+
+ mQueue.processRequest(unrevReq);
+
+ // retrieve the request status
+ auditApprovalStatus = unrevReq.getRequestStatus().toString();
+
+ RequestStatus status = unrevReq.getRequestStatus();
+ String type = unrevReq.getRequestType();
+
+ if ((status == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_UNCERT4CRL_REQUEST)) && (status == RequestStatus.SVC_PENDING))) {
+
+ Integer result = unrevReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result != null && result.equals(IRequest.RES_SUCCESS)) {
+ header.addStringValue("unrevoked", "yes");
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ header.addStringValue("unrevoked", "no");
+ String error = unrevReq.getExtDataInString(IRequest.ERROR);
+
+ if (error != null) {
+ header.addStringValue("error", error);
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ error,
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+
+ /****************************************************/
+
+ /* IMPORTANT: In the event that the following */
+
+ /* "throw error;" statement is */
+
+ /* uncommented, uncomment the following */
+
+ /* signed audit log message, also!!! */
+
+ /****************************************************/
+
+ // // store a message in the signed audit log file
+ // // if and only if "auditApprovalStatus" is
+ // // "complete", "revoked", or "canceled"
+ // if( ( auditApprovalStatus.equals(
+ // RequestStatus.COMPLETE_STRING ) ) ||
+ // ( auditApprovalStatus.equals(
+ // RequestStatus.REJECTED_STRING ) ) ||
+ // ( auditApprovalStatus.equals(
+ // RequestStatus.CANCELED_STRING ) ) ) {
+ // auditMessage = CMS.getLogMessage(
+ // LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ // auditSubjectID,
+ // ILogger.FAILURE,
+ // auditRequesterID,
+ // auditSerialNumber,
+ // auditRequestType,
+ // auditReasonNum,
+ // auditApprovalStatus );
+ //
+ // audit( auditMessage );
+ // }
+
+ // throw error;
+ }
+ }
+
+ Integer updateCRLResult =
+ unrevReq.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 =
+ unrevReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR);
+
+ if (crlError != null)
+ header.addStringValue("updateCRLError",
+ crlError);
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ unrevReq.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 =
+ unrevReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null)
+ header.addStringValue("publishCRLError",
+ publError);
+ }
+ }
+ }
+
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = unrevReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (updateResult.equals(IRequest.RES_SUCCESS)) {
+ CMS.debug("DoUnrevoke: adding header " +
+ updateStatusStr + " yes ");
+ header.addStringValue(updateStatusStr, "yes");
+ } else {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+
+ CMS.debug("DoUnrevoke: adding header " +
+ updateStatusStr + " no ");
+ header.addStringValue(updateStatusStr, "no");
+ String error =
+ unrevReq.getExtDataInString(updateErrorStr);
+
+ if (error != null)
+ header.addStringValue(
+ updateErrorStr, error);
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ unrevReq.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 =
+ unrevReq.getExtDataInString(publishErrorStr);
+
+ if (error != null)
+ header.addStringValue(
+ publishErrorStr, error);
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ header.addStringValue("dirEnabled", "yes");
+ Integer[] ldapPublishStatus =
+ unrevReq.getExtDataInIntegerArray("ldapPublishStatus");
+
+ if (ldapPublishStatus != null) {
+ if (ldapPublishStatus[0] == IRequest.RES_SUCCESS) {
+ header.addStringValue("dirUpdated", "yes");
+ } else {
+ header.addStringValue("dirUpdated", "no");
+ }
+ }
+ } else {
+ header.addStringValue("dirEnabled", "no");
+ }
+
+ } else if (status == RequestStatus.PENDING) {
+ header.addStringValue("error", "Request Pending");
+ header.addStringValue("unrevoked", "pending");
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "pending",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ header.addStringValue("error", "Request Status.Error");
+ header.addStringValue("unrevoked", "no");
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ status.toString(),
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (EBaseException eAudit1) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+ }
+
+ return;
+ }
+
+ private BigInteger[] getSerialNumbers(HttpServletRequest req)
+ throws NumberFormatException {
+ String serialNumString = req.getParameter("serialNumber");
+
+ StringTokenizer snList = new StringTokenizer(serialNumString, " ");
+ Vector biList = new Vector();
+ while (snList.hasMoreTokens()) {
+ String snStr = snList.nextToken();
+ if (snStr != null) {
+ snStr = snStr.trim();
+ BigInteger bi;
+ if (snStr.startsWith("0x") || snStr.startsWith("0X")) {
+ bi = new BigInteger(snStr.substring(2), 16);
+ } else {
+ bi = new BigInteger(snStr);
+ }
+ if (bi.compareTo(BigInteger.ZERO) < 0) {
+ throw new NumberFormatException();
+ }
+ biList.addElement(bi);
+ } else {
+ throw new NumberFormatException();
+ }
+ }
+ if (biList.size() < 1) {
+ throw new NumberFormatException();
+ }
+
+ BigInteger[] biNumbers = new BigInteger[biList.size()];
+ for (int i = 0; i < biList.size(); i++) {
+ biNumbers[i] = (BigInteger) biList.elementAt(i);
+ }
+
+ return biNumbers;
+ }
+
+ /**
+ * 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 String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
new file mode 100644
index 000000000..8c290d0a7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
@@ -0,0 +1,613 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.lang.*;
+import java.math.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+
+/**
+ * 'Unrevoke' a certificate. (For certificates that are on-hold only,
+ * take them off-hold)
+ *
+ * @version $Revision$, $Date$
+ */
+public class DoUnrevokeTPS extends CMSServlet {
+
+ private final static String INFO = "DoUnrevoke";
+ private final static String TPL_FILE = "unrevocationResult.template";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private IRequestQueue mQueue = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private String errorString = "error=";
+ private String o_status = "status=0";
+
+ private final static String OFF_HOLD = "off-hold";
+ private final static int OFF_HOLD_REASON = 6;
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+ public DoUnrevokeTPS() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @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;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+ if (mAuthority instanceof ICertAuthority) {
+ mPublisherProcessor = ((ICertAuthority) mAuthority).getPublisherProcessor();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mRenderResult = false;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber Decimal serial number of certificate to unrevoke. The
+ * certificate must be revoked with a revovcation reason 'on hold' for this
+ * operation to succeed. The serial number may be expressed as a hex number by
+ * prefixing '0x' to the serialNumber string
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ BigInteger[] serialNumbers;
+ EBaseException error = 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", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+*/
+
+ try {
+ serialNumbers = getSerialNumbers(req);
+
+ //for audit log.
+ IAuthToken authToken = authenticate(cmsReq);
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ } else {
+ CMS.debug( "DoUnrevokeTPS::process() - authToken is null!" );
+ return;
+ }
+ String agentID = authToken.getInString("userid");
+ String initiative = AuditFormat.FROMAGENT + " agentID: " + agentID
+ + " authenticated by " + authMgr;
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "unrevoke");
+ } 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);
+ o_status = "status=3";
+ errorString = "error=unauthorized";
+ String pp = o_status+"\n"+errorString;
+ byte[] b = pp.getBytes();
+ resp.setContentType("text/html");
+ resp.setContentLength(b.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(b);
+ os.flush();
+ return;
+ }
+
+ process(serialNumbers, req, resp, locale[0], initiative);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUM_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ } catch (IOException e) {
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ o_status = "status=0";
+ errorString = "error=";
+ } else {
+ o_status = "status=3";
+ errorString = "error="+error.toString();
+ }
+
+ String pp = o_status+"\n"+errorString;
+ byte[] b = pp.getBytes();
+ resp.setContentType("text/html");
+ resp.setContentLength(b.length);
+ OutputStream os = resp.getOutputStream();
+ os.write(b);
+ os.flush();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("ADMIN_SRVLT_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+
+ /**
+ * Process X509 cert status change request
+ * <P>
+ *
+ * (Certificate Request - an "agent" cert status change request to take
+ * a certificate off-hold)
+ * <P>
+ *
+ * (Certificate Request Processed - an "agent" cert status change request
+ * to take a certificate off-hold)
+ * <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 (taken off-hold)
+ * </ul>
+ * @param serialNumbers the serial number of the certificate
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ * @param initiative string containing the audit format
+ * @exception EBaseException an error has occurred
+ */
+ private void process(BigInteger[] serialNumbers,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale, String initiative)
+ throws EBaseException {
+ boolean auditRequest = true;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditSerialNumber = auditSerialNumber(serialNumbers[0].toString());
+ String auditRequestType = OFF_HOLD;
+ String auditApprovalStatus = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String auditReasonNum = String.valueOf(OFF_HOLD_REASON);
+
+ try {
+ String snList = "";
+
+ // certs are for old cloning and they should be removed as soon as possible
+ X509CertImpl[] certs = new X509CertImpl[serialNumbers.length];
+ for (int i = 0; i < serialNumbers.length; i++) {
+ certs[i] = (X509CertImpl)getX509Certificate(serialNumbers[i]);
+ if (snList.length() > 0) snList += ", ";
+ snList += "0x" + serialNumbers[i].toString(16);
+ }
+
+ IRequest unrevReq = mQueue.newRequest(IRequest.UNREVOCATION_REQUEST);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+
+ unrevReq.setExtData(IRequest.REQ_TYPE, IRequest.UNREVOCATION_REQUEST);
+ unrevReq.setExtData(IRequest.OLD_SERIALS, serialNumbers);
+ unrevReq.setExtData(IRequest.REQUESTOR_TYPE, IRequest.REQUESTOR_AGENT);
+
+ // 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
+ auditRequest = false;
+
+ mQueue.processRequest(unrevReq);
+
+ // retrieve the request status
+ auditApprovalStatus = unrevReq.getRequestStatus().toString();
+
+ RequestStatus status = unrevReq.getRequestStatus();
+ String type = unrevReq.getRequestType();
+
+ if ((status == RequestStatus.COMPLETE) || ((type.equals(IRequest.CLA_UNCERT4CRL_REQUEST)) && (status == RequestStatus.SVC_PENDING))) {
+
+ Integer result = unrevReq.getExtDataInInteger(IRequest.RESULT);
+
+ if (result != null && result.equals(IRequest.RES_SUCCESS)) {
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ String error = unrevReq.getExtDataInString(IRequest.ERROR);
+
+ if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error;
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "completed with error: " +
+ error,
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ }
+ }
+
+ Integer updateCRLResult =
+ unrevReq.getExtDataInInteger(IRequest.CRL_UPDATE_STATUS);
+
+ if (updateCRLResult != null) {
+ if (!updateCRLResult.equals(IRequest.RES_SUCCESS)) {
+ String crlError =
+ unrevReq.getExtDataInString(IRequest.CRL_UPDATE_ERROR);
+
+ if (crlError != null) {
+ o_status = "status=3";
+ errorString = "error="+crlError;
+ }
+ }
+ // let known crl publishing status too.
+ Integer publishCRLResult =
+ unrevReq.getExtDataInInteger(IRequest.CRL_PUBLISH_STATUS);
+
+ if (publishCRLResult != null) {
+ if (!publishCRLResult.equals(IRequest.RES_SUCCESS)) {
+ String publError =
+ unrevReq.getExtDataInString(IRequest.CRL_PUBLISH_ERROR);
+
+ if (publError != null) {
+ o_status = "status=3";
+ errorString = "error="+publError;
+ }
+ }
+ }
+ }
+
+ // let known update and publish status of all crls.
+ Enumeration otherCRLs =
+ ((ICertificateAuthority) mAuthority).getCRLIssuingPoints();
+
+ while (otherCRLs.hasMoreElements()) {
+ ICRLIssuingPoint crl = (ICRLIssuingPoint)
+ otherCRLs.nextElement();
+ String crlId = crl.getId();
+
+ if (crlId.equals(ICertificateAuthority.PROP_MASTER_CRL))
+ continue;
+ String updateStatusStr = crl.getCrlUpdateStatusStr();
+ Integer updateResult = unrevReq.getExtDataInInteger(updateStatusStr);
+
+ if (updateResult != null) {
+ if (!updateResult.equals(IRequest.RES_SUCCESS)) {
+ String updateErrorStr = crl.getCrlUpdateErrorStr();
+ String error =
+ unrevReq.getExtDataInString(updateErrorStr);
+
+ if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error;
+ }
+ }
+ String publishStatusStr = crl.getCrlPublishStatusStr();
+ Integer publishResult =
+ unrevReq.getExtDataInInteger(publishStatusStr);
+
+ if (publishResult == null)
+ continue;
+ if (!publishResult.equals(IRequest.RES_SUCCESS)) {
+ String publishErrorStr =
+ crl.getCrlPublishErrorStr();
+
+ String error =
+ unrevReq.getExtDataInString(publishErrorStr);
+
+ if (error != null) {
+ o_status = "status=3";
+ errorString = "error="+error;
+ }
+ }
+ }
+ }
+
+ if (mPublisherProcessor != null && mPublisherProcessor.ldapEnabled()) {
+ Integer[] ldapPublishStatus =
+ unrevReq.getExtDataInIntegerArray("ldapPublishStatus");
+
+ if (ldapPublishStatus != null) {
+ if (ldapPublishStatus[0] != IRequest.RES_SUCCESS) {
+ o_status = "status=3";
+ errorString = "error=Problem in publishing to LDAP";
+ }
+ }
+ } else if (mPublisherProcessor == null || (! mPublisherProcessor.ldapEnabled())) {
+ o_status = "status=3";
+ errorString = "error=LDAP Publisher not enabled";
+ }
+
+ } else if (status == RequestStatus.PENDING) {
+ o_status = "status=2";
+ errorString = "error="+status.toString();
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ "pending",
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ } else {
+ o_status = "status=2";
+ errorString = "error=Undefined request status";
+
+ if (certs[0] != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.DOUNREVOKEFORMAT,
+ new Object[] {
+ unrevReq.getRequestId(),
+ initiative,
+ status.toString(),
+ certs[0].getSubjectDN(),
+ "0x" + serialNumbers[0].toString(16)}
+ );
+ }
+ }
+
+ // store a message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(RequestStatus.COMPLETE_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.REJECTED_STRING))
+ || (auditApprovalStatus.equals(RequestStatus.CANCELED_STRING))
+ ) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+
+ } catch (EBaseException eAudit1) {
+ if (auditRequest) {
+ // store a "CERT_STATUS_CHANGE_REQUEST" failure
+ // message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType);
+
+ audit(auditMessage);
+ } else {
+ // store a "CERT_STATUS_CHANGE_REQUEST_PROCESSED" failure
+ // message in the signed audit log file
+ // if and only if "auditApprovalStatus" is
+ // "complete", "revoked", or "canceled"
+ if ((auditApprovalStatus.equals(
+ RequestStatus.COMPLETE_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.REJECTED_STRING)) ||
+ (auditApprovalStatus.equals(
+ RequestStatus.CANCELED_STRING))) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditSerialNumber,
+ auditRequestType,
+ auditReasonNum,
+ auditApprovalStatus);
+
+ audit(auditMessage);
+ }
+ }
+ }
+
+ return;
+ }
+
+ private BigInteger[] getSerialNumbers(HttpServletRequest req)
+ throws NumberFormatException {
+ String serialNumString = req.getParameter("serialNumber");
+
+ StringTokenizer snList = new StringTokenizer(serialNumString, " ");
+ Vector biList = new Vector();
+ while (snList.hasMoreTokens()) {
+ String snStr = snList.nextToken();
+ if (snStr != null) {
+ snStr = snStr.trim();
+ BigInteger bi;
+ if (snStr.startsWith("0x") || snStr.startsWith("0X")) {
+ bi = new BigInteger(snStr.substring(2), 16);
+ } else {
+ bi = new BigInteger(snStr);
+ }
+ if (bi.compareTo(BigInteger.ZERO) < 0) {
+ throw new NumberFormatException();
+ }
+ biList.addElement(bi);
+ } else {
+ throw new NumberFormatException();
+ }
+ }
+ if (biList.size() < 1) {
+ throw new NumberFormatException();
+ }
+
+ BigInteger[] biNumbers = new BigInteger[biList.size()];
+ for (int i = 0; i < biList.size(); i++) {
+ biNumbers[i] = (BigInteger) biList.elementAt(i);
+ }
+
+ return biNumbers;
+ }
+
+ /**
+ * 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 String auditRequesterID(HttpServletRequest req) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = null;
+
+ // Obtain the requesterID
+ requesterID = req.getParameter("requestId");
+
+ if (requesterID != null) {
+ requesterID = requesterID.trim();
+ } else {
+ requesterID = ILogger.UNIDENTIFIED;
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Serial Number
+ *
+ * This method is called to obtain the serial number of the certificate
+ * whose status is to be changed for a signed audit log message.
+ * <P>
+ *
+ * @param eeSerialNumber a string containing the un-normalized serialNumber
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditSerialNumber(String eeSerialNumber) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ String serialNumber = null;
+
+ // Normalize the serialNumber
+ if (eeSerialNumber != null) {
+ serialNumber = eeSerialNumber.trim();
+
+ // convert it to hexadecimal
+ serialNumber = "0x"
+ + Integer.toHexString(
+ Integer.valueOf(serialNumber).intValue());
+ } else {
+ serialNumber = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ return serialNumber;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java b/pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java
new file mode 100644
index 000000000..a469e674e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/EnableEnrollResult.java
@@ -0,0 +1,183 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * For Face-to-face enrollment, enable EE enrollment feature
+ *
+ * @version $Revision$, $Date$
+ * @see com.netscape.cms.servlet.cert.DisableEnrollResult
+ */
+public class EnableEnrollResult extends CMSServlet {
+ private final static String TPL_FILE = "enableEnrollResult.template";
+ private String mFormPath = null;
+ private Random random = null;
+
+ public EnableEnrollResult() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to display own output.
+
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ random = new Random();
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Services the request
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "enable");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ X509Certificate sslClientCert = null;
+
+ sslClientCert = getSSLClientCertificate(httpReq);
+ String dn = (String) sslClientCert.getSubjectDN().toString();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String machine = configStore.getString("machineName");
+ String port = CMS.getEESSLPort();
+
+ header.addStringValue("machineName", machine);
+ header.addStringValue("port", port);
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ String host = args.getValueAsString("hostname", null);
+ boolean isEnable = mgr.isEnable(host);
+
+ if (isEnable) {
+ header.addStringValue("code", "1");
+ } else {
+ String timeout = args.getValueAsString("timeout", "600");
+
+ mgr.createEntry(host, dn, Long.parseLong(timeout) * 1000,
+ random.nextLong() + "", 0);
+ header.addStringValue("code", "0");
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java
new file mode 100644
index 000000000..a0de7ebdd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/EnrollServlet.java
@@ -0,0 +1,1831 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+
+import java.io.*;
+
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+
+
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import com.netscape.cms.servlet.processors.PKIProcessor;
+import com.netscape.cms.servlet.processors.CMCProcessor;
+import com.netscape.cms.servlet.processors.CRMFProcessor;
+import com.netscape.cms.servlet.processors.KeyGenProcessor;
+import com.netscape.cms.servlet.processors.PKCS10Processor;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.policy.IPolicyProcessor;
+
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import java.math.*;
+
+
+/**
+ * Submit a Certificate Enrollment request
+ *
+ * @version $Revision$, $Date$
+ */
+public class EnrollServlet extends CMSServlet {
+ public final static String ADMIN_ENROLL_SERVLET_ID = "caadminEnroll";
+
+ // enrollment templates.
+ public static final String
+ ENROLL_SUCCESS_TEMPLATE = "EnrollSuccess.template";
+
+ // http params
+ public static final String OLD_CERT_TYPE = "csrCertType";
+ public static final String CERT_TYPE = "certType";
+ // same as in ConfigConstant.java
+ public static final String REQUEST_FORMAT = "reqFormat";
+ public static final String REQUEST_FORMAT_PKCS10 = "PKCS10";
+ public static final String REQUEST_FORMAT_CMC = "CMC";
+ public static final String REQUEST_CONTENT = "requestContent";
+ public static final String SUBJECT_KEYGEN_INFO = "subjectKeyGenInfo";
+ public static final String PKCS10_REQUEST = "pkcs10Request";
+ public static final String CMC_REQUEST = "cmcRequest";
+ public static final String CRMF_REQUEST = "CRMFRequest";
+ public static final String SUBJECT_NAME = "subject";
+ public static final String CRMF_REQID = "crmfReqId";
+ public static final String CHALLENGE_PASSWORD = "challengePhrase";
+
+ private static final String CERT_AUTH_DUAL = "dual";
+ private static final String CERT_AUTH_ENCRYPTION = "encryption";
+ private static final String CERT_AUTH_SINGLE = "single";
+ private static final String CLIENT_ISSUER = "clientIssuer";
+
+ private boolean mAuthTokenOverride = true;
+ private String mEnrollSuccessTemplate = null;
+ private ICMSTemplateFiller
+ mEnrollSuccessFiller = new ImportCertsTemplateFiller();
+
+ ICertificateAuthority mCa = null;
+ ICertificateRepository mRepository = null;
+
+ private boolean enforcePop = false;
+
+ private String auditServiceID = ILogger.UNIDENTIFIED;
+ private final static String ADMIN_CA_ENROLLMENT_SERVLET =
+ "caadminEnroll";
+ private final static String AGENT_CA_BULK_ENROLLMENT_SERVLET =
+ "cabulkissuance";
+ private final static String AGENT_RA_BULK_ENROLLMENT_SERVLET =
+ "rabulkissuance";
+ private final static String EE_CA_CERT_BASED_ENROLLMENT_SERVLET =
+ "cacertbasedenrollment";
+ private final static String EE_CA_ENROLLMENT_SERVLET =
+ "caenrollment";
+ private final static String EE_RA_CERT_BASED_ENROLLMENT_SERVLET =
+ "racertbasedenrollment";
+ private final static String EE_RA_ENROLLMENT_SERVLET =
+ "raenrollment";
+ private final static byte EOL[] = { Character.LINE_SEPARATOR };
+ private final static String[]
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON = new String[] {
+
+ /* 0 */ "automated non-profile cert request rejection: "
+ + "unable to render OLD_CERT_TYPE response",
+
+ /* 1 */ "automated non-profile cert request rejection: "
+ + "unable to complete handleEnrollAuditLog() method",
+
+ /* 2 */ "automated non-profile cert request rejection: "
+ + "unable to render success template",
+
+ /* 3 */ "automated non-profile cert request rejection: "
+ + "indeterminate reason for inability to process "
+ + "cert request due to an EBaseException"
+ };
+ private final static String
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST =
+ "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5";
+ private final static String
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+
+ private static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+ private static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+
+ public EnrollServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.<p>
+ * the following parameters are read from the servlet config:
+ * <ul><li>CMSServlet.PROP_ID - ID for signed audit log messages
+ * <li>CMSServlet.PROP_SUCCESS_TEMPLATE - success template file
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ try {
+ super.init(sc);
+
+ CMS.debug("EnrollServlet: In Enroll Servlet init!");
+
+ try {
+ IConfigStore configStore = CMS.getConfigStore();
+ String PKI_Subsystem = configStore.getString( "subsystem.0.id",
+ null );
+
+ // CMS 6.1 began utilizing the "Certificate Profiles" framework
+ // instead of the legacy "Certificate Policies" framework.
+ //
+ // Beginning with CS 8.1, to meet the Common Criteria
+ // evaluation performed on this version of the product, it
+ // was determined that this legacy "Certificate Policies"
+ // framework would be deprecated and disabled by default
+ // (see Bugzilla Bug #472597).
+ //
+ // NOTE: The "Certificate Policies" framework ONLY applied to
+ // to CA, KRA, and legacy RA (pre-CMS 7.0) subsystems.
+ //
+ // Further, the "EnrollServlet.java" servlet is ONLY
+ // used by the CA for the following:
+ //
+ // SERVLET-NAME URL-PATTERN
+ // ====================================================
+ // caadminEnroll ca/admin/ca/adminEnroll.html
+ // cabulkissuance ca/agent/ca/bulkissuance.html
+ // cacertbasedenrollment ca/certbasedenrollment.html
+ // caenrollment ca/enrollment.html
+ //
+ // The "EnrollServlet.java" servlet is NOT used by
+ // the KRA.
+ //
+ if( PKI_Subsystem.trim().equalsIgnoreCase( "ca" ) ) {
+ String policyStatus = PKI_Subsystem.trim().toLowerCase()
+ + "." + "Policy"
+ + "." + IPolicyProcessor.PROP_ENABLE;
+
+ if( configStore.getBoolean( policyStatus, true ) == true ) {
+ // NOTE: If "<subsystem>.Policy.enable=<boolean>"
+ // is missing, then the referenced instance
+ // existed prior to this name=value pair
+ // existing in its 'CS.cfg' file, and thus
+ // we err on the side that the user may
+ // still need to use the policy framework.
+ CMS.debug( "EnrollServlet::init Certificate "
+ + "Policy Framework (deprecated) "
+ + "is ENABLED" );
+ } else {
+ // CS 8.1 Default: <subsystem>.Policy.enable=false
+ CMS.debug( "EnrollServlet::init Certificate "
+ + "Policy Framework (deprecated) "
+ + "is DISABLED" );
+ return;
+ }
+ }
+ } catch( EBaseException e ) {
+ throw new ServletException( "EnrollServlet::init - "
+ + "EBaseException: "
+ + "Unable to initialize "
+ + "Certificate Policy Framework "
+ + "(deprecated)" );
+ }
+
+ // override success template to allow direct import of keygen certs.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ try {
+ // determine the service ID for signed audit log messages
+ String id = sc.getInitParameter(CMSServlet.PROP_ID);
+
+ if (id != null) {
+ if (!(auditServiceID.equals(
+ ADMIN_CA_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ AGENT_CA_BULK_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ AGENT_RA_BULK_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_CA_CERT_BASED_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_CA_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_RA_CERT_BASED_ENROLLMENT_SERVLET))
+ && !(auditServiceID.equals(
+ EE_RA_ENROLLMENT_SERVLET))) {
+ auditServiceID = ILogger.UNIDENTIFIED;
+ } else {
+ auditServiceID = id.trim();
+ }
+ }
+
+ mEnrollSuccessTemplate = sc.getInitParameter(
+ CMSServlet.PROP_SUCCESS_TEMPLATE);
+ if (mEnrollSuccessTemplate == null)
+ mEnrollSuccessTemplate = ENROLL_SUCCESS_TEMPLATE;
+ String fillername = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE_FILLER);
+
+ if (fillername != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillername);
+
+ if (filler != null)
+ mEnrollSuccessFiller = filler;
+ }
+
+ // cfu
+ mCa = (ICertificateAuthority) CMS.getSubsystem("ca");
+
+ init_testbed_hack(mConfig);
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR",
+ e.toString(), mId));
+ }
+ } catch (ServletException eAudit1) {
+ // rethrow caught exception
+ throw eAudit1;
+ }
+ }
+
+
+ /**
+ * XXX (SHOULD CHANGE TO READ FROM Servletconfig)
+ * Getter method to see if Proof of Posession checking is enabled.
+ * this value is set in the CMS.cfg filem with the parameter
+ * "enrollment.enforcePop". It defaults to false
+ * @return true if user is required to Prove that they possess the
+ * private key corresponding to the public key in the certificate
+ * request they are submitting
+ */
+ public boolean getEnforcePop() {
+ return enforcePop;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <UL><LI>If the request is coming through the admin port, it is only
+ * allowed to continue if 'admin enrollment' is enabled in the CMS.cfg file
+ * <LI>If the CMS.cfg parameter useThreadNaming is true, the current thread is
+ * renamed with more information about the current request ID
+ * <LI>The request is preprocessed, then processed further in one
+ * of the cert request processor classes: KeyGenProcessor, PKCS10Processor,
+ * CMCProcessor, CRMFProcessor
+ * </UL>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ // SPECIAL CASE:
+ // if it is adminEnroll servlet,check if it's enabled
+ if (mId.equals(ADMIN_ENROLL_SERVLET_ID) &&
+ !CMSGateway.getEnableAdminEnroll()) {
+ log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("ADMIN_SRVLT_ENROLL_ACCESS_AFTER_SETUP"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_REDIRECTING_ADMINENROLL_ERROR", "Attempt to access adminEnroll after already setup."));
+ }
+
+ processX509(cmsReq);
+ }
+
+ private boolean getCertAuthEnrollStatus(IArgBlock httpParams) {
+
+ /*
+ * === certAuth based enroll ===
+ * "certAuthEnroll" is on.
+ * "certauthEnrollType can be one of the three:
+ * single - it's for single cert enrollment
+ * dual - it's for dual certs enrollment
+ * encryption - getting the encryption cert only via
+ * authentication of the signing cert
+ * (crmf or keyGenInfo)
+ */
+ boolean certAuthEnroll = false;
+
+ String certAuthEnrollOn =
+ httpParams.getValueAsString("certauthEnroll", null);
+
+ if ((certAuthEnrollOn != null) && (certAuthEnrollOn.equals("on"))) {
+ certAuthEnroll = true;
+ CMS.debug("EnrollServlet: certAuthEnroll is on");
+ }
+
+ return certAuthEnroll;
+
+ }
+
+ private String getCertAuthEnrollType(IArgBlock httpParams, boolean certAuthEnroll)
+ throws EBaseException {
+
+ String certauthEnrollType = null;
+
+ if (certAuthEnroll == true) {
+ certauthEnrollType =
+ httpParams.getValueAsString("certauthEnrollType", null);
+ if (certauthEnrollType != null) {
+ if (certauthEnrollType.equals("dual")) {
+ CMS.debug("EnrollServlet: certauthEnrollType is dual");
+ } else if (certauthEnrollType.equals("encryption")) {
+ CMS.debug("EnrollServlet: certauthEnrollType is encryption");
+ } else if (certauthEnrollType.equals("single")) {
+ CMS.debug("EnrollServlet: certauthEnrollType is single");
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERTAUTH_ENROLL_TYPE_1", certauthEnrollType));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERTAUTH_ENROLL_TYPE"));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("MSGW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ }
+ }
+
+ return certauthEnrollType;
+
+ }
+
+ private boolean checkClientCertSigningOnly(X509Certificate sslClientCert)
+ throws EBaseException {
+ if ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ false) ||
+ ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ true) &&
+ (CMS.isEncryptionCert((X509CertImpl) sslClientCert) ==
+ true))) {
+
+ // either it's not a signing cert, or it's a dual cert
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_TYPE"));
+ }
+
+ return true;
+ }
+
+ private X509CertInfo[] handleCertAuthDual(X509CertInfo certInfo, IAuthToken authToken, X509Certificate sslClientCert,
+ ICertificateAuthority mCa, String certBasedOldSubjectDN,
+ BigInteger certBasedOldSerialNum)
+ throws EBaseException {
+
+ CMS.debug("EnrollServlet: In handleCertAuthDual!");
+
+ if (mCa == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NOT_A_CA"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_A_CA"));
+ }
+
+ // first, make sure the client cert is indeed a
+ // signing only cert
+
+ try {
+
+ checkClientCertSigningOnly(sslClientCert);
+ } catch (ECMSGWException e) {
+
+ throw new ECMSGWException(e.toString());
+
+ }
+
+ X509Key key = null;
+
+ // for signing cert
+ key = (X509Key) sslClientCert.getPublicKey();
+ try {
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_IO", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+
+ String filter =
+ "(&(x509cert.subject=" + certBasedOldSubjectDN + ")(!(x509cert.serialNumber=" + certBasedOldSerialNum + "))(certStatus=VALID))";
+ ICertRecordList list =
+ (ICertRecordList) mCa.getCertificateRepository().findCertRecordsInList(filter, null, 10);
+ int size = list.getSize();
+ Enumeration en = list.getCertRecords(0, size - 1);
+ boolean gotEncCert = false;
+
+ CMS.debug("EnrollServlet: signing cert filter " + filter);
+
+ if (!en.hasMoreElements()) {
+ CMS.debug("EnrollServlet: pairing encryption cert not found!");
+ return null;
+ // pairing encryption cert not found
+ } else {
+ X509CertInfo encCertInfo = CMS.getDefaultX509CertInfo();
+ X509CertInfo[] cInfoArray = new X509CertInfo[] {certInfo,
+ encCertInfo};
+ int i = 1;
+
+ boolean encCertFound = false;
+
+ while (en.hasMoreElements()) {
+ ICertRecord record = (ICertRecord) en.nextElement();
+ X509CertImpl cert = record.getCertificate();
+
+ // if not encryption cert only, try next one
+ if ((CMS.isEncryptionCert(cert) == false) ||
+ ((CMS.isEncryptionCert(cert) == true) &&
+ (CMS.isSigningCert(cert) == true))) {
+
+ CMS.debug("EnrollServlet: Not encryption only cert, will try next one.");
+ continue;
+ }
+
+ key = (X509Key) cert.getPublicKey();
+ CMS.debug("EnrollServlet: Found key for encryption cert.");
+ encCertFound = true;
+
+ try {
+ encCertInfo = (X509CertInfo)
+ cert.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO_ENCRYPT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTINFO"));
+ }
+
+ try {
+ encCertInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+
+ CMS.debug("EnrollServlet: About to fillCertInfoFromAuthToken!");
+ PKIProcessor.fillCertInfoFromAuthToken(encCertInfo, authToken);
+
+ cInfoArray[i++] = encCertInfo;
+ break;
+
+ }
+ if (encCertFound == false) {
+ CMS.debug("EnrollServlet: Leaving because Enc Cert not found.");
+ return null;
+ }
+
+ CMS.debug("EnrollServlet: returning cInfoArray of length " + cInfoArray.length);
+ return cInfoArray;
+ }
+
+ }
+
+ private boolean handleEnrollAuditLog(IRequest req, CMSRequest cmsReq, String authMgr, IAuthToken authToken,
+ X509CertInfo certInfo, long startTime)
+ throws EBaseException {
+ //for audit log
+
+ String initiative = null;
+ String agentID = null;
+
+ if (authToken == null) {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ } else {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }
+
+ // if service not complete return standard templates.
+ RequestStatus status = req.getRequestStatus();
+
+ if (status != RequestStatus.COMPLETE) {
+ cmsReq.setIRequestStatus(); // set status acc. to IRequest status.
+ // audit log the status
+ try {
+ if (status == RequestStatus.REJECTED) {
+ Vector messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration msgs = messages.elements();
+ StringBuffer wholeMsg = new StringBuffer();
+
+ while (msgs.hasMoreElements()) {
+ wholeMsg.append("\n");
+ wholeMsg.append(msgs.nextElement());
+ }
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT),
+ " violation: " +
+ wholeMsg.toString()}
+ );
+ } else { // no policy violation, from agent
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ }
+ } else { // other imcomplete status
+ long endTime = CMS.getCurrentDate().getTime();
+
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT) + " time: " + (endTime - startTime), ""}
+ );
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ }
+ return false;
+ }
+ // if service error use standard error templates.
+ Integer result = req.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(req.getExtDataInString(IRequest.ERROR));
+ String[] svcErrors =
+ req.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //System.out.println(
+ //"revocation servlet: setting error description "+
+ //err.toString());
+ cmsReq.setErrorDescription(err);
+ // audit log the error
+ try {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed with error: " +
+ err,
+ certInfo.get(X509CertInfo.SUBJECT), ""
+ }
+ );
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ }
+
+ }
+ }
+ }
+ return false;
+
+ }
+
+ return true;
+
+ }
+
+ /**
+ * Process X509 certificate enrollment request
+ * <P>
+ *
+ * (Certificate Request - either an "admin" cert request for an admin
+ * certificate, an "agent" cert request for "bulk enrollment", or
+ * an "EE" standard cert request)
+ * <P>
+ *
+ * (Certificate Request Processed - either an automated "admin" non-profile
+ * based CA admin cert acceptance, an automated "admin" non-profile based
+ * CA admin cert rejection, an automated "EE" non-profile based cert
+ * acceptance, or an automated "EE" non-profile based cert rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST used when a
+ * non-profile cert request is made (before approval process)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a
+ * certificate request has just been through the approval process
+ * </ul>
+ * @param cmsReq a certificate enrollment request
+ * @exception EBaseException an error has occurred
+ */
+ protected void processX509(CMSRequest cmsReq)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = ILogger.UNIDENTIFIED;
+ String auditCertificateSubjectName = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String id = null;
+
+ // define variables common to try-catch-blocks
+ long startTime = 0;
+ IArgBlock httpParams = null;
+ HttpServletRequest httpReq = null;
+ IAuthToken authToken = null;
+ AuthzToken authzToken = null;
+ IRequest req = null;
+ X509CertInfo certInfo = null;
+
+ IConfigStore configStore = CMS.getConfigStore();
+
+ /* XXX shouldn't we read this from ServletConfig at init time? */
+ enforcePop = configStore.getBoolean("enrollment.enforcePop", false);
+ CMS.debug("EnrollServlet: enforcePop " + enforcePop);
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ startTime = CMS.getCurrentDate().getTime();
+ httpParams = cmsReq.getHttpParams();
+ httpReq = cmsReq.getHttpReq();
+ if (mAuthMgr != null) {
+ authToken = authenticate(cmsReq);
+ }
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } 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);
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ // create enrollment request in request queue.
+ req = mRequestQueue.newRequest(IRequest.ENROLLMENT_REQUEST);
+
+ // retrieve the actual "auditRequesterID"
+ if (req != null) {
+ // overwrite "auditRequesterID" if and only if "id" != null
+ id = req.getRequestId().toString();
+ if (id != null) {
+ auditRequesterID = id.trim();
+ }
+ }
+
+ try {
+ if (CMS.getConfigStore().getBoolean("useThreadNaming", false)) {
+ String currentName = Thread.currentThread().getName();
+
+ Thread.currentThread().setName(currentName
+ + "-request-"
+ + req.getRequestId().toString()
+ + "-"
+ + (new Date()).getTime());
+ }
+ } catch (Exception e) {
+ }
+
+ /*
+ * === certAuth based enroll ===
+ * "certAuthEnroll" is on.
+ * "certauthEnrollType can be one of the three:
+ * single - it's for single cert enrollment
+ * dual - it's for dual certs enrollment
+ * encryption - getting the encryption cert only via
+ * authentication of the signing cert
+ * (crmf or keyGenInfo)
+ */
+ boolean certAuthEnroll = false;
+ String certauthEnrollType = null;
+
+ certAuthEnroll = getCertAuthEnrollStatus(httpParams);
+
+ try {
+ if (certAuthEnroll == true) {
+ certauthEnrollType = getCertAuthEnrollType(httpParams,
+ certAuthEnroll);
+ }
+ } catch (ECMSGWException e) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(e.toString());
+ }
+
+ CMS.debug("EnrollServlet: In EnrollServlet.processX509!");
+ CMS.debug("EnrollServlet: certAuthEnroll " + certAuthEnroll);
+ CMS.debug("EnrollServlet: certauthEnrollType " + certauthEnrollType);
+
+ String challengePassword = httpParams.getValueAsString(
+ "challengePassword", "");
+
+ cmsReq.setIRequest(req);
+ saveHttpHeaders(httpReq, req);
+ saveHttpParams(httpParams, req);
+
+ X509Certificate sslClientCert = null;
+
+ // cert auth enroll
+ String certBasedOldSubjectDN = null;
+ BigInteger certBasedOldSerialNum = null;
+
+ // check if request was authenticated, if so set authtoken &
+ // certInfo. also if authenticated, take certInfo from authToken.
+ certInfo = null;
+ if (certAuthEnroll == true) {
+ sslClientCert = getSSLClientCertificate(httpReq);
+ if (sslClientCert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SSL_CLIENT_CERT"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SSL_CLIENT_CERT"));
+ }
+
+ certBasedOldSubjectDN = (String)
+ sslClientCert.getSubjectDN().toString();
+ certBasedOldSerialNum = (BigInteger)
+ sslClientCert.getSerialNumber();
+
+ CMS.debug("EnrollServlet: certBasedOldSubjectDN " + certBasedOldSubjectDN);
+ CMS.debug("EnrollServlet: certBasedOldSerialNum " + certBasedOldSerialNum);
+
+ // if the cert subject name is NOT MISSING, retrieve the
+ // actual "auditCertificateSubjectName" and "normalize" it
+ if (certBasedOldSubjectDN != null) {
+ // NOTE: This is ok even if the cert subject name
+ // is "" (empty)!
+ auditCertificateSubjectName = certBasedOldSubjectDN.trim();
+ }
+
+ try {
+ certInfo = (X509CertInfo)
+ ((X509CertImpl) sslClientCert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_CERTINFO"));
+ }
+ } else {
+ CMS.debug("EnrollServlet: No CertAuthEnroll.");
+ certInfo = CMS.getDefaultX509CertInfo();
+ }
+
+ X509CertInfo[] certInfoArray = new X509CertInfo[] {certInfo};
+
+ X509CertInfo authCertInfo = null;
+ String authMgr = AuditFormat.NOAUTH;
+
+ // if authentication
+ if (authToken != null) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ // don't store agent token in request.
+ // agent currently used for bulk issuance.
+ // if (!authMgr.equals(AuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ log(ILogger.LL_INFO,
+ "Enrollment request was authenticated by " +
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME));
+
+ PKIProcessor.fillCertInfoFromAuthToken(certInfo,
+ authToken);
+ // save authtoken attrs to request directly
+ // (for policy use)
+ saveAuthToken(authToken, req);
+ // req.set(IRequest.AUTH_TOKEN, authToken);
+ // }
+ }
+
+ CMS.debug("EnrollServlet: Enroll authMgr " + authMgr);
+
+ if (certAuthEnroll == true) {
+ // log(ILogger.LL_DEBUG,
+ // "just gotten subjectDN and serialNumber " +
+ // "from ssl client cert");
+ if (authToken == null) {
+ // authToken is null, can't match to anyone; bail!
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_PROCESS_ENROLL_NO_AUTH"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ return;
+ }
+ }
+
+ // fill certInfo from input types: keygen, cmc, pkcs10 or crmf
+ KeyGenInfo keyGenInfo = httpParams.getValueAsKeyGenInfo(
+ SUBJECT_KEYGEN_INFO, null);
+ PKCS10 pkcs10 = null;
+
+ String certType = null;
+
+ //
+ String test = httpParams.getValueAsString("certNickname", null);
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ certType = httpParams.getValueAsString(OLD_CERT_TYPE, null);
+ CMS.debug("EnrollServlet: certType " + certType);
+
+ if (certType == null) {
+ certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ CMS.debug("EnrollServlet: certType " + certType);
+ } else {
+ // some policies may rely on the fact that
+ // CERT_TYPE is set. So for 3.5.1 or eariler
+ // we need to set CERT_TYPE here.
+ req.setExtData(IRequest.HTTP_PARAMS, CERT_TYPE, certType);
+ }
+ if (certType.equals("client")) {
+ // coming from MSIE
+ String p10b64 = httpParams.getValueAsString(PKCS10_REQUEST,
+ null);
+
+ if (p10b64 != null) {
+ try {
+ byte[] bytes = CMS.AtoB(p10b64);
+
+ pkcs10 = new PKCS10(bytes);
+ } catch (Exception e) {
+ // ok, if the above fails, it could
+ // be a PKCS10 with header
+ pkcs10 = httpParams.getValueAsPKCS10(PKCS10_REQUEST,
+ false, null);
+ // e.printStackTrace();
+ }
+ }
+
+ //pkcs10 = httpParams.getValuePKCS10(PKCS10_REQUEST, null);
+
+ } else {
+ try {
+ // coming from server cut & paste blob.
+ pkcs10 = httpParams.getValueAsPKCS10(PKCS10_REQUEST,
+ false, null);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ String cmc = null;
+ String asciiBASE64Blob = httpParams.getValueAsString(CMC_REQUEST, null);
+
+ if(asciiBASE64Blob!=null)
+ {
+ int startIndex = asciiBASE64Blob.indexOf(HEADER);
+ int endIndex = asciiBASE64Blob.indexOf(TRAILER);
+ if (startIndex!= -1 && endIndex!=-1) {
+ startIndex = startIndex + HEADER.length();
+ cmc=asciiBASE64Blob.substring(startIndex, endIndex);
+ }else
+ cmc = asciiBASE64Blob;
+ CMS.debug("EnrollServlet: cmc " + cmc);
+ }
+
+ String crmf = httpParams.getValueAsString(CRMF_REQUEST, null);
+
+ CMS.debug("EnrollServlet: crmf " + crmf);
+
+ if (certAuthEnroll == true) {
+
+ PKIProcessor.fillCertInfoFromAuthToken(certInfo, authToken);
+
+ // for dual certs
+ if (certauthEnrollType.equals(CERT_AUTH_DUAL)) {
+
+ CMS.debug("EnrollServlet: Attempting CERT_AUTH_DUAL");
+ boolean gotEncCert = false;
+ X509CertInfo[] cInfoArray = null;
+
+ try {
+ cInfoArray = handleCertAuthDual(certInfo, authToken,
+ sslClientCert, mCa,
+ certBasedOldSubjectDN,
+ certBasedOldSerialNum);
+ } catch (ECMSGWException e) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(e.toString());
+ }
+
+ if (cInfoArray != null && cInfoArray.length != 0) {
+ CMS.debug("EnrollServlet: cInfoArray Length " + cInfoArray.length);
+
+ certInfoArray = cInfoArray;
+ gotEncCert = true;
+ }
+
+ if (gotEncCert == false) {
+ // encryption cert not found, bail
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage(
+ "CMSGW_ENCRYPTION_CERT_NOT_FOUND"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCRYPTION_CERT_NOT_FOUND"));
+ }
+
+ } else if (certauthEnrollType.equals(CERT_AUTH_ENCRYPTION)) {
+
+ // first, make sure the client cert is indeed a
+ // signing only cert
+
+ try {
+
+ checkClientCertSigningOnly(sslClientCert);
+ } catch (ECMSGWException e) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(e.toString());
+ }
+
+ /*
+ * either crmf or keyGenInfo
+ */
+ if (keyGenInfo != null) {
+ KeyGenProcessor keyGenProc = new KeyGenProcessor(cmsReq,
+ this);
+
+ keyGenProc.fillCertInfo(null, certInfo,
+ authToken, httpParams);
+
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ CMS.debug("EnrollServlet: sslClientCert issuerDN = " +
+ sslClientCert.getIssuerDN().toString());
+ } else if (crmf != null && crmf != "") {
+ CRMFProcessor crmfProc = new CRMFProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = crmfProc.fillCertInfoArray(crmf,
+ authToken,
+ httpParams,
+ req);
+
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ CMS.debug("EnrollServlet: sslClientCert issuerDN = " +
+ sslClientCert.getIssuerDN().toString());
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_PROCESS_ENROLL_REQ") +
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+
+ } else if (certauthEnrollType.equals(CERT_AUTH_SINGLE)) {
+
+ // have to be buried here to handle the issuer
+
+ if (keyGenInfo != null) {
+ KeyGenProcessor keyGenProc = new KeyGenProcessor(cmsReq,
+ this);
+
+ keyGenProc.fillCertInfo(null, certInfo,
+ authToken, httpParams);
+ } else if (pkcs10 != null) {
+ PKCS10Processor pkcs10Proc = new PKCS10Processor(cmsReq,
+ this);
+
+ pkcs10Proc.fillCertInfo(pkcs10, certInfo,
+ authToken, httpParams);
+ } else if (cmc != null && cmc != "") {
+ CMCProcessor cmcProc = new CMCProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = cmcProc.fillCertInfoArray(cmc,
+ authToken,
+ httpParams,
+ req);
+ } else if (crmf != null && crmf != "") {
+ CRMFProcessor crmfProc = new CRMFProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = crmfProc.fillCertInfoArray(crmf,
+ authToken,
+ httpParams,
+ req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_PROCESS_ENROLL_REQ") +
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin
+ // certificate, an "agent" cert request for
+ // "bulk enrollment", or an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ }
+
+ } else if (keyGenInfo != null) {
+
+ CMS.debug("EnrollServlet: Trying KeyGen with no cert auth.");
+ KeyGenProcessor keyGenProc = new KeyGenProcessor(cmsReq, this);
+
+ keyGenProc.fillCertInfo(null, certInfo, authToken, httpParams);
+ } else if (pkcs10 != null) {
+ CMS.debug("EnrollServlet: Trying PKCS10 with no cert auth.");
+ PKCS10Processor pkcs10Proc = new PKCS10Processor(cmsReq, this);
+
+ pkcs10Proc.fillCertInfo(pkcs10, certInfo, authToken, httpParams);
+ } else if (cmc != null) {
+ CMS.debug("EnrollServlet: Trying CMC with no cert auth.");
+ CMCProcessor cmcProc = new CMCProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = cmcProc.fillCertInfoArray(cmc, authToken,
+ httpParams, req);
+ } else if (crmf != null && crmf != "") {
+ CMS.debug("EnrollServlet: Trying CRMF with no cert auth.");
+ CRMFProcessor crmfProc = new CRMFProcessor(cmsReq, this, enforcePop);
+
+ certInfoArray = crmfProc.fillCertInfoArray(crmf, authToken,
+ httpParams, req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_PROCESS_ENROLL_REQ") +
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+
+
+ // if ca, fill in default signing alg here
+
+ try {
+ ICertificateAuthority caSub =
+ (ICertificateAuthority) CMS.getSubsystem("ca");
+ if (certInfoArray != null && caSub != null) {
+ for (int ix = 0; ix < certInfoArray.length; ix++) {
+ X509CertInfo ci = (X509CertInfo)certInfoArray[ix];
+ String defaultSig = caSub.getDefaultAlgorithm();
+ AlgorithmId algid = AlgorithmId.get(defaultSig);
+ ci.set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(algid));
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("Failed to set signing alg to certinfo " + e.toString());
+ }
+
+ req.setExtData(IRequest.CERT_INFO, certInfoArray);
+
+
+ if (challengePassword != null && !challengePassword.equals("")) {
+ String pwd = hashPassword(challengePassword);
+
+ req.setExtData(CHALLENGE_PASSWORD, pwd);
+ }
+
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ // (either an "admin" cert request for an admin certificate,
+ // an "agent" cert request for "bulk enrollment", or
+ // an "EE" standard cert request)
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ auditServiceID,
+ auditCertificateSubjectName);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ X509CertImpl[] issuedCerts = null;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ // send request to request queue.
+ mRequestQueue.processRequest(req);
+ // process result.
+
+ // render OLD_CERT_TYPE's response differently, we
+ // do not want any javascript in HTML, and need to
+ // override the default render.
+ if (httpParams.getValueAsString(OLD_CERT_TYPE, null) != null) {
+ try {
+ renderServerEnrollResult(cmsReq);
+ cmsReq.setStatus(CMSRequest.SUCCESS); // no default render
+
+ issuedCerts =
+ cmsReq.getIRequest().getExtDataInCertArray(
+ IRequest.ISSUED_CERTS);
+
+ for (int i = 0; i < issuedCerts.length; i++) {
+ // (automated "agent" cert request processed
+ // - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(issuedCerts[i]));
+
+ audit(auditMessage);
+ }
+ } catch (IOException ex) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[0]);
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ boolean completed = handleEnrollAuditLog(req, cmsReq,
+ mAuthMgr, authToken,
+ certInfo, startTime);
+
+ if (completed == false) {
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[1]);
+
+ audit(auditMessage);
+
+ return;
+ }
+
+ // service success
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ issuedCerts = req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ String initiative = null;
+ String agentID;
+
+ if (authToken == null) {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ } else {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }
+
+ // audit log the success.
+ long endTime = CMS.getCurrentDate().getTime();
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[]
+ { req.getRequestId(),
+ initiative,
+ mAuthMgr,
+ "completed",
+ issuedCerts[0].getSubjectDN(),
+ "cert issued serial number: 0x" +
+ issuedCerts[0].getSerialNumber().toString(16) +
+ " time: " +
+ (endTime - startTime) }
+ );
+
+ // handle initial admin enrollment if in adminEnroll mode.
+ checkAdminEnroll(cmsReq, issuedCerts);
+
+ // return cert as mime type binary if requested.
+ if (checkImportCertToNav(cmsReq.getHttpResp(),
+ httpParams, issuedCerts[0])) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ for (int i = 0; i < issuedCerts.length; i++) {
+ // (automated "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(issuedCerts[i]));
+
+ audit(auditMessage);
+ }
+
+ return;
+ }
+
+ // use success template.
+ try {
+ cmsReq.setResult(issuedCerts);
+ renderTemplate(cmsReq, mEnrollSuccessTemplate,
+ mEnrollSuccessFiller);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ for (int i = 0; i < issuedCerts.length; i++) {
+ // (automated "agent" cert request processed - "accepted")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(issuedCerts[i]));
+
+ audit(auditMessage);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_TEMP_REND_ERR",
+ mEnrollSuccessFiller.toString(),
+ e.toString()));
+
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[2]);
+
+ audit(auditMessage);
+
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_RETURNING_RESULT_ERROR"));
+ }
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ // (automated "agent" cert request processed - "rejected")
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ SIGNED_AUDIT_AUTOMATED_REJECTION_REASON[3]);
+
+ audit(auditMessage);
+
+ throw eAudit1;
+ }
+
+ return;
+ }
+
+ /**
+ * check if this is first enroll from admin enroll.
+ * If so disable admin enroll from here on.
+ */
+ protected void checkAdminEnroll(CMSRequest cmsReq, X509CertImpl[] issuedCerts)
+ throws EBaseException {
+ // this is special case, get the admin certificate
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID)) {
+ addAdminAgent(cmsReq, issuedCerts);
+ CMSGateway.disableAdminEnroll();
+ }
+ }
+
+ protected void addAdminAgent(CMSRequest cmsReq, X509CertImpl[] issuedCerts)
+ throws EBaseException {
+ String userid = cmsReq.getHttpParams().getValueAsString("uid");
+ IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ IUser adminuser = ug.createUser(userid);
+
+ adminuser.setX509Certificates(issuedCerts);
+ try {
+ ug.addUserCert(adminuser);
+ } catch (netscape.ldap.LDAPException e) {
+ CMS.debug(
+ "EnrollServlet: Cannot add admin's certificate to its entry in the " +
+ "user group database. Error " + e);
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ADDING_ADMIN_CERT_ERROR", e.toString()));
+ }
+ IGroup agentGroup =
+ ug.getGroupFromName(CA_AGENT_GROUP);
+
+ if (agentGroup != null) {
+ // add user to the group if necessary
+ if (!agentGroup.isMember(userid)) {
+ agentGroup.addMemberName(userid);
+ ug.modifyGroup(agentGroup);
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_USRGRP,
+ AuditFormat.LEVEL, AuditFormat.ADDUSERGROUPFORMAT,
+ new Object[] {userid, userid, CA_AGENT_GROUP}
+ );
+
+ }
+ } else {
+ String msg = "Cannot add admin to the " +
+ CA_AGENT_GROUP +
+ " group: Group does not exist.";
+
+ CMS.debug("EnrollServlet: " + msg);
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_ADDING_ADMIN_ERROR"));
+ }
+ }
+
+ protected void renderServerEnrollResult(CMSRequest cmsReq) throws
+ IOException {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ httpResp.setContentType("text/html");
+ ServletOutputStream out = null;
+
+ out = httpResp.getOutputStream();
+
+ // get template based on request status
+ out.println("<HTML>");
+ out.println("<TITLE>");
+ out.println("Server Enrollment");
+ out.println("</TITLE>");
+ // out.println("<BODY BGCOLOR=white>");
+
+ if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ out.println("<H1>");
+ out.println("SUCCESS");
+ out.println("</H1>");
+ out.println("Your request is submitted and approved. Please cut and paste the certificate into your server."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("Certificate: ");
+ out.println("<P>");
+ out.println("<PRE>");
+ X509CertImpl certs[] =
+ cmsReq.getIRequest().getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ out.println(CMS.getEncodedCert(certs[0]));
+ out.println("</PRE>");
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ out.println("<!HTTP_OUTPUT X509_CERTIFICATE=" +
+ CMS.getEncodedCert(certs[0]) + ">");
+ } else if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.PENDING)) {
+ out.println("<H1>");
+ out.println("PENDING");
+ out.println("</H1>");
+ out.println("Your request is submitted. You can check on the status of your request with an authorized agent or local administrator by referring to the request ID."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ } else {
+ out.println("<H1>");
+ out.println("ERROR");
+ out.println("</H1>");
+ out.println("<!INFO>");
+ out.println("Please consult your local administrator for assistance."); // XXX - localize the message
+ out.println("<!/INFO>");
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Error: ");
+ out.println(cmsReq.getError()); // XXX - need to parse in Locale
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT ERROR=" +
+ cmsReq.getError() + ">");
+ }
+
+ /**
+ // include all the input data
+ ArgBlock args = cmsReq.getHttpParams();
+ Enumeration ele = args.getElements();
+ while (ele.hasMoreElements()) {
+ String eleT = (String)ele.nextElement();
+ out.println("<!HTTP_INPUT " + eleT + "=" +
+ args.get(eleT) + ">");
+ }
+ **/
+
+ out.println("</HTML>");
+ }
+
+ // XXX ALERT !!
+ // Remove the following and calls to them when we bundle a cartman
+ // later than alpha1.
+ // These are here to cover up problem in cartman where the
+ // key usage extension always ends up being digital signature only
+ // and for rsa-ex ends up having no bits set.
+
+ private boolean mIsTestBed = false;
+
+ private void init_testbed_hack(IConfigStore config)
+ throws EBaseException {
+ mIsTestBed = config.getBoolean("isTestBed", true);
+ }
+
+ private void do_testbed_hack(
+ int nummsgs, X509CertInfo[] certinfo, IArgBlock httpParams)
+ throws EBaseException {
+ if (!mIsTestBed)
+ return;
+
+ // get around bug in cartman - bits are off by one byte.
+ for (int i = 0; i < certinfo.length; i++) {
+ try {
+ X509CertInfo cert = certinfo[i];
+ CertificateExtensions exts = (CertificateExtensions)
+ cert.get(CertificateExtensions.NAME);
+
+ if (exts == null) {
+ // should not happen.
+ continue;
+ }
+ KeyUsageExtension ext = (KeyUsageExtension)
+ exts.get(KeyUsageExtension.NAME);
+
+ if (ext == null)
+ // should not happen
+ continue;
+ byte[] value = ext.getExtensionValue();
+
+ if (value[0] == 0x03 && value[1] == 0x02 && value[2] == 0x07) {
+ byte[] newvalue = new byte[value.length + 1];
+
+ newvalue[0] = 0x03;
+ newvalue[1] = 0x03;
+ newvalue[2] = 0x07;
+ newvalue[3] = value[3];
+ // force encryption certs to have digitial signature
+ // set too so smime can find the cert for encryption.
+ if (value[3] == 0x20) {
+
+ /*
+ newvalue[3] = 0x3f;
+ newvalue[4] = (byte)0x80;
+ */
+ if (httpParams.getValueAsBoolean(
+ "dual-use-hack", true)) {
+ newvalue[3] = (byte) 0xE0; // same as rsa-dual-use.
+ }
+ }
+ newvalue[4] = 0;
+ KeyUsageExtension newext =
+ new KeyUsageExtension(Boolean.valueOf(true),
+ (Object) newvalue);
+
+ exts.delete(KeyUsageExtension.NAME);
+ exts.set(KeyUsageExtension.NAME, newext);
+
+ }
+ } catch (IOException e) {
+ // should never happen
+ continue;
+ } catch (CertificateException e) {
+ // should never happen
+ continue;
+ }
+ }
+
+ }
+
+ /**
+ * 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 x509cert an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(X509CertImpl x509cert) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ 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 = com.netscape.osutil.OSUtil.BtoA(rawData).trim();
+
+ StringBuffer sb = new StringBuffer();
+ // extract all line separators from the "base64Data"
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (base64Data.substring(i, i).getBytes() != EOL) {
+ sb.append(base64Data.substring(i, 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;
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java
new file mode 100644
index 000000000..196c56a9b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetBySerial.java
@@ -0,0 +1,292 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.security.cert.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.cmsutil.crypto.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.*;
+import org.mozilla.jss.pkix.primitive.*;
+import org.mozilla.jss.pkix.crmf.*;
+
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Retrieve certificate by serial number.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetBySerial extends CMSServlet {
+
+ private final static String INFO = "GetBySerial";
+
+ private final static String IMPORT_CERT_TEMPLATE = "ImportCert.template";
+ private String mImportTemplate = null;
+ private String mIETemplate = null;
+ private ICMSTemplateFiller mImportTemplateFiller = null;
+ IRequestQueue mReqQ = null;
+
+ public GetBySerial() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the template file
+ * "ImportCert.template" to import the cert to the users browser,
+ * if that is what the user requested
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ try {
+ mImportTemplate = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ mIETemplate = sc.getInitParameter("importCertTemplate");
+ if (mImportTemplate == null)
+ mImportTemplate = IMPORT_CERT_TEMPLATE;
+ } catch (Exception e) {
+ mImportTemplate = null;
+ }
+ mImportTemplateFiller = new ImportCertsTemplateFiller();
+
+ // override success and error templates to null -
+ // handle templates locally.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ ICertificateAuthority mCa = (ICertificateAuthority) CMS.getSubsystem("ca");
+ if (mCa == null) {
+ return;
+ }
+
+ mReqQ = mCa.getRequestQueue();
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber serial number of certificate in HEX
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ int serialNumber = -1;
+ boolean noError = true;
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse response = cmsReq.getHttpResp();
+ IArgBlock args = cmsReq.getHttpParams();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "import");
+ } 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 serial = args.getValueAsString("serialNumber", null);
+ String browser = args.getValueAsString("browser", null);
+ BigInteger serialNo = null;
+
+ try {
+ serialNo = new BigInteger(serial, 16);
+ } catch (NumberFormatException e) {
+ serialNo = null;
+ }
+ if (serial == null || serialNo == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_SERIAL_NUMBER"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_SERIAL_NUMBER")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ ICertRecord certRecord = (ICertRecord) getCertRecord(serialNo);
+ if (certRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CERT_SERIAL_NOT_FOUND_1", serialNo.toString(16)));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CERT_SERIAL_NOT_FOUND", "0x" + serialNo.toString(16))));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ // if RA, needs requestOwner to match
+ // first, find the user's group
+ if (authToken != null) {
+ String group = authToken.getInString("group");
+
+ if ((group != null) && (group != "")) {
+ CMS.debug("GetBySerial process: auth group="+group);
+ if (group.equals("Registration Manager Agents")) {
+ boolean groupMatched = false;
+ // find the cert record's orig. requestor's group
+ MetaInfo metai = certRecord.getMetaInfo();
+ if (metai != null) {
+ String reqId = (String) metai.get(ICertRecord.META_REQUEST_ID);
+ RequestId rid = new RequestId(reqId);
+ IRequest creq = mReqQ.findRequest(rid);
+ if (creq != null) {
+ String reqOwner = creq.getRequestOwner();
+ if (reqOwner != null) {
+ CMS.debug("GetBySerial process: req owner="+reqOwner);
+ if (reqOwner.equals(group))
+ groupMatched = true;
+ }
+ }
+ }
+ if (groupMatched == false) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CERT_SERIAL_NOT_FOUND_1", serialNo.toString(16)));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CERT_SERIAL_NOT_FOUND", "0x" + serialNo.toString(16))));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ }
+ }
+ }
+
+ X509CertImpl cert = certRecord.getCertificate();
+
+ String browser1 = req.getParameter("browser");
+ if (cert != null) {
+ // if there's a crmf request id, set that too.
+ if (browser != null && browser.equals("ie")) {
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ Locale[] locale = new Locale[1];
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+ ICertificateAuthority ca = (ICertificateAuthority)CMS.getSubsystem("ca");
+ CertificateChain cachain = ca.getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+ X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+ int m = 1, n = 0;
+
+ for (; n < cacerts.length; m++, n++) {
+ userChain[m] = (X509CertImpl) cacerts[n];
+ }
+
+ userChain[0] = cert;
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]), userChain, new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try {
+ p7.encodeSignedData(bos);
+ } catch (Exception eee) {
+ }
+
+ byte[] p7Bytes = bos.toByteArray();
+ String p7Str = CMS.BtoA(p7Bytes);
+
+ header.addStringValue("pkcs7", CryptoUtil.normalizeCertStr(p7Str));
+ try {
+ CMSTemplate form = getTemplate(mIETemplate, req, locale);
+ ServletOutputStream out = response.getOutputStream();
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ response.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ return;
+ } catch (Exception ee) {
+ CMS.debug("GetBySerial process: Exception="+ee.toString());
+ }
+ } //browser is IE
+
+ MetaInfo metai = certRecord.getMetaInfo();
+ String crmfReqId = null;
+
+ if (metai != null) {
+ crmfReqId = (String) metai.get(ICertRecord.META_CRMF_REQID);
+ if (crmfReqId != null)
+ cmsReq.setResult(IRequest.CRMF_REQID, crmfReqId);
+ }
+
+ if (crmfReqId == null && checkImportCertToNav(
+ cmsReq.getHttpResp(), cmsReq.getHttpParams(), cert)) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ // use import cert template to return cert.
+ X509CertImpl[] certs = new X509CertImpl[] { (X509CertImpl) cert };
+
+ cmsReq.setResult(certs);
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ // XXX follow request in cert record to set certtype, which will
+ // import cert only if it's client. For now assume "client" if
+ // someone clicked to import this cert.
+ cmsReq.getHttpParams().set("certType", "client");
+
+ try {
+ renderTemplate(cmsReq, mImportTemplate, mImportTemplateFiller);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java
new file mode 100644
index 000000000..4093b989f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCAChain.java
@@ -0,0 +1,405 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+ import com.netscape.cms.servlet.base.*;
+ import java.io.*;
+ import java.util.*;
+ import java.math.*;
+ import javax.servlet.*;
+ import java.security.cert.*;
+ import javax.servlet.http.*;
+ import netscape.ldap.*;
+ import netscape.security.x509.*;
+ import com.netscape.certsrv.base.*;
+ import com.netscape.certsrv.authority.*;
+ import com.netscape.certsrv.policy.*;
+ import com.netscape.certsrv.request.IRequest;
+ import com.netscape.certsrv.dbs.*;
+ import com.netscape.certsrv.dbs.certdb.*;
+ import com.netscape.certsrv.ldap.*;
+ import com.netscape.certsrv.logging.*;
+ import com.netscape.certsrv.apps.CMS;
+ import com.netscape.certsrv.authentication.*;
+ import com.netscape.certsrv.authorization.*;
+ import com.netscape.cms.servlet.*;
+
+
+ /**
+ * Retrieve the Certificates comprising the CA Chain for this CA.
+ *
+ * @version $Revision$, $Date$
+ */
+ public class GetCAChain extends CMSServlet {
+ private final static String TPL_FILE = "displayCaCert.template";
+ private String mFormPath = null;
+
+ public GetCAChain() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ // override success to display own output.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ // coming from ee
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param op 'downloadBIN' - return the binary certificate chain
+ * <li>http.param op 'displayIND' - display pretty-print of certificate chain components
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ // Get the operation code
+ String op = null;
+
+ op = args.getValueAsString("op", null);
+ if (op == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_OPTIONS_SELECTED"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_OPTIONS_SELECTED"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ AuthzToken authzToken = null;
+
+ if (op.startsWith("download")) {
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "download");
+ } 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;
+ }
+
+ downloadChain(op, args, httpReq, httpResp, cmsReq);
+ } else if (op.startsWith("display")) {
+ try {
+ authzToken = mAuthz.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;
+ }
+
+ displayChain(op, args, httpReq, httpResp, cmsReq);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_OPTIONS_CA_CHAIN"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_OPTIONS_SELECTED"));
+ }
+ // cmsReq.setResult(null);
+ return;
+ }
+
+ private void downloadChain(String op,
+ IArgBlock args,
+ HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ CMSRequest cmsReq)
+ throws EBaseException {
+
+ /* check browser info ? */
+
+ /* check if pkcs7 will work for both nav and ie */
+
+ byte[] bytes = null;
+
+ /*
+ * Some IE actions - IE doesn't want PKCS7 for "download" CA Cert.
+ * This means that we can only hand out the root CA, and not
+ * the whole chain.
+ */
+
+ if (clientIsMSIE(httpReq) && (op.equals("download") || op.equals("downloadBIN"))) {
+ X509Certificate[] caCerts =
+ ((ICertAuthority) mAuthority).getCACertChain().getChain();
+
+ try {
+ bytes = caCerts[0].getEncoded();
+ } catch (CertificateEncodingException e) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_GETTING_CACERT_ENCODED", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_GETTING_CA_CERT_ERROR"));
+ }
+ } else {
+ CertificateChain certChain =
+ ((ICertAuthority) mAuthority).getCACertChain();
+
+ if (certChain == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_CHAIN_EMPTY"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CA_CHAIN_EMPTY"));
+ }
+
+ try {
+ ByteArrayOutputStream encoded = new ByteArrayOutputStream();
+
+ certChain.encode(encoded, false);
+ bytes = encoded.toByteArray();
+ } catch (IOException e) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_ENCODING_CA_CHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCODING_CA_CHAIN_ERROR"));
+ }
+ }
+
+ String mimeType = null;
+
+ if (op.equals("downloadBIN")) {
+ mimeType = "application/octet-stream";
+ } else {
+ try {
+ mimeType = args.getValueAsString("mimeType");
+ } catch (EBaseException e) {
+ mimeType = "application/octet-stream";
+ }
+ }
+
+ try {
+ if (op.equals("downloadBIN")) {
+ // file suffixes changed to comply with RFC 5280
+ // requirements for AIA extensions
+ if (clientIsMSIE(httpReq)) {
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=ca.cer");
+ } else {
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=ca.p7c");
+ }
+ }
+ httpResp.setContentType(mimeType);
+ httpResp.getOutputStream().write(bytes);
+ httpResp.setContentLength(bytes.length);
+ httpResp.getOutputStream().flush();
+ } catch (IOException e) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAYING_CACHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAYING_CACHAIN_ERROR"));
+ }
+ }
+
+ private void displayChain(String op,
+ IArgBlock args,
+ HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ CMSRequest cmsReq)
+ throws EBaseException {
+ String outputString = null;
+
+ CertificateChain certChain =
+ ((ICertAuthority) mAuthority).getCACertChain();
+
+ if (certChain == null) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_CHAIN_NOT_AVAILABLE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CA_CHAIN_NOT_AVAILABLE"));
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ String displayFormat = null;
+
+ if (op.equals("displayIND")) {
+ displayFormat = "individual";
+ } else {
+ try {
+ displayFormat = args.getValueAsString("displayFormat");
+ } catch (EBaseException e) {
+ displayFormat = "chain";
+ }
+ }
+
+ header.addStringValue("displayFormat", displayFormat);
+
+ if (displayFormat.equals("chain")) {
+ String subjectdn = null;
+ byte[] bytes = null;
+
+ try {
+ subjectdn =
+ certChain.getFirstCertificate().getSubjectDN().toString();
+ ByteArrayOutputStream encoded = new ByteArrayOutputStream();
+
+ certChain.encode(encoded);
+ bytes = encoded.toByteArray();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_ENCODING_CA_CHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCODING_CA_CHAIN_ERROR"));
+ }
+
+ String chainBase64 = getBase64(bytes);
+
+ header.addStringValue("subjectdn", subjectdn);
+ header.addStringValue("chainBase64", chainBase64);
+ } else {
+ try {
+ X509Certificate[] certs = certChain.getChain();
+
+ header.addIntegerValue("length", certs.length);
+ locale[0] = getLocale(httpReq);
+ for (int i = 0; i < certs.length; i++) {
+ byte[] bytes = null;
+
+ try {
+ bytes = certs[i].getEncoded();
+ } catch (CertificateEncodingException e) {
+ throw new IOException("Internal Error");
+ }
+ String subjectdn = certs[i].getSubjectDN().toString();
+ String finger = null;
+ try {
+ finger = CMS.getFingerPrints(certs[i]);
+ } catch (Exception e) {
+ throw new IOException("Internal Error");
+ }
+
+ ICertPrettyPrint certDetails =
+ CMS.getCertPrettyPrint((X509CertImpl) certs[i]);
+
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("fingerprints", finger);
+ rarg.addStringValue("subjectdn", subjectdn);
+ rarg.addStringValue("base64", getBase64(bytes));
+ rarg.addStringValue("certDetails",
+ certDetails.toString(locale[0]));
+ argSet.addRepeatRecord(rarg);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_DISPLAYING_CACHAIN_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAYING_CACHAIN_ERROR"));
+ }
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+
+ }
+
+ /**
+ * gets base 64 encoded cert
+ */
+ private String getBase64(byte[] certBytes) {
+ String certBase64 = CMS.BtoA(certBytes);
+
+ return certBase64;
+ }
+
+ /**
+ * gets base 64 encoded cert chain
+ */
+ private String getChainBase64(byte[] certBytes) {
+ String certBase64 = CMS.BtoA(certBytes);
+
+ return certBase64;
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader("accept-language");
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java
new file mode 100644
index 000000000..6298b7d59
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCRL.java
@@ -0,0 +1,468 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.*;
+
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Retrieve CRL for a Certificate Authority
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetCRL extends CMSServlet {
+ private final static String TPL_FILE = "displayCRL.template";
+ private String mFormPath = null;
+
+ public GetCRL() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ * @see DisplayCRL#process
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ 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;
+ }
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+CMS.debug("**** mFormPath before getTemplate = "+mFormPath);
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // Get the operation code
+ String op = null;
+ String crlId = null;
+
+ op = args.getValueAsString("op", null);
+ crlId = args.getValueAsString("crlIssuingPoint", null);
+ if (op == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_OPTIONS_SELECTED"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_OPTIONS_SELECTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if (crlId == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_NO_CRL_ISSUING_POINT"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_CRL_SELECTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ ICRLIssuingPointRecord crlRecord = null;
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+ ICRLIssuingPoint crlIP = null;
+ if (ca != null) crlIP = ca.getCRLIssuingPoint(crlId);
+
+ try {
+ crlRecord = (ICRLIssuingPointRecord) ca.getCRLRepository().readCRLIssuingPointRecord(crlId);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CRL_ISSUING_POINT_FOUND", crlId));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_FOUND")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if (crlRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlId));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_UPDATED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ header.addStringValue("crlIssuingPoint", crlId);
+ header.addStringValue("crlNumber", crlRecord.getCRLNumber().toString());
+ long lCRLSize = crlRecord.getCRLSize().longValue();
+
+ header.addLongValue("crlSize", lCRLSize);
+ if (crlIP != null) {
+ header.addStringValue("crlDescription", crlIP.getDescription());
+ }
+
+ String crlDisplayType = args.getValueAsString("crlDisplayType", null);
+ if (crlDisplayType != null) {
+ header.addStringValue("crlDisplayType", crlDisplayType);
+ }
+
+ if ((op.equals("checkCRLcache") ||
+ (op.equals("displayCRL") && crlDisplayType != null && crlDisplayType.equals("cachedCRL"))) &&
+ (crlIP == null || (!crlIP.isCRLCacheEnabled()) || crlIP.isCRLCacheEmpty())) {
+ cmsReq.setError(
+ CMS.getUserMessage(
+ ((crlIP != null && crlIP.isCRLCacheEnabled() && crlIP.isCRLCacheEmpty())?
+ "CMS_GW_CRL_CACHE_IS_EMPTY":"CMS_GW_CRL_CACHE_IS_NOT_ENABLED"), crlId));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ byte[] crlbytes = null;
+
+ if (op.equals("importDeltaCRL") || op.equals("getDeltaCRL") ||
+ (op.equals("displayCRL") && crlDisplayType != null &&
+ crlDisplayType.equals("deltaCRL"))) {
+ crlbytes = crlRecord.getDeltaCRL();
+ } else if (op.equals("importCRL") || op.equals("getCRL") ||
+ op.equals("checkCRL") ||
+ (op.equals("displayCRL") &&
+ crlDisplayType != null &&
+ (crlDisplayType.equals("entireCRL") ||
+ crlDisplayType.equals("crlHeader") ||
+ crlDisplayType.equals("base64Encoded")))) {
+ crlbytes = crlRecord.getCRL();
+ }
+
+ if (crlbytes == null && (!op.equals("checkCRLcache")) &&
+ (!(op.equals("displayCRL") && crlDisplayType != null &&
+ crlDisplayType.equals("cachedCRL")))) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlId));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_UPDATED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ byte[] bytes = crlbytes;
+
+ X509CRLImpl crl = null;
+
+ if (op.equals("checkCRL") || op.equals("importCRL") ||
+ op.equals("importDeltaCRL") ||
+ (op.equals("displayCRL") && crlDisplayType != null &&
+ (crlDisplayType.equals("entireCRL") ||
+ crlDisplayType.equals("crlHeader") ||
+ crlDisplayType.equals("base64Encoded") ||
+ crlDisplayType.equals("deltaCRL")))) {
+ try {
+ if (op.equals("displayCRL") && crlDisplayType != null &&
+ crlDisplayType.equals("crlHeader")) {
+ crl = new X509CRLImpl(crlbytes, false);
+ } else {
+ crl = new X509CRLImpl(crlbytes);
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_FAILED_DECODE_CRL_1", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODE_CRL_FAILED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if (crl == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_FAILED_DECODE_CRL"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DECODE_CRL_FAILED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ if ((op.equals("importDeltaCRL") || (op.equals("displayCRL") &&
+ crlDisplayType != null && crlDisplayType.equals("deltaCRL"))) &&
+ ((!(crlIP != null && crlIP.isThisCurrentDeltaCRL(crl))) &&
+ (crlRecord.getCRLNumber() == null ||
+ crlRecord.getDeltaCRLNumber() == null ||
+ crlRecord.getDeltaCRLNumber().compareTo(crlRecord.getCRLNumber()) < 0 ||
+ crlRecord.getDeltaCRLSize() == null ||
+ crlRecord.getDeltaCRLSize().longValue() == -1))) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_NO_DELTA_CRL_1"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRL_NOT_UPDATED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ }
+
+ String mimeType = "application/x-pkcs7-crl";
+
+ if (op.equals("checkCRLcache") || op.equals("checkCRL") || op.equals("displayCRL")) {
+ header.addStringValue("toDo", op);
+ String certSerialNumber = args.getValueAsString("certSerialNumber", "");
+
+ header.addStringValue("certSerialNumber", certSerialNumber);
+ if (certSerialNumber.startsWith("0x")) {
+ certSerialNumber = hexToDecimal(certSerialNumber);
+ }
+
+ if (op.equals("checkCRLcache")) {
+ if (crlIP.getRevocationDateFromCache(
+ new BigInteger(certSerialNumber), false, false) != null) {
+ header.addBooleanValue("isOnCRL", true);
+ } else {
+ header.addBooleanValue("isOnCRL", false);
+ }
+ }
+
+ if (op.equals("checkCRL")) {
+ header.addBooleanValue("isOnCRL",
+ crl.isRevoked(new BigInteger(certSerialNumber)));
+ }
+
+ if (op.equals("displayCRL")) {
+ if (crlDisplayType.equals("entireCRL") || crlDisplayType.equals("cachedCRL")) {
+ ICRLPrettyPrint crlDetails = (crlDisplayType.equals("entireCRL"))?
+ CMS.getCRLPrettyPrint(crl):
+ CMS.getCRLCachePrettyPrint(crlIP);
+ String pageStart = args.getValueAsString("pageStart", null);
+ String pageSize = args.getValueAsString("pageSize", null);
+
+ if (pageStart != null && pageSize != null) {
+ long lPageStart = new Long(pageStart).longValue();
+ long lPageSize = new Long(pageSize).longValue();
+
+ if (lPageStart < 1) lPageStart = 1;
+
+ header.addStringValue("crlPrettyPrint",
+ crlDetails.toString(locale[0],
+ lCRLSize, lPageStart, lPageSize));
+ header.addLongValue("pageStart", lPageStart);
+ header.addLongValue("pageSize", lPageSize);
+ } else {
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale[0]));
+ }
+ } else if (crlDisplayType.equals("crlHeader")) {
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(crl);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale[0], lCRLSize, 0, 0));
+ } else if (crlDisplayType.equals("base64Encoded")) {
+ try {
+ byte[] ba = crl.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ } else if (crlDisplayType.equals("deltaCRL")) {
+ header.addIntegerValue("deltaCRLSize",
+ crl.getNumberOfRevokedCertificates());
+
+ ICRLPrettyPrint crlDetails = CMS.getCRLPrettyPrint(crl);
+
+ header.addStringValue(
+ "crlPrettyPrint", crlDetails.toString(locale[0], 0, 0, 0));
+
+ try {
+ byte[] ba = crl.getEncoded();
+ String crlBase64Encoded = com.netscape.osutil.OSUtil.BtoA(ba);
+ int length = crlBase64Encoded.length();
+ int i = 0;
+ int j = 0;
+ int n = 1;
+
+ while (i < length) {
+ int k = crlBase64Encoded.indexOf('\n', i);
+
+ if (n < 100 && k > -1) {
+ n++;
+ i = k + 1;
+ } else {
+ n = 1;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ if (k > -1) {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, k));
+ i = k + 1;
+ j = i;
+ } else {
+ rarg.addStringValue("crlBase64Encoded", crlBase64Encoded.substring(j, length));
+ i = length;
+ }
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ } catch (CRLException e) {
+ }
+ }
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ return;
+ } else if (op.equals("importCRL") || op.equals("importDeltaCRL")) {
+ if (clientIsMSIE(httpReq))
+ mimeType = "application/pkix-crl";
+ else
+ mimeType = "application/x-pkcs7-crl";
+ } else if (op.equals("getCRL")) {
+ mimeType = "application/octet-stream";
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=" + crlId + ".crl");
+ } else if (op.equals("getDeltaCRL")) {
+ mimeType = "application/octet-stream";
+ httpResp.setHeader("Content-disposition",
+ "attachment; filename=delta-" + crlId + ".crl");
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_OPTIONS_SELECTED"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_OPTIONS_SELECTED"));
+ }
+
+ try {
+ // if (clientIsMSIE(httpReq) && op.equals("getCRL"))
+ // httpResp.setHeader("Content-disposition",
+ // "attachment; filename=getCRL.crl");
+ httpResp.setContentType(mimeType);
+ httpResp.setContentLength(bytes.length);
+ httpResp.getOutputStream().write(bytes);
+ httpResp.getOutputStream().flush();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_DISPLAYING_CRLINFO"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAYING_CRLINFO_ERROR"));
+ }
+ // cmsReq.setResult(null);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ private String hexToDecimal(String hex) {
+ String newHex = hex.substring(2);
+ BigInteger bi = new BigInteger(newHex, 16);
+
+ return bi.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java
new file mode 100644
index 000000000..7f260216c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetCertFromRequest.java
@@ -0,0 +1,338 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import netscape.security.extensions.*;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.Extension;
+import netscape.security.x509.KeyUsageExtension;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import java.io.*;
+import java.util.Locale;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Gets a issued certificate from a request id.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetCertFromRequest extends CMSServlet {
+ 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.
+ * <ul>
+ * <li>http.param requestId The request ID to search on
+ * </ul>
+ *
+ * @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 {
+ Integer.parseInt(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;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java
new file mode 100644
index 000000000..7f1196bab
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetEnableStatus.java
@@ -0,0 +1,174 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.math.*;
+import javax.servlet.*;
+import java.security.cert.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.cms.authentication.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Servlet to get the enrollment status, enable or disable.
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetEnableStatus extends CMSServlet {
+ private final static String TPL_FILE = "userEnroll.template";
+ private String mFormPath = null;
+
+ public GetEnableStatus() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // coming from agent
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "read");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String reqHost = httpReq.getRemoteHost();
+
+ // Construct an ArgBlock
+ IArgBlock args = cmsReq.getHttpParams();
+
+ if (!(mAuthority instanceof IRegistrationAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CA_FROM_RA_NOT_IMP"));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_YET_IMPLEMENTED")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE",
+ mFormPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+ long timeout = mgr.DEFAULT_TIMEOUT / 1000;
+
+ header.addStringValue("timeout", "" + timeout);
+ header.addStringValue("reqHost", reqHost);
+
+ for (Enumeration hosts = mgr.getHosts(); hosts.hasMoreElements();) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("hosts", (String) hosts.nextElement());
+ argSet.addRepeatRecord(rarg);
+ }
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java b/pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java
new file mode 100644
index 000000000..4d9515861
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/GetInfo.java
@@ -0,0 +1,368 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.dbs.crldb.*;
+
+
+/**
+ * Get detailed information about CA CRL processing
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetInfo extends CMSServlet {
+
+ private final static String INFO = "GetInfo";
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs GetInfo servlet.
+ */
+ public GetInfo() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ mFormPath = "";
+ if (mAuthority instanceof ICertificateAuthority)
+ mCA = (ICertificateAuthority) mAuthority;
+
+ // override success to do output our own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * XXX Process the HTTP request.
+ * <ul>
+ * <li>http.param template filename of template to use to render the result
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ 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;
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ String template = req.getParameter("template");
+ String formFile = "";
+
+/*
+ for (int i = 0; ((template != null) && (i < template.length())); i++) {
+ char c = template.charAt(i);
+ if (!Character.isLetterOrDigit(c) && c != '_' && c != '-') {
+ template = null;
+ break;
+ }
+ }
+*/
+
+
+ if (template != null) {
+ formFile = template + ".template";
+ } else {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE_1"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+CMS.debug("*** formFile = "+formFile);
+ try {
+ form = getTemplate(formFile, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", formFile, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ process(argSet, header, req, resp, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ if (mCA != null) {
+ String crlIssuingPoints = "";
+ String crlNumbers = "";
+ String deltaNumbers = "";
+ String crlSizes = "";
+ String deltaSizes = "";
+ String crlDescriptions = "";
+ StringBuffer crlSplits = new StringBuffer();
+ String recentChanges = "";
+ String crlTesting = "";
+ boolean isDeltaCRLEnabled = false;
+
+ String masterHost = CMS.getConfigStore().getString("master.ca.agent.host", "");
+ String masterPort = CMS.getConfigStore().getString("master.ca.agent.port", "");
+
+ if (masterHost != null && masterHost.length() > 0 &&
+ masterPort != null && masterPort.length() > 0) {
+
+ ICRLRepository crlRepository = mCA.getCRLRepository();
+
+ Vector ipNames = crlRepository.getIssuingPointsNames();
+ for (int i = 0; i < ipNames.size(); i++) {
+ String ipName = (String)ipNames.elementAt(i);
+ ICRLIssuingPointRecord crlRecord = null;
+ try {
+ crlRecord = crlRepository.readCRLIssuingPointRecord(ipName);
+ } catch (Exception e) {
+ }
+ if (crlRecord != null) {
+ if (crlIssuingPoints.length() > 0)
+ crlIssuingPoints += "+";
+ crlIssuingPoints += ipName;
+
+ BigInteger crlNumber = crlRecord.getCRLNumber();
+ if (crlNumbers.length() > 0)
+ crlNumbers += "+";
+ if (crlNumber != null)
+ crlNumbers += crlNumber.toString();
+
+ if (crlSizes.length() > 0)
+ crlSizes += "+";
+ crlSizes += ((crlRecord.getCRLSize() != null)?
+ crlRecord.getCRLSize().toString(): "-1");
+
+ if (deltaSizes.length() > 0)
+ deltaSizes += "+";
+ long dSize = -1;
+ if (crlRecord.getDeltaCRLSize() != null)
+ dSize = crlRecord.getDeltaCRLSize().longValue();
+ deltaSizes += dSize;
+
+ BigInteger deltaNumber = crlRecord.getDeltaCRLNumber();
+ if (deltaNumbers.length() > 0)
+ deltaNumbers += "+";
+ if (deltaNumber != null && dSize > -1) {
+ deltaNumbers += deltaNumber.toString();
+ isDeltaCRLEnabled |= true;
+ } else {
+ deltaNumbers += "0";
+ }
+
+ if (recentChanges.length() > 0)
+ recentChanges += "+";
+ recentChanges += "-, -, -";
+
+ if (crlTesting.length() > 0)
+ crlTesting += "+";
+ crlTesting += "0";
+ }
+ }
+
+ } else {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (ip.isCRLIssuingPointEnabled()) {
+ if (crlIssuingPoints.length() > 0)
+ crlIssuingPoints += "+";
+ crlIssuingPoints += ip.getId();
+
+ BigInteger crlNumber = ip.getCRLNumber();
+ if (crlNumbers.length() > 0)
+ crlNumbers += "+";
+ if (crlNumber != null)
+ crlNumbers += crlNumber.toString();
+
+ BigInteger deltaNumber = ip.getDeltaCRLNumber();
+ if (deltaNumbers.length() > 0)
+ deltaNumbers += "+";
+ if (deltaNumber != null)
+ deltaNumbers += deltaNumber.toString();
+
+ if (crlSizes.length() > 0)
+ crlSizes += "+";
+ crlSizes += ip.getCRLSize();
+
+ if (deltaSizes.length() > 0)
+ deltaSizes += "+";
+ deltaSizes += ip.getDeltaCRLSize();
+
+ if (crlDescriptions.length() > 0)
+ crlDescriptions += "+";
+ crlDescriptions += ip.getDescription();
+
+ if (recentChanges.length() > 0)
+ recentChanges += "+";
+ if (ip.isCRLUpdateInProgress() == ip.CRL_PUBLISHING_STARTED) {
+ recentChanges += "Publishing CRL #" + ip.getCRLNumber();
+ } else if (ip.isCRLUpdateInProgress() == ip.CRL_UPDATE_STARTED) {
+ recentChanges += "Creating CRL #" + ip.getNextCRLNumber();
+ } else { // ip.CRL_UPDATE_DONE
+ recentChanges += ip.getNumberOfRecentlyRevokedCerts() + ", " +
+ ip.getNumberOfRecentlyUnrevokedCerts() + ", " +
+ ip.getNumberOfRecentlyExpiredCerts();
+ }
+ isDeltaCRLEnabled |= ip.isDeltaCRLEnabled();
+
+ if (crlSplits.length() > 0)
+ crlSplits.append("+");
+ Vector splits = ip.getSplitTimes();
+
+ for (int i = 0; i < splits.size(); i++) {
+ crlSplits.append(splits.elementAt(i));
+ if (i + 1 < splits.size())
+ crlSplits.append(",");
+ }
+
+ if (crlTesting.length() > 0)
+ crlTesting += "+";
+ crlTesting += ((ip.isCRLCacheTestingEnabled())?"1":"0");
+ }
+ }
+
+ }
+
+ header.addStringValue("crlIssuingPoints", crlIssuingPoints);
+ header.addStringValue("crlDescriptions", crlDescriptions);
+ header.addStringValue("crlNumbers", crlNumbers);
+ header.addStringValue("deltaNumbers", deltaNumbers);
+ header.addStringValue("crlSizes", crlSizes);
+ header.addStringValue("deltaSizes", deltaSizes);
+ header.addStringValue("crlSplits", crlSplits.toString());
+ header.addStringValue("crlTesting", crlTesting);
+ header.addBooleanValue("isDeltaCRLEnabled", isDeltaCRLEnabled);
+
+ header.addStringValue("master_host", masterHost);
+ header.addStringValue("master_port", masterPort);
+
+ header.addStringValue("masterCRLIssuingPoint", mCA.PROP_MASTER_CRL);
+ ICRLIssuingPoint ip0 = mCA.getCRLIssuingPoint(mCA.PROP_MASTER_CRL);
+
+ if (ip0 != null) {
+ header.addStringValue("defaultAlgorithm", ip0.getSigningAlgorithm());
+ }
+
+ if (recentChanges.length() > 0)
+ header.addStringValue("recentChanges", recentChanges);
+
+ String validAlgorithms = null;
+ String[] allAlgorithms = mCA.getCASigningAlgorithms();
+
+ if (allAlgorithms == null) {
+ CMS.debug("GetInfo: signing algorithms set to All algorithms");
+ allAlgorithms = AlgorithmId.ALL_SIGNING_ALGORITHMS;
+ }
+
+ for (int i = 0; i < allAlgorithms.length; i++) {
+ if (i > 0) {
+ validAlgorithms += "+" + allAlgorithms[i];
+ } else {
+ validAlgorithms = allAlgorithms[i];
+ }
+ }
+ if (validAlgorithms != null)
+ header.addStringValue("validAlgorithms", validAlgorithms);
+ }
+
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java
new file mode 100644
index 000000000..3f4eb66a9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/HashEnrollServlet.java
@@ -0,0 +1,1241 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.*;
+import java.io.*;
+
+import java.security.InvalidKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+
+
+import netscape.security.x509.*;
+import netscape.security.util.ObjectIdentifier;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.pkix.crmf.CertTemplate;
+import org.mozilla.jss.pkix.crmf.CertReqMsg;
+import org.mozilla.jss.pkix.crmf.CertRequest;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
+import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.asn1.InvalidBERException;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.authentication.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import java.math.*;
+
+
+/**
+ * performs face-to-face enrollment.
+ *
+ * @version $Revision$, $Date$
+ */
+public class HashEnrollServlet extends CMSServlet {
+ public final static String ADMIN_ENROLL_SERVLET_ID = "adminEnroll";
+
+ // enrollment templates.
+ public static final String
+ ENROLL_SUCCESS_TEMPLATE = "/ra/HashEnrollSuccess.template";
+
+ // http params
+ public static final String OLD_CERT_TYPE = "csrCertType";
+ public static final String CERT_TYPE = "certType";
+ // same as in ConfigConstant.java
+ public static final String REQUEST_FORMAT = "reqFormat";
+ public static final String REQUEST_CONTENT = "requestContent";
+ public static final String SUBJECT_KEYGEN_INFO = "subjectKeyGenInfo";
+ public static final String CRMF_REQUEST = "CRMFRequest";
+ public static final String SUBJECT_NAME = "subject";
+ public static final String CRMF_REQID = "crmfReqId";
+ public static final String CHALLENGE_PASSWORD = "challengePhrase";
+
+ private static final String CERT_AUTH_DUAL = "dual";
+ private static final String CERT_AUTH_ENCRYPTION = "encryption";
+ private static final String CERT_AUTH_SINGLE = "single";
+ private static final String CLIENT_ISSUER = "clientIssuer";
+ public static final String TPL_ERROR_FILE = "/ra/GenErrorHashDirEnroll.template";
+
+ private boolean mAuthTokenOverride = true;
+ private String mEnrollSuccessTemplate = null;
+ private ICMSTemplateFiller
+ mEnrollSuccessFiller = new ImportCertsTemplateFiller();
+
+ ICertificateAuthority mCa = null;
+ ICertificateRepository mRepository = null;
+
+ public HashEnrollServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet.
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success template to allow direct import of keygen certs.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ try {
+ mEnrollSuccessTemplate = sc.getInitParameter(
+ CMSServlet.PROP_SUCCESS_TEMPLATE);
+ if (mEnrollSuccessTemplate == null)
+ mEnrollSuccessTemplate = ENROLL_SUCCESS_TEMPLATE;
+ String fillername =
+ sc.getInitParameter(PROP_SUCCESS_TEMPLATE_FILLER);
+
+ if (fillername != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillername);
+
+ if (filler != null)
+ mEnrollSuccessFiller = filler;
+ }
+
+ // cfu
+ mCa = (ICertificateAuthority) CMS.getSubsystem("ca");
+
+ init_testbed_hack(mConfig);
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(), mId));
+ }
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @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();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ String certType = null;
+
+ String reqHost = httpReq.getRemoteHost();
+
+ String host = httpParams.getValueAsString("hostname", null);
+
+ if (host == null || !host.equals(reqHost)) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr;
+
+ Date date = new Date();
+ long currTime = date.getTime();
+ long timeout = mgr.getTimeout(reqHost);
+ long lastlogin = mgr.getLastLogin(reqHost);
+ long diff = currTime - lastlogin;
+
+ boolean enable = mgr.isEnable(reqHost);
+
+ if (!enable) {
+ printError(cmsReq, "0");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+ if (lastlogin == 0)
+ mgr.setLastLogin(reqHost, currTime);
+ else if (diff > timeout) {
+ mgr.disable(reqHost);
+ printError(cmsReq, "2");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ mgr.setLastLogin(reqHost, currTime);
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ certType = httpParams.getValueAsString(OLD_CERT_TYPE, null);
+ if (certType == null) {
+ certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ } else {;
+ }
+
+ processX509(cmsReq);
+ }
+
+ private void printError(CMSRequest cmsReq, String errorCode)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ header.addStringValue("authority", "Registration Manager");
+ header.addStringValue("errorCode", errorCode);
+ String formPath = TPL_ERROR_FILE;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(formPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", formPath, e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ return;
+ }
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM",
+ e.toString()));
+ cmsReq.setError(new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")));
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ }
+
+ protected void processX509(CMSRequest cmsReq)
+ throws EBaseException {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+
+ // create enrollment request in request queue.
+ IRequest req = mRequestQueue.newRequest(IRequest.ENROLLMENT_REQUEST);
+
+ /*
+ * === certAuth based enroll ===
+ * "certAuthEnroll" is on.
+ * "certauthEnrollType can be one of the three:
+ * single - it's for single cert enrollment
+ * dual - it's for dual certs enrollment
+ * encryption - getting the encryption cert only via
+ * authentication of the signing cert
+ * (crmf or keyGenInfo)
+ */
+ boolean certAuthEnroll = false;
+
+ String certAuthEnrollOn =
+ httpParams.getValueAsString("certauthEnroll", null);
+ X509CertInfo new_certInfo = null;
+
+ if ((certAuthEnrollOn != null) && (certAuthEnrollOn.equals("on"))) {
+ certAuthEnroll = true;
+ CMS.debug("HashEnrollServlet: certAuthEnroll is on");
+ }
+
+ String certauthEnrollType = null;
+
+ if (certAuthEnroll == true) {
+ certauthEnrollType =
+ httpParams.getValueAsString("certauthEnrollType", null);
+ if (certauthEnrollType != null) {
+ if (certauthEnrollType.equals("dual")) {
+ CMS.debug("HashEnrollServlet: certauthEnrollType is dual");
+ } else if (certauthEnrollType.equals("encryption")) {
+ CMS.debug("HashEnrollServlet: certauthEnrollType is encryption");
+ } else if (certauthEnrollType.equals("single")) {
+ CMS.debug("HashEnrollServlet: certauthEnrollType is single");
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERTAUTH_ENROLL_TYPE_1", certauthEnrollType));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERTAUTH_ENROLL_TYPE"));
+ }
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTAUTH_ENROLL_TYPE"));
+ }
+ }
+
+ String challengePassword = httpParams.getValueAsString("challengePassword", "");
+
+ cmsReq.setIRequest(req);
+ saveHttpHeaders(httpReq, req);
+ saveHttpParams(httpParams, req);
+ IAuthToken token = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, token,
+ mAuthzResourceName, "import");
+ } catch (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ X509Certificate sslClientCert = null;
+ // cert auth enroll
+ String certBasedOldSubjectDN = null;
+ BigInteger certBasedOldSerialNum = null;
+
+ // check if request was authenticated, if so set authtoken & certInfo.
+ // also if authenticated, take certInfo from authToken.
+ X509CertInfo certInfo = null;
+
+ if (certAuthEnroll == true) {
+ sslClientCert = getSSLClientCertificate(httpReq);
+ if (sslClientCert == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_MISSING_SSL_CLIENT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SSL_CLIENT_CERT"));
+ }
+
+ certBasedOldSubjectDN = (String) sslClientCert.getSubjectDN().toString();
+ certBasedOldSerialNum = (BigInteger) sslClientCert.getSerialNumber();
+ try {
+ certInfo = (X509CertInfo)
+ ((X509CertImpl) sslClientCert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO_ENCRYPT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_CERTINFO"));
+ }
+ } else {
+ certInfo = CMS.getDefaultX509CertInfo();
+ }
+
+ X509CertInfo[] certInfoArray = new X509CertInfo[] {certInfo};
+
+ //AuthToken authToken = access.getAuthToken();
+ IConfigStore configStore = CMS.getConfigStore();
+ String val = configStore.getString("hashDirEnrollment.name");
+ IAuthSubsystem authSS = (IAuthSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ IAuthManager authMgr1 = authSS.get(val);
+ HashAuthentication mgr = (HashAuthentication) authMgr1;
+ String pageID = httpParams.getValueAsString("pageID", null);
+
+ IAuthToken authToken = mgr.getAuthToken(pageID);
+
+ X509CertInfo authCertInfo = null;
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken == null) {
+ printError(cmsReq, "3");
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ } else {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ // don't store agent token in request.
+ // agent currently used for bulk issuance.
+ // if (!authMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ log(ILogger.LL_INFO,
+ "Enrollment request was authenticated by " +
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME));
+ fillCertInfoFromAuthToken(certInfo, authToken);
+ // save authtoken attrs to request directly (for policy use)
+ saveAuthToken(authToken, req);
+ // req.set(IRequest.AUTH_TOKEN, authToken);
+ // }
+ }
+
+ if (certAuthEnroll == true) {
+ // log(ILogger.LL_DEBUG, "just gotten subjectDN and serialNumber from ssl client cert");
+ if (authToken == null) {
+ // authToken is null, can't match to anyone; bail!
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_PROCESS_ENROLL_NO_AUTH"));
+ return;
+ }
+ }
+
+ // fill certInfo from input types: keygen, cmc, pkcs10 or crmf
+ KeyGenInfo keyGenInfo =
+ httpParams.getValueAsKeyGenInfo(SUBJECT_KEYGEN_INFO, null);
+
+ String certType = null;
+
+ //
+ String test = httpParams.getValueAsString("certNickname", null);
+
+ // support Enterprise 3.5.1 server where CERT_TYPE=csrCertType
+ // instead of certType
+ certType = httpParams.getValueAsString(OLD_CERT_TYPE, null);
+ if (certType == null) {
+ certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ } else {
+ // some policies may rely on the fact that
+ // CERT_TYPE is set. So for 3.5.1 or eariler
+ // we need to set CERT_TYPE here.
+ req.setExtData(IRequest.HTTP_PARAMS, CERT_TYPE, certType);
+ }
+
+ String crmf =
+ httpParams.getValueAsString(CRMF_REQUEST, null);
+
+ if (certAuthEnroll == true) {
+
+ fillCertInfoFromAuthToken(certInfo, authToken);
+
+ // for dual certs
+ if (certauthEnrollType.equals(CERT_AUTH_DUAL)) {
+ if (mCa == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NOT_A_CA"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NOT_A_CA"));
+ }
+
+ // first, make sure the client cert is indeed a
+ // signing only cert
+ if ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ false) ||
+ ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ true) &&
+ (CMS.isEncryptionCert((X509CertImpl) sslClientCert) ==
+ true))) {
+ // either it's not a signing cert, or it's a dual cert
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_TYPE"));
+ }
+ X509Key key = null;
+
+ // for signing cert
+ key = (X509Key) sslClientCert.getPublicKey();
+ try {
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+
+ String filter =
+ "(&(x509cert.subject=" + certBasedOldSubjectDN + ")(!(x509cert.serialNumber=" + certBasedOldSerialNum + "))(certStatus=VALID))";
+ ICertRecordList list =
+ (ICertRecordList) mCa.getCertificateRepository().findCertRecordsInList(filter,
+ null, 10);
+ int size = list.getSize();
+ Enumeration en = list.getCertRecords(0, size - 1);
+ boolean gotEncCert = false;
+
+ if (!en.hasMoreElements()) {
+ // pairing encryption cert not found
+ } else {
+ X509CertInfo encCertInfo = CMS.getDefaultX509CertInfo();
+ X509CertInfo[] cInfoArray = new X509CertInfo[] {certInfo,
+ encCertInfo};
+ int i = 1;
+
+ while (en.hasMoreElements()) {
+ ICertRecord record = (ICertRecord) en.nextElement();
+ X509CertImpl cert = record.getCertificate();
+
+ // if not encryption cert only, try next one
+ if ((CMS.isEncryptionCert(cert) == false) ||
+ ((CMS.isEncryptionCert(cert) == true) &&
+ (CMS.isSigningCert(cert) == true))) {
+ continue;
+ }
+
+ key = (X509Key) cert.getPublicKey();
+ try {
+ encCertInfo = (X509CertInfo)
+ cert.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ } catch (CertificateParsingException ex) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTINFO_ENCRYPT_CERT"));
+ throw new ECMSGWException(
+ CMS.getUserMessage(getLocale(httpReq), "CMS_GW_MISSING_CERTINFO"));
+ }
+
+ try {
+ encCertInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAILED_SET_KEY_FROM_CERT_AUTH_ENROLL_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_KEY_FROM_CERT_AUTH_ENROLL_FAILED", e.toString()));
+ }
+ fillCertInfoFromAuthToken(encCertInfo, authToken);
+
+ cInfoArray[i++] = encCertInfo;
+ certInfoArray = cInfoArray;
+ gotEncCert = true;
+ break;
+ }
+ }
+
+ if (gotEncCert == false) {
+ // encryption cert not found, bail
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ENCRYPTION_CERT_NOT_FOUND"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_ENCRYPTION_CERT_NOT_FOUND"));
+ }
+ } else if (certauthEnrollType.equals(CERT_AUTH_ENCRYPTION)) {
+ // first, make sure the client cert is indeed a
+ // signing only cert
+ if ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ false) ||
+ ((CMS.isSigningCert((X509CertImpl) sslClientCert) ==
+ true) &&
+ (CMS.isEncryptionCert((X509CertImpl) sslClientCert) ==
+ true))) {
+ // either it's not a signing cert, or it's a dual cert
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_TYPE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_TYPE"));
+ }
+
+ /*
+ * crmf
+ */
+ if (crmf != null && crmf != "") {
+ certInfoArray = fillCRMF(crmf, authToken, httpParams, req);
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ CMS.debug(
+ "HashEnrollServlet: sslClientCert issuerDN = " + sslClientCert.getIssuerDN().toString());
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq),
+ "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+ } else if (certauthEnrollType.equals(CERT_AUTH_SINGLE)) {
+ // have to be buried here to handle the issuer
+
+ if (crmf != null && crmf != "") {
+ certInfoArray = fillCRMF(crmf, authToken, httpParams, req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq),
+ "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+ req.setExtData(CLIENT_ISSUER,
+ sslClientCert.getIssuerDN().toString());
+ }
+ } else if (crmf != null && crmf != "") {
+ certInfoArray = fillCRMF(crmf, authToken, httpParams, req);
+ } else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_KEYGEN_INFO"));
+ throw new ECMSGWException(CMS.getUserMessage(getLocale(httpReq),
+ "CMS_GW_MISSING_KEYGEN_INFO"));
+ }
+
+ req.setExtData(IRequest.CERT_INFO, certInfoArray);
+
+ if (challengePassword != null && !challengePassword.equals("")) {
+ String pwd = hashPassword(challengePassword);
+
+ req.setExtData(CHALLENGE_PASSWORD, pwd);
+ }
+
+ // send request to request queue.
+ mRequestQueue.processRequest(req);
+ // process result.
+
+ // render OLD_CERT_TYPE's response differently, we
+ // dont want any javascript in HTML, and need to
+ // override the default render.
+ if (httpParams.getValueAsString(OLD_CERT_TYPE, null) != null) {
+ try {
+ renderServerEnrollResult(cmsReq);
+ cmsReq.setStatus(CMSRequest.SUCCESS); // no default render
+ } catch (IOException ex) {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ }
+ return;
+ }
+
+ //for audit log
+ String initiative = null;
+ String agentID = null;
+
+ if (!authMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ } else {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }
+
+ // if service not complete return standard templates.
+ RequestStatus status = req.getRequestStatus();
+
+ if (status != RequestStatus.COMPLETE) {
+ cmsReq.setIRequestStatus(); // set status acc. to IRequest status.
+ // audit log the status
+ try {
+ if (status == RequestStatus.REJECTED) {
+ Vector messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration msgs = messages.elements();
+ StringBuffer wholeMsg = new StringBuffer();
+
+ while (msgs.hasMoreElements()) {
+ wholeMsg.append("\n");
+ wholeMsg.append(msgs.nextElement());
+ }
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT),
+ " violation: " +
+ wholeMsg.toString()},
+ ILogger.L_MULTILINE
+ );
+ } else { // no policy violation, from agent
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ }
+ } else { // other imcomplete status
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING", e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING", e.toString()));
+ }
+ return;
+ }
+ // if service error use standard error templates.
+ Integer result = req.getExtDataInInteger(IRequest.RESULT);
+
+ if (result.equals(IRequest.RES_ERROR)) {
+
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(req.getExtDataInString(IRequest.ERROR));
+ String[] svcErrors =
+ req.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //System.out.println(
+ //"revocation servlet: setting error description "+
+ //err.toString());
+ cmsReq.setErrorDescription(err);
+ // audit log the error
+ try {
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed with error: " +
+ err,
+ certInfo.get(X509CertInfo.SUBJECT), ""}
+ );
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CANT_GET_CERT_SUBJ_AUDITING",
+ e.toString()));
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // service success
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ X509CertImpl[] issuedCerts =
+ req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ // audit log the success.
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ issuedCerts[0].getSubjectDN(),
+ "cert issued serial number: 0x" +
+ issuedCerts[0].getSerialNumber().toString(16)}
+ );
+
+ // return cert as mime type binary if requested.
+ if (checkImportCertToNav(
+ cmsReq.getHttpResp(), httpParams, issuedCerts[0])) {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ return;
+ }
+
+ // use success template.
+ try {
+ cmsReq.setResult(issuedCerts);
+ renderTemplate(cmsReq, mEnrollSuccessTemplate,
+ mEnrollSuccessFiller);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_TEMP_REND_ERR", mEnrollSuccessFiller.toString(), e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_RETURNING_RESULT_ERROR"));
+ }
+ return;
+ }
+
+ /**
+ * fill subject name, validity, extensions from authoken if any,
+ * overriding what was in pkcs10.
+ * fill subject name, extensions from http input if not authenticated.
+ * requests not authenticated will need to be approved by an agent.
+ */
+ protected void fillCertInfoFromAuthToken(
+ X509CertInfo certInfo, IAuthToken authToken)
+ throws EBaseException {
+ // override subject, validity and extensions from auth token
+ // CA determines algorithm, version and issuer.
+ // take key from keygen, cmc, pkcs10 or crmf.
+
+ // subject name.
+ try {
+ String subjectname =
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT);
+
+ if (subjectname != null) {
+ CertificateSubjectName certSubject = (CertificateSubjectName)
+ new CertificateSubjectName(new X500Name(subjectname));
+
+ certInfo.set(X509CertInfo.SUBJECT, certSubject);
+ log(ILogger.LL_INFO,
+ "cert subject set to " + certSubject + " from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_SUBJECT_NAME_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_SUBJECT_NAME_ERROR"));
+ }
+
+ // validity
+ try {
+ CertificateValidity validity = null;
+ Date notBefore =
+ authToken.getInDate(AuthToken.TOKEN_CERT_NOTBEFORE);
+ Date notAfter =
+ authToken.getInDate(AuthToken.TOKEN_CERT_NOTAFTER);
+
+ if (notBefore != null && notAfter != null) {
+ validity = new CertificateValidity(notBefore, notAfter);
+ certInfo.set(X509CertInfo.VALIDITY, validity);
+ log(ILogger.LL_INFO,
+ "cert validity set to " + validity + " from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_VALIDITY_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_VALIDITY_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_VALIDITY_ERROR"));
+ }
+
+ // extensions
+ try {
+ CertificateExtensions extensions =
+ authToken.getInCertExts(X509CertInfo.EXTENSIONS);
+
+ if (extensions != null) {
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ log(ILogger.LL_INFO, "cert extensions set from authtoken");
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_EXTENSIONS_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_EXTENSIONS_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_ERROR_SET_EXTENSIONS_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SET_EXTENSIONS_ERROR"));
+ }
+ }
+
+ protected X509CertInfo[] fillCRMF(
+ String crmf, IAuthToken authToken, IArgBlock httpParams, IRequest req)
+ throws EBaseException {
+ try {
+ byte[] crmfBlob = CMS.AtoB(crmf);
+ ByteArrayInputStream crmfBlobIn =
+ new ByteArrayInputStream(crmfBlob);
+
+ SEQUENCE crmfMsgs = (SEQUENCE)
+ new SEQUENCE.OF_Template(new CertReqMsg.Template()).decode(crmfBlobIn);
+
+ int nummsgs = crmfMsgs.size();
+ X509CertInfo[] certInfoArray = new X509CertInfo[nummsgs];
+
+ for (int i = 0; i < nummsgs; i++) {
+ // decode message.
+ CertReqMsg certReqMsg = (CertReqMsg) crmfMsgs.elementAt(i);
+
+ /*
+ if (certReqMsg.hasPop()) {
+ try {
+ certReqMsg.verify();
+ } catch (ChallengeResponseException ex) {
+ // create and save the challenge
+ // construct the cmmf message together
+ // in a sequence to challenge the requestor
+ } catch (Exception e) {
+ // failed, should only affect one request
+ }
+ }
+ */
+ CertRequest certReq = certReqMsg.getCertReq();
+ INTEGER certReqId = certReq.getCertReqId();
+ int srcId = certReqId.intValue();
+
+ req.setExtData(IRequest.CRMF_REQID, String.valueOf(srcId));
+
+ CertTemplate certTemplate = certReq.getCertTemplate();
+ X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
+
+ // get key
+ SubjectPublicKeyInfo spki = certTemplate.getPublicKey();
+ ByteArrayOutputStream keyout = new ByteArrayOutputStream();
+
+ spki.encode(keyout);
+ byte[] keybytes = keyout.toByteArray();
+ X509Key key = new X509Key();
+
+ key.decode(keybytes);
+ certInfo.set(X509CertInfo.KEY, new CertificateX509Key(key));
+
+ // field suggested notBefore and notAfter in CRMF
+ // Tech Support #383184
+ if (certTemplate.getNotBefore() != null || certTemplate.getNotAfter() != null) {
+ CertificateValidity certValidity = new CertificateValidity(certTemplate.getNotBefore(), certTemplate.getNotAfter());
+
+ certInfo.set(X509CertInfo.VALIDITY, certValidity);
+ }
+
+ if (certTemplate.hasSubject()) {
+ Name subjectdn = certTemplate.getSubject();
+ ByteArrayOutputStream subjectEncStream =
+ new ByteArrayOutputStream();
+
+ subjectdn.encode(subjectEncStream);
+ byte[] subjectEnc = subjectEncStream.toByteArray();
+ X500Name subject = new X500Name(subjectEnc);
+
+ certInfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(subject));
+ } else if (authToken == null ||
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) == null) {
+ // No subject name - error!
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SUBJECT_NAME_FROM_AUTHTOKEN"));
+ }
+
+ // get extensions
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (CertificateException e) {
+ extensions = null;
+ } catch (IOException e) {
+ extensions = null;
+ }
+ if (certTemplate.hasExtensions()) {
+ // put each extension from CRMF into CertInfo.
+ // index by extension name, consistent with
+ // CertificateExtensions.parseExtension() method.
+ if (extensions == null)
+ extensions = new CertificateExtensions();
+ int numexts = certTemplate.numExtensions();
+
+ for (int j = 0; j < numexts; j++) {
+ org.mozilla.jss.pkix.cert.Extension jssext =
+ certTemplate.extensionAt(j);
+ boolean isCritical = jssext.getCritical();
+ org.mozilla.jss.asn1.OBJECT_IDENTIFIER jssoid =
+ jssext.getExtnId();
+ long[] numbers = jssoid.getNumbers();
+ int[] oidNumbers = new int[numbers.length];
+
+ for (int k = numbers.length - 1; k >= 0; k--) {
+ oidNumbers[k] = (int) numbers[k];
+ }
+ ObjectIdentifier oid =
+ new ObjectIdentifier(oidNumbers);
+ org.mozilla.jss.asn1.OCTET_STRING jssvalue =
+ jssext.getExtnValue();
+ ByteArrayOutputStream jssvalueout =
+ new ByteArrayOutputStream();
+
+ jssvalue.encode(jssvalueout);
+ byte[] extValue = jssvalueout.toByteArray();
+
+ Extension ext =
+ new Extension(oid, isCritical, extValue);
+
+ extensions.parseExtension(ext);
+ }
+
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+
+ }
+
+ // Added a new configuration parameter
+ // eeGateway.Enrollment.authTokenOverride=[true|false]
+ // By default, it is set to true. In most
+ // of the case, administrator would want
+ // to have the control of the subject name
+ // formulation.
+ // -- CRMFfillCert
+ if (authToken != null &&
+ authToken.getInString(AuthToken.TOKEN_CERT_SUBJECT) != null) {
+ // if authenticated override subect name, validity and
+ // extensions if any from authtoken.
+ fillCertInfoFromAuthToken(certInfo, authToken);
+ }
+
+ certInfoArray[i] = certInfo;
+ }
+
+ do_testbed_hack(nummsgs, certInfoArray, httpParams);
+
+ return certInfoArray;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (InvalidBERException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_CRMF_TO_CERTINFO_1",
+ e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_CRMF_TO_CERTINFO_ERROR"));
+ }
+ }
+
+ protected void renderServerEnrollResult(CMSRequest cmsReq) throws
+ IOException {
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ httpResp.setContentType("text/html");
+ ServletOutputStream out = null;
+
+ out = httpResp.getOutputStream();
+
+ // get template based on request status
+ out.println("<HTML>");
+ out.println("<TITLE>");
+ out.println("Server Enrollment");
+ out.println("</TITLE>");
+ // out.println("<BODY BGCOLOR=white>");
+
+ if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ out.println("<H1>");
+ out.println("SUCCESS");
+ out.println("</H1>");
+ out.println("Your request is submitted and approved. Please cut and paste the certificate into your server."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("Certificate: ");
+ out.println("<P>");
+ out.println("<PRE>");
+ X509CertImpl certs[] =
+ cmsReq.getIRequest().getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ out.println(CMS.getEncodedCert(certs[0]));
+ out.println("</PRE>");
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ out.println("<!HTTP_OUTPUT X509_CERTIFICATE=" +
+ CMS.getEncodedCert(certs[0]) + ">");
+ } else if (cmsReq.getIRequest().getRequestStatus().equals(RequestStatus.PENDING)) {
+ out.println("<H1>");
+ out.println("PENDING");
+ out.println("</H1>");
+ out.println("Your request is submitted. You can check on the status of your request with an authorized agent or local administrator by referring to the request ID."); // XXX - localize the message
+ out.println("<P>");
+ out.println("Request Creation Time: ");
+ out.println(cmsReq.getIRequest().getCreationTime().toString());
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Request ID: ");
+ out.println(cmsReq.getIRequest().getRequestId().toString());
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_CREATION_TIME=" +
+ cmsReq.getIRequest().getCreationTime().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT REQUEST_ID=" +
+ cmsReq.getIRequest().getRequestId().toString() + ">");
+ } else {
+ out.println("<H1>");
+ out.println("ERROR");
+ out.println("</H1>");
+ out.println("<!INFO>");
+ out.println("Please consult your local administrator for assistance."); // XXX - localize the message
+ out.println("<!/INFO>");
+ out.println("<P>");
+ out.println("Request Status: ");
+ out.println(cmsReq.getStatus().toString());
+ out.println("<P>");
+ out.println("Error: ");
+ out.println(cmsReq.getError()); // XXX - need to parse in Locale
+ out.println("<P>");
+ out.println("<!HTTP_OUTPUT REQUEST_STATUS=" +
+ cmsReq.getStatus().toString() + ">");
+ out.println("<!HTTP_OUTPUT ERROR=" +
+ cmsReq.getError() + ">");
+ }
+
+ /**
+ // include all the input data
+ IArgBlock args = cmsReq.getHttpParams();
+ Enumeration ele = args.getElements();
+ while (ele.hasMoreElements()) {
+ String eleT = (String)ele.nextElement();
+ out.println("<!HTTP_INPUT " + eleT + "=" +
+ args.get(eleT) + ">");
+ }
+ **/
+
+ out.println("</HTML>");
+ }
+
+ // XXX ALERT !!
+ // Remove the following and calls to them when we bundle a cartman
+ // later than alpha1.
+ // These are here to cover up problem in cartman where the
+ // key usage extension always ends up being digital signature only
+ // and for rsa-ex ends up having no bits set.
+
+ private boolean mIsTestBed = false;
+
+ private void init_testbed_hack(IConfigStore config)
+ throws EBaseException {
+ mIsTestBed = config.getBoolean("isTestBed", true);
+ }
+
+ private void do_testbed_hack(
+ int nummsgs, X509CertInfo[] certinfo, IArgBlock httpParams)
+ throws EBaseException {
+ if (!mIsTestBed)
+ return;
+
+ // get around bug in cartman - bits are off by one byte.
+ for (int i = 0; i < certinfo.length; i++) {
+ try {
+ X509CertInfo cert = certinfo[i];
+ CertificateExtensions exts = (CertificateExtensions)
+ cert.get(CertificateExtensions.NAME);
+
+ if (exts == null) {
+ // should not happen.
+ continue;
+ }
+ KeyUsageExtension ext = (KeyUsageExtension)
+ exts.get(KeyUsageExtension.NAME);
+
+ if (ext == null)
+ // should not happen
+ continue;
+ byte[] value = ext.getExtensionValue();
+
+ if (value[0] == 0x03 && value[1] == 0x02 && value[2] == 0x07) {
+ byte[] newvalue = new byte[value.length + 1];
+
+ newvalue[0] = 0x03;
+ newvalue[1] = 0x03;
+ newvalue[2] = 0x07;
+ newvalue[3] = value[3];
+ // force encryption certs to have digitial signature
+ // set too so smime can find the cert for encryption.
+ if (value[3] == 0x20) {
+
+ /*
+ newvalue[3] = 0x3f;
+ newvalue[4] = (byte)0x80;
+ */
+ if (httpParams.getValueAsBoolean(
+ "dual-use-hack", true)) {
+ newvalue[3] = (byte) 0xE0; // same as rsa-dual-use.
+ }
+ }
+ newvalue[4] = 0;
+ KeyUsageExtension newext =
+ new KeyUsageExtension(Boolean.valueOf(true),
+ (Object) newvalue);
+
+ exts.delete(KeyUsageExtension.NAME);
+ exts.set(KeyUsageExtension.NAME, newext);
+ }
+ } catch (IOException e) {
+ // should never happen
+ continue;
+ } catch (CertificateException e) {
+ // should never happen
+ continue;
+ }
+ }
+
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java
new file mode 100644
index 000000000..98da80372
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ImportCertsTemplateFiller.java
@@ -0,0 +1,372 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Locale;
+import java.math.BigInteger;
+import java.io.ByteArrayOutputStream;
+import java.io.StringWriter;
+import java.io.StringReader;
+import java.io.BufferedReader;
+
+
+import javax.servlet.http.HttpServletRequest;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.NoSuchAlgorithmException;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.SignerInfo;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.keydb.*;
+import com.netscape.certsrv.request.IRequest;
+
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.pkix.cmmf.*;
+
+
+/**
+ * Set up HTTP response to import certificate into browsers
+ *
+ * The result must have been populate with the set of certificates
+ * to return.
+ * <pre>
+ * inputs: certtype.
+ * outputs:
+ * - cert type from http input (if any)
+ * - CA chain
+ * - authority name (RM, CM, DRM)
+ * - scheme:host:port of server.
+ * array of one or more
+ * - cert serial number
+ * - cert pretty print
+ * - cert in base 64 encoding.
+ * - cmmf blob to import
+ * </pre>
+ * @version $Revision$, $Date$
+ */
+public class ImportCertsTemplateFiller implements ICMSTemplateFiller {
+ public static final String CRMF_REQID = "crmfReqId";
+ public static final String ISSUED_CERT_SERIAL = "serialNo";
+ public static final String CERT_TYPE = "certType";
+ public static final String BASE64_CERT = "base64Cert";
+ public static final String CERT_PRETTYPRINT = "certPrettyPrint";
+ public static final String CERT_FINGERPRINT = "certFingerprint"; // cisco
+ public static final String CERT_NICKNAME = "certNickname";
+ public static final String CMMF_RESP = "cmmfResponse";
+ public static final String PKCS7_RESP = "pkcs7ChainBase64"; // for MSIE
+
+ public ImportCertsTemplateFiller() {
+ }
+
+ /**
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+ Certificate[] certs = (Certificate[]) cmsReq.getResult();
+
+ if (certs instanceof X509CertImpl[])
+ return getX509TemplateParams(cmsReq, authority, locale, e);
+ else
+ return null;
+ }
+
+ public CMSTemplateParams getX509TemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(header, fixed);
+
+ // set host name and port.
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ String host = httpReq.getServerName();
+ int port = httpReq.getServerPort();
+ String scheme = httpReq.getScheme();
+ String format = httpReq.getParameter("format");
+ if(format!=null && format.equals("cmc"))
+ fixed.set("importCMC", "false");
+ String agentPort = ""+port;
+ fixed.set("agentHost", host);
+ fixed.set("agentPort", agentPort);
+ fixed.set(ICMSTemplateFiller.HOST, host);
+ fixed.set(ICMSTemplateFiller.PORT, Integer.valueOf(port));
+ fixed.set(ICMSTemplateFiller.SCHEME, scheme);
+ IRequest r = cmsReq.getIRequest();
+
+ if (r != null) {
+ fixed.set(ICMSTemplateFiller.REQUEST_ID, r.getRequestId().toString());
+ }
+
+ // set key record (if KRA enabled)
+ if (r != null) {
+ BigInteger keyRecSerialNo = r.getExtDataInBigInteger("keyRecord");
+
+ if (keyRecSerialNo != null) {
+ fixed.set(ICMSTemplateFiller.KEYREC_ID, keyRecSerialNo.toString());
+ }
+ }
+
+ // set cert type.
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ String certType =
+ httpParams.getValueAsString(CERT_TYPE, null);
+
+ if (certType != null)
+ fixed.set(CERT_TYPE, certType);
+
+ // this authority
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ (String) authority.getOfficialName());
+
+ // CA chain.
+ CertificateChain cachain =
+ ((ICertAuthority) authority).getCACertChain();
+ X509Certificate[] cacerts = cachain.getChain();
+
+ String replyTo = httpParams.getValueAsString("replyTo", null);
+
+ if (replyTo != null) fixed.set("replyTo", replyTo);
+
+ // set user + CA cert chain and pkcs7 for MSIE.
+ X509CertImpl[] userChain = new X509CertImpl[cacerts.length + 1];
+ int m = 1, n = 0;
+
+ for (; n < cacerts.length; m++, n++)
+ userChain[m] = (X509CertImpl) cacerts[n];
+
+ // certs.
+ X509CertImpl[] certs = (X509CertImpl[]) cmsReq.getResult();
+
+ // expose CRMF request id
+ String crmfReqId = cmsReq.getExtData(IRequest.CRMF_REQID);
+
+ if (crmfReqId == null) {
+ crmfReqId = (String) cmsReq.getResult(
+ IRequest.CRMF_REQID);
+ }
+ if (crmfReqId != null) {
+ fixed.set(CRMF_REQID, crmfReqId);
+ }
+
+ // set CA certs in cmmf, initialize CertRepContent
+ // note cartman can't trust ca certs yet but it'll import them.
+ // also set cert nickname for cartman.
+ CertRepContent certRepContent = null;
+
+ if (CMSServlet.doCMMFResponse(httpParams)) {
+ byte[][] caPubs = new byte[cacerts.length][];
+
+ for (int j = 0; j < cacerts.length; j++)
+ caPubs[j] = ((X509CertImpl) cacerts[j]).getEncoded();
+ certRepContent = new CertRepContent(caPubs);
+
+ String certnickname =
+ cmsReq.getHttpParams().getValueAsString(CERT_NICKNAME, null);
+
+ // if nickname is not requested set to subject name by default.
+ if (certnickname == null)
+ fixed.set(CERT_NICKNAME, certs[0].getSubjectDN().toString());
+ else
+ fixed.set(CERT_NICKNAME, certnickname);
+ }
+
+ // make pkcs7 for MSIE
+ if (CMSServlet.clientIsMSIE(cmsReq.getHttpReq()) &&
+ (certType == null || certType.equals("client"))) {
+ userChain[0] = certs[0];
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ userChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ byte[] p7Bytes = bos.toByteArray();
+ // String p7Str = encoder.encodeBuffer(p7Bytes);
+ String p7Str = CMS.BtoA(p7Bytes);
+
+ header.set(PKCS7_RESP, p7Str);
+ }
+
+ // set base 64, pretty print and cmmf response for each issued cert.
+ for (int i = 0; i < certs.length; i++) {
+ IArgBlock repeat = CMS.createArgBlock();
+ X509CertImpl cert = certs[i];
+
+ // set serial number.
+ BigInteger serialNo =
+ ((X509Certificate) cert).getSerialNumber();
+
+ repeat.addBigIntegerValue(ISSUED_CERT_SERIAL, serialNo, 16);
+
+ // set base64 encoded blob.
+ byte[] certEncoded = cert.getEncoded();
+ // String b64 = encoder.encodeBuffer(certEncoded);
+ String b64 = CMS.BtoA(certEncoded);
+ String b64cert = "-----BEGIN CERTIFICATE-----\n" +
+ b64 + "\n-----END CERTIFICATE-----";
+
+ repeat.set(BASE64_CERT, b64cert);
+
+ // set cert pretty print.
+
+ String prettyPrintRequested =
+ cmsReq.getHttpParams().getValueAsString(CERT_PRETTYPRINT, null);
+
+ if (prettyPrintRequested == null) {
+ prettyPrintRequested = "true";
+ }
+ String ppStr = "";
+
+ if (!prettyPrintRequested.equals("false")) {
+ ICertPrettyPrint pp = CMS.getCertPrettyPrint(cert);
+
+ ppStr = pp.toString(locale);
+ }
+ repeat.set(CERT_PRETTYPRINT, ppStr);
+
+ // Now formulate a PKCS#7 blob
+ X509CertImpl[] certsInChain = new X509CertImpl[1];;
+ if (cacerts != null) {
+ for (int j = 0; j < cacerts.length; j++) {
+ if (cert.equals(cacerts[j])) {
+ certsInChain = new
+ X509CertImpl[cacerts.length];
+ break;
+ }
+ certsInChain = new X509CertImpl[cacerts.length + 1];
+ }
+ }
+
+ // Set the EE cert
+ certsInChain[0] = cert;
+
+ // Set the Ca certificate chain
+ if (cacerts != null) {
+ for (int j = 0; j < cacerts.length; j++) {
+ if (!cert.equals(cacerts[j]))
+ certsInChain[j + 1] = (X509CertImpl) cacerts[j];
+ }
+ }
+ // Wrap the chain into a degenerate P7 object
+ String p7Str;
+
+ try {
+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ certsInChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos);
+ byte[] p7Bytes = bos.toByteArray();
+
+ //p7Str = encoder.encodeBuffer(p7Bytes);
+ p7Str = CMS.BtoA(p7Bytes);
+ repeat.addStringValue("pkcs7ChainBase64", p7Str);
+ } catch (Exception ex) {
+ //p7Str = "PKCS#7 B64 Encoding error - " + ex.toString()
+ //+ "; Please contact your administrator";
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_FORMING_PKCS7_ERROR"));
+ }
+
+ // set cert fingerprint (for Cisco routers)
+ String fingerprint = null;
+
+ try {
+ fingerprint = CMS.getFingerPrints(cert);
+ } catch (CertificateEncodingException ex) {
+ // should never happen
+ throw new EBaseException(
+ CMS.getUserMessage(locale, "CMS_BASE_INTERNAL_ERROR", ex.toString()));
+ } catch (NoSuchAlgorithmException ex) {
+ // should never happen
+ throw new EBaseException(
+ CMS.getUserMessage(locale, "CMS_BASE_INTERNAL_ERROR", ex.toString()));
+ }
+ if (fingerprint != null && fingerprint.length() > 0)
+ repeat.set(CERT_FINGERPRINT, fingerprint);
+
+ // cmmf response for this cert.
+ if (CMSServlet.doCMMFResponse(httpParams) && crmfReqId != null &&
+ (certType == null || certType.equals("client"))) {
+ PKIStatusInfo status = new PKIStatusInfo(PKIStatusInfo.granted);
+ CertifiedKeyPair certifiedKP =
+ new CertifiedKeyPair(new CertOrEncCert(certEncoded));
+ CertResponse resp =
+ new CertResponse(new INTEGER(crmfReqId), status,
+ certifiedKP);
+
+ certRepContent.addCertResponse(resp);
+ }
+
+ params.addRepeatRecord(repeat);
+ }
+
+ // if cartman set whole cmmf response (CertRepContent) string.
+ if (CMSServlet.doCMMFResponse(httpParams)) {
+ ByteArrayOutputStream certRepOut = new ByteArrayOutputStream();
+
+ certRepContent.encode(certRepOut);
+ byte[] certRepBytes = certRepOut.toByteArray();
+ String certRepB64 = com.netscape.osutil.OSUtil.BtoA(certRepBytes);
+ // add CR to each return as required by cartman
+ BufferedReader certRepB64lines =
+ new BufferedReader(new StringReader(certRepB64));
+ StringWriter certRepStringOut = new StringWriter();
+ String oneLine = null;
+ boolean first = true;
+
+ while ((oneLine = certRepB64lines.readLine()) != null) {
+ if (first) {
+ //certRepStringOut.write("\""+oneLine+"\"");
+ certRepStringOut.write(oneLine);
+ first = false;
+ } else {
+ //certRepStringOut.write("+\"\\n"+oneLine+"\"");
+ certRepStringOut.write("\n" + oneLine);
+ }
+ }
+ String certRepString = certRepStringOut.toString();
+
+ fixed.set(CMMF_RESP, certRepString);
+ }
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java
new file mode 100644
index 000000000..d7160daa6
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ListCerts.java
@@ -0,0 +1,733 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.provider.RSAPublicKey;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Retrieve a paged list of certs matching the specified query
+ *
+ * @version $Revision$, $Date$
+ */
+public class ListCerts extends CMSServlet {
+
+ private final static String TPL_FILE = "queryCert.template";
+ private final static String INFO = "ListCerts";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+
+ private final static String CURRENT_TIME = "currentTime";
+ private final static String USE_CLIENT_FILTER = "useClientFilter";
+ private final static String ALLOWED_CLIENT_FILTERS = "allowedClientFilters";
+
+ private ICertificateRepository mCertDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private boolean mReverse = false;
+ private boolean mHardJumpTo = false; //jump to the end
+ private String mDirection = null;
+ private boolean mUseClientFilter = false;
+ private Vector mAllowedClientFilters = new Vector();
+ private int mMaxReturns = 2000;
+
+ /**
+ * Constructs query key servlet.
+ */
+ public ListCerts() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "queryCert.template" to render the response
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to render own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ mCertDB = ca.getCertificateRepository();
+ mAuthName = ca.getX500Name();
+ }
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ try {
+ mMaxReturns = Integer.parseInt(sc.getInitParameter("maxResults"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+
+ /* useClientFilter should be off by default. We keep
+ this parameter around so that we do not break
+ the client applications that submits raw LDAP
+ filter into this servlet. */
+ if (sc.getInitParameter(USE_CLIENT_FILTER) != null &&
+ sc.getInitParameter(USE_CLIENT_FILTER).equalsIgnoreCase("true")) { mUseClientFilter = true;
+ }
+ if (sc.getInitParameter(ALLOWED_CLIENT_FILTERS) == null || sc.getInitParameter(ALLOWED_CLIENT_FILTERS).equals("")) {
+ mAllowedClientFilters.addElement("(certStatus=*)");
+ mAllowedClientFilters.addElement("(certStatus=VALID)");
+ mAllowedClientFilters.addElement("(|(certStatus=VALID)(certStatus=INVALID)(certStatus=EXPIRED))");
+ mAllowedClientFilters.addElement("(|(certStatus=VALID)(certStatus=REVOKED))");
+ } else {
+ StringTokenizer st = new StringTokenizer(sc.getInitParameter(ALLOWED_CLIENT_FILTERS), ",");
+ while (st.hasMoreTokens()) {
+ mAllowedClientFilters.addElement(st.nextToken());
+ }
+ }
+ }
+
+ public String buildFilter(HttpServletRequest req)
+ {
+ String queryCertFilter = req.getParameter("queryCertFilter");
+
+ com.netscape.certsrv.apps.CMS.debug("client queryCertFilter=" + queryCertFilter);
+
+ if (mUseClientFilter) {
+ com.netscape.certsrv.apps.CMS.debug("useClientFilter=true");
+ Enumeration filters = mAllowedClientFilters.elements();
+ // check to see if the filter is allowed
+ while (filters.hasMoreElements()) {
+ String filter = (String)filters.nextElement();
+ com.netscape.certsrv.apps.CMS.debug("Comparing filter=" + filter + " queryCertFilter=" + queryCertFilter);
+ if (filter.equals(queryCertFilter)) {
+ return queryCertFilter;
+ }
+ }
+ com.netscape.certsrv.apps.CMS.debug("Requested filter '" + queryCertFilter + "' is not allowed. Please check the " + ALLOWED_CLIENT_FILTERS + "parameter");
+ return null;
+ } else {
+ com.netscape.certsrv.apps.CMS.debug("useClientFilter=false");
+ }
+
+ boolean skipRevoked = false;
+ boolean skipNonValid = false;
+ if (req.getParameter("skipRevoked") != null &&
+ req.getParameter("skipRevoked").equals("on")) {
+ skipRevoked = true;
+ }
+ if (req.getParameter("skipNonValid") != null &&
+ req.getParameter("skipNonValid").equals("on")) {
+ skipNonValid = true;
+ }
+
+ if (!skipRevoked && !skipNonValid) {
+ queryCertFilter = "(certStatus=*)";
+ } else if (skipRevoked && skipNonValid) {
+ queryCertFilter = "(certStatus=VALID)";
+ } else if (skipRevoked) {
+ queryCertFilter = "(|(certStatus=VALID)(certStatus=INVALID)(certStatus=EXPIRED))";
+ } else if (skipNonValid) {
+ queryCertFilter = "(|(certStatus=VALID)(certStatus=REVOKED))";
+ }
+ return queryCertFilter;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param maxCount Number of certificates to show
+ * <li>http.param queryFilter and ldap style filter specifying the
+ * certificates to show
+ * <li>http.param querySentinelDown the serial number of the first certificate to show (default decimal, or hex if prefixed with 0x) when paging down
+ * <li>http.param querySentinelUp the serial number of the first certificate to show (default decimal, or hex if prefixed with 0x) when paging up
+ * <li>http.param direction "up", "down", "begin", or "end"
+ * </ul>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } catch (Exception e) {
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String revokeAll = null;
+ EBaseException error = null;
+
+ int maxCount = -1;
+ BigInteger sentinel = new BigInteger("0");
+
+ IArgBlock header = com.netscape.certsrv.apps.CMS.createArgBlock();
+ IArgBlock ctx = com.netscape.certsrv.apps.CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ com.netscape.certsrv.apps.CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ mHardJumpTo = false;
+ try {
+
+ if (req.getParameter("direction") != null) {
+ mDirection = req.getParameter("direction").trim();
+ mReverse = mDirection.equals("up");
+ if (mReverse)
+ com.netscape.certsrv.apps.CMS.debug("reverse is true");
+ else
+ com.netscape.certsrv.apps.CMS.debug("reverse is false");
+
+ }
+
+ if (req.getParameter("maxCount") != null) {
+ maxCount = Integer.parseInt(req.getParameter("maxCount"));
+ }
+ if (maxCount == -1 || maxCount > mMaxReturns) {
+ com.netscape.certsrv.apps.CMS.debug("Resetting page size from " + maxCount + " to " + mMaxReturns);
+ maxCount = mMaxReturns;
+ }
+
+ String sentinelStr = "";
+ if (mReverse) {
+ sentinelStr = req.getParameter("querySentinelUp");
+ } else if (mDirection.equals("end")) {
+ // this servlet will figure out the end
+ sentinelStr = "0";
+ mReverse = true;
+ mHardJumpTo = true;
+ } else if (mDirection.equals("down")) {
+ sentinelStr = req.getParameter("querySentinelDown");
+ } else
+ sentinelStr = "0";
+ //begin and non-specified have sentinel default "0"
+
+ if (sentinelStr != null) {
+ if (sentinelStr.trim().startsWith("0x")) {
+ sentinel = new BigInteger(sentinelStr.trim().substring(2), 16);
+ } else {
+ sentinel = new BigInteger(sentinelStr, 10);
+ }
+ }
+
+ revokeAll = req.getParameter("revokeAll");
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ X509CertImpl caCert = ((ICertificateAuthority) mAuthority).getSigningUnit().getCertImpl();
+
+ //if (isCertFromCA(caCert))
+ header.addStringValue("caSerialNumber",
+ caCert.getSerialNumber().toString(16));
+ }
+
+ // constructs the ldap filter on the server side
+ String queryCertFilter = buildFilter(req);
+
+ if (queryCertFilter == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ com.netscape.certsrv.apps.CMS.debug("queryCertFilter=" + queryCertFilter);
+
+ int totalRecordCount = -1;
+
+ try {
+ totalRecordCount = Integer.parseInt(req.getParameter("totalRecordCount"));
+ } catch (Exception e) {
+ }
+ processCertFilter(argSet, header, maxCount,
+ sentinel,
+ totalRecordCount,
+ req.getParameter("serialTo"),
+ queryCertFilter,
+ req, resp, revokeAll, locale[0]);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, com.netscape.certsrv.apps.CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+
+ error = new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ ctx.addIntegerValue("maxCount", maxCount);
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ com.netscape.certsrv.apps.CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void processCertFilter(CMSTemplateParams argSet,
+ IArgBlock header,
+ int maxCount,
+ BigInteger sentinel,
+ int totalRecordCount,
+ String serialTo,
+ String filter,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String revokeAll,
+ Locale locale
+ ) throws EBaseException {
+ BigInteger serialToVal = MINUS_ONE;
+
+ try {
+ if (serialTo != null) {
+ serialTo = serialTo.trim();
+ if (serialTo.startsWith("0x")) {
+ serialToVal = new BigInteger
+ (serialTo.substring(2), 16);
+ serialTo = serialToVal.toString();
+ } else {
+ serialToVal = new BigInteger(serialTo);
+ }
+ }
+ } catch (Exception e) {
+ }
+
+ String jumpTo = sentinel.toString();
+ int pSize = 0;
+ if (mReverse) {
+ if (!mHardJumpTo) //reverse gets one more
+ pSize = -1*maxCount-1;
+ else
+ pSize = -1*maxCount;
+ } else
+ pSize = maxCount;
+
+ ICertRecordList list = (ICertRecordList) mCertDB.findCertRecordsInList(
+ filter, (String[]) null, jumpTo, mHardJumpTo, "serialno",
+ pSize);
+ // retrive maxCount + 1 entries
+
+ Enumeration e = list.getCertRecords(0, maxCount);
+
+ ICertRecordList tolist = null;
+ int toCurIndex = 0;
+
+ if (!serialToVal.equals(MINUS_ONE)) {
+ // if user specify a range, we need to
+ // calculate the totalRecordCount
+ tolist = (ICertRecordList) mCertDB.findCertRecordsInList(
+ filter,
+ (String[]) null, serialTo,
+ "serialno", maxCount);
+ Enumeration en = tolist.getCertRecords(0, 0);
+
+ if (en == null || (!en.hasMoreElements())) {
+ toCurIndex = list.getSize() - 1;
+ } else {
+ toCurIndex = tolist.getCurrentIndex();
+ ICertRecord rx = (ICertRecord) en.nextElement();
+ BigInteger curToSerial = rx.getSerialNumber();
+
+ if (curToSerial.compareTo(serialToVal) == -1) {
+ toCurIndex = list.getSize() - 1;
+ } else {
+ if (!rx.getSerialNumber().toString().equals(serialTo.trim())) {
+ toCurIndex = toCurIndex - 1;
+ }
+ }
+ }
+ }
+
+ int curIndex = list.getCurrentIndex();
+
+ int count = 0;
+ BigInteger firstSerial = new BigInteger("0");
+ BigInteger curSerial = new BigInteger("0");
+ ICertRecord[] recs = new ICertRecord[maxCount];
+ int rcount = 0;
+
+ if (e != null) {
+ /* in reverse (page up), because the sentinel is the one after the
+ * last item to be displayed, we need to skip it
+ */
+ while ((count < ((mReverse &&!mHardJumpTo)? (maxCount+1):maxCount)) && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null) {
+ com.netscape.certsrv.apps.CMS.debug("record "+count+" is null");
+ break;
+ }
+ curSerial = rec.getSerialNumber();
+ com.netscape.certsrv.apps.CMS.debug("record "+count+" is serial#"+curSerial);
+
+ if (count == 0) {
+ firstSerial = curSerial;
+ if (mReverse && !mHardJumpTo) {//reverse got one more, skip
+ count++;
+ continue;
+ }
+ }
+
+ // DS has a problem where last record will be returned
+ // even though the filter is not matched.
+ /*cfu - is this necessary? it breaks when paging up
+ if (curSerial.compareTo(sentinel) == -1) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial compare sentinel -1 break...");
+
+ break;
+ }
+ */
+ if (!serialToVal.equals(MINUS_ONE)) {
+ // check if we go over the limit
+ if (curSerial.compareTo(serialToVal) == 1) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial compare serialToVal 1 breaking...");
+ break;
+ }
+ }
+
+ if (mReverse) {
+ recs[rcount++] = rec;
+ } else {
+
+ IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
+
+ fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+ count++;
+ }
+ } else {
+ com.netscape.certsrv.apps.CMS.debug(
+ "ListCerts::processCertFilter() - no Cert Records found!" );
+ return;
+ }
+
+ if (mReverse) {
+ // fill records into arg block and argSet
+ for (int ii = rcount-1; ii>= 0; ii--) {
+ if (recs[ii] != null) {
+ IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
+ //com.netscape.certsrv.apps.CMS.debug("item "+ii+" is serial # "+ recs[ii].getSerialNumber());
+ fillRecordIntoArg(recs[ii], rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+ }
+
+ // peek ahead
+ ICertRecord nextRec = null;
+
+ if (e.hasMoreElements()) {
+ nextRec = (ICertRecord) e.nextElement();
+ }
+
+ header.addStringValue("op", req.getParameter("op"));
+ if (revokeAll != null)
+ header.addStringValue("revokeAll", revokeAll);
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+ if (!serialToVal.equals(MINUS_ONE))
+ header.addStringValue("serialTo", serialToVal.toString());
+ header.addStringValue("serviceURL", req.getRequestURI());
+ header.addStringValue("queryCertFilter", filter);
+ header.addStringValue("templateName", "queryCert");
+ header.addStringValue("queryFilter", filter);
+ header.addIntegerValue("maxCount", maxCount);
+ if (totalRecordCount == -1) {
+ if (!serialToVal.equals(MINUS_ONE)) {
+ totalRecordCount = toCurIndex - curIndex + 1;
+ com.netscape.certsrv.apps.CMS.debug("totalRecordCount="+totalRecordCount);
+ } else {
+ totalRecordCount = list.getSize() -
+ list.getCurrentIndex();
+ com.netscape.certsrv.apps.CMS.debug("totalRecordCount="+totalRecordCount);
+ }
+ }
+
+ header.addIntegerValue("totalRecordCount", totalRecordCount);
+ header.addIntegerValue("currentRecordCount", list.getSize() -
+ list.getCurrentIndex());
+
+ String qs = "";
+ if (mReverse)
+ qs = "querySentinelUp";
+ else
+ qs = "querySentinelDown";
+
+ if (mHardJumpTo) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial added to querySentinelUp:"+ curSerial.toString());
+
+ header.addStringValue("querySentinelUp", curSerial.toString());
+ } else {
+ if (nextRec == null) {
+ header.addStringValue(qs, null);
+ com.netscape.certsrv.apps.CMS.debug("nextRec is null");
+ if (mReverse) {
+ com.netscape.certsrv.apps.CMS.debug("curSerial added to querySentinelUp:"+ curSerial.toString());
+
+ header.addStringValue("querySentinelUp", curSerial.toString());
+ }
+ } else {
+ BigInteger nextRecNo = nextRec.getSerialNumber();
+
+ if (serialToVal.equals(MINUS_ONE)) {
+ header.addStringValue(
+ qs, nextRecNo.toString());
+ } else {
+ if (nextRecNo.compareTo(serialToVal) <= 0) {
+ header.addStringValue(
+ qs, nextRecNo.toString());
+ } else {
+ header.addStringValue(qs,
+ null);
+ }
+ }
+ com.netscape.certsrv.apps.CMS.debug("querySentinel "+qs+" = "+nextRecNo.toString());
+ }
+ } // !mHardJumpto
+
+ header.addStringValue(!mReverse? "querySentinelUp":"querySentinelDown",
+ firstSerial.toString());
+
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ int maxCount, int sentinel,
+ String filter, HttpServletRequest req,
+ HttpServletResponse resp,
+ String revokeAll, Locale locale)
+ throws EBaseException {
+ try {
+ if (filter.indexOf(CURRENT_TIME, 0) > -1) {
+ filter = insertCurrentTime(filter);
+ }
+ if (revokeAll != null && revokeAll.indexOf(CURRENT_TIME, 0) > -1) {
+ revokeAll = insertCurrentTime(revokeAll);
+ }
+
+ // xxx the filter includes serial number range???
+ ICertRecordList list =
+ (ICertRecordList) mCertDB.findCertRecordsInList(filter, null, maxCount);
+ // sentinel is the index on the list now, not serial number
+ Enumeration e =
+ list.getCertRecords(sentinel, sentinel + maxCount - 1);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ count++;
+ IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock();
+
+ fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+
+ header.addStringValue("op", req.getParameter("op"));
+ if (revokeAll != null)
+ header.addStringValue("revokeAll", revokeAll);
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+ header.addStringValue("serviceURL", req.getRequestURI());
+ header.addStringValue("templateName", "queryCert");
+ header.addStringValue("queryFilter", filter);
+ header.addIntegerValue("maxCount", maxCount);
+ header.addIntegerValue("totalRecordCount", list.getSize());
+ if ((sentinel + count) < list.getSize())
+ header.addIntegerValue("querySentinelDown", sentinel + count);
+ else
+ header.addStringValue("querySentinelDown", null);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERROR_LISTCERTS", e.toString()));
+ throw e;
+ }
+ return;
+ }
+
+ private String insertCurrentTime(String filter) {
+ Date now = null;
+ StringBuffer newFilter = new StringBuffer();
+ int k = 0;
+ int i = filter.indexOf(CURRENT_TIME, k);
+
+ while (i > -1) {
+ if (now == null) now = new Date();
+ if (newFilter.length() == 0) {
+ newFilter.append(filter.substring(k, i));
+ newFilter.append(now.getTime());
+ } else {
+ newFilter.append(filter.substring(k, i));
+ newFilter.append(now.getTime());
+ }
+ k = i + CURRENT_TIME.length();
+ i = filter.indexOf(CURRENT_TIME, k);
+ }
+ if (k > 0) {
+ newFilter.append(filter.substring(k, filter.length()));
+ }
+ return newFilter.toString();
+ }
+
+ /**
+ * Fills cert record into argument block.
+ */
+ private void fillRecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl xcert = rec.getCertificate();
+
+ if (xcert != null) {
+ fillX509RecordIntoArg(rec, rarg);
+ }
+ }
+
+ private void fillX509RecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl cert = rec.getCertificate();
+
+ rarg.addIntegerValue("version", cert.getVersion());
+ rarg.addStringValue("serialNumber", cert.getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal", cert.getSerialNumber().toString());
+
+ if (cert.getSubjectDN().toString().equals("")) {
+ rarg.addStringValue("subject", " ");
+ } else
+ rarg.addStringValue("subject", cert.getSubjectDN().toString());
+
+ rarg.addStringValue("type", "X.509");
+
+ try {
+ PublicKey pKey = cert.getPublicKey();
+ X509Key key = null;
+
+ if (pKey instanceof CertificateX509Key) {
+ CertificateX509Key certKey = (CertificateX509Key) pKey;
+
+ key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ }
+ if (pKey instanceof X509Key) {
+ key = (X509Key) pKey;
+ }
+ rarg.addStringValue("subjectPublicKeyAlgorithm", key.getAlgorithmId().getOID().toString());
+ if (key.getAlgorithmId().toString().equalsIgnoreCase("RSA")) {
+ RSAPublicKey rsaKey = new RSAPublicKey(key.getEncoded());
+
+ rarg.addIntegerValue("subjectPublicKeyLength", rsaKey.getKeySize());
+ }
+ } catch (Exception e) {
+ rarg.addStringValue("subjectPublicKeyAlgorithm", null);
+ rarg.addIntegerValue("subjectPublicKeyLength", 0);
+ }
+
+ rarg.addLongValue("validNotBefore", cert.getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter", cert.getNotAfter().getTime() / 1000);
+ rarg.addStringValue("signatureAlgorithm", cert.getSigAlgOID());
+ String issuedBy = rec.getIssuedBy();
+
+ if (issuedBy == null) issuedBy = "";
+ rarg.addStringValue("issuedBy", issuedBy); // cert.getIssuerDN().toString()
+ rarg.addLongValue("issuedOn", rec.getCreateTime().getTime() / 1000);
+
+ rarg.addStringValue("revokedBy",
+ ((rec.getRevokedBy() == null) ? "" : rec.getRevokedBy()));
+ if (rec.getRevokedOn() == null) {
+ rarg.addStringValue("revokedOn", null);
+ } else {
+ rarg.addLongValue("revokedOn", rec.getRevokedOn().getTime() / 1000);
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration enum1 = crlExts.getElements();
+ int reason = 0;
+
+ while (enum1.hasMoreElements()) {
+ Extension ext = (Extension) enum1.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ break;
+ }
+ }
+ rarg.addIntegerValue("revocationReason", reason);
+ }
+ }
+ }
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java b/pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java
new file mode 100644
index 000000000..6b4e76496
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/Monitor.java
@@ -0,0 +1,389 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Provide statistical queries of request and certificate records.
+ *
+ * @version $Revision$, $Date$
+ */
+public class Monitor extends CMSServlet {
+
+ private final static String TPL_FILE = "monitor.template";
+ private final static String INFO = "Monitor";
+
+ private ICertificateRepository mCertDB = null;
+ private IRequestQueue mQueue = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+
+ private int mTotalCerts = 0;
+ private int mTotalReqs = 0;
+
+ /**
+ * Constructs query servlet.
+ */
+ public Monitor() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'monitor.template' to render the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to render own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ mCertDB = ca.getCertificateRepository();
+ mAuthName = ca.getX500Name();
+ }
+ mQueue = mAuthority.getRequestQueue();
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param startTime start of time period to query
+ * <li>http.param endTime end of time period to query
+ * <li>http.param interval time between queries
+ * <li>http.param numberOfIntervals number of queries to run
+ * <li>http.param maxResults =number
+ * <li>http.param timeLimit =time
+ * </ul>
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ 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 startTime = null;
+ String endTime = null;
+ String interval = null;
+ String numberOfIntervals = null;
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ 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.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ startTime = req.getParameter("startTime");
+ endTime = req.getParameter("endTime");
+ interval = req.getParameter("interval");
+ numberOfIntervals = req.getParameter("numberOfIntervals");
+
+ process(argSet, header, startTime, endTime, interval, numberOfIntervals, locale[0]);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_PROCESSING_REQ", e.toString()));
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE",
+ e.toString()));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ String startTime, String endTime,
+ String interval, String numberOfIntervals,
+ Locale locale)
+ throws EBaseException {
+ if (interval == null || interval.length() == 0) {
+ header.addStringValue("error", "Invalid interval: " + interval);
+ return;
+ }
+ if (numberOfIntervals == null || numberOfIntervals.length() == 0) {
+ header.addStringValue("error", "Invalid number of intervals: " + numberOfIntervals);
+ return;
+ }
+
+ Date startDate = StringToDate(startTime);
+
+ if (startDate == null) {
+ header.addStringValue("error", "Invalid start time: " + startTime);
+ return;
+ }
+
+ int iInterval = 0;
+
+ try {
+ iInterval = Integer.parseInt(interval);
+ } catch (NumberFormatException nfe) {
+ header.addStringValue("error", "Invalid interval: " + interval);
+ return;
+ }
+
+ int iNumberOfIntervals = 0;
+
+ try {
+ iNumberOfIntervals = Integer.parseInt(numberOfIntervals);
+ } catch (NumberFormatException nfe) {
+ header.addStringValue("error", "Invalid number of intervals: " + numberOfIntervals);
+ return;
+ }
+
+ header.addStringValue("startDate", startDate.toString());
+ header.addStringValue("startTime", startTime);
+ header.addIntegerValue("interval", iInterval);
+ header.addIntegerValue("numberOfIntervals", iNumberOfIntervals);
+
+ mTotalCerts = 0;
+ mTotalReqs = 0;
+
+ Date d1 = startDate;
+
+ for (int i = 0; i < iNumberOfIntervals; i++) {
+ Date d2 = nextDate(d1, iInterval - 1);
+ IArgBlock rarg = CMS.createArgBlock();
+ String e = getIntervalInfo(rarg, d1, d2);
+
+ if (e != null) {
+ header.addStringValue("error", e);
+ return;
+ }
+ argSet.addRepeatRecord(rarg);
+ d1 = nextDate(d2, 1);
+ }
+
+ header.addIntegerValue("totalNumberOfCertificates", mTotalCerts);
+ header.addIntegerValue("totalNumberOfRequests", mTotalReqs);
+
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+
+ return;
+ }
+
+ Date nextDate(Date d, int seconds) {
+ Date date = new Date((d.getTime()) + ((long) (seconds * 1000)));
+
+ return date;
+ }
+
+ String getIntervalInfo(IArgBlock arg, Date startDate, Date endDate) {
+ if (startDate != null && endDate != null) {
+ String startTime = DateToZString(startDate);
+ String endTime = DateToZString(endDate);
+ String filter = null;
+
+ arg.addStringValue("startTime", startTime);
+ arg.addStringValue("endTime", endTime);
+
+ try {
+ if (mCertDB != null) {
+ filter = Filter(ICertRecord.ATTR_CREATE_TIME, startTime, endTime);
+
+ Enumeration e = mCertDB.findCertRecs(filter);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec != null) {
+ count++;
+ }
+ }
+ arg.addIntegerValue("numberOfCertificates", count);
+ mTotalCerts += count;
+ }
+
+ if (mQueue != null) {
+ filter = Filter(IRequestRecord.ATTR_CREATE_TIME, startTime, endTime);
+
+ IRequestList reqList = mQueue.listRequestsByFilter(filter);
+
+ int count = 0;
+
+ while (reqList != null && reqList.hasMoreElements()) {
+ IRequestRecord rec = (IRequestRecord) reqList.nextRequest();
+
+ if (rec != null) {
+ if (count == 0) {
+ arg.addStringValue("firstRequest", rec.getRequestId().toString());
+ }
+ count++;
+ }
+ }
+ arg.addIntegerValue("numberOfRequests", count);
+ mTotalReqs += count;
+ }
+ } catch (Exception ex) {
+ return "Exception: " + ex;
+ }
+
+ return null;
+ } else {
+ return "Missing start or end date";
+ }
+ }
+
+ Date StringToDate(String z) {
+ Date d = null;
+
+ if (z != null && (z.length() == 14 ||
+ z.length() == 15 && (z.charAt(14) == 'Z' || z.charAt(14) == 'z'))) {
+ // 20020516132030Z or 20020516132030
+ try {
+ int year = Integer.parseInt(z.substring(0, 4)) - 1900;
+ int month = Integer.parseInt(z.substring(4, 6)) - 1;
+ int date = Integer.parseInt(z.substring(6, 8));
+ int hour = Integer.parseInt(z.substring(8, 10));
+ int minute = Integer.parseInt(z.substring(10, 12));
+ int second = Integer.parseInt(z.substring(12, 14));
+
+ d = new Date(year, month, date, hour, minute, second);
+ } catch (NumberFormatException nfe) {
+ }
+ } else if (z != null && z.length() > 1 && z.charAt(0) == '-') { // -5
+ try {
+ int i = Integer.parseInt(z);
+
+ d = new Date();
+ d = nextDate(d, i);
+ } catch (NumberFormatException nfe) {
+ }
+ }
+
+ return d;
+ }
+
+ String DateToZString(Date d) {
+ String time = "" + (d.getYear() + 1900);
+ int i = d.getMonth() + 1;
+
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getDate();
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getHours();
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getMinutes();
+ if (i < 10) time += "0";
+ time += i;
+ i = d.getSeconds();
+ if (i < 10) time += "0";
+ time += i + "Z";
+ return time;
+ }
+
+ String Filter(String name, String start, String end) {
+ String filter = "(&(" + name + ">=" + start + ")(" + name + "<=" + end + "))";
+
+ return filter;
+ }
+
+ String uriFilter(String name, String start, String end) {
+ String filter = "(%26(" + name + "%3e%3d" + start + ")(" + name + "%3c%3d" + end + "))";
+
+ return filter;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java b/pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java
new file mode 100644
index 000000000..bb39b3ad8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/ReasonToRevoke.java
@@ -0,0 +1,281 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Specify the RevocationReason when revoking a certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class ReasonToRevoke extends CMSServlet {
+
+ private final static String TPL_FILE = "reasonToRevoke.template";
+ private final static String INFO = "ReasonToRevoke";
+
+ private ICertificateRepository mCertDB = null;
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+ private Random mRandom = null;
+ private Nonces mNonces = null;
+ private int mTimeLimits = 30; /* in seconds */
+
+ public ReasonToRevoke() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'reasonToRevoke.template' to render the response
+ *
+ * @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;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ mCertDB = ((ICertificateAuthority) mAuthority).getCertificateRepository();
+ }
+
+ if (mCA != null && mCA.noncesEnabled()) {
+ mRandom = new Random();
+ mNonces = mCA.getNonces();
+ }
+
+ mTemplates.remove(CMSRequest.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 */
+ }
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ 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(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ String revokeAll = null;
+ int totalRecordCount = 1;
+ EBaseException error = 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.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ try {
+ if (req.getParameter("totalRecordCount") != null) {
+ totalRecordCount =
+ Integer.parseInt(req.getParameter("totalRecordCount"));
+ }
+
+ revokeAll = req.getParameter("revokeAll");
+
+ process(argSet, header, req, resp,
+ revokeAll, totalRecordCount, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_RECORD_COUNT_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req), "CMS_BASE_INVALID_NUMBER_FORMAT"));
+ }
+
+ /*
+ 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) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String revokeAll, int totalRecordCount,
+ Locale locale)
+ throws EBaseException {
+
+ header.addStringValue("revokeAll", revokeAll);
+ header.addIntegerValue("totalRecordCount", totalRecordCount);
+
+ if (mNonces != null) {
+ long n = mRandom.nextLong();
+ long m = mNonces.addNonce(n, getSSLClientCertificate(req));
+ if ((n + m) != 0) {
+ header.addStringValue("nonce", Long.toString(m));
+ }
+ }
+
+ try {
+ if (mCA != null) {
+ X509CertImpl caCert = mCA.getSigningUnit().getCertImpl();
+
+ if (isCertFromCA(caCert)) {
+ header.addStringValue("caSerialNumber",
+ caCert.getSerialNumber().toString(16));
+ }
+ }
+
+ /**
+ ICertRecordList list = mCertDB.findCertRecordsInList(
+ revokeAll, null, totalRecordCount);
+ Enumeration e = list.getCertRecords(0, totalRecordCount - 1);
+ **/
+ Enumeration e = mCertDB.searchCertificates(revokeAll,
+ totalRecordCount, mTimeLimits);
+
+ int count = 0;
+ String errorMsg = null;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec == null)
+ continue;
+ X509CertImpl xcert = rec.getCertificate();
+
+ if (xcert != null)
+ if (!(rec.getStatus().equals(ICertRecord.STATUS_REVOKED))) {
+ count++;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("serialNumber",
+ xcert.getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal",
+ xcert.getSerialNumber().toString());
+ rarg.addStringValue("subject",
+ xcert.getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ xcert.getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ xcert.getNotAfter().getTime() / 1000);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+
+ header.addIntegerValue("verifiedRecordCount", count);
+
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Error " + e);
+ throw e;
+ }
+ return;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java
new file mode 100644
index 000000000..f046ebc9d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RemoteAuthConfig.java
@@ -0,0 +1,607 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.cert.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.logging.*;
+
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Allow agent to turn on/off authentication managers
+ *
+ * @version $Revision$, $Date$
+ */
+public class RemoteAuthConfig extends CMSServlet {
+
+ private final static String INFO = "RemoteAuthConfig";
+ private final static String TPL_FILE = "remoteAuthConfig.template";
+ private final static String ENABLE_REMOTE_CONFIG = "enableRemoteConfiguration";
+ private final static String REMOTELY_SET_INSTANCES = "remotelySetInstances";
+ private final static String MEMBER_OF = "memberOf";
+ private final static String UNIQUE_MEMBER = "uniqueMember";
+
+ private String mFormPath = null;
+ private IAuthSubsystem mAuthSubsystem = null;
+ private IConfigStore mAuthConfig = null;
+ private IConfigStore mFileConfig = null;
+ private Vector mRemotelySetInstances = new Vector();
+ private boolean mEnableRemoteConfiguration = false;
+
+ /**
+ * Constructs RemoteAuthConfig servlet.
+ */
+ public RemoteAuthConfig() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ *
+ * Presence of "auths.enableRemoteConfiguration=true" in CMS.cfg
+ * enables remote configuration for authentication plugins.
+ * List of remotely set instances can be found in CMS.cfg
+ * at "auths.remotelySetInstances=<name1>,<name2>,...,<nameN>"
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mFileConfig = CMS.getConfigStore();
+ mAuthConfig = mFileConfig.getSubStore("auths");
+ try {
+ mEnableRemoteConfiguration = mAuthConfig.getBoolean(ENABLE_REMOTE_CONFIG, false);
+ } catch (EBaseException eb) {
+ // Thanks to design of getBoolean we have to catch but we will never get anything.
+ }
+
+ String remoteList = null;
+
+ try {
+ remoteList = mAuthConfig.getString(REMOTELY_SET_INSTANCES, null);
+ } catch (EBaseException eb) {
+ // Thanks to design of getString we have to catch but we will never get anything.
+ }
+ if (remoteList != null) {
+ StringTokenizer s = new StringTokenizer(remoteList, ",");
+
+ while (s.hasMoreTokens()) {
+ String token = s.nextToken();
+
+ if (token != null && token.trim().length() > 0) {
+ mRemotelySetInstances.add(token.trim());
+ }
+ }
+ }
+
+ mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Serves HTTPS request. The format of this request is as follows:
+ * https://host:ee-port/remoteAuthConfig?
+ * op="add"|"delete"&
+ * instance=<instanceName>&
+ * of=<authPluginName>&
+ * host=<hostName>&
+ * port=<portNumber>&
+ * password=<password>&
+ * [adminDN=<adminDN>]&
+ * [uid=<uid>]&
+ * [baseDN=<baseDN>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ String host = req.getParameter("host");
+ String port = req.getParameter("port");
+
+ String adminDN = req.getParameter("adminDN");
+ String uid = req.getParameter("uid");
+ String baseDN = req.getParameter("baseDN");
+ String password = req.getParameter("password");
+
+ String replyTo = req.getParameter("replyTo");
+
+ if (replyTo != null && replyTo.length() > 0) {
+ ctx.addStringValue("replyTo", replyTo);
+ }
+
+ if (mEnableRemoteConfiguration) {
+ String errMsg = null;
+
+ if (adminDN != null && adminDN.length() > 0) {
+ errMsg = authenticateRemoteAdmin(host, port, adminDN, password);
+ } else {
+ errMsg = authenticateRemoteAdmin(host, port, uid, baseDN, password);
+ }
+ if (errMsg == null || errMsg.length() == 0) {
+ if (mAuthSubsystem != null && mAuthConfig != null) {
+ String op = req.getParameter("op");
+
+ if (op == null || op.length() == 0) {
+ header.addStringValue("error", "Undefined operation");
+ } else {
+ header.addStringValue("op", op);
+
+ if (op.equals("delete")) {
+ String plugin = req.getParameter("of");
+
+ if (isPluginListed(plugin)) {
+ String instance = req.getParameter("instance");
+
+ if (isInstanceListed(instance)) {
+ errMsg = deleteInstance(instance);
+ if (errMsg != null && errMsg.length() > 0) {
+ header.addStringValue("error", errMsg);
+ } else {
+ header.addStringValue("plugin", plugin);
+ header.addStringValue("instance", instance);
+ }
+ } else {
+ header.addStringValue("error", "Unknown instance " +
+ instance + ".");
+ }
+ } else {
+ header.addStringValue("error", "Unknown plugin name: " + plugin);
+ }
+ } else if (op.equals("add")) {
+ String plugin = req.getParameter("of");
+
+ if (isPluginListed(plugin)) {
+ String instance = req.getParameter("instance");
+
+ if (instance == null || instance.length() == 0) {
+ instance = makeInstanceName();
+ }
+ if (isInstanceListed(instance)) {
+ header.addStringValue("error", "Instance name " +
+ instance + " is already in use.");
+ } else {
+ errMsg = addInstance(instance, plugin,
+ host, port, baseDN,
+ req.getParameter("dnPattern"));
+ if (errMsg != null && errMsg.length() > 0) {
+ header.addStringValue("error", errMsg);
+ } else {
+ header.addStringValue("plugin", plugin);
+ header.addStringValue("instance", instance);
+ }
+ }
+ } else {
+ header.addStringValue("error", "Unknown plugin name: " + plugin);
+ }
+ } else {
+ header.addStringValue("error", "Unsupported operation: " + op);
+ }
+ }
+ } else {
+ header.addStringValue("error", "Invalid configuration data.");
+ }
+ } else {
+ header.addStringValue("error", errMsg);
+ }
+ } else {
+ header.addStringValue("error", "Remote configuration is disabled.");
+ }
+ 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", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private String authenticateRemoteAdmin(String host, String port,
+ String adminDN, String password) {
+ if (host == null || host.length() == 0) {
+ return "Missing host name.";
+ }
+ if (port == null || port.length() == 0 || port.trim().length() == 0) {
+ return "Missing port number.";
+ }
+ if (adminDN == null || adminDN.length() == 0) {
+ return "Missing admin DN.";
+ }
+ if (password == null || password.length() == 0) {
+ return "Missing password.";
+ }
+ int p = 0;
+
+ try {
+ p = Integer.parseInt(port.trim());
+ } catch (NumberFormatException e) {
+ return "Invalid port number: " + port + " (" + e.toString() + ")";
+ }
+
+ boolean connected = false;
+ LDAPConnection c = new LDAPConnection();
+
+ try {
+ c.connect(host, p);
+ connected = true;
+ try {
+ c.authenticate(adminDN, password);
+ LDAPEntry entry = c.read(adminDN);
+ LDAPAttribute attr = entry.getAttribute(MEMBER_OF);
+
+ if (attr != null) {
+ Enumeration eVals = attr.getStringValues();
+
+ while (eVals.hasMoreElements()) {
+ String nextValue = (String) eVals.nextElement();
+
+ if (nextValue.indexOf("Administrator") > -1) {
+ LDAPEntry groupEntry = c.read(nextValue);
+
+ if (groupEntry != null) {
+ LDAPAttribute gAttr = groupEntry.getAttribute(UNIQUE_MEMBER);
+
+ if (gAttr != null) {
+ Enumeration eValues = gAttr.getStringValues();
+
+ while (eValues.hasMoreElements()) {
+ String value = (String) eValues.nextElement();
+
+ if (value.equals(entry.getDN())) {
+ c.disconnect();
+ return null;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ c.disconnect();
+ return null;
+ }
+
+ } catch (LDAPException e) {
+
+ /*
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ case LDAPException.INVALID_CREDENTIALS:
+ case LDAPException.INSUFFICIENT_ACCESS_RIGHTS:
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ default:
+ }
+ */
+ c.disconnect();
+ return "LDAP error: " + e.toString();
+ }
+
+ if (connected) {
+ c.disconnect();
+ }
+ } catch (LDAPException e) {
+ return "LDAP error: " + e.toString();
+ }
+
+ return "Access unauthorized";
+ }
+
+ private String authenticateRemoteAdmin(String host, String port,
+ String uid, String baseDN,
+ String password) {
+ if (host == null || host.length() == 0) {
+ return "Missing host name.";
+ }
+ if (port == null || port.length() == 0 || port.trim().length() == 0) {
+ return "Missing port number.";
+ }
+ if (uid == null || uid.length() == 0) {
+ return "Missing UID.";
+ }
+ if (uid.indexOf('*') > -1) {
+ return "Invalid UID: " + uid;
+ }
+ if (password == null || password.length() == 0) {
+ return "Missing password.";
+ }
+ int p = 0;
+
+ try {
+ p = Integer.parseInt(port.trim());
+ } catch (NumberFormatException e) {
+ return "Invalid port number: " + port + " (" + e.toString() + ")";
+ }
+ if (baseDN == null || baseDN.length() == 0) {
+ return "Missing base DN.";
+ }
+
+ boolean connected = false;
+ LDAPConnection c = new LDAPConnection();
+
+ try {
+ c.connect(host, p);
+ connected = true;
+ boolean memberOf = false;
+ LDAPSearchResults results = c.search(baseDN, LDAPv2.SCOPE_SUB,
+ "(uid=" + uid + ")",
+ null, false);
+
+ while (results.hasMoreElements()) {
+ LDAPEntry entry = null;
+
+ try {
+ entry = results.next();
+ c.authenticate(entry.getDN(), password);
+ LDAPAttribute attr = entry.getAttribute(MEMBER_OF);
+
+ if (attr != null) {
+ memberOf = true;
+ Enumeration eVals = attr.getStringValues();
+
+ while (eVals.hasMoreElements()) {
+ String nextValue = (String) eVals.nextElement();
+
+ if (nextValue.indexOf("Administrator") > -1) {
+ LDAPEntry groupEntry = c.read(nextValue);
+
+ if (groupEntry != null) {
+ LDAPAttribute gAttr = groupEntry.getAttribute(UNIQUE_MEMBER);
+
+ if (gAttr != null) {
+ Enumeration eValues = gAttr.getStringValues();
+
+ while (eValues.hasMoreElements()) {
+ String value = (String) eValues.nextElement();
+
+ if (value.equals(entry.getDN())) {
+ c.disconnect();
+ return null;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ } catch (LDAPException e) {
+ switch (e.getLDAPResultCode()) {
+ case LDAPException.NO_SUCH_OBJECT:
+ continue;
+
+ case LDAPException.INVALID_CREDENTIALS:
+ break;
+
+ case LDAPException.INSUFFICIENT_ACCESS_RIGHTS:
+ break;
+
+ case LDAPException.LDAP_PARTIAL_RESULTS:
+ break;
+
+ default:
+ continue;
+ }
+ }
+ }
+ if (connected) {
+ c.disconnect();
+ }
+
+ if (!memberOf) {
+ return null;
+ }
+ } catch (LDAPException e) {
+ return "LDAP error: " + e.toString();
+ }
+
+ return "Access unauthorized";
+ }
+
+ private String addInstance(String instance, String plugin,
+ String host, String port,
+ String baseDN, String dnPattern) {
+ if (host == null || host.length() == 0) {
+ return "Missing host name.";
+ }
+ if (port == null || port.length() == 0) {
+ return "Missing port number.";
+ }
+
+ IConfigStore c0 = mAuthConfig.getSubStore("instance");
+ IConfigStore c1 = c0.makeSubStore(instance);
+
+ c1.putString("dnpattern", dnPattern);
+ c1.putString("ldapByteAttributes", "");
+ c1.putString("ldapStringAttributes", "");
+ c1.putString("pluginName", plugin);
+ if (baseDN != null && baseDN.length() > 0)
+ c1.putString("ldap.basedn", baseDN);
+ c1.putString("ldap.minConns", "");
+ c1.putString("ldap.maxConns", "");
+ c1.putString("ldap.ldapconn.host", host);
+ c1.putString("ldap.ldapconn.port", port);
+ c1.putString("ldap.ldapconn.secureConn", "false");
+ c1.putString("ldap.ldapconn.version", "3");
+
+ mRemotelySetInstances.add(instance);
+
+ IAuthManager authMgrInst = mAuthSubsystem.getAuthManagerPlugin(plugin);
+
+ if (authMgrInst != null) {
+ try {
+ authMgrInst.init(instance, plugin, c1);
+ } catch (EBaseException e) {
+ c0.removeSubStore(instance);
+ mRemotelySetInstances.remove(instance);
+ return e.toString();
+ }
+ mAuthSubsystem.add(instance, authMgrInst);
+ }
+
+ StringBuffer list = new StringBuffer();
+
+ for (int i = 0; i < mRemotelySetInstances.size(); i++) {
+ if (i > 0) list.append(",");
+ list.append((String) mRemotelySetInstances.elementAt(i));
+ }
+
+ mAuthConfig.putString(REMOTELY_SET_INSTANCES, list.toString());
+
+ try {
+ mFileConfig.commit(false);
+ } catch (EBaseException e) {
+ c0.removeSubStore(instance);
+ mRemotelySetInstances.remove(instance);
+ return e.toString();
+ }
+
+ return null;
+ }
+
+ private String deleteInstance(String instance) {
+ IConfigStore c = mAuthConfig.getSubStore("instance");
+
+ c.removeSubStore(instance);
+
+ if (mRemotelySetInstances.remove(instance)) {
+ StringBuffer list = new StringBuffer();
+
+ for (int i = 0; i < mRemotelySetInstances.size(); i++) {
+ if (i > 0) list.append(",");
+ list.append((String) mRemotelySetInstances.elementAt(i));
+ }
+
+ mAuthConfig.putString(REMOTELY_SET_INSTANCES, list.toString());
+ }
+
+ try {
+ mFileConfig.commit(false);
+ } catch (EBaseException e) {
+ return e.toString();
+ }
+ mAuthSubsystem.delete(instance);
+
+ return null;
+ }
+
+ private boolean isPluginListed(String pluginName) {
+ boolean isListed = false;
+
+ if (pluginName != null && pluginName.length() > 0) {
+ Enumeration e = mAuthSubsystem.getAuthManagerPlugins();
+
+ while (e.hasMoreElements()) {
+ AuthMgrPlugin plugin = (AuthMgrPlugin) e.nextElement();
+
+ if (pluginName.equals(plugin.getId())) {
+ isListed = true;
+ break;
+ }
+ }
+ }
+
+ return isListed;
+ }
+
+ private boolean isInstanceListed(String instanceName) {
+ boolean isListed = false;
+
+ if (instanceName != null && instanceName.length() > 0) {
+ Enumeration e = mAuthSubsystem.getAuthManagers();
+
+ while (e.hasMoreElements()) {
+ IAuthManager authManager = (IAuthManager) e.nextElement();
+
+ if (instanceName.equals(authManager.getName())) {
+ isListed = true;
+ break;
+ }
+ }
+ }
+
+ return isListed;
+ }
+
+ private String makeInstanceName() {
+ Date now = new Date();
+ int y = 1900 + now.getYear();
+ String name = "R" + y;
+
+ if (now.getMonth() < 10) name += "0";
+ name += now.getMonth();
+ if (now.getDate() < 10) name += "0";
+ name += now.getDate();
+ if (now.getHours() < 10) name += "0";
+ name += now.getHours();
+ if (now.getMinutes() < 10) name += "0";
+ name += now.getMinutes();
+ if (now.getSeconds() < 10) name += "0";
+ name += now.getSeconds();
+ return name;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java
new file mode 100644
index 000000000..fb0bf75da
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RenewalServlet.java
@@ -0,0 +1,517 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Date;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+
+import netscape.security.x509.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.AuditFormat;
+import netscape.security.extensions.*;
+
+/**
+ * Certificate Renewal
+ *
+ * @version $Revision$, $Date$
+ */
+public class RenewalServlet extends CMSServlet {
+ // renewal templates.
+ public static final String
+ RENEWAL_SUCCESS_TEMPLATE = "RenewalSuccess.template";
+
+ // http params
+ public static final String CERT_TYPE = "certType";
+ public static final String SERIAL_NO = "serialNo";
+ // XXX can't do pkcs10 cause it's got no serial no.
+ // (unless put serial no in pki attributes)
+ // public static final String PKCS10 = "pkcs10";
+ public static final String IMPORT_CERT = "importCert";
+
+ private String mRenewalSuccessTemplate = RENEWAL_SUCCESS_TEMPLATE;
+ private ICMSTemplateFiller
+ mRenewalSuccessFiller = new ImportCertsTemplateFiller();
+
+ public RenewalServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet makes use of the
+ * template file "RenewalSuccess.template" to render the
+ * response
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success template. has same info as enrollment.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ try {
+ mRenewalSuccessTemplate = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mRenewalSuccessTemplate == null)
+ mRenewalSuccessTemplate = RENEWAL_SUCCESS_TEMPLATE;
+ String fillername =
+ sc.getInitParameter(PROP_SUCCESS_TEMPLATE_FILLER);
+
+ if (fillername != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillername);
+
+ if (filler != null)
+ mRenewalSuccessFiller = filler;
+ }
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(),
+ mId));
+ }
+
+ }
+
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ protected void process(CMSRequest cmsReq)
+ throws EBaseException {
+ long startTime = CMS.getCurrentDate().getTime();
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+
+ // renewal requires either:
+ // - coming from ee:
+ // - old cert from ssl client auth
+ // - old certs from auth manager
+ // - coming from agent or trusted RA:
+ // - serial no of cert to be renewed.
+
+ BigInteger old_serial_no = null;
+ X509CertImpl old_cert = null;
+ X509CertImpl renewed_cert = null;
+ Date notBefore = null;
+ Date notAfter = null;
+ boolean doSaveAuthToken = false;
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "renew");
+ } 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 authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null && !mAuthMgr.equals("sslClientCertAuthMgr")) {
+ authMgr =
+ authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+
+ // coming from agent
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ X509Certificate[] cert = new X509Certificate[1];
+
+ old_serial_no = getCertFromAgent(httpParams, cert);
+ old_cert = (X509CertImpl) cert[0];
+
+ // optional validity params from input.
+ int beginYear = httpParams.getValueAsInt("beginYear", -1);
+ int beginMonth = httpParams.getValueAsInt("beginMonth", -1);
+ int beginDate = httpParams.getValueAsInt("beginDate", -1);
+ int endYear = httpParams.getValueAsInt("endYear", -1);
+ int endMonth = httpParams.getValueAsInt("endMonth", -1);
+ int endDate = httpParams.getValueAsInt("endDate", -1);
+
+ if (beginYear != -1 && beginMonth != -1 && beginDate != -1 &&
+ endYear != -1 && endMonth != -1 && endDate != -1) {
+ notBefore = new Date(beginYear, beginMonth, beginDate);
+ notAfter = new Date(endYear, endMonth, endDate);
+ }
+ } // coming from client
+ else {
+ // from auth manager
+ X509CertImpl[] cert = new X509CertImpl[1];
+
+ old_serial_no = getCertFromAuthMgr(authToken, cert);
+ old_cert = cert[0];
+ }
+
+ IRequest req = null;
+
+ try {
+ // get ready to send request to request queue.
+ X509CertInfo new_certInfo = null;
+
+ req = mRequestQueue.newRequest(IRequest.RENEWAL_REQUEST);
+ req.setExtData(IRequest.OLD_SERIALS, new BigInteger[] {old_serial_no});
+ if (old_cert != null) {
+ req.setExtData(IRequest.OLD_CERTS,
+ new X509CertImpl[] { old_cert }
+ );
+ // create new certinfo from old_cert contents.
+ X509CertInfo old_certInfo = (X509CertInfo)
+ ((X509CertImpl) old_cert).get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+
+ new_certInfo = new X509CertInfo(old_certInfo.getEncodedInfo());
+ } else {
+ // if no old cert (came from RA agent) create new cert info
+ // (serializable) to pass through policies. And set the old
+ // serial number to pick up.
+ new_certInfo = new CertInfo();
+ new_certInfo.set(X509CertInfo.SERIAL_NUMBER,
+ new CertificateSerialNumber(old_serial_no));
+ }
+
+ if (notBefore == null || notAfter == null) {
+ notBefore = new Date(0);
+ notAfter = new Date(0);
+ }
+ new_certInfo.set(X509CertInfo.VALIDITY,
+ new CertificateValidity(notBefore, notAfter));
+ req.setExtData(IRequest.CERT_INFO, new X509CertInfo[] { new_certInfo }
+ );
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SETTING_RENEWAL_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SETTING_RENEWAL_VALIDITY_ERROR"));
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERROR_SETTING_RENEWAL_VALIDITY_1", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_SETTING_RENEWAL_VALIDITY_ERROR"));
+ }
+
+ saveHttpHeaders(httpReq, req);
+ saveHttpParams(httpParams, req);
+ if (doSaveAuthToken)
+ saveAuthToken(authToken, req);
+ cmsReq.setIRequest(req);
+
+ // send request to request queue.
+ mRequestQueue.processRequest(req);
+
+ // for audit log
+ String initiative = null;
+ String agentID = null;
+
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ agentID = authToken.getInString("userid");
+ initiative = AuditFormat.FROMAGENT + " agentID: " + agentID;
+ }else {
+ // request is from eegateway, so fromUser.
+ initiative = AuditFormat.FROMUSER;
+ }
+
+ // check resulting status
+ RequestStatus status = req.getRequestStatus();
+
+ if (status != RequestStatus.COMPLETE) {
+ cmsReq.setIRequestStatus();
+ // audit log the status
+ if (status == RequestStatus.REJECTED) {
+ Vector messages = req.getExtDataInStringVector(IRequest.ERRORS);
+
+ if (messages != null) {
+ Enumeration msgs = messages.elements();
+ StringBuffer wholeMsg = new StringBuffer();
+
+ while (msgs.hasMoreElements()) {
+ wholeMsg.append("\n");
+ wholeMsg.append(msgs.nextElement());
+ }
+
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "violation: " +
+ wholeMsg.toString()}
+ // wholeMsg},
+ // ILogger.L_MULTILINE
+ );
+ } else { // no policy violation, from agent
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "" }
+ );
+ }
+ } else { // other imcomplete status
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ status.toString(),
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "" }
+ );
+ }
+ return;
+ }
+
+ // service error
+ Integer result = req.getExtDataInInteger(IRequest.RESULT);
+
+ CMS.debug(
+ "RenewalServlet: Result for request " + req.getRequestId() + " is " + result);
+ if (result.equals(IRequest.RES_ERROR)) {
+ CMS.debug(
+ "RenewalServlet: Result for request " + req.getRequestId() + " is error.");
+
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(req.getExtDataInString(IRequest.ERROR));
+ String[] svcErrors =
+ req.getExtDataInStringArray(IRequest.SVCERRORS);
+
+ if (svcErrors != null && svcErrors.length > 0) {
+ for (int i = 0; i < svcErrors.length; i++) {
+ String err = svcErrors[i];
+
+ if (err != null) {
+ //System.out.println(
+ //"revocation servlet: setting error description "+
+ //err.toString());
+ cmsReq.setErrorDescription(err);
+ mLogger.log(ILogger.EV_AUDIT,
+ ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed with error: " +
+ err,
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "" }
+ );
+
+ }
+ }
+ }
+ return;
+ }
+
+ // success.
+ X509CertImpl[] certs = req.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+
+ renewed_cert = certs[0];
+ respondSuccess(cmsReq, renewed_cert);
+ long endTime = CMS.getCurrentDate().getTime();
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.RENEWALFORMAT,
+ new Object[] {
+ req.getRequestId(),
+ initiative,
+ authMgr,
+ "completed",
+ old_cert.getSubjectDN(),
+ old_cert.getSerialNumber().toString(16),
+ "new serial number: 0x" +
+ renewed_cert.getSerialNumber().toString(16) + " time: " + (endTime - startTime)}
+ );
+
+ return;
+ }
+
+ private void respondSuccess(
+ CMSRequest cmsReq, X509CertImpl renewed_cert)
+ throws EBaseException {
+ cmsReq.setResult(new X509CertImpl[] {renewed_cert}
+ );
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+
+ // check if cert should be imported.
+ // browser must have input type set to nav or cartman since
+ // there's no other way to tell
+
+ IArgBlock httpParams = cmsReq.getHttpParams();
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ String certType = httpParams.getValueAsString(CERT_TYPE, "client");
+ String agent = httpReq.getHeader("user-agent");
+
+ if (checkImportCertToNav(cmsReq.getHttpResp(),
+ httpParams, renewed_cert)) {
+ return;
+ } else {
+ try {
+ renderTemplate(cmsReq,
+ mRenewalSuccessTemplate, mRenewalSuccessFiller);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGE_ERROR_DISPLAY_TEMPLATE_1",
+ mRenewalSuccessTemplate, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+ return;
+ }
+
+ protected BigInteger getRenewedCert(ICertRecord certRec)
+ throws EBaseException {
+ BigInteger renewedCert = null;
+ String serial = null;
+ MetaInfo meta = certRec.getMetaInfo();
+
+ if (meta == null) {
+ log(ILogger.LL_INFO,
+ "no meta info in cert serial 0x" + certRec.getSerialNumber().toString(16));
+ return null;
+ }
+ serial = (String) meta.get(ICertRecord.META_RENEWED_CERT);
+ if (serial == null) {
+ log(ILogger.LL_INFO,
+ "no renewed cert in cert 0x" + certRec.getSerialNumber().toString(16));
+ return null;
+ }
+ renewedCert = new BigInteger(serial);
+ log(ILogger.LL_INFO,
+ "renewed cert serial 0x" + renewedCert.toString(16) + "found for 0x" +
+ certRec.getSerialNumber().toString(16));
+ return renewedCert;
+ }
+
+ /**
+ * get certs to renew from agent.
+ */
+ private BigInteger getCertFromAgent(
+ IArgBlock httpParams, X509Certificate[] certContainer)
+ throws EBaseException {
+ BigInteger serialno = null;
+ X509Certificate cert = null;
+
+ // get serial no
+ serialno = httpParams.getValueAsBigInteger(SERIAL_NO, null);
+ if (serialno == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_RENEW"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SERIALNO_FOR_RENEW"));
+ }
+ // get cert from db if we're cert authority.
+ if (mAuthority instanceof ICertificateAuthority) {
+ cert = getX509Certificate(serialno);
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_RENEW_1", serialno.toString(16)));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_RENEWAL"));
+ }
+ }
+ certContainer[0] = cert;
+ return serialno;
+ }
+
+ /**
+ * get cert to renew from auth manager
+ */
+ private BigInteger getCertFromAuthMgr(
+ IAuthToken authToken, X509Certificate[] certContainer)
+ throws EBaseException {
+ X509CertImpl cert =
+ authToken.getInCert(AuthToken.TOKEN_CERT);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_RENEW_FROM_AUTHMGR"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_RENEW_FROM_AUTHMGR"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE, "certficate from auth manager for " +
+ " renewal is not from this ca.");
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_RENEWAL"));
+ }
+ certContainer[0] = cert;
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ return serialno;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java
new file mode 100644
index 000000000..67a829f9d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationServlet.java
@@ -0,0 +1,386 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Random;
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateEncodingException;
+
+import netscape.security.x509.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authorization.*;
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Perform the first step in revoking a certificate
+ *
+ * @version $Revision$, $Date$
+ */
+public class RevocationServlet extends CMSServlet {
+ private final static String PROP_REVOKEBYDN = "revokeByDN";
+ // revocation templates.
+ private final static String TPL_FILE = "reasonToRevoke.template";
+
+ // http params
+ public static final String SERIAL_NO = "serialNo";
+ // XXX can't do pkcs10 cause it's got no serial no.
+ // (unless put serial no in pki attributes)
+ // public static final String PKCS10 = "pkcs10";
+ public static final String REASON_CODE = "reasonCode";
+
+ private String mFormPath = null;
+ private boolean mRevokeByDN = true;
+
+ private Random mRandom = null;
+ private Nonces mNonces = null;
+
+
+ public RevocationServlet() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses
+ * the template file "reasonToRevoke.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);
+ // override success template. has same info as enrollment.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ mFormPath = "/" + TPL_FILE;
+ try {
+ mFormPath = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (mFormPath == null)
+ mFormPath = "/" + TPL_FILE;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ if (((ICertificateAuthority) mAuthority).noncesEnabled()) {
+ mNonces = ((ICertificateAuthority) mAuthority).getNonces();
+ mRandom = new Random();
+ }
+ }
+
+ // set to false by revokeByDN=false in web.xml
+ mRevokeByDN = false;
+ String tmp = sc.getInitParameter(PROP_REVOKEBYDN);
+
+ if (tmp == null || tmp.trim().equalsIgnoreCase("false"))
+ mRevokeByDN = false;
+ else if (tmp.trim().equalsIgnoreCase("true"))
+ mRevokeByDN = true;
+ } catch (Exception e) {
+ }
+ }
+
+
+ /**
+ * Process the HTTP request. Note that this servlet does not
+ * actually perform the certificate revocation. This is the first
+ * step in the multi-step revocation process. (the next step is
+ * in the ReasonToRevoke servlet.
+ *
+ * @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();
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ // revocation requires either:
+ // - coming from ee:
+ // - old cert from ssl client auth
+ // - old certs from auth manager
+ // - coming from agent or trusted RA:
+ // - serial no of cert to be revoked.
+
+ BigInteger old_serial_no = null;
+ X509CertImpl old_cert = null;
+ String revokeAll = null;
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ try {
+ form = getTemplate(mFormPath, httpReq, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", mFormPath, e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "submit");
+ } 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;
+ }
+
+ // coming from agent
+ if (mAuthMgr != null && mAuthMgr.equals(IAuthSubsystem.CERTUSERDB_AUTHMGR_ID)) {
+ X509Certificate[] cert = new X509Certificate[1];
+
+ old_serial_no = getCertFromAgent(httpParams, cert);
+ old_cert = (X509CertImpl) cert[0];
+ } // coming from client
+ else {
+ // from auth manager
+ X509CertImpl[] cert = new X509CertImpl[1];
+
+ old_serial_no = getCertFromAuthMgr(authToken, cert);
+ old_cert = cert[0];
+ }
+
+ header.addStringValue("serialNumber", old_cert.getSerialNumber().toString(16));
+ header.addStringValue("serialNumberDecimal", old_cert.getSerialNumber().toString());
+ // header.addStringValue("subject", old_cert.getSubjectDN().toString());
+ // header.addLongValue("validNotBefore", old_cert.getNotBefore().getTime()/1000);
+ // header.addLongValue("validNotAfter", old_cert.getNotAfter().getTime()/1000);
+
+ if (mNonces != null) {
+ long n = mRandom.nextLong();
+ long m = mNonces.addNonce(n, (X509Certificate)old_cert);
+ if ((n + m) != 0) {
+ header.addStringValue("nonce", Long.toString(m));
+ }
+ }
+
+ boolean noInfo = false;
+ X509CertImpl[] certsToRevoke = null;
+
+ if (mAuthority instanceof ICertificateAuthority) {
+ certsToRevoke = ((ICertificateAuthority) mAuthority).getCertificateRepository().getX509Certificates(
+ old_cert.getSubjectDN().toString(),
+ ICertificateRepository.ALL_UNREVOKED_CERTS);
+
+ } else if (mAuthority instanceof IRegistrationAuthority) {
+ IRequest req = mRequestQueue.newRequest(IRequest.GETCERTS_REQUEST);
+ String filter = "(&(" + ICertRecord.ATTR_X509CERT + "." +
+ X509CertInfo.SUBJECT + "=" +
+ old_cert.getSubjectDN().toString() + ")(|(" +
+ ICertRecord.ATTR_CERT_STATUS + "=" +
+ ICertRecord.STATUS_VALID + ")(" +
+ ICertRecord.ATTR_CERT_STATUS + "=" +
+ ICertRecord.STATUS_EXPIRED + ")))";
+
+ req.setExtData(IRequest.CERT_FILTER, filter);
+ mRequestQueue.processRequest(req);
+ RequestStatus status = req.getRequestStatus();
+
+ if (status == RequestStatus.COMPLETE) {
+ header.addStringValue("request", req.getRequestId().toString());
+ Enumeration enum1 = req.getExtDataKeys();
+
+ while (enum1.hasMoreElements()) {
+ String name = (String) enum1.nextElement();
+
+ if (name.equals(IRequest.OLD_CERTS)) {
+ X509CertImpl[] certs = req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ certsToRevoke = certs;
+ }
+ }
+ } else {
+ noInfo = true;
+ }
+ }
+
+ boolean authorized = false;
+
+ if (certsToRevoke != null && certsToRevoke.length > 0) {
+ for (int i = 0; i < certsToRevoke.length; i++) {
+ if (old_cert.getSerialNumber().equals(certsToRevoke[i].getSerialNumber())) {
+ authorized = true;
+ break;
+ }
+ }
+ }
+
+ if (!noInfo && (certsToRevoke == null || certsToRevoke.length == 0 ||
+ (!authorized))) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERT_ALREADY_REVOKED_1", old_serial_no.toString(16)));
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_CERT_ALREADY_REVOKED"));
+ }
+
+ if (!mRevokeByDN || noInfo) {
+ certsToRevoke = new X509CertImpl[1];
+ certsToRevoke[0] = old_cert;
+ try {
+ byte[] ba = old_cert.getEncoded();
+ // Do base 64 encoding
+
+ header.addStringValue("b64eCertificate", com.netscape.osutil.OSUtil.BtoA(ba));
+ } catch (CertificateEncodingException e) {
+ }
+ }
+
+ if (certsToRevoke != null && certsToRevoke.length > 0) {
+ header.addIntegerValue("totalRecordCount", certsToRevoke.length);
+ header.addIntegerValue("verifiedRecordCount", certsToRevoke.length);
+
+ for (int i = 0; i < certsToRevoke.length; i++) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("serialNumber",
+ certsToRevoke[i].getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal",
+ certsToRevoke[i].getSerialNumber().toString());
+ rarg.addStringValue("subject",
+ certsToRevoke[i].getSubjectDN().toString());
+ rarg.addLongValue("validNotBefore",
+ certsToRevoke[i].getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter",
+ certsToRevoke[i].getNotAfter().getTime() / 1000);
+ argSet.addRepeatRecord(rarg);
+ }
+ } else {
+ header.addIntegerValue("totalRecordCount", 0);
+ header.addIntegerValue("verifiedRecordCount", 0);
+ }
+
+ // set revocation reason, default to unspecified if not set.
+ int reasonCode = httpParams.getValueAsInt(REASON_CODE, 0);
+
+ header.addIntegerValue("reason", reasonCode);
+
+ try {
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ httpResp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ return;
+ }
+
+ /**
+ * get cert to revoke from agent.
+ */
+ private BigInteger getCertFromAgent(
+ IArgBlock httpParams, X509Certificate[] certContainer)
+ throws EBaseException {
+ BigInteger serialno = null;
+ X509Certificate cert = null;
+
+ // get serial no
+ serialno = httpParams.getValueAsBigInteger(SERIAL_NO, null);
+ if (serialno == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_SERIALNO_FOR_REVOKE"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_SERIALNO_FOR_REVOKE"));
+ }
+
+ // get cert from db if we're cert authority.
+ if (mAuthority instanceof ICertificateAuthority) {
+ cert = getX509Certificate(serialno);
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ }
+ certContainer[0] = cert;
+ return serialno;
+ }
+
+ /**
+ * get cert to revoke from auth manager
+ */
+ private BigInteger getCertFromAuthMgr(
+ IAuthToken authToken, X509Certificate[] certContainer)
+ throws EBaseException {
+ X509CertImpl cert =
+ authToken.getInCert(AuthToken.TOKEN_CERT);
+
+ if (cert == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_MISSING_CERTS_REVOKE_FROM_AUTHMGR"));
+ }
+ if (mAuthority instanceof ICertificateAuthority &&
+ !isCertFromCA(cert)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_INVALID_CERT_FOR_REVOCATION"));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_CERT_FOR_REVOCATION"));
+ }
+ certContainer[0] = cert;
+ BigInteger serialno = ((X509Certificate) cert).getSerialNumber();
+
+ return serialno;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java
new file mode 100644
index 000000000..95622c9bb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/RevocationSuccessTemplateFiller.java
@@ -0,0 +1,101 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.x509.RevokedCertImpl;
+
+import org.mozilla.jss.ssl.SSLSocket;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.cms.servlet.*;
+
+
+/**
+ * Certificates Template filler.
+ * must have list of certificates in result.
+ * looks at inputs: certtype.
+ * outputs:
+ * - cert type from http input (if any)
+ * - CA chain
+ * - authority name (RM, CM, DRM)
+ * - scheme:host:port of server.
+ * array of one or more
+ * - cert serial number
+ * - cert pretty print
+ * - cert in base 64 encoding.
+ * - cmmf blob to import
+ * @version $Revision$, $Date$
+ */
+class RevocationSuccessTemplateFiller implements ICMSTemplateFiller {
+ public final static String SERIAL_NO = "serialNo";
+
+ public RevocationSuccessTemplateFiller() {
+ }
+
+ /**
+ * @param cmsReq CMS Request
+ * @param authority this authority
+ * @param locale locale of template.
+ * @param e unexpected exception e. ignored.
+ */
+ public CMSTemplateParams getTemplateParams(
+ CMSRequest cmsReq, IAuthority authority, Locale locale, Exception e)
+ throws Exception {
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams params = new CMSTemplateParams(null, fixed);
+
+ // set host name and port.
+ HttpServletRequest httpReq = cmsReq.getHttpReq();
+ String host = httpReq.getServerName();
+ int port = httpReq.getServerPort();
+ String scheme = httpReq.getScheme();
+
+ fixed.set(ICMSTemplateFiller.HOST, host);
+ fixed.set(ICMSTemplateFiller.PORT, Integer.valueOf(port));
+ fixed.set(ICMSTemplateFiller.SCHEME, scheme);
+
+ // this authority
+ fixed.set(ICMSTemplateFiller.AUTHORITY,
+ (String) authority.getOfficialName());
+
+ // XXX CA chain.
+
+ RevokedCertImpl[] revoked =
+ (RevokedCertImpl[]) cmsReq.getResult();
+
+ // revoked certs.
+ for (int i = 0; i < revoked.length; i++) {
+ IArgBlock repeat = CMS.createArgBlock();
+
+ repeat.set(SERIAL_NO, revoked[i].getSerialNumber());
+ params.addRepeatRecord(repeat);
+ }
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java b/pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java
new file mode 100644
index 000000000..3f74a2696
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/SrchCerts.java
@@ -0,0 +1,758 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.provider.RSAPublicKey;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.dbs.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Search for certificates matching complex query filter
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchCerts extends CMSServlet {
+
+ private final static String TPL_FILE = "srchCert.template";
+ private final static String INFO = "SrchCerts";
+ private final static BigInteger MINUS_ONE = new BigInteger("-1");
+ private final static String PROP_MAX_SEARCH_RETURNS = "maxSearchReturns";
+
+ private final static String CURRENT_TIME = "currentTime";
+ private final static int MAX_RESULTS = 1000;
+
+ private ICertificateRepository mCertDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private int mMaxReturns = MAX_RESULTS;
+ private int mTimeLimits = 30; /* in seconds */
+ private boolean mUseClientFilter = false;
+
+ /**
+ * Constructs query key servlet.
+ */
+ public SrchCerts() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses srchCert.template
+ * to render the response
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // override success to render own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mAuthority instanceof ISubsystem) {
+ ISubsystem sub = (ISubsystem) mAuthority;
+ IConfigStore authConfig = sub.getConfigStore();
+
+ if (authConfig != null) {
+ try {
+ mMaxReturns = authConfig.getInteger(PROP_MAX_SEARCH_RETURNS, MAX_RESULTS);
+ } catch (EBaseException e) {
+ // do nothing
+ }
+ }
+ }
+ if (mAuthority instanceof ICertificateAuthority) {
+ ICertificateAuthority ca = (ICertificateAuthority) mAuthority;
+
+ mCertDB = ca.getCertificateRepository();
+ mAuthName = ca.getX500Name();
+ }
+
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ /* Server-Side time limit */
+ try {
+ int maxResults = Integer.parseInt(sc.getInitParameter("maxResults"));
+ if (maxResults < mMaxReturns)
+ mMaxReturns = maxResults;
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+ try {
+ mTimeLimits = Integer.parseInt(sc.getInitParameter("timeLimits"));
+ } catch (Exception e) {
+ /* do nothing, just use the default if integer parsing failed */
+ }
+
+ /* useClientFilter should be off by default. We keep
+ this parameter around so that we do not break
+ the client applications that submits raw LDAP
+ filter into this servlet. */
+ if (sc.getInitParameter("useClientFilter") != null &&
+ sc.getInitParameter("useClientFilter").equalsIgnoreCase("true")) {
+ mUseClientFilter = true;
+ }
+ }
+
+ private boolean isOn(HttpServletRequest req, String name)
+ {
+ String inUse = req.getParameter(name);
+ if (inUse == null) {
+ return false;
+ }
+ if (inUse.equals("on")) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isOff(HttpServletRequest req, String name)
+ {
+ String inUse = req.getParameter(name);
+ if (inUse == null) {
+ return false;
+ }
+ if (inUse.equals("off")) {
+ return true;
+ }
+ return false;
+ }
+
+ private void buildCertStatusFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "statusInUse")) {
+ return;
+ }
+ String status = req.getParameter("status");
+ filter.append("(certStatus=");
+ filter.append(status);
+ filter.append(")");
+ }
+
+ private void buildProfileFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "profileInUse")) {
+ return;
+ }
+ String profile = req.getParameter("profile");
+ filter.append("(certMetaInfo=profileId:");
+ filter.append(profile);
+ filter.append(")");
+ }
+
+ private void buildBasicConstraintsFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "basicConstraintsInUse")) {
+ return;
+ }
+ filter.append("(x509cert.BasicConstraints.isCA=on)");
+ }
+
+ private void buildSerialNumberRangeFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "serialNumberRangeInUse")) {
+ return;
+ }
+ boolean changed = false;
+ String serialFrom = req.getParameter("serialFrom");
+ if (serialFrom != null && !serialFrom.equals("")) {
+ filter.append("(certRecordId>=" + serialFrom + ")");
+ changed = true;
+ }
+ String serialTo = req.getParameter("serialTo");
+ if (serialTo != null && !serialTo.equals("")) {
+ filter.append("(certRecordId<=" + serialTo + ")");
+ changed = true;
+ }
+ if (!changed) {
+ filter.append("(certRecordId=*)");
+ }
+ }
+
+ private void buildAVAFilter(HttpServletRequest req, String paramName,
+ String avaName, StringBuffer lf, String match)
+ {
+ String val = req.getParameter(paramName);
+ if (val != null && !val.equals("")) {
+ if (match != null && match.equals("exact")) {
+ lf.append("(|");
+ lf.append("(x509cert.subject=*");
+ lf.append(avaName);
+ lf.append("=");
+ lf.append(escapeValueRfc1779(val, true));
+ lf.append(",*)");
+ lf.append("(x509cert.subject=*");
+ lf.append(avaName);
+ lf.append("=");
+ lf.append(escapeValueRfc1779(val, true));
+ lf.append(")");
+ lf.append(")");
+ } else {
+ lf.append("(x509cert.subject=*");
+ lf.append(avaName);
+ lf.append("=");
+ lf.append("*");
+ lf.append(escapeValueRfc1779(val, true));
+ lf.append("*)");
+ }
+ }
+ }
+
+ private void buildSubjectFilter(HttpServletRequest req, StringBuffer filter)
+ {
+ if (!isOn(req, "subjectInUse")) {
+ return;
+ }
+ StringBuffer lf = new StringBuffer();
+ String match = req.getParameter("match");
+
+ buildAVAFilter(req, "eMail", "E", lf, match);
+ buildAVAFilter(req, "commonName", "CN", lf, match);
+ buildAVAFilter(req, "userID", "UID", lf, match);
+ buildAVAFilter(req, "orgUnit", "OU", lf, match);
+ buildAVAFilter(req, "org", "O", lf, match);
+ buildAVAFilter(req, "locality", "L", lf, match);
+ buildAVAFilter(req, "state", "ST", lf, match);
+ buildAVAFilter(req, "country", "C", lf, match);
+
+ if (lf.length() == 0) {
+ filter.append("(x509cert.subject=*)");
+ return;
+ }
+ if (match.equals("exact")) {
+ filter.append("(&");
+ filter.append(lf);
+ filter.append(")");
+ } else {
+ filter.append("(|");
+ filter.append(lf);
+ filter.append(")");
+ }
+ }
+
+ private void buildRevokedByFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "revokedByInUse")) {
+ return;
+ }
+ String revokedBy = req.getParameter("revokedBy");
+ if (revokedBy == null || revokedBy.equals("")) {
+ filter.append("(certRevokedBy=*)");
+ } else {
+ filter.append("(certRevokedBy=");
+ filter.append(revokedBy);
+ filter.append(")");
+ }
+ }
+
+ private void buildDateFilter(HttpServletRequest req, String prefix,
+ String outStr, long adjustment,
+ StringBuffer filter)
+ {
+ String queryCertFilter = null;
+ long epoch = 0;
+ try {
+ epoch = Long.parseLong(req.getParameter(prefix));
+ } catch (NumberFormatException e) {
+ // exception safely ignored
+ }
+ Calendar from = Calendar.getInstance();
+ from.setTimeInMillis(epoch);
+ CMS.debug("buildDateFilter epoch=" + req.getParameter(prefix));
+ CMS.debug("buildDateFilter from=" + from);
+ filter.append("(");
+ filter.append(outStr);
+ filter.append(Long.toString(from.getTimeInMillis() + adjustment));
+ filter.append(")");
+ }
+
+ private void buildRevokedOnFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "revokedOnInUse")) {
+ return;
+ }
+ buildDateFilter(req, "revokedOnFrom", "certRevokedOn>=", 0, filter);
+ buildDateFilter(req, "revokedOnTo", "certRevokedOn<=", 86399999,
+ filter);
+ }
+
+ private void buildRevocationReasonFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "revocationReasonInUse")) {
+ return;
+ }
+ String reasons = req.getParameter("revocationReason");
+ if (reasons == null) {
+ return;
+ }
+ String queryCertFilter = null;
+ StringTokenizer st = new StringTokenizer(reasons, ",");
+ if (st.hasMoreTokens()) {
+ filter.append("(|");
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if (queryCertFilter == null) {
+ queryCertFilter = "";
+ }
+ filter.append("(x509cert.certRevoInfo=");
+ filter.append(token);
+ filter.append(")");
+ }
+ filter.append(")");
+ }
+ }
+
+ private void buildIssuedByFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "issuedByInUse")) {
+ return;
+ }
+ String issuedBy = req.getParameter("issuedBy");
+ if (issuedBy == null || issuedBy.equals("")) {
+ filter.append("(certIssuedBy=*)");
+ } else {
+ filter.append("(certIssuedBy=");
+ filter.append(issuedBy);
+ filter.append(")");
+ }
+ }
+
+ private void buildIssuedOnFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "issuedOnInUse")) {
+ return;
+ }
+ buildDateFilter(req, "issuedOnFrom", "certCreateTime>=", 0, filter);
+ buildDateFilter(req, "issuedOnTo", "certCreateTime<=", 86399999,
+ filter);
+ }
+
+ private void buildValidNotBeforeFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "validNotBeforeInUse")) {
+ return;
+ }
+ buildDateFilter(req, "validNotBeforeFrom", "x509cert.notBefore>=",
+ 0, filter);
+ buildDateFilter(req, "validNotBeforeTo", "x509cert.notBefore<=",
+ 86399999, filter);
+ }
+
+ private void buildValidNotAfterFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "validNotAfterInUse")) {
+ return;
+ }
+ buildDateFilter(req, "validNotAfterFrom", "x509cert.notAfter>=",
+ 0, filter);
+ buildDateFilter(req, "validNotAfterTo", "x509cert.notAfter<=",
+ 86399999, filter);
+ }
+
+ private void buildValidityLengthFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "validityLengthInUse")) {
+ return;
+ }
+ String op = req.getParameter("validityOp");
+ long count = 0;
+ try {
+ count = Long.parseLong(req.getParameter("count"));
+ } catch (NumberFormatException e) {
+ // safely ignore
+ }
+ long unit = 0;
+ try {
+ unit = Long.parseLong(req.getParameter("unit"));
+ } catch (NumberFormatException e) {
+ // safely ignore
+ }
+ filter.append("(");
+ filter.append("x509cert.duration");
+ filter.append(op);
+ filter.append(count * unit);
+ filter.append(")");
+ }
+
+ private void buildCertTypeFilter(HttpServletRequest req,
+ StringBuffer filter)
+ {
+ if (!isOn(req, "certTypeInUse")) {
+ return;
+ }
+ if (isOn(req, "SSLClient")) {
+ filter.append("(x509cert.nsExtension.SSLClient=on)");
+ } else if (isOff(req, "SSLClient")) {
+ filter.append("(x509cert.nsExtension.SSLClient=off)");
+ }
+ if (isOn(req, "SSLServer")) {
+ filter.append("(x509cert.nsExtension.SSLServer=on)");
+ } else if (isOff(req, "SSLServer")) {
+ filter.append("(x509cert.nsExtension.SSLServer=off)");
+ }
+ if (isOn(req, "SecureEmail")) {
+ filter.append("(x509cert.nsExtension.SecureEmail=on)");
+ } else if (isOff(req, "SecureEmail")) {
+ filter.append("(x509cert.nsExtension.SecureEmail=off)");
+ }
+ if (isOn(req, "SubordinateSSLCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateSSLCA=on)");
+ } else if (isOff(req, "SubordinateSSLCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateSSLCA=off)");
+ }
+ if (isOn(req, "SubordinateEmailCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateEmailCA=on)");
+ } else if (isOff(req, "SubordinateEmailCA")) {
+ filter.append("(x509cert.nsExtension.SubordinateEmailCA=off)");
+ }
+ }
+
+ public String buildFilter(HttpServletRequest req)
+ {
+ String queryCertFilter = req.getParameter("queryCertFilter");
+
+ StringBuffer filter = new StringBuffer();
+ buildSerialNumberRangeFilter(req, filter);
+ buildSubjectFilter(req, filter);
+ buildRevokedByFilter(req, filter);
+ buildRevokedOnFilter(req, filter);
+ buildRevocationReasonFilter(req, filter);
+ buildIssuedByFilter(req, filter);
+ buildIssuedOnFilter(req, filter);
+ buildValidNotBeforeFilter(req, filter);
+ buildValidNotAfterFilter(req, filter);
+ buildValidityLengthFilter(req, filter);
+ buildCertTypeFilter(req, filter);
+ buildCertStatusFilter(req, filter);
+ buildProfileFilter(req, filter);
+ buildBasicConstraintsFilter(req, filter);
+
+ if (mUseClientFilter) {
+ CMS.debug("useClientFilter=true");
+ } else {
+ CMS.debug("useClientFilter=false");
+ CMS.debug("client queryCertFilter = " + queryCertFilter);
+ queryCertFilter = "(&" + filter.toString() + ")";
+ }
+ CMS.debug("queryCertFilter = " + queryCertFilter);
+ return queryCertFilter;
+ }
+
+ /**
+ * Serves HTTP request. This format of this request is as follows:
+ * queryCert?
+ * [maxCount=<number>]
+ * [queryFilter=<filter>]
+ * [revokeAll=<filter>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "list");
+ } 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 revokeAll = null;
+ EBaseException error = null;
+ int maxResults = -1;
+ int timeLimit = -1;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+
+ try {
+ form = getTemplate(mFormPath, req, locale);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_GET_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ revokeAll = req.getParameter("revokeAll");
+
+ String maxResultsStr = req.getParameter("maxResults");
+
+ if (maxResultsStr != null && maxResultsStr.length() > 0)
+ maxResults = Integer.parseInt(maxResultsStr);
+ String timeLimitStr = req.getParameter("timeLimit");
+
+ if (timeLimitStr != null && timeLimitStr.length() > 0)
+ timeLimit = Integer.parseInt(timeLimitStr);
+
+ String queryCertFilter = buildFilter(req);
+ process(argSet, header, queryCertFilter,
+ revokeAll, maxResults, timeLimit, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT"));
+ error = new EBaseException(CMS.getUserMessage(getLocale(req),"CMS_BASE_INVALID_NUMBER_FORMAT"));
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ String filter, String revokeAll,
+ int maxResults, int timeLimit,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ try {
+ long startTime = CMS.getCurrentDate().getTime();
+
+ if (filter.indexOf(CURRENT_TIME, 0) > -1) {
+ filter = insertCurrentTime(filter);
+ }
+
+ // xxx the filter includes serial number range???
+ if (maxResults == -1 || maxResults > mMaxReturns) {
+ CMS.debug("Resetting maximum of returned results from " + maxResults + " to " + mMaxReturns);
+ maxResults = mMaxReturns;
+ }
+ if (timeLimit == -1 || timeLimit > mTimeLimits) {
+ CMS.debug("Resetting timelimit from " + timeLimit + " to " + mTimeLimits);
+ timeLimit = mTimeLimits;
+ }
+ CMS.debug("Start searching ... " + "filter=" + filter + " maxreturns=" + maxResults + " timelimit=" + timeLimit);
+ Enumeration e = mCertDB.searchCertificates(filter, maxResults, timeLimit);
+
+ int count = 0;
+
+ while (e != null && e.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) e.nextElement();
+
+ if (rec != null) {
+ count++;
+ IArgBlock rarg = CMS.createArgBlock();
+
+ fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ }
+ }
+
+ long endTime = CMS.getCurrentDate().getTime();
+
+ header.addStringValue("op", req.getParameter("op"));
+ if (mAuthName != null)
+ header.addStringValue("issuerName", mAuthName.toString());
+ header.addStringValue("time", Long.toString(endTime - startTime));
+ header.addStringValue("serviceURL", req.getRequestURI());
+ header.addStringValue("queryFilter", filter);
+ if (revokeAll != null)
+ header.addStringValue("revokeAll", revokeAll);
+ header.addIntegerValue("totalRecordCount", count);
+ header.addIntegerValue("maxSize", maxResults);
+ } catch (EBaseException e) {
+ CMS.getLogMessage("CMSGW_ERROR_LISTCERTS", e.toString());
+ throw e;
+ }
+ return;
+ }
+
+ private String insertCurrentTime(String filter) {
+ Date now = null;
+ StringBuffer newFilter = new StringBuffer();
+ int k = 0;
+ int i = filter.indexOf(CURRENT_TIME, k);
+
+ while (i > -1) {
+ if (now == null) now = new Date();
+ newFilter.append(filter.substring(k, i));
+ newFilter.append(now.getTime());
+ k = i + CURRENT_TIME.length();
+ i = filter.indexOf(CURRENT_TIME, k);
+ }
+ if (k > 0) {
+ newFilter.append(filter.substring(k, filter.length()));
+ }
+ return newFilter.toString();
+ }
+
+ /**
+ * Fills cert record into argument block.
+ */
+ private void fillRecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl xcert = rec.getCertificate();
+
+ if (xcert != null) {
+ fillX509RecordIntoArg(rec, rarg);
+ }
+ }
+
+ private void fillX509RecordIntoArg(ICertRecord rec, IArgBlock rarg)
+ throws EBaseException {
+
+ X509CertImpl cert = rec.getCertificate();
+
+ rarg.addIntegerValue("version", cert.getVersion());
+ rarg.addStringValue("serialNumber", cert.getSerialNumber().toString(16));
+ rarg.addStringValue("serialNumberDecimal", cert.getSerialNumber().toString());
+
+ String subject = (String) cert.getSubjectDN().toString();
+
+ if (subject.equals("")) {
+ rarg.addStringValue("subject", " ");
+ } else {
+ rarg.addStringValue("subject", subject);
+
+ }
+
+ rarg.addStringValue("type", "X.509");
+
+ try {
+ PublicKey pKey = cert.getPublicKey();
+ X509Key key = null;
+
+ if (pKey instanceof CertificateX509Key) {
+ CertificateX509Key certKey = (CertificateX509Key) pKey;
+
+ key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ }
+ if (pKey instanceof X509Key) {
+ key = (X509Key) pKey;
+ }
+ rarg.addStringValue("subjectPublicKeyAlgorithm", key.getAlgorithmId().getOID().toString());
+ if (key.getAlgorithmId().toString().equalsIgnoreCase("RSA")) {
+ RSAPublicKey rsaKey = new RSAPublicKey(key.getEncoded());
+
+ rarg.addIntegerValue("subjectPublicKeyLength", rsaKey.getKeySize());
+ }
+ } catch (Exception e) {
+ rarg.addStringValue("subjectPublicKeyAlgorithm", null);
+ rarg.addIntegerValue("subjectPublicKeyLength", 0);
+ }
+
+ rarg.addLongValue("validNotBefore", cert.getNotBefore().getTime() / 1000);
+ rarg.addLongValue("validNotAfter", cert.getNotAfter().getTime() / 1000);
+ rarg.addStringValue("signatureAlgorithm", cert.getSigAlgOID());
+ String issuedBy = rec.getIssuedBy();
+
+ if (issuedBy == null) issuedBy = "";
+ rarg.addStringValue("issuedBy", issuedBy); // cert.getIssuerDN().toString()
+ rarg.addLongValue("issuedOn", rec.getCreateTime().getTime() / 1000);
+
+ rarg.addStringValue("revokedBy",
+ ((rec.getRevokedBy() == null) ? "" : rec.getRevokedBy()));
+ if (rec.getRevokedOn() == null) {
+ rarg.addStringValue("revokedOn", null);
+ } else {
+ rarg.addLongValue("revokedOn", rec.getRevokedOn().getTime() / 1000);
+
+ IRevocationInfo revocationInfo = rec.getRevocationInfo();
+
+ if (revocationInfo != null) {
+ CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions();
+
+ if (crlExts != null) {
+ Enumeration enum1 = crlExts.getElements();
+ int reason = 0;
+
+ while (enum1.hasMoreElements()) {
+ Extension ext = (Extension) enum1.nextElement();
+
+ if (ext instanceof CRLReasonExtension) {
+ reason = ((CRLReasonExtension) ext).getReason().toInt();
+ break;
+ }
+ }
+ rarg.addIntegerValue("revocationReason", reason);
+ }
+ }
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java
new file mode 100644
index 000000000..52b66874f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateCRL.java
@@ -0,0 +1,512 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.util.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Force the CRL to be updated now.
+ *
+ * @version $Revision$, $Date$
+ */
+public class UpdateCRL extends CMSServlet {
+
+ private final static String INFO = "UpdateCRL";
+ private final static String TPL_FILE = "updateCRL.template";
+
+ private static Vector mTesting = new Vector();
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+
+ /**
+ * Constructs UpdateCRL servlet.
+ */
+ public UpdateCRL() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet. This servlet uses updateCRL.template
+ * to render the result
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mAuthority instanceof ICertificateAuthority)
+ mCA = (ICertificateAuthority) mAuthority;
+
+ // override success to do output orw own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param signatureAlgorithm the algorithm to use to sign the CRL
+ * <li>http.param waitForUpdate true/false - should the servlet wait until
+ * the CRL update is complete?
+ * <li>http.param clearCRLCache true/false - should the CRL cache cleared
+ * before the CRL is generated?
+ * <li>http.param crlIssuingPoint the CRL Issuing Point to Update
+ * </ul>
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IStatsSubsystem statsSub = (IStatsSubsystem)CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming("crl", true /* main action */);
+ }
+
+ long startTime = CMS.getCurrentDate().getTime();
+ IAuthToken authToken = authenticate(cmsReq);
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "update");
+ } 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);
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ return;
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ 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()));
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ String signatureAlgorithm =
+ req.getParameter("signatureAlgorithm");
+
+ process(argSet, header, req, resp,
+ signatureAlgorithm, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE",
+ e.toString()));
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ if (statsSub != null) {
+ statsSub.endTiming("crl");
+ }
+ }
+
+ private CRLExtensions crlEntryExtensions (String reason, String invalidity) {
+ CRLExtensions entryExts = new CRLExtensions();
+
+ CRLReasonExtension crlReasonExtn = null;
+ if (reason != null && reason.length() > 0) {
+ try {
+ RevocationReason revReason = RevocationReason.fromInt(Integer.parseInt(reason));
+ if (revReason == null) revReason = RevocationReason.UNSPECIFIED;
+ crlReasonExtn = new CRLReasonExtension(revReason);
+ } catch (Exception e) {
+ CMS.debug("Invalid revocation reason: "+reason);
+ }
+ }
+
+ InvalidityDateExtension invalidityDateExtn = null;
+ if (invalidity != null && invalidity.length() > 0) {
+ long now = System.currentTimeMillis();
+ Date invalidityDate = null;
+ try {
+ long backInTime = Long.parseLong(invalidity);
+ invalidityDate = new Date(now-(backInTime*60000));
+ } catch (Exception e) {
+ CMS.debug("Invalid invalidity time offset: "+invalidity);
+ }
+ if (invalidityDate != null) {
+ try {
+ invalidityDateExtn = new InvalidityDateExtension(invalidityDate);
+ } catch (Exception e) {
+ CMS.debug("Error creating invalidity extension: "+e);
+ }
+ }
+ }
+
+ if (crlReasonExtn != null) {
+ try {
+ entryExts.set(crlReasonExtn.getName(), crlReasonExtn);
+ } catch (Exception e) {
+ CMS.debug("Error adding revocation reason extension to entry extensions: "+e);
+ }
+ }
+
+ if (invalidityDateExtn != null) {
+ try {
+ entryExts.set(invalidityDateExtn.getName(), invalidityDateExtn);
+ } catch (Exception e) {
+ CMS.debug("Error adding invalidity date extension to entry extensions: "+e);
+ }
+ }
+
+ return entryExts;
+ }
+
+ private void addInfo(CMSTemplateParams argSet, ICRLIssuingPoint crlIssuingPoint, long cacheUpdate) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addLongValue("cacheUpdate", cacheUpdate);
+
+ String crlNumbers = crlIssuingPoint.getCRLNumber().toString();
+ BigInteger deltaNumber = crlIssuingPoint.getDeltaCRLNumber();
+ String crlSizes = "" + crlIssuingPoint.getCRLSize();
+ if (deltaNumber != null && deltaNumber.compareTo(BigInteger.ZERO) > 0) {
+ if (crlNumbers != null)
+ crlNumbers += ",";
+ if (crlNumbers != null)
+ crlNumbers += deltaNumber.toString();
+ if (crlSizes != null)
+ crlSizes += "," + crlIssuingPoint.getDeltaCRLSize();
+ }
+ rarg.addStringValue("crlNumbers", crlNumbers);
+ rarg.addStringValue("crlSizes", crlSizes);
+
+ StringBuffer crlSplits = new StringBuffer();
+ Vector splits = crlIssuingPoint.getSplitTimes();
+ for (int i = 0; i < splits.size(); i++) {
+ crlSplits.append(splits.elementAt(i));
+ if (i + 1 < splits.size())
+ crlSplits.append(",");
+ }
+ rarg.addStringValue("crlSplits", crlSplits.toString());
+
+ argSet.addRepeatRecord(rarg);
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String signatureAlgorithm,
+ Locale locale)
+ throws EBaseException {
+ long startTime = CMS.getCurrentDate().getTime();
+ String waitForUpdate =
+ req.getParameter("waitForUpdate");
+ String clearCache =
+ req.getParameter("clearCRLCache");
+ String crlIssuingPointId =
+ req.getParameter("crlIssuingPoint");
+ String test = req.getParameter("test");
+ String add = req.getParameter("add");
+ String from = req.getParameter("from");
+ String by = req.getParameter("by");
+ String reason = req.getParameter("reason");
+ String invalidity = req.getParameter("invalidity");
+ String results = req.getParameter("results");
+
+ if (crlIssuingPointId != null) {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (crlIssuingPointId.equals(ip.getId())) {
+ break;
+ }
+ if (!ips.hasMoreElements()) crlIssuingPointId = null;
+ }
+ }
+ if (crlIssuingPointId == null) {
+ crlIssuingPointId = mCA.PROP_MASTER_CRL;
+ }
+
+ ICRLIssuingPoint crlIssuingPoint =
+ mCA.getCRLIssuingPoint(crlIssuingPointId);
+ header.addStringValue("crlIssuingPoint", crlIssuingPointId);
+ IPublisherProcessor lpm = mCA.getPublisherProcessor();
+
+ if (crlIssuingPoint != null) {
+ if (clearCache != null && clearCache.equals("true") &&
+ crlIssuingPoint.isCRLGenerationEnabled() &&
+ crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
+ crlIssuingPoint.isCRLIssuingPointInitialized()
+ == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+ crlIssuingPoint.clearCRLCache();
+ }
+ if (waitForUpdate != null && waitForUpdate.equals("true") &&
+ crlIssuingPoint.isCRLGenerationEnabled() &&
+ crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
+ crlIssuingPoint.isCRLIssuingPointInitialized()
+ == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+ if (test != null && test.equals("true") &&
+ crlIssuingPoint.isCRLCacheTestingEnabled() &&
+ (!mTesting.contains(crlIssuingPointId))) {
+ CMS.debug("CRL test started.");
+ mTesting.add(crlIssuingPointId);
+ BigInteger addLen = null;
+ BigInteger startFrom = null;
+ if (add != null && add.length() > 0 &&
+ from != null && from.length() > 0) {
+ try {
+ addLen = new BigInteger(add);
+ startFrom = new BigInteger(from);
+ } catch (Exception e) {
+ }
+ }
+ if (addLen != null && startFrom != null) {
+ Date revocationDate = CMS.getCurrentDate();
+ String err = null;
+
+ CRLExtensions entryExts = crlEntryExtensions (reason, invalidity);
+
+ BigInteger serialNumber = startFrom;
+ BigInteger counter = addLen;
+ BigInteger stepBy = null;
+ if (by != null && by.length() > 0) {
+ try {
+ stepBy = new BigInteger(by);
+ } catch (Exception e) {
+ }
+ }
+
+ long t1 = System.currentTimeMillis();
+ long t2 = 0;
+
+ while (counter.compareTo(BigInteger.ZERO) > 0) {
+ RevokedCertImpl revokedCert =
+ new RevokedCertImpl(serialNumber, revocationDate, entryExts);
+ crlIssuingPoint.addRevokedCert(serialNumber, revokedCert);
+ serialNumber = serialNumber.add(BigInteger.ONE);
+ counter = counter.subtract(BigInteger.ONE);
+
+ if ((counter.compareTo(BigInteger.ZERO) == 0) ||
+ (stepBy != null && ((counter.mod(stepBy)).compareTo(BigInteger.ZERO) == 0))) {
+ t2 = System.currentTimeMillis();
+ long t0 = t2 - t1;
+ t1 = t2;
+ try {
+ if (signatureAlgorithm != null) {
+ crlIssuingPoint.updateCRLNow(signatureAlgorithm);
+ } else {
+ crlIssuingPoint.updateCRLNow();
+ }
+ } catch (Throwable e) {
+ counter = BigInteger.ZERO;
+ err = e.toString();
+ }
+ if (results != null && results.equals("1")) {
+ addInfo(argSet, crlIssuingPoint, t0);
+ }
+ }
+ }
+ if (err != null) {
+ header.addStringValue("crlUpdate", "Failure");
+ header.addStringValue("error", err);
+ } else {
+ header.addStringValue("crlUpdate", "Success");
+ }
+ } else {
+ CMS.debug("CRL test error: missing parameters.");
+ header.addStringValue("crlUpdate", "missingParameters");
+ }
+
+ mTesting.remove(crlIssuingPointId);
+ CMS.debug("CRL test finished.");
+ } else if (test != null && test.equals("true") &&
+ crlIssuingPoint.isCRLCacheTestingEnabled() &&
+ mTesting.contains(crlIssuingPointId)) {
+ header.addStringValue("crlUpdate", "testingInProgress");
+ } else if (test != null && test.equals("true") &&
+ (!crlIssuingPoint.isCRLCacheTestingEnabled())) {
+ header.addStringValue("crlUpdate", "testingNotEnabled");
+ } else {
+ try {
+ EBaseException publishError = null;
+
+ try {
+ long now1 = System.currentTimeMillis();
+
+ if (signatureAlgorithm != null) {
+ crlIssuingPoint.updateCRLNow(signatureAlgorithm);
+ } else {
+ crlIssuingPoint.updateCRLNow();
+ }
+
+ long now2 = System.currentTimeMillis();
+
+ header.addStringValue("time", "" + (now2 - now1));
+ } catch (EErrorPublishCRL e) {
+ publishError = e;
+ }
+
+ if (lpm != null && lpm.enabled()) {
+ Enumeration rules = lpm.getRules(IPublisherProcessor.PROP_LOCAL_CRL);
+ if (rules != null && rules.hasMoreElements()) {
+ if (publishError != null) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("error", publishError.toString(locale));
+ } else {
+ header.addStringValue("crlPublished", "Success");
+ }
+ }
+ }
+
+ // for audit log
+ SessionContext sContext = SessionContext.getContext();
+ String agentId = (String) sContext.get(SessionContext.USER_ID);
+ IAuthToken authToken = (IAuthToken) sContext.get(SessionContext.AUTH_TOKEN);
+ String authMgr = AuditFormat.NOAUTH;
+
+ if (authToken != null) {
+ authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+ }
+ long endTime = CMS.getCurrentDate().getTime();
+
+ if (crlIssuingPoint.getNextUpdate() != null) {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.CRLUPDATEFORMAT,
+ new Object[] {
+ AuditFormat.FROMAGENT + " agentID: " + agentId,
+ authMgr,
+ "completed",
+ crlIssuingPoint.getId(),
+ crlIssuingPoint.getCRLNumber(),
+ crlIssuingPoint.getLastUpdate(),
+ crlIssuingPoint.getNextUpdate(),
+ Long.toString(crlIssuingPoint.getCRLSize()) + " time: " + (endTime - startTime)}
+ );
+ }else {
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.CRLUPDATEFORMAT,
+ new Object[] {
+ AuditFormat.FROMAGENT + " agentID: " + agentId,
+ authMgr,
+ "completed",
+ crlIssuingPoint.getId(),
+ crlIssuingPoint.getCRLNumber(),
+ crlIssuingPoint.getLastUpdate(),
+ "not set",
+ Long.toString(crlIssuingPoint.getCRLSize()) + " time: " + (endTime - startTime)}
+ );
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_UPDATE_CRL", e.toString()));
+ if ((lpm != null) && lpm.enabled() && (e instanceof ELdapException)) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("error", e.toString(locale));
+ } else {
+ throw e;
+ }
+ }
+ }
+ } else {
+ if (crlIssuingPoint.isCRLIssuingPointInitialized()
+ != ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+ header.addStringValue("crlUpdate", "notInitialized");
+ } else if (crlIssuingPoint.isCRLUpdateInProgress()
+ != ICRLIssuingPoint.CRL_UPDATE_DONE ||
+ crlIssuingPoint.isManualUpdateSet()) {
+ header.addStringValue("crlUpdate", "inProgress");
+ } else if (!crlIssuingPoint.isCRLGenerationEnabled()) {
+ header.addStringValue("crlUpdate", "Disabled");
+ } else {
+ crlIssuingPoint.setManualUpdate(signatureAlgorithm);
+ header.addStringValue("crlUpdate", "Scheduled");
+ }
+ }
+ }
+ return;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java
new file mode 100644
index 000000000..5f5afad1d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/UpdateDir.java
@@ -0,0 +1,734 @@
+// --- 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 com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.base.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.util.*;
+import java.text.*;
+import java.math.*;
+import java.security.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.ca.*;
+
+import com.netscape.cms.servlet.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.certsrv.dbs.crldb.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authorization.*;
+
+
+/**
+ * Update the configured LDAP server with specified objects
+ *
+ * @version $Revision$, $Date$
+ */
+public class UpdateDir extends CMSServlet {
+
+ private final static String INFO = "UpdateDir";
+ private final static String TPL_FILE = "updateDir.template";
+ private final static int UPDATE_ALL = 0;
+ private final static int UPDATE_CRL = 1;
+ private final static int UPDATE_CA = 2;
+ private final static int UPDATE_VALID = 3;
+ private final static int VALID_FROM = 4;
+ private final static int VALID_TO = 5;
+ private final static int UPDATE_EXPIRED = 6;
+ private final static int EXPIRED_FROM = 7;
+ private final static int EXPIRED_TO = 8;
+ private final static int UPDATE_REVOKED = 9;
+ private final static int REVOKED_FROM = 10;
+ private final static int REVOKED_TO = 11;
+ private final static int CHECK_FLAG = 12;
+ private final static String[] updateName =
+ {"updateAll", "updateCRL", "updateCA",
+ "updateValid", "validFrom", "validTo",
+ "updateExpired", "expiredFrom", "expiredTo",
+ "updateRevoked", "revokedFrom", "revokedTo",
+ "checkFlag"};
+
+ private String mFormPath = null;
+ private ICertificateAuthority mCA = null;
+ private IPublisherProcessor mPublisherProcessor = null;
+ private ICRLRepository mCRLRepository = null;
+ private boolean mClonedCA = false;
+
+ /**
+ * Constructs UpdateDir servlet.
+ */
+ public UpdateDir() {
+ super();
+ }
+
+ /**
+ * Initialize the servlet. This servlet uses the template
+ * 'updateDir.template' to render the response
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+
+ if( mAuthority != null ) {
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ if (mAuthority instanceof ICertificateAuthority) {
+ mCA = (ICertificateAuthority) mAuthority;
+ mPublisherProcessor = mCA.getPublisherProcessor();
+ mCRLRepository = mCA.getCRLRepository();
+ }
+
+ // override success to do output orw own template.
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null) {
+ mFormPath = mOutputTemplatePath;
+ }
+ }
+ }
+
+ /**
+ * Process the HTTP request.
+ *
+ * @param cmsReq the object holding the request and response information
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "update");
+ } 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;
+ }
+
+ EBaseException error = null;
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ 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.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+
+ try {
+ String crlIssuingPointId = req.getParameter("crlIssuingPoint");
+
+ if (mPublisherProcessor == null ||
+ !mPublisherProcessor.enabled())
+ throw new ECMSGWException(CMS.getUserMessage("CMS_GW_NO_PUB_MODULE"));
+
+ String[] updateValue = new String[updateName.length];
+
+ for (int i = 0; i < updateName.length; i++) {
+ updateValue[i] = req.getParameter(updateName[i]);
+ }
+
+ String masterHost = CMS.getConfigStore().getString("master.ca.agent.host", "");
+ String masterPort = CMS.getConfigStore().getString("master.ca.agent.port", "");
+ if (masterHost != null && masterHost.length() > 0 &&
+ masterPort != null && masterPort.length() > 0) {
+ mClonedCA = true;
+ }
+
+ process(argSet, header, req, resp, crlIssuingPointId, updateValue, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ if (error == null) {
+ 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(CMSRequest.SUCCESS);
+ }
+ } else {
+ cmsReq.setStatus(CMSRequest.ERROR);
+ cmsReq.setError(error);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ }
+
+ private void updateCRLIssuingPoint(
+ IArgBlock header,
+ String crlIssuingPointId,
+ ICRLIssuingPoint crlIssuingPoint,
+ Locale locale) {
+ SessionContext sc = SessionContext.getContext();
+
+ sc.put(ICRLIssuingPoint.SC_ISSUING_POINT_ID, crlIssuingPointId);
+ sc.put(ICRLIssuingPoint.SC_IS_DELTA_CRL, "false");
+ ICRLIssuingPointRecord crlRecord = null;
+
+ try {
+ if (mCRLRepository != null) {
+ crlRecord = (ICRLIssuingPointRecord)mCRLRepository.readCRLIssuingPointRecord(crlIssuingPointId);
+ }
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_GET_CRL_RECORD", e.toString()));
+ }
+
+ if (crlRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", crlIssuingPointId));
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ } else {
+ String publishDN = (crlIssuingPoint != null)? crlIssuingPoint.getPublishDN(): null;
+ byte[] crlbytes = crlRecord.getCRL();
+
+ if (crlbytes == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_CRL_NOT_YET_UPDATED_1", ""));
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError",
+ new ECMSGWException(CMS.getUserMessage(locale, "CMS_GW_CRL_NOT_YET_UPDATED")).toString());
+ } else {
+ X509CRLImpl crl = null;
+
+ try {
+ crl = new X509CRLImpl(crlbytes);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_CRL", e.toString()));
+ }
+
+ if (crl == null) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError",
+ new ECMSGWException(CMS.getUserMessage(locale,"CMS_GW_DECODE_CRL_FAILED")).toString());
+ } else {
+ try {
+ if (publishDN != null) {
+ mPublisherProcessor.publishCRL(publishDN, crl);
+ } else {
+ mPublisherProcessor.publishCRL(crl,crlIssuingPointId);
+ }
+ header.addStringValue("crlPublished", "Success");
+ } catch (ELdapException e) {
+ header.addStringValue("crlPublished", "Failure");
+ header.addStringValue("crlError", e.toString(locale));
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR_PUBLISH_CRL", e.toString()));
+ }
+ }
+ }
+
+ sc.put(ICRLIssuingPoint.SC_IS_DELTA_CRL, "true");
+ // handle delta CRL if any
+ byte[] deltaCrlBytes = crlRecord.getDeltaCRL();
+
+ if (deltaCrlBytes != null) {
+ X509CRLImpl deltaCrl = null;
+
+ try {
+ deltaCrl = new X509CRLImpl(deltaCrlBytes);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_DECODE_DELTA_CRL", e.toString()));
+ }
+
+ boolean goodDelta = false;
+ if (mClonedCA) {
+ BigInteger crlNumber = crlRecord.getCRLNumber();
+ BigInteger deltaNumber = crlRecord.getDeltaCRLNumber();
+ Long deltaCRLSize = crlRecord.getDeltaCRLSize();
+ if (deltaCRLSize != null && deltaCRLSize.longValue() > -1 &&
+ crlNumber != null && deltaNumber != null &&
+ deltaNumber.compareTo(crlNumber) >= 0) {
+ goodDelta = true;
+ }
+ }
+
+ if (deltaCrl != null && ((mClonedCA && goodDelta) ||
+ (crlIssuingPoint != null &&
+ crlIssuingPoint.isThisCurrentDeltaCRL(deltaCrl)))) {
+ try {
+ if (publishDN != null) {
+ mPublisherProcessor.publishCRL(publishDN, deltaCrl);
+ } else {
+ mPublisherProcessor.publishCRL(deltaCrl,crlIssuingPointId);
+ }
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_PUBLISH_DELTA_CRL", e.toString()));
+ }
+ }
+ }
+ } // if
+ }
+
+ private void process(CMSTemplateParams argSet, IArgBlock header,
+ HttpServletRequest req,
+ HttpServletResponse resp,
+ String crlIssuingPointId,
+ String[] updateValue,
+ Locale locale)
+ throws EBaseException {
+ // all or crl
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_CRL] != null &&
+ updateValue[UPDATE_CRL].equalsIgnoreCase("yes"))) {
+ // check if received issuing point ID is known to the server
+ if (crlIssuingPointId != null) {
+ Enumeration ips = mCA.getCRLIssuingPoints();
+
+ while (ips.hasMoreElements()) {
+ ICRLIssuingPoint ip = (ICRLIssuingPoint) ips.nextElement();
+
+ if (crlIssuingPointId.equals(ip.getId())) {
+ break;
+ }
+ if (!ips.hasMoreElements()) crlIssuingPointId = null;
+ }
+ }
+ if (crlIssuingPointId == null) {
+ // publish all issuing points
+ if (mClonedCA && mCRLRepository != null) {
+ Vector ipNames = mCRLRepository.getIssuingPointsNames();
+ if (ipNames != null && ipNames.size() > 0) {
+ for (int i = 0; i < ipNames.size(); i++) {
+ String ipName = (String)ipNames.elementAt(i);
+
+ updateCRLIssuingPoint(header, ipName, null, locale);
+ }
+ }
+ } else {
+ Enumeration oips = mCA.getCRLIssuingPoints();
+
+ while (oips.hasMoreElements()) {
+ ICRLIssuingPoint oip = (ICRLIssuingPoint) oips.nextElement();
+
+ updateCRLIssuingPoint(header, oip.getId(), oip, locale);
+ }
+ }
+ } else {
+ ICRLIssuingPoint crlIssuingPoint =
+ mCA.getCRLIssuingPoint(crlIssuingPointId);
+ ICRLIssuingPointRecord crlRecord = null;
+
+ updateCRLIssuingPoint(header, crlIssuingPointId,
+ crlIssuingPoint, locale);
+ }
+ }
+
+ ICertificateRepository certificateRepository = (ICertificateRepository) mCA.getCertificateRepository();
+
+ // all or ca
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_CA] != null &&
+ updateValue[UPDATE_CA].equalsIgnoreCase("yes"))) {
+ X509CertImpl caCert = mCA.getSigningUnit().getCertImpl();
+
+ try {
+ mPublisherProcessor.publishCACert(caCert);
+ header.addStringValue("caCertPublished", "Success");
+ } catch (ELdapException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("LDAP_ERROR_PUBLISH_CACERT_1",
+ caCert.getSerialNumber().toString(16), e.toString()));
+ header.addStringValue("caCertPublished", "Failure");
+ header.addStringValue("caCertError", e.toString(locale));
+ }
+ }
+
+ // all or valid
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_VALID] != null &&
+ updateValue[UPDATE_VALID].equalsIgnoreCase("yes"))) {
+ if (certificateRepository != null) {
+ if (updateValue[VALID_FROM].startsWith("0x")) {
+ updateValue[VALID_FROM] = hexToDecimal(updateValue[VALID_FROM]);
+ }
+ if (updateValue[VALID_TO].startsWith("0x")) {
+ updateValue[VALID_TO] = hexToDecimal(updateValue[VALID_TO]);
+ }
+ Enumeration validCerts = null;
+
+ if (updateValue[CHECK_FLAG] != null &&
+ updateValue[CHECK_FLAG].equalsIgnoreCase("yes")) {
+ validCerts =
+ certificateRepository.getValidNotPublishedCertificates(
+ updateValue[VALID_FROM],
+ updateValue[VALID_TO]);
+ } else {
+ validCerts =
+ certificateRepository.getValidCertificates(
+ updateValue[VALID_FROM],
+ updateValue[VALID_TO]);
+ }
+ int i = 0;
+ int l = 0;
+ String validCertsError = "";
+
+ if (validCerts != null) {
+ while (validCerts.hasMoreElements()) {
+ ICertRecord certRecord =
+ (ICertRecord) validCerts.nextElement();
+ //X509CertImpl cert = certRecord.getCertificate();
+ X509CertImpl cert = null;
+ Object o = certRecord.getCertificate();
+
+ if (o instanceof X509CertImpl)
+ cert = (X509CertImpl) o;
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ metaInfo = (MetaInfo) certRecord.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ // ca's self signed signing cert and
+ // server cert has no related request and
+ // have no metaInfo
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_GET_ICERT_RECORD",
+ cert.getSerialNumber().toString(16)));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+
+ IRequest r = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ r = mCA.getRequestQueue().findRequest(rid);
+ }
+
+ try {
+ l++;
+ SessionContext sc = SessionContext.getContext();
+
+ if (r == null) {
+ if (CMS.isEncryptionCert(cert))
+ sc.put((Object) "isEncryptionCert", (Object) "true");
+ else
+ sc.put((Object) "isEncryptionCert", (Object) "false");
+ mPublisherProcessor.publishCert(cert, null);
+ } else {
+ if (CMS.isEncryptionCert(cert))
+ r.setExtData("isEncryptionCert", "true");
+ else
+ r.setExtData("isEncryptionCert", "false");
+ mPublisherProcessor.publishCert(cert, r);
+ }
+ i++;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_PUBLISH_CERT", certRecord.getSerialNumber().toString(16),
+ e.toString()));
+ validCertsError +=
+ "Failed to publish certificate: 0x" +
+ certRecord.getSerialNumber().toString(16) +
+ ".\n <BR> &nbsp;&nbsp;&nbsp;&nbsp;";
+ }
+ }
+ }
+ if (i > 0 && i == l) {
+ header.addStringValue("validCertsPublished",
+ "Success");
+ if (i == 1)
+ header.addStringValue("validCertsError", i +
+ " valid certificate is published in the directory.");
+ else
+ header.addStringValue("validCertsError", i +
+ " valid certificates are published in the directory.");
+ } else {
+ if (l == 0) {
+ header.addStringValue("validCertsPublished", "No");
+ } else {
+ header.addStringValue("validCertsPublished", "Failure");
+ header.addStringValue("validCertsError",
+ validCertsError);
+ }
+ }
+ } else {
+ header.addStringValue("validCertsPublished", "Failure");
+ header.addStringValue("validCertsError", "Certificate repository is unavailable.");
+ }
+ }
+
+ // all or expired
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_EXPIRED] != null &&
+ updateValue[UPDATE_EXPIRED].equalsIgnoreCase("yes"))) {
+ if (certificateRepository != null) {
+ if (updateValue[EXPIRED_FROM].startsWith("0x")) {
+ updateValue[EXPIRED_FROM] = hexToDecimal(updateValue[EXPIRED_FROM]);
+ }
+ if (updateValue[EXPIRED_TO].startsWith("0x")) {
+ updateValue[EXPIRED_TO] = hexToDecimal(updateValue[EXPIRED_TO]);
+ }
+ Enumeration expiredCerts = null;
+
+ if (updateValue[CHECK_FLAG] != null &&
+ updateValue[CHECK_FLAG].equalsIgnoreCase("yes")) {
+ expiredCerts =
+ certificateRepository.getExpiredPublishedCertificates(
+ updateValue[EXPIRED_FROM],
+ updateValue[EXPIRED_TO]);
+ } else {
+ expiredCerts =
+ certificateRepository.getExpiredCertificates(
+ updateValue[EXPIRED_FROM],
+ updateValue[EXPIRED_TO]);
+ }
+ int i = 0;
+ int l = 0;
+ StringBuffer expiredCertsError = new StringBuffer();
+
+ if (expiredCerts != null) {
+ while (expiredCerts.hasMoreElements()) {
+ ICertRecord certRecord =
+ (ICertRecord) expiredCerts.nextElement();
+ //X509CertImpl cert = certRecord.getCertificate();
+ X509CertImpl cert = null;
+ Object o = certRecord.getCertificate();
+
+ if (o instanceof X509CertImpl)
+ cert = (X509CertImpl) o;
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ metaInfo = (MetaInfo) certRecord.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ // ca's self signed signing cert and
+ // server cert has no related request and
+ // have no metaInfo
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_GET_ICERT_RECORD",
+ cert.getSerialNumber().toString(16)));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+
+ IRequest r = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ r = mCA.getRequestQueue().findRequest(rid);
+ }
+
+ try {
+ l++;
+ if (r == null) {
+ mPublisherProcessor.unpublishCert(cert, null);
+ } else {
+ mPublisherProcessor.unpublishCert(cert, r);
+ }
+ i++;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LDAP_ERROR_UNPUBLISH_CERT",
+ certRecord.getSerialNumber().toString(16),
+ e.toString()));
+ expiredCertsError.append(
+ "Failed to unpublish certificate: 0x");
+ expiredCertsError.append(
+ certRecord.getSerialNumber().toString(16));
+ expiredCertsError.append(
+ ".\n <BR> &nbsp;&nbsp;&nbsp;&nbsp;");
+ }
+ }
+ }
+ if (i > 0 && i == l) {
+ header.addStringValue("expiredCertsUnpublished", "Success");
+ if (i == 1)
+ header.addStringValue("expiredCertsError", i +
+ " expired certificate is unpublished in the directory.");
+ else
+ header.addStringValue("expiredCertsError", i +
+ " expired certificates are unpublished in the directory.");
+ } else {
+ if (l == 0) {
+ header.addStringValue("expiredCertsUnpublished", "No");
+ } else {
+ header.addStringValue("expiredCertsUnpublished", "Failure");
+ header.addStringValue("expiredCertsError",
+ expiredCertsError.toString());
+ }
+ }
+ } else {
+ header.addStringValue("expiredCertsUnpublished", "Failure");
+ header.addStringValue("expiredCertsError", "Certificate repository is unavailable.");
+ }
+ }
+
+ // all or revoked
+ if ((updateValue[UPDATE_ALL] != null &&
+ updateValue[UPDATE_ALL].equalsIgnoreCase("yes")) ||
+ (updateValue[UPDATE_REVOKED] != null &&
+ updateValue[UPDATE_REVOKED].equalsIgnoreCase("yes"))) {
+ if (certificateRepository != null) {
+ if (updateValue[REVOKED_FROM].startsWith("0x")) {
+ updateValue[REVOKED_FROM] = hexToDecimal(updateValue[REVOKED_FROM]);
+ }
+ if (updateValue[REVOKED_TO].startsWith("0x")) {
+ updateValue[REVOKED_TO] = hexToDecimal(updateValue[REVOKED_TO]);
+ }
+ Enumeration revokedCerts = null;
+
+ if (updateValue[CHECK_FLAG] != null &&
+ updateValue[CHECK_FLAG].equalsIgnoreCase("yes")) {
+ revokedCerts =
+ certificateRepository.getRevokedPublishedCertificates(
+ updateValue[REVOKED_FROM],
+ updateValue[REVOKED_TO]);
+ } else {
+ revokedCerts =
+ certificateRepository.getRevokedCertificates(
+ updateValue[REVOKED_FROM],
+ updateValue[REVOKED_TO]);
+ }
+ int i = 0;
+ int l = 0;
+ String revokedCertsError = "";
+
+ if (revokedCerts != null) {
+ while (revokedCerts.hasMoreElements()) {
+ ICertRecord certRecord =
+ (ICertRecord) revokedCerts.nextElement();
+ //X509CertImpl cert = certRecord.getCertificate();
+ X509CertImpl cert = null;
+ Object o = certRecord.getCertificate();
+
+ if (o instanceof X509CertImpl)
+ cert = (X509CertImpl) o;
+
+ MetaInfo metaInfo = null;
+ String ridString = null;
+
+ metaInfo = (MetaInfo) certRecord.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ // ca's self signed signing cert and
+ // server cert has no related request and
+ // have no metaInfo
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_FAIL_GET_ICERT_RECORD",
+ cert.getSerialNumber().toString(16)));
+ } else {
+ ridString = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ }
+
+ IRequest r = null;
+
+ if (ridString != null) {
+ RequestId rid = new RequestId(ridString);
+
+ r = mCA.getRequestQueue().findRequest(rid);
+ }
+
+ try {
+ l++;
+ if (r == null) {
+ mPublisherProcessor.unpublishCert(cert, null);
+ } else {
+ mPublisherProcessor.unpublishCert(cert, r);
+ }
+ i++;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("LDAP_ERROR_UNPUBLISH_CERT",
+ certRecord.getSerialNumber().toString(16),
+ e.toString()));
+ revokedCertsError +=
+ "Failed to unpublish certificate: 0x" +
+ certRecord.getSerialNumber().toString(16) +
+ ".\n <BR> &nbsp;&nbsp;&nbsp;&nbsp;";
+ }
+ }
+ }
+ if (i > 0 && i == l) {
+ header.addStringValue("revokedCertsUnpublished", "Success");
+ if (i == 1)
+ header.addStringValue("revokedCertsError", i +
+ " revoked certificate is unpublished in the directory.");
+ else
+ header.addStringValue("revokedCertsError", i +
+ " revoked certificates are unpublished in the directory.");
+ } else {
+ if (l == 0) {
+ header.addStringValue("revokedCertsUnpublished", "No");
+ } else {
+ header.addStringValue("revokedCertsUnpublished", "Failure");
+ header.addStringValue("revokedCertsError",
+ revokedCertsError);
+ }
+ }
+ } else {
+ header.addStringValue("revokedCertsUnpublished", "Failure");
+ header.addStringValue("revokedCertsError", "Certificate repository is unavailable.");
+ }
+ }
+
+ return;
+ }
+
+ private String hexToDecimal(String hex) {
+ String newHex = hex.substring(2);
+ BigInteger bi = new BigInteger(newHex, 16);
+
+ return bi.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java
new file mode 100644
index 000000000..97dde1a31
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/CRSEnrollment.java
@@ -0,0 +1,2126 @@
+// --- 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.scep;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import netscape.ldap.*;
+import java.security.*;
+import java.security.MessageDigest;
+
+import netscape.security.x509.*;
+import netscape.security.pkcs.*;
+import netscape.security.util.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.authentication.AuthCredentials;
+import com.netscape.certsrv.profile.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.cms.servlet.profile.*;
+import org.mozilla.jss.pkcs7.*;
+import org.mozilla.jss.asn1.*;
+import org.mozilla.jss.*;
+import org.mozilla.jss.util.*;
+import org.mozilla.jss.crypto.*;
+import org.mozilla.jss.pkix.cert.Certificate;
+import com.netscape.cmsutil.scep.CRSPKIMessage;
+
+
+/**
+ * This servlet deals with PKCS#10-based certificate requests from
+ * CRS, now called SCEP, and defined at:
+ * http://search.ietf.org/internet-drafts/draft-nourse-scep-02.txt
+ *
+ * The router is hardcoded to look for the http://host:80/cgi-bin/pkiclient.exe
+ *
+ * The HTTP parameters are 'operation' and 'message'
+ * operation can be either 'GetCACert' or 'PKIOperation'
+ *
+ * @version $Revision$, $Date$
+ */
+public class CRSEnrollment extends HttpServlet
+{
+ protected IProfileSubsystem mProfileSubsystem = null;
+ protected String mProfileId = null;
+ protected ICertAuthority mAuthority;
+ protected IConfigStore mConfig = null;
+ protected IAuthSubsystem mAuthSubsystem;
+ protected String mAppendDN=null;
+ protected String mEntryObjectclass=null;
+ protected boolean mCreateEntry=false;
+ protected boolean mFlattenDN=false;
+
+ private String mAuthManagerName;
+ private String mSubstoreName;
+ private boolean mEnabled = false;
+ private boolean mUseCA = true;
+ private String mNickname = null;
+ private String mTokenName = "";
+ private String mHashAlgorithm = "SHA1";
+ private String mHashAlgorithmList = null;
+ private String[] mAllowedHashAlgorithm;
+ private String mConfiguredEncryptionAlgorithm = "DES3";
+ private String mEncryptionAlgorithm = "DES3";
+ private String mEncryptionAlgorithmList = null;
+ private String[] mAllowedEncryptionAlgorithm;
+ private Random mRandom = null;
+ private int mNonceSizeLimit = 0;
+ protected ILogger mLogger = CMS.getLogger();
+ private ICertificateAuthority ca;
+ /* for hashing challenge password */
+ protected MessageDigest mSHADigest = null;
+
+ private static final String PROP_SUBSTORENAME = "substorename";
+ private static final String PROP_AUTHORITY = "authority";
+ private static final String PROP_CRS = "crs";
+ private static final String PROP_CRSCA = "casubsystem";
+ private static final String PROP_CRSAUTHMGR = "authName";
+ private static final String PROP_APPENDDN = "appendDN";
+ private static final String PROP_CREATEENTRY= "createEntry";
+ private static final String PROP_FLATTENDN = "flattenDN";
+ private static final String PROP_ENTRYOC = "entryObjectclass";
+
+ // URL parameters
+ private static final String URL_OPERATION = "operation";
+ private static final String URL_MESSAGE = "message";
+
+ // possible values for 'operation'
+ private static final String OP_GETCACERT = "GetCACert";
+ private static final String OP_PKIOPERATION = "PKIOperation";
+
+ public static final String AUTH_PASSWORD = "pwd";
+
+ public static final String AUTH_CREDS = "AuthCreds";
+ public static final String AUTH_TOKEN = "AuthToken";
+ public static final String AUTH_FAILED = "AuthFailed";
+
+ public static final String SANE_DNSNAME = "DNSName";
+ public static final String SANE_IPADDRESS = "IPAddress";
+
+ public static final String CERTINFO = "CertInfo";
+ public static final String SUBJECTNAME = "SubjectName";
+
+
+ public static ObjectIdentifier OID_UNSTRUCTUREDNAME = null;
+ public static ObjectIdentifier OID_UNSTRUCTUREDADDRESS = null;
+ public static ObjectIdentifier OID_SERIALNUMBER = null;
+
+ public CRSEnrollment(){}
+
+ public static Hashtable toHashtable(HttpServletRequest req) {
+ Hashtable httpReqHash = new Hashtable();
+ Enumeration names = req.getParameterNames();
+ while (names.hasMoreElements()) {
+ String name = (String)names.nextElement();
+ httpReqHash.put(name, req.getParameter(name));
+ }
+ return httpReqHash;
+ }
+
+ public void init(ServletConfig sc) {
+ // Find the CertificateAuthority we should use for CRS.
+ String crsCA = sc.getInitParameter(PROP_AUTHORITY);
+ if (crsCA == null)
+ crsCA = "ca";
+ mAuthority = (ICertAuthority) CMS.getSubsystem(crsCA);
+ ca = (ICertificateAuthority)mAuthority;
+
+ if (mAuthority == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_CANT_FIND_AUTHORITY",crsCA));
+ }
+
+ try {
+ if (mAuthority instanceof ISubsystem) {
+ IConfigStore authorityConfig = ((ISubsystem)mAuthority).getConfigStore();
+ IConfigStore scepConfig = authorityConfig.getSubStore("scep");
+ mEnabled = scepConfig.getBoolean("enable", false);
+ mHashAlgorithm = scepConfig.getString("hashAlgorithm", "SHA1");
+ mConfiguredEncryptionAlgorithm = scepConfig.getString("encryptionAlgorithm", "DES3");
+ mNonceSizeLimit = scepConfig.getInteger("nonceSizeLimit", 0);
+ mHashAlgorithmList = scepConfig.getString("allowedHashAlgorithms", "SHA1,SHA256,SHA512");
+ mAllowedHashAlgorithm = mHashAlgorithmList.split(",");
+ mEncryptionAlgorithmList = scepConfig.getString("allowedEncryptionAlgorithms", "DES3");
+ mAllowedEncryptionAlgorithm = mEncryptionAlgorithmList.split(",");
+ mNickname = scepConfig.getString("nickname", ca.getNickname());
+ if (mNickname.equals(ca.getNickname())) {
+ mTokenName = ca.getSigningUnit().getTokenName();
+ } else {
+ mTokenName = scepConfig.getString("tokenname", "");
+ mUseCA = false;
+ }
+ }
+ } catch (EBaseException e) {
+ CMS.debug("CRSEnrollment: init: EBaseException: "+e);
+ }
+ mEncryptionAlgorithm = mConfiguredEncryptionAlgorithm;
+ CMS.debug("CRSEnrollment: init: SCEP support is "+((mEnabled)?"enabled":"disabled")+".");
+ CMS.debug("CRSEnrollment: init: SCEP nickname: "+mNickname);
+ CMS.debug("CRSEnrollment: init: CA nickname: "+ca.getNickname());
+ CMS.debug("CRSEnrollment: init: Token name: "+mTokenName);
+ CMS.debug("CRSEnrollment: init: Is SCEP using CA keys: "+mUseCA);
+ CMS.debug("CRSEnrollment: init: mNonceSizeLimit: "+mNonceSizeLimit);
+ CMS.debug("CRSEnrollment: init: mHashAlgorithm: "+mHashAlgorithm);
+ CMS.debug("CRSEnrollment: init: mHashAlgorithmList: "+mHashAlgorithmList);
+ for (int i = 0; i < mAllowedHashAlgorithm.length; i++) {
+ mAllowedHashAlgorithm[i] = mAllowedHashAlgorithm[i].trim();
+ CMS.debug("CRSEnrollment: init: mAllowedHashAlgorithm["+i+"]="+mAllowedHashAlgorithm[i]);
+ }
+ CMS.debug("CRSEnrollment: init: mEncryptionAlgorithm: "+mEncryptionAlgorithm);
+ CMS.debug("CRSEnrollment: init: mEncryptionAlgorithmList: "+mEncryptionAlgorithmList);
+ for (int i = 0; i < mAllowedEncryptionAlgorithm.length; i++) {
+ mAllowedEncryptionAlgorithm[i] = mAllowedEncryptionAlgorithm[i].trim();
+ CMS.debug("CRSEnrollment: init: mAllowedEncryptionAlgorithm["+i+"]="+mAllowedEncryptionAlgorithm[i]);
+ }
+
+ try {
+ mProfileSubsystem = (IProfileSubsystem)CMS.getSubsystem("profile");
+ mProfileId = sc.getInitParameter("profileId");
+ CMS.debug("CRSEnrollment: init: mProfileId="+mProfileId);
+
+ mAuthSubsystem = (IAuthSubsystem)CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ mAuthManagerName = sc.getInitParameter(PROP_CRSAUTHMGR);
+ mAppendDN = sc.getInitParameter(PROP_APPENDDN);
+ String tmp = sc.getInitParameter(PROP_CREATEENTRY);
+ if (tmp != null && tmp.trim().equalsIgnoreCase("true"))
+ mCreateEntry = true;
+ else
+ mCreateEntry = false;
+ tmp = sc.getInitParameter(PROP_FLATTENDN);
+ if (tmp != null && tmp.trim().equalsIgnoreCase("true"))
+ mFlattenDN = true;
+ else
+ mFlattenDN = false;
+ mEntryObjectclass = sc.getInitParameter(PROP_ENTRYOC);
+ if (mEntryObjectclass == null)
+ mEntryObjectclass = "cep";
+ mSubstoreName = sc.getInitParameter(PROP_SUBSTORENAME);
+ if (mSubstoreName == null)
+ mSubstoreName = "default";
+ } catch (Exception e) {
+ }
+
+ OID_UNSTRUCTUREDNAME = X500NameAttrMap.getDefault().getOid("UNSTRUCTUREDNAME");
+ OID_UNSTRUCTUREDADDRESS = X500NameAttrMap.getDefault().getOid("UNSTRUCTUREDADDRESS");
+ OID_SERIALNUMBER = X500NameAttrMap.getDefault().getOid("SERIALNUMBER");
+
+
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ }
+ catch (NoSuchAlgorithmException e) {
+ }
+
+ mRandom = new Random();
+ }
+
+
+ /**
+ *
+ * Service a CRS Request. It all starts here. This is where the message from the
+ * router is processed
+ *
+ * @param httpReq The HttpServletRequest.
+ * @param httpResp The HttpServletResponse.
+ *
+ */
+ public void service(HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws ServletException
+ {
+ boolean running_state = CMS.isInRunningState();
+ if (!running_state)
+ throw new ServletException(
+ "CMS server is not ready to serve.");
+
+ String operation = null;
+ String message = null;
+ mEncryptionAlgorithm = mConfiguredEncryptionAlgorithm;
+
+
+ // Parse the URL from the HTTP Request. Split it up into
+ // a structure which enables us to read the form elements
+ IArgBlock input = CMS.createArgBlock(toHashtable(httpReq));
+
+ try {
+ // Read in two form parameters - the router sets these
+ operation = (String)input.get(URL_OPERATION);
+ CMS.debug("operation=" + operation);
+ message = (String)input.get(URL_MESSAGE);
+ CMS.debug("message=" + message);
+
+ if (!mEnabled) {
+ CMS.debug("CRSEnrollment: SCEP support is disabled.");
+ throw new ServletException("SCEP support is disabled.");
+ }
+ if (operation == null) {
+ // 'operation' is mandatory.
+ throw new ServletException("Bad request: operation missing from URL");
+ }
+
+ /**
+ * the router can make two kinds of requests
+ * 1) simple request for CA cert
+ * 2) encoded, signed, enveloped request for anything else (PKIOperation)
+ */
+
+ if (operation.equals(OP_GETCACERT)) {
+ handleGetCACert(httpReq, httpResp);
+ }
+ else if (operation.equals(OP_PKIOPERATION)) {
+ String decodeMode = (String)input.get("decode");
+ if (decodeMode == null || decodeMode.equals("false")) {
+ handlePKIOperation(httpReq, httpResp, message);
+ } else {
+ decodePKIMessage(httpReq, httpResp, message);
+ }
+ }
+ else {
+ CMS.debug("Invalid operation " + operation);
+ throw new ServletException("unknown operation requested: "+operation);
+ }
+
+ }
+ catch (ServletException e)
+ {
+ CMS.debug("ServletException " + e);
+ throw new ServletException(e.getMessage().toString());
+ }
+ catch (Exception e)
+ {
+ CMS.debug("Service exception " + e);
+ log(ILogger.LL_FAILURE,e.getMessage());
+ }
+
+ }
+
+ /**
+ * Log a message to the system log
+ */
+
+
+ private void log(int level, String msg) {
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ level, "CEP Enrollment: "+msg);
+ }
+
+ private boolean isAlgorithmAllowed (String[] allowedAlgorithm, String algorithm) {
+ boolean allowed = false;
+
+ if (algorithm != null && algorithm.length() > 0) {
+ for (int i = 0; i < allowedAlgorithm.length; i++) {
+ if (algorithm.equalsIgnoreCase(allowedAlgorithm[i])) {
+ allowed = true;
+ }
+ }
+ }
+
+ return allowed;
+ }
+
+ public IAuthToken authenticate(AuthCredentials credentials, IProfileAuthenticator authenticator,
+ HttpServletRequest request) throws EBaseException {
+
+ // build credential
+ Enumeration authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ String authName = (String) authNames.nextElement();
+
+ credentials.set(authName, request.getParameter(authName));
+ }
+ }
+
+ credentials.set("clientHost", request.getRemoteHost());
+ IAuthToken authToken = authenticator.authenticate(credentials);
+ if (authToken == null) {
+ return null;
+ }
+ 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;
+ }
+
+ /**
+ * Return the CA certificate back to the requestor.
+ * This needs to be changed so that if the CA has a certificate chain,
+ * the whole thing should get packaged as a PKIMessage (degnerate PKCS7 - no
+ * signerInfo)
+ */
+
+ public void handleGetCACert(HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws ServletException {
+ java.security.cert.X509Certificate[] chain = null;
+
+ CertificateChain certChain = mAuthority.getCACertChain();
+
+ try {
+ if (certChain == null) {
+ throw new ServletException("Internal Error: cannot get CA Cert");
+ }
+
+ chain = certChain.getChain();
+
+ byte[] bytes = null;
+
+ int i = 0;
+ String message = (String)httpReq.getParameter(URL_MESSAGE);
+ CMS.debug("handleGetCACert message=" + message);
+ if (message != null) {
+ try {
+ int j = Integer.parseInt(message);
+ if (j < chain.length) {
+ i = j;
+ }
+ } catch (NumberFormatException e1) {
+ }
+ }
+ CMS.debug("handleGetCACert selected chain=" + i);
+
+ if (mUseCA) {
+ bytes = chain[i].getEncoded();
+ } else {
+ CryptoContext cx = new CryptoContext();
+ bytes = cx.getSigningCert().getEncoded();
+ }
+
+ httpResp.setContentType("application/x-x509-ca-cert");
+
+
+// The following code may be used one day to encode
+// the RA/CA cert chain for RA mode, but it will need some
+// work.
+
+ /******
+ SET certs = new SET();
+ for (int i=0; i<chain.length; i++) {
+ ANY cert = new ANY(chain[i].getEncoded());
+ certs.addElement(cert);
+ }
+
+ SignedData crsd = new SignedData(
+ new SET(), // empty set of digestAlgorithmID's
+ new ContentInfo(
+ new OBJECT_IDENTIFIER(new long[] {1,2,840,113549,1,7,1}),
+ null), //empty content
+ certs,
+ null, // no CRL's
+ new SET() // empty SignerInfos
+ );
+
+ ContentInfo wrap = new ContentInfo(ContentInfo.SIGNED_DATA, crsd);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ wrap.encode(baos);
+
+ bytes = baos.toByteArray();
+
+ httpResp.setContentType("application/x-x509-ca-ra-cert");
+ *****/
+
+ httpResp.setContentLength(bytes.length);
+ httpResp.getOutputStream().write(bytes);
+ httpResp.getOutputStream().flush();
+
+ CMS.debug("Output certificate chain:");
+ CMS.debug(bytes);
+ }
+ catch (Exception e) {
+ CMS.debug("handleGetCACert exception " + e);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_SENDING_DER_ENCODE_CERT",e.getMessage()));
+ throw new ServletException("Failed sending DER encoded version of CA cert to client");
+ }
+
+ }
+
+ public String getPasswordFromP10(PKCS10 p10)
+ {
+ PKCS10Attributes p10atts = p10.getAttributes();
+ Enumeration e = p10atts.getElements();
+
+ try {
+ while (e.hasMoreElements()) {
+ PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement();
+ CertAttrSet attr = p10a.getAttributeValue();
+
+ if (attr.getName().equals(ChallengePassword.NAME)) {
+ if (attr.get(ChallengePassword.PASSWORD) != null) {
+ return (String)attr.get(ChallengePassword.PASSWORD);
+ }
+ }
+ }
+ } catch(Exception e1) {
+ // do nothing
+ }
+ return null;
+ }
+
+ /**
+ * If the 'operation' is 'PKIOperation', the 'message' part of the URL is a
+ * PKIMessage structure. We decode it to see what type message it is.
+ */
+
+ /**
+ * Decodes the PKI message and return information to RA.
+ */
+ public void decodePKIMessage(HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ String msg)
+ throws ServletException {
+
+ CryptoContext cx=null;
+
+ CRSPKIMessage req=null;
+
+ byte[] decodedPKIMessage;
+ byte[] response=null;
+ String responseData = "";
+
+ decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg);
+
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(decodedPKIMessage);
+
+ // We make two CRSPKIMessages. One of them, is the request, so we initialize
+ // it from the DER given to us from the router.
+ // The second is the response, and we'll fill this in as we go.
+
+ if (decodedPKIMessage.length < 50) {
+ throw new ServletException("CRS request is too small to be a real request ("+
+ decodedPKIMessage.length+" bytes)");
+ }
+ try {
+ req = new CRSPKIMessage(is);
+ String ea = req.getEncryptionAlgorithm();
+ if (!isAlgorithmAllowed (mAllowedEncryptionAlgorithm, ea)) {
+ CMS.debug("CRSEnrollment: decodePKIMessage: Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ throw new ServletException("Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ }
+ String da = req.getDigestAlgorithmName();
+ if (!isAlgorithmAllowed (mAllowedHashAlgorithm, da)) {
+ CMS.debug("CRSEnrollment: decodePKIMessage: Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ throw new ServletException("Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ }
+ if (ea != null) {
+ mEncryptionAlgorithm = ea;
+ }
+ }
+ catch (Exception e) {
+ CMS.debug(e);
+ throw new ServletException("Could not decode the request.");
+ }
+
+ // Create a new crypto context for doing all the crypto operations
+ cx = new CryptoContext();
+
+ // Verify Signature on message (throws exception if sig bad)
+ verifyRequest(req,cx);
+ unwrapPKCS10(req,cx);
+
+ IProfile profile = mProfileSubsystem.getProfile(mProfileId);
+ if (profile == null) {
+ CMS.debug("Profile '" + mProfileId + "' not found.");
+ throw new ServletException("Profile '" + mProfileId + "' not found.");
+ } else {
+ CMS.debug("Found profile '" + mProfileId + "'.");
+ }
+
+ IProfileAuthenticator authenticator = null;
+ try {
+ CMS.debug("Retrieving authenticator");
+ authenticator = profile.getAuthenticator();
+ if (authenticator == null) {
+ CMS.debug("Authenticator not found.");
+ throw new ServletException("Authenticator not found.");
+ } else {
+ CMS.debug("Got authenticator=" + authenticator.getClass().getName());
+ }
+ } catch (EProfileException e) {
+ throw new ServletException("Authenticator not found.");
+ }
+ AuthCredentials credentials = new AuthCredentials();
+ 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("sslClientCertProvider", new SSLClientCertProvider(httpReq));
+
+ try {
+ authToken = authenticate(credentials, authenticator, httpReq);
+ } catch (Exception e) {
+ CMS.debug("Authentication failure: "+ e.getMessage());
+ throw new ServletException("Authentication failure: "+ e.getMessage());
+ }
+ if (authToken == null) {
+ CMS.debug("Authentication failure.");
+ throw new ServletException("Authentication failure.");
+ }
+
+ // Deal with Transaction ID
+ String transactionID = req.getTransactionID();
+ responseData = responseData +
+ "<TransactionID>" + transactionID + "</TransactionID>";
+
+ // End-User or RA's IP address
+ responseData = responseData +
+ "<RemoteAddr>" + httpReq.getRemoteAddr() + "</RemoteAddr>";
+
+ responseData = responseData +
+ "<RemoteHost>" + httpReq.getRemoteHost() + "</RemoteHost>";
+
+ // Deal with Nonces
+ byte[] sn = req.getSenderNonce();
+
+ // Deal with message type
+ String mt = req.getMessageType();
+ responseData = responseData +
+ "<MessageType>" + mt + "</MessageType>";
+
+ PKCS10 p10 = (PKCS10)req.getP10();
+ X500Name p10subject = p10.getSubjectName();
+ responseData = responseData +
+ "<SubjectName>" + p10subject.toString() + "</SubjectName>";
+
+ String pkcs10Attr = "";
+ PKCS10Attributes p10atts = p10.getAttributes();
+ Enumeration e = p10atts.getElements();
+
+ while (e.hasMoreElements()) {
+ PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement();
+ CertAttrSet attr = p10a.getAttributeValue();
+
+
+ if (attr.getName().equals(ChallengePassword.NAME)) {
+ if (attr.get(ChallengePassword.PASSWORD) != null) {
+ pkcs10Attr = pkcs10Attr +
+ "<ChallengePassword><Password>" + (String)attr.get(ChallengePassword.PASSWORD) + "</Password></ChallengePassword>";
+ }
+
+ }
+ String extensionsStr = "";
+ if (attr.getName().equals(ExtensionsRequested.NAME)) {
+
+ Enumeration exts = ((ExtensionsRequested)attr).getExtensions().elements();
+ while (exts.hasMoreElements()) {
+ Extension ext = (Extension) exts.nextElement();
+
+ if (ext.getExtensionId().equals(
+ OIDMap.getOID(SubjectAlternativeNameExtension.IDENT)) ) {
+ DerOutputStream dos = new DerOutputStream();
+ SubjectAlternativeNameExtension sane = new SubjectAlternativeNameExtension(
+ Boolean.valueOf(false), // noncritical
+ ext.getExtensionValue());
+
+
+ Vector v =
+ (Vector) sane.get(SubjectAlternativeNameExtension. SUBJECT_NAME);
+
+ Enumeration gne = v.elements();
+
+ StringBuffer subjAltNameStr = new StringBuffer();
+ while (gne.hasMoreElements()) {
+ GeneralNameInterface gni = (GeneralNameInterface) gne.nextElement();
+ if (gni instanceof GeneralName) {
+ GeneralName genName = (GeneralName) gni;
+
+ String gn = genName.toString();
+ int colon = gn.indexOf(':');
+ String gnType = gn.substring(0,colon).trim();
+ String gnValue = gn.substring(colon+1).trim();
+
+ subjAltNameStr.append("<");
+ subjAltNameStr.append(gnType);
+ subjAltNameStr.append(">");
+ subjAltNameStr.append(gnValue);
+ subjAltNameStr.append("</");
+ subjAltNameStr.append(gnType);
+ subjAltNameStr.append(">");
+ }
+ } // while
+ extensionsStr = "<SubjAltName>" +
+ subjAltNameStr.toString() + "</SubjAltName>";
+ } // if
+ } // while
+ pkcs10Attr = pkcs10Attr +
+ "<Extensions>" + extensionsStr + "</Extensions>";
+ } // if extensions
+ } // while
+ responseData = responseData +
+ "<PKCS10>" + pkcs10Attr + "</PKCS10>";
+
+ } catch (ServletException e) {
+ throw new ServletException(e.getMessage().toString());
+ } catch (CRSInvalidSignatureException e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ } catch (Exception e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ throw new ServletException("Failed to process message in CEP servlet: "+ e.getMessage());
+ }
+
+ // We have now processed the request, and need to make the response message
+
+ try {
+
+ responseData = "<XMLResponse>" + responseData + "</XMLResponse>";
+ // Get the response coding
+ response = responseData.getBytes();
+
+ // Encode the httpResp into B64
+ httpResp.setContentType("application/xml");
+ httpResp.setContentLength(response.length);
+ httpResp.getOutputStream().write(response);
+ httpResp.getOutputStream().flush();
+
+ int i1 = responseData.indexOf("<Password>");
+ if (i1 > -1) {
+ i1 += 10; // 10 is a length of "<Password>"
+ int i2 = responseData.indexOf("</Password>", i1);
+ if (i2 > -1) {
+ responseData = responseData.substring(0, i1) + "********" +
+ responseData.substring(i2, responseData.length());
+ }
+ }
+
+ CMS.debug("Output (decoding) PKIOperation response:");
+ CMS.debug(responseData);
+ }
+ catch (Exception e) {
+ throw new ServletException("Failed to create response for CEP message"+e.getMessage());
+ }
+
+ }
+
+
+ /**
+ * finds a request with this transaction ID.
+ * If could not find any request - return null
+ * If could only find 'rejected' or 'cancelled' requests, return null
+ * If found 'pending' or 'completed' request - return that request
+ */
+
+
+ public void handlePKIOperation(HttpServletRequest httpReq,
+ HttpServletResponse httpResp,
+ String msg)
+ throws ServletException {
+
+
+ CryptoContext cx=null;
+
+ CRSPKIMessage req=null;
+ CRSPKIMessage crsResp=null;
+
+ byte[] decodedPKIMessage;
+ byte[] response=null;
+ X509CertImpl cert = null;
+
+ decodedPKIMessage = com.netscape.osutil.OSUtil.AtoB(msg);
+
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(decodedPKIMessage);
+
+ // We make two CRSPKIMessages. One of them, is the request, so we initialize
+ // it from the DER given to us from the router.
+ // The second is the response, and we'll fill this in as we go.
+
+ if (decodedPKIMessage.length < 50) {
+ throw new ServletException("CRS request is too small to be a real request ("+
+ decodedPKIMessage.length+" bytes)");
+ }
+ try {
+ req = new CRSPKIMessage(is);
+ String ea = req.getEncryptionAlgorithm();
+ if (!isAlgorithmAllowed (mAllowedEncryptionAlgorithm, ea)) {
+ CMS.debug("CRSEnrollment: handlePKIOperation: Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ throw new ServletException("Encryption algorithm '"+ea+
+ "' is not allowed ("+mEncryptionAlgorithmList+").");
+ }
+ String da = req.getDigestAlgorithmName();
+ if (!isAlgorithmAllowed (mAllowedHashAlgorithm, da)) {
+ CMS.debug("CRSEnrollment: handlePKIOperation: Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ throw new ServletException("Hashing algorithm '"+da+
+ "' is not allowed ("+mHashAlgorithmList+").");
+ }
+ if (ea != null) {
+ mEncryptionAlgorithm = ea;
+ }
+ crsResp = new CRSPKIMessage();
+ }
+ catch (ServletException e) {
+ throw new ServletException(e.getMessage().toString());
+ }
+ catch (Exception e) {
+ CMS.debug(e);
+ throw new ServletException("Could not decode the request.");
+ }
+ crsResp.setMessageType(crsResp.mType_CertRep);
+
+ // Create a new crypto context for doing all the crypto operations
+ cx = new CryptoContext();
+
+ // Verify Signature on message (throws exception if sig bad)
+ verifyRequest(req,cx);
+
+ // Deal with Transaction ID
+ String transactionID = req.getTransactionID();
+ if (transactionID == null) {
+ throw new ServletException("Error: malformed PKIMessage - missing transactionID");
+ }
+ else {
+ crsResp.setTransactionID(transactionID);
+ }
+
+ // Deal with Nonces
+ byte[] sn = req.getSenderNonce();
+ if (sn == null) {
+ throw new ServletException("Error: malformed PKIMessage - missing sendernonce");
+ }
+ else {
+ if (mNonceSizeLimit > 0 && sn.length > mNonceSizeLimit) {
+ byte[] snLimited = (mNonceSizeLimit > 0)? new byte[mNonceSizeLimit]: null;
+ System.arraycopy(sn, 0, snLimited, 0, mNonceSizeLimit);
+ crsResp.setRecipientNonce(snLimited);
+ } else {
+ crsResp.setRecipientNonce(sn);
+ }
+ byte[] serverNonce = new byte[16];
+ mRandom.nextBytes(serverNonce);
+ crsResp.setSenderNonce(serverNonce);
+ // crsResp.setSenderNonce(new byte[] {0});
+ }
+
+ // Deal with message type
+ String mt = req.getMessageType();
+ if (mt == null) {
+ throw new ServletException("Error: malformed PKIMessage - missing messageType");
+ }
+
+ // now run appropriate code, depending on message type
+ if (mt.equals(req.mType_PKCSReq)) {
+ CMS.debug("Processing PKCSReq");
+ try {
+ // Check if there is an existing request. If this returns non-null,
+ // then the request is 'active' (either pending or completed) in
+ // which case, we compare the hash of the new request to the hash of the
+ // one in the queue - if they are the same, I return the state of the
+ // original request - as if it was 'getCertInitial' message.
+ // If the hashes are different, then the user attempted to enroll
+ // for a new request with the same txid, which is not allowed -
+ // so we return 'failure'.
+
+ IRequest cmsRequest= findRequestByTransactionID(req.getTransactionID(),true);
+
+ // If there was no request (with a cert) with this transaction ID,
+ // process it as a new request
+
+ cert = handlePKCSReq(httpReq, cmsRequest,req,crsResp,cx);
+
+ }
+ catch (CRSFailureException e) {
+ throw new ServletException("Couldn't handle CEP request (PKCSReq) - "+e.getMessage());
+ }
+ }
+ else if (mt.equals(req.mType_GetCertInitial)) {
+ CMS.debug("Processing GetCertInitial");
+ cert = handleGetCertInitial(req,crsResp);
+ } else {
+ CMS.debug("Invalid request type " + mt);
+ }
+ }
+ catch (ServletException e) {
+ throw new ServletException(e.getMessage().toString());
+ }
+ catch (CRSInvalidSignatureException e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ }
+ catch (Exception e) {
+ CMS.debug("handlePKIMessage exception " + e);
+ CMS.debug(e);
+ throw new ServletException("Failed to process message in CEP servlet: "+ e.getMessage());
+ }
+
+ // We have now processed the request, and need to make the response message
+
+ try {
+ // make the response
+ processCertRep(cx, cert,crsResp, req);
+
+ // Get the response coding
+ response = crsResp.getResponse();
+
+ // Encode the crsResp into B64
+ httpResp.setContentType("application/x-pki-message");
+ httpResp.setContentLength(response.length);
+ httpResp.getOutputStream().write(response);
+ httpResp.getOutputStream().flush();
+
+ CMS.debug("Output PKIOperation response:");
+ CMS.debug(CMS.BtoA(response));
+ }
+ catch (Exception e) {
+ throw new ServletException("Failed to create response for CEP message"+e.getMessage());
+ }
+
+ }
+
+
+ /**
+ * finds a request with this transaction ID.
+ * If could not find any request - return null
+ * If could only find 'rejected' or 'cancelled' requests, return null
+ * If found 'pending' or 'completed' request - return that request
+ */
+
+ public IRequest findRequestByTransactionID(String txid, boolean ignoreRejected)
+ throws EBaseException {
+
+ /* Check if certificate request has been completed */
+
+ IRequestQueue rq = ca.getRequestQueue();
+ IRequest foundRequest = null;
+
+ Enumeration rids = rq.findRequestsBySourceId(txid);
+ if (rids == null) { return null; }
+
+ int count=0;
+ while (rids.hasMoreElements()) {
+ RequestId rid = (RequestId) rids.nextElement();
+ if (rid == null) {
+ continue;
+ }
+
+ IRequest request = rq.findRequest(rid);
+ if (request == null) {
+ continue;
+ }
+ if ( !ignoreRejected ||
+ request.getRequestStatus().equals(RequestStatus.PENDING) ||
+ request.getRequestStatus().equals(RequestStatus.COMPLETE)) {
+ if (foundRequest != null) {
+ }
+ foundRequest = request;
+ }
+ }
+ return foundRequest;
+ }
+
+ /**
+ * Called if the router is requesting us to send it its certificate
+ * Examine request queue for a request matching the transaction ID.
+ * Ignore any rejected or cancelled requests.
+ *
+ * If a request is found in the pending state, the response should be
+ * 'pending'
+ *
+ * If a request is found in the completed state, the response should be
+ * to return the certificate
+ *
+ * If no request is found, the response should be to return null
+ *
+ */
+
+ public X509CertImpl handleGetCertInitial(CRSPKIMessage req,CRSPKIMessage resp)
+ {
+ IRequest foundRequest=null;
+
+ // already done by handlePKIOperation
+ // resp.setRecipientNonce(req.getSenderNonce());
+ // resp.setSenderNonce(null);
+
+ try {
+ foundRequest = findRequestByTransactionID(req.getTransactionID(),false);
+ } catch (EBaseException e) {
+ }
+
+ if (foundRequest == null) {
+ resp.setFailInfo(resp.mFailInfo_badCertId);
+ resp.setPKIStatus(resp.mStatus_FAILURE);
+ return null;
+ }
+
+ return makeResponseFromRequest(req,resp,foundRequest);
+ }
+
+
+ public void verifyRequest(CRSPKIMessage req, CryptoContext cx)
+ throws CRSInvalidSignatureException {
+
+ // Get Signed Data
+
+ byte[] reqAAbytes = req.getAA();
+ byte[] reqAAsig = req.getAADigest();
+
+ }
+
+
+ /**
+ * Create an entry for this user in the publishing directory
+ *
+ */
+
+ private boolean createEntry(String dn)
+ {
+ boolean result = false;
+
+ IPublisherProcessor ldapPub = mAuthority.getPublisherProcessor();
+ if (ldapPub == null || !ldapPub.enabled()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERROR_CREATE_ENTRY_FROM_CEP"));
+
+ return result;
+ }
+
+ ILdapConnFactory connFactory = ((IPublisherProcessor)ldapPub).getLdapConnModule().getLdapConnFactory();
+ if (connFactory == null) {
+ return result;
+ }
+
+ LDAPConnection connection=null;
+ try {
+ connection = connFactory.getConn();
+ String[] objectclasses = { "top", mEntryObjectclass };
+ LDAPAttribute ocAttrs = new LDAPAttribute("objectclass",objectclasses);
+
+ LDAPAttributeSet attrSet = new LDAPAttributeSet();
+ attrSet.add(ocAttrs);
+
+ LDAPEntry newEntry = new LDAPEntry(dn, attrSet);
+ connection.add(newEntry);
+ result=true;
+ }
+ catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_FAIL_CREAT_ENTRY_EXISTS",dn));
+ }
+ finally {
+ try {
+ connFactory.returnConn(connection);
+ }
+ catch (Exception f) {}
+ }
+ return result;
+ }
+
+
+
+ /**
+ * Here we decrypt the PKCS10 message from the client
+ *
+ */
+
+ public void unwrapPKCS10(CRSPKIMessage req, CryptoContext cx)
+ throws ServletException,
+ CryptoManager.NotInitializedException,
+ CryptoContext.CryptoContextException,
+ CRSFailureException {
+
+ byte[] decryptedP10bytes = null;
+ SymmetricKey sk;
+ SymmetricKey skinternal;
+ SymmetricKey.Type skt;
+ KeyWrapper kw;
+ Cipher cip;
+ EncryptionAlgorithm ea;
+ boolean errorInRequest = false;
+
+ // Unwrap the session key with the Cert server key
+ try {
+ kw = cx.getKeyWrapper();
+
+ kw.initUnwrap(cx.getPrivateKey(),null);
+
+ skt = SymmetricKey.Type.DES;
+ ea = EncryptionAlgorithm.DES_CBC;
+ if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) {
+ skt = SymmetricKey.Type.DES3;
+ ea = EncryptionAlgorithm.DES3_CBC;
+ }
+
+ sk = kw.unwrapSymmetric(req.getWrappedKey(),
+ skt,
+ SymmetricKey.Usage.DECRYPT,
+ 0); // keylength is ignored
+
+ skinternal = cx.getDESKeyGenerator().clone(sk);
+
+ cip = skinternal.getOwningToken().getCipherContext(ea);
+
+ cip.initDecrypt(skinternal,(new IVParameterSpec(req.getIV())));
+
+ decryptedP10bytes = cip.doFinal(req.getEncryptedPkcs10());
+ CMS.debug("decryptedP10bytes:");
+ CMS.debug(decryptedP10bytes);
+
+ req.setP10(new PKCS10(decryptedP10bytes));
+ } catch (Exception e) {
+ CMS.debug("failed to unwrap PKCS10 " + e);
+ throw new CRSFailureException("Could not unwrap PKCS10 blob: "+e.getMessage());
+ }
+
+ }
+
+
+
+private void getDetailFromRequest(CRSPKIMessage req, CRSPKIMessage crsResp)
+ throws CRSFailureException {
+
+ IRequest issueReq = null;
+ X509CertImpl issuedCert=null;
+ Vector extensionsRequested = null;
+ SubjectAlternativeNameExtension sane = null;
+ CertAttrSet requested_ext = null;
+
+ try {
+ PKCS10 p10 = (PKCS10)req.getP10();
+
+ if (p10 == null) {
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ throw new CRSFailureException("Failed to decode pkcs10 from CEP request");
+ }
+
+ AuthCredentials authCreds = new AuthCredentials();
+
+ String challengePassword = null;
+ // Here, we make a new CertInfo - it's a new start for a certificate
+
+ X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
+
+ // get some stuff out of the request
+ X509Key key = p10.getSubjectPublicKeyInfo();
+ X500Name p10subject = p10.getSubjectName();
+
+ X500Name subject=null;
+
+ // The following code will copy all the attributes
+ // into the AuthCredentials so they can be used for
+ // authentication
+ //
+ // Optionally, you can re-map the subject name from:
+ // one RDN, with many AVA's to
+ // many RDN's with one AVA in each.
+
+ Enumeration rdne = p10subject.getRDNs();
+ Vector rdnv = new Vector();
+
+ Hashtable sanehash = new Hashtable();
+
+ X500NameAttrMap xnap = X500NameAttrMap.getDefault();
+ while (rdne.hasMoreElements()) {
+ RDN rdn = (RDN) rdne.nextElement();
+ int i=0;
+ AVA[] oldavas = rdn.getAssertion();
+ for (i=0; i<rdn.getAssertionLength(); i++) {
+ AVA[] newavas = new AVA[1];
+ newavas[0] = oldavas[i];
+
+ authCreds.set(xnap.getName(oldavas[i].getOid()),
+ oldavas[i].getValue().getAsString());
+
+ if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDNAME)) {
+
+ sanehash.put(SANE_DNSNAME,oldavas[i].getValue().getAsString());
+ }
+ if (oldavas[i].getOid().equals(OID_UNSTRUCTUREDADDRESS)) {
+ sanehash.put(SANE_IPADDRESS,oldavas[i].getValue().getAsString());
+ }
+
+ RDN newrdn = new RDN(newavas);
+ if (mFlattenDN) {
+ rdnv.addElement(newrdn);
+ }
+ }
+ }
+
+ if (mFlattenDN) subject = new X500Name(rdnv);
+ else subject = p10subject;
+
+
+ // create default key usage extension
+ KeyUsageExtension kue = new KeyUsageExtension();
+ kue.set(KeyUsageExtension.DIGITAL_SIGNATURE, Boolean.valueOf(true));
+ kue.set(KeyUsageExtension.KEY_ENCIPHERMENT, Boolean.valueOf(true));
+
+
+ PKCS10Attributes p10atts = p10.getAttributes();
+ Enumeration e = p10atts.getElements();
+
+ while (e.hasMoreElements()) {
+ PKCS10Attribute p10a = (PKCS10Attribute)e.nextElement();
+ CertAttrSet attr = p10a.getAttributeValue();
+
+
+ if (attr.getName().equals(ChallengePassword.NAME)) {
+ if (attr.get(ChallengePassword.PASSWORD) != null) {
+ req.put(AUTH_PASSWORD,
+ (String)attr.get(ChallengePassword.PASSWORD));
+ req.put(ChallengePassword.NAME,
+ hashPassword(
+ (String)attr.get(ChallengePassword.PASSWORD)));
+ }
+ }
+
+ if (attr.getName().equals(ExtensionsRequested.NAME)) {
+
+ Enumeration exts = ((ExtensionsRequested)attr).getExtensions().elements();
+ while (exts.hasMoreElements()) {
+ Extension ext = (Extension) exts.nextElement();
+
+ if (ext.getExtensionId().equals(
+ OIDMap.getOID(KeyUsageExtension.IDENT)) ) {
+
+ kue = new KeyUsageExtension(
+ new Boolean(false), // noncritical
+ ext.getExtensionValue());
+ }
+
+ if (ext.getExtensionId().equals(
+ OIDMap.getOID(SubjectAlternativeNameExtension.IDENT)) ) {
+ DerOutputStream dos = new DerOutputStream();
+ sane = new SubjectAlternativeNameExtension(
+ new Boolean(false), // noncritical
+ ext.getExtensionValue());
+
+
+ Vector v =
+ (Vector) sane.get(SubjectAlternativeNameExtension. SUBJECT_NAME);
+
+ Enumeration gne = v.elements();
+
+ while (gne.hasMoreElements()) {
+ GeneralNameInterface gni = (GeneralNameInterface) gne.nextElement();
+ if (gni instanceof GeneralName) {
+ GeneralName genName = (GeneralName) gni;
+
+ String gn = genName.toString();
+ int colon = gn.indexOf(':');
+ String gnType = gn.substring(0,colon).trim();
+ String gnValue = gn.substring(colon+1).trim();
+
+ authCreds.set(gnType,gnValue);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (authCreds != null) req.put(AUTH_CREDS,authCreds);
+
+ try {
+ if (sane == null) sane = makeDefaultSubjectAltName(sanehash);
+ } catch (Exception sane_e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME",
+ sane_e.getMessage()));
+ }
+
+
+
+ try {
+ if (mAppendDN != null && ! mAppendDN.equals("")) {
+
+ X500Name newSubject = new X500Name(subject.toString());
+ subject = new X500Name( subject.toString().concat(","+mAppendDN));
+ }
+
+ } catch (Exception sne) {
+ log(ILogger.LL_INFO, "Unable to use appendDN parameter: "+mAppendDN+". Error is "+sne.getMessage()+" Using unmodified subjectname");
+ }
+
+ if (subject != null) req.put(SUBJECTNAME, subject);
+
+ if (key == null || subject == null) {
+ // log
+ //throw new ERegistrationException(RegistrationResources.ERROR_MALFORMED_P10);
+ }
+
+
+
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+
+ certInfo.set(X509CertInfo.SUBJECT,
+ new CertificateSubjectName(subject));
+
+ certInfo.set(X509CertInfo.KEY,
+ new CertificateX509Key(key));
+
+ CertificateExtensions ext = new CertificateExtensions();
+
+ if (kue != null) {
+ ext.set(KeyUsageExtension.NAME, kue);
+ }
+
+ // add subjectAltName extension, if present
+ if (sane != null) {
+ ext.set(SubjectAlternativeNameExtension.NAME, sane);
+ }
+
+ certInfo.set(X509CertInfo.EXTENSIONS,ext);
+
+ req.put(CERTINFO, certInfo);
+ } catch (Exception e) {
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ return ;
+ } // NEED TO FIX
+ }
+
+
+ private SubjectAlternativeNameExtension makeDefaultSubjectAltName(Hashtable ht) {
+
+ // if no subjectaltname extension was requested, we try to make it up
+ // from some of the elements of the subject name
+
+ int itemCount = ht.size();
+ GeneralNameInterface[] gn = new GeneralNameInterface[ht.size()];
+
+ itemCount = 0;
+ Enumeration en = ht.keys();
+ while (en.hasMoreElements()) {
+ String key = (String) en.nextElement();
+ if (key.equals(SANE_DNSNAME)) {
+ gn[itemCount++] = new DNSName((String)ht.get(key));
+ }
+ if (key.equals(SANE_IPADDRESS)) {
+ gn[itemCount++] = new IPAddressName((String)ht.get(key));
+ }
+ }
+
+ try {
+ return new SubjectAlternativeNameExtension( new GeneralNames(gn) );
+ } catch (Exception e) {
+ log(ILogger.LL_INFO, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_SUBJ_ALT_NAME",
+ e.getMessage()));
+ return null;
+ }
+ }
+
+
+
+ // Perform authentication
+
+ /*
+ * if the authentication is set up for CEP, and the user provides
+ * some credential, an attempt is made to authenticate the user
+ * If this fails, this method will return true
+ * If it is sucessful, this method will return true and
+ * an authtoken will be in the request
+ *
+ * If authentication is not configured, this method will
+ * return false. The request will be processed in the usual
+ * way, but no authtoken will be in the request.
+ *
+ * In other word, this method returns true if the request
+ * should be aborted, false otherwise.
+ */
+
+ private boolean authenticateUser(CRSPKIMessage req) {
+ boolean authenticationFailed = true;
+
+ if (mAuthManagerName == null) {
+ return false;
+ }
+
+ String password = (String)req.get(AUTH_PASSWORD);
+
+ AuthCredentials authCreds = (AuthCredentials)req.get(AUTH_CREDS);
+
+ if (authCreds == null) {
+ authCreds = new AuthCredentials();
+ }
+
+ // authtoken starts as null
+ AuthToken token = null;
+
+ if (password != null && !password.equals("")) {
+ try {
+ authCreds.set(AUTH_PASSWORD,password);
+ } catch (Exception e) {}
+ }
+
+
+ try {
+ token = (AuthToken)mAuthSubsystem.authenticate(authCreds,mAuthManagerName);
+ authCreds.delete(AUTH_PASSWORD);
+ // if we got here, the authenticate call must not have thrown
+ // an exception
+ authenticationFailed = false;
+ }
+ catch (EInvalidCredentials ex) {
+ // Invalid credentials - we must reject the request
+ authenticationFailed = true;
+ }
+ catch (EMissingCredential mc) {
+ // Misssing credential - we'll log, and process manually
+ authenticationFailed = false;
+ }
+ catch (EBaseException ex) {
+ // If there's some other error, we'll reject
+ // So, we just continue on, - AUTH_TOKEN will not be set.
+ }
+
+ if (token != null) {
+ req.put(AUTH_TOKEN,token);
+ }
+
+ return authenticationFailed;
+ }
+
+ private boolean areFingerprintsEqual(IRequest req, Hashtable fingerprints)
+ {
+
+ Hashtable old_fprints = req.getExtDataInHashtable(IRequest.FINGERPRINTS);
+ if (old_fprints == null) { return false; }
+
+ byte[] old_md5 = CMS.AtoB((String) old_fprints.get("MD5"));
+ byte[] new_md5 = (byte[]) fingerprints.get("MD5");
+
+ if (old_md5.length != new_md5.length) return false;
+
+ for (int i=0;i<old_md5.length; i++) {
+ if (old_md5[i] != new_md5[i]) return false;
+ }
+ return true;
+ }
+
+ public X509CertImpl handlePKCSReq(HttpServletRequest httpReq,
+ IRequest cmsRequest, CRSPKIMessage req,
+ CRSPKIMessage crsResp, CryptoContext cx)
+ throws ServletException,
+ CryptoManager.NotInitializedException,
+ CRSFailureException {
+
+ try {
+ unwrapPKCS10(req,cx);
+ Hashtable fingerprints = makeFingerPrints(req);
+
+ if (cmsRequest != null) {
+ if (areFingerprintsEqual(cmsRequest, fingerprints)) {
+ CMS.debug("created response from request");
+ return makeResponseFromRequest(req,crsResp,cmsRequest);
+ }
+ else {
+ CMS.debug("duplicated transaction id");
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_DUP_TRANS_ID"));
+ crsResp.setFailInfo(crsResp.mFailInfo_badRequest);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ return null;
+ }
+ }
+
+ getDetailFromRequest(req,crsResp);
+ boolean authFailed = authenticateUser(req);
+
+ if (authFailed) {
+ CMS.debug("authentication failed");
+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_AUTH"));
+ crsResp.setFailInfo(crsResp.mFailInfo_badIdentity);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+
+
+ // perform audit log
+ String auditMessage = CMS.getLogMessage(
+ "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5",
+ httpReq.getRemoteAddr(),
+ ILogger.FAILURE,
+ req.getTransactionID(),
+ "CRSEnrollment",
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+ ILogger signedAuditLogger = CMS.getSignedAuditLogger();
+ if (signedAuditLogger != null) {
+ signedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null, ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY, auditMessage);
+ }
+
+ return null;
+ }
+ else {
+ IRequest ireq = postRequest(httpReq, req,crsResp);
+
+
+ CMS.debug("created response");
+ return makeResponseFromRequest(req,crsResp, ireq);
+ }
+ } catch (CryptoContext.CryptoContextException e) {
+ CMS.debug("failed to decrypt the request " + e);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ENROLL_FAIL_NO_DECRYPT_PKCS10",
+ e.getMessage()));
+ crsResp.setFailInfo(crsResp.mFailInfo_badMessageCheck);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ } catch (EBaseException e) {
+ CMS.debug("operation failure - " + e);
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERNOLL_FAIL_NO_NEW_REQUEST_POSTED",
+ e.getMessage()));
+ crsResp.setFailInfo(crsResp.mFailInfo_internalCAError);
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ }
+ return null;
+ }
+
+
+////// post the request
+
+/*
+ needed:
+
+ token (authtoken)
+ certInfo
+ fingerprints x
+ req.transactionID
+ crsResp
+*/
+
+private IRequest postRequest(HttpServletRequest httpReq, CRSPKIMessage req, CRSPKIMessage crsResp)
+throws EBaseException {
+ X500Name subject = (X500Name)req.get(SUBJECTNAME);
+
+ if (mCreateEntry) {
+ if (subject == null) {
+ CMS.debug( "CRSEnrollment::postRequest() - subject is null!" );
+ return null;
+ }
+ createEntry(subject.toString());
+ }
+
+ // use profile framework to handle SCEP
+ if (mProfileId != null) {
+ PKCS10 pkcs10data = (PKCS10)req.getP10();
+ String pkcs10blob = CMS.BtoA(pkcs10data.toByteArray());
+
+ // XXX authentication handling
+ CMS.debug("Found profile=" + mProfileId);
+ IProfile profile = mProfileSubsystem.getProfile(mProfileId);
+ if (profile == null) {
+ CMS.debug("profile " + mProfileId + " not found");
+ return null;
+ }
+ IProfileContext ctx = profile.createContext();
+
+ IProfileAuthenticator authenticator = null;
+ try {
+ CMS.debug("Retrieving authenticator");
+ authenticator = profile.getAuthenticator();
+ if (authenticator == null) {
+ CMS.debug("No authenticator Found");
+ } else {
+ CMS.debug("Got authenticator=" + authenticator.getClass().getName());
+ }
+ } catch (EProfileException e) {
+ // authenticator not installed correctly
+ }
+
+ 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(httpReq));
+
+ String p10Password = getPasswordFromP10(pkcs10data);
+ AuthCredentials credentials = new AuthCredentials();
+ credentials.set("UID", httpReq.getRemoteAddr());
+ credentials.set("PWD", p10Password);
+
+ if (authenticator == null) {
+ // XXX - to help caRouterCert to work, we need to
+ // add authentication to caRouterCert
+ authToken = new AuthToken(null);
+ } else {
+ authToken = authenticate(credentials, authenticator, httpReq);
+ }
+
+ IRequest reqs[] = null;
+ CMS.debug("CRSEnrollment: Creating profile requests");
+ ctx.set(IEnrollProfile.CTX_CERT_REQUEST_TYPE, "pkcs10");
+ ctx.set(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob);
+ Locale locale = Locale.getDefault();
+ reqs = profile.createRequests(ctx, locale);
+ if (reqs == null) {
+ CMS.debug("CRSEnrollment: No request has been created");
+ return null;
+ } else {
+ CMS.debug("CRSEnrollment: Request (" + reqs.length + ") have been created");
+ }
+ // set transaction id
+ reqs[0].setSourceId(req.getTransactionID());
+ reqs[0].setExtData("profile", "true");
+ reqs[0].setExtData("profileId", mProfileId);
+ reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST_TYPE, IEnrollProfile.REQ_TYPE_PKCS10);
+ reqs[0].setExtData(IEnrollProfile.CTX_CERT_REQUEST, pkcs10blob);
+ reqs[0].setExtData("requestor_name", "");
+ reqs[0].setExtData("requestor_email", "");
+ reqs[0].setExtData("requestor_phone", "");
+ reqs[0].setExtData("profileRemoteHost", httpReq.getRemoteHost());
+ reqs[0].setExtData("profileRemoteAddr", httpReq.getRemoteAddr());
+ reqs[0].setExtData("profileApprovedBy", profile.getApprovedBy());
+
+ CMS.debug("CRSEnrollment: Populating inputs");
+ profile.populateInput(ctx, reqs[0]);
+ CMS.debug("CRSEnrollment: Populating requests");
+ profile.populate(reqs[0]);
+
+ CMS.debug("CRSEnrollment: Submitting request");
+ profile.submit(authToken, reqs[0]);
+ CMS.debug("CRSEnrollment: Done submitting request");
+ profile.getRequestQueue().markAsServiced(reqs[0]);
+ CMS.debug("CRSEnrollment: Request marked as serviced");
+
+ return reqs[0];
+
+ }
+
+ IRequestQueue rq = ca.getRequestQueue();
+ IRequest pkiReq = rq.newRequest(IRequest.ENROLLMENT_REQUEST);
+
+ AuthToken token = (AuthToken) req.get(AUTH_TOKEN);
+ if (token != null) {
+ pkiReq.setExtData(IRequest.AUTH_TOKEN,token);
+ }
+
+ pkiReq.setExtData(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE, IRequest.CEP_CERT);
+ X509CertInfo certInfo = (X509CertInfo) req.get(CERTINFO);
+ pkiReq.setExtData(IRequest.CERT_INFO, new X509CertInfo[] { certInfo } );
+ pkiReq.setExtData("cepsubstore", mSubstoreName);
+
+ try {
+ String chpwd = (String)req.get(ChallengePassword.NAME);
+ if (chpwd != null) {
+ pkiReq.setExtData("challengePhrase",
+ chpwd );
+ }
+ } catch (Exception pwex) {
+ }
+
+ Hashtable fingerprints = (Hashtable)req.get(IRequest.FINGERPRINTS);
+ if (fingerprints.size() > 0) {
+ Hashtable encodedPrints = new Hashtable(fingerprints.size());
+ Enumeration e = fingerprints.keys();
+ while (e.hasMoreElements()) {
+ String key = (String)e.nextElement();
+ byte[] value = (byte[])fingerprints.get(key);
+ encodedPrints.put(key, CMS.BtoA(value));
+ }
+ pkiReq.setExtData(IRequest.FINGERPRINTS, encodedPrints);
+ }
+
+ pkiReq.setSourceId(req.getTransactionID());
+
+ rq.processRequest(pkiReq);
+
+ crsResp.setPKIStatus(crsResp.mStatus_SUCCESS);
+
+ mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+ AuditFormat.LEVEL,
+ AuditFormat.ENROLLMENTFORMAT,
+ new Object[] {
+ pkiReq.getRequestId(),
+ AuditFormat.FROMROUTER,
+ mAuthManagerName == null ? AuditFormat.NOAUTH : mAuthManagerName,
+ "pending",
+ subject ,
+ ""}
+ );
+
+ return pkiReq;
+ }
+
+
+
+ public Hashtable makeFingerPrints(CRSPKIMessage req) {
+ Hashtable fingerprints = new Hashtable();
+
+ MessageDigest md;
+ String[] hashes = new String[] {"MD2", "MD5", "SHA1", "SHA256", "SHA512"};
+ PKCS10 p10 = (PKCS10)req.getP10();
+
+ for (int i=0;i<hashes.length;i++) {
+ try {
+ md = MessageDigest.getInstance(hashes[i]);
+ md.update(p10.getCertRequestInfo());
+ fingerprints.put(hashes[i],md.digest());
+ }
+ catch (NoSuchAlgorithmException nsa) {}
+ }
+
+ if (fingerprints != null) {
+ req.put(IRequest.FINGERPRINTS,fingerprints);
+ }
+ return fingerprints;
+ }
+
+
+ // Take a look to see if the request was successful, and fill
+ // in the response message
+
+
+ private X509CertImpl makeResponseFromRequest(CRSPKIMessage crsReq, CRSPKIMessage crsResp,
+ IRequest pkiReq)
+ {
+
+ X509CertImpl issuedCert=null;
+
+ RequestStatus status = pkiReq.getRequestStatus();
+
+ String profileId = pkiReq.getExtDataInString("profileId");
+ if (profileId != null) {
+ CMS.debug("CRSEnrollment: Found profile request");
+ X509CertImpl cert =
+ pkiReq.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
+ if (cert == null) {
+ CMS.debug("CRSEnrollment: No certificate has been found");
+ } else {
+ CMS.debug("CRSEnrollment: Found certificate");
+ }
+ crsResp.setPKIStatus(crsResp.mStatus_SUCCESS);
+ return cert;
+ }
+
+
+ if ( status.equals(RequestStatus.COMPLETE)) {
+ Integer success = pkiReq.getExtDataInInteger(IRequest.RESULT);
+
+
+ if (success.equals(IRequest.RES_SUCCESS)) {
+ // The cert was issued, lets send it back to the router
+ X509CertImpl[] issuedCertBuf =
+ pkiReq.getExtDataInCertArray(IRequest.ISSUED_CERTS);
+ if (issuedCertBuf == null || issuedCertBuf.length == 0) {
+ // writeError("Internal Error: Bad operation",httpReq,httpResp);
+ CMS.debug( "CRSEnrollment::makeResponseFromRequest() - " +
+ "Bad operation" );
+ return null;
+ }
+ issuedCert = issuedCertBuf[0];
+ crsResp.setPKIStatus(crsResp.mStatus_SUCCESS);
+
+ }
+ else { // status is not 'success' - there must've been a problem
+
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ crsResp.setFailInfo(crsResp.mFailInfo_badAlg);
+ }
+ }
+ else if (status.equals(RequestStatus.REJECTED_STRING) ||
+ status.equals(RequestStatus.CANCELED_STRING)) {
+ crsResp.setPKIStatus(crsResp.mStatus_FAILURE);
+ crsResp.setFailInfo(crsResp.mFailInfo_badRequest);
+ }
+ else { // not complete
+ crsResp.setPKIStatus(crsResp.mStatus_PENDING);
+ }
+
+ return issuedCert;
+ }
+
+
+
+
+
+
+ /**
+ * This needs to be re-written to log the messages to the system log, since there
+ * will be no visual webpage feedback for the user. (he's using a router)
+ */
+
+ private void writeError(String errMsg, HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws IOException
+ {
+ }
+
+
+ protected String hashPassword(String pwd) {
+ String salt = "lala123";
+ byte[] pwdDigest = mSHADigest.digest((salt+pwd).getBytes());
+ String b64E = com.netscape.osutil.OSUtil.BtoA(pwdDigest);
+ return "{SHA}"+b64E;
+ }
+
+
+
+
+ /**
+ * Make the CRSPKIMESSAGE response
+ */
+
+
+ private void processCertRep(CryptoContext cx,
+ X509CertImpl issuedCert,
+ CRSPKIMessage crsResp,
+ CRSPKIMessage crsReq)
+ throws CRSFailureException {
+ byte[] msgdigest = null;
+ byte[] encryptedDesKey = null;
+
+ try {
+ if (issuedCert != null) {
+
+ SymmetricKey sk;
+ SymmetricKey skinternal;
+
+ KeyGenAlgorithm kga = KeyGenAlgorithm.DES;
+ EncryptionAlgorithm ea = EncryptionAlgorithm.DES_CBC;
+ if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) {
+ kga = KeyGenAlgorithm.DES3;
+ ea = EncryptionAlgorithm.DES3_CBC;
+ }
+
+ // 1. Make the Degenerated PKCS7 with the recipient's certificate in it
+
+ byte toBeEncrypted[] =
+ crsResp.makeSignedRep(1, // version
+ issuedCert.getEncoded()
+ );
+
+ // 2. Encrypt the above byte array with a new random DES key
+
+ sk = cx.getDESKeyGenerator().generate();
+
+ skinternal = cx.getInternalToken().getKeyGenerator(kga).clone(sk);
+
+ byte[] padded = Cipher.pad(toBeEncrypted, ea.getBlockSize());
+
+
+ // This should be changed to generate proper DES IV.
+
+ Cipher cipher = cx.getInternalToken().getCipherContext(ea);
+ IVParameterSpec desIV =
+ new IVParameterSpec(new byte[]{
+ (byte)0xff, (byte)0x00,
+ (byte)0xff, (byte)0x00,
+ (byte)0xff, (byte)0x00,
+ (byte)0xff, (byte)0x00 } );
+
+ cipher.initEncrypt(sk,desIV);
+ byte[] encryptedData = cipher.doFinal(padded);
+
+ crsResp.makeEncryptedContentInfo(desIV.getIV(),encryptedData, mEncryptionAlgorithm);
+
+ // 3. Extract the recipient's public key
+
+ PublicKey rcpPK = crsReq.getSignerPublicKey();
+
+
+ // 4. Encrypt the DES key with the public key
+
+ // we have to move the key onto the interal token.
+ //skinternal = cx.getInternalKeyStorageToken().cloneKey(sk);
+ skinternal = cx.getInternalToken().cloneKey(sk);
+
+ KeyWrapper kw = cx.getInternalKeyWrapper();
+ kw.initWrap(rcpPK, null);
+ encryptedDesKey = kw.wrap(skinternal);
+
+ crsResp.setRcpIssuerAndSerialNumber(crsReq.getSgnIssuerAndSerialNumber());
+ crsResp.makeRecipientInfo(0, encryptedDesKey );
+
+ }
+
+
+ byte[] ed = crsResp.makeEnvelopedData(0);
+
+ // 7. Make Digest of SignedData Content
+ MessageDigest md = MessageDigest.getInstance(mHashAlgorithm);
+ msgdigest = md.digest(ed);
+
+ crsResp.setMsgDigest(msgdigest);
+
+ }
+
+ catch (Exception e) {
+ throw new CRSFailureException("Failed to create inner response to CEP message: "+e.getMessage());
+ }
+
+
+ // 5. Make a RecipientInfo
+
+ // The issuer name & serial number here, should be that of
+ // the EE's self-signed Certificate
+ // [I can get it from the req blob, but later, I should
+ // store the recipient's self-signed certificate with the request
+ // so I can get at it later. I need to do this to support
+ // 'PENDING']
+
+
+ try {
+
+ // 8. Make Authenticated Attributes
+ // we can just pull the transaction ID out of the request.
+ // Later, we will have to put it out of the Request queue,
+ // so we can support PENDING
+ crsResp.setTransactionID(crsReq.getTransactionID());
+ // recipientNonce and SenderNonce have already been set
+
+ crsResp.makeAuthenticatedAttributes();
+ // crsResp.makeAuthenticatedAttributes_old();
+
+
+
+ // now package up the rest of the SignerInfo
+ {
+ byte[] signingcertbytes = cx.getSigningCert().getEncoded();
+
+
+ Certificate.Template sgncert_t = new Certificate.Template();
+ Certificate sgncert =
+ (Certificate) sgncert_t.decode(new ByteArrayInputStream(signingcertbytes));
+
+ IssuerAndSerialNumber sgniasn =
+ new IssuerAndSerialNumber(sgncert.getInfo().getIssuer(),
+ sgncert.getInfo().getSerialNumber());
+
+ crsResp.setSgnIssuerAndSerialNumber(sgniasn);
+
+ // 10. Make SignerInfo
+ crsResp.makeSignerInfo(1, cx.getPrivateKey(), mHashAlgorithm);
+
+ // 11. Make SignedData
+ crsResp.makeSignedData(1, signingcertbytes, mHashAlgorithm);
+
+ crsResp.debug();
+ }
+ }
+ catch (Exception e) {
+ throw new CRSFailureException("Failed to create outer response to CEP request: "+e.getMessage());
+ }
+
+
+ // if debugging, dump out the response into a file
+
+ }
+
+
+
+ class CryptoContext {
+ private CryptoManager cm;
+ private CryptoToken internalToken;
+ private CryptoToken keyStorageToken;
+ private CryptoToken internalKeyStorageToken;
+ private KeyGenerator DESkg;
+ private Enumeration externalTokens = null;
+ private org.mozilla.jss.crypto.X509Certificate signingCert;
+ private org.mozilla.jss.crypto.PrivateKey signingCertPrivKey;
+ private int signingCertKeySize = 0;
+
+
+ class CryptoContextException extends Exception {
+ public CryptoContextException() { super(); }
+ public CryptoContextException(String s) { super(s); }
+ }
+
+ public CryptoContext()
+ throws CryptoContextException
+ {
+ try {
+ KeyGenAlgorithm kga = KeyGenAlgorithm.DES;
+ if (mEncryptionAlgorithm != null && mEncryptionAlgorithm.equals("DES3")) {
+ kga = KeyGenAlgorithm.DES3;
+ }
+ cm = CryptoManager.getInstance();
+ internalToken = cm.getInternalCryptoToken();
+ DESkg = internalToken.getKeyGenerator(kga);
+ if (mTokenName.equalsIgnoreCase(Constants.PR_INTERNAL_TOKEN) ||
+ mTokenName.equalsIgnoreCase("Internal Key Storage Token") ||
+ mTokenName.length() == 0) {
+ keyStorageToken = cm.getInternalKeyStorageToken();
+ internalKeyStorageToken = keyStorageToken;
+ CMS.debug("CRSEnrollment: CryptoContext: internal token name: '"+mTokenName+"'");
+ } else {
+ keyStorageToken = cm.getTokenByName(mTokenName);
+ internalKeyStorageToken = null;
+ mNickname = mTokenName + ":" + mNickname;
+ CMS.debug("CRSEnrollment: CryptoContext: token name: "+mTokenName+"'");
+ }
+ CMS.debug("CRSEnrollment: CryptoContext: mNickname: '"+mNickname+"'");
+ if (!mUseCA && internalKeyStorageToken == null) {
+ PasswordCallback cb = CMS.getPasswordCallback();
+ keyStorageToken.login(cb); // ONE_TIME by default.
+ }
+ signingCert = cm.findCertByNickname(mNickname);
+ signingCertPrivKey = cm.findPrivKeyByCert(signingCert);
+ byte[] encPubKeyInfo = signingCert.getPublicKey().getEncoded();
+ SEQUENCE.Template outer = SEQUENCE.getTemplate();
+ outer.addElement( ANY.getTemplate() ); // algid
+ outer.addElement( BIT_STRING.getTemplate() );
+ SEQUENCE outerSeq = (SEQUENCE) ASN1Util.decode(outer, encPubKeyInfo);
+ BIT_STRING bs = (BIT_STRING) outerSeq.elementAt(1);
+ byte[] encPubKey = bs.getBits();
+ if( bs.getPadCount() != 0) {
+ throw new CryptoContextException("Internal error: Invalid Public key. Not an integral number of bytes.");
+ }
+ SEQUENCE.Template inner = new SEQUENCE.Template();
+ inner.addElement( INTEGER.getTemplate());
+ inner.addElement( INTEGER.getTemplate());
+ SEQUENCE pubKeySeq = (SEQUENCE) ASN1Util.decode(inner, encPubKey);
+ INTEGER modulus = (INTEGER) pubKeySeq.elementAt(0);
+ signingCertKeySize = modulus.bitLength();
+
+ try {
+ FileOutputStream fos = new FileOutputStream("pubkey.der");
+ fos.write(signingCert.getPublicKey().getEncoded());
+ fos.close();
+ } catch (Exception e) {}
+
+ }
+ catch (InvalidBERException e) {
+ throw new CryptoContextException("Internal Error: Bad internal Certificate Representation. Not a valid RSA-signed certificate");
+ }
+ catch (CryptoManager.NotInitializedException e) {
+ throw new CryptoContextException("Crypto Manager not initialized");
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new CryptoContextException("Cannot create DES key generator");
+ }
+ catch (ObjectNotFoundException e) {
+ throw new CryptoContextException("Certificate not found: "+ca.getNickname());
+ }
+ catch (TokenException e) {
+ throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage());
+ }
+ catch (NoSuchTokenException e) {
+ throw new CryptoContextException("Crypto Token not found: "+e.getMessage());
+ }
+ catch (IncorrectPasswordException e) {
+ throw new CryptoContextException("Incorrect Password.");
+ }
+ }
+
+
+ public KeyGenerator getDESKeyGenerator() {
+ return DESkg;
+ }
+
+ public CryptoToken getInternalToken() {
+ return internalToken;
+ }
+
+ public void setExternalTokens( Enumeration tokens ) {
+ externalTokens = tokens;
+ }
+
+ public Enumeration getExternalTokens() {
+ return externalTokens;
+ }
+
+ public CryptoToken getInternalKeyStorageToken() {
+ return internalKeyStorageToken;
+ }
+
+ public CryptoToken getKeyStorageToken() {
+ return keyStorageToken;
+ }
+
+ public CryptoManager getCryptoManager() {
+ return cm;
+ }
+
+ public KeyWrapper getKeyWrapper()
+ throws CryptoContextException {
+ try {
+ return signingCertPrivKey.getOwningToken().getKeyWrapper(KeyWrapAlgorithm.RSA);
+ }
+ catch (TokenException e) {
+ throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage());
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new CryptoContextException(e.getMessage());
+ }
+ }
+
+ public KeyWrapper getInternalKeyWrapper()
+ throws CryptoContextException {
+ try {
+ return getInternalToken().getKeyWrapper(KeyWrapAlgorithm.RSA);
+ }
+ catch (TokenException e) {
+ throw new CryptoContextException("Problem with Crypto Token: "+e.getMessage());
+ }
+ catch (NoSuchAlgorithmException e) {
+ throw new CryptoContextException(e.getMessage());
+ }
+ }
+
+ public org.mozilla.jss.crypto.PrivateKey getPrivateKey() {
+ return signingCertPrivKey;
+ }
+
+ public org.mozilla.jss.crypto.X509Certificate getSigningCert() {
+ return signingCert;
+ }
+
+ }
+
+
+ /* General failure. The request/response cannot be processed. */
+
+
+ class CRSFailureException extends Exception {
+ public CRSFailureException() { super(); }
+ public CRSFailureException(String s) { super(s); }
+ }
+
+ class CRSInvalidSignatureException extends Exception {
+ public CRSInvalidSignatureException() { super(); }
+ public CRSInvalidSignatureException(String s) { super(s); }
+ }
+
+
+
+ class CRSPolicyException extends Exception {
+ public CRSPolicyException() { super(); }
+ public CRSPolicyException(String s) { super(s); }
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java
new file mode 100644
index 000000000..3e94228a1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ChallengePassword.java
@@ -0,0 +1,142 @@
+// --- 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.scep;
+
+import java.io.*;
+import java.security.*;
+import java.util.Properties;
+import java.util.*;
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.cmsutil.scep.*;
+import java.security.cert.CertificateException;
+
+/**
+ * Class for handling the decoding of a SCEP Challenge Password
+ * object. Currently this class cannot be used for encoding
+ * thus some fo the methods are unimplemented
+ */
+public class ChallengePassword implements CertAttrSet {
+
+ public static final String NAME = "ChallengePassword";
+ public static final String PASSWORD = "password";
+
+ private String cpw;
+
+
+ /**
+ * Get the password marshalled in this object
+ * @return the challenge password
+ */
+ public String toString() {
+ return cpw;
+ }
+
+ /**
+ * Create a ChallengePassword object
+ * @param stuff (must be of type byte[]) a DER-encoded by array following
+ * The ASN.1 template for ChallenegePassword specified in the SCEP
+ * documentation
+ * @throws IOException if the DER encoded byt array was malformed, or if it
+ * did not match the template
+ */
+
+ public ChallengePassword(Object stuff)
+ throws IOException {
+
+ ByteArrayInputStream is = new ByteArrayInputStream((byte[])stuff);
+ try {
+ decode(is);
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+
+ }
+
+ /**
+ * Currently Unimplemented
+ */
+ public void encode(OutputStream out)
+ throws CertificateException, IOException
+ { }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException
+ {
+ DerValue derVal = new DerValue(in);
+
+ construct(derVal);
+
+ }
+
+ private void construct(DerValue derVal) throws IOException {
+ try {
+ cpw = derVal.getPrintableString();
+ }
+ catch (NullPointerException e) {
+ cpw = "";
+ }
+ }
+
+
+ /**
+ * Currently Unimplemented
+ */
+ public void set(String name, Object obj)
+ throws CertificateException, IOException
+ { }
+
+ /**
+ * Get an attribute of this object.
+ * @param name the name of the attribute of this object to get. The only
+ * supported attribute is "password"
+ */
+ public Object get(String name)
+ throws CertificateException, IOException
+ {
+ if (name.equalsIgnoreCase(PASSWORD)) {
+ return cpw;
+ }
+ else {
+ throw new IOException("Attribute name not recognized by "+
+ "CertAttrSet: ChallengePassword");
+ }
+ }
+
+ /**
+ * Currently Unimplemented
+ */
+ public void delete(String name)
+ throws CertificateException, IOException
+ { }
+
+ /**
+ * @return an empty set of elements
+ */
+ public Enumeration getElements()
+ { return (new Hashtable()).elements();}
+
+ /**
+ * @return the String "ChallengePassword"
+ */
+ public String getName()
+ { return NAME;}
+
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java
new file mode 100644
index 000000000..616eab27b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/scep/ExtensionsRequested.java
@@ -0,0 +1,187 @@
+// --- 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.scep;
+
+import java.io.*;
+import java.security.*;
+import java.util.Properties;
+import java.util.*;
+
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import java.security.cert.CertificateException;
+import com.netscape.cmsutil.scep.*;
+
+
+public class ExtensionsRequested implements CertAttrSet {
+
+
+ public static final String NAME = "EXTENSIONS_REQUESTED";
+
+ public static final String KUE_DIGITAL_SIGNATURE = "kue_digital_signature";
+ public static final String KUE_KEY_ENCIPHERMENT = "kue_key_encipherment";
+
+ private String kue_digital_signature = "false";
+ private String kue_key_encipherment = "false";
+
+ private Vector exts = new Vector();
+
+ public ExtensionsRequested(Object stuff) throws IOException {
+ ByteArrayInputStream is = new ByteArrayInputStream((byte[]) stuff);
+
+ try {
+ decode(is);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public void encode(OutputStream out)
+ throws CertificateException, IOException
+ { }
+
+ public void decode(InputStream in)
+ throws CertificateException, IOException
+ {
+ DerValue derVal = new DerValue(in);
+
+ construct(derVal);
+ }
+
+ public void set(String name, Object obj)
+ throws CertificateException, IOException
+ { }
+
+ public Object get(String name)
+ throws CertificateException, IOException
+ {
+ if (name.equalsIgnoreCase(KUE_DIGITAL_SIGNATURE)) {
+ return kue_digital_signature;
+ }
+ if (name.equalsIgnoreCase(KUE_KEY_ENCIPHERMENT)) {
+ return kue_key_encipherment;
+ }
+
+ throw new IOException("Unsupported attribute queried");
+ }
+
+ public void delete(String name)
+ throws CertificateException, IOException
+ {
+ }
+
+ public Enumeration getElements()
+ { return (new Hashtable()).elements();}
+
+ public String getName()
+ { return NAME;}
+
+
+
+/**
+ construct - expects this in the inputstream (from the router):
+
+ 211 30 31: SEQUENCE {
+ 213 06 10: OBJECT IDENTIFIER '2 16 840 1 113733 1 9 8'
+ 225 31 17: SET {
+ 227 04 15: OCTET STRING, encapsulates {
+ 229 30 13: SEQUENCE {
+ 231 30 11: SEQUENCE {
+ 233 06 3: OBJECT IDENTIFIER keyUsage (2 5 29 15)
+ 238 04 4: OCTET STRING
+ : 03 02 05 A0
+ : }
+ : }
+ : }
+
+ or this (from IRE client):
+
+ 262 30 51: SEQUENCE {
+ 264 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 14)
+ 275 31 38: SET {
+ 277 30 36: SEQUENCE {
+ 279 30 34: SEQUENCE {
+ 281 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17)
+ 286 04 27: OCTET STRING
+ : 30 19 87 04 D0 0C 3E 6F 81 03 61 61 61 82 0C 61
+ : 61 61 2E 6D 63 6F 6D 2E 63 6F 6D
+ : }
+ : }
+ : }
+ : }
+
+
+ */
+ private void construct(DerValue dv) throws IOException {
+
+ DerInputStream stream = null;
+ DerValue[] dvs;
+
+ try { // try decoding as sequence first
+
+ stream = dv.toDerInputStream();
+
+ DerValue stream_dv = stream.getDerValue();
+ stream.reset();
+
+
+ dvs = stream.getSequence(2);
+ }
+ catch (IOException ioe) {
+ // if it failed, the outer sequence may be
+ // encapsulated in an octet string, as in the first
+ // example above
+
+ byte[] octet_string = dv.getOctetString();
+
+ // Make a new input stream from the byte array,
+ // and re-parse it as a sequence.
+
+ dv = new DerValue(octet_string);
+
+ stream = dv.toDerInputStream();
+ dvs = stream.getSequence(2);
+ }
+
+ // now, the stream will be in the correct format
+ stream.reset();
+
+ while (true) {
+ DerValue ext_dv=null;
+ try {
+ ext_dv = stream.getDerValue();
+ }
+ catch (IOException ex) {
+ break;
+ }
+
+ Extension ext = new Extension(ext_dv);
+ exts.addElement(ext);
+ }
+
+ }
+
+ public Vector getExtensions() {
+ return exts;
+ }
+
+}
+
+