summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2012-03-01 19:58:34 -0600
committerEndi Sukma Dewata <edewata@redhat.com>2012-03-30 16:54:32 -0500
commit0b39b68e4e72cbcf0f4d28488d54ce06117efa9c (patch)
tree1a2cfc235f1f6a062e7c88c554a9f9bf82822f72 /base
parent70fdf22f76494a84b6cbef10598ed897a48f0798 (diff)
downloadpki-0b39b68e4e72cbcf0f4d28488d54ce06117efa9c.tar.gz
pki-0b39b68e4e72cbcf0f4d28488d54ce06117efa9c.tar.xz
pki-0b39b68e4e72cbcf0f4d28488d54ce06117efa9c.zip
Added CMSException.
The CMSException was added to simplify error handling in REST services. The exception may include an error message and some other attributes. When the server throws a CMSException (or its subclass), the exception will be marshalled into XML and unmarshalled by the client, then thrown again as a new exception which can be caught by the application. Ticket #100
Diffstat (limited to 'base')
-rw-r--r--base/common/src/CMakeLists.txt2
-rw-r--r--base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java11
-rw-r--r--base/common/src/com/netscape/certsrv/request/RequestId.java11
-rw-r--r--base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java7
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/CMSException.java165
-rw-r--r--base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java17
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java5
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java5
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java25
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java5
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/RequestNotFoundException.java46
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/DRMErrorInterceptor.java43
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java105
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java50
14 files changed, 391 insertions, 106 deletions
diff --git a/base/common/src/CMakeLists.txt b/base/common/src/CMakeLists.txt
index 01ff33e47..ea9077f74 100644
--- a/base/common/src/CMakeLists.txt
+++ b/base/common/src/CMakeLists.txt
@@ -579,6 +579,7 @@ set(pki-cms_java_SRCS
com/netscape/cms/servlet/base/IndexServlet.java
com/netscape/cms/servlet/base/UserInfo.java
com/netscape/cms/servlet/base/PortsServlet.java
+ com/netscape/cms/servlet/base/CMSException.java
com/netscape/cms/servlet/base/CMSResourceService.java
com/netscape/cms/servlet/base/CMSServlet.java
com/netscape/cms/servlet/base/CMSStartServlet.java
@@ -664,6 +665,7 @@ set(pki-cms_java_SRCS
com/netscape/cms/servlet/request/IReqParser.java
com/netscape/cms/servlet/request/ReqParser.java
com/netscape/cms/servlet/request/QueryReq.java
+ com/netscape/cms/servlet/request/RequestNotFoundException.java
com/netscape/cms/servlet/request/SearchReqs.java
com/netscape/cms/servlet/request/ProcessCertReq.java
com/netscape/cms/servlet/request/CertReqParser.java
diff --git a/base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java
index f998bf97a..b8bb1870b 100644
--- a/base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java
+++ b/base/common/src/com/netscape/certsrv/dbs/keydb/KeyId.java
@@ -95,6 +95,17 @@ public class KeyId {
return value.toString();
}
+ /**
+ * Converts the KeyId into its hex string representation. The string
+ * form can be stored in a database (such as the LDAP directory)
+ *
+ * @return
+ * a string containing the hex (hex 16) value for the identifier.
+ */
+ public String toHexString() {
+ return "0x"+value.toString(16);
+ }
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/base/common/src/com/netscape/certsrv/request/RequestId.java b/base/common/src/com/netscape/certsrv/request/RequestId.java
index da61f2bc0..b643fa30d 100644
--- a/base/common/src/com/netscape/certsrv/request/RequestId.java
+++ b/base/common/src/com/netscape/certsrv/request/RequestId.java
@@ -94,6 +94,17 @@ public class RequestId {
return value.toString();
}
+ /**
+ * Converts the RequestId into its hex string representation. The string
+ * form can be stored in a database (such as the LDAP directory)
+ *
+ * @return
+ * a string containing the hex (base 16) value for the identifier.
+ */
+ public String toHexString() {
+ return "0x"+value.toString(16);
+ }
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java b/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java
index 48f410c73..4dccb141f 100644
--- a/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java
+++ b/base/common/src/com/netscape/cms/servlet/admin/SystemCertificateResourceService.java
@@ -21,8 +21,6 @@ package com.netscape.cms.servlet.admin;
import java.security.cert.CertificateEncodingException;
import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import com.netscape.certsrv.apps.CMS;
@@ -39,9 +37,6 @@ import com.netscape.cms.servlet.cert.model.CertificateData;
*/
public class SystemCertificateResourceService extends CMSResourceService implements SystemCertificateResource {
- @Context
- Request request;
-
/**
* Used to retrieve the transport certificate
*/
@@ -74,7 +69,7 @@ public class SystemCertificateResourceService extends CMSResourceService impleme
e.printStackTrace();
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
- return sendConditionalGetResponse(DEFAULT_LONG_CACHE_LIFETIME, cert, request);
+ return sendConditionalGetResponse(DEFAULT_LONG_CACHE_LIFETIME, cert);
}
}
diff --git a/base/common/src/com/netscape/cms/servlet/base/CMSException.java b/base/common/src/com/netscape/cms/servlet/base/CMSException.java
new file mode 100644
index 000000000..eda5566ac
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/base/CMSException.java
@@ -0,0 +1,165 @@
+package com.netscape.cms.servlet.base;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlValue;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+public class CMSException extends RuntimeException {
+
+ private static final long serialVersionUID = 6000910362260369923L;
+
+ public int code;
+
+ public CMSException(String message) {
+ super(message);
+ code = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
+ }
+
+ public CMSException(int code, String message) {
+ super(message);
+ this.code = code;
+ }
+
+ public CMSException(Response.Status status, String message) {
+ super(message);
+ code = status.getStatusCode();
+ }
+
+ public CMSException(String message, Throwable cause) {
+ super(message, cause);
+ code = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
+ }
+
+ public CMSException(int code, String message, Throwable cause) {
+ super(message, cause);
+ this.code = code;
+ }
+
+ public CMSException(Response.Status status, String message, Throwable cause) {
+ super(message, cause);
+ code = status.getStatusCode();
+ }
+
+ public CMSException(Data data) {
+ super(data.message);
+ code = data.code;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public Data getData() {
+ Data data = new Data();
+ data.className = getClass().getName();
+ data.code = code;
+ data.message = getMessage();
+ return data;
+ }
+
+ @XmlRootElement(name="CMSException")
+ public static class Data {
+
+ @XmlElement(name="ClassName")
+ public String className;
+
+ @XmlElement(name="Code")
+ public int code;
+
+ @XmlElement(name="Message")
+ public String message;
+
+ @XmlElement(name="Attributes")
+ @XmlJavaTypeAdapter(MapAdapter.class)
+ public Map<String, String> attributes = new LinkedHashMap<String, String>();
+
+ public String getAttribute(String name) {
+ return attributes.get(name);
+ }
+
+ public void setAttribute(String name, String value) {
+ attributes.put(name, value);
+ }
+ }
+
+ public static class MapAdapter extends XmlAdapter<AttributeList, Map<String, String>> {
+
+ public AttributeList marshal(Map<String, String> map) {
+ AttributeList list = new AttributeList();
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ Attribute attribute = new Attribute();
+ attribute.name = entry.getKey();
+ attribute.value = entry.getValue();
+ list.attributes.add(attribute);
+ }
+ return list;
+ }
+
+ public Map<String, String> unmarshal(AttributeList list) {
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ for (Attribute attribute : list.attributes) {
+ map.put(attribute.name, attribute.value);
+ }
+ return map;
+ }
+ }
+
+ public static class AttributeList {
+ @XmlElement(name="Attribute")
+ public List<Attribute> attributes = new ArrayList<Attribute>();
+ }
+
+ public static class Attribute {
+
+ @XmlAttribute
+ public String name;
+
+ @XmlValue
+ public String value;
+ }
+
+ @Provider
+ public static class Mapper implements ExceptionMapper<CMSException> {
+
+ public Response toResponse(CMSException exception) {
+ // convert CMSException into HTTP response with XML content
+ return Response
+ .status(exception.getCode())
+ .entity(exception.getData())
+ .type(MediaType.TEXT_XML)
+ .build();
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ Data data = new Data();
+ data.className = CMSException.class.getName();
+ data.code = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
+ data.message = "An error has occured";
+ data.setAttribute("attr1", "value1");
+ data.setAttribute("attr2", "value2");
+
+ JAXBContext context = JAXBContext.newInstance(Data.class);
+ Marshaller marshaller = context.createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ marshaller.marshal(data, System.out);
+ }
+}
diff --git a/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java
index acddba559..24c3cd74d 100644
--- a/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java
+++ b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java
@@ -20,9 +20,11 @@ package com.netscape.cms.servlet.base;
import java.security.cert.CertificateEncodingException;
import javax.ws.rs.core.CacheControl;
+import javax.ws.rs.core.Context;
import javax.ws.rs.core.EntityTag;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Response.ResponseBuilder;
import com.netscape.certsrv.apps.CMS;
@@ -35,13 +37,24 @@ import com.netscape.cms.servlet.cert.model.CertificateData;
*
*/
public class CMSResourceService {
+
public static final String HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----";
public static final String TRAILER = "-----END NEW CERTIFICATE REQUEST-----";
// caching parameters
- protected static final int DEFAULT_LONG_CACHE_LIFETIME = 1000;
+ public static final int DEFAULT_LONG_CACHE_LIFETIME = 1000;
+
+ @Context
+ protected UriInfo uriInfo;
+
+ @Context
+ protected Request request;
+
+ public Response createOKResponse(Object object) {
+ return Response.ok(object).build();
+ }
- protected Response sendConditionalGetResponse(int ctime, Object object, Request request) {
+ public Response sendConditionalGetResponse(int ctime, Object object) {
CacheControl cc = new CacheControl();
cc.setMaxAge(ctime);
EntityTag tag = new EntityTag(Integer.toString(object.hashCode()));
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java
index 79e6ccfdb..88f2f8a82 100644
--- a/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java
@@ -20,10 +20,8 @@ package com.netscape.cms.servlet.key;
import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
import com.netscape.cms.servlet.base.CMSResourceService;
import com.netscape.cms.servlet.key.model.KeyDAO;
@@ -43,9 +41,6 @@ import com.netscape.certsrv.dbs.keydb.KeyId;
*/
public class KeyResourceService extends CMSResourceService implements KeyResource{
- @Context
- UriInfo uriInfo;
-
/**
* Used to retrieve a key
* @param data
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java b/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
index a7876a6c6..d525d5a77 100644
--- a/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
+++ b/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java
@@ -21,9 +21,7 @@
package com.netscape.cms.servlet.key;
import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.EBaseException;
@@ -38,9 +36,6 @@ import com.netscape.cmsutil.ldap.LDAPUtil;
*/
public class KeysResourceService extends CMSResourceService implements KeysResource {
- @Context
- UriInfo uriInfo;
-
/**
* Used to generate list of key infos based on the search parameters
*/
diff --git a/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java b/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java
index 43e58bbdc..b9ba206c1 100644
--- a/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java
+++ b/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java
@@ -19,27 +19,24 @@
package com.netscape.cms.servlet.request;
import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
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.certsrv.request.RequestId;
+import com.netscape.cms.servlet.base.CMSException;
import com.netscape.cms.servlet.base.CMSResourceService;
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
- *
+ *
*/
public class KeyRequestResourceService extends CMSResourceService implements KeyRequestResource {
- @Context
- UriInfo uriInfo;
-
/**
* Used to retrieve key request info for a specific request
*/
@@ -52,15 +49,15 @@ public class KeyRequestResourceService extends CMSResourceService implements Key
} catch (EBaseException e) {
// log error
e.printStackTrace();
- throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
+ throw new CMSException(e.getMessage(), e);
}
if (info == null) {
// request does not exist
- throw new WebApplicationException(Response.Status.NOT_FOUND);
+ throw new RequestNotFoundException(id);
}
return info;
}
-
+
// Archiving - used to test integration with a browser
public KeyRequestInfo archiveKey(MultivaluedMap<String, String> form) {
ArchivalRequestData data = new ArchivalRequestData(form);
@@ -88,7 +85,7 @@ public class KeyRequestResourceService extends CMSResourceService implements Key
}
return info;
}
-
+
//Recovery - used to test integration with a browser
public KeyRequestInfo recoverKey(MultivaluedMap<String, String> form) {
RecoveryRequestData data = new RecoveryRequestData(form);
@@ -117,7 +114,7 @@ public class KeyRequestResourceService extends CMSResourceService implements Key
}
return info;
}
-
+
public void approveRequest(RequestId id) {
if (id == null) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
@@ -132,7 +129,7 @@ public class KeyRequestResourceService extends CMSResourceService implements Key
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
-
+
public void rejectRequest(RequestId id) {
if (id == null) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
@@ -147,7 +144,7 @@ public class KeyRequestResourceService extends CMSResourceService implements Key
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
}
-
+
public void cancelRequest(RequestId id) {
if (id == null) {
throw new WebApplicationException(Response.Status.BAD_REQUEST);
diff --git a/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java b/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java
index 11898ef7a..82b1efa07 100644
--- a/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java
+++ b/base/common/src/com/netscape/cms/servlet/request/KeyRequestsResourceService.java
@@ -19,9 +19,7 @@
package com.netscape.cms.servlet.request;
import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.EBaseException;
@@ -37,9 +35,6 @@ import com.netscape.cmsutil.ldap.LDAPUtil;
*/
public class KeyRequestsResourceService extends CMSResourceService implements KeyRequestsResource{
- @Context
- UriInfo uriInfo;
-
/**
* Used to generate list of key requests based on the search parameters
*/
diff --git a/base/common/src/com/netscape/cms/servlet/request/RequestNotFoundException.java b/base/common/src/com/netscape/cms/servlet/request/RequestNotFoundException.java
new file mode 100644
index 000000000..5d6b5563b
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/RequestNotFoundException.java
@@ -0,0 +1,46 @@
+package com.netscape.cms.servlet.request;
+
+import javax.ws.rs.core.Response;
+
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cms.servlet.base.CMSException;
+
+public class RequestNotFoundException extends CMSException {
+
+ private static final long serialVersionUID = -4784839378360933483L;
+
+ public RequestId requestId;
+
+ public RequestNotFoundException(RequestId requestId) {
+ this(requestId, "Request ID "+requestId.toHexString()+" not found");
+ }
+
+ public RequestNotFoundException(RequestId requestId, String message) {
+ super(Response.Status.NOT_FOUND, message);
+ this.requestId = requestId;
+ }
+
+ public RequestNotFoundException(RequestId requestId, String message, Throwable cause) {
+ super(Response.Status.NOT_FOUND, message, cause);
+ this.requestId = requestId;
+ }
+
+ public RequestNotFoundException(Data data) {
+ super(data);
+ requestId = new RequestId(data.getAttribute("requestId"));
+ }
+
+ public Data getData() {
+ Data data = super.getData();
+ data.setAttribute("requestId", requestId.toString());
+ return data;
+ }
+
+ public RequestId getRequestId() {
+ return requestId;
+ }
+
+ public void setRequestId(RequestId requestId) {
+ this.requestId = requestId;
+ }
+}
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMErrorInterceptor.java b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMErrorInterceptor.java
new file mode 100644
index 000000000..7572acef5
--- /dev/null
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMErrorInterceptor.java
@@ -0,0 +1,43 @@
+package com.netscape.cms.servlet.test;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.jboss.resteasy.client.ClientResponse;
+import org.jboss.resteasy.client.core.ClientErrorInterceptor;
+
+import com.netscape.cms.servlet.base.CMSException;
+
+public class DRMErrorInterceptor implements ClientErrorInterceptor {
+
+ public void handle(ClientResponse<?> response) {
+
+ // handle HTTP code 4xx and 5xx
+ int code = response.getResponseStatus().getStatusCode();
+ if (code < 400) return;
+
+ MultivaluedMap<String, String> headers = response.getHeaders();
+ String contentType = headers.getFirst("Content-Type");
+
+ // handle XML content only
+ if (!contentType.startsWith(MediaType.TEXT_XML)) return;
+
+ CMSException exception;
+
+ try {
+ // Requires RESTEasy 2.3.2
+ // https://issues.jboss.org/browse/RESTEASY-652
+ CMSException.Data data = response.getEntity(CMSException.Data.class);
+
+ Class<?> clazz = Class.forName(data.className);
+ exception = (CMSException) clazz.getConstructor(CMSException.Data.class).newInstance(data);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ throw exception;
+ }
+
+}
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
index 651873b20..14b2aa3dc 100644
--- a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
@@ -2,9 +2,9 @@ package com.netscape.cms.servlet.test;
import java.io.IOException;
import java.net.InetAddress;
-import java.net.MalformedURLException;
import java.net.Socket;
-import java.net.URL;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Enumeration;
@@ -18,9 +18,14 @@ import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.jboss.resteasy.client.ClientExecutor;
import org.jboss.resteasy.client.ClientResponse;
import org.jboss.resteasy.client.ProxyFactory;
+import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
+import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
+import org.mozilla.jss.ssl.SSLSocket;
+
import com.netscape.certsrv.dbs.keydb.KeyId;
import com.netscape.certsrv.request.RequestId;
-import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor;
import com.netscape.cms.servlet.admin.SystemCertificateResource;
import com.netscape.cms.servlet.cert.model.CertificateData;
import com.netscape.cms.servlet.key.KeyResource;
@@ -36,10 +41,6 @@ import com.netscape.cms.servlet.request.model.KeyRequestInfos;
import com.netscape.cms.servlet.request.model.RecoveryRequestData;
import com.netscape.cmsutil.util.Utils;
-import org.mozilla.jss.ssl.SSLCertificateApprovalCallback;
-import org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback;
-import org.mozilla.jss.ssl.SSLSocket;
-
public class DRMRestClient {
// Callback to approve or deny returned SSL server certs
@@ -47,7 +48,7 @@ public class DRMRestClient {
// ToDO: Look into taking this JSS http client code and move it into
// its own class to be used by possible future clients.
private class ServerCertApprovalCB implements SSLCertificateApprovalCallback {
-
+
public boolean approve(org.mozilla.jss.crypto.X509Certificate servercert,
SSLCertificateApprovalCallback.ValidityStatus status) {
@@ -81,7 +82,7 @@ public class DRMRestClient {
reason == SSLCertificateApprovalCallback.ValidityStatus.BAD_CERT_DOMAIN) {
//Allow these two since we haven't necessarily installed the CA cert for trust
- // and we are choosing "localhost" as the host for this client.
+ // and we are choosing "localhost" as the host for this client.
return true;
@@ -93,91 +94,95 @@ public class DRMRestClient {
return false;
}
}
-
+
private class JSSProtocolSocketFactory implements ProtocolSocketFactory {
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
-
+
SSLSocket sock = createJSSSocket(host,port, null, 0, null);
- return (Socket) sock;
+ return sock;
}
@Override
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException,
UnknownHostException {
-
+
SSLSocket sock = createJSSSocket(host,port, clientHost, clientPort, null);
- return (Socket) sock;
+ return sock;
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params)
throws IOException, UnknownHostException, ConnectTimeoutException {
-
+
SSLSocket sock = createJSSSocket(host, port, localAddress, localPort, null);
- return (Socket) sock;
+ return sock;
}
}
- private SSLSocket createJSSSocket(String host, int port, InetAddress localAddress,
+ private SSLSocket createJSSSocket(String host, int port, InetAddress localAddress,
int localPort, SSLClientCertificateSelectionCallback clientCertSelectionCallback)
throws IOException, UnknownHostException, ConnectTimeoutException {
-
+
SSLSocket sock = new SSLSocket(InetAddress.getByName(host),
port,
localAddress,
localPort,
new ServerCertApprovalCB(),
null);
-
+
if(sock != null && clientCertNickname != null) {
sock.setClientCertNickname(clientCertNickname);
}
-
+
return sock;
-
+
}
private KeyResource keyClient;
private KeysResource keysClient;
private KeyRequestsResource keyRequestsClient;
private KeyRequestResource keyRequestClient;
private SystemCertificateResource systemCertClient;
-
+
private String clientCertNickname = null;
-
- public DRMRestClient(String baseUri, String clientCertNick) throws MalformedURLException {
-
+
+ public DRMRestClient(String baseUri, String clientCertNick) throws URISyntaxException {
+
// For SSL we are assuming the caller has already intialized JSS and has
// a valid CryptoManager and CryptoToken
// optional clientCertNickname is provided for use if required.
-
-
- URL url = new URL(baseUri);
-
- String protocol = url.getProtocol();
- int port = url.getPort();
-
+
+
+ URI uri = new URI(baseUri);
+
+ String protocol = uri.getScheme();
+ int port = uri.getPort();
+
clientCertNickname = null;
if(protocol != null && protocol.equals("https")) {
if (clientCertNick != null) {
clientCertNickname = clientCertNick;
- }
-
- Protocol.registerProtocol("https",
+ }
+
+ Protocol.registerProtocol("https",
new Protocol(protocol, new JSSProtocolSocketFactory(), port));
}
-
+
HttpClient httpclient = new HttpClient();
ClientExecutor executor = new ApacheHttpClientExecutor(httpclient);
- systemCertClient = ProxyFactory.create(SystemCertificateResource.class, baseUri, executor);
- keyRequestsClient = ProxyFactory.create(KeyRequestsResource.class, baseUri, executor);
- keyRequestClient = ProxyFactory.create(KeyRequestResource.class, baseUri, executor);
- keysClient = ProxyFactory.create(KeysResource.class, baseUri, executor);
- keyClient = ProxyFactory.create(KeyResource.class, baseUri, executor);
+ ResteasyProviderFactory providerFactory = ResteasyProviderFactory.getInstance();
+ providerFactory.addClientErrorInterceptor(new DRMErrorInterceptor());
+
+ systemCertClient = ProxyFactory.create(SystemCertificateResource.class, uri, executor, providerFactory);
+ keyRequestsClient = ProxyFactory.create(KeyRequestsResource.class, uri, executor, providerFactory);
+ keyRequestClient = ProxyFactory.create(KeyRequestResource.class, uri, executor, providerFactory);
+ keysClient = ProxyFactory.create(KeysResource.class, uri, executor, providerFactory);
+ keyClient = ProxyFactory.create(KeyResource.class, uri, executor, providerFactory);
+ keyClient = ProxyFactory.create(KeyResource.class, uri, executor, providerFactory);
}
-
+
public String getTransportCert() {
@SuppressWarnings("unchecked")
ClientResponse<CertificateData> response = (ClientResponse<CertificateData>) systemCertClient.getTransportCert();
@@ -185,7 +190,7 @@ public class DRMRestClient {
String transportCert = certData.getB64();
return transportCert;
}
-
+
public Collection<KeyRequestInfo> listRequests(String requestState, String requestType) {
KeyRequestInfos infos = keyRequestsClient.listRequests(
requestState, requestType, null, new RequestId(0), 100, 100, 10
@@ -193,7 +198,7 @@ public class DRMRestClient {
Collection<KeyRequestInfo> list = infos.getRequests();
return list;
}
-
+
public KeyRequestInfo archiveSecurityData(byte[] encoded, String clientId, String dataType) {
// create archival request
ArchivalRequestData data = new ArchivalRequestData();
@@ -205,7 +210,7 @@ public class DRMRestClient {
KeyRequestInfo info = keyRequestClient.archiveKey(data);
return info;
}
-
+
public KeyDataInfo getKeyData(String clientId, String status) {
KeyDataInfos infos = keysClient.listKeys(clientId, status, 100, 10);
Collection<KeyDataInfo> list = infos.getKeyInfos();
@@ -220,7 +225,7 @@ public class DRMRestClient {
}
return null;
}
-
+
public KeyRequestInfo requestRecovery(KeyId keyId, byte[] rpwd, byte[] rkey, byte[] nonceData) {
// create recovery request
RecoveryRequestData data = new RecoveryRequestData();
@@ -239,11 +244,11 @@ public class DRMRestClient {
KeyRequestInfo info = keyRequestClient.recoverKey(data);
return info;
}
-
+
public void approveRecovery(RequestId recoveryId) {
keyRequestClient.approveRequest(recoveryId);
}
-
+
public KeyData retrieveKey(KeyId keyId, RequestId requestId, byte[] rpwd, byte[] rkey, byte[] nonceData) {
// create recovery request
RecoveryRequestData data = new RecoveryRequestData();
@@ -263,4 +268,8 @@ public class DRMRestClient {
KeyData key = keyClient.retrieveKey(data);
return key;
}
+
+ public KeyRequestInfo getRequest(RequestId id) {
+ return keyRequestClient.getRequestInfo(id);
+ }
}
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
index 8d83247b8..5323777bd 100644
--- a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
@@ -17,12 +17,17 @@
// --- END COPYRIGHT BLOCK ---
package com.netscape.cms.servlet.test;
-import java.net.MalformedURLException;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.Random;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.PosixParser;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.crypto.AlreadyInitializedException;
import org.mozilla.jss.crypto.CryptoToken;
@@ -32,19 +37,13 @@ import org.mozilla.jss.crypto.KeyGenAlgorithm;
import org.mozilla.jss.crypto.SymmetricKey;
import org.mozilla.jss.util.Password;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.PosixParser;
-
import com.netscape.certsrv.dbs.keydb.KeyId;
import com.netscape.certsrv.request.RequestId;
import com.netscape.cms.servlet.base.CMSResourceService;
import com.netscape.cms.servlet.key.model.KeyData;
import com.netscape.cms.servlet.key.model.KeyDataInfo;
import com.netscape.cms.servlet.request.KeyRequestResource;
+import com.netscape.cms.servlet.request.RequestNotFoundException;
import com.netscape.cms.servlet.request.model.KeyRequestInfo;
import com.netscape.cmsutil.crypto.CryptoUtil;
import com.netscape.cmsutil.util.Utils;
@@ -102,18 +101,18 @@ public class DRMTest {
if (cmd.hasOption("d")) {
db_dir = cmd.getOptionValue("d");
}
-
+
if (cmd.hasOption("s")) {
if(cmd.getOptionValue("s") != null && cmd.getOptionValue("s").equals("true")) {
protocol = "https";
}
}
-
+
if (cmd.hasOption("c")) {
String nick = cmd.getOptionValue("c");
-
+
if (nick != null && protocol.equals("https")) {
- clientCertNickname = nick;
+ clientCertNickname = nick;
}
}
@@ -123,7 +122,7 @@ public class DRMTest {
}
// used for crypto operations
- byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
IVParameterSpec ivps = null;
IVParameterSpec ivps_server = null;
@@ -168,7 +167,7 @@ public class DRMTest {
try {
CryptoManager.initialize(db_dir);
} catch (AlreadyInitializedException e) {
- // it is ok if it is already initialized
+ // it is ok if it is already initialized
} catch (Exception e) {
log("INITIALIZATION ERROR: " + e.toString());
System.exit(1);
@@ -192,15 +191,14 @@ public class DRMTest {
}
// Set base URI and get client
-
-
+
+
String baseUri = protocol + "://" + host + ":" + port + "/kra/pki";
DRMRestClient client;
try {
client = new DRMRestClient(baseUri, clientCertNickname);
- } catch (MalformedURLException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
return;
}
@@ -294,7 +292,7 @@ public class DRMTest {
ivps_server = new IVParameterSpec(Utils.base64decode(keyData.getNonceData()));
try {
- recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server,
+ recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server,
Utils.base64decode(wrappedRecoveredKey),
recoveryKey, EncryptionAlgorithm.DES3_CBC_PAD);
} catch (Exception e) {
@@ -406,7 +404,7 @@ public class DRMTest {
wrappedRecoveredKey = keyData.getWrappedPrivateData();
ivps_server = new IVParameterSpec( Utils.base64decode(keyData.getNonceData()));
try {
- recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server,
+ recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server,
Utils.base64decode(wrappedRecoveredKey),
recoveryKey, EncryptionAlgorithm.DES3_CBC_PAD);
recoveredKey = new String(Utils.base64decode(recoveredKey), "UTF-8");
@@ -476,6 +474,16 @@ public class DRMTest {
} else {
log("Success: recovered and archived passphrases do match!");
}
+
+ // Test 23: Get non-existent request
+ RequestId requestId = new RequestId("0xabcdef");
+ log("Getting non-existent request: " + requestId.toHexString());
+ try {
+ client.getRequest(requestId);
+ log("Error: getting non-existent request does not throw an exception");
+ } catch (RequestNotFoundException e) {
+ log("Success: getting non-existent request throws an exception: "+e.getMessage()+" ("+e.getRequestId().toHexString()+")");
+ }
}
private static void log(String string) {