>From 453caf2936b10a50cd030e8670d32e0966b26b37 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 CMSServlet (where auth/authz will reside).
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   |   90 ++++++++++++++++++++
 .../com/netscape/cms/servlet/base/CMSServlet.java  |   37 ++++++++
 .../cms/servlet/cert/model/CertificateData.java    |   53 ++++++++++++
 .../com/netscape/cms/servlet/key/KeyResource.java  |    5 +-
 .../com/netscape/cms/servlet/key/KeysResource.java |    6 +-
 .../cms/servlet/request/KeyRequestResource.java    |    7 +-
 .../cms/servlet/request/KeyRequestsResource.java   |    5 +-
 7 files changed, 198 insertions(+), 5 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/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..7efab2c648aabd6ca0241269166967f21598f92e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResource.java
@@ -0,0 +1,90 @@
+// --- 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.CMSServlet;
+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 CMSServlet {
+
+    private static final long serialVersionUID = -6886446610552734620L;
+
+    @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/CMSServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
index 2920d0f463b991b3400ee02080982f5e3bccfc14..4b99360b4051f28c4990d7b5047800b040aea666 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
@@ -43,6 +43,11 @@ import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+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 netscape.security.pkcs.ContentInfo;
 import netscape.security.pkcs.PKCS7;
@@ -81,6 +86,7 @@ import com.netscape.certsrv.request.IRequest;
 import com.netscape.certsrv.request.IRequestQueue;
 import com.netscape.certsrv.usrgrp.IGroup;
 import com.netscape.certsrv.usrgrp.IUGSubsystem;
+import com.netscape.cms.servlet.cert.model.CertificateData;
 import com.netscape.cms.servlet.common.AuthCredentials;
 import com.netscape.cms.servlet.common.CMSFileLoader;
 import com.netscape.cms.servlet.common.CMSGateway;
@@ -206,6 +212,12 @@ public abstract class CMSServlet extends HttpServlet {
     public static final String CERT_ATTR =
             "javax.servlet.request.X509Certificate";
 
+    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;
+
     // members. 
 
     protected boolean mRenderResult = true;
@@ -2296,4 +2308,29 @@ public abstract class CMSServlet extends HttpServlet {
         return result;
     }
 
+    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..9d0c810eb5585157c7e03f085083b94e93490334 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.CMSServlet;
 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,9 @@ import com.netscape.certsrv.base.EBaseException;
  * 
  */
 @Path("/key")
-public class KeyResource {
+public class KeyResource extends CMSServlet{
+    
+    private static final long serialVersionUID = -1889404699609432703L;
     
     @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..538408027ed48bc8caf26e4b177793c569dc941a 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.CMSServlet;
 import com.netscape.cms.servlet.key.model.KeyDAO;
 import com.netscape.cms.servlet.key.model.KeyDataInfo;
 
@@ -40,7 +41,10 @@ import com.netscape.cms.servlet.key.model.KeyDataInfo;
  * 
  */
 @Path("/keys")
-public class KeysResource {
+public class KeysResource extends CMSServlet{
+
+    private static final long serialVersionUID = -1081352247853302284L;
+
     @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..1c25b628ae2b504211b889b1a54d2e5f0ed9a973 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.CMSServlet;
 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,10 @@ import com.netscape.cms.servlet.request.model.RecoveryRequestData;
  * 
  */
 @Path("/keyrequest")
-public class KeyRequestResource {
-    
+public class KeyRequestResource extends CMSServlet{
+
+    private static final long serialVersionUID = 5355775730513207235L;
+
     @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..9f07b87f4165e6e2e783c0f39793635c59fd8413 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.CMSServlet;
 import com.netscape.cms.servlet.request.model.KeyRequestDAO;
 import com.netscape.cms.servlet.request.model.KeyRequestInfo;
  
@@ -39,7 +40,9 @@ import com.netscape.cms.servlet.request.model.KeyRequestInfo;
  *
  */
 @Path("/keyrequests")
-public class KeyRequestsResource {
+public class KeyRequestsResource extends CMSServlet{
+
+    private static final long serialVersionUID = 4280262793431600805L;
 
     @Context
     UriInfo uriInfo;
-- 
1.7.6.4

