f8ded1
From aa39354dbbf9df404f6ad374c837db0c421f2705 Mon Sep 17 00:00:00 2001
f8ded1
From: Christina Fu <cfu@redhat.com>
f8ded1
Date: Mon, 5 Jun 2017 08:50:25 -0700
f8ded1
Subject: [PATCH 01/14] Ticket #2617 part2: add revocation check to signing
f8ded1
 cert
f8ded1
f8ded1
---
f8ded1
 .../cms/authentication/CMCUserSignedAuth.java         | 19 +++++++++++++++++++
f8ded1
 .../authentication/CertUserDBAuthentication.java      |  2 +-
f8ded1
 2 files changed, 20 insertions(+), 1 deletion(-)
f8ded1
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
f8ded1
index 2128c1e..a18c25e 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
f8ded1
@@ -29,6 +29,7 @@ import java.io.ByteArrayInputStream;
f8ded1
 import java.io.ByteArrayOutputStream;
f8ded1
 import java.io.IOException;
f8ded1
 import java.math.BigInteger;
f8ded1
+import java.security.cert.CertificateExpiredException;
f8ded1
 import java.security.MessageDigest;
f8ded1
 import java.security.PublicKey;
f8ded1
 import java.util.Enumeration;
f8ded1
@@ -1076,7 +1077,10 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                             si.verify(digest, id, pubK);
f8ded1
                         }
f8ded1
                         CMS.debug(method + "finished checking signature");
f8ded1
+
f8ded1
                         // verify signer's certificate using the revocator
f8ded1
+                        // ...or not;  I think it just checks usage and
f8ded1
+                        // validity, but not revocation status
f8ded1
                         if (!cm.isCertValid(certByteArray, true, CryptoManager.CertUsage.SSLClient)) {
f8ded1
                             CMS.debug(method + "CMC signature failed to be verified");
f8ded1
                             s.close();
f8ded1
@@ -1086,6 +1090,21 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                         }
f8ded1
                         // At this point, the signature has been verified;
f8ded1
 
f8ded1
+                        // now check revocation status of the cert
f8ded1
+                        if (CMS.isRevoked(x509Certs)) {
f8ded1
+                            CMS.debug(method + "CMC signing cert is a revoked certificate");
f8ded1
+                            throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
f8ded1
+                        }
f8ded1
+                        try { //do this again anyways
f8ded1
+                            cert.checkValidity();
f8ded1
+                        } catch (CertificateExpiredException e) {
f8ded1
+                            CMS.debug(method + "CMC signing cert is an expired certificate");
f8ded1
+                            throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
f8ded1
+                        } catch (Exception e) {
f8ded1
+                            CMS.debug(method + e.toString());
f8ded1
+                            throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
f8ded1
+                        }
f8ded1
+
f8ded1
                         IAuthToken tempToken = new AuthToken(null);
f8ded1
 /*
f8ded1
                         netscape.security.x509.X500Name tempPrincipal = (X500Name) x509Certs[0].getSubjectDN();
f8ded1
diff --git a/base/server/cmscore/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java b/base/server/cmscore/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java
f8ded1
index 998d7e2..ae450fa 100644
f8ded1
--- a/base/server/cmscore/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java
f8ded1
+++ b/base/server/cmscore/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java
f8ded1
@@ -168,7 +168,7 @@ public class CertUserDBAuthentication implements IAuthManager, ICertUserDBAuthen
f8ded1
         try {
f8ded1
             user = (User) mCULocator.locateUser(certs);
f8ded1
         } catch (EUsrGrpException e) {
f8ded1
-            CMS.debug("CertUserDBAuthentication: cannot map certificate to any user");
f8ded1
+            CMS.debug("CertUserDBAuthentication: cannot map certificate to any user" + e);
f8ded1
             log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_AUTH_FAILED", x509Certs[0].getSerialNumber()
f8ded1
                     .toString(16), x509Certs[0].getSubjectDN().toString(), e.toString()));
f8ded1
             throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From 30fb7bf49ce0f4c726f937b3984a4e27abb39959 Mon Sep 17 00:00:00 2001
f8ded1
From: Jack Magne <jmagne@dhcp-16-206.sjc.redhat.com>
f8ded1
Date: Tue, 6 Jun 2017 16:16:32 -0700
f8ded1
Subject: [PATCH 04/14] Minor fix to already fixed issue:
f8ded1
f8ded1
The problem was that a tiny piece of the original patch didn't get checked in. This resolves this issue.
f8ded1
---
f8ded1
 base/native-tools/src/tkstool/key.c | 11 ++++++-----
f8ded1
 1 file changed, 6 insertions(+), 5 deletions(-)
f8ded1
f8ded1
diff --git a/base/native-tools/src/tkstool/key.c b/base/native-tools/src/tkstool/key.c
f8ded1
index e63da93..f208cbd 100644
f8ded1
--- a/base/native-tools/src/tkstool/key.c
f8ded1
+++ b/base/native-tools/src/tkstool/key.c
f8ded1
@@ -1219,13 +1219,14 @@ TKS_StoreSymmetricKeyAndNameIt( char              *symmetricKeyName,
f8ded1
     rvExtractSymmetricKey = PK11_ExtractKeyValue( /* symmetric key */ symKey );
f8ded1
     if( rvExtractSymmetricKey != SECSuccess ) {
f8ded1
         PR_fprintf( PR_STDERR,
f8ded1
-                    "ERROR:  Failed to extract the %s key!\n\n",
f8ded1
+                    "ERROR:  Failed to extract the %s key for final display, OK if in FIPs mode!\n\n",
f8ded1
                     symmetricKeyName );
f8ded1
-        goto destroyHexSymmetricKey;
f8ded1
-    }
f8ded1
+        symmetricKey = NULL;
f8ded1
+    } else {
f8ded1
 
f8ded1
-    /* If present, retrieve the raw key data */
f8ded1
-    symmetricKey = PK11_GetKeyData( /* symmetric key */  symKey );
f8ded1
+        /* If present, retrieve the raw key data */
f8ded1
+        symmetricKey = PK11_GetKeyData( /* symmetric key */  symKey );
f8ded1
+    }
f8ded1
 
f8ded1
 #if defined(DEBUG)
f8ded1
     /* For convenience, display the final symmetric key and */
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From 38df4274214938ceece85627abb6d4fe77b960ff Mon Sep 17 00:00:00 2001
f8ded1
From: Ade Lee <alee@redhat.com>
f8ded1
Date: Fri, 26 May 2017 13:06:18 -0400
f8ded1
Subject: [PATCH 06/14] Refactor client to not use keysets
f8ded1
f8ded1
It is simpler to simply tell the client which
f8ded1
algorithm to use for key wrapping and encryption, rather
f8ded1
than use key sets.  Therefore:
f8ded1
f8ded1
* KRAInfo and CAInfo are refactored to provide the
f8ded1
  algorithms required for key wrapping and encryption.
f8ded1
f8ded1
* Client is modified to use these parameters to determine
f8ded1
  which algorithms to use.
f8ded1
f8ded1
* We specify the OIDs that will be used in the PKIARchiveOptions
f8ded1
  more correctly.  The options are basically:
f8ded1
  AES-128-CBC, DES3-CBC, AES KeyWrap/Pad
f8ded1
f8ded1
Change-Id: Ic3fca902bbc45f7f72bcd4676c994f8a89c3a409
f8ded1
---
f8ded1
 base/common/src/org/dogtagpki/common/CAInfo.java   |  34 +++--
f8ded1
 base/common/src/org/dogtagpki/common/KRAInfo.java  |  34 +++++
f8ded1
 .../src/com/netscape/cmstools/CRMFPopClient.java   | 153 ++++++++++-----------
f8ded1
 .../cmstools/client/ClientCertRequestCLI.java      |  34 +----
f8ded1
 .../org/dogtagpki/server/rest/CAInfoService.java   |  18 +--
f8ded1
 .../org/dogtagpki/server/rest/KRAInfoService.java  |  40 +++++-
f8ded1
 .../com/netscape/cmsutil/crypto/CryptoUtil.java    |  22 +++
f8ded1
 7 files changed, 206 insertions(+), 129 deletions(-)
f8ded1
f8ded1
diff --git a/base/common/src/org/dogtagpki/common/CAInfo.java b/base/common/src/org/dogtagpki/common/CAInfo.java
f8ded1
index f21dcd0..0f68c7a 100644
f8ded1
--- a/base/common/src/org/dogtagpki/common/CAInfo.java
f8ded1
+++ b/base/common/src/org/dogtagpki/common/CAInfo.java
f8ded1
@@ -54,7 +54,8 @@ public class CAInfo extends ResourceMessage {
f8ded1
     }
f8ded1
 
f8ded1
     String archivalMechanism;
f8ded1
-    String wrappingKeySet;
f8ded1
+    String encryptAlgorithm;
f8ded1
+    String keyWrapAlgorithm;
f8ded1
 
f8ded1
     @XmlElement(name="ArchivalMechanism")
