>From 0330e0d3a1738ebc3dc1add2dc731ae513f41560 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Wed, 29 Jan 2014 13:29:23 -0500
Subject: [PATCH 187/187] Added more client code for DRM tests

---
 .../src/com/netscape/certsrv/key/KeyClient.java    | 24 +++++++
 .../netscape/certsrv/key/KeyRequestResource.java   | 12 ++--
 .../certsrv/key/SymKeyGenerationRequest.java       | 28 ++++++--
 .../src/com/netscape/certsrv/kra/KRAClient.java    | 19 ++++-
 .../src/com/netscape/cms/servlet/test/DRMTest.java | 82 +++++++++++++++++++++-
 .../kra/src/com/netscape/kra/SymKeyGenService.java | 24 ++-----
 .../netscape/cms/servlet/key/KeyRequestDAO.java    | 27 ++-----
 .../cms/servlet/request/KeyRequestService.java     | 15 +++-
 8 files changed, 171 insertions(+), 60 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/key/KeyClient.java b/base/common/src/com/netscape/certsrv/key/KeyClient.java
index 81519509e3b66dbbca21a720d4e34a2a2a71235c..5faab6fafe70c0ca0363887e5059b8354c7d30fc 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyClient.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyClient.java
@@ -19,6 +19,8 @@ package com.netscape.certsrv.key;
 
 import java.net.URISyntaxException;
 
+import org.jboss.resteasy.client.ClientResponse;
+
 import com.netscape.certsrv.client.Client;
 import com.netscape.certsrv.client.PKIClient;
 import com.netscape.certsrv.request.RequestId;
@@ -67,4 +69,26 @@ public class KeyClient extends Client {
                 maxResults,
                 maxTime);
     }
+
+    public KeyRequestInfo createRequest(KeyRequest data) {
+        @SuppressWarnings("unchecked")
+        ClientResponse<KeyRequestInfo> response = (ClientResponse<KeyRequestInfo>) keyRequestClient.createRequest(data);
+        return response.getEntity();
+    }
+
+    public KeyRequestInfo getRequestInfo(RequestId id) {
+        return keyRequestClient.getRequestInfo(id);
+    }
+
+    public void approveRequest(RequestId id) {
+        keyRequestClient.approveRequest(id);
+    }
+
+    public void rejectRequest(RequestId id) {
+        keyRequestClient.rejectRequest(id);
+    }
+
+    public void cancelRequest(RequestId id) {
+        keyRequestClient.cancelRequest(id);
+    }
 }
