>From 78ab038ba5d46c475bd7b065ec701ca3626dde74 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Fri, 6 Jan 2012 15:17:20 -0500
Subject: [PATCH] Added initial code for retrieving transport cert.

Resources now extend CMSResource.
Addressed following review comments:
* check for null pointers in SystemCertificateResource
* move logic from CertificatData constructor to CMSServlet builder method
* remove unused field uriInfo and replace hard-coded cache constant
---
 .../servlet/admin/SystemCertificateResource.java   |   88 ++++++++++++++++++++
 .../com/netscape/cms/servlet/base/CMSResource.java |   69 +++++++++++++++
 .../cms/servlet/cert/model/CertificateData.java    |   53 ++++++++++++
 .../com/netscape/cms/servlet/key/KeyResource.java  |    3 +-
 .../com/netscape/cms/servlet/key/KeysResource.java |    4 +-
 .../cms/servlet/request/KeyRequestResource.java    |    5 +-
 .../cms/servlet/request/KeyRequestsResource.java   |    5 +-
 7 files changed, 221 insertions(+), 6 deletions(-)
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/base/CMSResource.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java

diff --git a/pki/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java b/pki/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6f0264e2b17550d92de9c272a4eda02ba92a3fc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java
@@ -0,0 +1,88 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.admin;
+
+import java.security.cert.CertificateEncodingException;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cms.servlet.base.CMSResource;
+import com.netscape.cms.servlet.cert.model.CertificateData;
+
+/**
+ * This is the class used to list, retrieve and modify system certificates for all Java subsystems.
+ * 
+ * @author alee
+ * 
+ */
+@Path("/config/cert")
+public class SystemCertificateResource extends CMSResource {
+
+    @Context
+    Request request;
+
+    /**
+     * Used to retrieve key request info for a specific request
+     */
+    @GET
+    @Path("/transport")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    public Response getTransportCert() {
+        CertificateData cert = null;
+        IKeyRecoveryAuthority kra = null;
+
+        // auth and authz
+
+        kra = (IKeyRecoveryAuthority) CMS.getSubsystem("kra");
+        if (kra == null) {
+            // no KRA
+            throw new WebApplicationException(Response.Status.NOT_FOUND);
+        }
+
+        ITransportKeyUnit tu = kra.getTransportKeyUnit();
+        if (tu == null) {
+            CMS.debug("getTransportCert: transport key unit is null");
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        org.mozilla.jss.crypto.X509Certificate transportCert = tu.getCertificate();
+        if (transportCert == null) {
+            CMS.debug("getTransportCert: transport cert is null");
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        try {
+            cert = createCertificateData(transportCert);
+        } catch (CertificateEncodingException e) {
+            CMS.debug("getTransportCert: certificate encoding exception with transport cert");
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        return sendConditionalGetResponse(DEFAULT_LONG_CACHE_LIFETIME, cert, request);
+    }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/CMSResource.java b/pki/base/common/src/com/netscape/cms/servlet/base/CMSResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..48b04859bd1559596aed4268f547f696895a3777
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/CMSResource.java
@@ -0,0 +1,69 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.base;
+
+import java.security.cert.CertificateEncodingException;
+
+import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.Request;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.cert.model.CertificateData;
+
+/**
+ * Base class for CMS RESTful resources
+ * 
+ * @author alee
+ * 
+ */
+public class CMSResource {
+    protected static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
+    protected static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
+
+    // caching parameters
+    protected static final int DEFAULT_LONG_CACHE_LIFETIME = 1000;
+
+    protected Response sendConditionalGetResponse(int ctime, Object object, Request request) {
+        CacheControl cc = new CacheControl();
+        cc.setMaxAge(ctime);
+        EntityTag tag = new EntityTag(Integer.toString(object.hashCode()));
+
+        ResponseBuilder builder = request.evaluatePreconditions(tag);
+        if (builder != null) {
+            builder.cacheControl(cc);
+            return builder.build();
+        }
+
+        builder = Response.ok(object);
+        builder.cacheControl(cc);
+        builder.tag(tag);
+        return builder.build();
+    }
+
+    public CertificateData createCertificateData(org.mozilla.jss.crypto.X509Certificate cert)
+            throws CertificateEncodingException {
+        CertificateData data = new CertificateData();
+        String b64 = HEADER + CMS.BtoA(cert.getEncoded()) + TRAILER;
+        data.setB64(b64);
+        return data;
+    }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java b/pki/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java
new file mode 100644
index 0000000000000000000000000000000000000000..14c537098e4bb4deae61a440dde758baa7fe34f1
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/cert/model/CertificateData.java
@@ -0,0 +1,53 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.cert.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author alee
+ * 
+ */
+@XmlRootElement(name = "CertificateData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CertificateData {
+    @XmlElement
+    private String b64;
+
+    public CertificateData() {
+        // required for jaxb
+    }
+
+    /**
+     * @return the b64
+     */
+    public String getB64() {
+        return b64;
+    }
+
+    /**
+     * @param b64 the b64 to set
+     */
+    public void setB64(String b64) {
+        this.b64 = b64;
+    }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/KeyResource.java b/pki/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
index fef29f9cb79b8d36bb009ab08db6ba7f61d9a28b..dad3e29e52b80ff91f2d664b4bff20472b8e8a1a 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
@@ -29,6 +29,7 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
+import com.netscape.cms.servlet.base.CMSResource;
 import com.netscape.cms.servlet.key.model.KeyDAO;
 import com.netscape.cms.servlet.key.model.KeyData;
 import com.netscape.cms.servlet.request.model.KeyRequestDAO;
@@ -42,7 +43,7 @@ import com.netscape.certsrv.base.EBaseException;
  * 
  */
 @Path("/key")
-public class KeyResource {
+public class KeyResource extends CMSResource{
     
     @Context
     UriInfo uriInfo;
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/KeysResource.java b/pki/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
index 38a124e9a339a7bf61b9462f7150aa0b0a515839..70312db95133f05a8a1ad260be77bc096eb2236e 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
@@ -32,6 +32,7 @@ import javax.ws.rs.core.UriInfo;
 import java.util.List;
 
 import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.base.CMSResource;
 import com.netscape.cms.servlet.key.model.KeyDAO;
 import com.netscape.cms.servlet.key.model.KeyDataInfo;
 
@@ -40,7 +41,8 @@ import com.netscape.cms.servlet.key.model.KeyDataInfo;
  * 
  */
 @Path("/keys")
-public class KeysResource {
+public class KeysResource extends CMSResource{
+
     @Context
     UriInfo uriInfo;
 
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java
index 3a213495bd4f9e08092c2590c90375e6146911e9..8806695761b1dfcc500fc7f7fcbbe2e7fdac7acd 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java
@@ -31,6 +31,7 @@ import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.base.CMSResource;
 import com.netscape.cms.servlet.request.model.ArchivalRequestData;
 import com.netscape.cms.servlet.request.model.KeyRequestDAO;
 import com.netscape.cms.servlet.request.model.KeyRequestInfo;
@@ -41,8 +42,8 @@ import com.netscape.cms.servlet.request.model.RecoveryRequestData;
  * 
  */
 @Path("/keyrequest")
-public class KeyRequestResource {
-    
+public class KeyRequestResource extends CMSResource{
+
     @Context
     UriInfo uriInfo;
     
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java
index c5641cb1ad843c6162077d735b8dbfa1bb48663d..52f93c815687194dc3540132d9caca67449735bf 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java
@@ -31,6 +31,7 @@ import javax.ws.rs.core.UriInfo;
 
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.base.CMSResource;
 import com.netscape.cms.servlet.request.model.KeyRequestDAO;
 import com.netscape.cms.servlet.request.model.KeyRequestInfo;
  
@@ -39,8 +40,8 @@ import com.netscape.cms.servlet.request.model.KeyRequestInfo;
  *
  */
 @Path("/keyrequests")
-public class KeyRequestsResource {
-
+public class KeyRequestsResource extends CMSResource{
+ 
     @Context
     UriInfo uriInfo;
 
-- 
1.7.6.4