f8ded1
     public String getArchivalMechanism() {
f8ded1
@@ -65,13 +66,20 @@ public class CAInfo extends ResourceMessage {
f8ded1
         this.archivalMechanism = archivalMechanism;
f8ded1
     }
f8ded1
 
f8ded1
-    @XmlElement(name="WrappingKeySet")
f8ded1
-    public String getWrappingKeySet() {
f8ded1
-        return wrappingKeySet;
f8ded1
+    public String getEncryptAlgorithm() {
f8ded1
+        return encryptAlgorithm;
f8ded1
     }
f8ded1
 
f8ded1
-    public void setWrappingKeySet(String wrappingKeySet) {
f8ded1
-        this.wrappingKeySet = wrappingKeySet;
f8ded1
+    public void setEncryptAlgorithm(String encryptAlgorithm) {
f8ded1
+        this.encryptAlgorithm = encryptAlgorithm;
f8ded1
+    }
f8ded1
+
f8ded1
+    public String getKeyWrapAlgorithm() {
f8ded1
+        return keyWrapAlgorithm;
f8ded1
+    }
f8ded1
+
f8ded1
+    public void setKeyWrapAlgorithm(String keyWrapAlgorithm) {
f8ded1
+        this.keyWrapAlgorithm = keyWrapAlgorithm;
f8ded1
     }
f8ded1
 
f8ded1
     @Override
f8ded1
@@ -79,7 +87,8 @@ public class CAInfo extends ResourceMessage {
f8ded1
         final int prime = 31;
f8ded1
         int result = super.hashCode();
f8ded1
         result = prime * result + ((archivalMechanism == null) ? 0 : archivalMechanism.hashCode());
f8ded1
-        result = prime * result + ((wrappingKeySet == null) ? 0 : wrappingKeySet.hashCode());
f8ded1
+        result = prime * result + ((encryptAlgorithm == null) ? 0 : encryptAlgorithm.hashCode());
f8ded1
+        result = prime * result + ((keyWrapAlgorithm == null) ? 0 : keyWrapAlgorithm.hashCode());
f8ded1
         return result;
f8ded1
     }
f8ded1
 
f8ded1
@@ -97,10 +106,15 @@ public class CAInfo extends ResourceMessage {
f8ded1
                 return false;
f8ded1
         } else if (!archivalMechanism.equals(other.archivalMechanism))
f8ded1
             return false;
f8ded1
-        if (wrappingKeySet == null) {
f8ded1
-            if (other.wrappingKeySet != null)
f8ded1
+        if (encryptAlgorithm == null) {
f8ded1
+            if (other.encryptAlgorithm != null)
f8ded1
+                return false;
f8ded1
+        } else if (!encryptAlgorithm.equals(other.encryptAlgorithm))
f8ded1
+            return false;
f8ded1
+        if (keyWrapAlgorithm == null) {
f8ded1
+            if (other.keyWrapAlgorithm != null)
f8ded1
                 return false;
f8ded1
-        } else if (!wrappingKeySet.equals(other.wrappingKeySet))
f8ded1
+        } else if (!keyWrapAlgorithm.equals(other.keyWrapAlgorithm))
f8ded1
             return false;
f8ded1
         return true;
f8ded1
     }
f8ded1
diff --git a/base/common/src/org/dogtagpki/common/KRAInfo.java b/base/common/src/org/dogtagpki/common/KRAInfo.java
f8ded1
index e17bd64..66fb992 100644
f8ded1
--- a/base/common/src/org/dogtagpki/common/KRAInfo.java
f8ded1
+++ b/base/common/src/org/dogtagpki/common/KRAInfo.java
f8ded1
@@ -55,6 +55,8 @@ public class KRAInfo extends ResourceMessage {
f8ded1
 
f8ded1
     String archivalMechanism;
f8ded1
     String recoveryMechanism;
f8ded1
+    String encryptAlgorithm;
f8ded1
+    String wrapAlgorithm;
f8ded1
 
f8ded1
     @XmlElement(name="ArchivalMechanism")
f8ded1
     public String getArchivalMechanism() {
f8ded1
@@ -74,12 +76,32 @@ public class KRAInfo extends ResourceMessage {
f8ded1
         this.recoveryMechanism = recoveryMechanism;
f8ded1
     }
f8ded1
 
f8ded1
+    @XmlElement(name="EncryptAlgorithm")
f8ded1
+    public String getEncryptAlgorithm() {
f8ded1
+        return encryptAlgorithm;
f8ded1
+    }
f8ded1
+
f8ded1
+    public void setEncryptAlgorithm(String encryptAlgorithm) {
f8ded1
+        this.encryptAlgorithm = encryptAlgorithm;
f8ded1
+    }
f8ded1
+
f8ded1
+    @XmlElement(name="WrapAlgorithm")
f8ded1
+    public String getWrapAlgorithm() {
f8ded1
+        return wrapAlgorithm;
f8ded1
+    }
f8ded1
+
f8ded1
+    public void setWrapAlgorithm(String wrapAlgorithm) {
f8ded1
+        this.wrapAlgorithm = wrapAlgorithm;
f8ded1
+    }
f8ded1
+
f8ded1
     @Override
f8ded1
     public int hashCode() {
f8ded1
         final int prime = 31;
f8ded1
         int result = super.hashCode();
f8ded1
         result = prime * result + ((archivalMechanism == null) ? 0 : archivalMechanism.hashCode());
f8ded1
+        result = prime * result + ((encryptAlgorithm == null) ? 0 : encryptAlgorithm.hashCode());
f8ded1
         result = prime * result + ((recoveryMechanism == null) ? 0 : recoveryMechanism.hashCode());
f8ded1
+        result = prime * result + ((wrapAlgorithm == null) ? 0 : wrapAlgorithm.hashCode());
f8ded1
         return result;
f8ded1
     }
f8ded1
 
f8ded1
@@ -97,11 +119,21 @@ public class KRAInfo extends ResourceMessage {
f8ded1
                 return false;
f8ded1
         } else if (!archivalMechanism.equals(other.archivalMechanism))
f8ded1
             return false;
f8ded1
+        if (encryptAlgorithm == null) {
f8ded1
+            if (other.encryptAlgorithm != null)
f8ded1
+                return false;
f8ded1
+        } else if (!encryptAlgorithm.equals(other.encryptAlgorithm))
f8ded1
+            return false;
f8ded1
         if (recoveryMechanism == null) {
f8ded1
             if (other.recoveryMechanism != null)
f8ded1
                 return false;
f8ded1
         } else if (!recoveryMechanism.equals(other.recoveryMechanism))
f8ded1
             return false;
f8ded1
+        if (wrapAlgorithm == null) {
f8ded1
+            if (other.wrapAlgorithm != null)
f8ded1
+                return false;
f8ded1
+        } else if (!wrapAlgorithm.equals(other.wrapAlgorithm))
f8ded1
+            return false;
f8ded1
         return true;
f8ded1
     }
f8ded1
 
f8ded1
@@ -125,6 +157,8 @@ public class KRAInfo extends ResourceMessage {
f8ded1
         KRAInfo before = new KRAInfo();
f8ded1
         before.setArchivalMechanism("encrypt");
f8ded1
         before.setRecoveryMechanism("keywrap");
f8ded1
+        before.setEncryptAlgorithm("AES/CBC/Pad");
f8ded1
+        before.setWrapAlgorithm("AES KeyWrap/Padding");
f8ded1
 
f8ded1
         String string = before.toString();
f8ded1
         System.out.println(string);
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
index 0057a1d..b06faa6 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
@@ -190,11 +190,7 @@ public class CRMFPopClient {
f8ded1
         option.setArgName("extractable");
f8ded1
         options.addOption(option);
f8ded1
 
f8ded1
-        option = new Option("g", true, "KeyWrap");
f8ded1
-        option.setArgName("keyWrap");
f8ded1
-        options.addOption(option);
f8ded1
-
f8ded1
-        option = new Option("w", true, "Wrapping Keyset");
f8ded1
+        option = new Option("w", true, "Algorithm to be used for key wrapping");
f8ded1
         option.setArgName("keySet");
f8ded1
         options.addOption(option);
f8ded1
 
f8ded1
@@ -231,10 +227,7 @@ public class CRMFPopClient {
f8ded1
         System.out.println("                               - POP_NONE: without POP");
f8ded1
         System.out.println("                               - POP_SUCCESS: with valid POP");
f8ded1
         System.out.println("                               - POP_FAIL: with invalid POP (for testing)");
f8ded1
-        System.out.println("  -g <true|false>              Use KeyWrapping to wrap private key (default: true)");
f8ded1
-        System.out.println("                               - true: use a key wrapping algorithm");
f8ded1
-        System.out.println("                               - false: use an encryption algorithm");
f8ded1
-        System.out.println("  -w <keyset_id>               Key set ID to use when wrapping the private key");
f8ded1
+        System.out.println("  -w <keywrap algorithm>       Algorithm to use for key wrapping");
f8ded1
         System.out.println("  -b <transport cert>          PEM transport certificate (default: transport.txt)");
f8ded1
         System.out.println("  -v, --verbose                Run in verbose mode.");
f8ded1
         System.out.println("      --help                   Show help message.");
f8ded1
@@ -329,20 +322,17 @@ public class CRMFPopClient {
f8ded1
 
f8ded1
         boolean self_sign = cmd.hasOption("y");
f8ded1
 
f8ded1
-        // get the key wrapping mechanism
f8ded1
-        boolean keyWrap = true;
f8ded1
-        if (cmd.hasOption("g")) {
f8ded1
-            keyWrap = Boolean.parseBoolean(cmd.getOptionValue("g"));
f8ded1
+        // get the keywrap algorithm
f8ded1
+        KeyWrapAlgorithm keyWrapAlgorithm = null;
f8ded1
+        String kwAlg = KeyWrapAlgorithm.AES_KEY_WRAP_PAD.toString();
f8ded1
+        if (cmd.hasOption("w")) {
f8ded1
+            kwAlg = cmd.getOptionValue("w");
f8ded1
         } else {
f8ded1
-            String useKeyWrap = System.getenv("KEY_ARCHIVAL_USE_KEY_WRAPPING");
f8ded1
-            if (useKeyWrap != null) {
f8ded1
-                keyWrap = Boolean.parseBoolean(useKeyWrap);
f8ded1
+            String alg = System.getenv("KEY_ARCHIVAL_KEYWRAP_ALGORITHM");
f8ded1
+            if (alg != null) {
f8ded1
+                kwAlg = alg;
f8ded1
             }
f8ded1
         }
f8ded1
-        String archivalMechanism = keyWrap ? KRAInfoResource.KEYWRAP_MECHANISM :
f8ded1
-            KRAInfoResource.ENCRYPT_MECHANISM;
f8ded1
-
f8ded1
-        String wrappingKeySet = cmd.getOptionValue("w");
f8ded1
 
f8ded1
         String output = cmd.getOptionValue("o");
f8ded1
 
f8ded1
@@ -351,12 +341,11 @@ public class CRMFPopClient {
f8ded1
         String requestor = cmd.getOptionValue("r");
f8ded1
 
f8ded1
         if (hostPort != null) {
f8ded1
-            if (cmd.hasOption("g") || cmd.hasOption("w")) {
f8ded1
-                printError("Wrapping Key Set (-g) and keywrap (-w) options should " +
f8ded1
-                        "not be specified when hostport is specified.  " +
f8ded1
-                        "CRMFPopClient will contact the server to " +
f8ded1
-                        "determine the correct values for these parameters");
f8ded1
-                System.exit(1);
f8ded1
+            if (cmd.hasOption("w")) {
f8ded1
+                printError("Any value specified for the key wrap parameter (-w) " +
f8ded1
+                        "will be overriden.  CRMFPopClient will contact the " +
f8ded1
+                        "CA to determine the supported algorithm when " +
f8ded1
+                        "hostport is specified");
f8ded1
             }
f8ded1
         }
f8ded1
 
f8ded1
@@ -493,9 +482,9 @@ public class CRMFPopClient {
f8ded1
             System.out.println("Keypair private key id: " + kid);
f8ded1
 
f8ded1
             if (hostPort != null) {
f8ded1
-                // check the CA for the required keyset and archival mechanism
f8ded1
+                // check the CA for the required key wrap algorithm
f8ded1
                 // if found, override whatever has been set by the command line
f8ded1
-                // options or environment for archivalMechanism and wrappingKeySet
f8ded1
+                // options for the key wrap algorithm
f8ded1
 
f8ded1
                 ClientConfig config = new ClientConfig();
f8ded1
                 String host = hostPort.substring(0, hostPort.indexOf(':'));
f8ded1
@@ -503,31 +492,17 @@ public class CRMFPopClient {
f8ded1
                 config.setServerURL("http", host, port);
f8ded1
 
f8ded1
                 PKIClient pkiclient = new PKIClient(config);
f8ded1
-
f8ded1
-                // get archival mechanism
f8ded1
-                CAInfoClient infoClient = new CAInfoClient(pkiclient, "ca");
f8ded1
-                try {
f8ded1
-                    CAInfo info = infoClient.getInfo();
f8ded1
-                    archivalMechanism = info.getArchivalMechanism();
f8ded1
-                    wrappingKeySet = info.getWrappingKeySet();
f8ded1
-                } catch (PKIException e) {
f8ded1
-                    if (e.getCode() == 404) {
f8ded1
-                        // assume this is an older server,
f8ded1
-                        archivalMechanism = KRAInfoResource.KEYWRAP_MECHANISM;
f8ded1
-                        wrappingKeySet = "0";
f8ded1
-                    } else {
f8ded1
-                        throw new Exception("Failed to retrieve archive wrapping information from the CA: " + e, e);
f8ded1
-                    }
f8ded1
-                } catch (Exception e) {
f8ded1
-                    throw new Exception("Failed to retrieve archive wrapping information from the CA: " + e, e);
f8ded1
-                }
f8ded1
+                kwAlg = getKeyWrapAlgotihm(pkiclient);
f8ded1
             }
f8ded1
 
f8ded1
+            if (verbose) System.out.println("Using key wrap algorithm: " + kwAlg);
f8ded1
+            keyWrapAlgorithm = KeyWrapAlgorithm.fromString(kwAlg);
f8ded1
+
f8ded1
             if (verbose) System.out.println("Creating certificate request");
f8ded1
             CertRequest certRequest = client.createCertRequest(
f8ded1
                     self_sign,
f8ded1
                     token, transportCert, algorithm, keyPair,
f8ded1
-                    subject, archivalMechanism, wrappingKeySet);
f8ded1
+                    subject, keyWrapAlgorithm);
f8ded1
 
f8ded1
             ProofOfPossession pop = null;
f8ded1
 
f8ded1
@@ -592,6 +567,36 @@ public class CRMFPopClient {
f8ded1
         }
f8ded1
     }
f8ded1
 
f8ded1
+    public static String getKeyWrapAlgotihm(PKIClient pkiclient)
f8ded1
+            throws Exception {
f8ded1
+        String kwAlg = null;
f8ded1
+        CAInfoClient infoClient = new CAInfoClient(pkiclient, "ca");
f8ded1
+        String archivalMechanism = KRAInfoResource.KEYWRAP_MECHANISM;
f8ded1
+
f8ded1
+        try {
f8ded1
+            CAInfo info = infoClient.getInfo();
f8ded1
+            archivalMechanism = info.getArchivalMechanism();
f8ded1
+            kwAlg = info.getKeyWrapAlgorithm();
f8ded1
+        } catch (PKIException e) {
f8ded1
+            if (e.getCode() == 404) {
f8ded1
+                // assume this is an older server,
f8ded1
+                archivalMechanism = KRAInfoResource.KEYWRAP_MECHANISM;
f8ded1
+                kwAlg = KeyWrapAlgorithm.DES3_CBC_PAD.toString();
f8ded1
+            } else {
f8ded1
+                throw new Exception("Failed to retrieve archive wrapping information from the CA: " + e, e);
f8ded1
+            }
f8ded1
+        } catch (Exception e) {
f8ded1
+            throw new Exception("Failed to retrieve archive wrapping information from the CA: " + e, e);
f8ded1
+        }
f8ded1
+
f8ded1
+        if (!archivalMechanism.equals(KRAInfoResource.KEYWRAP_MECHANISM)) {
f8ded1
+            // new server with encryption set.  Use something we know will
f8ded1
+            // work.  AES-128-CBC
f8ded1
+            kwAlg = KeyWrapAlgorithm.AES_CBC_PAD.toString();
f8ded1
+        }
f8ded1
+        return kwAlg;
f8ded1
+    }
f8ded1
+
f8ded1
     public void setVerbose(boolean verbose) {
f8ded1
         this.verbose = verbose;
f8ded1
     }
f8ded1
@@ -637,10 +642,9 @@ public class CRMFPopClient {
f8ded1
             String algorithm,
f8ded1
             KeyPair keyPair,
f8ded1
             Name subject,
f8ded1
-            String archivalMechanism,
f8ded1
-            String wrappingKeySet) throws Exception {
f8ded1
+            KeyWrapAlgorithm keyWrapAlgorithm) throws Exception {
f8ded1
         return createCertRequest(false, token, transportCert, algorithm, keyPair,
f8ded1
-            subject, archivalMechanism, wrappingKeySet);
f8ded1
+            subject, keyWrapAlgorithm);
f8ded1
     }
f8ded1
 
f8ded1
     public CertRequest createCertRequest(
f8ded1
@@ -650,24 +654,15 @@ public class CRMFPopClient {
f8ded1
             String algorithm,
f8ded1
             KeyPair keyPair,
f8ded1
             Name subject,
f8ded1
-            String archivalMechanism,
f8ded1
-            String wrappingKeySet) throws Exception {
f8ded1
-        EncryptionAlgorithm encryptAlg = null;
f8ded1
-
f8ded1
-        if (wrappingKeySet == null) {
f8ded1
-            wrappingKeySet = System.getenv("KEY_WRAP_PARAMETER_SET");
f8ded1
+            KeyWrapAlgorithm keyWrapAlgorithm) throws Exception {
f8ded1
+        byte[] iv = null;
f8ded1
+        if (keyWrapAlgorithm.getParameterClasses() != null) {
f8ded1
+            iv = CryptoUtil.getNonceData(keyWrapAlgorithm.getBlockSize());
f8ded1
         }
f8ded1
+        OBJECT_IDENTIFIER kwOID = CryptoUtil.getOID(keyWrapAlgorithm);
f8ded1
 
f8ded1
-        if (wrappingKeySet != null && wrappingKeySet.equalsIgnoreCase("0")) {
f8ded1
-            // talking to an old server?
f8ded1
-            encryptAlg = EncryptionAlgorithm.DES3_CBC;
f8ded1
-        } else {
f8ded1
-            encryptAlg = EncryptionAlgorithm.AES_128_CBC;
f8ded1
-        }
f8ded1
-
f8ded1
-        byte[] iv = CryptoUtil.getNonceData(encryptAlg.getIVLength());
f8ded1
-        AlgorithmIdentifier aid = new AlgorithmIdentifier(encryptAlg.toOID(), new OCTET_STRING(iv));
f8ded1
-        WrappingParams params = getWrappingParams(encryptAlg, iv, archivalMechanism);
f8ded1
+        AlgorithmIdentifier aid = new AlgorithmIdentifier(kwOID, new OCTET_STRING(iv));
f8ded1
+        WrappingParams params = getWrappingParams(keyWrapAlgorithm, iv);
f8ded1
 
f8ded1
         PKIArchiveOptions opts = CryptoUtil.createPKIArchiveOptions(
f8ded1
                 token,
f8ded1
@@ -698,29 +693,21 @@ public class CRMFPopClient {
f8ded1
         return new CertRequest(new INTEGER(1), certTemplate, seq);
f8ded1
     }
f8ded1
 
f8ded1
-    private WrappingParams getWrappingParams(EncryptionAlgorithm encryptAlg, byte[] wrapIV,
f8ded1
-            String archivalMechanism) throws Exception {
f8ded1
-        if (encryptAlg.getAlg().toString().equalsIgnoreCase("AES")) {
f8ded1
-            KeyWrapAlgorithm wrapAlg = null;
f8ded1
-            IVParameterSpec wrapIVS = null;
f8ded1
-            if (archivalMechanism.equals(KRAInfoResource.ENCRYPT_MECHANISM)) {
f8ded1
-                // We will use AES_CBC_PAD as the a key wrap mechanism.  This
f8ded1
-                // can be decrypted using the same mechanism on the server.
f8ded1
-                wrapAlg = KeyWrapAlgorithm.AES_CBC_PAD;
f8ded1
-                wrapIVS = new IVParameterSpec(wrapIV);
f8ded1
-            } else {
f8ded1
-                wrapAlg = KeyWrapAlgorithm.AES_KEY_WRAP_PAD;
f8ded1
-            }
f8ded1
+    private WrappingParams getWrappingParams(KeyWrapAlgorithm kwAlg, byte[] iv) throws Exception {
f8ded1
+        IVParameterSpec ivps = iv != null ? new IVParameterSpec(iv): null;
f8ded1
+
f8ded1
+        if (kwAlg == KeyWrapAlgorithm.AES_KEY_WRAP_PAD ||
f8ded1
+            kwAlg == KeyWrapAlgorithm.AES_CBC_PAD) {
f8ded1
             return new WrappingParams(
f8ded1
                 SymmetricKey.AES, KeyGenAlgorithm.AES, 128,
f8ded1
-                KeyWrapAlgorithm.RSA, encryptAlg,
f8ded1
-                wrapAlg, wrapIVS, wrapIVS);
f8ded1
-        } else if (encryptAlg.getAlg().toString().equalsIgnoreCase("DESede")) {
f8ded1
+                KeyWrapAlgorithm.RSA, EncryptionAlgorithm.AES_128_CBC_PAD,
f8ded1
+                kwAlg, ivps, ivps);
f8ded1
+        } else if (kwAlg == KeyWrapAlgorithm.DES3_CBC_PAD) {
f8ded1
             return new WrappingParams(
f8ded1
                     SymmetricKey.DES3, KeyGenAlgorithm.DES3, 168,
f8ded1
                     KeyWrapAlgorithm.RSA, EncryptionAlgorithm.DES3_CBC_PAD,
f8ded1
                     KeyWrapAlgorithm.DES3_CBC_PAD,
f8ded1
-                    new IVParameterSpec(wrapIV), new IVParameterSpec(wrapIV));
f8ded1
+                    ivps, ivps);
f8ded1
         } else {
f8ded1
             throw new Exception("Invalid encryption algorithm");
f8ded1
         }
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
f8ded1
index a14bb24..9a0cfcc 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
f8ded1
@@ -29,18 +29,15 @@ import java.util.Vector;
f8ded1
 import org.apache.commons.cli.CommandLine;
f8ded1
 import org.apache.commons.cli.Option;
f8ded1
 import org.apache.commons.io.FileUtils;
f8ded1
-import org.dogtagpki.common.CAInfo;
f8ded1
-import org.dogtagpki.common.CAInfoClient;
f8ded1
-import org.dogtagpki.common.KRAInfoResource;
f8ded1
 import org.mozilla.jss.CryptoManager;
f8ded1
 import org.mozilla.jss.crypto.CryptoToken;
f8ded1
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
f8ded1
 import org.mozilla.jss.crypto.Signature;
f8ded1
 import org.mozilla.jss.crypto.X509Certificate;
f8ded1
 import org.mozilla.jss.pkix.crmf.CertRequest;
f8ded1
 import org.mozilla.jss.pkix.crmf.ProofOfPossession;
f8ded1
 import org.mozilla.jss.pkix.primitive.Name;
f8ded1
 
f8ded1
-import com.netscape.certsrv.base.PKIException;
f8ded1
 import com.netscape.certsrv.cert.CertClient;
f8ded1
 import com.netscape.certsrv.cert.CertEnrollmentRequest;
f8ded1
 import com.netscape.certsrv.cert.CertRequestInfos;
f8ded1
@@ -249,29 +246,13 @@ public class ClientCertRequestCLI extends CLI {
f8ded1
             CryptoManager manager = CryptoManager.getInstance();
f8ded1
             X509Certificate transportCert = manager.importCACertPackage(transportCertData);
f8ded1
 
f8ded1
-            // get archival mechanism
f8ded1
-            CAInfoClient infoClient = new CAInfoClient(client, "ca");
f8ded1
-            String archivalMechanism = KRAInfoResource.KEYWRAP_MECHANISM;
f8ded1
-            String wrappingKeySet = "1";
f8ded1
-            try {
f8ded1
-                CAInfo info = infoClient.getInfo();
f8ded1
-                archivalMechanism = info.getArchivalMechanism();
f8ded1
-                wrappingKeySet = info.getWrappingKeySet();
f8ded1
-            } catch (PKIException e) {
f8ded1
-                if (e.getCode() == 404) {
f8ded1
-                    // assume this is an older server,
f8ded1
-                    archivalMechanism = KRAInfoResource.KEYWRAP_MECHANISM;
f8ded1
-                    wrappingKeySet = "0";
f8ded1
-                } else {
f8ded1
-                    throw new Exception("Failed to retrieve archive wrapping information from the CA: " + e, e);
f8ded1
-                }
f8ded1
-            } catch (Exception e) {
f8ded1
-                throw new Exception("Failed to retrieve archive wrapping information from the CA: " + e, e);
f8ded1
-            }
f8ded1
+            // get archival and key wrap mechanisms from CA
f8ded1
+            String kwAlg = CRMFPopClient.getKeyWrapAlgotihm(client);
f8ded1
+            KeyWrapAlgorithm keyWrapAlgorithm = KeyWrapAlgorithm.fromString(kwAlg);
f8ded1
 
f8ded1
             csr = generateCrmfRequest(transportCert, subjectDN, attributeEncoding,
f8ded1
                     algorithm, length, curve, sslECDH, temporary, sensitive, extractable, withPop,
f8ded1
-                    archivalMechanism, wrappingKeySet);
f8ded1
+                    keyWrapAlgorithm);
f8ded1
 
f8ded1
         } else {
f8ded1
             throw new Exception("Unknown request type: " + requestType);
f8ded1
@@ -411,8 +392,7 @@ public class ClientCertRequestCLI extends CLI {
f8ded1
             int sensitive,
f8ded1
             int extractable,
f8ded1
             boolean withPop,
f8ded1
-            String archivalMechanism,
f8ded1
-            String wrappingKeySet
f8ded1
+            KeyWrapAlgorithm keyWrapAlgorithm
f8ded1
             ) throws Exception {
f8ded1
 
f8ded1
         CryptoManager manager = CryptoManager.getInstance();
f8ded1
@@ -434,7 +414,7 @@ public class ClientCertRequestCLI extends CLI {
f8ded1
         }
f8ded1
 
f8ded1
         CertRequest certRequest = client.createCertRequest(
f8ded1
-                token, transportCert, algorithm, keyPair, subject, archivalMechanism, wrappingKeySet);
f8ded1
+                token, transportCert, algorithm, keyPair, subject, keyWrapAlgorithm);
f8ded1
 
f8ded1
         ProofOfPossession pop = null;
f8ded1
         if (withPop) {
f8ded1
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java b/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java
f8ded1
index 398f499..52c9ca0 100644
f8ded1
--- a/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java
f8ded1
+++ b/base/server/cms/src/org/dogtagpki/server/rest/CAInfoService.java
f8ded1
@@ -28,6 +28,8 @@ import org.dogtagpki.common.CAInfo;
f8ded1
 import org.dogtagpki.common.CAInfoResource;
f8ded1
 import org.dogtagpki.common.KRAInfo;
f8ded1
 import org.dogtagpki.common.KRAInfoClient;
f8ded1
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
f8ded1
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
f8ded1
 import org.slf4j.Logger;
f8ded1
 import org.slf4j.LoggerFactory;
f8ded1
 
f8ded1
@@ -73,7 +75,8 @@ public class CAInfoService extends PKIService implements CAInfoResource {
f8ded1
     // KRA-related fields (the initial values are only used if we
f8ded1
     // did not yet receive authoritative info from KRA)
f8ded1
     private static String archivalMechanism = KRAInfoService.KEYWRAP_MECHANISM;
f8ded1
-    private static String wrappingKeySet = "0";
f8ded1
+    private static String encryptAlgorithm;
f8ded1
+    private static String keyWrapAlgorithm;
f8ded1
 
f8ded1
     @Override
f8ded1
     public Response getInfo() throws Exception {
f8ded1
@@ -116,7 +119,8 @@ public class CAInfoService extends PKIService implements CAInfoResource {
f8ded1
             }
f8ded1
 
f8ded1
             info.setArchivalMechanism(archivalMechanism);
f8ded1
-            info.setWrappingKeySet(wrappingKeySet);
f8ded1
+            info.setEncryptAlgorithm(encryptAlgorithm);
f8ded1
+            info.setKeyWrapAlgorithm(keyWrapAlgorithm);
f8ded1
         }
f8ded1
     }
f8ded1
 
f8ded1
@@ -125,10 +129,8 @@ public class CAInfoService extends PKIService implements CAInfoResource {
f8ded1
             KRAInfo kraInfo = getKRAInfoClient(connInfo).getInfo();
f8ded1
 
f8ded1
             archivalMechanism = kraInfo.getArchivalMechanism();
f8ded1
-
f8ded1
-            // request succeeded; the KRA is 10.4 or higher,
f8ded1
-            // therefore supports key set v1
f8ded1
-            wrappingKeySet = "1";
f8ded1
+            encryptAlgorithm = kraInfo.getEncryptAlgorithm();
f8ded1
+            keyWrapAlgorithm = kraInfo.getWrapAlgorithm();
f8ded1
 
f8ded1
             // mark info as authoritative
f8ded1
             kraInfoAuthoritative = true;
f8ded1
@@ -137,8 +139,8 @@ public class CAInfoService extends PKIService implements CAInfoResource {
f8ded1
                 // The KRAInfoResource was added in 10.4,
f8ded1
                 // so we are talking to a pre-10.4 KRA
f8ded1
 
f8ded1
-                // pre-10.4 only supports key set v0
f8ded1
-                wrappingKeySet = "0";
f8ded1
+                encryptAlgorithm = EncryptionAlgorithm.DES3_CBC_PAD.toString();
f8ded1
+                keyWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD.toString();
f8ded1
 
f8ded1
                 // pre-10.4 KRA does not advertise the archival
f8ded1
                 // mechanism; look for the old knob in CA's config
f8ded1
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java b/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java
f8ded1
index c4b3252..a9c3cdf 100644
f8ded1
--- a/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java
f8ded1
+++ b/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java
f8ded1
@@ -29,14 +29,25 @@ import org.slf4j.LoggerFactory;
f8ded1
 import com.netscape.certsrv.apps.CMS;
f8ded1
 import com.netscape.certsrv.base.EBaseException;
f8ded1
 import com.netscape.certsrv.base.IConfigStore;
f8ded1
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
f8ded1
+import com.netscape.certsrv.security.IStorageKeyUnit;
f8ded1
 import com.netscape.cms.servlet.base.PKIService;
f8ded1
 
f8ded1
+import netscape.security.util.WrappingParams;
f8ded1
+
f8ded1
 /**
f8ded1
  * @author Ade Lee
f8ded1
  */
f8ded1
 public class KRAInfoService extends PKIService implements KRAInfoResource {
f8ded1
 
f8ded1
     private static Logger logger = LoggerFactory.getLogger(InfoService.class);
f8ded1
+    private IKeyRecoveryAuthority kra;
f8ded1
+    private IStorageKeyUnit storageUnit;
f8ded1
+
f8ded1
+    public KRAInfoService() {
f8ded1
+        kra = (IKeyRecoveryAuthority) CMS.getSubsystem("kra");
f8ded1
+        storageUnit = kra.getStorageKeyUnit();
f8ded1
+    }
f8ded1
 
f8ded1
     @Override
f8ded1
     public Response getInfo() throws Exception {
f8ded1
@@ -47,7 +58,8 @@ public class KRAInfoService extends PKIService implements KRAInfoResource {
f8ded1
         KRAInfo info = new KRAInfo();
f8ded1
         info.setArchivalMechanism(getArchivalMechanism());
f8ded1
         info.setRecoveryMechanism(getRecoveryMechanism());
f8ded1
-
f8ded1
+        info.setEncryptAlgorithm(getEncryptAlgorithm());
f8ded1
+        info.setArchivalMechanism(getWrapAlgorithm());
f8ded1
 
f8ded1
         return createOKResponse(info);
f8ded1
     }
f8ded1
@@ -63,5 +75,31 @@ public class KRAInfoService extends PKIService implements KRAInfoResource {
f8ded1
         boolean encrypt_recovery = cs.getBoolean("kra.allowEncDecrypt.recovery", false);
f8ded1
         return encrypt_recovery ? KRAInfoResource.ENCRYPT_MECHANISM : KRAInfoResource.KEYWRAP_MECHANISM;
f8ded1
     }
f8ded1
+
f8ded1
+    String getWrapAlgorithm() throws EBaseException {
f8ded1
+        IConfigStore cs = CMS.getConfigStore();
f8ded1
+        boolean encrypt_archival = cs.getBoolean("kra.allowEncDecrypt.archival", false);
f8ded1
+        WrappingParams params = null;
f8ded1
+        try {
f8ded1
+            params = storageUnit.getWrappingParams(encrypt_archival);
f8ded1
+        } catch (Exception e) {
f8ded1
+            // return something that should always work
f8ded1
+            return "AES/CBC/Padding";
f8ded1
+        }
f8ded1
+        return params.getPayloadWrapAlgorithm().toString();
f8ded1
+    }
f8ded1
+
f8ded1
+    String getEncryptAlgorithm() throws EBaseException {
f8ded1
+        IConfigStore cs = CMS.getConfigStore();
f8ded1
+        boolean encrypt_archival = cs.getBoolean("kra.allowEncDecrypt.archival", false);
f8ded1
+        WrappingParams params = null;
f8ded1
+        try {
f8ded1
+            params = storageUnit.getWrappingParams(encrypt_archival);
f8ded1
+        } catch (Exception e) {
f8ded1
+            // return something that should always work
f8ded1
+            return "AES/CBC/Padding";
f8ded1
+        }
f8ded1
+        return params.getPayloadEncryptionAlgorithm().toString();
f8ded1
+    }
f8ded1
 }
f8ded1
 
f8ded1
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
f8ded1
index 95b8f81..84e4a65 100644
f8ded1
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
f8ded1
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
f8ded1
@@ -2713,6 +2713,28 @@ public class CryptoUtil {
f8ded1
         throw new NoSuchAlgorithmException();
f8ded1
     }
f8ded1
 
f8ded1
+    /*
f8ded1
+     * Useful method to map KeyWrap algorithms to an OID.
f8ded1
+     * This is not yet defined within JSS, although it will be valuable to do
f8ded1
+     * so.  The hard thing though is that the KeyWrapAlgorithms in JSS do not take
f8ded1
+     * KEK key size into account for algorithms like AES.  We assume 128 bits in
f8ded1
+     * this case.
f8ded1
+     *
f8ded1
+     * This is used in the generation of CRMF requests, and will be correlated to
f8ded1
+     * the subsequent reverse mapping method below.
f8ded1
+     */
f8ded1
+    public static OBJECT_IDENTIFIER getOID(KeyWrapAlgorithm kwAlg) throws NoSuchAlgorithmException {
f8ded1
+        if (kwAlg == KeyWrapAlgorithm.AES_KEY_WRAP_PAD)
f8ded1
+            return new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.8");
f8ded1
+        if (kwAlg == KeyWrapAlgorithm.AES_CBC_PAD)
f8ded1
+            return new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.2");
f8ded1
+        if ((kwAlg == KeyWrapAlgorithm.DES3_CBC_PAD) ||
f8ded1
+            (kwAlg == KeyWrapAlgorithm.DES_CBC_PAD))
f8ded1
+            return new OBJECT_IDENTIFIER("1.2.840.113549.3.7");
f8ded1
+
f8ded1
+        throw new NoSuchAlgorithmException();
f8ded1
+    }
f8ded1
+
f8ded1
 }
f8ded1
 
f8ded1
 // START ENABLE_ECC
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From d5c331a42955365b76a1549aec047e613d3185dc Mon Sep 17 00:00:00 2001
f8ded1
From: Ade Lee <alee@redhat.com>
f8ded1
Date: Tue, 6 Jun 2017 16:16:40 -0400
f8ded1
Subject: [PATCH 07/14] Server side changes to correctly parse the new
f8ded1
 PKIArchiveOptions
f8ded1
f8ded1
The server is modified to read the new OIDs in the PKIArchiveOptions
f8ded1
and handle them correctly.
f8ded1
f8ded1
Change-Id: I328df4d6588b3c2c26a387ab2e9ed742d36824d4
f8ded1
---
f8ded1
 base/common/src/org/dogtagpki/common/CAInfo.java   |  2 +
f8ded1
 .../src/com/netscape/cmstools/CRMFPopClient.java   | 20 ++++++--
f8ded1
 .../kra/src/com/netscape/kra/TransportKeyUnit.java | 21 ++++-----
f8ded1
 .../org/dogtagpki/server/rest/KRAInfoService.java  |  2 +-
f8ded1
 .../com/netscape/cmsutil/crypto/CryptoUtil.java    | 34 ++++++++++---
f8ded1
 .../src/netscape/security/util/WrappingParams.java | 55 ++++++++++++++++++++++
f8ded1
 6 files changed, 109 insertions(+), 25 deletions(-)
f8ded1
f8ded1
diff --git a/base/common/src/org/dogtagpki/common/CAInfo.java b/base/common/src/org/dogtagpki/common/CAInfo.java
f8ded1
index 0f68c7a..ada8098 100644
f8ded1
--- a/base/common/src/org/dogtagpki/common/CAInfo.java
f8ded1
+++ b/base/common/src/org/dogtagpki/common/CAInfo.java
f8ded1
@@ -66,6 +66,7 @@ public class CAInfo extends ResourceMessage {
f8ded1
         this.archivalMechanism = archivalMechanism;
f8ded1
     }
f8ded1
 
f8ded1
+    @XmlElement(name="EncryptAlgorithm")
f8ded1
     public String getEncryptAlgorithm() {
f8ded1
         return encryptAlgorithm;
f8ded1
     }
f8ded1
@@ -74,6 +75,7 @@ public class CAInfo extends ResourceMessage {
f8ded1
         this.encryptAlgorithm = encryptAlgorithm;
f8ded1
     }
f8ded1
 
f8ded1
+    @XmlElement(name="WrapAlgorithm")
f8ded1
     public String getKeyWrapAlgorithm() {
f8ded1
         return keyWrapAlgorithm;
f8ded1
     }
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
index b06faa6..25de2dd 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
@@ -191,7 +191,7 @@ public class CRMFPopClient {
f8ded1
         options.addOption(option);
f8ded1
 
f8ded1
         option = new Option("w", true, "Algorithm to be used for key wrapping");
f8ded1
-        option.setArgName("keySet");
f8ded1
+        option.setArgName("keywrap algorithm");
f8ded1
         options.addOption(option);
f8ded1
 
f8ded1
         options.addOption("y", false, "for Self-signed cmc.");
f8ded1
@@ -655,13 +655,23 @@ public class CRMFPopClient {
f8ded1
             KeyPair keyPair,
f8ded1
             Name subject,
f8ded1
             KeyWrapAlgorithm keyWrapAlgorithm) throws Exception {
f8ded1
-        byte[] iv = null;
f8ded1
-        if (keyWrapAlgorithm.getParameterClasses() != null) {
f8ded1
-            iv = CryptoUtil.getNonceData(keyWrapAlgorithm.getBlockSize());
f8ded1
-        }
f8ded1
+        byte[] iv = CryptoUtil.getNonceData(keyWrapAlgorithm.getBlockSize());
f8ded1
         OBJECT_IDENTIFIER kwOID = CryptoUtil.getOID(keyWrapAlgorithm);
f8ded1
 
f8ded1
+        /* TODO(alee)
f8ded1
+         *
f8ded1
+         * HACK HACK!
f8ded1
+         * algorithms like AES KeyWrap do not require an IV, but we need to include one
f8ded1
+         * in the AlgorithmIdentifier above, or the creation and parsing of the
f8ded1
+         * PKIArchiveOptions options will fail.  So we include an IV in aid, but null it
f8ded1
+         * later to correctly encrypt the data
f8ded1
+         */
f8ded1
         AlgorithmIdentifier aid = new AlgorithmIdentifier(kwOID, new OCTET_STRING(iv));
f8ded1
+
f8ded1
+        Class[] iv_classes = keyWrapAlgorithm.getParameterClasses();
f8ded1
+        if (iv_classes == null || iv_classes.length == 0)
f8ded1
+            iv = null;
f8ded1
+
f8ded1
         WrappingParams params = getWrappingParams(keyWrapAlgorithm, iv);
f8ded1
 
f8ded1
         PKIArchiveOptions opts = CryptoUtil.createPKIArchiveOptions(
f8ded1
diff --git a/base/kra/src/com/netscape/kra/TransportKeyUnit.java b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
f8ded1
index d0ad8b3..91af7cf 100644
f8ded1
--- a/base/kra/src/com/netscape/kra/TransportKeyUnit.java
f8ded1
+++ b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
f8ded1
@@ -267,7 +267,7 @@ public class TransportKeyUnit extends EncryptionUnit implements
f8ded1
      * Decrypts the user private key.  This is called on the transport unit.
f8ded1
      */
f8ded1
     public byte[] decryptExternalPrivate(byte encSymmKey[],
f8ded1
-            String symmAlgOID, byte symmAlgParams[], byte encValue[],
f8ded1
+            String wrapOID, byte wrapIV[], byte encValue[],
f8ded1
             org.mozilla.jss.crypto.X509Certificate transCert)
f8ded1
             throws Exception {
f8ded1
 
f8ded1
@@ -279,12 +279,10 @@ public class TransportKeyUnit extends EncryptionUnit implements
f8ded1
         CryptoToken token = getToken(transCert);
f8ded1
         PrivateKey wrappingKey = getPrivateKey(transCert);
f8ded1
         String priKeyAlgo = wrappingKey.getAlgorithm();
f8ded1
-        WrappingParams params = new WrappingParams(
f8ded1
-                symmAlgOID,
f8ded1
-                null,
f8ded1
+        WrappingParams params = WrappingParams.getWrappingParamsFromArchiveOptions(
f8ded1
+                wrapOID,
f8ded1
                 priKeyAlgo,
f8ded1
-                new IVParameterSpec(symmAlgParams),
f8ded1
-                null);
f8ded1
+                new IVParameterSpec(wrapIV));
f8ded1
 
f8ded1
         SymmetricKey sk = CryptoUtil.unwrap(
f8ded1
                 token,
f8ded1
@@ -303,6 +301,7 @@ public class TransportKeyUnit extends EncryptionUnit implements
f8ded1
                 params.getPayloadEncryptionAlgorithm());
f8ded1
     }
f8ded1
 
f8ded1
+
f8ded1
     /**
f8ded1
      * External unwrapping. Unwraps the symmetric key using
f8ded1
      * the transport private key.
f8ded1
@@ -342,19 +341,17 @@ public class TransportKeyUnit extends EncryptionUnit implements
f8ded1
      * the transport private key.
f8ded1
      */
f8ded1
     public PrivateKey unwrap(byte encSymmKey[],
f8ded1
-            String symmAlgOID, byte symmAlgParams[],
f8ded1
+            String wrapOID, byte wrapIV[],
f8ded1
             byte encValue[], PublicKey pubKey,
f8ded1
             org.mozilla.jss.crypto.X509Certificate transCert)
f8ded1
             throws Exception {
f8ded1
         CryptoToken token = getToken(transCert);
f8ded1
         PrivateKey wrappingKey = getPrivateKey(transCert);
f8ded1
         String priKeyAlgo = wrappingKey.getAlgorithm();
f8ded1
-        WrappingParams params = new WrappingParams(
f8ded1
-                symmAlgOID,
f8ded1
-                null,
f8ded1
+        WrappingParams params = WrappingParams.getWrappingParamsFromArchiveOptions(
f8ded1
+                wrapOID,
f8ded1
                 priKeyAlgo,
f8ded1
-                new IVParameterSpec(symmAlgParams),
f8ded1
-                new IVParameterSpec(symmAlgParams));
f8ded1
+                new IVParameterSpec(wrapIV));
f8ded1
 
f8ded1
         // (1) unwrap the session key
f8ded1
         SymmetricKey sk = CryptoUtil.unwrap(
f8ded1
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java b/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java
f8ded1
index a9c3cdf..c855b22 100644
f8ded1
--- a/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java
f8ded1
+++ b/base/server/cms/src/org/dogtagpki/server/rest/KRAInfoService.java
f8ded1
@@ -59,7 +59,7 @@ public class KRAInfoService extends PKIService implements KRAInfoResource {
f8ded1
         info.setArchivalMechanism(getArchivalMechanism());
f8ded1
         info.setRecoveryMechanism(getRecoveryMechanism());
f8ded1
         info.setEncryptAlgorithm(getEncryptAlgorithm());
f8ded1
-        info.setArchivalMechanism(getWrapAlgorithm());
f8ded1
+        info.setWrapAlgorithm(getWrapAlgorithm());
f8ded1
 
f8ded1
         return createOKResponse(info);
f8ded1
     }
f8ded1
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
f8ded1
index 84e4a65..eca8ddd 100644
f8ded1
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
f8ded1
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
f8ded1
@@ -2713,6 +2713,10 @@ public class CryptoUtil {
f8ded1
         throw new NoSuchAlgorithmException();
f8ded1
     }
f8ded1
 
f8ded1
+    public static final OBJECT_IDENTIFIER KW_AES_KEY_WRAP_PAD = new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.8");
f8ded1
+    public static final OBJECT_IDENTIFIER KW_AES_CBC_PAD = new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.2");
f8ded1
+    public static final OBJECT_IDENTIFIER KW_DES_CBC_PAD = new OBJECT_IDENTIFIER("1.2.840.113549.3.7");
f8ded1
+
f8ded1
     /*
f8ded1
      * Useful method to map KeyWrap algorithms to an OID.
f8ded1
      * This is not yet defined within JSS, although it will be valuable to do
f8ded1
@@ -2724,13 +2728,29 @@ public class CryptoUtil {
f8ded1
      * the subsequent reverse mapping method below.
f8ded1
      */
f8ded1
     public static OBJECT_IDENTIFIER getOID(KeyWrapAlgorithm kwAlg) throws NoSuchAlgorithmException {
f8ded1
-        if (kwAlg == KeyWrapAlgorithm.AES_KEY_WRAP_PAD)
f8ded1
-            return new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.8");
f8ded1
-        if (kwAlg == KeyWrapAlgorithm.AES_CBC_PAD)
f8ded1
-            return new OBJECT_IDENTIFIER("2.16.840.1.101.3.4.1.2");
f8ded1
-        if ((kwAlg == KeyWrapAlgorithm.DES3_CBC_PAD) ||
f8ded1
-            (kwAlg == KeyWrapAlgorithm.DES_CBC_PAD))
f8ded1
-            return new OBJECT_IDENTIFIER("1.2.840.113549.3.7");
f8ded1
+        String name = kwAlg.toString();
f8ded1
+        if (name.equals(KeyWrapAlgorithm.AES_KEY_WRAP_PAD.toString()))
f8ded1
+            return KW_AES_KEY_WRAP_PAD;
f8ded1
+        if (name.equals(KeyWrapAlgorithm.AES_CBC_PAD.toString()))
f8ded1
+            return KW_AES_CBC_PAD;
f8ded1
+        if (name.equals(KeyWrapAlgorithm.DES3_CBC_PAD.toString()))
f8ded1
+            return KW_DES_CBC_PAD;
f8ded1
+        if (name.equals(KeyWrapAlgorithm.DES_CBC_PAD.toString()))
f8ded1
+            return KW_DES_CBC_PAD;
f8ded1
+
f8ded1
+        throw new NoSuchAlgorithmException();
f8ded1
+    }
f8ded1
+
f8ded1
+    public static KeyWrapAlgorithm getKeyWrapAlgorithmFromOID(String wrapOID) throws NoSuchAlgorithmException {
f8ded1
+        OBJECT_IDENTIFIER oid = new OBJECT_IDENTIFIER(wrapOID);
f8ded1
+        if (oid.equals(KW_AES_KEY_WRAP_PAD))
f8ded1
+            return KeyWrapAlgorithm.AES_KEY_WRAP_PAD;
f8ded1
+
f8ded1
+        if (oid.equals(KW_AES_CBC_PAD))
f8ded1
+            return KeyWrapAlgorithm.AES_CBC_PAD;
f8ded1
+
f8ded1
+        if (oid.equals(KW_DES_CBC_PAD))
f8ded1
+            return KeyWrapAlgorithm.DES3_CBC_PAD;
f8ded1
 
f8ded1
         throw new NoSuchAlgorithmException();
f8ded1
     }
f8ded1
diff --git a/base/util/src/netscape/security/util/WrappingParams.java b/base/util/src/netscape/security/util/WrappingParams.java
f8ded1
index 8fe5df6..cda8870 100644
f8ded1
--- a/base/util/src/netscape/security/util/WrappingParams.java
f8ded1
+++ b/base/util/src/netscape/security/util/WrappingParams.java
f8ded1
@@ -10,6 +10,8 @@ import org.mozilla.jss.crypto.KeyWrapAlgorithm;
f8ded1
 import org.mozilla.jss.crypto.SymmetricKey;
f8ded1
 import org.mozilla.jss.crypto.SymmetricKey.Type;
f8ded1
 
f8ded1
+import com.netscape.cmsutil.crypto.CryptoUtil;
f8ded1
+
f8ded1
 public class WrappingParams {
f8ded1
     // session key attributes
f8ded1
     SymmetricKey.Type skType;
f8ded1
@@ -123,6 +125,59 @@ public class WrappingParams {
f8ded1
         }
f8ded1
     }
f8ded1
 
f8ded1
+    private WrappingParams(String wrapOID, String priKeyAlgo, IVParameterSpec wrapIV)
f8ded1
+            throws NumberFormatException, NoSuchAlgorithmException {
f8ded1
+        KeyWrapAlgorithm kwAlg = CryptoUtil.getKeyWrapAlgorithmFromOID(wrapOID);
f8ded1
+
f8ded1
+        if (kwAlg == KeyWrapAlgorithm.AES_KEY_WRAP_PAD) {
f8ded1
+            skType = SymmetricKey.AES;
f8ded1
+            skKeyGenAlgorithm = KeyGenAlgorithm.AES;
f8ded1
+            payloadWrapAlgorithm = KeyWrapAlgorithm.AES_KEY_WRAP_PAD;
f8ded1
+            payloadEncryptionAlgorithm = EncryptionAlgorithm.AES_128_CBC_PAD;
f8ded1
+            skLength = 128;
f8ded1
+        }
f8ded1
+
f8ded1
+        if (kwAlg == KeyWrapAlgorithm.AES_CBC_PAD) {
f8ded1
+            skType = SymmetricKey.AES;
f8ded1
+            skKeyGenAlgorithm = KeyGenAlgorithm.AES;
f8ded1
+            payloadWrapAlgorithm = KeyWrapAlgorithm.AES_CBC_PAD;
f8ded1
+            payloadEncryptionAlgorithm = EncryptionAlgorithm.AES_128_CBC_PAD;
f8ded1
+            skLength = 128;
f8ded1
+        }
f8ded1
+
f8ded1
+        if (kwAlg == KeyWrapAlgorithm.DES3_CBC_PAD || kwAlg == KeyWrapAlgorithm.DES_CBC_PAD) {
f8ded1
+            skType = SymmetricKey.DES;
f8ded1
+            skKeyGenAlgorithm = KeyGenAlgorithm.DES;
f8ded1
+            skWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD;
f8ded1
+            payloadWrapAlgorithm = KeyWrapAlgorithm.DES3_CBC_PAD;
f8ded1
+            payloadEncryptionAlgorithm = EncryptionAlgorithm.DES3_CBC_PAD;
f8ded1
+            skLength = 0;
f8ded1
+        }
f8ded1
+
f8ded1
+        if (priKeyAlgo.equals("EC")) {
f8ded1
+            skWrapAlgorithm = KeyWrapAlgorithm.AES_ECB;
f8ded1
+        } else {
f8ded1
+            skWrapAlgorithm = KeyWrapAlgorithm.RSA;
f8ded1
+        }
f8ded1
+
f8ded1
+        // set the IVs
f8ded1
+        payloadEncryptionIV = wrapIV;
f8ded1
+
f8ded1
+        if (payloadWrapAlgorithm == KeyWrapAlgorithm.AES_KEY_WRAP_PAD) {
f8ded1
+            // TODO(alee) Hack -- if we pass in null for the iv in the
f8ded1
+            // PKIArchiveOptions, we fail to decode correctly when parsing a
f8ded1
+            // CRMFPopClient request.
f8ded1
+            payloadWrappingIV = null;
f8ded1
+        } else {
f8ded1
+            payloadWrappingIV = wrapIV;
f8ded1
+        }
f8ded1
+    }
f8ded1
+
f8ded1
+    public static WrappingParams getWrappingParamsFromArchiveOptions(String wrapOID, String priKeyAlgo, IVParameterSpec wrapIV)
f8ded1
+            throws NumberFormatException, NoSuchAlgorithmException {
f8ded1
+        return new WrappingParams(wrapOID, priKeyAlgo, wrapIV);
f8ded1
+    }
f8ded1
+
f8ded1
     public SymmetricKey.Type getSkType() {
f8ded1
         return skType;
f8ded1
     }
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From 5bf30f2f6a52b7164ba31ab12ed2317b2c572610 Mon Sep 17 00:00:00 2001
f8ded1
From: Ade Lee <alee@redhat.com>
f8ded1
Date: Thu, 8 Jun 2017 16:08:30 -0400
f8ded1
Subject: [PATCH 10/14] Stop using hardcoded IV in CMC
f8ded1
f8ded1
Bugzilla #BZ 1458055
f8ded1
f8ded1
Change-Id: I229d7f18c46f0b55ec83f051614de1b59e125b82
f8ded1
---
f8ded1
 base/java-tools/src/com/netscape/cmstools/CMCRequest.java   | 13 ++++++++-----
f8ded1
 .../src/com/netscape/cms/profile/common/EnrollProfile.java  | 13 ++++++-------
f8ded1
 .../com/netscape/cms/servlet/common/CMCOutputTemplate.java  |  8 +++-----
f8ded1
 3 files changed, 17 insertions(+), 17 deletions(-)
f8ded1
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
f8ded1
index 8d49b20..4adf22b 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
f8ded1
@@ -40,6 +40,7 @@ import java.util.StringTokenizer;
f8ded1
 import org.mozilla.jss.CryptoManager;
f8ded1
 import org.mozilla.jss.asn1.ANY;
f8ded1
 import org.mozilla.jss.asn1.ASN1Util;
f8ded1
+import org.mozilla.jss.asn1.ASN1Value;
f8ded1
 import org.mozilla.jss.asn1.BIT_STRING;
f8ded1
 import org.mozilla.jss.asn1.ENUMERATED;
f8ded1
 import org.mozilla.jss.asn1.GeneralizedTime;
f8ded1
@@ -1708,6 +1709,12 @@ public class CMCRequest {
f8ded1
         try {
f8ded1
             TaggedRequest request = encryptedPop.getRequest();
f8ded1
             AlgorithmIdentifier thePOPAlgID = encryptedPop.getThePOPAlgID();
f8ded1
+
f8ded1
+            ASN1Value v = thePOPAlgID.getParameters();
f8ded1
+            v = ((ANY) v).decodeWith(new OCTET_STRING.Template());
f8ded1
+            byte iv[] = ((OCTET_STRING) v).toByteArray();
f8ded1
+            IVParameterSpec ivps = new IVParameterSpec(iv);
f8ded1
+
f8ded1
             AlgorithmIdentifier witnessAlgID = encryptedPop.getWitnessAlgID();
f8ded1
             OCTET_STRING witness = encryptedPop.getWitness();
f8ded1
             ContentInfo cms = encryptedPop.getContentInfo();
f8ded1
@@ -1734,13 +1741,9 @@ public class CMCRequest {
f8ded1
             }
f8ded1
             System.out.println(method + "symKey unwrapped.");
f8ded1
 
f8ded1
-            // TODO(alee) The code below should be replaced by code that generates a random IV
f8ded1
-            byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
f8ded1
-            IVParameterSpec default_iv = new IVParameterSpec(iv);
f8ded1
-
f8ded1
             byte challenge[] = CryptoUtil.decryptUsingSymmetricKey(
f8ded1
                     token,
f8ded1
-                    default_iv,
f8ded1
+                    ivps,
f8ded1
                     encCI.getEncryptedContent().toByteArray(),
f8ded1
                     symKey,
f8ded1
                     EncryptionAlgorithm.AES_128_CBC);
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
f8ded1
index 12fb736..2591ace 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
f8ded1
@@ -403,8 +403,7 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
                 String tokenName = CMS.getConfigStore().getString("cmc.token", CryptoUtil.INTERNAL_TOKEN_NAME);
f8ded1
                 token = CryptoUtil.getCryptoToken(tokenName);
f8ded1
 
f8ded1
-                // TODO(alee) Replace the IV definition with a call that generates a random IV of  the correct length
f8ded1
-                byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
f8ded1
+                byte[] iv = CryptoUtil.getNonceData(EncryptionAlgorithm.AES_128_CBC.getIVLength());
f8ded1
                 IVParameterSpec ivps = new IVParameterSpec(iv);
f8ded1
 
f8ded1
                 PublicKey userPubKey = X509Key.parsePublicKey(new DerValue(req_key_data));
f8ded1
@@ -466,6 +465,8 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
 
f8ded1
                 req.setExtData("pop_userPubEncryptedSession", pop_userPubEncryptedSession);
f8ded1
 
f8ded1
+                req.setExtData("pop_encryptedDataIV", iv);
f8ded1
+
f8ded1
                 // now compute and set witness
f8ded1
                 CMS.debug(method + "now compute and set witness");
f8ded1
                 String hashName = CryptoUtil.getDefaultHashAlgName();
f8ded1
@@ -1123,14 +1124,12 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
                 return null;
f8ded1
             }
f8ded1
 
f8ded1
-            // TODO(alee) The code below should be replaced by code that gets the IV from the Pop request
f8ded1
-            // This IV is supposed to be random
f8ded1
-            byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
f8ded1
-            IVParameterSpec default_iv = new IVParameterSpec(iv);
f8ded1
+            byte[] iv = req.getExtDataInByteArray("pop_encryptedDataIV");
f8ded1
+            IVParameterSpec ivps = new IVParameterSpec(iv);
f8ded1
 
f8ded1
             byte[] challenge_b = CryptoUtil.decryptUsingSymmetricKey(
f8ded1
                     token,
f8ded1
-                    default_iv,
f8ded1
+                    ivps,
f8ded1
                     pop_encryptedData,
f8ded1
                     symKey,
f8ded1
                     EncryptionAlgorithm.AES_128_CBC);
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
f8ded1
index 8e47298..8d6c37f 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
f8ded1
@@ -491,6 +491,7 @@ public class CMCOutputTemplate {
f8ded1
         //don't need this for encryptedPOP, but need to check for existence anyway
f8ded1
         byte[] pop_sysPubEncryptedSession = req.getExtDataInByteArray("pop_sysPubEncryptedSession");
f8ded1
         byte[] pop_userPubEncryptedSession = req.getExtDataInByteArray("pop_userPubEncryptedSession");
f8ded1
+        byte[] iv = req.getExtDataInByteArray("pop_encryptedDataIV");
f8ded1
         if ((pop_encryptedData != null) &&
f8ded1
                 (pop_sysPubEncryptedSession != null) &&
f8ded1
                 (pop_userPubEncryptedSession != null)) {
f8ded1
@@ -517,11 +518,8 @@ public class CMCOutputTemplate {
f8ded1
                     throw new EBaseException(method + msg);
f8ded1
                 }
f8ded1
 
f8ded1
-                // TODO(alee) The code below should be replaced by code that generates a random IV
f8ded1
-                byte[] default_iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
f8ded1
-
f8ded1
                 OBJECT_IDENTIFIER oid = EncryptionAlgorithm.AES_128_CBC.toOID();
f8ded1
-                AlgorithmIdentifier aid = new AlgorithmIdentifier(oid, new OCTET_STRING(default_iv));
f8ded1
+                AlgorithmIdentifier aid = new AlgorithmIdentifier(oid, new OCTET_STRING(iv));
f8ded1
 
f8ded1
                 encPop = new EncryptedPOP(
f8ded1
                         tReq,
f8ded1
@@ -532,7 +530,7 @@ public class CMCOutputTemplate {
f8ded1
 
f8ded1
             } catch (Exception e) {
f8ded1
                 CMS.debug(method + " excepton:" + e);
f8ded1
-                throw new EBaseException(method + " excepton:" + e);
f8ded1
+                throw new EBaseException(method + " exception:" + e);
f8ded1
             }
f8ded1
 
f8ded1
         } else {
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From 698192f4f62c55142a557f6489ed2323e17401b0 Mon Sep 17 00:00:00 2001
f8ded1
From: Christina Fu <cfu@redhat.com>
f8ded1
Date: Tue, 30 May 2017 14:12:06 -0700
f8ded1
Subject: [PATCH 11/14] Ticket #2619 Allow CA to process user-signed CMC
f8ded1
 revocation requests
f8ded1
f8ded1
First of all, the original CMC revocation only supports agent-signed CMC revocation requests from the UI where CMCRevReqServlet handles it with CMCAuth.  It is in violation with https://tools.ietf.org/html/rfc5273 CMC Transport Protocols, as for HTTP/HTTPS, the body of the message is the binary value of the BER encoding of the PKI Request or Response,so HTML is not an approved method.The other way is through profileSubmitCMCFullServlet (or maybe not, as it was completely broken).
f8ded1
f8ded1
One thing that's much less crucial, but goes along with rfc update is the name of the revocation request ASN1 structure. In the new rfc5272, it is now called RevokeRequest insead of RevRequest.
f8ded1
f8ded1
This patch revamped the CMC revocation provision and fixing what's broken and adding what's missing.
f8ded1
f8ded1
On the client side:
f8ded1
f8ded1
CMCRequest
f8ded1
f8ded1
- Commented out the code where it made an assumption to use OtherMsg for the signer information. This makes no sense as the outer layer SignedData would have the same information when signing happens.
f8ded1
f8ded1
- removed the revRequest.nickname parameter from the configuration.  From the code it seems like it expects the certificate to be revoked to exist in the user database, and it uses the same certificate to sign the revocation request.  The RFC does allow for self-signed revocation, but it also allows for signing with another certificate provided that it has same subject.  By removing the revRequest.nickname parameter, I am using the "nickname" parameter as the signer cert, which may or may not be the same certificate specified in revRequest.serial.  It is less confusing. The change also eliminate the need for the cert to be revoked to be present in the db.  In addition, revRequest.issuer only needs to be specified if revRequest.sharedSecret is used. The code will extract the issuer info from the signing cert.
f8ded1
f8ded1
- added support for unsigned data in support of shared secret in both CMCRequest and server;  The original code assumed that a cmc revocation request that relies on shared secret still requires agent signing.
f8ded1
f8ded1
CMCRevoke
f8ded1
f8ded1
- The original code assumed that the nss db password is the same as Shared Secret (!!).  This patch added a "-t" to accept shred secret, and keep the -p for the nss db password.
f8ded1
f8ded1
- The original code printed out b64 encoded request to the screen output as well as the file CMCRevoke.out.  Both are unusable directly.  This patch fixes it so that the output to the screen can be directly copied and pasted into the CMC revocate ui at ee (processed by CMCRevReqServlet);  Again, this is not RFC conforming, but I fixed it anyways;
f8ded1
f8ded1
- The output to the file CMCRevoke.out has been fixed so that it is the BER encoding of the request, which can be fed directly into the updated server that now conforms to the RFC (see below)
f8ded1
f8ded1
- This code still requires the signer certificate nickname to run, making the shared secret method moot.  Since CMCRequest has been updated to work properly, we can leave this for now.
f8ded1
f8ded1
On the server side.
f8ded1
f8ded1
CMCUserSignedAuth has been updated to handle unsigned DATA;  Recall that the original CMC revocation only handled SIGNED_DATA (making assumption that agent always signs the requests).  This addition is important to support shared secrets properly.
f8ded1
f8ded1
Another thing that's important change on the server side is that it now checks the revoking cert's subject against the signer's subject, if authenticated by CMCUserSignedAuth.  The original code did not do that, I think it is because it always checks if it's an agent or not.
f8ded1
f8ded1
Something that could be improved on is to have its own servlet.  However, due to the time restriction, I only updated existing EnrollProfile, ProfileSubmitCMCServlet, and CMCOutputTemplate to handle the rfc conforming cmc revocation requests.
f8ded1
f8ded1
The shared secret handling is left in the CMCOutputTemplate for now.  Logically it would make sense to go into CMCUserSignedAuth. This could be left as a possible later ticket for improvement.   Shared Token plugin implementation will be added in later ticket as well.
f8ded1
f8ded1
Previously missed signing cert validation is also added for more complete check.
f8ded1
Some SHA1 are turned into SHA2
f8ded1
f8ded1
Finally, some auditing are added, but it is not finalized.  It will be done in the next ticket(s).
f8ded1
---
f8ded1
 base/common/src/com/netscape/certsrv/apps/CMS.java |  10 +
f8ded1
 .../src/com/netscape/certsrv/apps/ICMSEngine.java  |   8 +
f8ded1
 .../com/netscape/certsrv/base/SessionContext.java  |   5 +
f8ded1
 .../src/com/netscape/cmstools/CMCRequest.java      | 251 ++++++++-----
f8ded1
 .../src/com/netscape/cmstools/CMCRevoke.java       | 133 +++----
f8ded1
 .../com/netscape/cms/authentication/CMCAuth.java   |  19 +-
f8ded1
 .../cms/authentication/CMCUserSignedAuth.java      | 198 +++++-----
f8ded1
 .../netscape/cms/profile/common/EnrollProfile.java |  80 ++--
f8ded1
 .../cms/servlet/cert/CMCRevReqServlet.java         |   4 +-
f8ded1
 .../com/netscape/cms/servlet/cert/ListCerts.java   |  10 +-
f8ded1
 .../cms/servlet/common/CMCOutputTemplate.java      | 407 +++++++++++++++------
f8ded1
 .../servlet/common/GenPendingTemplateFiller.java   |  15 +-
f8ded1
 .../servlet/profile/ProfileSubmitCMCServlet.java   |  12 +-
f8ded1
 .../src/com/netscape/cmscore/apps/CMSEngine.java   |  33 ++
f8ded1
 .../netscape/cmscore/app/CMSEngineDefaultStub.java |   5 +
f8ded1
 base/util/src/com/netscape/cmsutil/util/Utils.java |   5 +
f8ded1
 16 files changed, 769 insertions(+), 426 deletions(-)
f8ded1
f8ded1
diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java
f8ded1
index cc634cc..9df99ab 100644
f8ded1
--- a/base/common/src/com/netscape/certsrv/apps/CMS.java
f8ded1
+++ b/base/common/src/com/netscape/certsrv/apps/CMS.java
f8ded1
@@ -36,6 +36,7 @@ import org.dogtagpki.legacy.policy.ISubjAltNameConfig;
f8ded1
 import org.mozilla.jss.CryptoManager.CertificateUsage;
f8ded1
 import org.mozilla.jss.util.PasswordCallback;
f8ded1
 
f8ded1
+import com.netscape.certsrv.authentication.ISharedToken;
f8ded1
 import com.netscape.certsrv.acls.EACLsException;
f8ded1
 import com.netscape.certsrv.acls.IACL;
f8ded1
 import com.netscape.certsrv.authentication.IAuthSubsystem;
f8ded1
@@ -1575,6 +1576,15 @@ public final class CMS {
f8ded1
     }
f8ded1
 
f8ded1
     /**
f8ded1
+     * Retrieves the SharedToken class.
f8ded1
+     *
f8ded1
+     * @return named SharedToken class
f8ded1
+     */
f8ded1
+    public static ISharedToken getSharedTokenClass(String configName) {
f8ded1
+        return _engine.getSharedTokenClass(configName);
f8ded1
+    }
f8ded1
+
f8ded1
+    /**
f8ded1
      * Puts a password entry into the single-sign on cache.
f8ded1
      *
f8ded1
      * @param tag password tag
f8ded1
diff --git a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
f8ded1
index 3655b03..563b7c9 100644
f8ded1
--- a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
f8ded1
+++ b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
f8ded1
@@ -38,6 +38,7 @@ import org.mozilla.jss.util.PasswordCallback;
f8ded1
 
f8ded1
 import com.netscape.certsrv.acls.EACLsException;
f8ded1
 import com.netscape.certsrv.acls.IACL;
f8ded1
+import com.netscape.certsrv.authentication.ISharedToken;
f8ded1
 import com.netscape.certsrv.authority.IAuthority;
f8ded1
 import com.netscape.certsrv.base.EBaseException;
f8ded1
 import com.netscape.certsrv.base.IArgBlock;
f8ded1
@@ -681,6 +682,13 @@ public interface ICMSEngine extends ISubsystem {
f8ded1
     public ILdapConnFactory getLdapAnonConnFactory(String id) throws ELdapException;
f8ded1
 
f8ded1
     /**
f8ded1
+     * Retrieves the named SharedToken class
f8ded1
+     *
f8ded1
+     * @return named shared token class
f8ded1
+     */
f8ded1
+    public ISharedToken getSharedTokenClass(String configName);
f8ded1
+
f8ded1
+    /**
f8ded1
      * Retrieves the password check.
f8ded1
      *
f8ded1
      * @return default password checker
f8ded1
diff --git a/base/common/src/com/netscape/certsrv/base/SessionContext.java b/base/common/src/com/netscape/certsrv/base/SessionContext.java
f8ded1
index 81debae..8bcb3c1 100644
f8ded1
--- a/base/common/src/com/netscape/certsrv/base/SessionContext.java
f8ded1
+++ b/base/common/src/com/netscape/certsrv/base/SessionContext.java
f8ded1
@@ -53,6 +53,11 @@ public class SessionContext extends Hashtable<Object, Object> {
f8ded1
     public static final String AUTH_MANAGER_ID = "authManagerId"; // String
f8ded1
 
f8ded1
     /**
f8ded1
+     * Principal name object of the signed CMC request
f8ded1
+     */
f8ded1
+    public static final String CMC_SIGNER_PRINCIPAL = "cmcSignerPrincipal";
f8ded1
+
f8ded1
+    /**
f8ded1
      * User object of the authenticated user in the current thread.
f8ded1
      */
f8ded1
     public static final String USER = "user"; // IUser
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
f8ded1
index 4adf22b..00e03a7 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
f8ded1
@@ -72,15 +72,14 @@ import org.mozilla.jss.pkix.cmc.GetCert;
f8ded1
 import org.mozilla.jss.pkix.cmc.IdentityProofV2;
f8ded1
 import org.mozilla.jss.pkix.cmc.LraPopWitness;
f8ded1
 import org.mozilla.jss.pkix.cmc.OtherInfo;
f8ded1
-import org.mozilla.jss.pkix.cmc.OtherMsg;
f8ded1
 import org.mozilla.jss.pkix.cmc.PKIData;
f8ded1
 import org.mozilla.jss.pkix.cmc.PendInfo;
f8ded1
 import org.mozilla.jss.pkix.cmc.PopLinkWitnessV2;
f8ded1
 import org.mozilla.jss.pkix.cmc.ResponseBody;
f8ded1
+import org.mozilla.jss.pkix.cmc.RevokeRequest;
f8ded1
 import org.mozilla.jss.pkix.cmc.TaggedAttribute;
f8ded1
 import org.mozilla.jss.pkix.cmc.TaggedCertificationRequest;
f8ded1
 import org.mozilla.jss.pkix.cmc.TaggedRequest;
f8ded1
-import org.mozilla.jss.pkix.cmmf.RevRequest;
f8ded1
 import org.mozilla.jss.pkix.cms.ContentInfo;
f8ded1
 import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
f8ded1
 import org.mozilla.jss.pkix.cms.EncryptedContentInfo;
f8ded1
@@ -374,14 +373,30 @@ public class CMCRequest {
f8ded1
 
f8ded1
     /**
f8ded1
      * getCMCBlob create and return the enrollment request.
f8ded1
-     *
f8ded1
+     * It now handles two types of data input:
f8ded1
+     *  - SignedData (which is for signed data)
f8ded1
+     *  - data (which is for unsigned data)
f8ded1
      * @return the CMC enrollment request encoded in base64
f8ded1
      *
f8ded1
      */
f8ded1
-    static ContentInfo getCMCBlob(SignedData req) {
f8ded1
+    static ContentInfo getCMCBlob(SignedData signedData, byte[] data) {
f8ded1
         String method = "getCMCBlob: ";
f8ded1
         System.out.println(method + "begins");
f8ded1
-        ContentInfo fullEnrollmentReq = new ContentInfo(req);
f8ded1
+        ContentInfo fullEnrollmentReq = null;
f8ded1
+        if (signedData != null && data == null) {
f8ded1
+            System.out.println("getCMCBlob: generating signed data");
f8ded1
+            fullEnrollmentReq = new ContentInfo(signedData);
f8ded1
+        } else if (data != null && signedData == null) {
f8ded1
+            System.out.println("getCMCBlob: generating unsigned data");
f8ded1
+            fullEnrollmentReq = new ContentInfo(data);
f8ded1
+        } else if (signedData == null && data == null) {
f8ded1
+             System.out.println("getCMCBlob: both params are null");
f8ded1
+             System.exit(1);
f8ded1
+        } else {
f8ded1
+             System.out.println("getCMCBlob: both params are not null; only one of them can be used, the other must be null");
f8ded1
+             System.exit(1);
f8ded1
+        }
f8ded1
+
f8ded1
         try {
f8ded1
             ByteArrayOutputStream bs = new ByteArrayOutputStream();
f8ded1
             PrintStream ps = new PrintStream(bs);
f8ded1
@@ -768,29 +783,32 @@ public class CMCRequest {
f8ded1
         System.out.println("");
f8ded1
         System.out.println("#input: full path for the PKCS10 request or CRMF request,");
f8ded1
         System.out.println("#the content must be in Base-64 encoded format");
f8ded1
-        System.out.println("#Multiple files are supported. They must be separated by space.");
f8ded1
+//        System.out.println("#Multiple files are supported. They must be separated by space.");
f8ded1
+        System.out.println("# in case of revocation, input will be ignored");
f8ded1
         System.out.println("input=crmf.req");
f8ded1
         System.out.println("");
f8ded1
         System.out.println("#output: full path for the CMC request in binary format");
f8ded1
         System.out.println("output=cmc.req");
f8ded1
         System.out.println("");
f8ded1
-        System.out.println("#tokenname: name of token where agent signing cert can be found (default is internal)");
f8ded1
+        System.out.println("#tokenname: name of token where user signing cert can be found (default is internal)");
f8ded1
         System.out.println("tokenname=internal");
f8ded1
         System.out.println("");
f8ded1
-        System.out.println("#nickname: nickname for agent certificate which will be used");
f8ded1
-        System.out.println("#to sign the CMC full request.");
f8ded1
+        System.out.println("#nickname: nickname for user certificate which will be used");
f8ded1
+        System.out.println("#to sign the CMC full request (enrollment or revocation).");
f8ded1
+        System.out.println("");
f8ded1
         System.out.println("#selfSign: if selfSign is true, the CMC request will be");
f8ded1
-        System.out.println("#signed with the pairing private key of the request;");
f8ded1
+        System.out.println("#signed with the pairing private key of the enrollment request;");
f8ded1
         System.out.println("#and in which case the nickname will be ignored");
f8ded1
-        System.out.println("nickname=CMS Agent Certificate");
f8ded1
+        System.out.println("#If revRequest.sharedSecret is specified, then nickname will also be ignored.");
f8ded1
+        System.out.println("nickname=CMS User Signing Certificate");
f8ded1
         System.out.println("");
f8ded1
         System.out.println("selfSign=false");
f8ded1
         System.out.println("");
f8ded1
         System.out.println("#dbdir: directory for cert8.db, key3.db and secmod.db");
f8ded1
         System.out.println("dbdir=./");
f8ded1
         System.out.println("");
f8ded1
-        System.out.println("#password: password for cert8.db which stores the agent");
f8ded1
-        System.out.println("#certificate");
f8ded1
+        System.out.println("#password: password for cert8.db which stores the user signing");
f8ded1
+        System.out.println("#certificate and keys");
f8ded1
         System.out.println("password=pass");
f8ded1
         System.out.println("");
f8ded1
         System.out.println("#format: request format, either pkcs10 or crmf");
f8ded1
@@ -844,13 +862,19 @@ public class CMCRequest {
f8ded1
         System.out.println("#control. Otherwise, false.");
f8ded1
         System.out.println("revRequest.enable=false");
f8ded1
         System.out.println("");
f8ded1
+/*
f8ded1
         System.out.println("#revRequest.nickname: The nickname for the revoke certificate");
f8ded1
         System.out.println("revRequest.nickname=newuser's 102504a ID");
f8ded1
         System.out.println("");
f8ded1
+*/
f8ded1
         System.out.println("#revRequest.issuer: The issuer name for the certificate being");
f8ded1
-        System.out.println("#revoked.");
f8ded1
+        System.out.println("#revoked. It only needs to be specified when the request is unsigned,;");
f8ded1
+        System.out.println("#as in the case when sharedSecret is used;");
f8ded1
         System.out.println("revRequest.issuer=cn=Certificate Manager,c=us");
f8ded1
         System.out.println("");
f8ded1
+        System.out.println("#revRequest.sharedSecret: The sharedSecret");
f8ded1
+        System.out.println("revRequest.sharedSecret=");
f8ded1
+        System.out.println("");
f8ded1
         System.out.println("#revRequest.serial: The serial number for the certificate being");
f8ded1
         System.out.println("#revoked.");
f8ded1
         System.out.println("revRequest.serial=61");
f8ded1
@@ -861,9 +885,6 @@ public class CMCRequest {
f8ded1
         System.out.println("#                   certificateHold, removeFromCRL");
f8ded1
         System.out.println("revRequest.reason=unspecified");
f8ded1
         System.out.println("");
f8ded1
-        System.out.println("#revRequest.sharedSecret: The sharedSecret");
f8ded1
-        System.out.println("revRequest.sharedSecret=");
f8ded1
-        System.out.println("");
f8ded1
         System.out.println("#revRequest.comment: The human readable comment");
f8ded1
         System.out.println("revRequest.comment=");
f8ded1
         System.out.println("");
f8ded1
@@ -972,27 +993,27 @@ public class CMCRequest {
f8ded1
 
f8ded1
     private static ENUMERATED toCRLReason(String str) {
f8ded1
         if (str.equalsIgnoreCase("unspecified")) {
f8ded1
-            return RevRequest.unspecified;
f8ded1
+            return RevokeRequest.unspecified;
f8ded1
         } else if (str.equalsIgnoreCase("keyCompromise")) {
f8ded1
-            return RevRequest.keyCompromise;
f8ded1
+            return RevokeRequest.keyCompromise;
f8ded1
         } else if (str.equalsIgnoreCase("caCompromise")) {
f8ded1
-            return RevRequest.cACompromise;
f8ded1
+            return RevokeRequest.cACompromise;
f8ded1
         } else if (str.equalsIgnoreCase("affiliationChanged")) {
f8ded1
-            return RevRequest.affiliationChanged;
f8ded1
+            return RevokeRequest.affiliationChanged;
f8ded1
         } else if (str.equalsIgnoreCase("superseded")) {
f8ded1
-            return RevRequest.superseded;
f8ded1
+            return RevokeRequest.superseded;
f8ded1
         } else if (str.equalsIgnoreCase("cessationOfOperation")) {
f8ded1
-            return RevRequest.cessationOfOperation;
f8ded1
+            return RevokeRequest.cessationOfOperation;
f8ded1
         } else if (str.equalsIgnoreCase("certificateHold")) {
f8ded1
-            return RevRequest.certificateHold;
f8ded1
+            return RevokeRequest.certificateHold;
f8ded1
         } else if (str.equalsIgnoreCase("removeFromCRL")) {
f8ded1
-            return RevRequest.removeFromCRL;
f8ded1
+            return RevokeRequest.removeFromCRL;
f8ded1
         }
f8ded1
 
f8ded1
         System.out.println("Unrecognized CRL reason");
f8ded1
         System.exit(1);
f8ded1
 
f8ded1
-        return RevRequest.unspecified;
f8ded1
+        return RevokeRequest.unspecified;
f8ded1
     }
f8ded1
 
f8ded1
     /**
f8ded1
@@ -1119,42 +1140,84 @@ public class CMCRequest {
f8ded1
         return bpid;
f8ded1
     }
f8ded1
 
f8ded1
-    private static int addRevRequestAttr(int bpid, SEQUENCE seq, SEQUENCE otherMsgSeq, CryptoToken token, String tokenName, String nickname,
f8ded1
+    /*
f8ded1
+    * addRevRequestAttr adds the RevokeRequest control
f8ded1
+    * If sharedSecret exist, issuer name needs to be supplied;
f8ded1
+    * else signing cert is needed to extract issuerName
f8ded1
+    */
f8ded1
+    private static int addRevRequestAttr(int bpid, SEQUENCE seq,
f8ded1
+            CryptoToken token, X509Certificate revokeSignCert,
f8ded1
             String revRequestIssuer, String revRequestSerial, String revRequestReason,
f8ded1
             String revRequestSharedSecret, String revRequestComment, String invalidityDatePresent,
f8ded1
             CryptoManager manager) {
f8ded1
+
f8ded1
+        String method = "addRevRequestAttr: ";
f8ded1
         try {
f8ded1
-            if (nickname.length() <= 0) {
f8ded1
-                System.out.println("The nickname for the certificate being revoked is null");
f8ded1
-                System.exit(1);
f8ded1
-            }
f8ded1
-            String nickname1 = nickname;
f8ded1
             UTF8String comment = null;
f8ded1
             OCTET_STRING sharedSecret = null;
f8ded1
             GeneralizedTime d = null;
f8ded1
-            X500Name subjectname = new X500Name(revRequestIssuer);
f8ded1
+            X500Name issuerName = null;
f8ded1
+
f8ded1
+            if ((revRequestSerial == null) || (revRequestSerial.length() <= 0)) {
f8ded1
+                System.out.println(method + "revocation serial number must be supplied");
f8ded1
+                System.exit(1);
f8ded1
+            }
f8ded1
+            if ((revRequestReason == null) || (revRequestReason.length() <= 0)) {
f8ded1
+                System.out.println(method + "revocation reason must be supplied");
f8ded1
+                System.exit(1);
f8ded1
+            }
f8ded1
             INTEGER snumber = new INTEGER(revRequestSerial);
f8ded1
             ENUMERATED reason = toCRLReason(revRequestReason);
f8ded1
-            if (revRequestSharedSecret.length() > 0)
f8ded1
+
f8ded1
+            if ((revRequestSharedSecret != null) && (revRequestSharedSecret.length() > 0)) {
f8ded1
                 sharedSecret = new OCTET_STRING(revRequestSharedSecret.getBytes());
f8ded1
-            if (revRequestComment.length() > 0)
f8ded1
+                // in case of sharedSecret,
f8ded1
+                // issuer name will have to be provided;
f8ded1
+                // revokeSignCert is ignored;
f8ded1
+                if (revRequestIssuer == null) {
f8ded1
+                    System.out.println(method + "issuer name must be supplied when shared secret is used");
f8ded1
+                    System.exit(1);
f8ded1
+                }
f8ded1
+                issuerName = new X500Name(revRequestIssuer);
f8ded1
+            } else { // signing case; revokeSignCert is required
f8ded1
+                if (revokeSignCert == null) {
f8ded1
+                    System.out.println(method + "revokeSignCert must be supplied in the signing case");
f8ded1
+                    System.exit(1);
f8ded1
+                }
f8ded1
+            }
f8ded1
+
f8ded1
+            if (revRequestComment != null && revRequestComment.length() > 0)
f8ded1
                 comment = new UTF8String(revRequestComment);
f8ded1
             if (invalidityDatePresent.equals("true"))
f8ded1
                 d = new GeneralizedTime(new Date());
f8ded1
-            RevRequest revRequest =
f8ded1
-                    new RevRequest(new ANY(subjectname.getEncoded()), snumber,
f8ded1
-                            reason, d, sharedSecret, comment);
f8ded1
-            int revokeBpid = bpid;
f8ded1
+
f8ded1
+            if (sharedSecret == null) {
f8ded1
+                System.out.println(method + "no sharedSecret found; request will be signed;");
f8ded1
+
f8ded1
+                // getting issuerName from revokeSignCert
f8ded1
+                byte[] certB = revokeSignCert.getEncoded();
f8ded1
+                X509CertImpl impl = new X509CertImpl(certB);
f8ded1
+                issuerName = (X500Name) impl.getIssuerDN();
f8ded1
+            } else {
f8ded1
+                System.out.println(method + "sharedSecret found; request will be unsigned;");
f8ded1
+            }
f8ded1
+
f8ded1
+            RevokeRequest revRequest = new RevokeRequest(new ANY(issuerName.getEncoded()), snumber,
f8ded1
+                    reason, d, sharedSecret, comment);
f8ded1
+
f8ded1
             TaggedAttribute revRequestControl = new TaggedAttribute(
f8ded1
                     new INTEGER(bpid++),
f8ded1
                     OBJECT_IDENTIFIER.id_cmc_revokeRequest, revRequest);
f8ded1
             seq.addElement(revRequestControl);
f8ded1
+            System.out.println(method + "RevokeRequest control created.");
f8ded1
 
f8ded1
-            if (sharedSecret != null) {
f8ded1
-                System.out.println("Successfully create revRequest control. bpid = " + (bpid - 1));
f8ded1
-                System.out.println("");
f8ded1
-                return bpid;
f8ded1
-            }
f8ded1
+            return bpid;
f8ded1
+/*
f8ded1
+ * Constructing OtherMsg to include the SignerInfo makes no sense here
f8ded1
+ * as the outer layer SignedData would have SignerInfo.
f8ded1
+ * It is possibly done because the original code assumed a self-signed
f8ded1
+ * revocation request that is subsequently signed by an agent...
f8ded1
+ * which is not conforming to the RFC.
f8ded1
 
f8ded1
             EncapsulatedContentInfo revokeContent = new EncapsulatedContentInfo(
f8ded1
                     OBJECT_IDENTIFIER.id_cct_PKIData, revRequestControl);
f8ded1
@@ -1241,6 +1304,7 @@ public class CMCRequest {
f8ded1
             otherMsgSeq.addElement(otherMsg);
f8ded1
             System.out.println("Successfully create revRequest control. bpid = " + (bpid - 1));
f8ded1
             System.out.println("");
f8ded1
+*/
f8ded1
         } catch (Exception e) {
f8ded1
             System.out.println("Error in creating revRequest control. Check the parameters. Exception="+ e.toString());
f8ded1
             System.exit(1);
f8ded1
@@ -1346,9 +1410,9 @@ public class CMCRequest {
f8ded1
             String salt = "lala123" + date.toString();
f8ded1
 
f8ded1
             try {
f8ded1
-                MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
f8ded1
+                MessageDigest SHA256Digest = MessageDigest.getInstance("SHA256");
f8ded1
 
f8ded1
-                dig = SHA1Digest.digest(salt.getBytes());
f8ded1
+                dig = SHA256Digest.digest(salt.getBytes());
f8ded1
             } catch (NoSuchAlgorithmException ex) {
f8ded1
                 dig = salt.getBytes();
f8ded1
             }
f8ded1
@@ -1825,7 +1889,6 @@ public class CMCRequest {
f8ded1
         String dataReturnEnable = "false", dataReturnData = null;
f8ded1
         String transactionMgtEnable = "false", transactionMgtId = null;
f8ded1
         String senderNonceEnable = "false", senderNonce = null;
f8ded1
-        String revCertNickname = "";
f8ded1
         String revRequestEnable = "false", revRequestIssuer = null, revRequestSerial = null;
f8ded1
         String revRequestReason = null, revRequestSharedSecret = null, revRequestComment = null;
f8ded1
         String revRequestInvalidityDatePresent = "false";
f8ded1
@@ -1941,8 +2004,6 @@ public class CMCRequest {
f8ded1
                         revRequestComment = val;
f8ded1
                     } else if (name.equals("revRequest.invalidityDatePresent")) {
f8ded1
                         revRequestInvalidityDatePresent = val;
f8ded1
-                    } else if (name.equals("revRequest.nickname")) {
f8ded1
-                        revCertNickname = val;
f8ded1
                     } else if (name.equals("identification.enable")) {
f8ded1
                         identificationEnable = val;
f8ded1
                     } else if (name.equals("identification")) {
f8ded1
@@ -1985,7 +2046,8 @@ public class CMCRequest {
f8ded1
             printUsage();
f8ded1
         }
f8ded1
 
f8ded1
-        if (!selfSign.equals("true") && nickname == null) {
f8ded1
+        if ((!selfSign.equals("true") && (revRequestSharedSecret == null))
f8ded1
+                && nickname == null) {
f8ded1
             System.out.println("Missing nickname.");
f8ded1
             printUsage();
f8ded1
         }
f8ded1
@@ -2031,11 +2093,12 @@ public class CMCRequest {
f8ded1
                 certname.append(tokenName);
f8ded1
                 certname.append(":");
f8ded1
             }
f8ded1
-            if (!selfSign.equals("true") && nickname != null) {
f8ded1
+            if ((!selfSign.equals("true") || (revRequestSharedSecret == null))
f8ded1
+                    && nickname != null) {
f8ded1
                 certname.append(nickname);
f8ded1
                 signerCert = cm.findCertByNickname(certname.toString());
f8ded1
                 if (signerCert != null) {
f8ded1
-                    System.out.println("got signerCert: "+ certname.toString());
f8ded1
+                    System.out.println("got signerCert: " + certname.toString());
f8ded1
                 }
f8ded1
             }
f8ded1
 
f8ded1
@@ -2065,6 +2128,7 @@ public class CMCRequest {
f8ded1
                 }
f8ded1
             }
f8ded1
 
f8ded1
+            boolean isSharedSecretRevoke = false;
f8ded1
             if (decryptedPopEnable.equalsIgnoreCase("true")) {
f8ded1
                 if (encryptedPopResponseFile == null) {
f8ded1
                     System.out.println("ecryptedPop.enable = true, but encryptedPopResponseFile is not specified.");
f8ded1
@@ -2091,7 +2155,7 @@ public class CMCRequest {
f8ded1
                 }
f8ded1
             } else { // !decryptedPopEnable
f8ded1
 
f8ded1
-                if (ifilename == null) {
f8ded1
+                if (!revRequestEnable.equalsIgnoreCase("true") && ifilename == null) {
f8ded1
                     System.out.println("Missing input filename for PKCS10 or CRMF.");
f8ded1
                     printUsage();
f8ded1
                 }
f8ded1
@@ -2109,14 +2173,17 @@ public class CMCRequest {
f8ded1
                     }
f8ded1
                 }
f8ded1
 
f8ded1
-                StringTokenizer tokenizer = new StringTokenizer(ifilename, " ");
f8ded1
-                String[] ifiles = new String[num];
f8ded1
-                for (int i = 0; i < num; i++) {
f8ded1
-                    String ss = tokenizer.nextToken();
f8ded1
-                    ifiles[i] = ss;
f8ded1
-                    if (ss == null) {
f8ded1
-                        System.out.println("Missing input file for the request.");
f8ded1
-                        System.exit(1);
f8ded1
+                String[] ifiles = null;
f8ded1
+                if (revRequestEnable.equalsIgnoreCase("false")) {
f8ded1
+                    StringTokenizer tokenizer = new StringTokenizer(ifilename, " ");
f8ded1
+                    ifiles = new String[num];
f8ded1
+                    for (int i = 0; i < num; i++) {
f8ded1
+                        String ss = tokenizer.nextToken();
f8ded1
+                        ifiles[i] = ss;
f8ded1
+                        if (ss == null) {
f8ded1
+                            System.out.println("Missing input file for the request.");
f8ded1
+                            System.exit(1);
f8ded1
+                        }
f8ded1
                     }
f8ded1
                 }
f8ded1
 
f8ded1
@@ -2126,11 +2193,12 @@ public class CMCRequest {
f8ded1
                 }
f8ded1
 
f8ded1
                 if (format == null) {
f8ded1
-                    System.out.println("Missing format.");
f8ded1
-                    printUsage();
f8ded1
+                    System.out.println("Missing format..assume revocation");
f8ded1
+                    //printUsage();
f8ded1
                 }
f8ded1
+
f8ded1
                 String[] requests = new String[num];
f8ded1
-                for (int i = 0; i < num; i++) {
f8ded1
+                for (int i = 0; i < num && revRequestEnable.equalsIgnoreCase("false") ; i++) {
f8ded1
                     BufferedReader inputBlob = null;
f8ded1
                     try {
f8ded1
                         inputBlob = new BufferedReader(new InputStreamReader(
f8ded1
@@ -2222,20 +2290,20 @@ public class CMCRequest {
f8ded1
 
f8ded1
                 SEQUENCE otherMsgSeq = new SEQUENCE();
f8ded1
                 if (revRequestEnable.equalsIgnoreCase("true")) {
f8ded1
-                    if (revRequestIssuer.length() == 0 || revRequestSerial.length() == 0 ||
f8ded1
-                            revRequestReason.length() == 0) {
f8ded1
-                        System.out.println("Illegal parameters for revRequest control");
f8ded1
-                        printUsage();
f8ded1
-                        System.exit(1);
f8ded1
+                    if ((revRequestSharedSecret!= null)
f8ded1
+                             && (revRequestSharedSecret.length() > 0)) {
f8ded1
+                        isSharedSecretRevoke = true;
f8ded1
+                        //this will result in unsigned data
f8ded1
                     }
f8ded1
 
f8ded1
-                    bpid = addRevRequestAttr(bpid, controlSeq, otherMsgSeq, token, tokenName, revCertNickname,
f8ded1
+                    bpid = addRevRequestAttr(bpid, controlSeq, token, signerCert,
f8ded1
                             revRequestIssuer, revRequestSerial, revRequestReason, revRequestSharedSecret,
f8ded1
                             revRequestComment, revRequestInvalidityDatePresent, cm);
f8ded1
-                }
f8ded1
+                    pkidata = new PKIData(controlSeq, new SEQUENCE(), new SEQUENCE(), new SEQUENCE());
f8ded1
+                } else {
f8ded1
 
f8ded1
-                // create the request PKIData
f8ded1
-                pkidata = createPKIData(
f8ded1
+                    // create the request PKIData
f8ded1
+                    pkidata = createPKIData(
f8ded1
                         selfSign,
f8ded1
                         requests,
f8ded1
                         format, transactionMgtEnable, transactionMgtId,
f8ded1
@@ -2248,6 +2316,7 @@ public class CMCRequest {
f8ded1
                         popLinkWitnessV2keyGenAlg, popLinkWitnessV2macAlg,
f8ded1
                         controlSeq, otherMsgSeq, bpid,
f8ded1
                         token, privk);
f8ded1
+                }
f8ded1
 
f8ded1
                 if (pkidata == null) {
f8ded1
                     System.out.println("pkidata null after createPKIData(). Exiting with error");
f8ded1
@@ -2255,22 +2324,30 @@ public class CMCRequest {
f8ded1
                 }
f8ded1
             }
f8ded1
 
f8ded1
-            // sign the request
f8ded1
-            SignedData signedData = null;
f8ded1
-            if (selfSign.equalsIgnoreCase("true")) {
f8ded1
-                // selfSign signs with private key
f8ded1
-                System.out.println("selfSign is true...");
f8ded1
-                signedData = signData(privk, pkidata);
f8ded1
+            if (isSharedSecretRevoke) {
f8ded1
+                cmcblob = getCMCBlob(null,
f8ded1
+                        ASN1Util.encode(pkidata));
f8ded1
             } else {
f8ded1
-                // none selfSign signs with  existing cert
f8ded1
-                System.out.println("selfSign is false...");
f8ded1
-                signedData = signData(signerCert, tokenName, nickname, cm, pkidata);
f8ded1
-            }
f8ded1
-            if (signedData == null) {
f8ded1
-                System.out.println("signData() returns null. Exiting with error");
f8ded1
-                System.exit(1);
f8ded1
+
f8ded1
+                SignedData signedData = null;
f8ded1
+
f8ded1
+                // sign the request
f8ded1
+                if (selfSign.equalsIgnoreCase("true")) {
f8ded1
+                    // selfSign signs with private key
f8ded1
+                    System.out.println("selfSign is true...");
f8ded1
+                    signedData = signData(privk, pkidata);
f8ded1
+                } else {
f8ded1
+                    // none selfSign signs with  existing cert
f8ded1
+                    System.out.println("selfSign is false...");
f8ded1
+                    signedData = signData(signerCert, tokenName, nickname, cm, pkidata);
f8ded1
+                }
f8ded1
+                if (signedData == null) {
f8ded1
+                    System.out.println("signData() returns null. Exiting with error");
f8ded1
+                    System.exit(1);
f8ded1
+                }
f8ded1
+                cmcblob = getCMCBlob(signedData, null);
f8ded1
             }
f8ded1
-            cmcblob = getCMCBlob(signedData);
f8ded1
+
f8ded1
             if (cmcblob == null) {
f8ded1
                 System.out.println("getCMCBlob() returns null. Exiting with error");
f8ded1
                 System.exit(1);
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java b/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java
f8ded1
index c2572e6..e46e883 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRevoke.java
f8ded1
@@ -75,6 +75,7 @@ public class CMCRevoke {
f8ded1
     public static final String RFC7468_TRAILER = "-----END CERTIFICATE REQUEST-----";
f8ded1
     static String dValue = null, nValue = null, iValue = null, sValue = null, mValue = null, hValue = null,
f8ded1
             pValue = null, cValue = null;
f8ded1
+    static String tValue = null;
f8ded1
 
f8ded1
     public static final String CMS_BASE_CA_SIGNINGCERT_NOT_FOUND = "CA signing certificate not found";
f8ded1
     public static final String PR_REQUEST_CMC = "CMC";
f8ded1
@@ -109,8 +110,9 @@ public class CMCRevoke {
f8ded1
                     "-d<dir to cert8.db, key3.db> " +
f8ded1
                     "-n<nickname> " +
f8ded1
                     "-i<issuerName> " +
f8ded1
-                    "-s<serialName> " +
f8ded1
+                    "-s<serialNumber> " +
f8ded1
                     "-m<reason to revoke> " +
f8ded1
+                    "-t<shared secret> " +
f8ded1
                     "-p<password to db> " +
f8ded1
                     "-h<tokenname> " +
f8ded1
                     "-c<comment> ");
f8ded1
@@ -135,6 +137,8 @@ public class CMCRevoke {
f8ded1
                     mValue = cleanArgs(s[i].substring(2));
f8ded1
                 } else if (s[i].startsWith("-p")) {
f8ded1
                     pValue = cleanArgs(s[i].substring(2));
f8ded1
+                } else if (s[i].startsWith("-t")) {
f8ded1
+                    tValue = cleanArgs(s[i].substring(2));
f8ded1
                 } else if (s[i].startsWith("-h")) {
f8ded1
                     hValue = cleanArgs(s[i].substring(2));
f8ded1
                 } else if (s[i].startsWith("-c")) {
f8ded1
@@ -143,8 +147,6 @@ public class CMCRevoke {
f8ded1
 
f8ded1
             }
f8ded1
             // optional parameters
f8ded1
-            if (cValue == null)
f8ded1
-                cValue = "";
f8ded1
             if (hValue == null)
f8ded1
                 hValue = "";
f8ded1
 
f8ded1
@@ -160,7 +162,7 @@ public class CMCRevoke {
f8ded1
                         "-d<dir to cert8.db, key3.db> " +
f8ded1
                         "-n<nickname> " +
f8ded1
                         "-i<issuerName> " +
f8ded1
-                        "-s<serialName> " +
f8ded1
+                        "-s<serialNumber> " +
f8ded1
                         "-m<reason to revoke> " +
f8ded1
                         "-p<password to db> " +
f8ded1
                         "-h<tokenname> " +
f8ded1
@@ -191,9 +193,9 @@ public class CMCRevoke {
f8ded1
 
f8ded1
                 token.login(pass);
f8ded1
                 X509Certificate signerCert = getCertificate(cm, hValue, nValue);
f8ded1
-                String outBlob = createRevokeReq(hValue, signerCert, cm);
f8ded1
+                ContentInfo fullEnrollmentRequest = createRevokeReq(hValue, signerCert, cm);
f8ded1
 
f8ded1
-                printCMCRevokeRequest(outBlob);
f8ded1
+                printCMCRevokeRequest(fullEnrollmentRequest);
f8ded1
             } catch (Exception e) {
f8ded1
                 e.printStackTrace();
f8ded1
                 System.exit(1);
f8ded1
@@ -209,29 +211,48 @@ public class CMCRevoke {
f8ded1
      *
f8ded1
      * @param asciiBASE64Blob the ascii string of the request
f8ded1
      */
f8ded1
-    static void printCMCRevokeRequest(String asciiBASE64Blob) {
f8ded1
+    static void printCMCRevokeRequest(ContentInfo fullEnrollmentReq) {
f8ded1
+        String method = "printCMCRevokeRequest: ";
f8ded1
 
f8ded1
-        // (6) Finally, print the actual CMCSigning blob to the
f8ded1
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
f8ded1
+        ByteArrayOutputStream bs = new ByteArrayOutputStream();
f8ded1
+        PrintStream ps = new PrintStream(bs);
f8ded1
+
f8ded1
+        if (fullEnrollmentReq == null) {
f8ded1
+            System.out.println(method + "param fullEnrollmentRequest is null");
f8ded1
+            System.exit(1);
f8ded1
+        }
f8ded1
+        // format is PR_REQUEST_CMC
f8ded1
+        try {
f8ded1
+            fullEnrollmentReq.encode(os);
f8ded1
+        } catch (IOException e) {
f8ded1
+            System.out.println("CMCSigning:  I/O error " +
f8ded1
+                    "encountered during write():\n" +
f8ded1
+                    e);
f8ded1
+            System.exit(1);
f8ded1
+        }
f8ded1
+        //ps.print(Utils.base64encode(os.toByteArray()));
f8ded1
+        // no line breaks for ease of copy/paste for CA acceptance
f8ded1
+        System.out.println(RFC7468_HEADER);
f8ded1
+        ps.print(Utils.base64encodeSingleLine(os.toByteArray()));
f8ded1
+        ////fullEnrollmentReq.print(ps); // no header/trailer
f8ded1
+
f8ded1
+        String asciiBASE64Blob = bs.toString();
f8ded1
+        System.out.println(asciiBASE64Blob + "\n" + RFC7468_TRAILER);
f8ded1
+
f8ded1
+        // (6) Finally, print the actual CMCSigning binary blob to the
f8ded1
         //     specified output file
f8ded1
         FileOutputStream outputBlob = null;
f8ded1
 
f8ded1
         try {
f8ded1
             outputBlob = new FileOutputStream("CMCRevoke.out");
f8ded1
+            fullEnrollmentReq.encode(outputBlob);
f8ded1
         } catch (IOException e) {
f8ded1
             System.out.println("CMCSigning:  unable to open file CMCRevoke.out for writing:\n" + e);
f8ded1
             return;
f8ded1
         }
f8ded1
 
f8ded1
-        System.out.println(RFC7468_HEADER);
f8ded1
-        System.out.println(asciiBASE64Blob + RFC7468_TRAILER);
f8ded1
-        try {
f8ded1
-            asciiBASE64Blob = RFC7468_HEADER + "\n" + asciiBASE64Blob + RFC7468_TRAILER;
f8ded1
-            outputBlob.write(asciiBASE64Blob.getBytes());
f8ded1
-        } catch (IOException e) {
f8ded1
-            System.out.println("CMCSigning:  I/O error " +
f8ded1
-                    "encountered during write():\n" +
f8ded1
-                    e);
f8ded1
-        }
f8ded1
+        System.out.println("\nCMC revocation binary blob written to CMCRevoke.out\n");
f8ded1
 
f8ded1
         try {
f8ded1
             outputBlob.close();
f8ded1
@@ -280,12 +301,11 @@ public class CMCRevoke {
f8ded1
      * @param manager the crypto manger.
f8ded1
      * @return the CMC revocation request encoded in base64
f8ded1
      */
f8ded1
-    static String createRevokeReq(String tokenname, X509Certificate signerCert, CryptoManager manager) {
f8ded1
+    static ContentInfo createRevokeReq(String tokenname, X509Certificate signerCert, CryptoManager manager) {
f8ded1
 
f8ded1
         java.security.PrivateKey privKey = null;
f8ded1
         SignerIdentifier si = null;
f8ded1
         ContentInfo fullEnrollmentReq = null;
f8ded1
-        String asciiBASE64Blob = null;
f8ded1
 
f8ded1
         try {
f8ded1
 
f8ded1
@@ -305,8 +325,8 @@ public class CMCRevoke {
f8ded1
 
f8ded1
             if (privKey == null) {
f8ded1
                 System.out.println("CMCRevoke::createRevokeReq() - " +
f8ded1
-                                    "privKey is null!");
f8ded1
-                return "";
f8ded1
+                        "privKey is null!");
f8ded1
+                return null;
f8ded1
             }
f8ded1
 
f8ded1
             int bpid = 1;
f8ded1
@@ -319,65 +339,64 @@ public class CMCRevoke {
f8ded1
             byte[] dig;
f8ded1
 
f8ded1
             try {
f8ded1
-                MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
f8ded1
+                MessageDigest SHA2Digest = MessageDigest.getInstance("SHA256");
f8ded1
 
f8ded1
-                dig = SHA1Digest.digest(salt.getBytes());
f8ded1
+                dig = SHA2Digest.digest(salt.getBytes());
f8ded1
             } catch (NoSuchAlgorithmException ex) {
f8ded1
                 dig = salt.getBytes();
f8ded1
             }
f8ded1
             String sn = Utils.base64encode(dig);
f8ded1
 
f8ded1
-            TaggedAttribute senderNonce =
f8ded1
-                    new TaggedAttribute(new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_senderNonce,
f8ded1
-                            new OCTET_STRING(sn.getBytes()));
f8ded1
+            TaggedAttribute senderNonce = new TaggedAttribute(new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_senderNonce,
f8ded1
+                    new OCTET_STRING(sn.getBytes()));
f8ded1
 
f8ded1
             controlSeq.addElement(senderNonce);
f8ded1
 
f8ded1
             Name subjectName = new Name();
f8ded1
 
f8ded1
             subjectName.addCommonName(iValue);
f8ded1
-            org.mozilla.jss.pkix.cmmf.RevRequest lRevokeRequest =
f8ded1
-                    new org.mozilla.jss.pkix.cmmf.RevRequest(new ANY((new X500Name(iValue)).getEncoded()),
f8ded1
-                            new INTEGER(sValue),
f8ded1
-                            //org.mozilla.jss.pkix.cmmf.RevRequest.unspecified,
f8ded1
-                            new ENUMERATED((new Integer(mValue)).longValue()),
f8ded1
-                            null,
f8ded1
-                            new OCTET_STRING(pValue.getBytes()),
f8ded1
-                            new UTF8String(cValue.toCharArray()));
f8ded1
+            org.mozilla.jss.pkix.cmc.RevokeRequest lRevokeRequest = new org.mozilla.jss.pkix.cmc.RevokeRequest(
f8ded1
+                    new ANY((new X500Name(iValue)).getEncoded()),
f8ded1
+                    new INTEGER(sValue),
f8ded1
+                    //org.mozilla.jss.pkix.cmc.RevokeRequest.unspecified,
f8ded1
+                    new ENUMERATED((new Integer(mValue)).longValue()),
f8ded1
+                    null,
f8ded1
+                    (tValue != null) ? new OCTET_STRING(tValue.getBytes()) : null,
f8ded1
+                    (cValue != null) ? new UTF8String(cValue.toCharArray()) : null);
f8ded1
             //byte[] encoded = ASN1Util.encode(lRevokeRequest);
f8ded1
-            //org.mozilla.jss.asn1.ASN1Template template = new  org.mozilla.jss.pkix.cmmf.RevRequest.Template();
f8ded1
-            //org.mozilla.jss.pkix.cmmf.RevRequest revRequest = (org.mozilla.jss.pkix.cmmf.RevRequest)
f8ded1
+            //org.mozilla.jss.asn1.ASN1Template template = new  org.mozilla.jss.pkix.cmc.RevokeRequest.Template();
f8ded1
+            //org.mozilla.jss.pkix.cmc.RevokeRequest revRequest = (org.mozilla.jss.pkix.cmc.RevokeRequest)
f8ded1
             //                                                               template.decode(new java.io.ByteArrayInputStream(
f8ded1
             //                                                               encoded));
f8ded1
 
f8ded1
-            ByteArrayOutputStream os = new ByteArrayOutputStream();
f8ded1
-            //lRevokeRequest.encode(os); // khai
f8ded1
-            TaggedAttribute revokeRequestTag =
f8ded1
-                    new TaggedAttribute(new INTEGER(bpid++), OBJECT_IDENTIFIER.id_cmc_revokeRequest,
f8ded1
-                            lRevokeRequest);
f8ded1
+            TaggedAttribute revokeRequestTag = new TaggedAttribute(new INTEGER(bpid++),
f8ded1
+                    OBJECT_IDENTIFIER.id_cmc_revokeRequest,
f8ded1
+                    lRevokeRequest);
f8ded1
 
f8ded1
             controlSeq.addElement(revokeRequestTag);
f8ded1
             PKIData pkidata = new PKIData(controlSeq, new SEQUENCE(), new SEQUENCE(), new SEQUENCE());
f8ded1
 
f8ded1
             EncapsulatedContentInfo ci = new EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData, pkidata);
f8ded1
-            // SHA1 is the default digest Alg for now.
f8ded1
             DigestAlgorithm digestAlg = null;
f8ded1
             SignatureAlgorithm signAlg = null;
f8ded1
-            org.mozilla.jss.crypto.PrivateKey.Type signingKeyType = ((org.mozilla.jss.crypto.PrivateKey) privKey).getType();
f8ded1
+            org.mozilla.jss.crypto.PrivateKey.Type signingKeyType = ((org.mozilla.jss.crypto.PrivateKey) privKey)
f8ded1
+                    .getType();
f8ded1
             if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.RSA)) {
f8ded1
-                signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
f8ded1
+                signAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest;
f8ded1
             } else if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.EC)) {
f8ded1
-                signAlg = SignatureAlgorithm.ECSignatureWithSHA1Digest;
f8ded1
-            } else if (signingKeyType.equals(org.mozilla.jss.crypto.PrivateKey.Type.DSA)) {
f8ded1
-                signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
f8ded1
+                signAlg = SignatureAlgorithm.ECSignatureWithSHA256Digest;
f8ded1
+            } else {
f8ded1
+                System.out.println("Algorithm not supported:" +
f8ded1
+                        signingKeyType);
f8ded1
+                return null;
f8ded1
             }
f8ded1
 
f8ded1
             MessageDigest SHADigest = null;
f8ded1
             byte[] digest = null;
f8ded1
 
f8ded1
             try {
f8ded1
-                SHADigest = MessageDigest.getInstance("SHA1");
f8ded1
-                digestAlg = DigestAlgorithm.SHA1;
f8ded1
+                SHADigest = MessageDigest.getInstance("SHA256");
f8ded1
+                digestAlg = DigestAlgorithm.SHA256;
f8ded1
 
f8ded1
                 ByteArrayOutputStream ostream = new ByteArrayOutputStream();
f8ded1
 
f8ded1
@@ -411,21 +430,11 @@ public class CMCRevoke {
f8ded1
 
f8ded1
             fullEnrollmentReq = new ContentInfo(req);
f8ded1
 
f8ded1
-            ByteArrayOutputStream bs = new ByteArrayOutputStream();
f8ded1
-            PrintStream ps = new PrintStream(bs);
f8ded1
-
f8ded1
-            if (fullEnrollmentReq != null) {
f8ded1
-                // format is PR_REQUEST_CMC
f8ded1
-                fullEnrollmentReq.encode(os);
f8ded1
-                ps.print(Utils.base64encode(os.toByteArray()));
f8ded1
-                ////fullEnrollmentReq.print(ps); // no header/trailer
f8ded1
-            }
f8ded1
-
f8ded1
-            asciiBASE64Blob = bs.toString();
f8ded1
         } catch (Exception e) {
f8ded1
             e.printStackTrace();
f8ded1
             System.exit(1);
f8ded1
         }
f8ded1
-        return asciiBASE64Blob;
f8ded1
+
f8ded1
+        return fullEnrollmentReq;
f8ded1
     }
f8ded1
 }
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java b/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java
f8ded1
index b898353..9441167 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java
f8ded1
@@ -237,6 +237,9 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
      */
f8ded1
     public IAuthToken authenticate(IAuthCredentials authCred) throws EMissingCredential, EInvalidCredentials,
f8ded1
             EBaseException {
f8ded1
+        String method = "CMCAuth: authenticate: ";
f8ded1
+        String msg = "";
f8ded1
+
f8ded1
         String auditMessage = null;
f8ded1
         String auditSubjectID = auditSubjectID();
f8ded1
         String auditReqType = ILogger.UNIDENTIFIED;
f8ded1
@@ -261,7 +264,7 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
             }
f8ded1
             String cmc = (String) returnVal;
f8ded1
             if (cmc == null) {
f8ded1
-                CMS.debug("CMCAuth: Authentication failed. Missing CMC.");
f8ded1
+                CMS.debug(method + "Authentication failed. Missing CMC.");
f8ded1
 
f8ded1
                 // store a message in the signed audit log file
f8ded1
                 auditMessage = CMS.getLogMessage(
f8ded1
@@ -279,8 +282,9 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
             }
f8ded1
 
f8ded1
             if (cmc.equals("")) {
f8ded1
-                log(ILogger.LL_FAILURE,
f8ded1
-                        "cmc : attempted login with empty CMC.");
f8ded1
+                msg = "attempted login with empty CMC";
f8ded1
+                CMS.debug(method + msg);
f8ded1
+                log(ILogger.LL_FAILURE, method + msg);
f8ded1
 
f8ded1
                 // store a message in the signed audit log file
f8ded1
                 auditMessage = CMS.getLogMessage(
f8ded1
@@ -331,6 +335,7 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                 if (!cmcReq.getContentType().equals(
f8ded1
                         org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA) ||
f8ded1
                         !cmcReq.hasContent()) {
f8ded1
+                    CMS.debug(method + "malformed cmc: either not ContentInfo.SIGNED_DATA or cmcReq has no content");
f8ded1
                     // store a message in the signed audit log file
f8ded1
                     auditMessage = CMS.getLogMessage(
f8ded1
                             AuditEvent.CMC_SIGNED_REQUEST_SIG_VERIFY,
f8ded1
@@ -358,13 +363,13 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                 if (checkSignerInfo) {
f8ded1
                     IAuthToken agentToken = verifySignerInfo(authToken, cmcFullReq);
f8ded1
                     if (agentToken == null) {
f8ded1
-                        CMS.debug("CMCAuth: authenticate() agentToken null");
f8ded1
+                        CMS.debug(method + "agentToken null");
f8ded1
                         throw new EBaseException("CMCAuth: agent verifySignerInfo failure");
f8ded1
                     }
f8ded1
                     userid = agentToken.getInString("userid");
f8ded1
                     uid = agentToken.getInString("cn");
f8ded1
                 } else {
f8ded1
-                    CMS.debug("CMCAuth: authenticate() signerInfo verification bypassed");
f8ded1
+                    CMS.debug(method + "signerInfo verification bypassed");
f8ded1
                 }
f8ded1
                 // reset value of auditSignerInfo
f8ded1
                 if (uid != null) {
f8ded1
@@ -377,6 +382,8 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
 
f8ded1
                 if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) ||
f8ded1
                         !ci.hasContent()) {
f8ded1
+                    msg = "request EncapsulatedContentInfo content type not OBJECT_IDENTIFIER.id_cct_PKIData";
f8ded1
+                    CMS.debug( method + msg);
f8ded1
                     // store a message in the signed audit log file
f8ded1
                     auditMessage = CMS.getLogMessage(
f8ded1
                             AuditEvent.CMC_SIGNED_REQUEST_SIG_VERIFY,
f8ded1
@@ -406,6 +413,7 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
 
f8ded1
                 if (numReqs == 0) {
f8ded1
                     // revocation request
f8ded1
+                    CMS.debug(method + "numReqs 0, assume revocation request");
f8ded1
 
f8ded1
                     // reset value of auditReqType
f8ded1
                     auditReqType = SIGNED_AUDIT_REVOCATION_REQUEST_TYPE;
f8ded1
@@ -476,6 +484,7 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                     }
f8ded1
                 } else {
f8ded1
                     // enrollment request
f8ded1
+                    CMS.debug(method + "numReqs not 0, assume enrollment request");
f8ded1
 
f8ded1
                     // reset value of auditReqType
f8ded1
                     auditReqType = SIGNED_AUDIT_ENROLLMENT_REQUEST_TYPE;
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
f8ded1
index a18c25e..2e4d6dc 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
f8ded1
@@ -29,9 +29,9 @@ import java.io.ByteArrayInputStream;
f8ded1
 import java.io.ByteArrayOutputStream;
f8ded1
 import java.io.IOException;
f8ded1
 import java.math.BigInteger;
f8ded1
-import java.security.cert.CertificateExpiredException;
f8ded1
 import java.security.MessageDigest;
f8ded1
 import java.security.PublicKey;
f8ded1
+import java.security.cert.CertificateExpiredException;
f8ded1
 import java.util.Enumeration;
f8ded1
 import java.util.Hashtable;
f8ded1
 import java.util.Locale;
f8ded1
@@ -323,85 +323,90 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                 byte[] cmcBlob = CMS.AtoB(asciiBASE64Blob);
f8ded1
                 ByteArrayInputStream cmcBlobIn = new ByteArrayInputStream(cmcBlob);
f8ded1
 
f8ded1
-                org.mozilla.jss.pkix.cms.ContentInfo cmcReq =
f8ded1
-                        (org.mozilla.jss.pkix.cms.ContentInfo) org.mozilla.jss.pkix.cms.ContentInfo
f8ded1
+                org.mozilla.jss.pkix.cms.ContentInfo cmcReq = (org.mozilla.jss.pkix.cms.ContentInfo) org.mozilla.jss.pkix.cms.ContentInfo
f8ded1
                         .getTemplate().decode(
f8ded1
                                 cmcBlobIn);
f8ded1
 
f8ded1
-                if (!cmcReq.getContentType().equals(
f8ded1
-                        org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA) ||
f8ded1
-                        !cmcReq.hasContent()) {
f8ded1
-
f8ded1
-                    cmcBlobIn.close();
f8ded1
-                    msg = "cmc rquest content type is not ContentInfo.SIGNED_DATA";
f8ded1
-                    CMS.debug(msg);
f8ded1
-                    throw new EBaseException(msg);
f8ded1
-                }
f8ded1
-
f8ded1
-                SignedData cmcFullReq = (SignedData) cmcReq.getInterpretedContent();
f8ded1
-
f8ded1
                 String userid = ILogger.UNIDENTIFIED;
f8ded1
                 String uid = ILogger.UNIDENTIFIED;
f8ded1
 
f8ded1
-                IConfigStore cmc_config = CMS.getConfigStore();
f8ded1
-                boolean checkSignerInfo = cmc_config.getBoolean("cmc.signerInfo.verify", true);
f8ded1
-                if (checkSignerInfo) {
f8ded1
-                    // selfSigned will be set in verifySignerInfo if applicable
f8ded1
-                    IAuthToken userToken = verifySignerInfo(auditContext, authToken, cmcFullReq);
f8ded1
-                    if (userToken == null) {
f8ded1
-                        msg = "userToken null; verifySignerInfo failure";
f8ded1
-                        CMS.debug(method + msg);
f8ded1
-                        throw new EBaseException(msg);
f8ded1
-                    } else {
f8ded1
-                        if (selfSigned) {
f8ded1
-                            CMS.debug(method
f8ded1
-                                    + " self-signed cmc request will not have user identification info at this point.");
f8ded1
-                            auditSignerInfo = "selfSigned";
f8ded1
+                SignedData cmcFullReq = null;
f8ded1
+                OCTET_STRING content = null;
f8ded1
+                OBJECT_IDENTIFIER id = null;
f8ded1
+                org.mozilla.jss.pkix.cms.SignerInfo selfsign_signerInfo = null;
f8ded1
+                if (cmcReq.getContentType().equals(
f8ded1
+                        org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA)) {
f8ded1
+                    CMS.debug(method + "cmc request content is signed data");
f8ded1
+                    cmcFullReq = (SignedData) cmcReq.getInterpretedContent();
f8ded1
+
f8ded1
+                    IConfigStore cmc_config = CMS.getConfigStore();
f8ded1
+                    boolean checkSignerInfo = cmc_config.getBoolean("cmc.signerInfo.verify", true);
f8ded1
+                    if (checkSignerInfo) {
f8ded1
+                        // selfSigned will be set in verifySignerInfo if applicable
f8ded1
+                        IAuthToken userToken = verifySignerInfo(auditContext, authToken, cmcFullReq);
f8ded1
+                        if (userToken == null) {
f8ded1
+                            msg = "userToken null; verifySignerInfo failure";
f8ded1
+                            CMS.debug(method + msg);
f8ded1
+                            throw new EBaseException(msg);
f8ded1
                         } else {
f8ded1
-                            CMS.debug(method + "signed with user cert");
f8ded1
-                            userid = userToken.getInString("userid");
f8ded1
-                            uid = userToken.getInString("cn");
f8ded1
-                            if (userid == null && uid == null) {
f8ded1
-                                msg = " verifySignerInfo failure... missing userid and cn";
f8ded1
-                                CMS.debug(method + msg);
f8ded1
-                                throw new EBaseException(msg);
f8ded1
-                            }
f8ded1
-                            // reset value of auditSignerInfo
f8ded1
-                            if (uid != null && !uid.equals(ILogger.UNIDENTIFIED)) {
f8ded1
-                                CMS.debug(method + "setting auditSignerInfo to uid:" + uid.trim());
f8ded1
-                                auditSignerInfo = uid.trim();
f8ded1
-                                auditSubjectID = uid.trim();
f8ded1
-                                authToken.set(IAuthToken.USER_ID, auditSubjectID);
f8ded1
-                            } else if (userid != null && !userid.equals(ILogger.UNIDENTIFIED)) {
f8ded1
-                                CMS.debug(method + "setting auditSignerInfo to userid:" + userid);
f8ded1
-                                auditSignerInfo = userid.trim();
f8ded1
-                                auditSubjectID = userid.trim();
f8ded1
-                                authToken.set(IAuthToken.USER_ID, auditSubjectID);
f8ded1
+                            if (selfSigned) {
f8ded1
+                                CMS.debug(method
f8ded1
+                                        + " self-signed cmc request will not have user identification info at this point.");
f8ded1
+                                auditSignerInfo = "selfSigned";
f8ded1
+                            } else {
f8ded1
+                                CMS.debug(method + "signed with user cert");
f8ded1
+                                userid = userToken.getInString("userid");
f8ded1
+                                uid = userToken.getInString("cn");
f8ded1
+                                if (userid == null && uid == null) {
f8ded1
+                                    msg = " verifySignerInfo failure... missing userid and cn";
f8ded1
+                                    CMS.debug(method + msg);
f8ded1
+                                    throw new EBaseException(msg);
f8ded1
+                                }
f8ded1
+                                // reset value of auditSignerInfo
f8ded1
+                                if (uid != null && !uid.equals(ILogger.UNIDENTIFIED)) {
f8ded1
+                                    CMS.debug(method + "setting auditSignerInfo to uid:" + uid.trim());
f8ded1
+                                    auditSignerInfo = uid.trim();
f8ded1
+                                    auditSubjectID = uid.trim();
f8ded1
+                                    authToken.set(IAuthToken.USER_ID, auditSubjectID);
f8ded1
+                                } else if (userid != null && !userid.equals(ILogger.UNIDENTIFIED)) {
f8ded1
+                                    CMS.debug(method + "setting auditSignerInfo to userid:" + userid);
f8ded1
+                                    auditSignerInfo = userid.trim();
f8ded1
+                                    auditSubjectID = userid.trim();
f8ded1
+                                    authToken.set(IAuthToken.USER_ID, auditSubjectID);
f8ded1
+                                }
f8ded1
                             }
f8ded1
                         }
f8ded1
+                    } else {
f8ded1
+                        CMS.debug(method + " signerInfo verification bypassed");
f8ded1
                     }
f8ded1
-                } else {
f8ded1
-                    CMS.debug(method + " signerInfo verification bypassed");
f8ded1
-                }
f8ded1
 
f8ded1
-                EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
f8ded1
-                SET sis = cmcFullReq.getSignerInfos();
f8ded1
-                // only one SignerInfo for selfSigned
f8ded1
-                org.mozilla.jss.pkix.cms.SignerInfo selfsign_signerInfo =
f8ded1
-                        (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(0);
f8ded1
+                    EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
f8ded1
+                    SET sis = cmcFullReq.getSignerInfos();
f8ded1
+                    // only one SignerInfo for selfSigned
f8ded1
+                    selfsign_signerInfo = (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(0);
f8ded1
 
f8ded1
-                OBJECT_IDENTIFIER id = ci.getContentType();
f8ded1
+                    id = ci.getContentType();
f8ded1
 
f8ded1
-                if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) ||
f8ded1
-                        !ci.hasContent()) {
f8ded1
-                    msg = "request EncapsulatedContentInfo content type not OBJECT_IDENTIFIER.id_cct_PKIData";
f8ded1
-                    CMS.debug(method + msg);
f8ded1
+                    if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) ||
f8ded1
+                            !ci.hasContent()) {
f8ded1
+                        msg = "request EncapsulatedContentInfo content type not OBJECT_IDENTIFIER.id_cct_PKIData";
f8ded1
+                        CMS.debug(method + msg);
f8ded1
+
f8ded1
+                        throw new EBaseException(msg);
f8ded1
+                    }
f8ded1
 
f8ded1
+                    content = ci.getContent();
f8ded1
+                } else if (cmcReq.getContentType().equals( //unsigned
f8ded1
+                        org.mozilla.jss.pkix.cms.ContentInfo.DATA)) {
f8ded1
+                    CMS.debug(method + "cmc request content is unsigned data...verifySignerInfo will not be called;");
f8ded1
+                    content = (OCTET_STRING) cmcReq.getInterpretedContent();
f8ded1
+                } else {
f8ded1
+                    cmcBlobIn.close();
f8ded1
+                    msg = "unsupported cmc rquest content type; must be either ContentInfo.SIGNED_DATA or ContentInfo.DATA;";
f8ded1
+                    CMS.debug(msg);
f8ded1
                     throw new EBaseException(msg);
f8ded1
                 }
f8ded1
 
f8ded1
-                OCTET_STRING content = ci.getContent();
f8ded1
-
f8ded1
                 ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
f8ded1
                 PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
f8ded1
 
f8ded1
@@ -426,7 +431,8 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
 
f8ded1
                             if (type.equals(
f8ded1
                                     OBJECT_IDENTIFIER.id_cmc_revokeRequest)) {
f8ded1
-                                /* TODO: user-signed revocation to be handled in next ticket
f8ded1
+                                //further checks and actual revocation happen in CMCOutputTemplate
f8ded1
+
f8ded1
                                 // if( i ==1 ) {
f8ded1
                                 //     taggedAttribute.getType() ==
f8ded1
                                 //       OBJECT_IDENTIFIER.id_cmc_revokeRequest
f8ded1
@@ -440,25 +446,23 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                                 for (int j = 0; j < numVals; j++) {
f8ded1
                                     // serialNumber    INTEGER
f8ded1
 
f8ded1
-                                    // SEQUENCE RevRequest = (SEQUENCE)
f8ded1
+                                    // SEQUENCE RevokeRequest = (SEQUENCE)
f8ded1
                                     //     values.elementAt(j);
f8ded1
                                     byte[] encoded = ASN1Util.encode(
f8ded1
                                             values.elementAt(j));
f8ded1
-                                    org.mozilla.jss.asn1.ASN1Template template = new
f8ded1
-                                            org.mozilla.jss.pkix.cmmf.RevRequest.Template();
f8ded1
-                                    org.mozilla.jss.pkix.cmmf.RevRequest revRequest =
f8ded1
-                                            (org.mozilla.jss.pkix.cmmf.RevRequest)
f8ded1
-                                            ASN1Util.decode(template, encoded);
f8ded1
+                                    org.mozilla.jss.asn1.ASN1Template template = new org.mozilla.jss.pkix.cmc.RevokeRequest.Template();
f8ded1
+                                    org.mozilla.jss.pkix.cmc.RevokeRequest revRequest = (org.mozilla.jss.pkix.cmc.RevokeRequest) ASN1Util
f8ded1
+                                            .decode(template, encoded);
f8ded1
 
f8ded1
-                                    // SEQUENCE RevRequest = (SEQUENCE)
f8ded1
+                                    // SEQUENCE RevokeRequest = (SEQUENCE)
f8ded1
                                     //     ASN1Util.decode(
f8ded1
                                     //         SEQUENCE.getTemplate(),
f8ded1
                                     //         ASN1Util.encode(
f8ded1
                                     //         values.elementAt(j)));
f8ded1
 
f8ded1
-                                    // SEQUENCE RevRequest =
f8ded1
+                                    // SEQUENCE RevokeRequest =
f8ded1
                                     //     values.elementAt(j);
f8ded1
-                                    // int revReqSize = RevRequest.size();
f8ded1
+                                    // int revReqSize = RevokeRequest.size();
f8ded1
                                     // if( revReqSize > 3 ) {
f8ded1
                                     //     INTEGER serialNumber =
f8ded1
                                     //         new INTEGER((long)0);
f8ded1
@@ -473,13 +477,10 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                                     Integer IntObject = Integer.valueOf((int) reasonCode);
f8ded1
                                     authToken.set(REASON_CODE, IntObject);
f8ded1
 
f8ded1
-
f8ded1
                                     //authToken.set("uid", uid);
f8ded1
                                     //authToken.set("userid", userid);
f8ded1
 
f8ded1
                                 }
f8ded1
-                                */
f8ded1
-
f8ded1
                             }
f8ded1
                         }
f8ded1
 
f8ded1
@@ -648,8 +649,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                                 certInfoArray[i] = certInfo;
f8ded1
 
f8ded1
                                 if (selfSigned) {
f8ded1
-                                    selfsign_skiExtn =
f8ded1
-                                            (SubjectKeyIdentifierExtension) CryptoUtil
f8ded1
+                                    selfsign_skiExtn = (SubjectKeyIdentifierExtension) CryptoUtil
f8ded1
                                             .getExtensionFromCertTemplate(template, PKIXExtensions.SubjectKey_Id);
f8ded1
                                     if (selfsign_skiExtn != null) {
f8ded1
                                         CMS.debug(method +
f8ded1
@@ -702,16 +702,24 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                 throw new EInvalidCredentials(e.toString());
f8ded1
             }
f8ded1
 
f8ded1
-            // store a message in the signed audit log file
f8ded1
-            auditMessage = CMS.getLogMessage(
f8ded1
-                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS,
f8ded1
-                    auditSubjectID,
f8ded1
-                    ILogger.SUCCESS,
f8ded1
-                    auditReqType,
f8ded1
-                    auditCertSubject,
f8ded1
-                    auditSignerInfo);
f8ded1
-
f8ded1
-            audit(auditMessage);
f8ded1
+            // For accuracy, make sure revocation by shared secret doesn't
f8ded1
+            // log CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS
f8ded1
+            if (authToken.get(IAuthManager.CRED_CMC_SIGNING_CERT) != null ||
f8ded1
+                    authToken.get(IAuthManager.CRED_CMC_SELF_SIGNED) != null) {
f8ded1
+                // store a message in the signed audit log file
f8ded1
+                auditMessage = CMS.getLogMessage(
f8ded1
+                        AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS,
f8ded1
+                        auditSubjectID,
f8ded1
+                        ILogger.SUCCESS,
f8ded1
+                        auditReqType,
f8ded1
+                        auditCertSubject,
f8ded1
+                        auditSignerInfo);
f8ded1
+
f8ded1
+                audit(auditMessage);
f8ded1
+            } else {
f8ded1
+                CMS.debug(method
f8ded1
+                        + "audit event CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS not logged due to unsigned data for revocation with shared secret.");
f8ded1
+            }
f8ded1
 
f8ded1
             CMS.debug(method + "ends successfully; returning authToken");
f8ded1
             return authToken;
f8ded1
@@ -1029,10 +1037,15 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                         } else {
f8ded1
                             CMS.debug(method + "found signing cert... verifying");
f8ded1
 
f8ded1
-                            //capture auditSubjectID first in case of failure
f8ded1
-                            netscape.security.x509.X500Name tempPrincipal =
f8ded1
+                            // capture auditSubjectID first in case of failure
f8ded1
+                            netscape.security.x509.X500Name principal =
f8ded1
                                     (X500Name) x509Certs[0].getSubjectDN();
f8ded1
-                            CN = tempPrincipal.getCommonName(); //tempToken.get("userid");
f8ded1
+
f8ded1
+                            // capture signer principal to be checked against
f8ded1
+                            // cert subject principal later in CMCOutputTemplate
f8ded1
+                            // in case of user signed revocation
f8ded1
+                            auditContext.put(SessionContext.CMC_SIGNER_PRINCIPAL, principal);
f8ded1
+                            CN = principal.getCommonName(); //tempToken.get("userid");
f8ded1
                             CMS.debug(method + " Principal name = " + CN);
f8ded1
                             auditContext.put(SessionContext.USER_ID, CN);
f8ded1
 
f8ded1
@@ -1093,15 +1106,18 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
f8ded1
                         // now check revocation status of the cert
f8ded1
                         if (CMS.isRevoked(x509Certs)) {
f8ded1
                             CMS.debug(method + "CMC signing cert is a revoked certificate");
f8ded1
+                            s.close();
f8ded1
                             throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
f8ded1
                         }
f8ded1
                         try { //do this again anyways
f8ded1
                             cert.checkValidity();
f8ded1
                         } catch (CertificateExpiredException e) {
f8ded1
                             CMS.debug(method + "CMC signing cert is an expired certificate");
f8ded1
+                            s.close();
f8ded1
                             throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
f8ded1
                         } catch (Exception e) {
f8ded1
                             CMS.debug(method + e.toString());
f8ded1
+                            s.close();
f8ded1
                             throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
f8ded1
                         }
f8ded1
 
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
f8ded1
index 2591ace..74da8e7 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
f8ded1
@@ -588,16 +588,25 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
         try {
f8ded1
             byte data[] = CMS.AtoB(creq);
f8ded1
             ByteArrayInputStream cmcBlobIn = new ByteArrayInputStream(data);
f8ded1
+            PKIData pkiData = null;
f8ded1
 
f8ded1
             org.mozilla.jss.pkix.cms.ContentInfo cmcReq = (org.mozilla.jss.pkix.cms.ContentInfo) org.mozilla.jss.pkix.cms.ContentInfo
f8ded1
                     .getTemplate().decode(cmcBlobIn);
f8ded1
-            org.mozilla.jss.pkix.cms.SignedData cmcFullReq = (org.mozilla.jss.pkix.cms.SignedData) cmcReq
f8ded1
-                    .getInterpretedContent();
f8ded1
-            org.mozilla.jss.pkix.cms.EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
f8ded1
-            OCTET_STRING content = ci.getContent();
f8ded1
-
f8ded1
+            OCTET_STRING content = null;
f8ded1
+            if (cmcReq.getContentType().equals(
f8ded1
+                    org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA)) {
f8ded1
+                CMS.debug(method + "cmc request content is signed data");
f8ded1
+                org.mozilla.jss.pkix.cms.SignedData cmcFullReq = (org.mozilla.jss.pkix.cms.SignedData) cmcReq
f8ded1
+                        .getInterpretedContent();
f8ded1
+                org.mozilla.jss.pkix.cms.EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
f8ded1
+                content = ci.getContent();
f8ded1
+
f8ded1
+            } else { // for unsigned revocation requests (using shared secret)
f8ded1
+                CMS.debug(method + "cmc request content is unsigned data");
f8ded1
+                content = (OCTET_STRING) cmcReq.getInterpretedContent();
f8ded1
+            }
f8ded1
             ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
f8ded1
-            PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
f8ded1
+            pkiData = (PKIData) (new PKIData.Template()).decode(s);
f8ded1
 
f8ded1
             mCMCData = pkiData;
f8ded1
             //PKIData pkiData = (PKIData)
f8ded1
@@ -708,6 +717,8 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
             byte randomSeed[] = null;
f8ded1
             UTF8String ident_s = null;
f8ded1
             SessionContext context = SessionContext.getContext();
f8ded1
+
f8ded1
+            boolean id_cmc_revokeRequest = false;
f8ded1
             if (!context.containsKey("numOfControls")) {
f8ded1
                 CMS.debug(method + "numcontrols="+ numcontrols);
f8ded1
                 if (numcontrols > 0) {
f8ded1
@@ -735,7 +746,13 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
                     for (int i = 0; i < numcontrols; i++) {
f8ded1
                         attributes[i] = (TaggedAttribute) controlSeq.elementAt(i);
f8ded1
                         OBJECT_IDENTIFIER oid = attributes[i].getType();
f8ded1
-                        if (oid.equals(OBJECT_IDENTIFIER.id_cmc_decryptedPOP)) {
f8ded1
+                        if (oid.equals(OBJECT_IDENTIFIER.id_cmc_revokeRequest)) {
f8ded1
+                            id_cmc_revokeRequest = true;
f8ded1
+                            // put in context for processing in 
f8ded1
+                            // CMCOutputTemplate.java later
f8ded1
+                            context.put(OBJECT_IDENTIFIER.id_cmc_revokeRequest,
f8ded1
+                                    attributes[i]);
f8ded1
+                        } else if (oid.equals(OBJECT_IDENTIFIER.id_cmc_decryptedPOP)) {
f8ded1
                             CMS.debug(method + " id_cmc_decryptedPOP found");
f8ded1
                             id_cmc_decryptedPOP = true;
f8ded1
                             decPopVals = attributes[i].getValues();
f8ded1
@@ -766,6 +783,10 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
                      */
f8ded1
                     CMS.debug(method + "processing controls...");
f8ded1
 
f8ded1
+                    if (id_cmc_revokeRequest) {
f8ded1
+                        CMS.debug(method + "revocation control");
f8ded1
+                    }
f8ded1
+
f8ded1
                     if (id_cmc_identification) {
f8ded1
                         if (ident == null) {
f8ded1
                             msg = "id_cmc_identification contains null attribute value";
f8ded1
@@ -801,7 +822,7 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
 
f8ded1
                     // checking Proof Of Identity, if not pre-signed
f8ded1
 
f8ded1
-                    if (donePOI) {
f8ded1
+                    if (donePOI || id_cmc_revokeRequest) {
f8ded1
                         // for logging purposes
f8ded1
                         if (id_cmc_identityProofV2) {
f8ded1
                             CMS.debug(method
f8ded1
@@ -921,6 +942,7 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
             SEQUENCE otherMsgSeq = pkiData.getOtherMsgSequence();
f8ded1
             int numOtherMsgs = otherMsgSeq.size();
f8ded1
             if (!context.containsKey("numOfOtherMsgs")) {
f8ded1
+                CMS.debug(method + "found numOfOtherMsgs: " + numOtherMsgs);
f8ded1
                 context.put("numOfOtherMsgs", Integer.valueOf(numOtherMsgs));
f8ded1
                 for (int i = 0; i < numOtherMsgs; i++) {
f8ded1
                     OtherMsg omsg = (OtherMsg) (ASN1Util.decode(OtherMsg.getTemplate(),
f8ded1
@@ -959,6 +981,8 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
                 boolean valid = true;
f8ded1
                 for (int i = 0; i < nummsgs; i++) {
f8ded1
                     msgs[i] = (TaggedRequest) reqSeq.elementAt(i);
f8ded1
+                    if (id_cmc_revokeRequest)
f8ded1
+                        continue;
f8ded1
                     if (popLinkWitnessRequired &&
f8ded1
                             !context.containsKey("POPLinkWitnessV2") &&
f8ded1
                             !context.containsKey("POPLinkWitness")) {
f8ded1
@@ -1271,7 +1295,7 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
         boolean sharedSecretFound = true;
f8ded1
         String configName = "cmc.sharedSecret.class";
f8ded1
         String sharedSecret = null;
f8ded1
-        ISharedToken tokenClass = getSharedTokenClass(configName);
f8ded1
+        ISharedToken tokenClass = CMS.getSharedTokenClass(configName);
f8ded1
         if (tokenClass == null) {
f8ded1
             CMS.debug(method + " Failed to retrieve shared secret plugin class");
f8ded1
             sharedSecretFound = false;
f8ded1
@@ -1498,40 +1522,6 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
         return bpids;
f8ded1
     }
f8ded1
 
f8ded1
-
f8ded1
-    ISharedToken getSharedTokenClass(String configName) {
f8ded1
-        String method = "EnrollProfile: getSharedTokenClass: ";
f8ded1
-        ISharedToken tokenClass = null;
f8ded1
-
f8ded1
-        String name = null;
f8ded1
-        try {
f8ded1
-            CMS.debug(method + "getting :" + configName);
f8ded1
-            name = CMS.getConfigStore().getString(configName);
f8ded1
-            CMS.debug(method + "Shared Secret plugin class name retrieved:" +
f8ded1
-                    name);
f8ded1
-        } catch (Exception e) {
f8ded1
-            CMS.debug(method + " Failed to retrieve shared secret plugin class name");
f8ded1
-            return null;
f8ded1
-        }
f8ded1
-
f8ded1
-        try {
f8ded1
-            tokenClass = (ISharedToken) Class.forName(name).newInstance();
f8ded1
-            CMS.debug(method + "Shared Secret plugin class retrieved");
f8ded1
-        } catch (ClassNotFoundException e) {
f8ded1
-            CMS.debug(method + " Failed to find class name: " + name);
f8ded1
-            return null;
f8ded1
-        } catch (InstantiationException e) {
f8ded1
-            CMS.debug("EnrollProfile: Failed to instantiate class: " + name);
f8ded1
-            return null;
f8ded1
-        } catch (IllegalAccessException e) {
f8ded1
-            CMS.debug(method + " Illegal access: " + name);
f8ded1
-            return null;
f8ded1
-        }
f8ded1
-
f8ded1
-        return tokenClass;
f8ded1
-    }
f8ded1
-
f8ded1
-
f8ded1
     /**
f8ded1
      * verifyIdentityProofV2 handles IdentityProofV2 as defined by RFC5272
f8ded1
      *
f8ded1
@@ -1577,7 +1567,7 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
         }
f8ded1
 
f8ded1
         String configName = "cmc.sharedSecret.class";
f8ded1
-        ISharedToken tokenClass = getSharedTokenClass(configName);
f8ded1
+        ISharedToken tokenClass = CMS.getSharedTokenClass(configName);
f8ded1
 
f8ded1
         if (tokenClass == null) {
f8ded1
             msg = " Failed to retrieve shared secret plugin class";
f8ded1
@@ -1681,7 +1671,7 @@ public abstract class EnrollProfile extends BasicProfile
f8ded1
             return false;
f8ded1
 
f8ded1
         String configName = "cmc.sharedSecret.class";
f8ded1
-            ISharedToken tokenClass = getSharedTokenClass(configName);
f8ded1
+            ISharedToken tokenClass = CMS.getSharedTokenClass(configName);
f8ded1
         if (tokenClass == null) {
f8ded1
             CMS.debug(method + " Failed to retrieve shared secret plugin class");
f8ded1
             return false;
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
f8ded1
index 24ba494..a66cd95 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
f8ded1
@@ -142,6 +142,8 @@ public class CMCRevReqServlet extends CMSServlet {
f8ded1
      * @param cmsReq the object holding the request and response information
f8ded1
      */
f8ded1
     protected void process(CMSRequest cmsReq) throws EBaseException {
f8ded1
+        String method = "CMCRevReqServlet: process: ";
f8ded1
+        CMS.debug(method + "begins");
f8ded1
 
f8ded1
         String cmcAgentSerialNumber = null;
f8ded1
         IArgBlock httpParams = cmsReq.getHttpParams();
f8ded1
@@ -151,7 +153,7 @@ public class CMCRevReqServlet extends CMSServlet {
f8ded1
         CMSTemplate form = null;
f8ded1
         Locale[] locale = new Locale[1];
f8ded1
 
f8ded1
-        CMS.debug("**** mFormPath = " + mFormPath);
f8ded1
+        CMS.debug(method + "**** mFormPath = " + mFormPath);
f8ded1
         try {
f8ded1
             form = getTemplate(mFormPath, req, locale);
f8ded1
         } catch (IOException e) {
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/ListCerts.java b/base/server/cms/src/com/netscape/cms/servlet/cert/ListCerts.java
f8ded1
index 3794f10..01c4b6a 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/ListCerts.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/ListCerts.java
f8ded1
@@ -461,11 +461,11 @@ public class ListCerts extends CMSServlet {
f8ded1
                 ICertRecord rec = e.nextElement();
f8ded1
 
f8ded1
                 if (rec == null) {
f8ded1
-                    CMS.debug("ListCerts: * record " + count + " is null");
f8ded1
+                    //CMS.debug("ListCerts: * record " + count + " is null");
f8ded1
                     break;
f8ded1
                 }
f8ded1
                 curSerial = rec.getSerialNumber();
f8ded1
-                CMS.debug("ListCerts: * record " + count + ": " + curSerial);
f8ded1
+                //CMS.debug("ListCerts: * record " + count + ": " + curSerial);
f8ded1
 
f8ded1
                 if (count == 0) {
f8ded1
                     firstSerial = curSerial;
f8ded1
@@ -493,11 +493,11 @@ public class ListCerts extends CMSServlet {
f8ded1
                 }
f8ded1
 
f8ded1
                 if (mReverse) {
f8ded1
-                    CMS.debug("ListCerts: returning with rcount: " + rcount);
f8ded1
+                    //CMS.debug("ListCerts: returning with rcount: " + rcount);
f8ded1
                     recs[rcount++] = rec;
f8ded1
 
f8ded1
                 } else {
f8ded1
-                    CMS.debug("ListCerts: returning with arg block");
f8ded1
+                    //CMS.debug("ListCerts: returning with arg block");
f8ded1
                     IArgBlock rarg = CMS.createArgBlock();
f8ded1
                     fillRecordIntoArg(rec, rarg);
f8ded1
                     argSet.addRepeatRecord(rarg);
f8ded1
@@ -514,7 +514,7 @@ public class ListCerts extends CMSServlet {
f8ded1
             CMS.debug("ListCerts: fill records into arg block and argSet");
f8ded1
             for (int ii = rcount - 1; ii >= 0; ii--) {
f8ded1
                 if (recs[ii] != null) {
f8ded1
-                    CMS.debug("ListCerts: processing recs[" + ii + "]");
f8ded1
+                    //CMS.debug("ListCerts: processing recs[" + ii + "]");
f8ded1
                     IArgBlock rarg = CMS.createArgBlock();
f8ded1
                     // CMS.debug("item " + ii + " is serial #" + recs[ii].getSerialNumber());
f8ded1
                     fillRecordIntoArg(recs[ii], rarg);
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
f8ded1
index 8d6c37f..067dce7 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/servlet/common/CMCOutputTemplate.java
f8ded1
@@ -25,6 +25,7 @@ import java.math.BigInteger;
f8ded1
 import java.security.MessageDigest;
f8ded1
 import java.security.NoSuchAlgorithmException;
f8ded1
 import java.security.PublicKey;
f8ded1
+import java.security.cert.CertificateExpiredException;
f8ded1
 import java.util.Date;
f8ded1
 import java.util.Hashtable;
f8ded1
 
f8ded1
@@ -55,9 +56,9 @@ import org.mozilla.jss.pkix.cmc.OtherInfo;
f8ded1
 import org.mozilla.jss.pkix.cmc.OtherMsg;
f8ded1
 import org.mozilla.jss.pkix.cmc.PendInfo;
f8ded1
 import org.mozilla.jss.pkix.cmc.ResponseBody;
f8ded1
+import org.mozilla.jss.pkix.cmc.RevokeRequest;
f8ded1
 import org.mozilla.jss.pkix.cmc.TaggedAttribute;
f8ded1
 import org.mozilla.jss.pkix.cmc.TaggedRequest;
f8ded1
-import org.mozilla.jss.pkix.cmmf.RevRequest;
f8ded1
 import org.mozilla.jss.pkix.cms.ContentInfo;
f8ded1
 import org.mozilla.jss.pkix.cms.EncapsulatedContentInfo;
f8ded1
 import org.mozilla.jss.pkix.cms.EnvelopedData;
f8ded1
@@ -76,8 +77,10 @@ import com.netscape.certsrv.base.SessionContext;
f8ded1
 import com.netscape.certsrv.ca.ICertificateAuthority;
f8ded1
 import com.netscape.certsrv.dbs.certdb.ICertRecord;
f8ded1
 import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
f8ded1
+import com.netscape.certsrv.logging.AuditEvent;
f8ded1
 import com.netscape.certsrv.logging.AuditFormat;
f8ded1
 import com.netscape.certsrv.logging.ILogger;
f8ded1
+import com.netscape.certsrv.logging.event.CertStatusChangeRequestProcessedEvent;
f8ded1
 import com.netscape.certsrv.profile.IEnrollProfile;
f8ded1
 import com.netscape.certsrv.request.IRequest;
f8ded1
 import com.netscape.certsrv.request.IRequestQueue;
f8ded1
@@ -101,6 +104,8 @@ import netscape.security.x509.X509Key;
f8ded1
  * @version $ $, $Date$
f8ded1
  */
f8ded1
 public class CMCOutputTemplate {
f8ded1
+    protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
f8ded1
+
f8ded1
     public CMCOutputTemplate() {
f8ded1
     }
f8ded1
 
f8ded1
@@ -212,14 +217,12 @@ public class CMCOutputTemplate {
f8ded1
                     }
f8ded1
                 }
f8ded1
             } else {
f8ded1
-                CMS.debug(method + " reqs null.  why?");
f8ded1
+                CMS.debug(method + " reqs null. could be revocation");
f8ded1
             }
f8ded1
 
f8ded1
             TaggedAttribute tagattr = null;
f8ded1
             CMCStatusInfo cmcStatusInfo = null;
f8ded1
 
f8ded1
-//cfu
f8ded1
-
f8ded1
             SEQUENCE decryptedPOPBpids = (SEQUENCE) context.get("decryptedPOP");
f8ded1
             if (decryptedPOPBpids != null && decryptedPOPBpids.size() > 0) {
f8ded1
                 OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
f8ded1
@@ -880,8 +883,8 @@ public class CMCOutputTemplate {
f8ded1
                 String salt = "lala123" + date.toString();
f8ded1
                 byte[] dig;
f8ded1
                 try {
f8ded1
-                    MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
f8ded1
-                    dig = SHA1Digest.digest(salt.getBytes());
f8ded1
+                    MessageDigest SHA2Digest = MessageDigest.getInstance("SHA256");
f8ded1
+                    dig = SHA2Digest.digest(salt.getBytes());
f8ded1
                 } catch (NoSuchAlgorithmException ex) {
f8ded1
                     dig = salt.getBytes();
f8ded1
                 }
f8ded1
@@ -920,22 +923,59 @@ public class CMCOutputTemplate {
f8ded1
     private int processRevokeRequestControl(TaggedAttribute attr,
f8ded1
             SEQUENCE controlSeq, int bpid) throws InvalidBERException, EBaseException,
f8ded1
             IOException {
f8ded1
+        String method = "CMCOutputTemplate: processRevokeRequestControl: ";
f8ded1
+        String msg = "";
f8ded1
+        CMS.debug(method + "begins");
f8ded1
         boolean revoke = false;
f8ded1
         SessionContext context = SessionContext.getContext();
f8ded1
+        String authManagerId = (String) context.get(SessionContext.AUTH_MANAGER_ID);
f8ded1
+        if (authManagerId == null) {
f8ded1
+            CMS.debug(method + "authManagerId null.????");
f8ded1
+            //unlikely, but...
f8ded1
+            authManagerId = "none";
f8ded1
+        } else {
f8ded1
+            CMS.debug(method + "authManagerId =" + authManagerId);
f8ded1
+        }
f8ded1
+
f8ded1
+        // in case of CMCUserSignedAuth,
f8ded1
+        // for matching signer and revoked cert principal
f8ded1
+        X500Name signerPrincipal = null;
f8ded1
+
f8ded1
+        // for auditing
f8ded1
+        String auditRequesterID = null;
f8ded1
+        auditRequesterID = (String) context.get(SessionContext.USER_ID);
f8ded1
+
f8ded1
+        if (auditRequesterID != null) {
f8ded1
+            auditRequesterID = auditRequesterID.trim();
f8ded1
+        } else {
f8ded1
+            auditRequesterID = ILogger.NONROLEUSER;
f8ded1
+        }
f8ded1
+        signerPrincipal = (X500Name) context.get(SessionContext.CMC_SIGNER_PRINCIPAL);
f8ded1
+        String auditSubjectID = null;
f8ded1
+        String auditRequestType = "revoke";
f8ded1
+        String auditSerialNumber = null;
f8ded1
+        String auditReasonNum = null;
f8ded1
+        RequestStatus auditApprovalStatus = RequestStatus.REJECTED;
f8ded1
+
f8ded1
         if (attr != null) {
f8ded1
             INTEGER attrbpid = attr.getBodyPartID();
f8ded1
             CMCStatusInfo cmcStatusInfo = null;
f8ded1
             SET vals = attr.getValues();
f8ded1
             if (vals.size() > 0) {
f8ded1
-                RevRequest revRequest =
f8ded1
-                        (RevRequest) (ASN1Util.decode(new RevRequest.Template(),
f8ded1
-                                ASN1Util.encode(vals.elementAt(0))));
f8ded1
-                OCTET_STRING str = revRequest.getSharedSecret();
f8ded1
+                RevokeRequest revRequest = (RevokeRequest) (ASN1Util.decode(new RevokeRequest.Template(),
f8ded1
+                        ASN1Util.encode(vals.elementAt(0))));
f8ded1
+                OCTET_STRING reqSecret = revRequest.getSharedSecret();
f8ded1
                 INTEGER pid = attr.getBodyPartID();
f8ded1
                 TaggedAttribute tagattr = null;
f8ded1
                 INTEGER revokeCertSerial = revRequest.getSerialNumber();
f8ded1
+                ENUMERATED n = revRequest.getReason();
f8ded1
+                RevocationReason reason = toRevocationReason(n);
f8ded1
+                auditReasonNum = reason.toString();
f8ded1
                 BigInteger revokeSerial = new BigInteger(revokeCertSerial.toByteArray());
f8ded1
-                if (str == null) {
f8ded1
+                auditSerialNumber = revokeSerial.toString();
f8ded1
+
f8ded1
+                if (reqSecret == null) {
f8ded1
+                    CMS.debug(method + "no shared secret in request; Checking signature;");
f8ded1
                     boolean needVerify = true;
f8ded1
                     try {
f8ded1
                         needVerify = CMS.getConfigStore().getBoolean("cmc.revokeCert.verify", true);
f8ded1
@@ -943,67 +983,75 @@ public class CMCOutputTemplate {
f8ded1
                     }
f8ded1
 
f8ded1
                     if (needVerify) {
f8ded1
-                        Integer num1 = (Integer) context.get("numOfOtherMsgs");
f8ded1
-                        int num = num1.intValue();
f8ded1
-                        for (int i = 0; i < num; i++) {
f8ded1
-                            OtherMsg data = (OtherMsg) context.get("otherMsg" + i);
f8ded1
-                            INTEGER dpid = data.getBodyPartID();
f8ded1
-                            if (pid.longValue() == dpid.longValue()) {
f8ded1
-                                ANY msgValue = data.getOtherMsgValue();
f8ded1
-                                SignedData msgData =
f8ded1
-                                        (SignedData) msgValue.decodeWith(SignedData.getTemplate());
f8ded1
-                                if (!verifyRevRequestSignature(msgData)) {
f8ded1
-                                    OtherInfo otherInfo =
f8ded1
-                                            new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK),
f8ded1
-                                                    null);
f8ded1
-                                    SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
-                                    failed_bpids.addElement(attrbpid);
f8ded1
-                                    cmcStatusInfo =
f8ded1
-                                            new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null,
f8ded1
-                                                    otherInfo);
f8ded1
-                                    tagattr = new TaggedAttribute(
f8ded1
-                                            new INTEGER(bpid++),
f8ded1
-                                            OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
-                                    controlSeq.addElement(tagattr);
f8ded1
-                                    return bpid;
f8ded1
+                        if (authManagerId.equals("CMCUserSignedAuth")) {
f8ded1
+                            if (signerPrincipal == null) {
f8ded1
+                                CMS.debug(method + "missing CMC signer principal");
f8ded1
+                                OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
f8ded1
+                                        new INTEGER(OtherInfo.BAD_MESSAGE_CHECK),
f8ded1
+                                        null);
f8ded1
+                                SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
+                                failed_bpids.addElement(attrbpid);
f8ded1
+                                cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null,
f8ded1
+                                        otherInfo);
f8ded1
+                                tagattr = new TaggedAttribute(
f8ded1
+                                        new INTEGER(bpid++),
f8ded1
+                                        OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
+                                controlSeq.addElement(tagattr);
f8ded1
+                                return bpid;
f8ded1
+                            }
f8ded1
+                        } else { // !CMCUserSignedAuth
f8ded1
+
f8ded1
+                            // this code is making the assumption that OtherMsg
f8ded1
+                            // is used for signer info in signed cmc revocation,
f8ded1
+                            // when in fact the signer info is
f8ded1
+                            // in the outer layer and should have already been
f8ded1
+                            // verified in the auth manager;
f8ded1
+                            // Left here for possible legacy client(s)
f8ded1
+
f8ded1
+                            Integer num1 = (Integer) context.get("numOfOtherMsgs");
f8ded1
+                            CMS.debug(method + "found numOfOtherMsgs =" + num1.toString());
f8ded1
+                            int num = num1.intValue();
f8ded1
+                            for (int i = 0; i < num; i++) {
f8ded1
+                                OtherMsg data = (OtherMsg) context.get("otherMsg" + i);
f8ded1
+                                INTEGER dpid = data.getBodyPartID();
f8ded1
+                                if (pid.longValue() == dpid.longValue()) {
f8ded1
+                                    CMS.debug(method + "body part id match;");
f8ded1
+                                    ANY msgValue = data.getOtherMsgValue();
f8ded1
+                                    SignedData msgData = (SignedData) msgValue.decodeWith(SignedData.getTemplate());
f8ded1
+                                    if (!verifyRevRequestSignature(msgData)) {
f8ded1
+                                        OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL,
f8ded1
+                                                new INTEGER(OtherInfo.BAD_MESSAGE_CHECK),
f8ded1
+                                                null);
f8ded1
+                                        SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
+                                        failed_bpids.addElement(attrbpid);
f8ded1
+                                        cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids,
f8ded1
+                                                (String) null,
f8ded1
+                                                otherInfo);
f8ded1
+                                        tagattr = new TaggedAttribute(
f8ded1
+                                                new INTEGER(bpid++),
f8ded1
+                                                OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
+                                        controlSeq.addElement(tagattr);
f8ded1
+                                        return bpid;
f8ded1
+                                    }
f8ded1
+                                } else {
f8ded1
+                                    CMS.debug(method + "body part id do not match;");
f8ded1
                                 }
f8ded1
                             }
f8ded1
                         }
f8ded1
                     }
f8ded1
 
f8ded1
                     revoke = true;
f8ded1
+                } else { //use shared secret; request unsigned
f8ded1
+                    CMS.debug(method + "checking shared secret");
f8ded1
                     // check shared secret
f8ded1
-                } else {
f8ded1
-                    ISharedToken tokenClass = null;
f8ded1
-                    boolean sharedSecretFound = true;
f8ded1
-                    String name = null;
f8ded1
-                    try {
f8ded1
-                        name = CMS.getConfigStore().getString("cmc.revokeCert.sharedSecret.class");
f8ded1
-                    } catch (EPropertyNotFound e) {
f8ded1
-                        CMS.debug("EnrollProfile: Failed to find the token class in the configuration file.");
f8ded1
-                        sharedSecretFound = false;
f8ded1
-                    } catch (EBaseException e) {
f8ded1
-                        CMS.debug("EnrollProfile: Failed to find the token class in the configuration file.");
f8ded1
-                        sharedSecretFound = false;
f8ded1
-                    }
f8ded1
-
f8ded1
-                    try {
f8ded1
-                        tokenClass = (ISharedToken) Class.forName(name).newInstance();
f8ded1
-                    } catch (ClassNotFoundException e) {
f8ded1
-                        CMS.debug("EnrollProfile: Failed to find class name: " + name);
f8ded1
-                        sharedSecretFound = false;
f8ded1
-                    } catch (InstantiationException e) {
f8ded1
-                        CMS.debug("EnrollProfile: Failed to instantiate class: " + name);
f8ded1
-                        sharedSecretFound = false;
f8ded1
-                    } catch (IllegalAccessException e) {
f8ded1
-                        CMS.debug("EnrollProfile: Illegal access: " + name);
f8ded1
-                        sharedSecretFound = false;
f8ded1
-                    }
f8ded1
-
f8ded1
-                    if (!sharedSecretFound) {
f8ded1
-                        CMS.debug("CMCOutputTemplate: class for shared secret was not found.");
f8ded1
-                        OtherInfo otherInfo =
f8ded1
-                                new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR), null);
f8ded1
+                    //TODO: remember to provide one-time-use when working
f8ded1
+                    //      on shared token
f8ded1
+                    ISharedToken tokenClass =
f8ded1
+                            CMS.getSharedTokenClass("cmc.revokeCert.sharedSecret.class");
f8ded1
+                    if (tokenClass == null) {
f8ded1
+                        CMS.debug(method + " Failed to retrieve shared secret plugin class");
f8ded1
+                        OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR),
f8ded1
+                                null);
f8ded1
                         SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
                         failed_bpids.addElement(attrbpid);
f8ded1
                         cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo);
f8ded1
@@ -1014,15 +1062,13 @@ public class CMCOutputTemplate {
f8ded1
                         return bpid;
f8ded1
                     }
f8ded1
 
f8ded1
-                    String sharedSecret = null;
f8ded1
-                    if (tokenClass != null) {
f8ded1
-                        sharedSecret = tokenClass.getSharedToken(revokeSerial);
f8ded1
-                    }
f8ded1
+                    String sharedSecret = 
f8ded1
+                            sharedSecret = tokenClass.getSharedToken(revokeSerial);
f8ded1
 
f8ded1
                     if (sharedSecret == null) {
f8ded1
-                        CMS.debug("CMCOutputTemplate: class for shared secret was not found.");
f8ded1
-                        OtherInfo otherInfo =
f8ded1
-                                new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR), null);
f8ded1
+                        CMS.debug("CMCOutputTemplate: shared secret not found.");
f8ded1
+                        OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.INTERNAL_CA_ERROR),
f8ded1
+                                null);
f8ded1
                         SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
                         failed_bpids.addElement(attrbpid);
f8ded1
                         cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo);
f8ded1
@@ -1033,15 +1079,17 @@ public class CMCOutputTemplate {
f8ded1
                         return bpid;
f8ded1
                     }
f8ded1
 
f8ded1
-                    byte[] strb = str.toByteArray();
f8ded1
-                    String clientSC = new String(strb);
f8ded1
+                    byte[] reqSecretb = reqSecret.toByteArray();
f8ded1
+                    String clientSC = new String(reqSecretb);
f8ded1
                     if (clientSC.equals(sharedSecret)) {
f8ded1
-                        CMS.debug("CMCOutputTemplate: Both client and server shared secret are the same, can go ahead to revoke certificate.");
f8ded1
+                        CMS.debug(method
f8ded1
+                                + " Client and server shared secret are the same, can go ahead and revoke certificate.");
f8ded1
                         revoke = true;
f8ded1
                     } else {
f8ded1
-                        CMS.debug("CMCOutputTemplate: Both client and server shared secret are not the same, cant revoke certificate.");
f8ded1
-                        OtherInfo otherInfo =
f8ded1
-                                new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), null);
f8ded1
+                        CMS.debug(method
f8ded1
+                                + " Client and server shared secret are not the same, cannot revoke certificate.");
f8ded1
+                        OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK),
f8ded1
+                                null);
f8ded1
                         SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
                         failed_bpids.addElement(attrbpid);
f8ded1
                         cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo);
f8ded1
@@ -1049,6 +1097,16 @@ public class CMCOutputTemplate {
f8ded1
                                 new INTEGER(bpid++),
f8ded1
                                 OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
                         controlSeq.addElement(tagattr);
f8ded1
+
f8ded1
+                        audit(new CertStatusChangeRequestProcessedEvent(
f8ded1
+                                auditSubjectID,
f8ded1
+                                ILogger.FAILURE,
f8ded1
+                                auditRequesterID,
f8ded1
+                                auditSerialNumber,
f8ded1
+                                auditRequestType,
f8ded1
+                                auditReasonNum,
f8ded1
+                                auditApprovalStatus));
f8ded1
+
f8ded1
                         return bpid;
f8ded1
                     }
f8ded1
                 }
f8ded1
@@ -1060,11 +1118,11 @@ public class CMCOutputTemplate {
f8ded1
                     try {
f8ded1
                         record = repository.readCertificateRecord(revokeSerial);
f8ded1
                     } catch (EBaseException ee) {
f8ded1
-                        CMS.debug("CMCOutputTemplate: Exception: " + ee.toString());
f8ded1
+                        CMS.debug(method + "Exception: " + ee.toString());
f8ded1
                     }
f8ded1
 
f8ded1
                     if (record == null) {
f8ded1
-                        CMS.debug("CMCOutputTemplate: The certificate is not found");
f8ded1
+                        CMS.debug(method + " The certificate is not found");
f8ded1
                         OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_CERT_ID), null);
f8ded1
                         SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
                         failed_bpids.addElement(attrbpid);
f8ded1
@@ -1088,11 +1146,46 @@ public class CMCOutputTemplate {
f8ded1
                         controlSeq.addElement(tagattr);
f8ded1
                         return bpid;
f8ded1
                     }
f8ded1
+
f8ded1
                     X509CertImpl impl = record.getCertificate();
f8ded1
+
f8ded1
+                    X500Name certPrincipal = (X500Name) impl.getSubjectDN();
f8ded1
+                    auditSubjectID = certPrincipal.getCommonName();
f8ded1
+
f8ded1
+                    // in case of user-signed request, check if signer
f8ded1
+                    // principal matches that of the revoking cert
f8ded1
+                    if ((reqSecret == null) && authManagerId.equals("CMCUserSignedAuth")) {
f8ded1
+                        if (!certPrincipal.equals(signerPrincipal)) {
f8ded1
+                            msg = "certificate principal and signer do not match";
f8ded1
+                            CMS.debug(method + msg);
f8ded1
+                            OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_IDENTITY),
f8ded1
+                                    null);
f8ded1
+                            SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
+                            failed_bpids.addElement(attrbpid);
f8ded1
+                            cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, msg,
f8ded1
+                                    otherInfo);
f8ded1
+                            tagattr = new TaggedAttribute(
f8ded1
+                                    new INTEGER(bpid++),
f8ded1
+                                    OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
+                            controlSeq.addElement(tagattr);
f8ded1
+
f8ded1
+                            audit(new CertStatusChangeRequestProcessedEvent(
f8ded1
+                                    auditSubjectID,
f8ded1
+                                    ILogger.FAILURE,
f8ded1
+                                    auditRequesterID,
f8ded1
+                                    auditSerialNumber,
f8ded1
+                                    auditRequestType,
f8ded1
+                                    auditReasonNum,
f8ded1
+                                    auditApprovalStatus));
f8ded1
+
f8ded1
+                            return bpid;
f8ded1
+                        } else {
f8ded1
+                            CMS.debug(method + "certificate principal and signer match");
f8ded1
+                        }
f8ded1
+                    }
f8ded1
+
f8ded1
                     X509CertImpl[] impls = new X509CertImpl[1];
f8ded1
                     impls[0] = impl;
f8ded1
-                    ENUMERATED n = revRequest.getReason();
f8ded1
-                    RevocationReason reason = toRevocationReason(n);
f8ded1
                     CRLReasonExtension crlReasonExtn = new CRLReasonExtension(reason);
f8ded1
                     CRLExtensions entryExtn = new CRLExtensions();
f8ded1
                     GeneralizedTime t = revRequest.getInvalidityDate();
f8ded1
@@ -1105,8 +1198,8 @@ public class CMCOutputTemplate {
f8ded1
                         entryExtn.set(crlReasonExtn.getName(), crlReasonExtn);
f8ded1
                     }
f8ded1
 
f8ded1
-                    RevokedCertImpl revCertImpl =
f8ded1
-                            new RevokedCertImpl(impl.getSerialNumber(), CMS.getCurrentDate(), entryExtn);
f8ded1
+                    RevokedCertImpl revCertImpl = new RevokedCertImpl(impl.getSerialNumber(), CMS.getCurrentDate(),
f8ded1
+                            entryExtn);
f8ded1
                     RevokedCertImpl[] revCertImpls = new RevokedCertImpl[1];
f8ded1
                     revCertImpls[0] = revCertImpl;
f8ded1
                     IRequestQueue queue = ca.getRequestQueue();
f8ded1
@@ -1122,20 +1215,30 @@ public class CMCOutputTemplate {
f8ded1
                     RequestStatus stat = revReq.getRequestStatus();
f8ded1
                     if (stat == RequestStatus.COMPLETE) {
f8ded1
                         Integer result = revReq.getExtDataInInteger(IRequest.RESULT);
f8ded1
-                        CMS.debug("CMCOutputTemplate: revReq result = " + result);
f8ded1
+                        CMS.debug(method + " revReq result = " + result);
f8ded1
                         if (result.equals(IRequest.RES_ERROR)) {
f8ded1
                             CMS.debug("CMCOutputTemplate: revReq exception: " +
f8ded1
                                     revReq.getExtDataInString(IRequest.ERROR));
f8ded1
-                            OtherInfo otherInfo =
f8ded1
-                                    new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_REQUEST), null);
f8ded1
+                            OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_REQUEST),
f8ded1
+                                    null);
f8ded1
                             SEQUENCE failed_bpids = new SEQUENCE();
f8ded1
                             failed_bpids.addElement(attrbpid);
f8ded1
-                            cmcStatusInfo =
f8ded1
-                                    new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null, otherInfo);
f8ded1
+                            cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.FAILED, failed_bpids, (String) null,
f8ded1
+                                    otherInfo);
f8ded1
                             tagattr = new TaggedAttribute(
f8ded1
                                     new INTEGER(bpid++),
f8ded1
                                     OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
                             controlSeq.addElement(tagattr);
f8ded1
+
f8ded1
+                            audit(new CertStatusChangeRequestProcessedEvent(
f8ded1
+                                    auditSubjectID,
f8ded1
+                                    ILogger.FAILURE,
f8ded1
+                                    auditRequesterID,
f8ded1
+                                    auditSerialNumber,
f8ded1
+                                    auditRequestType,
f8ded1
+                                    auditReasonNum,
f8ded1
+                                    auditApprovalStatus));
f8ded1
+
f8ded1
                             return bpid;
f8ded1
                         }
f8ded1
                     }
f8ded1
@@ -1148,7 +1251,7 @@ public class CMCOutputTemplate {
f8ded1
                                     impl.getSubjectDN(),
f8ded1
                                     impl.getSerialNumber().toString(16),
f8ded1
                                     reason.toString() });
f8ded1
-                    CMS.debug("CMCOutputTemplate: Certificate get revoked.");
f8ded1
+                    CMS.debug(method + " Certificate revoked.");
f8ded1
                     SEQUENCE success_bpids = new SEQUENCE();
f8ded1
                     success_bpids.addElement(attrbpid);
f8ded1
                     cmcStatusInfo = new CMCStatusInfo(CMCStatusInfo.SUCCESS,
f8ded1
@@ -1157,6 +1260,16 @@ public class CMCOutputTemplate {
f8ded1
                             new INTEGER(bpid++),
f8ded1
                             OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
                     controlSeq.addElement(tagattr);
f8ded1
+
f8ded1
+                    auditApprovalStatus = RequestStatus.COMPLETE;
f8ded1
+                    audit(new CertStatusChangeRequestProcessedEvent(
f8ded1
+                            auditSubjectID,
f8ded1
+                            ILogger.SUCCESS,
f8ded1
+                            auditRequesterID,
f8ded1
+                            auditSerialNumber,
f8ded1
+                            auditRequestType,
f8ded1
+                            auditReasonNum,
f8ded1
+                            auditApprovalStatus));
f8ded1
                     return bpid;
f8ded1
                 } else {
f8ded1
                     OtherInfo otherInfo = new OtherInfo(OtherInfo.FAIL, new INTEGER(OtherInfo.BAD_MESSAGE_CHECK), null);
f8ded1
@@ -1167,6 +1280,16 @@ public class CMCOutputTemplate {
f8ded1
                             new INTEGER(bpid++),
f8ded1
                             OBJECT_IDENTIFIER.id_cmc_cMCStatusInfo, cmcStatusInfo);
f8ded1
                     controlSeq.addElement(tagattr);
f8ded1
+
f8ded1
+                    audit(new CertStatusChangeRequestProcessedEvent(
f8ded1
+                            auditSubjectID,
f8ded1
+                            ILogger.FAILURE,
f8ded1
+                            auditRequesterID,
f8ded1
+                            auditSerialNumber,
f8ded1
+                            auditRequestType,
f8ded1
+                            auditReasonNum,
f8ded1
+                            auditApprovalStatus));
f8ded1
+
f8ded1
                     return bpid;
f8ded1
                 }
f8ded1
             }
f8ded1
@@ -1175,54 +1298,81 @@ public class CMCOutputTemplate {
f8ded1
         return bpid;
f8ded1
     }
f8ded1
 
f8ded1
+    protected void audit(AuditEvent event) {
f8ded1
+
f8ded1
+        String template = event.getMessage();
f8ded1
+        Object[] params = event.getParameters();
f8ded1
+
f8ded1
+        String message = CMS.getLogMessage(template, params);
f8ded1
+
f8ded1
+        audit(message);
f8ded1
+    }
f8ded1
+
f8ded1
+    protected void audit(String msg) {
f8ded1
+        // in this case, do NOT strip preceding/trailing whitespace
f8ded1
+        // from passed-in String parameters
f8ded1
+
f8ded1
+        if (mSignedAuditLogger == null) {
f8ded1
+            return;
f8ded1
+        }
f8ded1
+
f8ded1
+        mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
f8ded1
+                null,
f8ded1
+                ILogger.S_SIGNED_AUDIT,
f8ded1
+                ILogger.LL_SECURITY,
f8ded1
+                msg);
f8ded1
+    }
f8ded1
+
f8ded1
     private RevocationReason toRevocationReason(ENUMERATED n) {
f8ded1
         long code = n.getValue();
f8ded1
-        if (code == RevRequest.aACompromise.getValue())
f8ded1
+        if (code == RevokeRequest.aACompromise.getValue())
f8ded1
             return RevocationReason.UNSPECIFIED;
f8ded1
-        else if (code == RevRequest.affiliationChanged.getValue())
f8ded1
+        else if (code == RevokeRequest.affiliationChanged.getValue())
f8ded1
             return RevocationReason.AFFILIATION_CHANGED;
f8ded1
-        else if (code == RevRequest.cACompromise.getValue())
f8ded1
+        else if (code == RevokeRequest.cACompromise.getValue())
f8ded1
             return RevocationReason.CA_COMPROMISE;
f8ded1
-        else if (code == RevRequest.certificateHold.getValue())
f8ded1
+        else if (code == RevokeRequest.certificateHold.getValue())
f8ded1
             return RevocationReason.CERTIFICATE_HOLD;
f8ded1
-        else if (code == RevRequest.cessationOfOperation.getValue())
f8ded1
+        else if (code == RevokeRequest.cessationOfOperation.getValue())
f8ded1
             return RevocationReason.CESSATION_OF_OPERATION;
f8ded1
-        else if (code == RevRequest.keyCompromise.getValue())
f8ded1
+        else if (code == RevokeRequest.keyCompromise.getValue())
f8ded1
             return RevocationReason.KEY_COMPROMISE;
f8ded1
-        else if (code == RevRequest.privilegeWithdrawn.getValue())
f8ded1
+        else if (code == RevokeRequest.privilegeWithdrawn.getValue())
f8ded1
             return RevocationReason.UNSPECIFIED;
f8ded1
-        else if (code == RevRequest.removeFromCRL.getValue())
f8ded1
+        else if (code == RevokeRequest.removeFromCRL.getValue())
f8ded1
             return RevocationReason.REMOVE_FROM_CRL;
f8ded1
-        else if (code == RevRequest.superseded.getValue())
f8ded1
+        else if (code == RevokeRequest.superseded.getValue())
f8ded1
             return RevocationReason.SUPERSEDED;
f8ded1
-        else if (code == RevRequest.unspecified.getValue())
f8ded1
+        else if (code == RevokeRequest.unspecified.getValue())
f8ded1
             return RevocationReason.UNSPECIFIED;
f8ded1
         return RevocationReason.UNSPECIFIED;
f8ded1
     }
f8ded1
 
f8ded1
     private boolean verifyRevRequestSignature(SignedData msgData) {
f8ded1
+        String method = "CMCOutputTemplate: verifyRevRequestSignature: ";
f8ded1
+        CMS.debug(method + "begins");
f8ded1
         try {
f8ded1
             EncapsulatedContentInfo ci = msgData.getContentInfo();
f8ded1
             OCTET_STRING content = ci.getContent();
f8ded1
             ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
f8ded1
             TaggedAttribute tattr = (TaggedAttribute) (new TaggedAttribute.Template()).decode(s);
f8ded1
             SET values = tattr.getValues();
f8ded1
-            RevRequest revRequest = null;
f8ded1
-            if (values != null && values.size() > 0)
f8ded1
-                revRequest =
f8ded1
-                        (RevRequest) (ASN1Util.decode(new RevRequest.Template(),
f8ded1
-                                ASN1Util.encode(values.elementAt(0))));
f8ded1
+            RevokeRequest revRequest = null;
f8ded1
+            if (values != null && values.size() > 0) {
f8ded1
+                revRequest = (RevokeRequest) (ASN1Util.decode(new RevokeRequest.Template(),
f8ded1
+                        ASN1Util.encode(values.elementAt(0))));
f8ded1
+            } else {
f8ded1
+                CMS.debug(method + "attribute null");
f8ded1
+                return false;
f8ded1
+            }
f8ded1
 
f8ded1
             SET dias = msgData.getDigestAlgorithmIdentifiers();
f8ded1
             int numDig = dias.size();
f8ded1
             Hashtable<String, byte[]> digs = new Hashtable<String, byte[]>();
f8ded1
             for (int i = 0; i < numDig; i++) {
f8ded1
-                AlgorithmIdentifier dai =
f8ded1
-                        (AlgorithmIdentifier) dias.elementAt(i);
f8ded1
-                String name =
f8ded1
-                        DigestAlgorithm.fromOID(dai.getOID()).toString();
f8ded1
-                MessageDigest md =
f8ded1
-                        MessageDigest.getInstance(name);
f8ded1
+                AlgorithmIdentifier dai = (AlgorithmIdentifier) dias.elementAt(i);
f8ded1
+                String name = DigestAlgorithm.fromOID(dai.getOID()).toString();
f8ded1
+                MessageDigest md = MessageDigest.getInstance(name);
f8ded1
                 byte[] digest = md.digest(content.toByteArray());
f8ded1
                 digs.put(name, digest);
f8ded1
             }
f8ded1
@@ -1230,8 +1380,7 @@ public class CMCOutputTemplate {
f8ded1
             SET sis = msgData.getSignerInfos();
f8ded1
             int numSis = sis.size();
f8ded1
             for (int i = 0; i < numSis; i++) {
f8ded1
-                org.mozilla.jss.pkix.cms.SignerInfo si =
f8ded1
-                        (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(i);
f8ded1
+                org.mozilla.jss.pkix.cms.SignerInfo si = (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(i);
f8ded1
                 String name = si.getDigestAlgorithm().toString();
f8ded1
                 byte[] digest = digs.get(name);
f8ded1
                 if (digest == null) {
f8ded1
@@ -1242,17 +1391,15 @@ public class CMCOutputTemplate {
f8ded1
                 }
f8ded1
                 SignerIdentifier sid = si.getSignerIdentifier();
f8ded1
                 if (sid.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) {
f8ded1
-                    org.mozilla.jss.pkix.cms.IssuerAndSerialNumber issuerAndSerialNumber =
f8ded1
-                            sid.getIssuerAndSerialNumber();
f8ded1
+                    org.mozilla.jss.pkix.cms.IssuerAndSerialNumber issuerAndSerialNumber = sid
f8ded1
+                            .getIssuerAndSerialNumber();
f8ded1
                     java.security.cert.X509Certificate cert = null;
f8ded1
                     if (msgData.hasCertificates()) {
f8ded1
                         SET certs = msgData.getCertificates();
f8ded1
                         int numCerts = certs.size();
f8ded1
                         for (int j = 0; j < numCerts; j++) {
f8ded1
-                            org.mozilla.jss.pkix.cert.Certificate certJss =
f8ded1
-                                    (Certificate) certs.elementAt(j);
f8ded1
-                            org.mozilla.jss.pkix.cert.CertificateInfo certI =
f8ded1
-                                    certJss.getInfo();
f8ded1
+                            org.mozilla.jss.pkix.cert.Certificate certJss = (Certificate) certs.elementAt(j);
f8ded1
+                            org.mozilla.jss.pkix.cert.CertificateInfo certI = certJss.getInfo();
f8ded1
                             Name issuer = certI.getIssuer();
f8ded1
                             byte[] issuerB = ASN1Util.encode(issuer);
f8ded1
                             INTEGER sn = certI.getSerialNumber();
f8ded1
@@ -1268,11 +1415,33 @@ public class CMCOutputTemplate {
f8ded1
                     }
f8ded1
 
f8ded1
                     if (cert != null) {
f8ded1
+                        CMS.debug(method + "found cert");
f8ded1
                         PublicKey pbKey = cert.getPublicKey();
f8ded1
                         PK11PubKey pubK = PK11PubKey.fromSPKI(((X509Key) pbKey).getKey());
f8ded1
                         si.verify(digest, ci.getContentType(), pubK);
f8ded1
+
f8ded1
+                        // now check validity of the cert
f8ded1
+                        java.security.cert.X509Certificate[] x509Certs = new java.security.cert.X509Certificate[1];
f8ded1
+                        x509Certs[0] = cert;
f8ded1
+                        if (CMS.isRevoked(x509Certs)) {
f8ded1
+                            CMS.debug(method + "CMC signing cert is a revoked certificate");
f8ded1
+                            return false;
f8ded1
+                        }
f8ded1
+                        try {
f8ded1
+                            cert.checkValidity();
f8ded1
+                        } catch (CertificateExpiredException e) {
f8ded1
+                            CMS.debug(method + "CMC signing cert is an expired certificate");
f8ded1
+                            return false;
f8ded1
+                        } catch (Exception e) {
f8ded1
+                            return false;
f8ded1
+                        }
f8ded1
+
f8ded1
                         return true;
f8ded1
+                    } else {
f8ded1
+                        CMS.debug(method + "cert not found");
f8ded1
                     }
f8ded1
+                } else {
f8ded1
+                    CMS.debug(method + "unsupported SignerIdentifier for CMC revocation");
f8ded1
                 }
f8ded1
             }
f8ded1
 
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java b/base/server/cms/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java
f8ded1
index 83a2d8c..4578a98 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/servlet/common/GenPendingTemplateFiller.java
f8ded1
@@ -158,9 +158,9 @@ public class GenPendingTemplateFiller implements ICMSTemplateFiller {
f8ded1
                 byte[] dig;
f8ded1
 
f8ded1
                 try {
f8ded1
-                    MessageDigest SHA1Digest = MessageDigest.getInstance("SHA1");
f8ded1
+                    MessageDigest SHA2Digest = MessageDigest.getInstance("SHA256");
f8ded1
 
f8ded1
-                    dig = SHA1Digest.digest(salt.getBytes());
f8ded1
+                    dig = SHA2Digest.digest(salt.getBytes());
f8ded1
                 } catch (NoSuchAlgorithmException ex) {
f8ded1
                     dig = salt.getBytes();
f8ded1
                 }
f8ded1
@@ -199,16 +199,15 @@ public class GenPendingTemplateFiller implements ICMSTemplateFiller {
f8ded1
                     SignerIdentifier si = new
f8ded1
                             SignerIdentifier(SignerIdentifier.ISSUER_AND_SERIALNUMBER, ias, null);
f8ded1
 
f8ded1
-                    // SHA1 is the default digest Alg for now.
f8ded1
                     DigestAlgorithm digestAlg = null;
f8ded1
                     SignatureAlgorithm signAlg = null;
f8ded1
                     org.mozilla.jss.crypto.PrivateKey privKey = CryptoManager.getInstance().findPrivKeyByCert(x509cert);
f8ded1
                     org.mozilla.jss.crypto.PrivateKey.Type keyType = privKey.getType();
f8ded1
 
f8ded1
                     if (keyType.equals(org.mozilla.jss.crypto.PrivateKey.RSA)) {
f8ded1
-                        signAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest;
f8ded1
-                    } else if (keyType.equals(org.mozilla.jss.crypto.PrivateKey.DSA)) {
f8ded1
-                        signAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest;
f8ded1
+                        signAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest;
f8ded1
+                    } else if (keyType.equals(org.mozilla.jss.crypto.PrivateKey.EC)) {
f8ded1
+                        signAlg = SignatureAlgorithm.ECSignatureWithSHA256Digest;
f8ded1
                     } else {
f8ded1
                         CMS.debug("GenPendingTemplateFiller::getTemplateParams() - "
f8ded1
                                  + "keyType " + keyType.toString()
f8ded1
@@ -220,8 +219,8 @@ public class GenPendingTemplateFiller implements ICMSTemplateFiller {
f8ded1
                     byte[] digest = null;
f8ded1
 
f8ded1
                     try {
f8ded1
-                        SHADigest = MessageDigest.getInstance("SHA1");
f8ded1
-                        digestAlg = DigestAlgorithm.SHA1;
f8ded1
+                        SHADigest = MessageDigest.getInstance("SHA256");
f8ded1
+                        digestAlg = DigestAlgorithm.SHA256;
f8ded1
 
f8ded1
                         ByteArrayOutputStream ostream = new ByteArrayOutputStream();
f8ded1
 
f8ded1
diff --git a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
f8ded1
index 93039a4..330b5ff 100644
f8ded1
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
f8ded1
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
f8ded1
@@ -413,7 +413,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
f8ded1
         }
f8ded1
 
f8ded1
         setInputsIntoContext(request, profile, ctx);
f8ded1
-        CMS.debug("ProfileSubmistServlet: set Inputs into Context");
f8ded1
+        CMS.debug("ProfileSubmitCMCServlet: set Inputs into Context");
f8ded1
 
f8ded1
         // before creating the request, authenticate the request
f8ded1
 
f8ded1
@@ -560,9 +560,14 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
f8ded1
         // In case of decryptedPOP, request already exists, find it and
f8ded1
         // put in provedReq.
f8ded1
         IRequest provedReq = null;
f8ded1
+        boolean isRevoke = false;
f8ded1
         if (reqs == null) {
f8ded1
             // handling DecryptedPOP request here
f8ded1
             Integer reqID = (Integer) context.get("cmcDecryptedPopReqId");
f8ded1
+            if (reqID == null) {
f8ded1
+                CMS.debug("ProfileSubmitCMCServlet: revocation request");
f8ded1
+                isRevoke = true;
f8ded1
+            } else {
f8ded1
             provedReq = profile.getRequestQueue().findRequest(new RequestId(reqID.toString()));
f8ded1
             if (provedReq == null) {
f8ded1
 
f8ded1
@@ -584,6 +589,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
f8ded1
             } else {
f8ded1
                 CMS.debug("ProfileSubmitCMCServlet: provedReq not null");
f8ded1
             }
f8ded1
+            }
f8ded1
         }
f8ded1
 
f8ded1
         String errorCode = null;
f8ded1
@@ -592,7 +598,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
f8ded1
         ///////////////////////////////////////////////
f8ded1
         // populate request
f8ded1
         ///////////////////////////////////////////////
f8ded1
-        for (int k = 0; (provedReq == null) &&(k < reqs.length); k++) {
f8ded1
+        for (int k = 0; (!isRevoke) && (provedReq == null) &&(k < reqs.length); k++) {
f8ded1
             // adding parameters to request
f8ded1
             setInputsIntoRequest(request, profile, reqs[k]);
f8ded1
 
f8ded1
@@ -712,7 +718,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
f8ded1
             if (reqs != null && reqs.length > 0)
f8ded1
                 error_codes = new int[reqs.length];
f8ded1
 
f8ded1
-            for (int k = 0; (provedReq == null) && (k < reqs.length); k++) {
f8ded1
+            for (int k = 0; (!isRevoke) && (provedReq == null) && (k < reqs.length); k++) {
f8ded1
                 try {
f8ded1
                     // reset the "auditRequesterID"
f8ded1
                     auditRequesterID = auditRequesterID(reqs[k]);
f8ded1
diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
f8ded1
index 94a0783..b111f71 100644
f8ded1
--- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
f8ded1
+++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
f8ded1
@@ -62,6 +62,7 @@ import org.mozilla.jss.util.PasswordCallback;
f8ded1
 import org.w3c.dom.Element;
f8ded1
 import org.w3c.dom.NodeList;
f8ded1
 
f8ded1
+import com.netscape.certsrv.authentication.ISharedToken;
f8ded1
 import com.netscape.certsrv.acls.ACL;
f8ded1
 import com.netscape.certsrv.acls.ACLEntry;
f8ded1
 import com.netscape.certsrv.acls.EACLsException;
f8ded1
@@ -1912,6 +1913,38 @@ public class CMSEngine implements ICMSEngine {
f8ded1
         }
f8ded1
     }
f8ded1
 
f8ded1
+    public ISharedToken getSharedTokenClass(String configName) {
f8ded1
+        String method = "CMSEngine: getSharedTokenClass: ";
f8ded1
+        ISharedToken tokenClass = null;
f8ded1
+
f8ded1
+        String name = null;
f8ded1
+        try {
f8ded1
+            CMS.debug(method + "getting :" + configName);
f8ded1
+            name = CMS.getConfigStore().getString(configName);
f8ded1
+            CMS.debug(method + "Shared Secret plugin class name retrieved:" +
f8ded1
+                    name);
f8ded1
+        } catch (Exception e) {
f8ded1
+            CMS.debug(method + " Failed to retrieve shared secret plugin class name");
f8ded1
+            return null;
f8ded1
+        }
f8ded1
+
f8ded1
+        try {
f8ded1
+            tokenClass = (ISharedToken) Class.forName(name).newInstance();
f8ded1
+            CMS.debug(method + "Shared Secret plugin class retrieved");
f8ded1
+        } catch (ClassNotFoundException e) {
f8ded1
+            CMS.debug(method + " Failed to find class name: " + name);
f8ded1
+            return null;
f8ded1
+        } catch (InstantiationException e) {
f8ded1
+            CMS.debug("EnrollProfile: Failed to instantiate class: " + name);
f8ded1
+            return null;
f8ded1
+        } catch (IllegalAccessException e) {
f8ded1
+            CMS.debug(method + " Illegal access: " + name);
f8ded1
+            return null;
f8ded1
+        }
f8ded1
+
f8ded1
+        return tokenClass;
f8ded1
+    }
f8ded1
+
f8ded1
     public ILogger getLogger() {
f8ded1
         return Logger.getLogger();
f8ded1
     }
f8ded1
diff --git a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java
f8ded1
index dd28adb..b314dac 100644
f8ded1
--- a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java
f8ded1
+++ b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java
f8ded1
@@ -23,6 +23,7 @@ import com.netscape.certsrv.acls.EACLsException;
f8ded1
 import com.netscape.certsrv.acls.IACL;
f8ded1
 import com.netscape.certsrv.apps.ICMSEngine;
f8ded1
 import com.netscape.certsrv.apps.ICommandQueue;
f8ded1
+import com.netscape.certsrv.authentication.ISharedToken;
f8ded1
 import com.netscape.certsrv.authority.IAuthority;
f8ded1
 import com.netscape.certsrv.base.EBaseException;
f8ded1
 import com.netscape.certsrv.base.IArgBlock;
f8ded1
@@ -370,6 +371,10 @@ public class CMSEngineDefaultStub implements ICMSEngine {
f8ded1
         return null;
f8ded1
     }
f8ded1
 
f8ded1
+    public ISharedToken getSharedTokenClass(String configName) {
f8ded1
+        return null;
f8ded1
+    }
f8ded1
+
f8ded1
     public void putPasswordCache(String tag, String pw) {
f8ded1
     }
f8ded1
 
f8ded1
diff --git a/base/util/src/com/netscape/cmsutil/util/Utils.java b/base/util/src/com/netscape/cmsutil/util/Utils.java
f8ded1
index 98becdc..933432d 100644
f8ded1
--- a/base/util/src/com/netscape/cmsutil/util/Utils.java
f8ded1
+++ b/base/util/src/com/netscape/cmsutil/util/Utils.java
f8ded1
@@ -285,6 +285,11 @@ public class Utils {
f8ded1
         return string;
f8ded1
     }
f8ded1
 
f8ded1
+    public static String base64encodeSingleLine(byte[] bytes) {
f8ded1
+        String string = new Base64().encodeToString(bytes);
f8ded1
+        return string;
f8ded1
+    }
f8ded1
+ 
f8ded1
     public static byte[] base64decode(String string) {
f8ded1
         byte[] bytes = Base64.decodeBase64(string);
f8ded1
         return bytes;
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From 4328b770f8cbbb4c85919bc50201dff2e230dcc3 Mon Sep 17 00:00:00 2001
f8ded1
From: Ade Lee <alee@redhat.com>
f8ded1
Date: Thu, 8 Jun 2017 21:14:00 -0400
f8ded1
Subject: [PATCH 12/14] Add possible keywrap algorithms to usage
f8ded1
f8ded1
Added possible key wrap algorithms to the CRMFPopClient
f8ded1
usage statement to make it clear what options are available.
f8ded1
f8ded1
Part of BZ #1458047
f8ded1
f8ded1
Change-Id: Ie49ec9cd9bbb5c112668469f701363b967695ef3
f8ded1
---
f8ded1
 base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java | 2 ++
f8ded1
 1 file changed, 2 insertions(+)
f8ded1
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
index 25de2dd..0aaec28 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
@@ -228,6 +228,8 @@ public class CRMFPopClient {
f8ded1
         System.out.println("                               - POP_SUCCESS: with valid POP");
f8ded1
         System.out.println("                               - POP_FAIL: with invalid POP (for testing)");
f8ded1
         System.out.println("  -w <keywrap algorithm>       Algorithm to use for key wrapping");
f8ded1
+        System.out.println("                               - default: \"AES KeyWrap/Padding\"");
f8ded1
+        System.out.println("                               - \"AES/CBC/PKCS5Padding\"");
f8ded1
         System.out.println("  -b <transport cert>          PEM transport certificate (default: transport.txt)");
f8ded1
         System.out.println("  -v, --verbose                Run in verbose mode.");
f8ded1
         System.out.println("      --help                   Show help message.");
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From 9edd684fef78845acee95a766f34a9c57a1ab604 Mon Sep 17 00:00:00 2001
f8ded1
From: Ade Lee <alee@redhat.com>
f8ded1
Date: Thu, 8 Jun 2017 22:08:01 -0400
f8ded1
Subject: [PATCH 13/14] Add one more possible keywrap algorithm to usage
f8ded1
f8ded1
Added one more key wrap algorithms to the CRMFPopClient
f8ded1
usage statement.
f8ded1
f8ded1
Part of BZ #1458047
f8ded1
f8ded1
Change-Id: Ic52410a6a23f850944a6b96385b26a9bba12b51a
f8ded1
---
f8ded1
 base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java | 1 +
f8ded1
 1 file changed, 1 insertion(+)
f8ded1
f8ded1
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
index 0aaec28..66453c3 100644
f8ded1
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
f8ded1
@@ -230,6 +230,7 @@ public class CRMFPopClient {
f8ded1
         System.out.println("  -w <keywrap algorithm>       Algorithm to use for key wrapping");
f8ded1
         System.out.println("                               - default: \"AES KeyWrap/Padding\"");
f8ded1
         System.out.println("                               - \"AES/CBC/PKCS5Padding\"");
f8ded1
+        System.out.println("                               - \"DES3/CBC/Pad\"");
f8ded1
         System.out.println("  -b <transport cert>          PEM transport certificate (default: transport.txt)");
f8ded1
         System.out.println("  -v, --verbose                Run in verbose mode.");
f8ded1
         System.out.println("      --help                   Show help message.");
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1
f8ded1
f8ded1
From 53564487e46040a9115fba51c8403ecacb50187e Mon Sep 17 00:00:00 2001
f8ded1
From: Fraser Tweedale <ftweedal@redhat.com>
f8ded1
Date: Thu, 8 Jun 2017 14:25:23 +1000
f8ded1
Subject: [PATCH 14/14] KRA PKCS #12 export: add config to use 3DES PBE
f8ded1
 encryption
f8ded1
f8ded1
Restore the 3DES PKCS #12 key recovery code path, alongside the new
f8ded1
AES variant, which is broken on Thales nethsm.  Add the
f8ded1
'kra.legacyPKCS12' config for selecting which version to use, with
f8ded1
the default value of 'true' (i.e., use 3DES).
f8ded1
f8ded1
Part of: https://pagure.io/dogtagpki/issue/2728
f8ded1
f8ded1
Change-Id: Ic02fe8ba3a4c2c049913ff48d3f6dfdc830b4360
f8ded1
---
f8ded1
 base/kra/src/com/netscape/kra/RecoveryService.java | 43 ++++++++++++++++------
f8ded1
 1 file changed, 32 insertions(+), 11 deletions(-)
f8ded1
f8ded1
diff --git a/base/kra/src/com/netscape/kra/RecoveryService.java b/base/kra/src/com/netscape/kra/RecoveryService.java
f8ded1
index eee800a..023eb80 100644
f8ded1
--- a/base/kra/src/com/netscape/kra/RecoveryService.java
f8ded1
+++ b/base/kra/src/com/netscape/kra/RecoveryService.java
f8ded1
@@ -487,19 +487,40 @@ public class RecoveryService implements IService {
f8ded1
             PasswordConverter passConverter = new
f8ded1
                     PasswordConverter();
f8ded1
 
f8ded1
-            byte[] epkiBytes = ct.getCryptoStore().getEncryptedPrivateKeyInfo(
f8ded1
-                /* NSS has a bug that causes any AES CBC encryption
f8ded1
-                 * to use AES-256, but AlgorithmID contains chosen
f8ded1
-                 * alg.  To avoid mismatch, use AES_256_CBC. */
f8ded1
-                passConverter, pass, EncryptionAlgorithm.AES_256_CBC, 0, priKey);
f8ded1
-            CMS.debug("RecoverService: createPFX() getEncryptedPrivateKeyInfo() returned");
f8ded1
-            if (epkiBytes == null) {
f8ded1
-                CMS.debug("RecoverService: createPFX() epkiBytes null");
f8ded1
-                throw new EBaseException("getEncryptedPrivateKeyInfo returned null");
f8ded1
+            boolean legacyP12 =
f8ded1
+                CMS.getConfigStore().getBoolean("kra.legacyPKCS12", true);
f8ded1
+
f8ded1
+            ASN1Value key;
f8ded1
+            if (legacyP12) {
f8ded1
+                Random ran = new SecureRandom();
f8ded1
+                byte[] salt = new byte[20];
f8ded1
+                ran.nextBytes(salt);
f8ded1
+
f8ded1
+                key = EncryptedPrivateKeyInfo.createPBE(
f8ded1
+                        PBEAlgorithm.PBE_SHA1_DES3_CBC,
f8ded1
+                        pass, salt, 1, passConverter, priKey, ct);
f8ded1
+                CMS.debug("RecoverService: createPFX() EncryptedPrivateKeyInfo.createPBE() returned");
f8ded1
+                if (key == null) {
f8ded1
+                    CMS.debug("RecoverService: createPFX() key null");
f8ded1
+                    throw new EBaseException("EncryptedPrivateKeyInfo.createPBE() failed");
f8ded1
+                } else {
f8ded1
+                    CMS.debug("RecoverService: createPFX() key not null");
f8ded1
+                }
f8ded1
             } else {
f8ded1
-                CMS.debug("RecoverService: createPFX() epkiBytes not null");
f8ded1
+                byte[] epkiBytes = ct.getCryptoStore().getEncryptedPrivateKeyInfo(
f8ded1
+                    /* NSS has a bug that causes any AES CBC encryption
f8ded1
+                     * to use AES-256, but AlgorithmID contains chosen
f8ded1
+                     * alg.  To avoid mismatch, use AES_256_CBC. */
f8ded1
+                    passConverter, pass, EncryptionAlgorithm.AES_256_CBC, 0, priKey);
f8ded1
+                CMS.debug("RecoverService: createPFX() getEncryptedPrivateKeyInfo() returned");
f8ded1
+                if (epkiBytes == null) {
f8ded1
+                    CMS.debug("RecoverService: createPFX() epkiBytes null");
f8ded1
+                    throw new EBaseException("getEncryptedPrivateKeyInfo returned null");
f8ded1
+                } else {
f8ded1
+                    CMS.debug("RecoverService: createPFX() epkiBytes not null");
f8ded1
+                }
f8ded1
+                key = new ANY(epkiBytes);
f8ded1
             }
f8ded1
-            ASN1Value key = new ANY(epkiBytes);
f8ded1
 
f8ded1
             SET keyAttrs = createBagAttrs(
f8ded1
                     x509cert.getSubjectDN().toString(),
f8ded1
-- 
f8ded1
1.8.3.1
f8ded1