summaryrefslogtreecommitdiffstats
path: root/base/common/src/com/netscape/cms/servlet/key
diff options
context:
space:
mode:
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet/key')
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java187
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java194
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java213
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java125
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java249
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java235
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java266
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GetPk12.java260
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java280
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java308
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java87
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyResource.java33
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java129
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeysResource.java23
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java91
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java529
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/SrchKey.java297
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java318
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java202
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyData.java76
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java85
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.java87
22 files changed, 4274 insertions, 0 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java b/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java
new file mode 100644
index 000000000..59b01f26a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.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.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * A class representing a recoverKey servlet. This servlet
+ * shows key information and presents a list of text boxes
+ * so that recovery agents can type in their identifiers
+ * and passwords.
+ *
+ * @version $Revision$, $Date$
+ */
+public class ConfirmRecoverBySerial extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2221819191344494389L;
+ private final static String INFO = "recoverBySerial";
+ private final static String TPL_FILE =
+ "confirmRecoverBySerial.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_M = "noOfRequiredAgents";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyRepository mKeyDB = null;
+ private IKeyService mRecoveryService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs ConfirmRecoverBySerial servlet.
+ */
+ public ConfirmRecoverBySerial() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mRecoveryService = (IKeyService) mAuthority;
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request. The format of this request is
+ * as follows:
+ * confirmRecoverBySerial?
+ * [serialNumber=<serialno>]
+ */
+ public void process(CMSRequest cmsReq) throws EBaseException {
+
+ // Note that we should try to handle all the exceptions
+ // instead of passing it up back to the servlet
+ // framework.
+
+ HttpServletRequest req = cmsReq.getHttpReq();
+ HttpServletResponse resp = cmsReq.getHttpResp();
+
+ authenticate(cmsReq);
+
+ 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 fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ BigInteger seqNum = BigInteger.ZERO;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = new BigInteger(req.getParameter(IN_SERIALNO));
+ }
+
+ // make sure this page, which contains password
+ // information, is not cache. Too bad, this is
+ // only good for NS browser, not IE specifically.
+ resp.setHeader("pragma", "no-cache");
+
+ process(argSet, header, seqNum, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Requests for a list of agent passwords.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, BigInteger seq,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ try {
+ header.addBigIntegerValue(OUT_SERIALNO, seq, 10);
+ header.addIntegerValue(OUT_M,
+ mRecoveryService.getNoOfRequiredAgents());
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(seq);
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java b/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java
new file mode 100644
index 000000000..8876d9350
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java
@@ -0,0 +1,194 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Display a specific Key Archival Request
+ * <P>
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerial extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -537957487396615246L;
+ private final static String INFO = "displayBySerial";
+ private final static String TPL_FILE = "displayBySerial.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyRepository mKeyDB = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs displayBySerial servlet.
+ */
+ public DisplayBySerial() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "displayBySerial.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber serial number of the key archival request
+ * </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;
+ }
+
+ 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"));
+ }
+
+ // Note that we should try to handle all the exceptions
+ // instead of passing it up back to the servlet
+ // framework.
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ BigInteger seqNum = BigInteger.ZERO;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = new BigInteger(req.getParameter(IN_SERIALNO));
+ }
+ process(argSet, header, seqNum, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+ }
+
+ /**
+ * Display information about a particular key.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, BigInteger seq,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(seq);
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java b/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java
new file mode 100644
index 000000000..29cc2b3b3
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java
@@ -0,0 +1,213 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Display a Specific Key Archival Request, and initiate
+ * key recovery process
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayBySerialForRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6876016034084761827L;
+ private final static String INFO = "displayBySerial";
+ private final static String TPL_FILE = "displayBySerialForRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyRepository mKeyDB = null;
+ private String mFormPath = null;
+ private IKeyService mService = null;
+
+ /**
+ * Constructor
+ */
+ public DisplayBySerialForRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "displayBySerialForRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/agent/" + mAuthority.getId() + "/" + TPL_FILE;
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ mService = (IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param serialNumber request ID of key archival request
+ * <li>http.param publicKeyData
+ * </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;
+ }
+
+ 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"));
+ }
+
+ // Note that we should try to handle all the exceptions
+ // instead of passing it up back to the servlet
+ // framework.
+
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ BigInteger seqNum = BigInteger.ZERO;
+
+ try {
+ if (req.getParameter(IN_SERIALNO) != null) {
+ seqNum = new BigInteger(req.getParameter(IN_SERIALNO));
+ }
+ process(argSet, header,
+ req.getParameter("publicKeyData"),
+ seqNum, req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println(e.toString());
+ }
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Display information about a particular key.
+ */
+ private synchronized void process(CMSTemplateParams argSet,
+ IArgBlock header, String publicKeyData, BigInteger seq,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ try {
+ header.addIntegerValue("noOfRequiredAgents",
+ mService.getNoOfRequiredAgents());
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue("keySplitting",
+ CMS.getConfigStore().getString("kra.keySplitting"));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ if (publicKeyData != null) {
+ header.addStringValue("publicKeyData",
+ publicKeyData);
+ }
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(seq);
+
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+
+ // recovery identifier
+ header.addStringValue("recoveryID", mService.getRecoveryID());
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java b/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java
new file mode 100644
index 000000000..dd224cc8a
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java
@@ -0,0 +1,125 @@
+// --- 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.key;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Retrieve Transport Certificate used to
+ * wrap Private key Archival requests
+ *
+ * @version $Revision$, $Date$
+ */
+public class DisplayTransport extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6509083753395783705L;
+ private final static String INFO = "displayTransport";
+
+ /**
+ * Constructs displayTransport servlet.
+ */
+ public DisplayTransport() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * 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 {
+
+ 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;
+ }
+
+ try {
+ IKeyRecoveryAuthority kra =
+ (IKeyRecoveryAuthority) mAuthority;
+ ITransportKeyUnit tu = kra.getTransportKeyUnit();
+ org.mozilla.jss.crypto.X509Certificate transportCert =
+ tu.getCertificate();
+
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("text/html");
+ String content = "";
+
+ content += "<HTML><PRE>";
+ String mime64 =
+ "-----BEGIN CERTIFICATE-----\n" +
+ CMS.BtoA(transportCert.getEncoded()) +
+ "-----END CERTIFICATE-----\n";
+
+ content += mime64;
+ content += "</PRE></HTML>";
+ resp.setContentType("text/html");
+ resp.getOutputStream().write(content.getBytes());
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_STREAM_TEMPLATE", e.toString()));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java b/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java
new file mode 100644
index 000000000..cd440da08
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java
@@ -0,0 +1,249 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * View the Key Recovery Request
+ *
+ * @version $Revision$, $Date$
+ */
+public class ExamineRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -953282265332774966L;
+ private final static String INFO = "examineRecovery";
+ private final static String TPL_FILE = "examineRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_UID = "uid";
+ private final static String IN_PWD = "pwd";
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_DELIVERY = "p12Delivery";
+ private final static String IN_CERT = "cert";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyService mService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs EA servlet.
+ */
+ public ExamineRecovery() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mService = (IKeyService) mAuthority;
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID recovery request ID
+ * </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;
+ }
+
+ 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 fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ EBaseException error = null;
+
+ try {
+ process(argSet, header,
+ req.getParameter("recoveryID"),
+ req, resp, locale[0]);
+ } catch (EBaseException e) {
+ error = e;
+ } catch (Exception e) {
+ error = new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ /*
+ catch (NumberFormatException e) {
+ error = eBaseException(
+
+ header.addStringValue(OUT_ERROR,
+ MessageFormatter.getLocalizedString(
+ locale[0],
+ BaseResources.class.getName(),
+ BaseResources.INTERNAL_ERROR_1,
+ e.toString()));
+ }
+ */
+
+ try {
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ ServletOutputStream out = resp.getOutputStream();
+ 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"));
+ }
+ }
+
+ /**
+ * Recovers a key. The p12 will be protected by the password
+ * provided by the administrator.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, String recoveryID,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale)
+ throws EBaseException {
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ header.addStringValue("keySplitting",
+ CMS.getConfigStore().getString("kra.keySplitting"));
+ Hashtable<String, Object> params = mService.getRecoveryParams(
+ recoveryID);
+
+ if (params == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_RECOVERY_TOKEN_FOUND_1", recoveryID));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_RECOVERY_TOKEN_FOUND", recoveryID));
+ }
+ String keyID = (String) params.get("keyID");
+ header.addStringValue("serialNumber", keyID);
+ header.addStringValue("recoveryID", recoveryID);
+
+ IKeyRepository mKeyDB =
+ ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ IKeyRecord rec = (IKeyRecord) mKeyDB.readKeyRecord(new
+ BigInteger(keyID));
+ KeyRecordParser.fillRecordIntoArg(rec, header);
+
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Error e " + e);
+ throw e;
+ }
+
+ /*
+ catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ */
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java b/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java
new file mode 100644
index 000000000..55d79b1ab
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java
@@ -0,0 +1,235 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.Credential;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Check to see if a Key Recovery Request has been approved
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetApprovalStatus extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8257339915430654983L;
+ private final static String INFO = "getApprovalStatus";
+ private final static String TPL_FILE = "getApprovalStatus.template";
+ private final static String TPL_FINISH = "finishRecovery.template";
+
+ private final static String IN_DELIVERY = "p12Delivery";
+
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_ERROR = "errorDetails";
+ private final static String OUT_STATUS = "status";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs getApprovalStatus servlet.
+ */
+ public GetApprovalStatus() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template files
+ * "getApprovalStatus.template" and "finishRecovery.template"
+ * to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ // mFormPath = "/"+authority.getId()+"/"+TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID request ID to check
+ * </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 (Exception e) {
+ // do nothing for now
+ }
+
+ if (authzToken == null) {
+ cmsReq.setStatus(CMSRequest.UNAUTHORIZED);
+ return;
+ }
+
+ CMSTemplate form = null;
+ Locale[] locale = new Locale[1];
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+ int rComplete = 0;
+
+ // get status and populate argSet
+ try {
+ String recoveryID = req.getParameter("recoveryID");
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ Hashtable<String, Object> params = mService.getRecoveryParams(recoveryID);
+
+ if (params == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_RECOVERY_TOKEN_FOUND_1", recoveryID));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_RECOVERY_TOKEN_FOUND", recoveryID));
+ }
+ header.addStringValue("serialNumber",
+ (String) params.get("keyID"));
+
+ int requiredNumber = mService.getNoOfRequiredAgents();
+
+ header.addIntegerValue("noOfRequiredAgents", requiredNumber);
+
+ Vector<Credential> dc = ((IKeyRecoveryAuthority) mService).getAppAgents(recoveryID);
+ Enumeration<Credential> agents = dc.elements();
+
+ while (agents.hasMoreElements()) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ rarg.addStringValue("agentName", agents.nextElement().getIdentifier());
+ argSet.addRepeatRecord(rarg);
+ }
+ if (dc.size() >= requiredNumber) {
+ // got all approval, return pk12
+ byte pkcs12[] = ((IKeyRecoveryAuthority) mService).getPk12(recoveryID);
+
+ if (pkcs12 != null) {
+ rComplete = 1;
+ header.addStringValue(OUT_STATUS, "complete");
+
+ /*
+ mService.destroyRecoveryParams(recoveryID);
+ try {
+ resp.setContentType("application/x-pkcs12");
+ resp.getOutputStream().write(pkcs12);
+ return;
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ MessageFormatter.getLocalizedString(
+ locale[0],
+ BaseResources.class.getName(),
+ BaseResources.INTERNAL_ERROR_1,
+ e.toString()));
+ }
+ */
+ } else if (((IKeyRecoveryAuthority) mService).getError(recoveryID) != null) {
+ // error in recovery process
+ header.addStringValue(OUT_ERROR,
+ ((IKeyRecoveryAuthority) mService).getError(recoveryID));
+ rComplete = 1;
+ } else {
+ // pk12 hasn't been created yet.
+ }
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale[0]));
+ rComplete = 1;
+ }
+
+ try {
+ if (rComplete == 1) {
+ mFormPath = "/" + ((IAuthority) mService).getId() + "/" + TPL_FINISH;
+ } else {
+ mFormPath = "/" + ((IAuthority) mService).getId() + "/" + TPL_FILE;
+ }
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ 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"));
+ }
+
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java b/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java
new file mode 100644
index 000000000..9d67cab8d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java
@@ -0,0 +1,266 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Get the recovered key in PKCS#12 format
+ * - for asynchronous key recovery only
+ *
+ */
+public class GetAsyncPk12 extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 6933634840339605800L;
+
+ private final static String INFO = "getAsyncPk12";
+
+ private final static String TPL_FILE = "finishAsyncRecovery.template";
+
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_PASSWORD_AGAIN = "p12PasswordAgain";
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private final static String OUT_STATUS = "status";
+
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS_4";
+
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE_4";
+
+ private String mFormPath = null;
+
+ /**
+ * Constructs getAsyncPk12 servlet.
+ */
+ public GetAsyncPk12() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "finishAsyncRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/agent/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param reqID request id for recovery
+ * </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();
+ String auditMessage = null;
+ String agent = null;
+ String reqID = null;
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ 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;
+ }
+
+ 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"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // get status and populate argSet
+ try {
+ reqID = req.getParameter("reqID");
+ header.addStringValue("reqID", reqID);
+
+ // only the init DRM agent can get the pkcs12
+ SessionContext sContext = SessionContext.getContext();
+
+ if (sContext != null) {
+ agent = (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ if (agent == null) {
+ CMS.debug("GetAsyncPk12::process() - agent is null!");
+ throw new EBaseException("agent is null");
+ }
+
+ String initAgent = "undefined";
+ initAgent = mService.getInitAgentAsyncKeyRecovery(reqID);
+
+ if ((initAgent.equals("undefined")) || !agent.equals(initAgent)) {
+ log(ILogger.LL_SECURITY,
+ CMS.getLogMessage("CMSGW_INVALID_AGENT_ASYNC_3",
+ reqID, initAgent));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_AGENT_ASYNC",
+ reqID, initAgent));
+ }
+
+ // The async recovery request must be in "approved" state
+ // i.e. all required # of recovery agents approved
+ if (mService.isApprovedAsyncKeyRecovery(reqID) != true) {
+ CMS.debug("GetAsyncPk12::process() - # required recovery agents not met");
+ throw new EBaseException("# required recovery agents not met");
+ }
+
+ String password = req.getParameter(IN_PASSWORD);
+ String passwordAgain = req.getParameter(IN_PASSWORD_AGAIN);
+
+ if (password == null || password.equals("")) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not found");
+ throw new EBaseException("PKCS12 password not found");
+ }
+ if (passwordAgain == null || !passwordAgain.equals(password)) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not matched");
+ throw new EBaseException("PKCS12 password not matched");
+ }
+
+ // got all approval, return pk12
+ byte pkcs12[] = mService.doKeyRecovery(reqID, password);
+
+ if (pkcs12 != null) {
+ try {
+ resp.setContentType("application/x-pkcs12");
+ resp.getOutputStream().write(pkcs12);
+ mRenderResult = false;
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,
+ agent,
+ ILogger.SUCCESS,
+ reqID,
+ "");
+
+ audit(auditMessage);
+
+ return;
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ } else if (((IKeyRecoveryAuthority) mService).getError(reqID) != null) {
+ // error in recovery process
+ header.addStringValue(OUT_ERROR,
+ ((IKeyRecoveryAuthority) mService).getError(reqID));
+ } else {
+ // pk12 hasn't been created yet. Shouldn't get here
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale[0]));
+ }
+
+ if ((agent != null) && (reqID != null)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,
+ agent,
+ ILogger.FAILURE,
+ reqID,
+ "");
+
+ audit(auditMessage);
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/GetPk12.java b/base/common/src/com/netscape/cms/servlet/key/GetPk12.java
new file mode 100644
index 000000000..96fe7c85d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GetPk12.java
@@ -0,0 +1,260 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Get the recovered key in PKCS#12 format
+ *
+ * @version $Revision$, $Date$
+ */
+public class GetPk12 extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8974964964333880697L;
+
+ private final static String INFO = "getPk12";
+
+ private final static String TPL_FILE = "finishRecovery.template";
+
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private final static String OUT_STATUS = "status";
+
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS_4";
+
+ private final static String LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE =
+ "LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE_4";
+
+ private String mFormPath = null;
+
+ /**
+ * Constructs getPk12 servlet.
+ */
+ public GetPk12() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "finishRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/agent/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID ID of request to recover
+ * </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();
+ String auditMessage = null;
+ String recoveryID = null;
+ String agent = null;
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ 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;
+ }
+
+ 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"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ // get status and populate argSet
+ try {
+ recoveryID = req.getParameter("recoveryID");
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ Hashtable<String, Object> params = mService.getRecoveryParams(recoveryID);
+
+ if (params == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_RECOVERY_TOKEN_FOUND_1", recoveryID));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_NO_RECOVERY_TOKEN_FOUND", recoveryID));
+ }
+
+ // only the init DRM agent can get the pkcs12
+ SessionContext sContext = SessionContext.getContext();
+ if (sContext != null) {
+ agent = (String) sContext.get(SessionContext.USER_ID);
+ }
+
+ if (agent == null) {
+ CMS.debug("GetPk12::process() - agent is null!");
+ throw new EBaseException("agent is null");
+ }
+
+ String initAgent = (String) params.get("agent");
+
+ if (!agent.equals(initAgent)) {
+ log(ILogger.LL_SECURITY,
+
+ CMS.getLogMessage("CMSGW_INVALID_AGENT_3",
+ recoveryID,
+ initAgent));
+ throw new ECMSGWException(
+ CMS.getUserMessage("CMS_GW_INVALID_AGENT",
+ agent, initAgent, recoveryID));
+ }
+
+ header.addStringValue("serialNumber",
+ (String) params.get("keyID"));
+
+ // got all approval, return pk12
+ byte pkcs12[] = ((IKeyRecoveryAuthority) mService).getPk12(recoveryID);
+
+ if (pkcs12 != null) {
+ mService.destroyRecoveryParams(recoveryID);
+ try {
+ resp.setContentType("application/x-pkcs12");
+ resp.getOutputStream().write(pkcs12);
+ mRenderResult = false;
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,
+ agent,
+ ILogger.SUCCESS,
+ recoveryID,
+ "");
+
+ audit(auditMessage);
+
+ return;
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ } else if (((IKeyRecoveryAuthority) mService).getError(recoveryID) != null) {
+ // error in recovery process
+ header.addStringValue(OUT_ERROR,
+ ((IKeyRecoveryAuthority) mService).getError(recoveryID));
+ } else {
+ // pk12 hasn't been created yet. Shouldn't get here
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale[0]));
+ }
+
+ if ((agent != null) && (recoveryID != null)) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,
+ agent,
+ ILogger.FAILURE,
+ recoveryID,
+ "");
+
+ audit(auditMessage);
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java b/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java
new file mode 100644
index 000000000..7c0c0cb1c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java
@@ -0,0 +1,280 @@
+// --- 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) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.key;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Approve an asynchronous key recovery request
+ *
+ */
+public class GrantAsyncRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4200111795169532676L;
+ private final static String INFO = "grantAsyncRecovery";
+ private final static String TPL_FILE = "grantAsyncRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_REQ_ID = "reqID";
+ private final static String IN_UID = "uid";
+ private final static String IN_CERT = "cert";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyService mService = null;
+ private String mFormPath = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN_4";
+
+ /**
+ * Constructs EA servlet.
+ */
+ public GrantAsyncRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'grantAsyncRecovery.template' to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param reqID request ID of the request to approve
+ * <li>http.param agentID User ID of the agent approving the request
+ *
+ * </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();
+
+ CMS.debug("GrantAsyncRecovery: process() begins");
+
+ IAuthToken authToken = authenticate(cmsReq);
+
+ AuthzToken authzToken = null;
+
+ try {
+ authzToken = authorize(mAclMethod, authToken,
+ mAuthzResourceName, "recover");
+ } 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;
+ }
+
+ 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 fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ String agentID = authToken.getInString("uid");
+ CMS.debug("GrantAsyncRecovery: process() agent uid=" + agentID);
+ CMS.debug("GrantAsyncRecovery: process() request id=" + req.getParameter("reqID"));
+ try {
+ process(argSet, header,
+ req.getParameter("reqID"),
+ agentID,
+ req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Update agent approval list
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN used whenever DRM agents login as recovery agents
+ * to approve key recovery requests
+ * </ul>
+ *
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param reqID string containing the recovery request ID
+ * @param agentID string containing the agent ID
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, String reqID,
+ String agentID,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequestID = reqID;
+ String auditAgentID = agentID;
+
+ // "normalize" the "reqID"
+ if (auditRequestID != null) {
+ auditRequestID = auditRequestID.trim();
+
+ if (auditRequestID.equals("")) {
+ auditRequestID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditRequestID = ILogger.UNIDENTIFIED;
+ }
+
+ // "normalize" the "auditAgentID"
+ if (auditAgentID != null) {
+ auditAgentID = auditAgentID.trim();
+
+ if (auditAgentID.equals("")) {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+
+ // update approving agent list
+ mService.addAgentAsyncKeyRecovery(reqID, agentID);
+
+ header.addStringValue("requestID", reqID);
+ header.addStringValue("agentID", agentID);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequestID,
+ auditAgentID);
+
+ audit(auditMessage);
+
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequestID,
+ auditAgentID);
+
+ audit(auditMessage);
+ } catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequestID,
+ auditAgentID);
+
+ audit(auditMessage);
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java b/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java
new file mode 100644
index 000000000..02aacc31c
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java
@@ -0,0 +1,308 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.kra.IKeyService;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Approve a key recovery request
+ *
+ * @version $Revision$, $Date$
+ */
+public class GrantRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 991970686415492L;
+ private final static String INFO = "grantRecovery";
+ private final static String TPL_FILE = "grantRecovery.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_UID = "uid";
+ private final static String IN_PWD = "pwd";
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_DELIVERY = "p12Delivery";
+ private final static String IN_CERT = "cert";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private IKeyService mService = null;
+ private String mFormPath = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN =
+ "LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN_4";
+
+ /**
+ * Constructs EA servlet.
+ */
+ public GrantRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * 'grantRecovery.template' to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Process the HTTP request.
+ * <ul>
+ * <li>http.param recoveryID ID of the request to approve
+ * <li>http.param agentID User ID of the agent approving the request
+ * <li>http.param agentPWD Password of the agent approving the request
+ *
+ * </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, "recover");
+ } 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;
+ }
+
+ 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 fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, fixed);
+
+ String agentID = authToken.getInString("uid");
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ agentID = req.getParameter("agentID");
+ }
+ try {
+ process(argSet, header,
+ req.getParameter("recoveryID"),
+ agentID,
+ req.getParameter("agentPWD"),
+ req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Recovers a key. The p12 will be protected by the password
+ * provided by the administrator.
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN used whenever DRM agents login as recovery agents
+ * to approve key recovery requests
+ * </ul>
+ *
+ * @param argSet CMS template parameters
+ * @param header argument block
+ * @param recoveryID string containing the recovery ID
+ * @param agentID string containing the agent ID
+ * @param agentPWD string containing the agent password
+ * @param req HTTP servlet request
+ * @param resp HTTP servlet response
+ * @param locale the system locale
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, String recoveryID,
+ String agentID, String agentPWD,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRecoveryID = recoveryID;
+ String auditAgentID = agentID;
+
+ // "normalize" the "auditRecoveryID"
+ if (auditRecoveryID != null) {
+ auditRecoveryID = auditRecoveryID.trim();
+
+ if (auditRecoveryID.equals("")) {
+ auditRecoveryID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditRecoveryID = ILogger.UNIDENTIFIED;
+ }
+
+ // "normalize" the "auditAgentID"
+ if (auditAgentID != null) {
+ auditAgentID = auditAgentID.trim();
+
+ if (auditAgentID.equals("")) {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+ } else {
+ auditAgentID = ILogger.UNIDENTIFIED;
+ }
+
+ try {
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+
+ Hashtable<String, Object> h = mService.getRecoveryParams(recoveryID);
+
+ if (h == null) {
+ header.addStringValue(OUT_ERROR,
+ "No such token found");
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+
+ return;
+ }
+ header.addStringValue("serialNumber",
+ (String) h.get("keyID"));
+
+ mService.addDistributedCredential(recoveryID, agentID, agentPWD);
+ header.addStringValue("agentID",
+ agentID);
+ header.addStringValue("recoveryID",
+ recoveryID);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+ } catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_KEY_RECOVERY_AGENT_LOGIN,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRecoveryID,
+ auditAgentID);
+
+ audit(auditMessage);
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java b/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java
new file mode 100644
index 000000000..aeee624c0
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java
@@ -0,0 +1,87 @@
+// --- 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.key;
+
+import java.util.Date;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+
+/**
+ * Output a 'pretty print' of a Key Archival record
+ *
+ * @version $Revision$, $Date$
+ */
+public class KeyRecordParser {
+
+ public final static String OUT_STATE = "state";
+ public final static String OUT_OWNER_NAME = "ownerName";
+ public final static String OUT_SERIALNO = "serialNumber";
+ public final static String OUT_KEY_ALGORITHM = "keyAlgorithm";
+ public final static String OUT_PUBLIC_KEY = "publicKey";
+ public final static String OUT_KEY_LEN = "keyLength";
+ public final static String OUT_ARCHIVED_BY = "archivedBy";
+ public final static String OUT_ARCHIVED_ON = "archivedOn";
+ public final static String OUT_RECOVERED_BY = "recoveredBy";
+ public final static String OUT_RECOVERED_ON = "recoveredOn";
+
+ /**
+ * Fills key record into argument block.
+ */
+ public static void fillRecordIntoArg(IKeyRecord rec, IArgBlock rarg)
+ throws EBaseException {
+ if (rec == null)
+ return;
+ rarg.addStringValue(OUT_STATE,
+ rec.getState().toString());
+ rarg.addStringValue(OUT_OWNER_NAME,
+ rec.getOwnerName());
+ rarg.addBigIntegerValue(OUT_SERIALNO,
+ rec.getSerialNumber(), 10);
+ rarg.addStringValue(OUT_KEY_ALGORITHM,
+ rec.getAlgorithm());
+ // Possible Enhancement: sun's BASE64Encode is not
+ // fast. We may may to have our native implmenetation.
+ IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
+
+ rarg.addStringValue(OUT_PUBLIC_KEY,
+ pp.toHexString(rec.getPublicKeyData(), 0, 20));
+ Integer keySize = rec.getKeySize();
+
+ if (keySize == null) {
+ rarg.addIntegerValue(OUT_KEY_LEN, 512);
+ } else {
+ rarg.addIntegerValue(OUT_KEY_LEN, keySize.intValue());
+ }
+ rarg.addStringValue(OUT_ARCHIVED_BY,
+ rec.getArchivedBy());
+ rarg.addLongValue(OUT_ARCHIVED_ON,
+ rec.getCreateTime().getTime() / 1000);
+ Date dateOfRevocation[] = rec.getDateOfRevocation();
+
+ if (dateOfRevocation != null) {
+ rarg.addStringValue(OUT_RECOVERED_BY,
+ "null");
+ rarg.addStringValue(OUT_RECOVERED_ON,
+ "null");
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeyResource.java b/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
new file mode 100644
index 000000000..a47c46d86
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
@@ -0,0 +1,33 @@
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import com.netscape.cms.servlet.key.model.KeyData;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+
+@Path("/key")
+public interface KeyResource {
+
+ /**
+ * Used to retrieve a key
+ * @param data
+ * @return
+ */
+ @POST
+ @Path("retrieve")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ public KeyData retrieveKey(RecoveryRequestData data);
+
+ // retrieval - used to test integration with a browser
+ @POST
+ @Path("retrieve")
+ @Produces(MediaType.TEXT_XML)
+ @Consumes({ MediaType.APPLICATION_FORM_URLENCODED})
+ public KeyData retrieveKey(MultivaluedMap<String, String> form);
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java
new file mode 100644
index 000000000..79e6ccfdb
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java
@@ -0,0 +1,129 @@
+// --- 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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.key;
+
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.key.model.KeyDAO;
+import com.netscape.cms.servlet.key.model.KeyData;
+import com.netscape.cms.servlet.request.model.KeyRequestDAO;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.KeyId;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyResourceService extends CMSResourceService implements KeyResource{
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Used to retrieve a key
+ * @param data
+ * @return
+ */
+ public KeyData retrieveKey(RecoveryRequestData data) {
+ // auth and authz
+ KeyId keyId = validateRequest(data);
+ KeyDAO dao = new KeyDAO();
+ KeyData keyData;
+ try {
+ keyData = dao.getKey(keyId, data);
+ } catch (EBaseException e) {
+ // log error
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ if (keyData == null) {
+ // no key record
+ throw new WebApplicationException(Response.Status.GONE);
+ }
+ return keyData;
+ }
+
+ // retrieval - used to test integration with a browser
+ public KeyData retrieveKey(MultivaluedMap<String, String> form) {
+ RecoveryRequestData data = new RecoveryRequestData(form);
+ return retrieveKey(data);
+ }
+
+ private KeyId validateRequest(RecoveryRequestData data) {
+
+ // confirm request exists
+ RequestId reqId = data.getRequestId();
+ if (reqId == null) {
+ // log error
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ // confirm that at least one wrapping method exists
+ // There must be at least the wrapped session key method.
+ if ((data.getTransWrappedSessionKey() == null)) {
+ // log error
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ KeyRequestDAO reqDAO = new KeyRequestDAO();
+ KeyRequestInfo reqInfo;
+ try {
+ reqInfo = reqDAO.getRequest(reqId, uriInfo);
+ } catch (EBaseException e1) {
+ // failed to get request
+ e1.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ if (reqInfo == null) {
+ // request not found
+ throw new WebApplicationException(Response.Status.GONE);
+ }
+
+ //confirm request is of the right type
+ String type = reqInfo.getRequestType();
+ if (!type.equals(IRequest.SECURITY_DATA_RECOVERY_REQUEST)) {
+ // log error
+ throw new WebApplicationException(Response.Status.BAD_REQUEST);
+ }
+
+ //confirm that agent is originator of request, else throw 401
+ // TO-DO
+
+ // confirm request is in approved state
+ String status = reqInfo.getRequestStatus();
+ if (!status.equals(RequestStatus.APPROVED.toString())) {
+ // log error
+ throw new WebApplicationException(Response.Status.UNAUTHORIZED);
+ }
+
+ return reqInfo.getKeyId();
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeysResource.java b/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
new file mode 100644
index 000000000..c93ffa4c9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
@@ -0,0 +1,23 @@
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import com.netscape.cms.servlet.key.model.KeyDataInfos;
+
+@Path("/keys")
+public interface KeysResource {
+ public static final int DEFAULT_MAXTIME = 10;
+ public static final int DEFAULT_MAXRESULTS = 100;
+
+ @GET
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+ public KeyDataInfos listKeys(@QueryParam("clientID") String clientID,
+ @QueryParam("status") String status,
+ @DefaultValue(""+DEFAULT_MAXRESULTS) @QueryParam("maxResults") int maxResults,
+ @DefaultValue(""+DEFAULT_MAXTIME) @QueryParam("maxTime") int maxTime);
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java b/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
new file mode 100644
index 000000000..a7876a6c6
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
@@ -0,0 +1,91 @@
+// --- 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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+/**
+ *
+ */
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.base.CMSResourceService;
+import com.netscape.cms.servlet.key.model.KeyDAO;
+import com.netscape.cms.servlet.key.model.KeyDataInfos;
+import com.netscape.cmsutil.ldap.LDAPUtil;
+
+/**
+ * @author alee
+ *
+ */
+public class KeysResourceService extends CMSResourceService implements KeysResource {
+
+ @Context
+ UriInfo uriInfo;
+
+ /**
+ * Used to generate list of key infos based on the search parameters
+ */
+ public KeyDataInfos listKeys(String clientID, String status, int maxResults, int maxTime) {
+ // auth and authz
+
+ // get ldap filter
+ String filter = createSearchFilter(status, clientID);
+ CMS.debug("listKeys: filter is " + filter);
+
+ KeyDAO dao = new KeyDAO();
+ KeyDataInfos infos;
+ try {
+ infos = dao.listKeys(filter, maxResults, maxTime, uriInfo);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ return infos;
+ }
+
+ private String createSearchFilter(String status, String clientID) {
+ String filter = "";
+ int matches = 0;
+
+ if ((status == null) && (clientID == null)) {
+ filter = "(serialno=*)";
+ return filter;
+ }
+
+ if (status != null) {
+ filter += "(status=" + LDAPUtil.escape(status) + ")";
+ matches ++;
+ }
+
+ if (clientID != null) {
+ filter += "(clientID=" + LDAPUtil.escape(clientID) + ")";
+ matches ++;
+ }
+
+ if (matches > 1) {
+ filter = "(&" + filter + ")";
+ }
+
+ return filter;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java b/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java
new file mode 100644
index 000000000..28ff30803
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java
@@ -0,0 +1,529 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.security.Credential;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+import com.netscape.cmsutil.util.Cert;
+
+/**
+ * A class representing a recoverBySerial servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public class RecoverBySerial extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -4544485601409309840L;
+ private final static String INFO = "recoverBySerial";
+ private final static String TPL_FILE = "recoverBySerial.template";
+
+ private final static String IN_SERIALNO = "serialNumber";
+ private final static String IN_UID = "uid";
+ private final static String IN_PWD = "pwd";
+ private final static String IN_PASSWORD = "p12Password";
+ private final static String IN_PASSWORD_AGAIN = "p12PasswordAgain";
+ private final static String IN_DELIVERY = "p12Delivery";
+ private final static String IN_CERT = "cert";
+ private final static String IN_NICKNAME = "nickname";
+
+ private final static String OUT_OP = "op";
+ private final static String OUT_SERIALNO = IN_SERIALNO;
+ private final static String OUT_RECOVERY_SUCCESS = "recoverySuccess";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_ERROR = "errorDetails";
+
+ private final static String SCHEME = "scheme";
+ private final static String HOST = "host";
+ private final static String PORT = "port";
+
+ private com.netscape.certsrv.kra.IKeyService mService = null;
+ private String mFormPath = null;
+
+ /**
+ * Constructs EA servlet.
+ */
+ public RecoverBySerial() {
+ super();
+ }
+
+ /**
+ * Initializes the servlet.
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+ mService = (com.netscape.certsrv.kra.IKeyService) mAuthority;
+
+ mTemplates.remove(CMSRequest.SUCCESS);
+ if (mOutputTemplatePath != null)
+ mFormPath = mOutputTemplatePath;
+ }
+
+ /**
+ * Returns serlvet information.
+ */
+ public String getServletInfo() {
+ return INFO;
+ }
+
+ /**
+ * Serves HTTP request. The format of this request is as follows:
+ * recoverBySerial?
+ * [serialNumber=<number>]
+ * [uid#=<uid>]
+ * [pwd#=<password>]
+ * [localAgents=yes|null]
+ * [recoveryID=recoveryID]
+ * [pkcs12Password=<password of pkcs12>]
+ * [pkcs12PasswordAgain=<password of pkcs12>]
+ * [pkcs12Delivery=<delivery mechanism for pkcs12>]
+ * [cert=<encryption certificate>]
+ */
+ 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, "recover");
+ } 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;
+ }
+
+ 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"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock fixed = CMS.createArgBlock();
+ CMSTemplateParams argSet = 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();
+
+ fixed.set(HOST, host);
+ fixed.set(PORT, Integer.valueOf(port));
+ fixed.set(SCHEME, scheme);
+
+ SessionContext ctx = null;
+
+ try {
+ String initAsyncRecovery = req.getParameter("initAsyncRecovery");
+
+ // this information is needed within the server for
+ // various signed audit log messages to report
+ ctx = SessionContext.getContext();
+
+ /*
+ When Recovery is first initiated, if it is in asynch mode,
+ no pkcs#12 password is needed.
+ The initiating agent uid will be recorded in the recovery
+ request.
+ Later, as approving agents submit their approvals, they will
+ also be listed in the request.
+ */
+ if ((initAsyncRecovery != null) &&
+ initAsyncRecovery.equalsIgnoreCase("ON")) {
+ process(form, argSet, header,
+ req.getParameter(IN_SERIALNO),
+ req.getParameter(IN_CERT),
+ req, resp, locale[0]);
+
+ int requiredNumber = mService.getNoOfRequiredAgents();
+ header.addIntegerValue("noOfRequiredAgents", requiredNumber);
+ } else {
+ String recoveryID = req.getParameter("recoveryID");
+
+ if (recoveryID != null && !recoveryID.equals("")) {
+ ctx.put(SessionContext.RECOVERY_ID,
+ req.getParameter("recoveryID"));
+ }
+ byte pkcs12[] = process(form, argSet, header,
+ req.getParameter(IN_SERIALNO),
+ req.getParameter("localAgents"),
+ req.getParameter(IN_PASSWORD),
+ req.getParameter(IN_PASSWORD_AGAIN),
+ req.getParameter(IN_CERT),
+ req.getParameter(IN_DELIVERY),
+ req.getParameter(IN_NICKNAME),
+ req, resp, locale[0]);
+
+ if (pkcs12 != null) {
+ //resp.setStatus(HttpServletResponse.SC_OK);
+ resp.setContentType("application/x-pkcs12");
+ //resp.setContentLength(pkcs12.length);
+ resp.getOutputStream().write(pkcs12);
+ mRenderResult = false;
+ return;
+ }
+ }
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ } finally {
+ SessionContext.releaseContext();
+ }
+
+ // return status page
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Async Key Recovery - request initiation
+ */
+ private void process(CMSTemplate form, CMSTemplateParams argSet,
+ IArgBlock header, String seq, String cert,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+
+ // seq is the key id
+ if (seq == null) {
+ header.addStringValue(OUT_ERROR, "sequence number not found");
+ return;
+ }
+ X509CertImpl x509cert = null;
+
+ if (cert == null || cert.trim().length() == 0) {
+ header.addStringValue(OUT_ERROR, "certificate not found");
+ return;
+ } else {
+ try {
+ x509cert = Cert.mapCert(cert);
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ }
+ if (x509cert == null) {
+ header.addStringValue(OUT_ERROR, "invalid X.509 certificate");
+ return;
+ }
+
+ SessionContext sContext = SessionContext.getContext();
+
+ try {
+ String reqID = mService.initAsyncKeyRecovery(
+ new BigInteger(seq), x509cert,
+ (String) sContext.get(SessionContext.USER_ID));
+ header.addStringValue(OUT_SERIALNO, req.getParameter(IN_SERIALNO));
+ header.addStringValue("requestID", reqID);
+ } catch (EBaseException e) {
+ String error =
+ "Failed to recover key for key id " +
+ seq + ".\nException: " + e.toString();
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, error);
+ try {
+ ((IKeyRecoveryAuthority) mService).createError(seq, error);
+ } catch (EBaseException eb) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, eb.toString());
+ }
+ }
+ return;
+ }
+
+ /**
+ * Recovers a key. The p12 will be protected by the password
+ * provided by the administrator.
+ */
+ private byte[] process(CMSTemplate form, CMSTemplateParams argSet,
+ IArgBlock header, String seq, String localAgents,
+ String password, String passwordAgain,
+ String cert, String delivery, String nickname,
+ HttpServletRequest req, HttpServletResponse resp,
+ Locale locale) {
+ if (seq == null) {
+ header.addStringValue(OUT_ERROR, "sequence number not found");
+ return null;
+ }
+ if (password == null || password.equals("")) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not found");
+ return null;
+ }
+ if (passwordAgain == null || !passwordAgain.equals(password)) {
+ header.addStringValue(OUT_ERROR, "PKCS12 password not matched");
+ return null;
+ }
+ X509CertImpl x509cert = null;
+
+ if (cert == null || cert.trim().length() == 0) {
+ // perform recovery
+ header.addStringValue(OUT_ERROR, "certificate not found");
+ return null;
+ } else {
+ try {
+ x509cert = Cert.mapCert(cert);
+ } catch (IOException e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ }
+ if (x509cert == null) {
+ header.addStringValue(OUT_ERROR, "invalid X.509 certificate");
+ return null;
+ }
+ try {
+ Credential creds[] = null;
+
+ SessionContext sContext = SessionContext.getContext();
+ String agent = null;
+
+ if (sContext != null) {
+ agent = (String) sContext.get(SessionContext.USER_ID);
+ }
+ if (CMS.getConfigStore().getBoolean("kra.keySplitting")) {
+ if (localAgents == null) {
+ String recoveryID = req.getParameter("recoveryID");
+
+ if (recoveryID == null || recoveryID.equals("")) {
+ header.addStringValue(OUT_ERROR, "No recovery ID specified");
+ return null;
+ }
+ Hashtable<String, Object> params = mService.createRecoveryParams(recoveryID);
+
+ params.put("keyID", req.getParameter(IN_SERIALNO));
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ params.put("agent", agent);
+
+ // new thread to wait for pk12
+ Thread waitThread = new WaitApprovalThread(recoveryID,
+ seq, password, x509cert, delivery, nickname,
+ SessionContext.getContext());
+
+ waitThread.start();
+ return null;
+ } else {
+ Vector<Credential> v = new Vector<Credential>();
+
+ for (int i = 0; i < mService.getNoOfRequiredAgents(); i++) {
+ String uid = req.getParameter(IN_UID + i);
+ String pwd = req.getParameter(IN_PWD + i);
+
+ if (uid != null && pwd != null && !uid.equals("") &&
+ !pwd.equals("")) {
+ v.addElement(new Credential(uid, pwd));
+ } else {
+ header.addStringValue(OUT_ERROR, "Uid(s) or password(s) are not provided");
+ return null;
+ }
+ }
+ if (v.size() != mService.getNoOfRequiredAgents()) {
+ header.addStringValue(OUT_ERROR, "Uid(s) or password(s) are not provided");
+ return null;
+ }
+ creds = new Credential[v.size()];
+ v.copyInto(creds);
+ }
+
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addBigIntegerValue(OUT_SERIALNO,
+ new BigInteger(seq), 10);
+ header.addStringValue(OUT_SERVICE_URL,
+ req.getRequestURI());
+ byte pkcs12[] = mService.doKeyRecovery(
+ new BigInteger(seq),
+ creds, password, x509cert,
+ delivery, nickname, agent);
+
+ return pkcs12;
+ } else {
+ String recoveryID = req.getParameter("recoveryID");
+
+ if (recoveryID == null || recoveryID.equals("")) {
+ header.addStringValue(OUT_ERROR, "No recovery ID specified");
+ return null;
+ }
+ Hashtable<String, Object> params = mService.createRecoveryParams(recoveryID);
+
+ params.put("keyID", req.getParameter(IN_SERIALNO));
+
+ header.addStringValue("recoveryID", recoveryID);
+
+ params.put("agent", agent);
+
+ // new thread to wait for pk12
+ Thread waitThread = new WaitApprovalThread(recoveryID,
+ seq, password, x509cert, delivery, nickname,
+ SessionContext.getContext());
+
+ waitThread.start();
+ return null;
+ }
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ } catch (Exception e) {
+ header.addStringValue(OUT_ERROR, e.toString());
+ }
+ return null;
+ }
+
+ /**
+ * Wait approval thread. Wait for recovery agents' approval
+ * exit when required number of approval received
+ */
+ final class WaitApprovalThread extends Thread {
+ String theRecoveryID = null;
+ String theSeq = null;
+ String thePassword = null;
+ X509CertImpl theCert = null;
+ String theDelivery = null;
+ String theNickname = null;
+ SessionContext theSc = null;
+
+ /**
+ * Wait approval thread constructor including thread name
+ */
+ public WaitApprovalThread(String recoveryID, String seq,
+ String password, X509CertImpl cert,
+ String delivery, String nickname, SessionContext sc) {
+ super();
+ super.setName("waitApproval." + recoveryID + "-" +
+ (Thread.activeCount() + 1));
+ theRecoveryID = recoveryID;
+ theSeq = seq;
+ thePassword = password;
+ theCert = cert;
+ theDelivery = delivery;
+ theNickname = nickname;
+ theSc = sc;
+ }
+
+ public void run() {
+ SessionContext.setContext(theSc);
+ Credential creds[] = null;
+
+ try {
+ creds = mService.getDistributedCredentials(theRecoveryID);
+ } catch (EBaseException e) {
+ String error =
+ "Failed to get required approvals for recovery id " +
+ theRecoveryID + ".\nException: " + e.toString();
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, error);
+ try {
+ ((IKeyRecoveryAuthority) mService).createError(theRecoveryID, error);
+ } catch (EBaseException eb) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, eb.toString());
+ }
+ return;
+ }
+
+ SessionContext sContext = SessionContext.getContext();
+
+ try {
+ byte pkcs12[] = mService.doKeyRecovery(
+ new BigInteger(theSeq),
+ creds, thePassword, theCert,
+ theDelivery, theNickname,
+ (String) sContext.get(SessionContext.USER_ID));
+
+ ((IKeyRecoveryAuthority) mService).createPk12(theRecoveryID, pkcs12);
+ } catch (EBaseException e) {
+ String error =
+ "Failed to recover key for recovery id " +
+ theRecoveryID + ".\nException: " + e.toString();
+
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, error);
+ try {
+ ((IKeyRecoveryAuthority) mService).createError(theRecoveryID, error);
+ } catch (EBaseException eb) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM,
+ ILogger.S_KRA, ILogger.LL_FAILURE, eb.toString());
+ }
+ }
+ return;
+ }
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/SrchKey.java b/base/common/src/com/netscape/cms/servlet/key/SrchKey.java
new file mode 100644
index 000000000..bff14e9f2
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/SrchKey.java
@@ -0,0 +1,297 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Retrieve archived keys matching search criteria
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchKey extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -6404955402865756665L;
+ private final static String TPL_FILE = "srchKey.template";
+ private final static String INFO = "srchKey";
+ private final static String PROP_MAX_SEARCH_RETURNS = "maxSearchReturns";
+
+ // input parameters
+ private final static String IN_MAXCOUNT = "maxCount";
+ private final static String IN_FILTER = "queryFilter";
+ private final static String IN_SENTINEL = "querySentinel";
+
+ // output parameters
+ private final static String OUT_FILTER = IN_FILTER;
+ private final static String OUT_MAXCOUNT = IN_MAXCOUNT;
+ private final static String OUT_SENTINEL = IN_SENTINEL;
+ private final static String OUT_OP = "op";
+ private final static String OUT_ERROR = "errorDetails";
+ private final static String OUT_ARCHIVER = "archiverName";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_TOTAL_COUNT = "totalRecordCount";
+ private final static String OUT_TEMPLATE = "templateName";
+
+ private IKeyRepository mKeyDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private int mMaxReturns = 100;
+ private int mTimeLimits = 30; /* in seconds */
+
+ /**
+ * Constructs query key servlet.
+ */
+ public SrchKey() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "srchKey.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ /* maxReturns doesn't seem to do anything useful in this
+ servlet!!! */
+ try {
+ String tmp =
+ sc.getInitParameter(PROP_MAX_SEARCH_RETURNS);
+
+ if (tmp == null)
+ mMaxReturns = 100;
+ else
+ mMaxReturns = Integer.parseInt(tmp);
+ } catch (Exception e) {
+ // do nothing
+ }
+
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ mAuthName = ((IKeyRecoveryAuthority) mAuthority).getX500Name();
+
+ 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.
+ * <ul>
+ * <li>http.param maxCount maximum number of matches to show in result
+ * <li>http.param maxResults maximum number of matches to run in ldapsearch
+ * <li>http.param queryFilter ldap-style filter to search with
+ * <li>http.param querySentinel ID of first request to show
+ * <li>http.param timeLimit number of seconds to limit ldap search to
+ * </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, "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;
+ }
+
+ 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"));
+ }
+
+ // process query if authentication is successful
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+
+ int maxCount = -1;
+ int sentinel = 0;
+ int maxResults = -1;
+ int timeLimit = -1;
+
+ try {
+ if (req.getParameter(IN_MAXCOUNT) != null) {
+ maxCount = Integer.parseInt(
+ req.getParameter(IN_MAXCOUNT));
+ }
+ if (req.getParameter(IN_SENTINEL) != null) {
+ sentinel = Integer.parseInt(
+ req.getParameter(IN_SENTINEL));
+ }
+ 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);
+ process(argSet, header, ctx, maxCount, maxResults,
+ timeLimit, sentinel,
+ req.getParameter(IN_FILTER), req, resp, locale[0]);
+ } catch (NumberFormatException e) {
+ header.addStringValue(OUT_ERROR,
+ CMS.getUserMessage(locale[0], "CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ try {
+ ServletOutputStream out = resp.getOutputStream();
+
+ resp.setContentType("text/html");
+ form.renderOutput(out, argSet);
+ } 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"));
+ }
+ cmsReq.setStatus(CMSRequest.SUCCESS);
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, IArgBlock ctx,
+ int maxCount, int maxResults, int timeLimit, int sentinel, String filter,
+ HttpServletRequest req, HttpServletResponse resp, Locale locale) {
+
+ try {
+ // Fill header
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_ARCHIVER,
+ mAuthName.toString());
+ // STRANGE: IE does not like the following:
+ // header.addStringValue(OUT_SERVICE_URL,
+ // req.getRequestURI());
+ // XXX
+ header.addStringValue(OUT_SERVICE_URL,
+ "/kra?");
+ header.addStringValue(OUT_TEMPLATE,
+ TPL_FILE);
+ header.addStringValue(OUT_FILTER,
+ filter);
+
+ if (timeLimit == -1 || timeLimit > mTimeLimits) {
+ CMS.debug("Resetting timelimit from " + timeLimit + " to " + mTimeLimits);
+ timeLimit = mTimeLimits;
+ }
+ CMS.debug("Start searching ... timelimit=" + timeLimit);
+ Enumeration<IKeyRecord> e = mKeyDB.searchKeys(filter,
+ maxResults, timeLimit);
+ int count = 0;
+
+ if (e == null) {
+ header.addStringValue(OUT_SENTINEL,
+ null);
+ } else {
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = e.nextElement();
+ // rec is null when we specify maxResults
+ // DS will return an err=4, which triggers
+ // a LDAPException.SIZE_LIMIT_ExCEEDED
+ // in DSSearchResults.java
+ if (rec != null) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ KeyRecordParser.fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ count++;
+ }
+ }
+ }
+
+ header.addIntegerValue("maxSize", mMaxReturns);
+ header.addIntegerValue(OUT_TOTAL_COUNT, count);
+ ctx.addIntegerValue(OUT_MAXCOUNT, maxCount);
+ } catch (EBaseException e) {
+ header.addStringValue(OUT_ERROR, e.toString(locale));
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java b/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java
new file mode 100644
index 000000000..95c777701
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java
@@ -0,0 +1,318 @@
+// --- 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.key;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import netscape.security.x509.X500Name;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cms.servlet.base.CMSServlet;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.ECMSGWException;
+
+/**
+ * Retrieve archived keys matching given public key material
+ *
+ *
+ * @version $Revision$, $Date$
+ */
+public class SrchKeyForRecovery extends CMSServlet {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5426987963811540460L;
+ private final static String TPL_FILE = "srchKeyForRecovery.template";
+ private final static String INFO = "srchKey";
+ private final static String PROP_MAX_SEARCH_RETURNS = "maxSearchReturns";
+
+ // input parameters
+ private final static String IN_MAXCOUNT = "maxCount";
+ private final static String IN_FILTER = "queryFilter";
+ private final static String IN_SENTINEL = "querySentinel";
+
+ // output parameters
+ private final static String OUT_FILTER = IN_FILTER;
+ private final static String OUT_MAXCOUNT = IN_MAXCOUNT;
+ private final static String OUT_SENTINEL = IN_SENTINEL;
+ private final static String OUT_OP = "op";
+ private final static String OUT_ERROR = "errorDetails";
+ private final static String OUT_ARCHIVER = "archiverName";
+ private final static String OUT_SERVICE_URL = "serviceURL";
+ private final static String OUT_TOTAL_COUNT = "totalRecordCount";
+ private final static String OUT_TEMPLATE = "templateName";
+
+ private IKeyRepository mKeyDB = null;
+ private X500Name mAuthName = null;
+ private String mFormPath = null;
+ private int mMaxReturns = 100;
+ private int mTimeLimits = 30; /* in seconds */
+
+ /**
+ * Constructs query key servlet.
+ */
+ public SrchKeyForRecovery() {
+ super();
+ }
+
+ /**
+ * initialize the servlet. This servlet uses the template file
+ * "srchKeyForRecovery.template" to process the response.
+ *
+ * @param sc servlet configuration, read from the web.xml file
+ */
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mFormPath = "/" + mAuthority.getId() + "/" + TPL_FILE;
+
+ try {
+ String tmp =
+ sc.getInitParameter(PROP_MAX_SEARCH_RETURNS);
+
+ if (tmp == null)
+ mMaxReturns = 100;
+ else
+ mMaxReturns = Integer.parseInt(tmp);
+ } catch (Exception e) {
+ // do nothing
+ }
+
+ mKeyDB = ((IKeyRecoveryAuthority) mAuthority).getKeyRepository();
+ mAuthName = ((IKeyRecoveryAuthority) mAuthority).getX500Name();
+
+ 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.
+ * <ul>
+ * <li>http.param maxCount maximum number of matches to show in result
+ * <li>http.param maxResults maximum number of matches to run in ldapsearch
+ * <li>http.param publicKeyData public key data to search on
+ * <li>http.param querySentinel ID of first request to show
+ * <li>http.param timeLimit number of seconds to limit ldap search to
+ * </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, "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;
+ }
+
+ 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"));
+ }
+
+ // process query if authentication is successful
+ IArgBlock header = CMS.createArgBlock();
+ IArgBlock ctx = CMS.createArgBlock();
+ CMSTemplateParams argSet = new CMSTemplateParams(header, ctx);
+ EBaseException error = null;
+
+ int maxCount = -1;
+ int sentinel = 0;
+ int maxResults = -1;
+ int timeLimit = -1;
+
+ try {
+ if (req.getParameter(IN_MAXCOUNT) != null) {
+ maxCount = Integer.parseInt(
+ req.getParameter(IN_MAXCOUNT));
+ }
+ if (req.getParameter(IN_SENTINEL) != null) {
+ sentinel = Integer.parseInt(
+ req.getParameter(IN_SENTINEL));
+ }
+ 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);
+ process(argSet, header, ctx, maxCount, maxResults, timeLimit, sentinel,
+ req.getParameter("publicKeyData"), req.getParameter(IN_FILTER), 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 (Exception e) {
+ error = new EBaseException(BaseResources.INTERNAL_ERROR_1, e);
+ }
+ */
+
+ try {
+ if (error == null) {
+ String xmlOutput = req.getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ outputXML(resp, argSet);
+ } else {
+ ServletOutputStream out = resp.getOutputStream();
+ 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"));
+ }
+ }
+
+ /**
+ * Process the key search.
+ */
+ private void process(CMSTemplateParams argSet,
+ IArgBlock header, IArgBlock ctx,
+ int maxCount, int maxResults, int timeLimit, int sentinel, String publicKeyData,
+ String filter,
+ HttpServletRequest req, HttpServletResponse resp, Locale locale)
+ throws EBaseException {
+
+ try {
+ // Fill header
+ header.addStringValue(OUT_OP,
+ req.getParameter(OUT_OP));
+ header.addStringValue(OUT_ARCHIVER,
+ mAuthName.toString());
+ // STRANGE: IE does not like the following:
+ // header.addStringValue(OUT_SERVICE_URL,
+ // req.getRequestURI());
+ // XXX
+ header.addStringValue(OUT_SERVICE_URL,
+ "/kra?");
+ header.addStringValue(OUT_TEMPLATE,
+ TPL_FILE);
+ header.addStringValue(OUT_FILTER,
+ filter);
+ if (publicKeyData != null) {
+ header.addStringValue("publicKeyData",
+ publicKeyData);
+ }
+
+ if (timeLimit == -1 || timeLimit > mTimeLimits) {
+ CMS.debug("Resetting timelimit from " + timeLimit + " to " + mTimeLimits);
+ timeLimit = mTimeLimits;
+ }
+ CMS.debug("Start searching ... timelimit=" + timeLimit);
+ Enumeration<IKeyRecord> e = mKeyDB.searchKeys(filter, maxResults, timeLimit);
+ int count = 0;
+
+ if (e == null) {
+ header.addStringValue(OUT_SENTINEL,
+ null);
+ } else {
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = e.nextElement();
+ // rec is null when we specify maxResults
+ // DS will return an err=4, which triggers
+ // a LDAPException.SIZE_LIMIT_ExCEEDED
+ // in DSSearchResults.java
+ if (rec != null) {
+ IArgBlock rarg = CMS.createArgBlock();
+
+ KeyRecordParser.fillRecordIntoArg(rec, rarg);
+ argSet.addRepeatRecord(rarg);
+ count++;
+ }
+ }
+ }
+
+ header.addIntegerValue("maxSize", mMaxReturns);
+ header.addIntegerValue(OUT_TOTAL_COUNT, count);
+ ctx.addIntegerValue(OUT_MAXCOUNT, maxCount);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "Error " + e);
+ throw e;
+ }
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java
new file mode 100644
index 000000000..f479c6f0d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java
@@ -0,0 +1,202 @@
+// --- 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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.key.model;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.ws.rs.Path;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.key.KeyResource;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyDAO {
+
+ private IKeyRepository repo;
+ private IKeyRecoveryAuthority kra;
+ private IRequestQueue queue;
+
+ public KeyDAO() {
+ kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" );
+ repo = kra.getKeyRepository();
+ queue = kra.getRequestQueue();
+ }
+ /**
+ * Returns list of keys meeting specified search filter.
+ * Currently, vlv searches are not used for keys.
+ *
+ * @param filter
+ * @param maxResults
+ * @param maxTime
+ * @param uriInfo
+ * @return
+ * @throws EBaseException
+ */
+ public KeyDataInfos listKeys(String filter, int maxResults, int maxTime, UriInfo uriInfo)
+ throws EBaseException {
+ List <KeyDataInfo> list = new ArrayList<KeyDataInfo>();
+ Enumeration<IKeyRecord> e = null;
+
+ e = repo.searchKeys(filter, maxResults, maxTime);
+ if (e == null) {
+ throw new EBaseException("search results are null");
+ }
+
+ while (e.hasMoreElements()) {
+ IKeyRecord rec = e.nextElement();
+ if (rec != null) {
+ list.add(createKeyDataInfo(rec, uriInfo));
+ }
+ }
+
+ KeyDataInfos ret = new KeyDataInfos();
+ ret.setKeyInfos(list);
+
+ return ret;
+ }
+
+ public KeyData getKey(KeyId keyId, RecoveryRequestData data) throws EBaseException {
+ KeyData keyData;
+
+ RequestId rId = data.getRequestId();
+
+ String transWrappedSessionKey;
+ String sessionWrappedPassphrase;
+
+ IRequest request = queue.findRequest(rId);
+
+ if (request == null) {
+ return null;
+ }
+
+ // get wrapped key
+ IKeyRecord rec = repo.readKeyRecord(keyId.toBigInteger());
+ if (rec == null) {
+ return null;
+ }
+
+ Hashtable<String, Object> requestParams = kra.getVolatileRequest(
+ request.getRequestId());
+
+ if(requestParams == null) {
+ throw new EBaseException("Can't obtain Volatile requestParams in KeyDAO.getKey!");
+ }
+
+ String sessWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_SESS_WRAPPED_DATA);
+ String passWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_PASS_WRAPPED_DATA);
+ String nonceData = (String) requestParams.get(IRequest.SECURITY_DATA_IV_STRING_OUT);
+
+ if (sessWrappedKeyData != null || passWrappedKeyData != null) {
+ //The recovery process has already placed a valid recovery
+ //package, either session key wrapped or pass wrapped, into the request.
+ //Request already has been processed.
+ keyData = new KeyData();
+
+ } else {
+ // The request has not yet been processed, let's see if the RecoveryRequestData contains
+ // the info now needed to process the recovery request.
+
+ transWrappedSessionKey = data.getTransWrappedSessionKey();
+ sessionWrappedPassphrase = data.getSessionWrappedPassphrase();
+ nonceData = data.getNonceData();
+
+ if (transWrappedSessionKey == null) {
+ //There must be at least a transWrappedSessionKey input provided.
+ //The command AND the request have provided insufficient data, end of the line.
+ throw new EBaseException("Can't retrieve key, insufficient input data!");
+ }
+
+ if (sessionWrappedPassphrase != null) {
+ requestParams.put(IRequest.SECURITY_DATA_SESS_PASS_PHRASE, sessionWrappedPassphrase);
+ }
+
+ if (transWrappedSessionKey != null) {
+ requestParams.put(IRequest.SECURITY_DATA_TRANS_SESS_KEY, transWrappedSessionKey);
+ }
+
+ if (nonceData != null) {
+ requestParams.put(IRequest.SECURITY_DATA_IV_STRING_IN, nonceData);
+ }
+
+ try {
+ // Has to be in this state or it won't go anywhere.
+ request.setRequestStatus(RequestStatus.BEGIN);
+ queue.processRequest(request);
+ } catch (EBaseException e) {
+ kra.destroyVolatileRequest(request.getRequestId());
+ throw new EBaseException(e.toString());
+ }
+
+ nonceData = null;
+ keyData = new KeyData();
+
+ sessWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_SESS_WRAPPED_DATA);
+ passWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_PASS_WRAPPED_DATA);
+ nonceData = (String) requestParams.get(IRequest.SECURITY_DATA_IV_STRING_OUT);
+
+ }
+
+ if (sessWrappedKeyData != null) {
+ keyData.setWrappedPrivateData(sessWrappedKeyData);
+ }
+ if (passWrappedKeyData != null) {
+ keyData.setWrappedPrivateData(passWrappedKeyData);
+ }
+ if (nonceData != null) {
+ keyData.setNonceData(nonceData);
+ }
+
+ kra.destroyVolatileRequest(request.getRequestId());
+
+ queue.markAsServiced(request);
+
+ return keyData;
+ }
+
+ public KeyDataInfo createKeyDataInfo(IKeyRecord rec, UriInfo uriInfo) throws EBaseException {
+ KeyDataInfo ret = new KeyDataInfo();
+
+ Path keyPath = KeyResource.class.getAnnotation(Path.class);
+ BigInteger serial = rec.getSerialNumber();
+
+ UriBuilder keyBuilder = uriInfo.getBaseUriBuilder();
+ keyBuilder.path(keyPath.value() + "/" + serial);
+ ret.setKeyURL(keyBuilder.build().toString());
+
+ return ret;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java
new file mode 100644
index 000000000..4f303e27d
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java
@@ -0,0 +1,76 @@
+// --- 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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ *
+ */
+package com.netscape.cms.servlet.key.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyData {
+ @XmlElement
+ String wrappedPrivateData;
+
+ @XmlElement
+ String nonceData;
+
+ public KeyData() {
+ // required for JAXB (defaults)
+ }
+
+ /**
+ * @return the wrappedPrivateData
+ */
+ public String getWrappedPrivateData() {
+ return wrappedPrivateData;
+ }
+
+ /**
+ * @param wrappedPrivateData the wrappedPrivateData to set
+ */
+ public void setWrappedPrivateData(String wrappedPrivateData) {
+ this.wrappedPrivateData = wrappedPrivateData;
+ }
+
+ /**
+ * @return the nonceData
+ */
+
+ public String getNonceData() {
+ return nonceData;
+ }
+
+ /**
+ * @param nonceData the nonceData to set
+ */
+
+ public void setNonceData(String nonceData) {
+ this.nonceData = nonceData;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java
new file mode 100644
index 000000000..88b31b4d1
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java
@@ -0,0 +1,85 @@
+// --- 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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+/**
+ *
+ */
+package com.netscape.cms.servlet.key.model;
+
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import com.netscape.certsrv.dbs.keydb.KeyId;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityDataInfo")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyDataInfo {
+
+ @XmlElement
+ protected String keyURL;
+
+ @XmlElement
+ protected String clientID;
+
+ public KeyDataInfo() {
+ // required for JAXB (defaults)
+ }
+
+ /**
+ * @return the keyURL
+ */
+ public String getKeyURL() {
+ return keyURL;
+ }
+
+ /**
+ * @param keyURL the keyURL to set
+ */
+ public void setKeyURL(String keyURL) {
+ this.keyURL = keyURL;
+ }
+
+ /**
+ * @return the key ID in the keyURL
+ */
+ public KeyId getKeyId() {
+ String id = keyURL.substring(keyURL.lastIndexOf("/") + 1);
+ return new KeyId(id);
+ }
+
+ /**
+ * @return the clientID
+ */
+ public String getClientID() {
+ return clientID;
+ }
+
+ /**
+ * @param clientID the clientID to set
+ */
+ public void setClientID(String clientID) {
+ this.clientID = clientID;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.java b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.java
new file mode 100644
index 000000000..b01184708
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfos.java
@@ -0,0 +1,87 @@
+// --- 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) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.key.model;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.netscape.cms.servlet.base.model.Link;
+
+@XmlRootElement(name = "SecurityDataInfos")
+public class KeyDataInfos {
+
+ protected Collection<KeyDataInfo> keyInfos;
+ protected List<Link> links;
+
+ /**
+ * @return the keyInfos
+ */
+ @XmlElementRef
+ public Collection<KeyDataInfo> getKeyInfos() {
+ return keyInfos;
+ }
+ /**
+ * @param keyInfos the keyInfos to set
+ */
+ public void setKeyInfos(Collection<KeyDataInfo> keyInfos) {
+ this.keyInfos = keyInfos;
+ }
+ /**
+ * @return the links
+ */
+ @XmlElementRef
+ public List<Link> getLinks() {
+ return links;
+ }
+ /**
+ * @param links the links to set
+ */
+ public void setLinks(List<Link> links) {
+ this.links = links;
+ }
+
+ @XmlTransient
+ public String getNext() {
+ if (links == null) {
+ return null;
+ }
+ for (Link link : links) {
+ if ("next".equals(link.getRelationship())) {
+ return link.getHref();
+ }
+ }
+ return null;
+ }
+
+ @XmlTransient
+ public String getPrevious() {
+ if (links == null) {
+ return null;
+ }
+ for (Link link : links) {
+ if ("previous".equals(link.getRelationship())) {
+ return link.getHref();
+ }
+ }
+ return null;
+ }
+}