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)
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) {