From 10385991bcd921497f64d5bb82929835e8e02756 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Sat, 16 Apr 2016 11:48:52 -0400
Subject: [PATCH 289/293] Added realm for archival and key generation through
 REST

This will allow users to specify the realm when generating
or archiving a request.  No interface change is needed (yet)
because the extra parameter is passed through the request.

Part of Ticket #2041
---
 .../certsrv/key/AsymKeyGenerationRequest.java      |  2 +
 .../netscape/certsrv/key/KeyArchivalRequest.java   | 19 +++++
 .../src/com/netscape/certsrv/key/KeyClient.java    | 90 +++++++++++++++++++---
 .../netscape/certsrv/key/KeyGenerationRequest.java | 14 ++++
 .../certsrv/key/SymKeyGenerationRequest.java       |  2 +
 .../com/netscape/cmstools/key/KeyArchiveCLI.java   | 14 +++-
 .../com/netscape/cmstools/key/KeyGenerateCLI.java  | 20 +++--
 .../src/com/netscape/kra/AsymKeyGenService.java    |  6 ++
 .../src/com/netscape/kra/SecurityDataService.java  |  7 ++
 .../kra/src/com/netscape/kra/SymKeyGenService.java |  5 ++
 .../netscape/cms/servlet/key/KeyRequestDAO.java    | 26 ++++++-
 11 files changed, 184 insertions(+), 21 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/key/AsymKeyGenerationRequest.java b/base/common/src/com/netscape/certsrv/key/AsymKeyGenerationRequest.java
