>From 167dc8d6e1b5d60ee5c33e8e92f217d76b5da6e3 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Mon, 12 Dec 2011 22:57:33 -0500
Subject: [PATCH] Initial skeleton code for drm resteasy interface

Integrated files into current servlet structure.
Allowed exceptions to bubble up to top level.
Move bean initialization logic into DAO objects.
---
 pki/.classpath                                     |    1 +
 .../src/com/netscape/certsrv/request/IRequest.java |    2 +
 .../com/netscape/cms/servlet/key/KeyResource.java  |  135 ++++++++++++++++
 .../com/netscape/cms/servlet/key/KeysResource.java |   68 ++++++++
 .../com/netscape/cms/servlet/key/model/KeyDAO.java |  102 ++++++++++++
 .../netscape/cms/servlet/key/model/KeyData.java    |   57 +++++++
 .../cms/servlet/key/model/KeyDataInfo.java         |   75 +++++++++
 .../cms/servlet/request/KeyRequestResource.java    |  168 ++++++++++++++++++++
 .../cms/servlet/request/KeyRequestsResource.java   |   72 +++++++++
 .../servlet/request/model/ArchivalRequestData.java |  123 ++++++++++++++
 .../cms/servlet/request/model/KeyRequestDAO.java   |  138 ++++++++++++++++
 .../cms/servlet/request/model/KeyRequestInfo.java  |  101 ++++++++++++
 .../servlet/request/model/RecoveryRequestData.java |  122 ++++++++++++++
 pki/base/kra/shared/webapps/kra/WEB-INF/web.xml    |   27 +++
 pki/specs/pki-core.spec                            |    6 +-
 15 files changed, 1196 insertions(+), 1 deletions(-)
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/KeyResource.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java
 create mode 100644 pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java

diff --git a/pki/.classpath b/pki/.classpath
index 2f3aa43d5e4447bd3149f4f5218dec98b4e9493f..07ba2826ba16bf9d9c186de892b0a57e0514f88c 100644
--- a/pki/.classpath
+++ b/pki/.classpath
@@ -24,5 +24,6 @@
 	<classpathentry kind="lib" path="/usr/share/java/servlet.jar"/>
 	<classpathentry kind="lib" path="/usr/share/java/xerces-j2.jar"/>
 	<classpathentry kind="lib" path="/usr/share/java/junit4.jar"/>
+	<classpathentry kind="lib" path="/usr/share/candlepin/lib/jaxrs-api-2.2.1.GA.jar"/>
 	<classpathentry kind="output" path="build/classes"/>
 </classpath>
diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequest.java b/pki/base/common/src/com/netscape/certsrv/request/IRequest.java
index 477a14c65bb5526db5b4f5ba2f48f2db2beacd19..0af5d1692a38140d460fd2d95a0c79d25ec8c491 100644
--- a/pki/base/common/src/com/netscape/certsrv/request/IRequest.java
+++ b/pki/base/common/src/com/netscape/certsrv/request/IRequest.java
@@ -71,6 +71,8 @@ public interface IRequest {
     public static final String CLA_UNCERT4CRL_REQUEST = "uncert4crl";
     public static final String NETKEY_KEYGEN_REQUEST = "netkeyKeygen";
     public static final String NETKEY_KEYRECOVERY_REQUEST = "netkeyKeyRecovery";
+    public static final String SECURITY_DATA_ENROLLMENT_REQUEST = "securityDataEnrollment";
+    public static final String SECURITY_DATA_RECOVERY_REQUEST = "securityDataRecovery";
 
     public static final String REQUESTOR_NAME = "csrRequestorName";
     public static final String REQUESTOR_PHONE = "csrRequestorPhone";
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
new file mode 100644
index 0000000000000000000000000000000000000000..fef29f9cb79b8d36bb009ab08db6ba7f61d9a28b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeyResource.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.cms.servlet.key.model.KeyDAO;
+import com.netscape.cms.servlet.key.model.KeyData;
+import com.netscape.cms.servlet.request.model.KeyRequestDAO;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.base.EBaseException;
+/**
+ * @author alee
+ * 
+ */
+@Path("/key")
+public class KeyResource {
+    
+    @Context
+    UriInfo uriInfo;
+    
+    /**
+     * Used to retrieve a key
+     * @param data
+     * @return
+     */
+    @POST
+    @Path("retrieve")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    public KeyData retrieveKey(RecoveryRequestData data) {
+        // auth and authz
+        String keyId = validateRequest(data);
+        KeyDAO dao = new KeyDAO();
+        KeyData keyData;
+        try {
+            keyData = dao.getKey(keyId, data);
+        } catch (EBaseException e) {
+            // log error
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        if (keyData == null) {
+            // no key record
+            throw new WebApplicationException(Response.Status.GONE);
+        }
+        return keyData;
+    }
+    
+    // retrieval - used to test integration with a browser
+    @POST
+    @Path("retrieve")
+    @Produces(MediaType.TEXT_XML)
+    public KeyData retrieveKey(MultivaluedMap<String, String> form) {
+        RecoveryRequestData data = new RecoveryRequestData(form);
+        return retrieveKey(data);
+    }
+    
+    private String validateRequest(RecoveryRequestData data) {
+        // confirm that at least one wrapping method exists
+        if ((data.getTransWrappedSessionKey() == null) && (data.getTransWrappedSessionKey() == null)) {
+            // log error
+            throw new WebApplicationException(Response.Status.BAD_REQUEST);
+        }
+        
+        // confirm request exists
+        String reqId = data.getRequestId();
+        if (reqId == null) {
+            // log error
+            throw new WebApplicationException(Response.Status.BAD_REQUEST);
+        }
+        KeyRequestDAO reqDAO = new KeyRequestDAO();
+        KeyRequestInfo reqInfo;
+        try {
+            reqInfo = reqDAO.getRequest(reqId, uriInfo);
+        } catch (EBaseException e1) {
+            // failed to get request
+            e1.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        if (reqInfo == null) {
+            // request not found
+            throw new WebApplicationException(Response.Status.GONE);
+        }
+        
+        //confirm request is of the right type
+        String type = reqInfo.getRequestType();
+        if (!type.equals(IRequest.SECURITY_DATA_RECOVERY_REQUEST)) {
+            // log error
+            throw new WebApplicationException(Response.Status.BAD_REQUEST);
+        }
+        
+        //confirm that agent is originator of request, else throw 401 
+        //  TO-DO
+        
+        // confirm request is in approved state
+        String status = reqInfo.getRequestStatus();
+        if (!status.equals(RequestStatus.APPROVED.toString())) {
+            // log error
+            throw new WebApplicationException(Response.Status.UNAUTHORIZED);
+        }
+        
+        String keyURL = reqInfo.getKeyURL();
+        return keyURL.substring(keyURL.lastIndexOf("/")); 
+    }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..38a124e9a339a7bf61b9462f7150aa0b0a515839
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeysResource.java
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+/**
+ * 
+ */
+package com.netscape.cms.servlet.key;
+
+import javax.ws.rs.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.Response;
+import javax.ws.rs.core.UriInfo;
+ 
+import java.util.List;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.key.model.KeyDAO;
+import com.netscape.cms.servlet.key.model.KeyDataInfo;
+
+/**
+ * @author alee
+ * 
+ */
+@Path("/keys")
+public class KeysResource {
+    @Context
+    UriInfo uriInfo;
+
+    /**
+     * Used to generate list of key infos based on the search parameters
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    public List<KeyDataInfo> listKeys() {
+        // auth and authz
+        // parse search parameters from uriInfo and create search filter
+        // String clientID = uriInfo.getQueryParameters().getFirst(CLIENT_ID);
+        String filter = "objectClass=keyRecord";
+        KeyDAO dao = new KeyDAO();
+        List<KeyDataInfo> info;
+        try {
+            info = dao.listKeys(filter, uriInfo);
+        } catch (EBaseException e) {
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        return info;
+    }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7a2d8ed1dab7b3ac0505c46df28612b723c0db7
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.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) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.key.model;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyDAO {
+
+    private IKeyRepository repo;
+    private int maxSize = 100;
+    private int maxTime = 20;
+    
+    public KeyDAO() {
+        IKeyRecoveryAuthority kra = null;
+        kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" );
+        repo = kra.getKeyRepository();
+    }
+    /**
+     * This will find the keys in the database matching the specified search parameters
+     * Needs input validation and probably paging, maybe using the vlv functions
+     * @throws EBaseException 
+     */
+    public List<KeyDataInfo> listKeys(String filter, UriInfo uriInfo) throws EBaseException {
+        List <KeyDataInfo> list = new ArrayList<KeyDataInfo>();         
+        Enumeration<IKeyRecord> e = null;
+        
+        e = repo.searchKeys(filter, maxSize, maxTime);
+         
+        if (e == null) {
+            throw new EBaseException("search results are null");
+        }
+        
+        while (e.hasMoreElements()) {
+            IKeyRecord rec = e.nextElement();
+            list.add(createKeyDataInfo(rec, uriInfo));
+        }
+        return list;
+    }
+    
+    public KeyData getKey(String keyId, RecoveryRequestData data) throws EBaseException {
+        KeyData keyData = null;
+        BigInteger serial = new BigInteger(keyId);
+        
+        // get wrapped key
+        IKeyRecord rec = repo.readKeyRecord(serial);
+        if (rec == null) {
+            // key does not exist
+            // log the error
+            return null;  
+        }
+        // TODO unwrap the key and wrap with the credential in RecoveryRequestData
+        // need to figure out how to do this with jmagne 
+        
+        return keyData;
+    }
+    
+    public KeyDataInfo createKeyDataInfo(IKeyRecord rec, UriInfo uriInfo) throws EBaseException {
+        KeyDataInfo ret = new KeyDataInfo();
+        String serial = null;
+        serial = (rec.getSerialNumber()).toString();
+         
+        UriBuilder keyBuilder = uriInfo.getBaseUriBuilder();
+        keyBuilder.path("/key/" + serial);
+        ret.setKeyURL(keyBuilder.build().toString());
+        
+        // clientID = rec.getClientID();
+        // TODO add other fields as needed
+        return ret;
+    }
+    
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e6e80deceadcc13eb4ab8be384bb75e999e22aa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java
@@ -0,0 +1,57 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * 
+ */
+package com.netscape.cms.servlet.key.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityData")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyData {
+    @XmlElement
+    String wrappedPrivateData;
+    
+    public KeyData() {
+        // required for JAXB (defaults)
+    }
+
+    /**
+     * @return the wrappedPrivateData
+     */
+    public String getWrappedPrivateData() {
+        return wrappedPrivateData;
+    }
+
+    /**
+     * @param wrappedPrivateData the wrappedPrivateData to set
+     */
+    public void setWrappedPrivateData(String wrappedPrivateData) {
+        this.wrappedPrivateData = wrappedPrivateData;
+    }
+    
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..46843ba9061fd398fc86fcf36915c1d5e57d6ae8
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDataInfo.java
@@ -0,0 +1,75 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+/**
+ * 
+ */
+package com.netscape.cms.servlet.key.model;
+
+ 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+/**
+ * @author alee
+ *
+ */
+@XmlRootElement(name="SecurityDataInfo")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyDataInfo {
+    
+    @XmlElement
+    protected String keyURL;
+
+    @XmlElement
+    protected String clientID;
+    
+    public KeyDataInfo() {
+        // required for JAXB (defaults)
+    }
+
+    /**
+     * @return the keyURL
+     */
+    public String getKeyURL() {
+        return keyURL;
+    }
+
+    /**
+     * @param keyURL the keyURL to set
+     */
+    public void setKeyURL(String keyURL) {
+        this.keyURL = keyURL;
+    }
+
+    /**
+     * @return the clientID
+     */
+    public String getClientID() {
+        return clientID;
+    }
+
+    /**
+     * @param clientID the clientID to set
+     */
+    public void setClientID(String clientID) {
+        this.clientID = clientID;
+    }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..3a213495bd4f9e08092c2590c90375e6146911e9
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java
@@ -0,0 +1,168 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.request;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+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.request.model.ArchivalRequestData;
+import com.netscape.cms.servlet.request.model.KeyRequestDAO;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+import com.netscape.cms.servlet.request.model.RecoveryRequestData;
+ 
+/**
+ * @author alee
+ * 
+ */
+@Path("/keyrequest")
+public class KeyRequestResource {
+    
+    @Context
+    UriInfo uriInfo;
+    
+    /**
+     * Used to retrieve key request info for a specific request
+     */
+    @GET
+    @Path("{id}")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML  })
+    public KeyRequestInfo getRequestInfo(@PathParam("id") String id) {
+        // auth and authz
+        KeyRequestDAO dao = new KeyRequestDAO();
+        KeyRequestInfo info;
+        try {
+            info = dao.getRequest(id, uriInfo);
+        } catch (EBaseException e) {
+            // log error
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        if (info == null) {
+            // request does not exist
+            throw new WebApplicationException(Response.Status.NOT_FOUND);
+        }
+        return info;
+    }
+    
+    // Archiving - used to test integration with a browser
+    @POST
+    @Path("archive")
+    @Produces({ MediaType.TEXT_XML })
+    public KeyRequestInfo archiveKey(MultivaluedMap<String, String> form) {
+        ArchivalRequestData data = new ArchivalRequestData(form);
+        return archiveKey(data);
+    }
+
+    @POST
+    @Path("archive")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    public KeyRequestInfo archiveKey(ArchivalRequestData data) {
+        // auth and authz
+        KeyRequestDAO dao = new KeyRequestDAO();
+        KeyRequestInfo info;
+        try {
+            info = dao.submitRequest(data, uriInfo);
+        } catch (EBaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        return info;
+    }
+    
+    //Recovery - used to test integration with a browser
+    @POST
+    @Path("recover")
+    @Produces({ MediaType.TEXT_XML })
+    public KeyRequestInfo recoverKey(MultivaluedMap<String, String> form) {
+        RecoveryRequestData data = new RecoveryRequestData(form);
+        return recoverKey(data);
+    }
+
+    @POST
+    @Path("recover")
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+    public KeyRequestInfo recoverKey(RecoveryRequestData data) {
+        // auth and authz
+        KeyRequestDAO dao = new KeyRequestDAO();
+        KeyRequestInfo info;
+        try {
+            info = dao.submitRequest(data, uriInfo);
+        } catch (EBaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        return info;
+    }
+    
+    @POST
+    @Path("approve/{id}")
+    public void approveRequest(@PathParam("id") String id) {
+        // auth and authz
+        KeyRequestDAO dao = new KeyRequestDAO();
+        try {
+            dao.approveRequest(id);
+        } catch (EBaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+    }
+    
+    @POST
+    @Path("reject/{id}")
+    public void rejectRequest(@PathParam("id") String id) {
+        // auth and authz
+        KeyRequestDAO dao = new KeyRequestDAO();
+        try {
+            dao.rejectRequest(id);
+        } catch (EBaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+    }
+    
+    @POST
+    @Path("cancel/{id}")
+    public void cancelRequest(@PathParam("id") String id) {
+        // auth and authz
+        KeyRequestDAO dao = new KeyRequestDAO();
+        try {
+            dao.cancelRequest(id);
+        } catch (EBaseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..c5641cb1ad843c6162077d735b8dbfa1bb48663d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResource.java
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+ 
+package com.netscape.cms.servlet.request;
+
+import java.util.List;
+
+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.Response;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cms.servlet.request.model.KeyRequestDAO;
+import com.netscape.cms.servlet.request.model.KeyRequestInfo;
+ 
+/**
+ * @author alee
+ *
+ */
+@Path("/keyrequests")
+public class KeyRequestsResource {
+
+    @Context
+    UriInfo uriInfo;
+
+    /**
+     * Used to generate list of key requests based on the search parameters
+     */
+    @GET
+    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
+    public List<KeyRequestInfo> listRequests() {
+        // auth and authz
+        // parse search parameters from uriInfo and create search filter
+        // String clientID = uriInfo.getQueryParameters().getFirst(CLIENT_ID);
+        String filter = "requestState=complete";
+        KeyRequestDAO reqDAO = new KeyRequestDAO();
+        List<KeyRequestInfo> requests;
+        try {
+            CMS.debug("alee: getting requests");
+            requests = reqDAO.listRequests(filter, uriInfo);
+            CMS.debug("alee: got request");
+        } catch (EBaseException e) {
+            // log error
+            e.printStackTrace();
+            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+        }
+        CMS.debug("going into return");
+        return requests;
+    }
+        
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.java b/pki/base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.java
new file mode 100644
index 0000000000000000000000000000000000000000..8a25c668471733b355b677c7185216fa3d0c73de
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/model/ArchivalRequestData.java
@@ -0,0 +1,123 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * 
+ */
+package com.netscape.cms.servlet.request.model;
+
+import javax.ws.rs.core.MultivaluedMap;
+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="SecurityDataArchivalRequest")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ArchivalRequestData {
+
+    private static final String CLIENT_ID = "clientID";
+    private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
+    private static final String DATA_TYPE = "dataType";
+    private static final String WRAPPED_PRIVATE_DATA = "wrappedPrivateData";
+
+    @XmlElement
+    protected String clientId;
+    
+    @XmlElement
+    protected String transWrappedSessionKey;
+    
+    @XmlElement
+    protected String dataType;
+    
+    @XmlElement
+    protected String wrappedPrivateData;
+    
+    public ArchivalRequestData() {
+        // required for JAXB (defaults)
+    }
+    
+    public ArchivalRequestData(MultivaluedMap<String, String> form) {        
+        clientId = form.getFirst(CLIENT_ID);
+        transWrappedSessionKey = form.getFirst(TRANS_WRAPPED_SESSION_KEY);
+        dataType = form.getFirst(DATA_TYPE);
+        wrappedPrivateData = form.getFirst(WRAPPED_PRIVATE_DATA);
+    }
+
+    /**
+     * @return the clientId
+     */
+    public String getClientId() {
+        return clientId;
+    }
+
+    /**
+     * @param clientId the clientId to set
+     */
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    /**
+     * @return the transWrappedSessionKey
+     */
+    public String getTransWrappedSessionKey() {
+        return transWrappedSessionKey;
+    }
+
+    /**
+     * @param transWrappedSessionKey the transWrappedSessionKey to set
+     */
+    public void setTransWrappedSessionKey(String transWrappedSessionKey) {
+        this.transWrappedSessionKey = transWrappedSessionKey;
+    }
+
+    /**
+     * @return the dataType
+     */
+    public String getDataType() {
+        return dataType;
+    }
+
+    /**
+     * @param dataType the dataType to set
+     */
+    public void setDataType(String dataType) {
+        this.dataType = dataType;
+    }
+
+    /**
+     * @return the wrappedPrivateData
+     */
+    public String getWrappedPrivateData() {
+        return wrappedPrivateData;
+    }
+
+    /**
+     * @param wrappedPrivateData the wrappedPrivateData to set
+     */
+    public void setWrappedPrivateData(String wrappedPrivateData) {
+        this.wrappedPrivateData = wrappedPrivateData;
+    }
+    
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java b/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb266d15d59b47c5cebff0f628bcf8044f29650f
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java
@@ -0,0 +1,138 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.request.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestList;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+
+/**
+ * @author alee
+ *
+ */
+public class KeyRequestDAO {
+    private IRequestQueue queue;
+    
+    public KeyRequestDAO() {
+        IKeyRecoveryAuthority kra = null;
+        kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" );
+        queue = kra.getRequestQueue();
+    }
+
+    /**
+     * This will find the requests in the database matching the specified search parameters
+     * Needs input validation and probably paging, maybe using the vlv functions
+     * @throws EBaseException 
+     */
+    public List<KeyRequestInfo> listRequests(String filter, UriInfo uriInfo) throws EBaseException {
+        List <KeyRequestInfo> list = new ArrayList<KeyRequestInfo>();  
+        IRequestList requests = queue.listRequestsByFilter(filter);
+        while (requests.hasMoreElements()) {
+            RequestId rid = (RequestId) requests.nextElement();
+            IRequest request;
+            request = queue.findRequest(rid);
+            list.add(createKeyRequestInfo(request, uriInfo));
+        }
+        return list;
+    }
+    
+    /**
+     * Gets info for a specific request
+     * @param id
+     * @return info for specific request
+     * @throws EBaseException 
+     */
+    public KeyRequestInfo getRequest(String id, UriInfo uriInfo) throws EBaseException {
+        IRequest request = queue.findRequest(new RequestId(id));
+        if (request == null) {
+            return null;
+        }
+        KeyRequestInfo info = createKeyRequestInfo(request, uriInfo);
+        return info;
+    }
+    /**
+     * Submits an archival request and processes it.
+     * @param data
+     * @return info for the request submitted.
+     * @throws EBaseException 
+     */
+    public KeyRequestInfo submitRequest(ArchivalRequestData data, UriInfo uriInfo) throws EBaseException {
+        IRequest request = queue.newRequest(IRequest.SECURITY_DATA_ENROLLMENT_REQUEST);
+        //TODO : 
+        //set data using request.setExtData(field, data)
+        queue.processRequest(request);
+        return createKeyRequestInfo(request, uriInfo);
+    }
+    /**
+     * Submits a key recovery request.
+     * @param data
+     * @return info on the recovery request created
+     * @throws EBaseException 
+     */
+    public KeyRequestInfo submitRequest(RecoveryRequestData data, UriInfo uriInfo) throws EBaseException { 
+        IRequest request = queue.newRequest(IRequest.SECURITY_DATA_RECOVERY_REQUEST);
+        // set data using request.setExtData(field, data)
+        queue.processRequest(request);
+        return createKeyRequestInfo(request, uriInfo);
+    }
+
+    public void approveRequest(String id) throws EBaseException {
+        IRequest request = queue.findRequest(new RequestId(id));
+        request.setRequestStatus(RequestStatus.APPROVED);
+    }
+    
+    public void rejectRequest(String id) throws EBaseException {
+        IRequest request = queue.findRequest(new RequestId(id));
+        request.setRequestStatus(RequestStatus.CANCELED);
+    }
+    
+    public void cancelRequest(String id) throws EBaseException {
+        IRequest request = queue.findRequest(new RequestId(id));
+        request.setRequestStatus(RequestStatus.REJECTED);
+    }
+    
+    public KeyRequestInfo createKeyRequestInfo(IRequest request, UriInfo uriInfo) {
+        KeyRequestInfo ret = new KeyRequestInfo();
+        
+        ret.setRequestType(request.getRequestType());
+        ret.setRequestStatus(request.getRequestStatus().toString());
+        
+        String rid = request.getRequestId().toString();
+        UriBuilder reqBuilder = uriInfo.getBaseUriBuilder();
+        reqBuilder.path("/keyRequest/" + rid);
+        ret.setRequestURL(reqBuilder.build().toString());
+        
+        String kid = request.getExtDataInString("keyrecord");
+        UriBuilder keyBuilder = uriInfo.getBaseUriBuilder();
+        keyBuilder.path("/key/" + kid);
+        ret.setKeyURL(keyBuilder.build().toString());
+        
+        return ret;
+    }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java b/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..d768e2ba98e9dda41909f872630b3bf986257618
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestInfo.java
@@ -0,0 +1,101 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.request.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;
+
+@XmlRootElement(name="SecurityDataRequestInfo")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class KeyRequestInfo {
+
+    @XmlElement
+    protected String requestType;
+    
+    @XmlElement
+    protected String requestStatus;
+    
+    @XmlElement
+    protected String requestURL;
+    
+    @XmlElement
+    protected String keyURL;
+    
+    public KeyRequestInfo(){
+        // required to be here for JAXB (defaults)
+    }
+    
+    /**
+     * @return the requestType
+     */
+    public String getRequestType() {
+        return requestType;
+    }
+
+    /**
+     * @param requestType the requestType to set
+     */
+    public void setRequestType(String requestType) {
+        this.requestType = requestType;
+    }
+
+    /**
+     * @return the requestStatus
+     */
+    public String getRequestStatus() {
+        return requestStatus;
+    }
+
+    /**
+     * @param requestStatus the requestStatus to set
+     */
+    public void setRequestStatus(String requestStatus) {
+        this.requestStatus = requestStatus;
+    }
+
+    /**
+     * @return the requestURL
+     */
+    public String getRequestURL() {
+        return requestURL;
+    }
+
+    /**
+     * @param requestURL the requestURL to set
+     */
+    public void setRequestURL(String requestURL) {
+        this.requestURL = requestURL;
+    }
+
+    /**
+     * @return the keyURL
+     */
+    public String getKeyURL() {
+        return keyURL;
+    }
+
+    /**
+     * @param keyURL the keyURL to set
+     */
+    public void setKeyURL(String keyURL) {
+        this.keyURL = keyURL;
+    }
+}
diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java b/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java
new file mode 100644
index 0000000000000000000000000000000000000000..88533a38da070b578984b720374b4152abd08178
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java
@@ -0,0 +1,122 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * 
+ */
+package com.netscape.cms.servlet.request.model;
+
+import javax.ws.rs.core.MultivaluedMap;
+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="SecurityDataRecoveryRequest")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class RecoveryRequestData {
+    
+    private static final String KEY_ID = "keyId";
+    private static final String REQUEST_ID = "requestId";
+    private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
+    private static final String TRANS_WRAPPED_PASSPHRASE = "transWrappedPassphrase";
+
+    @XmlElement
+    protected String keyId;
+    
+    @XmlElement
+    protected String requestId;
+    
+    @XmlElement
+    protected String transWrappedSessionKey;
+    
+    @XmlElement
+    protected String transWrappedPassphrase;
+    
+    public RecoveryRequestData() {
+        // required for JAXB (defaults)
+    }
+    
+    public RecoveryRequestData(MultivaluedMap<String, String> form) {
+        keyId = form.getFirst(KEY_ID);
+        requestId = form.getFirst(REQUEST_ID);
+        transWrappedSessionKey = form.getFirst(TRANS_WRAPPED_SESSION_KEY);
+        transWrappedPassphrase = form.getFirst(TRANS_WRAPPED_PASSPHRASE);
+    }
+
+    /**
+     * @return the keyId
+     */
+    public String getKeyId() {
+        return keyId;
+    }
+
+    /**
+     * @param keyId the keyId to set
+     */
+    public void setKeyId(String keyId) {
+        this.keyId = keyId;
+    }
+
+    /**
+     * @return the requestId
+     */
+    public String getRequestId() {
+        return requestId;
+    }
+
+    /**
+     * @param requestId the requestId to set
+     */
+    public void setRequestId(String requestId) {
+        this.requestId = requestId;
+    }
+
+    /**
+     * @return the transWrappedSessionKey
+     */
+    public String getTransWrappedSessionKey() {
+        return transWrappedSessionKey;
+    }
+
+    /**
+     * @param transWrappedSessionKey the transWrappedSessionKey to set
+     */
+    public void setTransWrappedSessionKey(String transWrappedSessionKey) {
+        this.transWrappedSessionKey = transWrappedSessionKey;
+    }
+
+    /**
+     * @return the transWrappedPassphrase
+     */
+    public String getTransWrappedPassphrase() {
+        return transWrappedPassphrase;
+    }
+
+    /**
+     * @param transWrappedPassphrase the transWrappedPassphrase to set
+     */
+    public void setTransWrappedPassphrase(String transWrappedPassphrase) {
+        this.transWrappedPassphrase = transWrappedPassphrase;
+    }
+
+}
diff --git a/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml b/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml
index fdc2779b1a583579472388f7d87c52ee0b6bbda0..4e9027acc6dc310cb275c2f4faceb367d8f899e4 100644
--- a/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml
+++ b/pki/base/kra/shared/webapps/kra/WEB-INF/web.xml
@@ -756,6 +756,28 @@
                          <param-value> ee          </param-value> </init-param>
    </servlet>
 
+   <context-param>
+      <param-name>resteasy.scan</param-name>
+      <param-value>true</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.servlet.mapping.prefix</param-name>
+      <param-value>/pki</param-value>
+   </context-param>
+
+   <context-param>
+      <param-name>resteasy.resource.method-interceptors</param-name>
+      <param-value>
+         org.jboss.resteasy.core.ResourceMethodSecurityInterceptor
+      </param-value>
+   </context-param>
+
+   <servlet>
+      <servlet-name>Resteasy</servlet-name>
+      <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+   </servlet>
+
 [PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT]
    <filter-mapping>
       <filter-name>  AgentRequestFilter  </filter-name>
@@ -783,6 +805,11 @@
 [PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT]
 
    <servlet-mapping>
+      <servlet-name>Resteasy</servlet-name>
+      <url-pattern>/pki/*</url-pattern>
+   </servlet-mapping>
+
+   <servlet-mapping>
       <servlet-name>  kraserver  </servlet-name>
       <url-pattern>   /server  </url-pattern>
    </servlet-mapping>
diff --git a/pki/specs/pki-core.spec b/pki/specs/pki-core.spec
index 075a10aac2a709b1887899ad3774b28fa9643a6d..c9bb229a0d5af6621ce19b21ac4fe2148f7cb1db 100644
--- a/pki/specs/pki-core.spec
+++ b/pki/specs/pki-core.spec
@@ -1,6 +1,6 @@
 Name:             pki-core
 Version:          9.0.16
-Release:          1%{?dist}
+Release:          2%{?dist}
 Summary:          Certificate System - PKI Core Components
 URL:              http://pki.fedoraproject.org/
 License:          GPLv2
@@ -26,6 +26,7 @@ BuildRequires:    selinux-policy-devel
 BuildRequires:    velocity
 BuildRequires:    xalan-j2
 BuildRequires:    xerces-j2
+BuildRequires:    candlepin-deps
 %if 0%{?fedora} >= 16
 BuildRequires:    jpackage-utils >= 0:1.7.5-10
 BuildRequires:    jss >= 4.2.6-19.1
@@ -274,6 +275,9 @@ Group:            System Environment/Base
 BuildArch:        noarch
 
 Requires:         java >= 1:1.6.0
+Requires:         candlepin-deps
+Requires:         javassist
+Requires:         jettison
 Requires:         pki-common-theme >= 9.0.0
 Requires:         pki-java-tools = %{version}-%{release}
 Requires:         pki-setup = %{version}-%{release}
-- 
1.7.6.4

