From a4682ceae6774956461edd03b2485bbacea445f4 Mon Sep 17 00:00:00 2001 From: mharmsen Date: Tue, 4 Oct 2011 01:17:41 +0000 Subject: Bugzilla Bug #688225 - (dogtagIPAv2.1) TRACKER: of the Dogtag fixes for freeIPA 2.1 git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/tags/IPA_v2_RHEL_6_2_20111003@2252 c9f7a03b-bd48-0410-a16d-cbbf54688b0b --- .../cms/servlet/key/ConfirmRecoverBySerial.java | 189 ++++++++ .../netscape/cms/servlet/key/DisplayBySerial.java | 194 ++++++++ .../servlet/key/DisplayBySerialForRecovery.java | 212 +++++++++ .../netscape/cms/servlet/key/DisplayTransport.java | 135 ++++++ .../netscape/cms/servlet/key/ExamineRecovery.java | 251 ++++++++++ .../cms/servlet/key/GetApprovalStatus.java | 238 ++++++++++ .../com/netscape/cms/servlet/key/GetAsyncPk12.java | 241 ++++++++++ .../src/com/netscape/cms/servlet/key/GetPk12.java | 235 +++++++++ .../cms/servlet/key/GrantAsyncRecovery.java | 288 +++++++++++ .../netscape/cms/servlet/key/GrantRecovery.java | 315 ++++++++++++ .../netscape/cms/servlet/key/KeyRecordParser.java | 102 ++++ .../netscape/cms/servlet/key/RecoverBySerial.java | 528 +++++++++++++++++++++ .../src/com/netscape/cms/servlet/key/SrchKey.java | 293 ++++++++++++ .../cms/servlet/key/SrchKeyForRecovery.java | 314 ++++++++++++ 14 files changed, 3535 insertions(+) create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java (limited to 'pki/base/common/src/com/netscape/cms/servlet/key') diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java new file mode 100644 index 000000000..1fe0e2f11 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/ConfirmRecoverBySerial.java @@ -0,0 +1,189 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.base.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.authority.*; +import com.netscape.certsrv.dbs.keydb.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; + + +/** + * 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 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=] + */ + 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(); + + IAuthToken authToken = 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); + + int seqNum = -1; + + try { + if (req.getParameter(IN_SERIALNO) != null) { + seqNum = Integer.parseInt( + 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, int seq, + HttpServletRequest req, HttpServletResponse resp, + Locale locale) { + try { + header.addIntegerValue(OUT_SERIALNO, seq); + 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(new BigInteger( + Integer.toString(seq))); + + KeyRecordParser.fillRecordIntoArg(rec, header); + } catch (EBaseException e) { + header.addStringValue(OUT_ERROR, e.toString(locale)); + } + } +} diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerial.java new file mode 100644 index 000000000..fc1d9e8f4 --- /dev/null +++ b/pki/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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.authority.*; +import com.netscape.certsrv.base.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Display a specific Key Archival Request + *