diff --git a/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java b/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java
index 3f2536100c43267be0a216d4fe7356d4d8c50dd9..7531a2425497a30d2ee29578f01d64a9e7988424 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java
@@ -23,14 +23,14 @@ import com.netscape.certsrv.request.RequestId;
 public interface KeyRequestResource {
 
     /* Data types */
-    public final String SYMMETRIC_KEY_TYPE = "symmetricKey";
-    public final String PASS_PHRASE_TYPE = "passPhrase";
-    public final String ASYMMETRIC_KEY_TYPE = "asymmetricKey";
+    public static final String SYMMETRIC_KEY_TYPE = "symmetricKey";
+    public static final String PASS_PHRASE_TYPE = "passPhrase";
+    public static final String ASYMMETRIC_KEY_TYPE = "asymmetricKey";
 
     /* Request types */
-    public final String ARCHIVAL_REQUEST = "archival";
-    public final String KEY_GENERATION_REQUEST = "keygen";
-    public final String RECOVERY_REQUEST = "recovery";
+    public static final String ARCHIVAL_REQUEST = "archival";
+    public static final String KEY_GENERATION_REQUEST = "keygen";
+    public static final String RECOVERY_REQUEST = "recovery";
 
     /**
      * Used to generate list of key requests based on the search parameters
diff --git a/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java b/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
index 19e6aa67c01c46c081a16d4a6bf1b2de465e56dc..ad6ad6b6a445e3178dbaabc422c7687856ddf044 100644
--- a/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
@@ -2,7 +2,9 @@ package com.netscape.certsrv.key;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.ws.rs.core.MultivaluedMap;
 import javax.xml.bind.annotation.XmlAccessType;
@@ -10,6 +12,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import org.apache.commons.lang.StringUtils;
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
 
 /**
  * @author alee
@@ -24,13 +27,24 @@ public class SymKeyGenerationRequest extends KeyRequest {
     private static final String KEY_ALGORITHM = "keyAlgorithm";
     private static final String KEY_USAGE = "keyUsage";
 
-    // usages
-    public static final String ENCRYPT_USAGE = "encrypt";
-    public static final String DECRYPT_USAGE = "decrypt";
-    public static final String SIGN_USAGE = "sign";
-    public static final String VERIFY_USAGE = "verify";
-    public static final String WRAP_USAGE = "wrap";
+    /* Symmetric Key usages */
     public static final String UWRAP_USAGE = "unwrap";
+    public static final String WRAP_USAGE = "wrap";
+    public static final String VERIFY_USAGE = "verify";
+    public static final String SIGN_USAGE = "sign";
+    public static final String DECRYPT_USAGE = "decrypt";
+    public static final String ENCRYPT_USAGE = "encrypt";
+
+    public static final Map<String, KeyGenAlgorithm> KEYGEN_ALGORITHMS;
+    static {
+        KEYGEN_ALGORITHMS = new HashMap<String, KeyGenAlgorithm>();
+        KEYGEN_ALGORITHMS.put("DES", KeyGenAlgorithm.DES);
+        KEYGEN_ALGORITHMS.put("DESede", KeyGenAlgorithm.DESede);
+        KEYGEN_ALGORITHMS.put("DES3", KeyGenAlgorithm.DES3);
+        KEYGEN_ALGORITHMS.put("RC2", KeyGenAlgorithm.RC2);
+        KEYGEN_ALGORITHMS.put("RC4", KeyGenAlgorithm.RC4);
+        KEYGEN_ALGORITHMS.put("AES", KeyGenAlgorithm.AES);
+    }
 
     public List<String> getUsages() {
         String usageString = properties.get(KEY_USAGE);
@@ -131,7 +145,7 @@ public class SymKeyGenerationRequest extends KeyRequest {
 
         SymKeyGenerationRequest before = new SymKeyGenerationRequest();
         before.setClientId("vek 12345");
-        before.setKeyAlgorithm("aes");
+        before.setKeyAlgorithm("AES");
         before.setKeySize(128);
         before.setRequestType(KeyRequestResource.KEY_GENERATION_REQUEST);
         before.addUsage(SymKeyGenerationRequest.DECRYPT_USAGE);
diff --git a/base/common/src/com/netscape/certsrv/kra/KRAClient.java b/base/common/src/com/netscape/certsrv/kra/KRAClient.java
index 6ff7ea23ec2fba1fcd7f204f671103cb8573cca1..6330008b5d1524893ef80f2f5ff44a3bcd1432a4 100644
--- a/base/common/src/com/netscape/certsrv/kra/KRAClient.java
+++ b/base/common/src/com/netscape/certsrv/kra/KRAClient.java
@@ -3,6 +3,7 @@ package com.netscape.certsrv.kra;
 import java.net.URISyntaxException;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
 import org.jboss.resteasy.client.ClientResponse;
 
@@ -20,6 +21,7 @@ import com.netscape.certsrv.key.KeyRequestInfo;
 import com.netscape.certsrv.key.KeyRequestInfoCollection;
 import com.netscape.certsrv.key.KeyRequestResource;
 import com.netscape.certsrv.key.KeyResource;
+import com.netscape.certsrv.key.SymKeyGenerationRequest;
 import com.netscape.certsrv.logging.AuditClient;
 import com.netscape.certsrv.request.RequestId;
 import com.netscape.certsrv.selftests.SelfTestClient;
@@ -147,7 +149,7 @@ public class KRAClient extends SubsystemClient {
         return keyRequestClient.getRequestInfo(id);
     }
 
-    public RequestId requestKeyRecovery(String keyId, String b64Certificate) {
+    public KeyRequestInfo requestKeyRecovery(String keyId, String b64Certificate) {
         // create key recovery request
         KeyRecoveryRequest data = new KeyRecoveryRequest();
         data.setKeyId(new KeyId(keyId));
@@ -157,7 +159,7 @@ public class KRAClient extends SubsystemClient {
         @SuppressWarnings("unchecked")
         ClientResponse<KeyRequestInfo> response = (ClientResponse<KeyRequestInfo>)
                 keyRequestClient.createRequest(data);
-        return client.getEntity(response).getRequestId();
+        return client.getEntity(response);
     }
 
     public KeyData recoverKey(RequestId requestId, String passphrase) {
@@ -169,4 +171,17 @@ public class KRAClient extends SubsystemClient {
         KeyData key = keyClient.retrieveKey(data);
         return key;
     }
+
+    public KeyRequestInfo generateKey(String clientId, String keyAlgorithm, int keySize, List<String> usages) {
+        SymKeyGenerationRequest data = new SymKeyGenerationRequest();
+        data.setClientId(clientId);
+        data.setKeyAlgorithm(keyAlgorithm);
+        data.setKeySize(keySize);
+        data.setRequestType(KeyRequestResource.KEY_GENERATION_REQUEST);
+        data.setUsages(usages);
+
+        @SuppressWarnings("unchecked")
+        ClientResponse<KeyRequestInfo> response = (ClientResponse<KeyRequestInfo>) keyRequestClient.createRequest(data);
+        return response.getEntity();
+    }
 }
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 06c368e5b3fb18d68826d5f29a5afec2dfb268ec..52139b2a18d752b8c2b088f7cd32e63f11f71edf 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,9 +17,11 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.cms.servlet.test;
 
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Random;
 
 import org.apache.commons.cli.CommandLine;
@@ -44,6 +46,7 @@ import com.netscape.certsrv.key.KeyData;
 import com.netscape.certsrv.key.KeyDataInfo;
 import com.netscape.certsrv.key.KeyRequestInfo;
 import com.netscape.certsrv.key.KeyRequestResource;
+import com.netscape.certsrv.key.SymKeyGenerationRequest;
 import com.netscape.certsrv.kra.KRAClient;
 import com.netscape.certsrv.request.RequestId;
 import com.netscape.certsrv.request.RequestNotFoundException;
@@ -514,7 +517,7 @@ public class DRMTest {
                                 "greWr3xTsy6gF2yphUEkGHh4v22XvK+FLx9Jb6zloMWA2GG9gpUpvMnl1fH4";
 
         log("Requesting X509 key recovery.");
-        recoveryRequestId = client.requestKeyRecovery(keyID, b64Certificate);
+        recoveryRequestId = client.requestKeyRecovery(keyID, b64Certificate).getRequestId();
         log("Requesting X509 key recovery request: " + recoveryRequestId);
 
         // Test 25: Approve x509 key recovery
@@ -529,6 +532,83 @@ public class DRMTest {
         } catch (RequestNotFoundException e) {
             log("Error: recovering X509Key");
         }
+
+        // test 27: Generate symmetric key
+        clientId = "Symmetric Key #1234";
+        List<String> usages = new ArrayList<String>();
+        usages.add(SymKeyGenerationRequest.DECRYPT_USAGE);
+        usages.add(SymKeyGenerationRequest.ENCRYPT_USAGE);
+        KeyRequestInfo genKeyInfo = client.generateKey("Symmetric Key #1234", "AES", 128, usages);
+        printRequestInfo(genKeyInfo);
+        keyId = genKeyInfo.getKeyId();
+
+        // test 28: Get keyId for active key with client ID
+        log("Getting key ID for symmetric key");
+        keyInfo = client.getKeyData(clientId, "active");
+        keyId2 = keyInfo.getKeyId();
+        if (keyId2 == null) {
+            log("No archived key found");
+        } else {
+            log("Archived Key found: " + keyId);
+        }
+
+        if (!keyId.equals(keyId2)) {
+            log("Error: key ids from search and archival do not match");
+        } else {
+            log("Success: keyids from search and archival match.");
+        }
+
+        // Test 29: Submit a recovery request for the symmetric key using a session key
+        log("Submitting a recovery request for the  symmetric key using session key");
+        try {
+            recoveryKey = CryptoUtil.generateKey(token, KeyGenAlgorithm.DES3);
+            wrappedRecoveryKey = CryptoUtil.wrapSymmetricKey(manager, token, transportCert, recoveryKey);
+            KeyRequestInfo info = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivps.getIV());
+            recoveryRequestId = info.getRequestId();
+        } catch (Exception e) {
+            log("Exception in recovering symmetric key using session key: " + e.getMessage());
+        }
+
+        // Test 30: Approve recovery
+        log("Approving recovery request: " + recoveryRequestId);
+        client.approveRecovery(recoveryRequestId);
+
+        // Test 31: Get key
+        log("Getting key: " + keyId);
+
+        keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivps.getIV());
+        wrappedRecoveredKey = keyData.getWrappedPrivateData();
+
+        ivps_server = new IVParameterSpec(Utils.base64decode(keyData.getNonceData()));
+        try {
+            recoveredKey = CryptoUtil.unwrapUsingSymmetricKey(token, ivps_server,
+                    Utils.base64decode(wrappedRecoveredKey),
+                    recoveryKey, EncryptionAlgorithm.DES3_CBC_PAD);
+        } catch (Exception e) {
+            log("Exception in unwrapping key: " + e.toString());
+            e.printStackTrace();
+        }
+
+        // test 31: Generate symmetric key - invalid algorithm
+        try {
+            genKeyInfo = client.generateKey("Symmetric Key #1235", "AFS", 128, usages);
+        } catch (Exception e) {
+            log("Exception: " + e);
+        }
+
+        // test 32: Generate symmetric key - invalid key size
+        try {
+            genKeyInfo = client.generateKey("Symmetric Key #1236", "AES", 135, usages);
+        } catch (Exception e) {
+            log("Exception: " + e);
+        }
+
+        // test 33: Generate symmetric key - usages not defined
+        try {
+            genKeyInfo = client.generateKey("Symmetric Key #1236", "DES", 56, usages);
+        } catch (Exception e) {
+            log("Exception: " + e);
+        }
     }
 
     private static void log(String string) {
diff --git a/base/kra/src/com/netscape/kra/SymKeyGenService.java b/base/kra/src/com/netscape/kra/SymKeyGenService.java
index c3a03d968a5971ec0f39f171574ef9ec51735bfc..311725b8cb74be8863501d7371cf7ad6058ce17b 100644
--- a/base/kra/src/com/netscape/kra/SymKeyGenService.java
+++ b/base/kra/src/com/netscape/kra/SymKeyGenService.java
@@ -108,7 +108,10 @@ public class SymKeyGenService implements IService {
         }
 
         CryptoToken token = mStorageUnit.getToken();
-        KeyGenAlgorithm kgAlg = getKeyGenAlgorithm(algorithm);
+        KeyGenAlgorithm kgAlg = SymKeyGenerationRequest.KEYGEN_ALGORITHMS.get(algorithm);
+        if (kgAlg == null) {
+            throw new EBaseException("Invalid algorithm");
+        }
 
         SymmetricKey.Usage keyUsages[];
         if (usages.size() > 0) {
@@ -210,25 +213,6 @@ public class SymKeyGenService implements IService {
         return true;
     }
 
-    KeyGenAlgorithm getKeyGenAlgorithm(String algorithm) throws EBaseException {
-        switch (algorithm) {
-        case "DES":
-            return KeyGenAlgorithm.DES;
-        case "DESede":
-            return KeyGenAlgorithm.DESede;
-        case "DES3":
-            return KeyGenAlgorithm.DES3;
-        case "RC4":
-            return KeyGenAlgorithm.RC4;
-        case "AES":
-            return KeyGenAlgorithm.AES;
-        case "RC2":
-            return KeyGenAlgorithm.RC2;
-        default:
-            throw new EBaseException("Invalid algorithm");
-        }
-    }
-
     //ToDo: return real owner with auth
     private String getOwnerName(IRequest request) {
         return DEFAULT_OWNER;
diff --git a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
index be166c001f8f23db461d045deecb7c811d616965..8ecf11074932a80e9cf5253ad87eb3a400cd4189 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
@@ -218,31 +218,12 @@ public class KeyRequestDAO extends CMSRequestDAO {
             throw new BadRequestException("Can not archive already active existing key!");
         }
 
-        boolean isValid = true;
-        switch(algName) {
-        case "DES":
-            if (! KeyGenAlgorithm.DES.isValidStrength(size)) isValid = false;
-            break;
-        case "DESede":
-            if (! KeyGenAlgorithm.DESede.isValidStrength(size)) isValid = false;
-            break;
-        case "DES3":
-            if (! KeyGenAlgorithm.DES3.isValidStrength(size)) isValid = false;
-            break;
-        case "RC4":
-            if (! KeyGenAlgorithm.RC4.isValidStrength(size)) isValid = false;
-            break;
-        case "AES":
-            if (! KeyGenAlgorithm.AES.isValidStrength(size)) isValid = false;
-            break;
-        case "RC2":
-            if (! KeyGenAlgorithm.RC2.isValidStrength(size)) isValid = false;
-            break;
-        default:
-            throw new BadRequestException("Invalid algorithm");
+        KeyGenAlgorithm alg = SymKeyGenerationRequest.KEYGEN_ALGORITHMS.get(algName);
+        if (alg == null) {
+            throw new BadRequestException("Invalid Algorithm");
         }
 
-        if (!isValid) {
+        if (!alg.isValidStrength(size)) {
             throw new BadRequestException("Invalid key size for this algorithm");
         }
 
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 6cad363ca1a7c38b51569dd93c08f5947cacb9fa..6b78e69ec7a21cca1b6860006b81ef086700a5f1 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
@@ -79,6 +79,9 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
     private static final String LOGGING_SIGNED_AUDIT_SECURITY_DATA_ARCHIVAL_REQUEST =
             "LOGGING_SIGNED_AUDIT_SECURITY_DATA_ARCHIVAL_REQUEST_4";
 
+    private static final String LOGGING_SIGNED_AUDIT_SYMKEY_GENERATION_REQUEST =
+            "LOGGING_SIGNED_AUDIT_SYMKEY_GENERATION_REQUEST_4";
+
     private static final String LOGGING_SIGNED_AUDIT_SECURITY_DATA_RECOVERY_REQUEST =
             "LOGGING_SIGNED_AUDIT_SECURITY_DATA_RECOVERY_REQUEST_4";
 
@@ -364,6 +367,16 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         auditor.log(msg);
     }
 
+    public void auditSymKeyGenRequestMade(RequestId requestId, String status, String clientId) {
+        String msg = CMS.getLogMessage(
+                LOGGING_SIGNED_AUDIT_SYMKEY_GENERATION_REQUEST,
+                servletRequest.getUserPrincipal().getName(),
+                status,
+                requestId != null ? requestId.toString() : "null",
+                clientId);
+        auditor.log(msg);
+    }
+
     @Override
     public Response createRequest(MultivaluedMap<String, String> form) {
         KeyRequest data = new KeyRequest(form);
@@ -394,7 +407,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         KeyRequestInfo info;
         try {
             info = dao.submitRequest(data, uriInfo);
-            auditArchivalRequestMade(info.getRequestId(), ILogger.SUCCESS, data.getClientId());
+            auditSymKeyGenRequestMade(info.getRequestId(), ILogger.SUCCESS, data.getClientId());
 
             return Response
                     .created(new URI(info.getRequestURL()))
-- 
1.8.4.2