index 867c06acf64dda91f97bddec24cc17ffe4dd5f07..df3d7acc8e1e4db3d2ef5f975683e301725b2773 100644
--- a/base/common/src/com/netscape/certsrv/key/AsymKeyGenerationRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/AsymKeyGenerationRequest.java
@@ -56,6 +56,7 @@ public class AsymKeyGenerationRequest extends KeyGenerationRequest {
         attributes.put(KEY_ALGORITHM, form.getFirst(KEY_ALGORITHM));
         attributes.put(KEY_USAGE, form.getFirst(KEY_USAGE));
         attributes.put(TRANS_WRAPPED_SESSION_KEY, form.getFirst(TRANS_WRAPPED_SESSION_KEY));
+        attributes.put(REALM,  form.getFirst(REALM));
 
         String usageString = attributes.get(KEY_USAGE);
         if (!StringUtils.isBlank(usageString)) {
@@ -109,6 +110,7 @@ public class AsymKeyGenerationRequest extends KeyGenerationRequest {
         usages.add(AsymKeyGenerationRequest.ENCRYPT);
         usages.add(AsymKeyGenerationRequest.DECRYPT);
         request.setUsages(usages);
+        request.setRealm("ipa-vault");
 
         System.out.println(request.toString());
     }
diff --git a/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java b/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java
index 03bbfb53a40e3969708d7ee02d479903fb945203..d2a7749b3f8aac2c9025e48bce5aff727923c286 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java
@@ -52,6 +52,9 @@ public class KeyArchivalRequest extends ResourceMessage {
     private static final String KEY_ALGORITHM = "keyAlgorithm";
     private static final String KEY_SIZE = "keySize";
 
+    // parameters to set realm
+    private static final String REALM = "realm";
+
     public KeyArchivalRequest() {
         // required for JAXB (defaults)
         setClassName(getClass().getName());
@@ -65,6 +68,7 @@ public class KeyArchivalRequest extends ResourceMessage {
         attributes.put(KEY_SIZE, form.getFirst(KEY_SIZE));
         attributes.put(PKI_ARCHIVE_OPTIONS, form.getFirst(PKI_ARCHIVE_OPTIONS));
         attributes.put(TRANS_WRAPPED_SESSION_KEY, form.getFirst(TRANS_WRAPPED_SESSION_KEY));
+        attributes.put(REALM, form.getFirst(REALM));
         setClassName(getClass().getName());
     }
 
@@ -199,6 +203,20 @@ public class KeyArchivalRequest extends ResourceMessage {
         attributes.put(KEY_SIZE, Integer.toString(keySize));
     }
 
+    /**
+     * @return the authentication realm
+     */
+    public String getRealm() {
+        return attributes.get(REALM);
+    }
+
+    /**
+     * @param realm - the authentication realm
+     */
+    public void setRealm(String realm) {
+        attributes.put(REALM, realm);
+    }
+
     public String toString() {
         try {
             return ResourceMessage.marshal(this, KeyArchivalRequest.class);
@@ -222,6 +240,7 @@ public class KeyArchivalRequest extends ResourceMessage {
         before.setDataType(KeyRequestResource.SYMMETRIC_KEY_TYPE);
         before.setWrappedPrivateData("XXXXABCDEFXXX");
         before.setKeyAlgorithm(KeyRequestResource.AES_ALGORITHM);
+        before.setRealm("ipa-vault");
         before.setKeySize(128);
 
         String string = before.toString();
diff --git a/base/common/src/com/netscape/certsrv/key/KeyClient.java b/base/common/src/com/netscape/certsrv/key/KeyClient.java
index ade3765a97b9bfb62c762661511bfcec6b11c90f..04eb6539f6accc1cde30ca1d3b8832d3b915d32b 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyClient.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyClient.java
@@ -517,12 +517,13 @@ public class KeyClient extends Client {
      *
      * @param clientKeyId -- Client Key Identfier
      * @param passphrase -- Secret passphrase to be archived
+     * @param realm -- authorization realm
      * @return A KeyRequestResponse object with information about the request.
      * @throws Exception - Exceptions of type NoSuchAlgorithmException, IllegalStateException, TokenException,
      *             IOException, CertificateEncodingException, InvalidKeyException, InvalidAlgorithmParameterException,
      *             BadPaddingException, IllegalBlockSizeException
      */
-    public KeyRequestResponse archivePassphrase(String clientKeyId, String passphrase) throws Exception {
+    public KeyRequestResponse archivePassphrase(String clientKeyId, String passphrase, String realm) throws Exception {
 
         // Default algorithm OID for DES_EDE3_CBC
         String algorithmOID = EncryptionAlgorithm.DES3_CBC.toOID().toString();
@@ -533,7 +534,13 @@ public class KeyClient extends Client {
                 sessionKey, KeyRequestResource.DES3_ALGORITHM);
 
         return archiveEncryptedData(clientKeyId, KeyRequestResource.PASS_PHRASE_TYPE, null, 0, algorithmOID,
-                nonceData, encryptedData, transWrappedSessionKey);
+                nonceData, encryptedData, transWrappedSessionKey, realm);
+    }
+
+    /* Old signature for backwards compatibility */
+    @Deprecated
+    public KeyRequestResponse archivePassphrase(String clientKeyId, String passphrase) throws Exception {
+        return archivePassphrase(clientKeyId, passphrase, null);
     }
 
     /**
@@ -546,13 +553,14 @@ public class KeyClient extends Client {
      * @param clientKeyId -- Client Key Identifier
      * @param keyAlgorithm -- Algorithm used by the symmetric key
      * @param keySize -- Strength of the symmetric key (secret)
+     * @param realm -- authorization realm
      * @return A KeyRequestResponse object with information about the request.
      * @throws Exception - Exceptions of type NoSuchAlgorithmException, IllegalStateException, TokenException,
      *             IOException, CertificateEncodingException, InvalidKeyException, InvalidAlgorithmParameterException,
      *             BadPaddingException, IllegalBlockSizeException
      */
     public KeyRequestResponse archiveSymmetricKey(String clientKeyId, SymmetricKey secret, String keyAlgorithm,
-            int keySize) throws Exception {
+            int keySize, String realm) throws Exception {
 
         // Default algorithm OID for DES_EDE3_CBC
         String algorithmOID = EncryptionAlgorithm.DES3_CBC.toOID().toString();
@@ -562,7 +570,14 @@ public class KeyClient extends Client {
         byte[] transWrappedSessionKey = crypto.wrapSessionKeyWithTransportCert(sessionKey, this.transportCert);
 
         return archiveEncryptedData(clientKeyId, KeyRequestResource.SYMMETRIC_KEY_TYPE, keyAlgorithm, keySize,
-                algorithmOID, nonceData, encryptedData, transWrappedSessionKey);
+                algorithmOID, nonceData, encryptedData, transWrappedSessionKey, realm);
+    }
+
+    /* old method signature for backwards compatibility */
+    @Deprecated
+    public KeyRequestResponse archiveSymmetricKey(String clientKeyId, SymmetricKey secret, String keyAlgorithm,
+            int keySize) throws Exception {
+        return archiveSymmetricKey(clientKeyId, secret, keyAlgorithm,keySize, null);
     }
 
     /**
@@ -581,11 +596,12 @@ public class KeyClient extends Client {
      * @param encryptedData -- which is the secret wrapped by a session
      *            key (168 bit 3DES symmetric key)
      * @param transWrappedSessionKey -- session key wrapped by the transport cert.
+     * @param realm -- authorization realm
      * @return A KeyRequestResponse object with information about the request.
      */
     public KeyRequestResponse archiveEncryptedData(String clientKeyId, String dataType, String keyAlgorithm,
-            int keySize,
-            String algorithmOID, byte[] nonceData, byte[] encryptedData, byte[] transWrappedSessionKey) {
+            int keySize, String algorithmOID, byte[] nonceData, byte[] encryptedData,
+            byte[] transWrappedSessionKey, String realm) {
 
         if (clientKeyId == null || dataType == null) {
             throw new IllegalArgumentException("Client key id and data type must be specified.");
@@ -612,9 +628,22 @@ public class KeyClient extends Client {
         data.setWrappedPrivateData(req1);
         data.setTransWrappedSessionKey(Utils.base64encode(transWrappedSessionKey));
 
+        if (realm != null) {
+            data.setRealm(realm);
+        }
+
         return submitRequest(data);
     }
 
+    /* old signature for backwards compatibility */
+    @Deprecated
+    public KeyRequestResponse archiveEncryptedData(String clientKeyId, String dataType, String keyAlgorithm,
+            int keySize, String algorithmOID, byte[] nonceData, byte[] encryptedData,
+            byte[] transWrappedSessionKey) {
+        return archiveEncryptedData(clientKeyId, dataType, keyAlgorithm, keySize, algorithmOID, nonceData,
+                encryptedData, transWrappedSessionKey, null);
+    }
+
     /**
      * Archive a secret (symmetric key or passphrase) on the DRM using a PKIArchiveOptions data format.
      *
@@ -624,11 +653,12 @@ public class KeyClient extends Client {
      * @param keySize -- Strength of the symmetric key
      * @param pkiArchiveOptions -- is the data to be archived wrapped in a
      *            PKIArchiveOptions structure
+     * @param realm -- authorization realm
      * @return A KeyRequestResponse object with information about the request.
      * @throws Exception
      */
     public KeyRequestResponse archivePKIOptions(String clientKeyId, String dataType, String keyAlgorithm, int keySize,
-            byte[] pkiArchiveOptions) {
+            byte[] pkiArchiveOptions, String realm) {
 
         if (clientKeyId == null || dataType == null) {
             throw new IllegalArgumentException("Client key id and data type must be specified.");
@@ -653,9 +683,20 @@ public class KeyClient extends Client {
         String options = Utils.base64encode(pkiArchiveOptions);
         data.setPKIArchiveOptions(options);
 
+        if (realm != null) {
+            data.setRealm(realm);
+        }
+
         return submitRequest(data);
     }
 
+    /* old method signature for backwards compatibility */
+    @Deprecated
+    public KeyRequestResponse archivePKIOptions(String clientKeyId, String dataType, String keyAlgorithm, int keySize,
+            byte[] pkiArchiveOptions) {
+        return archivePKIOptions(clientKeyId, dataType, keyAlgorithm, keySize, pkiArchiveOptions, null);
+    }
+
     /**
      * Generate and archive a symmetric key in the DRM.
      *
@@ -663,11 +704,14 @@ public class KeyClient extends Client {
      * @param keyAlgorithm -- Algorithm to be used to generate the key
      * @param keySize -- Strength of the keys
      * @param usages -- Usages of the generated key.
+     * @param transWrappedSessionKey - client generated session key wrapped by
+     *         KRA transport key
+     * @param realm -- authorization realm
      * @return a KeyRequestResponse which contains a KeyRequestInfo
      *         object that describes the URL for the request and generated key.
      */
     public KeyRequestResponse generateSymmetricKey(String clientKeyId, String keyAlgorithm, int keySize,
-            List<String> usages, String transWrappedSessionKey) {
+            List<String> usages, String transWrappedSessionKey, String realm) {
         if (clientKeyId == null) {
             throw new IllegalArgumentException("Client Key Identifier must be specified.");
         }
@@ -687,21 +731,34 @@ public class KeyClient extends Client {
         data.setUsages(usages);
         data.setTransWrappedSessionKey(transWrappedSessionKey);
 
+        if (realm != null) {
+            data.setRealm(realm);
+        }
+
         return submitRequest(data);
     }
 
+    /* old method signature for backwards compatibility */
+    @Deprecated
+    public KeyRequestResponse generateSymmetricKey(String clientKeyId, String keyAlgorithm, int keySize,
+            List<String> usages, String transWrappedSessionKey) {
+        return generateSymmetricKey(clientKeyId, keyAlgorithm, keySize, usages, transWrappedSessionKey, null);
+    }
+
     /**
      * Generate and archive an asymmetric keys in the DRM
      *
      * @param clientKeyId -- Client Key Identifier
      * @param keyAlgorithm -- Algorithm to be used to generate the asymmetric keys
      * @param keySize -- Strength of the keys
-     * @param usages
-     * @param transWrappedSessionKey
+     * @param usages  -- key usages
+     * @param transWrappedSessionKey  -- client generated session key wrapped by the
+     *        KRA transport key
+     * @param realm  -- authorization realm
      * @return
      */
     public KeyRequestResponse generateAsymmetricKey(String clientKeyId, String keyAlgorithm, int keySize,
-            List<String> usages, byte[] transWrappedSessionKey) {
+            List<String> usages, byte[] transWrappedSessionKey, String realm) {
 
         if (clientKeyId == null) {
             throw new IllegalArgumentException("Client Key Identifier must be specified.");
@@ -747,6 +804,17 @@ public class KeyClient extends Client {
         data.setUsages(usages);
         data.setTransWrappedSessionKey(Utils.base64encode(transWrappedSessionKey));
 
+        if (realm != null) {
+            data.setRealm(realm);
+        }
+
         return submitRequest(data);
     }
+
+    /* old method signature for backwards compatibility */
+    @Deprecated
+    public KeyRequestResponse generateAsymmetricKey(String clientKeyId, String keyAlgorithm, int keySize,
+            List<String> usages, byte[] transWrappedSessionKey) {
+        return generateAsymmetricKey(clientKeyId, keyAlgorithm, keySize, usages, transWrappedSessionKey, null);
+    }
 }
diff --git a/base/common/src/com/netscape/certsrv/key/KeyGenerationRequest.java b/base/common/src/com/netscape/certsrv/key/KeyGenerationRequest.java
index ed36b6d9dbfdece3922d9ca6647a06fb4cc56d8c..37fc1c2b2775c4ce4da7eab81caf42ff39d2045f 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyGenerationRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyGenerationRequest.java
@@ -38,6 +38,7 @@ public class KeyGenerationRequest extends ResourceMessage{
     protected static final String KEY_ALGORITHM = "keyAlgorithm";
     protected static final String KEY_USAGE = "keyUsage";
     protected static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
+    protected static final String REALM = "realm";
 
 
     public List<String> getUsages() {
@@ -122,4 +123,17 @@ public class KeyGenerationRequest extends ResourceMessage{
         attributes.put(TRANS_WRAPPED_SESSION_KEY, transWrappedSessionKey);
     }
 
+    /**
+     * @return the realm
+     */
+    public String getRealm() {
+        return attributes.get(REALM);
+    }
+
+    /**
+     * @param realm - authorization realm to set
+     */
+    public void setRealm(String realm) {
+        attributes.put(REALM, realm);
+    }
 }
diff --git a/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java b/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
index 7f65d0e59c1f8facf1e270ca12d1fe56adc9e063..a85d102a85da9aeb6e27026fd73be35e1b12263c 100644
--- a/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
@@ -40,6 +40,7 @@ public class SymKeyGenerationRequest extends KeyGenerationRequest {
         attributes.put(KEY_ALGORITHM, form.getFirst(KEY_ALGORITHM));
         attributes.put(KEY_USAGE, form.getFirst(KEY_USAGE));
         attributes.put(TRANS_WRAPPED_SESSION_KEY, form.getFirst(TRANS_WRAPPED_SESSION_KEY));
+        attributes.put(REALM, form.getFirst(REALM));
 
         String usageString = attributes.get(KEY_USAGE);
         if (!StringUtils.isBlank(usageString)) {
@@ -97,6 +98,7 @@ public class SymKeyGenerationRequest extends KeyGenerationRequest {
         before.addUsage(SymKeyGenerationRequest.DECRYPT_USAGE);
         before.addUsage(SymKeyGenerationRequest.ENCRYPT_USAGE);
         before.addUsage(SymKeyGenerationRequest.SIGN_USAGE);
+        before.setRealm("ipa");
 
         String string = before.toString();
         System.out.println(string);
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java
index d9bdd8843041a0f55946677b968bdeef8da03be8..e9ce7f2ec48017e6f78ab923dbc0adea2011abf6 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java
@@ -45,6 +45,10 @@ public class KeyArchiveCLI extends CLI {
                 "Location of the request template file.\nUsed for archiving already encrypted data.");
         option.setArgName("Input file path");
         options.addOption(option);
+
+        option = new Option(null, "realm", true, "Authorization realm.");
+        option.setArgName("Realm");
+        options.addOption(option);
     }
 
     public void execute(String[] args) {
@@ -88,13 +92,15 @@ public class KeyArchiveCLI extends CLI {
 
                 if (req.getPKIArchiveOptions() != null) {
                     response = keyCLI.keyClient.archivePKIOptions(req.getClientKeyId(), req.getDataType(),
-                            req.getKeyAlgorithm(), req.getKeySize(), Utils.base64decode(req.getPKIArchiveOptions()));
+                            req.getKeyAlgorithm(), req.getKeySize(), Utils.base64decode(req.getPKIArchiveOptions()),
+                            req.getRealm());
                 } else {
                     response = keyCLI.keyClient.archiveEncryptedData(req.getClientKeyId(), req.getDataType(),
                             req.getKeyAlgorithm(), req.getKeySize(), req.getAlgorithmOID(),
                             Utils.base64decode(req.getSymmetricAlgorithmParams()),
                             Utils.base64decode(req.getWrappedPrivateData()),
-                            Utils.base64decode(req.getTransWrappedSessionKey()));
+                            Utils.base64decode(req.getTransWrappedSessionKey()),
+                            req.getRealm());
                 }
 
             } catch (JAXBException e) {
@@ -123,8 +129,10 @@ public class KeyArchiveCLI extends CLI {
                 printHelp();
                 System.exit(-1);
             }
+            String realm = cmd.getOptionValue("realm");
+
             try {
-                response = keyCLI.keyClient.archivePassphrase(clientKeyId, passphrase);
+                response = keyCLI.keyClient.archivePassphrase(clientKeyId, passphrase, realm);
             } catch (Exception e) {
                 System.err.println(e.getMessage());
                 if (verbose)
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java
index c8608731e7c6bef66174f5fb0012df9fd89cf82b..4149ee677f36efea070f1b551964b3dc67b12e22 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java
@@ -48,6 +48,14 @@ public class KeyGenerateCLI extends CLI {
                 + "\nAdditional usages for RSA and DSA type keys: derive, sign_recover, verify_recover.");
         option.setArgName("list of usages");
         options.addOption(option);
+
+        option = new Option(
+                null,
+                "realm",
+                true,
+                "Authorization realm");
+        option.setArgName("realm");
+        options.addOption(option);
     }
 
     public void execute(String[] args) {
@@ -80,6 +88,7 @@ public class KeyGenerateCLI extends CLI {
         String clientKeyId = cmdArgs[0];
         String keyAlgorithm = cmd.getOptionValue("key-algorithm");
         String keySize = cmd.getOptionValue("key-size");
+        String realm = cmd.getOptionValue("realm");
 
         if (keySize == null) {
             switch (keyAlgorithm) {
@@ -118,6 +127,7 @@ public class KeyGenerateCLI extends CLI {
         if (givenUsages != null) {
             usages = Arrays.asList(givenUsages.split(","));
         }
+
         KeyRequestResponse response = null;
         switch (keyAlgorithm) {
         case KeyRequestResource.DES3_ALGORITHM:
@@ -126,15 +136,13 @@ public class KeyGenerateCLI extends CLI {
         case KeyRequestResource.RC4_ALGORITHM:
         case KeyRequestResource.AES_ALGORITHM:
         case KeyRequestResource.RC2_ALGORITHM:
-            response = keyCLI.keyClient.generateSymmetricKey(clientKeyId, keyAlgorithm,
-                    size,
-                    usages, null);
+            response = keyCLI.keyClient.generateSymmetricKey(
+                    clientKeyId, keyAlgorithm, size, usages, null, realm);
             break;
         case KeyRequestResource.RSA_ALGORITHM:
         case KeyRequestResource.DSA_ALGORITHM:
-            response = keyCLI.keyClient.generateAsymmetricKey(clientKeyId, keyAlgorithm,
-                    size,
-                    usages, null);
+            response = keyCLI.keyClient.generateAsymmetricKey(
+                    clientKeyId, keyAlgorithm, size, usages, null, realm);
             break;
         default:
             System.err.println("Error: Algorithm not supported.");
diff --git a/base/kra/src/com/netscape/kra/AsymKeyGenService.java b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
index f4f68ea01489dd802d297d5cc284812468d3da60..26a284fd0cc6367431f3a1d1b816dbb5bde3382f 100644
--- a/base/kra/src/com/netscape/kra/AsymKeyGenService.java
+++ b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
@@ -78,6 +78,8 @@ public class AsymKeyGenService implements IService {
         String keySizeStr = request.getExtDataInString(IRequest.KEY_GEN_SIZE);
         int keySize = Integer.valueOf(keySizeStr);
 
+        String realm = request.getRealm();
+
         KeyPairGeneratorSpi.Usage[] usageList = null;
         String usageStr = request.getExtDataInString(IRequest.KEY_GEN_USAGES);
         if (usageStr != null) {
@@ -174,6 +176,10 @@ public class AsymKeyGenService implements IService {
         record.set(KeyRecord.ATTR_KEY_SIZE, keySize);
         request.setExtData(ATTR_KEY_RECORD, serialNo);
 
+        if (realm != null) {
+            record.set(KeyRecord.ATTR_REALM, realm);
+        }
+
         storage.addKeyRecord(record);
 
         auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.SUCCESS, request.getRequestId(),
diff --git a/base/kra/src/com/netscape/kra/SecurityDataService.java b/base/kra/src/com/netscape/kra/SecurityDataService.java
index 3a163e23b6cbaaf0ecaddf43c0ad922636a87805..349ef9460fd49c3b738dfefa540b19af66763717 100644
--- a/base/kra/src/com/netscape/kra/SecurityDataService.java
+++ b/base/kra/src/com/netscape/kra/SecurityDataService.java
@@ -100,6 +100,9 @@ public class SecurityDataService implements IService {
         String algorithm = request.getExtDataInString(IRequest.SECURITY_DATA_ALGORITHM);
         int strength = request.getExtDataInInteger(IRequest.SECURITY_DATA_STRENGTH);
 
+        // parameter for realm
+        String realm = request.getRealm();
+
         CMS.debug("SecurityDataService.serviceRequest. Request id: " + id);
         CMS.debug("SecurityDataService.serviceRequest wrappedSecurityData: " + wrappedSecurityData);
 
@@ -262,6 +265,10 @@ public class SecurityDataService implements IService {
             rec.set(KeyRecord.ATTR_KEY_SIZE, strength);
         }
 
+        if (realm != null) {
+            rec.set(KeyRecord.ATTR_REALM,  realm);
+        }
+
         request.setExtData(ATTR_KEY_RECORD, serialNo);
 
         CMS.debug("KRA adding Security Data key record " + serialNo);
diff --git a/base/kra/src/com/netscape/kra/SymKeyGenService.java b/base/kra/src/com/netscape/kra/SymKeyGenService.java
index d308345d74014689b347e5fae29b5881908dc025..89c776d75e2d2059803223ca1bbb041ba5e1749d 100644
--- a/base/kra/src/com/netscape/kra/SymKeyGenService.java
+++ b/base/kra/src/com/netscape/kra/SymKeyGenService.java
@@ -89,6 +89,7 @@ public class SymKeyGenService implements IService {
         String id = request.getRequestId().toString();
         String clientKeyId = request.getExtDataInString(IRequest.SECURITY_DATA_CLIENT_KEY_ID);
         String algorithm = request.getExtDataInString(IRequest.KEY_GEN_ALGORITHM);
+        String realm = request.getRealm();
 
         String usageStr = request.getExtDataInString(IRequest.KEY_GEN_USAGES);
         List<String> usages = new ArrayList<String>(
@@ -212,6 +213,10 @@ public class SymKeyGenService implements IService {
         rec.set(KeyRecord.ATTR_KEY_SIZE, keySize);
         request.setExtData(ATTR_KEY_RECORD, serialNo);
 
+        if (realm != null) {
+            rec.set(KeyRecord.ATTR_REALM, realm);
+        }
+
         CMS.debug("KRA adding Security Data key record " + serialNo);
         storage.addKeyRecord(rec);
 
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 b643268721d140e3c4c6a4f8865e65fbb2ebd5ce..3d5300370107c5e859b0468525d42d92b0cf12c5 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
@@ -176,6 +176,7 @@ public class KeyRequestDAO extends CMSRequestDAO {
         String keyAlgorithm = data.getKeyAlgorithm();
         int keyStrength = dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE) ?
                 data.getKeySize(): 0;
+        String realm = data.getRealm();
 
         boolean keyExists = doesKeyExist(clientKeyId, "active");
 
@@ -204,6 +205,10 @@ public class KeyRequestDAO extends CMSRequestDAO {
 
         request.setExtData(IRequest.ATTR_REQUEST_OWNER, owner);
 
+        if (realm != null) {
+            request.setRealm(realm);
+        }
+
         queue.processRequest(request);
 
         queue.markAsServiced(request);
@@ -229,8 +234,9 @@ public class KeyRequestDAO extends CMSRequestDAO {
         IRequest request = queue.newRequest(IRequest.SECURITY_DATA_RECOVERY_REQUEST);
 
         KeyId keyId = data.getKeyId();
+        IKeyRecord rec = null;
         try {
-            repo.readKeyRecord(keyId.toBigInteger());
+            rec = repo.readKeyRecord(keyId.toBigInteger());
         } catch (EDBRecordNotFoundException e) {
             throw new KeyNotFoundException(keyId);
         }
@@ -262,6 +268,10 @@ public class KeyRequestDAO extends CMSRequestDAO {
         request.setExtData(IRequest.ATTR_REQUEST_OWNER, requestor);
         request.setExtData(IRequest.ATTR_APPROVE_AGENTS, requestor);
 
+        if (rec.getRealm() != null) {
+            request.setRealm(rec.getRealm());
+        }
+
         queue.processRequest(request);
 
         return createKeyRequestResponse(request, uriInfo);
@@ -274,6 +284,7 @@ public class KeyRequestDAO extends CMSRequestDAO {
         Integer keySize = data.getKeySize();
         List<String> usages = data.getUsages();
         String transWrappedSessionKey = data.getTransWrappedSessionKey();
+        String realm = data.getRealm();
 
         if (StringUtils.isBlank(clientKeyId)) {
             throw new BadRequestException("Invalid key generation request. Missing client ID");
@@ -322,6 +333,10 @@ public class KeyRequestDAO extends CMSRequestDAO {
                     transWrappedSessionKey);
         }
 
+        if (realm != null) {
+            request.setRealm(realm);
+        }
+
         queue.processRequest(request);
         queue.markAsServiced(request);
 
@@ -335,6 +350,7 @@ public class KeyRequestDAO extends CMSRequestDAO {
         Integer keySize = data.getKeySize();
         List<String> usages = data.getUsages();
         String transWrappedSessionKey = data.getTransWrappedSessionKey();
+        String realm = data.getRealm();
 
         if (StringUtils.isBlank(clientKeyId)) {
             throw new BadRequestException("Invalid key generation request. Missing client ID");
@@ -403,6 +419,10 @@ public class KeyRequestDAO extends CMSRequestDAO {
                     transWrappedSessionKey);
         }
 
+        if (realm != null) {
+            request.setRealm(realm);
+        }
+
         queue.processRequest(request);
         queue.markAsServiced(request);
 
@@ -450,6 +470,10 @@ public class KeyRequestDAO extends CMSRequestDAO {
             ret.setKeyURL(keyBuilder.build().toString());
         }
 
+        if (request.getRealm()!= null) {
+            ret.setRealm(request.getRealm());
+        }
+
         return ret;
     }
 
-- 
2.4.3

