summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java')
-rw-r--r--pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java351
1 files changed, 351 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java b/pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java
new file mode 100644
index 000000000..846ea7c48
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/publish/publishers/OCSPPublisher.java
@@ -0,0 +1,351 @@
+// --- 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.publish.publishers;
+
+
+import java.net.*;
+import java.math.*;
+import java.io.*;
+import java.security.cert.*;
+import java.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import org.mozilla.jss.ssl.*;
+import org.mozilla.jss.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.publish.*;
+import com.netscape.cmsutil.http.*;
+
+
+/**
+ * This publisher writes certificate and CRL into
+ * a directory.
+ *
+ * @version $Revision$, $Date$
+ */
+public class OCSPPublisher implements ILdapPublisher, IExtendedPluginInfo {
+ private static final String PROP_HOST = "host";
+ private static final String PROP_PORT = "port";
+ private static final String PROP_PATH = "path";
+ private static final String PROP_NICK = "nickName";
+ private static final String PROP_CLIENT_AUTH_ENABLE = "enableClientAuth";
+
+ private IConfigStore mConfig = null;
+ private String mHost = null;
+ private String mPort = null;
+ private String mPath = null;
+ private String mNickname = null;
+ private boolean mClientAuthEnabled = true;
+ private ILogger mLogger = CMS.getLogger();
+
+ /**
+ * Returns the implementation name.
+ */
+ public String getImplName() {
+ return "OCSPPublisher";
+ }
+
+ /**
+ * Returns the description of the ldap publisher.
+ */
+ public String getDescription() {
+ return "This publisher writes the CRL to CMS's OCSP server.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_HOST + ";string;Host of CMS's OCSP Secure agent service",
+ PROP_PORT + ";string;Port of CMS's OCSP Secure agent service",
+ PROP_PATH + ";string;URI of CMS's OCSP Secure agent service",
+ PROP_NICK + ";string;Nickname of cert used for client authentication",
+ PROP_CLIENT_AUTH_ENABLE + ";boolean;Client Authentication enabled",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-ldappublish-publisher-ocsppublisher",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Publishes CRLs to a Online Certificate Status Manager, an OCSP responder provided by CMS."
+ };
+
+ return params;
+ }
+
+ /**
+ * Returns the current instance parameters.
+ */
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+ String host = "";
+ String port = "";
+ String path = "";
+ String nickname = "";
+ String clientAuthEnabled = "";
+
+ try {
+ host = mConfig.getString(PROP_HOST);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_HOST + "=" + host);
+ try {
+ port = mConfig.getString(PROP_PORT);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_PORT + "=" + port);
+ try {
+ path = mConfig.getString(PROP_PATH);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_PATH + "=" + path);
+ try {
+ nickname = mConfig.getString(PROP_NICK);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_NICK + "=" + nickname);
+ try {
+ clientAuthEnabled = mConfig.getString(PROP_CLIENT_AUTH_ENABLE);
+ } catch (EBaseException e) {
+ }
+ v.addElement(PROP_CLIENT_AUTH_ENABLE + "=" + clientAuthEnabled);
+ return v;
+ }
+
+ /**
+ * Returns the initial default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ IConfigStore config = CMS.getConfigStore();
+ String nickname = "";
+ // get subsystem cert nickname as default for client auth
+ try {
+ nickname = config.getString("ca.subsystem.nickname", "");
+ String tokenname = config.getString("ca.subsystem.tokenname", "");
+ if (!tokenname.equals("internal") && !tokenname.equals("Internal Key Storage Token"))
+ nickname = tokenname+":"+nickname;
+ } catch (Exception e) {
+ }
+
+
+ v.addElement(PROP_HOST + "=");
+ v.addElement(PROP_PORT + "=");
+ v.addElement(PROP_PATH + "=/ocsp/agent/ocsp/addCRL");
+ v.addElement(PROP_CLIENT_AUTH_ENABLE + "=true");
+ v.addElement(PROP_NICK + "=" + nickname);
+ return v;
+ }
+
+ /**
+ * Initializes this plugin.
+ */
+ public void init(IConfigStore config) {
+ mConfig = config;
+ try {
+ mHost = mConfig.getString(PROP_HOST, "");
+ mPort = mConfig.getString(PROP_PORT, "");
+ mPath = mConfig.getString(PROP_PATH, "");
+ mNickname = mConfig.getString(PROP_NICK, "");
+ mClientAuthEnabled = mConfig.getBoolean(PROP_CLIENT_AUTH_ENABLE, true);
+ } catch (EBaseException e) {
+ }
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ protected Socket Connect(String host, boolean secure, JssSSLSocketFactory factory)
+ {
+ Socket socket = null;
+ StringTokenizer st = new StringTokenizer(host, " ");
+ while (st.hasMoreTokens()) {
+ String hp = st.nextToken(); // host:port
+ StringTokenizer st1 = new StringTokenizer(hp, ":");
+ String h = st1.nextToken();
+ int p = Integer.parseInt(st1.nextToken());
+ try {
+ if (secure) {
+ socket = factory.makeSocket(h, p);
+ } else {
+ socket = new Socket(h, p);
+ }
+ return socket;
+ } catch (Exception e) {
+ }
+ try {
+ Thread.sleep(5000); // 5 seconds delay
+ } catch (Exception e) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Publishs a object to the ldap directory.
+ *
+ * @param conn a Ldap connection
+ * (null if LDAP publishing is not enabled)
+ * @param dn dn of the ldap entry to publish cert
+ * (null if LDAP publishing is not enabled)
+ * @param object object to publish
+ * (java.security.cert.X509Certificate or,
+ * java.security.cert.X509CRL)
+ */
+ public synchronized void publish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException {
+ try {
+ if (!(object instanceof X509CRL))
+ return;
+ X509CRL crl = (X509CRL) object;
+
+ // talk to agent port of CMS
+
+ // open the connection and prepare it to POST
+ boolean secure = true;
+
+ String host = mHost;
+ int port = Integer.parseInt(mPort);
+ String path = mPath;
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: " +
+ "Host='" + host + "' Port='" + port +
+ "' URL='" + path + "'");
+ CMS.debug("OCSPPublisher: " +
+ "Host='" + host + "' Port='" + port +
+ "' URL='" + path + "'");
+
+ StringBuffer query = new StringBuffer();
+ query.append("crl=");
+ query.append(URLEncoder.encode("-----BEGIN CERTIFICATE REVOCATION LIST-----\n"));
+ query.append(URLEncoder.encode(CMS.BtoA(crl.getEncoded())));
+ query.append(URLEncoder.encode("\n-----END CERTIFICATE REVOCATION LIST-----"));
+ query.append("&noui=true");
+
+ Socket socket = null;
+ JssSSLSocketFactory factory;
+
+ if (mClientAuthEnabled) {
+ factory = new JssSSLSocketFactory(mNickname);
+ } else {
+ factory = new JssSSLSocketFactory();
+ }
+
+ if (mHost != null && mHost.indexOf(' ') != -1) {
+ // support failover hosts configuration
+ // host parameter can be
+ // "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
+ do {
+ socket = Connect(mHost, secure, factory);
+ } while (socket == null);
+ } else {
+ if (secure) {
+ socket = factory.makeSocket(host, port);
+ } else {
+ socket = new Socket(host, port);
+ }
+ }
+
+ if( socket == null ) {
+ CMS.debug( "OCSPPublisher::publish() - socket is null!" );
+ throw new ELdapException( "socket is null" );
+ }
+
+ // use HttpRequest and POST
+ HttpRequest httpReq = new HttpRequest();
+
+ httpReq.setMethod("POST");
+ httpReq.setURI(path);
+ httpReq.setHeader("Connection", "Keep-Alive");
+
+ httpReq.setHeader("Content-Type",
+ "application/x-www-form-urlencoded");
+ httpReq.setHeader("Content-Transfer-Encoding", "7bit");
+
+ httpReq.setHeader("Content-Length",
+ Integer.toString(query.length()));
+ httpReq.setContent(query.toString());
+ OutputStream os = socket.getOutputStream();
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os, "UTF8");
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: start sending CRL");
+ long startTime = CMS.getCurrentDate().getTime();
+ CMS.debug("OCSPPublisher: start CRL sending startTime=" + startTime);
+ httpReq.write(outputStreamWriter);
+ long endTime = CMS.getCurrentDate().getTime();
+ CMS.debug("OCSPPublisher: done CRL sending endTime=" + endTime + " diff=" + (endTime - startTime));
+
+ // Read the response
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: start getting response");
+ DataInputStream dis = new DataInputStream(socket.getInputStream());
+ String nextline;
+ String line = "";
+ String error = "";
+ boolean status = false;
+
+ while ((nextline = dis.readLine()) != null) {
+ if (nextline.startsWith("status=")) {
+ if (nextline.substring(7, nextline.length()).equals("0")) {
+ status = true;
+ }
+ }
+ if (nextline.startsWith("error=")) {
+ error = nextline.substring(6, nextline.length());
+ }
+ }
+ dis.close();
+ if (status) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: successful");
+ } else {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_INFO, "OCSPPublisher: failed - " + error);
+ }
+
+ } catch (IOException e) {
+ CMS.debug("OCSPPublisher: publish failed " + e.toString());
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_OCSP_PUBLISHER_ERROR", e.toString()));
+ } catch (CRLException e) {
+ CMS.debug("OCSPPublisher: publish failed " + e.toString());
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_OCSP_PUBLISHER_ERROR", e.toString()));
+ } catch (Exception e) {
+ CMS.debug("OCSPPublisher: publish failed " + e.toString());
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE, CMS.getLogMessage("PUBLISH_OCSP_PUBLISHER_ERROR", e.toString()));
+ }
+ }
+
+ /**
+ * Unpublishs a object to the ldap directory.
+ *
+ * @param conn the Ldap connection
+ * (null if LDAP publishing is not enabled)
+ * @param dn dn of the ldap entry to unpublish cert
+ * (null if LDAP publishing is not enabled)
+ * @param object object to unpublish
+ * (java.security.cert.X509Certificate)
+ */
+ public void unpublish(LDAPConnection conn, String dn, Object object)
+ throws ELdapException {
+ // NOT USED
+ }
+}