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