summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/common/src/com/netscape/certsrv/key/KeyData.java16
-rw-r--r--base/common/src/com/netscape/certsrv/key/KeyRecoveryRequest.java33
-rw-r--r--base/common/src/com/netscape/certsrv/kra/KRAClient.java22
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java38
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/key/KeyService.java70
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java65
6 files changed, 237 insertions, 7 deletions
diff --git a/base/common/src/com/netscape/certsrv/key/KeyData.java b/base/common/src/com/netscape/certsrv/key/KeyData.java
index 2ee7d1b92..b71861470 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyData.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyData.java
@@ -39,6 +39,9 @@ public class KeyData {
@XmlElement
String nonceData;
+ @XmlElement
+ String p12Data;
+
public KeyData() {
// required for JAXB (defaults)
}
@@ -73,4 +76,17 @@ public class KeyData {
this.nonceData = nonceData;
}
+ /**
+ * @return the p12Data
+ */
+ public String getP12Data() {
+ return p12Data;
+ }
+
+ /**
+ * @param p12Data the p12Data to set
+ */
+ public void setP12Data(String p12Data) {
+ this.p12Data = p12Data;
+ }
}
diff --git a/base/common/src/com/netscape/certsrv/key/KeyRecoveryRequest.java b/base/common/src/com/netscape/certsrv/key/KeyRecoveryRequest.java
index d14f61241..aa69d8336 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyRecoveryRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyRecoveryRequest.java
@@ -64,6 +64,12 @@ public class KeyRecoveryRequest {
@XmlElement
protected String nonceData;
+ @XmlElement
+ protected String certificate;
+
+ @XmlElement
+ protected String passphrase;
+
public KeyRecoveryRequest() {
// required for JAXB (defaults)
}
@@ -152,4 +158,31 @@ public class KeyRecoveryRequest {
this.nonceData = nonceData;
}
+ /**
+ * @return the certificate
+ */
+ public String getCertificate() {
+ return certificate;
+ }
+
+ /**
+ * @param certificate the certificate to set
+ */
+ public void setCertificate(String certificate) {
+ this.certificate = certificate;
+ }
+
+ /**
+ * @return the passphrase
+ */
+ public String getPassphrase() {
+ return passphrase;
+ }
+
+ /**
+ * @param passphrase the passphrase to set
+ */
+ public void setPassphrase(String passphrase) {
+ this.passphrase = passphrase;
+ }
}
diff --git a/base/common/src/com/netscape/certsrv/kra/KRAClient.java b/base/common/src/com/netscape/certsrv/kra/KRAClient.java
index 21f1a957d..81d600c33 100644
--- a/base/common/src/com/netscape/certsrv/kra/KRAClient.java
+++ b/base/common/src/com/netscape/certsrv/kra/KRAClient.java
@@ -144,4 +144,26 @@ public class KRAClient extends SubsystemClient {
public KeyRequestInfo getRequest(RequestId id) {
return keyRequestClient.getRequestInfo(id);
}
+
+ public RequestId requestKeyRecovery(String keyId, String b64Certificate) {
+ // create key recovery request
+ KeyRecoveryRequest data = new KeyRecoveryRequest();
+ data.setKeyId(new KeyId(keyId));
+ data.setCertificate(b64Certificate);
+
+ @SuppressWarnings("unchecked")
+ ClientResponse<KeyRequestInfo> response = (ClientResponse<KeyRequestInfo>)
+ keyRequestClient.recoverKey(data);
+ return client.getEntity(response).getRequestId();
+ }
+
+ public KeyData recoverKey(RequestId requestId, String passphrase) {
+ // recover key based on approved request
+ KeyRecoveryRequest data = new KeyRecoveryRequest();
+ data.setRequestId(requestId);
+ data.setPassphrase(passphrase);
+
+ KeyData key = keyClient.retrieveKey(data);
+ return key;
+ }
}
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 8b254a5e3..06c368e5b 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
@@ -491,6 +491,44 @@ public class DRMTest {
} catch (RequestNotFoundException e) {
log("Success: getting non-existent request throws an exception: "+e.getMessage()+" ("+e.getRequestId().toHexString()+")");
}
+
+ // Test 24: Request x509 key recovery
+ // This test requires to retrieve keyId and matching certificate
+ // from installed instances of CA and DRM
+ String keyID = "1";
+ String b64Certificate = "MIIC+TCCAeGgAwIBAgIBDDANBgkqhkiG9w0BAQsFADBOMSswKQYDVQQKDCJ1c2Vy"+
+ "c3lzLnJlZGhhdC5jb20gU2VjdXJpdHkgRG9tYWluMR8wHQYDVQQDDBZDQSBTaWdu"+
+ "aW5nIENlcnRpZmljYXRlMB4XDTEzMTAyNTE5MzQwM1oXDTE0MDQyMzE5MzQwM1ow"+
+ "EzERMA8GCgmSJomT8ixkAQEMAXgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB"+
+ "ALhLfGmKvxFsKXPh49q1QsluXU3WlyS1XnpDLgOAhgTNgO4sG6CpPdv6hZYIvQBb"+
+ "ZQ5bhuML+NXK+Q+EIiNk1cUTxgL3a30sPzy6QaFWxwM8i4uXm4nCBYv7T+n4V6/O"+
+ "xHIM2Ch/dviAb3vz+M9trErv9t+d2H8jNXT3sHuDb/kvAgMBAAGjgaAwgZ0wHwYD"+
+ "VR0jBBgwFoAUh1cxWFRY+nMsx4odQQI1GqyFxP8wSwYIKwYBBQUHAQEEPzA9MDsG"+
+ "CCsGAQUFBzABhi9odHRwOi8vZG9ndGFnMjAudXNlcnN5cy5yZWRoYXQuY29tOjgw"+
+ "ODAvY2Evb2NzcDAOBgNVHQ8BAf8EBAMCBSAwHQYDVR0lBBYwFAYIKwYBBQUHAwIG"+
+ "CCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4IBAQCvmbUzQOouE2LgQQcKfmgwwJMJ"+
+ "9tMrPwDUtyFdaIFoPL4uZaujSscaN4IWK2r5vIMJ65jwYCI7sI9En2ZfO28J9dQj"+
+ "lpqu6TaJ+xtaMk7OvXpVB7lJk73HAttMGjETlkoq/6EjxcugmJsDqVD0b2tO7Vd0"+
+ "hroBe2uPDHM2ASewZF415lUcRh0URtmxSazTInbyxpmy1wgSJQ0C6fMCeT+hUFlA"+
+ "0P4k1TIprapGVq7FpKcqlhK2gTBfTSnoO7gmXG/9MxJiYpb/Aph8ptXq6quHz1Mj"+
+ "greWr3xTsy6gF2yphUEkGHh4v22XvK+FLx9Jb6zloMWA2GG9gpUpvMnl1fH4";
+
+ log("Requesting X509 key recovery.");
+ recoveryRequestId = client.requestKeyRecovery(keyID, b64Certificate);
+ log("Requesting X509 key recovery request: " + recoveryRequestId);
+
+ // Test 25: Approve x509 key recovery
+ log("Approving X509 key recovery request: " + recoveryRequestId);
+ client.approveRecovery(recoveryRequestId);
+
+ // Test 26: Recover x509 key
+ log("Recovering X509 key based on request: " + recoveryRequestId);
+ try {
+ KeyData recoveredX509Key = client.recoverKey(recoveryRequestId, "netscape");
+ log("Success: X509Key recovered: "+ recoveredX509Key.getP12Data());
+ } catch (RequestNotFoundException e) {
+ log("Error: recovering X509Key");
+ }
}
private static void log(String string) {
diff --git a/base/server/cms/src/com/netscape/cms/servlet/key/KeyService.java b/base/server/cms/src/com/netscape/cms/servlet/key/KeyService.java
index 27cc909e5..a2e48b9ec 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/key/KeyService.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/key/KeyService.java
@@ -53,6 +53,7 @@ import com.netscape.certsrv.key.KeyRecoveryRequest;
import com.netscape.certsrv.key.KeyRequestInfo;
import com.netscape.certsrv.key.KeyResource;
import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
import com.netscape.certsrv.logging.ILogger;
import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IRequestQueue;
@@ -60,6 +61,7 @@ import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestStatus;
import com.netscape.cms.servlet.base.PKIService;
import com.netscape.cmsutil.ldap.LDAPUtil;
+import com.netscape.cmsutil.util.Utils;
/**
* @author alee
@@ -89,11 +91,13 @@ public class KeyService extends PKIService implements KeyResource {
private IKeyRepository repo;
private IKeyRecoveryAuthority kra;
private IRequestQueue queue;
+ private IKeyService service;
public KeyService() {
kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" );
repo = kra.getKeyRepository();
queue = kra.getRequestQueue();
+ service = (IKeyService) kra;
}
/**
@@ -108,11 +112,25 @@ public class KeyService extends PKIService implements KeyResource {
throw new BadRequestException("Cannot retrieve key. Invalid request");
}
// auth and authz
- KeyId keyId = validateRequest(data);
RequestId requestID = data.getRequestId();
+ IRequest request;
+ try {
+ request = queue.findRequest(requestID);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ auditRetrieveKey(ILogger.FAILURE, requestID, null, e.getMessage());
+ throw new PKIException(e.getMessage());
+ }
+ String type = request.getRequestType();
+ KeyId keyId = null;
KeyData keyData;
try {
- keyData = getKey(keyId, data);
+ if (IRequest.KEYRECOVERY_REQUEST.equals(type)) {
+ keyData = recoverKey(data);
+ } else {
+ keyId = validateRequest(data);
+ keyData = getKey(keyId, data);
+ }
} catch (EBaseException e) {
e.printStackTrace();
auditRetrieveKey(ILogger.FAILURE, requestID, keyId, e.getMessage());
@@ -403,4 +421,52 @@ public class KeyService extends PKIService implements KeyResource {
reason);
auditor.log(msg);
}
+
+ /**
+ * Used to retrieve a key
+ * @param data
+ * @return
+ */
+ private KeyData recoverKey(KeyRecoveryRequest data) {
+ // confirm request exists
+ RequestId reqId = data.getRequestId();
+
+ IRequest request = null;
+ try {
+ request = queue.findRequest(reqId);
+ } catch (EBaseException e) {
+ }
+ if (request == null) {
+ throw new HTTPGoneException("No request record.");
+ }
+ String type = request.getRequestType();
+ RequestStatus status = request.getRequestStatus();
+ if (!IRequest.KEYRECOVERY_REQUEST.equals(type) ||
+ !status.equals(RequestStatus.APPROVED)) {
+ auditRetrieveKey(ILogger.FAILURE, reqId, null, "Unauthorized request.");
+ throw new UnauthorizedException("Unauthorized request.");
+ }
+
+ String passphrase = data.getPassphrase();
+ byte pkcs12[] = null;
+ try {
+ pkcs12 = service.doKeyRecovery(reqId.toString(), passphrase);
+ } catch (EBaseException e) {
+ }
+ if (pkcs12 == null) {
+ throw new HTTPGoneException("Key not recovered.");
+ }
+ String pkcs12base64encoded = Utils.base64encode(pkcs12);
+
+ KeyData keyData = new KeyData();
+ keyData.setP12Data(pkcs12base64encoded);
+
+ try {
+ queue.processRequest(request);
+ queue.markAsServiced(request);
+ } catch (EBaseException e) {
+ }
+
+ return keyData;
+ }
}
diff --git a/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java b/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java
index 06b03176d..ada11be7c 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java
@@ -18,8 +18,10 @@
package com.netscape.cms.servlet.request;
+import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
+import java.security.cert.CertificateException;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Context;
@@ -30,6 +32,8 @@ import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
+import netscape.security.x509.X509CertImpl;
+
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.BadRequestException;
import com.netscape.certsrv.base.EBaseException;
@@ -40,12 +44,17 @@ import com.netscape.certsrv.key.KeyRecoveryRequest;
import com.netscape.certsrv.key.KeyRequestInfo;
import com.netscape.certsrv.key.KeyRequestInfos;
import com.netscape.certsrv.key.KeyRequestResource;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.kra.IKeyService;
import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestNotFoundException;
import com.netscape.cms.servlet.base.PKIService;
import com.netscape.cms.servlet.key.KeyRequestDAO;
import com.netscape.cmsutil.ldap.LDAPUtil;
+import com.netscape.cmsutil.util.Utils;
/**
* @author alee
@@ -79,6 +88,16 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
public static final int DEFAULT_MAXRESULTS = 100;
public static final int DEFAULT_MAXTIME = 10;
+ private IKeyRecoveryAuthority kra;
+ private IRequestQueue queue;
+ private IKeyService service;
+
+ public KeyRequestService() {
+ kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" );
+ queue = kra.getRequestQueue();
+ service = (IKeyService) kra;
+ }
+
/**
* Used to retrieve key request info for a specific request
*/
@@ -160,14 +179,16 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
if (data == null) {
throw new BadRequestException("Invalid request.");
}
- if (data.getTransWrappedSessionKey() == null
- && data.getSessionWrappedPassphrase() != null) {
+ if (data.getCertificate() == null &&
+ data.getTransWrappedSessionKey() == null &&
+ data.getSessionWrappedPassphrase() != null) {
throw new BadRequestException("No wrapped session key.");
}
KeyRequestDAO dao = new KeyRequestDAO();
KeyRequestInfo info;
try {
- info = dao.submitRequest(data, uriInfo);
+ info = (data.getCertificate() != null)?
+ requestKeyRecovery(data): dao.submitRequest(data, uriInfo);
auditRecoveryRequestMade(info.getRequestId(), ILogger.SUCCESS, data.getKeyId());
return Response
@@ -182,6 +203,33 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
}
}
+ private KeyRequestInfo requestKeyRecovery(KeyRecoveryRequest data) {
+ KeyRequestInfo info = null;
+ if (data == null) {
+ throw new BadRequestException("Invalid request.");
+ }
+ String keyId = data.getKeyId().toString();
+ String b64Certificate = data.getCertificate();
+ byte[] certData = Utils.base64decode(b64Certificate);
+ String agentID = servletRequest.getUserPrincipal().getName();
+ String requestId = null;
+ try {
+ requestId = service.initAsyncKeyRecovery(new BigInteger(keyId), new X509CertImpl(certData), agentID);
+ } catch (EBaseException | CertificateException e) {
+ e.printStackTrace();
+ throw new PKIException(e.toString());
+ }
+ IRequest request = null;
+ try {
+ request = queue.findRequest(new RequestId(requestId));
+ } catch (EBaseException e) {
+ }
+ KeyRequestDAO dao = new KeyRequestDAO();
+ info = dao.createCMSRequestInfo(request, uriInfo);
+
+ return info;
+ }
+
@Override
public void approveRequest(RequestId id) {
if (id == null) {
@@ -190,8 +238,15 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
// auth and authz
KeyRequestDAO dao = new KeyRequestDAO();
try {
- dao.approveRequest(id);
- auditRecoveryRequestChange(id, ILogger.SUCCESS, "approve");
+ IRequest request = queue.findRequest(id);
+ String type = request.getRequestType();
+ if (IRequest.KEYRECOVERY_REQUEST.equals(type)) {
+ service.addAgentAsyncKeyRecovery(id.toString(), servletRequest.getUserPrincipal().getName());
+ auditRecoveryRequestChange(id, ILogger.SUCCESS, "approve");
+ } else if (IRequest.SECURITY_DATA_RECOVERY_REQUEST.equals(type)) {
+ dao.approveRequest(id);
+ auditRecoveryRequestChange(id, ILogger.SUCCESS, "approve");
+ }
} catch (EBaseException e) {
e.printStackTrace();
auditRecoveryRequestChange(id, ILogger.FAILURE, "approve");