summaryrefslogtreecommitdiffstats
path: root/base/kra
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/kra
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/kra')
-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
3 files changed, 129 insertions, 69 deletions
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) {