+ * + * @version $Revision$, $Date$ + */ +public class DisplayBySerial extends CMSServlet { + + 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. + *

+ * + * @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); + int seqNum = -1; + + try { + if (req.getParameter(IN_SERIALNO) != null) { + seqNum = Integer.parseInt( + 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, int 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(new + BigInteger(Integer.toString(seq))); + + KeyRecordParser.fillRecordIntoArg(rec, header); + } catch (EBaseException e) { + header.addStringValue(OUT_ERROR, e.toString(locale)); + } + } +} diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java new file mode 100644 index 000000000..dcc687597 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayBySerialForRecovery.java @@ -0,0 +1,212 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.authority.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Display a Specific Key Archival Request, and initiate + * key recovery process + * + * @version $Revision$, $Date$ + */ +public class DisplayBySerialForRecovery extends CMSServlet { + + 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. + * + * + * @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); + + int seqNum = -1; + + try { + if (req.getParameter(IN_SERIALNO) != null) { + seqNum = Integer.parseInt( + 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, int 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(new + BigInteger(Integer.toString(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/pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java new file mode 100644 index 000000000..e52bb44ed --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/DisplayTransport.java @@ -0,0 +1,135 @@ +// --- 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 com.netscape.cms.servlet.base.*; +import com.netscape.cms.servlet.common.*; +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.authority.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.security.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Retrieve Transport Certificate used to + * wrap Private key Archival requests + * + * @version $Revision$, $Date$ + */ +public class DisplayTransport extends CMSServlet { + + 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 { + + 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; + } + + 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 += "
";
+            String mime64 = 
+                "-----BEGIN CERTIFICATE-----\n" + 
+                CMS.BtoA(transportCert.getEncoded()) + 
+                "-----END CERTIFICATE-----\n";
+
+            content += mime64;
+            content += "
"; + 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/pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java new file mode 100644 index 000000000..4d4607ba1 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/ExamineRecovery.java @@ -0,0 +1,251 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import java.security.cert.X509Certificate; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.authority.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.request.*; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * View the Key Recovery Request + * + * @version $Revision$, $Date$ + */ +public class ExamineRecovery extends CMSServlet { + + 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. + * + * + * @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); + int seq = -1; + + 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 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/pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java b/pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java new file mode 100644 index 000000000..36d991937 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/GetApprovalStatus.java @@ -0,0 +1,238 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import java.security.cert.X509Certificate; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.authority.*; +import com.netscape.certsrv.base.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.request.*; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.security.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Check to see if a Key Recovery Request has been approved + * + * @version $Revision$, $Date$ + */ +public class GetApprovalStatus extends CMSServlet { + + 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. + * + * + * @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 seq = -1; + int rComplete = 0; + + // get status and populate argSet + try { + String recoveryID = req.getParameter("recoveryID"); + + header.addStringValue("recoveryID", recoveryID); + + Hashtable 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 dc = ((IKeyRecoveryAuthority) mService).getAppAgents(recoveryID); + Enumeration agents = dc.elements(); + + while (agents.hasMoreElements()) { + IArgBlock rarg = CMS.createArgBlock(); + + rarg.addStringValue("agentName", ((Credential) 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/pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java b/pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java new file mode 100644 index 000000000..eb510bf59 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/GetAsyncPk12.java @@ -0,0 +1,241 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import java.security.cert.X509Certificate; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.authority.*; +import com.netscape.certsrv.base.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.request.*; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Get the recovered key in PKCS#12 format + * - for asynchronous key recovery only + * + */ +public class GetAsyncPk12 extends CMSServlet { + + 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 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. + * + * + * @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, "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); + int seq = -1; + + // get status and populate argSet + try { + String reqID = req.getParameter("reqID"); + header.addStringValue("reqID", reqID); + + // only the init DRM agent can get the pkcs12 + SessionContext sContext = SessionContext.getContext(); + String agent = null; + + 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; + 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])); + } + + 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/pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.java b/pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.java new file mode 100644 index 000000000..cd43cc8eb --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/GetPk12.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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import java.security.cert.X509Certificate; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.authority.*; +import com.netscape.certsrv.base.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.request.*; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Get the recovered key in PKCS#12 format + * + * @version $Revision$, $Date$ + */ +public class GetPk12 extends CMSServlet { + + 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 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. + * + * + * @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, "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); + int seq = -1; + + // get status and populate argSet + try { + String recoveryID = req.getParameter("recoveryID"); + + header.addStringValue("recoveryID", recoveryID); + + Hashtable 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(); + String agent = null; + + 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; + 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])); + } + + 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/pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java new file mode 100644 index 000000000..dbb5356cc --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/GrantAsyncRecovery.java @@ -0,0 +1,288 @@ +// --- 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 com.netscape.certsrv.kra.IKeyRecoveryAuthority; +import com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import java.security.cert.X509Certificate; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.authority.*; +import com.netscape.certsrv.base.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.request.*; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Approve an asynchronous key recovery request + * + */ +public class GrantAsyncRecovery extends CMSServlet { + + 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. + * + * + * @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); + + int seq = -1; + + 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 + *

+ * + *

+ * @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/pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java new file mode 100644 index 000000000..8119e4e37 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/GrantRecovery.java @@ -0,0 +1,315 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import java.security.cert.X509Certificate; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.authority.*; +import com.netscape.certsrv.base.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; + +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.request.*; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + + +/** + * Approve a key recovery request + * + * @version $Revision$, $Date$ + */ +public class GrantRecovery extends CMSServlet { + + 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. + * + * + * @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); + + int seq = -1; + + 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. + *

+ * + *

+ * @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 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/pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java b/pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java new file mode 100644 index 000000000..709f34337 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeyRecordParser.java @@ -0,0 +1,102 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.logging.*; + +/** + * 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.addIntegerValue(OUT_SERIALNO, + rec.getSerialNumber().intValue()); + 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/pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java b/pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java new file mode 100644 index 000000000..b1b46807a --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/RecoverBySerial.java @@ -0,0 +1,528 @@ +// --- 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 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; +import netscape.security.x509.X509CertImpl; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.math.BigInteger; +import java.util.Hashtable; +import java.util.Locale; +import java.util.Vector; + +/** + * A class representing a recoverBySerial servlet. + * + * @version $Revision$, $Date$ + */ +public class RecoverBySerial extends CMSServlet { + + 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=] + * [uid#=] + * [pwd#=] + * [localAgents=yes|null] + * [recoveryID=recoveryID] + * [pkcs12Password=] + * [pkcs12PasswordAgain=] + * [pkcs12Delivery=] + * [cert=] + */ + 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); + + int seq = -1; + + SessionContext ctx = null; + + try { + String localAgents = req.getParameter("localAgents"); + 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 { + ctx.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) { + 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) { + // 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 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 v = new Vector(); + + 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.addIntegerValue(OUT_SERIALNO, + Integer.parseInt(seq)); + 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 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/pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java new file mode 100644 index 000000000..21e61ed7d --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKey.java @@ -0,0 +1,293 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.authority.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + +/** + * Retrieve archived keys matching search criteria + * + * @version $Revision$, $Date$ + */ +public class SrchKey extends CMSServlet { + + 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. + *
    + *
  • http.param maxCount maximum number of matches to show in result + *
  • http.param maxResults maximum number of matches to run in ldapsearch + *
  • http.param queryFilter ldap-style filter to search with + *
  • http.param querySentinel ID of first request to show + *
  • http.param timeLimit number of seconds to limit ldap search to + *
+ * + * @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 e = mKeyDB.searchKeys(filter, + maxResults, timeLimit); + int count = 0; + + if (e == null) { + header.addStringValue(OUT_SENTINEL, + null); + } else { + while (e.hasMoreElements()) { + IKeyRecord rec = (IKeyRecord) + 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/pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java new file mode 100644 index 000000000..bd5bca4d5 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/servlet/key/SrchKeyForRecovery.java @@ -0,0 +1,314 @@ +// --- 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 com.netscape.cms.servlet.common.*; +import com.netscape.cms.servlet.base.*; + +import java.io.*; +import java.util.*; +import java.net.*; +import java.util.*; +import java.text.*; +import java.math.*; +import java.security.*; +import javax.servlet.*; +import javax.servlet.http.*; +import netscape.security.x509.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.authority.*; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.cms.servlet.*; +import com.netscape.certsrv.logging.*; +import com.netscape.certsrv.kra.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.authentication.*; +import com.netscape.certsrv.authorization.*; + +/** + * Retrieve archived keys matching given public key material + * + * + * @version $Revision$, $Date$ + */ +public class SrchKeyForRecovery extends CMSServlet { + + 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. + *
    + *
  • http.param maxCount maximum number of matches to show in result + *
  • http.param maxResults maximum number of matches to run in ldapsearch + *
  • http.param publicKeyData public key data to search on + *
  • http.param querySentinel ID of first request to show + *
  • http.param timeLimit number of seconds to limit ldap search to + *
+ * + * @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 e = mKeyDB.searchKeys(filter, maxResults, timeLimit); + int count = 0; + + if (e == null) { + header.addStringValue(OUT_SENTINEL, + null); + } else { + while (e.hasMoreElements()) { + IKeyRecord rec = (IKeyRecord) + 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; + } + } +} -- cgit