Blob Blame History Raw
From ee5af05036e87a9dad821c9dd8bc0198dac9bd65 Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Fri, 12 May 2017 13:00:54 -0600
Subject: [PATCH 01/27] Fix CA installation with HSM in FIPS mode

Bugzilla Bug #1450143 - CA installation with HSM in FIPS mode fails
dogtagpki Pagure Issue #2684 - CA installation with HSM in FIPS mode fails
---
 base/server/python/pki/server/deployment/pkihelper.py | 19 ++++++++++++++-----
 .../pki/server/deployment/scriptlets/finalization.py  |  3 ++-
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index 051778d..a1345de 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -1017,11 +1017,20 @@ class Instance:
                                  extra=config.PKI_INDENTATION_LEVEL_2)
             raise
 
-    def get_instance_status(self):
+    def get_instance_status(self, secure_connection=True):
+        pki_protocol = None
+        pki_port = None
+        if secure_connection:
+            pki_protocol = "https"
+            pki_port = self.mdict['pki_https_port']
+        else:
+            pki_protocol = "http"
+            pki_port = self.mdict['pki_http_port']
+
         connection = pki.client.PKIConnection(
-            protocol='https',
+            protocol=pki_protocol,
             hostname=self.mdict['pki_hostname'],
-            port=self.mdict['pki_https_port'],
+            port=pki_port,
             subsystem=self.mdict['pki_subsystem_type'],
             accept='application/xml',
             trust_env=False)
@@ -1049,11 +1058,11 @@ class Instance:
                 extra=config.PKI_INDENTATION_LEVEL_3)
             return None
 
-    def wait_for_startup(self, timeout):
+    def wait_for_startup(self, timeout, secure_connection=True):
         start_time = datetime.today()
         status = None
         while status != "running":
-            status = self.get_instance_status()
+            status = self.get_instance_status(secure_connection)
             time.sleep(1)
             stop_time = datetime.today()
             if (stop_time - start_time).total_seconds() >= timeout:
diff --git a/base/server/python/pki/server/deployment/scriptlets/finalization.py b/base/server/python/pki/server/deployment/scriptlets/finalization.py
index 941691c..75bb80e 100644
--- a/base/server/python/pki/server/deployment/scriptlets/finalization.py
+++ b/base/server/python/pki/server/deployment/scriptlets/finalization.py
@@ -58,7 +58,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         if config.str2bool(deployer.mdict['pki_restart_configured_instance']):
             deployer.systemd.restart()
             # wait for startup
-            status = deployer.instance.wait_for_startup(60)
+            # (must use 'http' protocol due to potential FIPS configuration)
+            status = deployer.instance.wait_for_startup(60, False)
             if status is None:
                 config.pki_log.error(
                     "server failed to restart",
-- 
1.8.3.1


From 4557cd497ecc3c753461617dd8f10067a3815042 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 16 May 2017 01:43:33 +0200
Subject: [PATCH 02/27] Added log messages for server shutdown.

Some log messages have been added to help troubleshoot the cause
of server shutdown.

Change-Id: Ie2a91647a0986fdb11cafed2aec48cce208ef1a2
---
 base/common/src/com/netscape/certsrv/apps/CMS.java                    | 4 ++++
 .../cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java       | 3 +++
 .../server/cms/src/com/netscape/cms/servlet/base/CMSStartServlet.java | 1 +
 .../cmscore/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java | 4 ++++
 4 files changed, 12 insertions(+)

diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java
index 8f1d648..cc634cc 100644
--- a/base/common/src/com/netscape/certsrv/apps/CMS.java
+++ b/base/common/src/com/netscape/certsrv/apps/CMS.java
@@ -1627,6 +1627,8 @@ public final class CMS {
             // Raidzilla Bug #57592:  Always print error message to stdout.
             System.out.println(e);
 
+            CMS.debug("CMS.start(): shutdown server");
+
             shutdown();
             throw e;
 
@@ -1722,6 +1724,8 @@ public final class CMS {
                         ILogger.LL_INFO,
                         "CMSEngine: Received shutdown signal");
 
+                CMS.debug("CMS.main(): shutdown server");
+
                 CMS.shutdown();
             };
         });
diff --git a/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java b/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
index e5a1474..f8bc34a 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
@@ -750,6 +750,7 @@ public final class CMSAdminServlet extends AdminServlet {
         if (stop != null) {
             //XXX Send response first then shutdown
             sendResponse(SUCCESS, null, params, resp);
+            CMS.debug("CMSAdminServlet.performTasks(): shutdown server");
             CMS.shutdown();
             return;
         }
@@ -3271,6 +3272,8 @@ public final class CMSAdminServlet extends AdminServlet {
                                     + "\n";
                             sendResponse(ERROR, content, null, resp);
 
+                            CMS.debug("CMSAdminServlet.runSelfTestsOnDemand(): shutdown server");
+
                             // shutdown the system gracefully
                             CMS.shutdown();
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/CMSStartServlet.java b/base/server/cms/src/com/netscape/cms/servlet/base/CMSStartServlet.java
index cfbf724..9609b06 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/base/CMSStartServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/base/CMSStartServlet.java
@@ -148,6 +148,7 @@ public class CMSStartServlet extends HttpServlet {
      * This method will be called when Tomcat is shutdown.
      */
     public void destroy() {
+        CMS.debug("CMSStartServlet.destroy(): shutdown server");
         CMS.shutdown();
     }
 }
diff --git a/base/server/cmscore/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
index 6ee3176..e1d6e15 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
@@ -547,6 +547,8 @@ public class SelfTestSubsystem
                                     "CMSCORE_SELFTESTS_RUN_ON_DEMAND_FAILED",
                                     instanceFullName));
 
+                    CMS.debug("SelfTestSubsystem.runSelfTestsOnDemand(): shutdown server");
+
                     // shutdown the system gracefully
                     CMS.shutdown();
 
@@ -1845,6 +1847,8 @@ public class SelfTestSubsystem
 
             audit(auditMessage);
 
+            CMS.debug("SelfTestSubsystem.startup(): shutdown server");
+
             // shutdown the system gracefully
             CMS.shutdown();
 
-- 
1.8.3.1


From 587cfa90b3b065f4c9c5bd0292202d5d9a4c2f54 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 25 Apr 2017 22:12:20 +0200
Subject: [PATCH 03/27] Simplified conditions to log CERT_REQUEST_PROCESSED.

The conditions to log CERT_REQUEST_PROCESSED have been simplified
since the auditInfoCertValue() will return SIGNED_AUDIT_EMPTY_VALUE
if the certificate object is not available in the request object.

https://pagure.io/dogtagpki/issue/2636

Change-Id: I946481c17729d2c349c949def113fc5563ec90ad
---
 .../logging/event/CertRequestProcessedEvent.java   |  2 +-
 .../netscape/cms/servlet/cert/CertProcessor.java   | 24 +++++------
 .../cms/servlet/connector/ConnectorServlet.java    | 47 +++++++++-------------
 .../servlet/profile/ProfileSubmitCMCServlet.java   | 44 +++++++++-----------
 4 files changed, 48 insertions(+), 69 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java b/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
index 777434b..a17f7d5 100644
--- a/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
@@ -96,7 +96,7 @@ public class CertRequestProcessedEvent extends AuditEvent {
      * @param x509cert an X509CertImpl
      * @return cert string containing the certificate
      */
-    public static String auditInfoCertValue(X509CertImpl x509cert) {
+    String auditInfoCertValue(X509CertImpl x509cert) {
 
         if (x509cert == null) {
             return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
index d25d817..1becd1b 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
@@ -246,21 +246,17 @@ public class CertProcessor extends CAProcessor {
                 req.setRequestStatus(RequestStatus.COMPLETE);
 
                 X509CertImpl x509cert = req.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
-                String auditInfoCertValue = CertRequestProcessedEvent.auditInfoCertValue(x509cert);
-
-                // TODO: simplify this condition
-                if (auditInfoCertValue != null) {
-                    if (!(auditInfoCertValue.equals(
-                            ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
-
-                        audit(new CertRequestProcessedEvent(
-                                auditSubjectID,
-                                ILogger.SUCCESS,
-                                auditRequesterID,
-                                ILogger.SIGNED_AUDIT_ACCEPTANCE,
-                                x509cert));
-                    }
+
+                if (x509cert != null) {
+
+                    audit(new CertRequestProcessedEvent(
+                            auditSubjectID,
+                            ILogger.SUCCESS,
+                            auditRequesterID,
+                            ILogger.SIGNED_AUDIT_ACCEPTANCE,
+                            x509cert));
                 }
+
             } catch (EDeferException e) {
                 // return defer message to the user
                 req.setRequestStatus(RequestStatus.PENDING);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
index b5ccdd2..eeb640e 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
@@ -620,40 +620,31 @@ public class ConnectorServlet extends CMSServlet {
                 if (isProfileRequest(thisreq)) {
 
                     X509CertImpl x509cert = thisreq.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
-                    String auditInfoCertValue = CertRequestProcessedEvent.auditInfoCertValue(x509cert);
-
-                    // TODO: simplify this condition
-                    if (auditInfoCertValue != null) {
-                        if (!(auditInfoCertValue.equals(
-                                   ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
-
-                            audit(new CertRequestProcessedEvent(
-                                    auditSubjectID,
-                                    ILogger.SUCCESS,
-                                    auditRequesterID,
-                                    ILogger.SIGNED_AUDIT_ACCEPTANCE,
-                                    x509cert));
-                        }
+
+                    if (x509cert != null) {
+
+                        audit(new CertRequestProcessedEvent(
+                                auditSubjectID,
+                                ILogger.SUCCESS,
+                                auditRequesterID,
+                                ILogger.SIGNED_AUDIT_ACCEPTANCE,
+                                x509cert));
                     }
                 }
+
             } catch (EBaseException eAudit1) {
                 if (isProfileRequest(thisreq)) {
 
                     X509CertImpl x509cert = thisreq.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
-                    String auditInfoCertValue = CertRequestProcessedEvent.auditInfoCertValue(x509cert);
-
-                    // TODO: simplify this condition
-                    if (auditInfoCertValue != null) {
-                        if (!(auditInfoCertValue.equals(
-                                   ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
-
-                            audit(new CertRequestProcessedEvent(
-                                    auditSubjectID,
-                                    ILogger.FAILURE,
-                                    auditRequesterID,
-                                    ILogger.SIGNED_AUDIT_ACCEPTANCE,
-                                    x509cert));
-                        }
+
+                    if (x509cert != null) {
+
+                        audit(new CertRequestProcessedEvent(
+                                auditSubjectID,
+                                ILogger.FAILURE,
+                                auditRequesterID,
+                                ILogger.SIGNED_AUDIT_ACCEPTANCE,
+                                x509cert));
                     }
                 }
 
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
index 1e128d0..0e101ed 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
@@ -696,21 +696,17 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
                     reqs[k].setRequestStatus(RequestStatus.COMPLETE);
 
                     X509CertImpl x509cert = reqs[k].getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
-                    String auditInfoCertValue = CertRequestProcessedEvent.auditInfoCertValue(x509cert);
-
-                    // TODO: simplify this condition
-                    if (auditInfoCertValue != null) {
-                        if (!(auditInfoCertValue.equals(
-                                    ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
-
-                            audit(new CertRequestProcessedEvent(
-                                        auditSubjectID,
-                                        ILogger.SUCCESS,
-                                        auditRequesterID,
-                                        ILogger.SIGNED_AUDIT_ACCEPTANCE,
-                                        x509cert));
-                        }
+
+                    if (x509cert != null) {
+
+                        audit(new CertRequestProcessedEvent(
+                                    auditSubjectID,
+                                    ILogger.SUCCESS,
+                                    auditRequesterID,
+                                    ILogger.SIGNED_AUDIT_ACCEPTANCE,
+                                    x509cert));
                     }
+
                 } catch (EDeferException e) {
                     // return defer message to the user
                     CMS.debug("ProfileSubmitCMCServlet: set request to PENDING");
@@ -794,21 +790,17 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
                     CMS.debug("ProfileSubmitCMCServlet: provedReq set to complete");
 
                     X509CertImpl x509cert = reqs[0].getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
-                    String auditInfoCertValue = CertRequestProcessedEvent.auditInfoCertValue(x509cert);
 
-                    // TODO: simplify this condition
-                    if (auditInfoCertValue != null) {
-                        if (!(auditInfoCertValue.equals(
-                                ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
+                    if (x509cert != null) {
 
-                            audit(new CertRequestProcessedEvent(
-                                    auditSubjectID,
-                                    ILogger.SUCCESS,
-                                    auditRequesterID,
-                                    ILogger.SIGNED_AUDIT_ACCEPTANCE,
-                                    x509cert));
-                        }
+                        audit(new CertRequestProcessedEvent(
+                                auditSubjectID,
+                                ILogger.SUCCESS,
+                                auditRequesterID,
+                                ILogger.SIGNED_AUDIT_ACCEPTANCE,
+                                x509cert));
                     }
+
                 } catch (ERejectException e) {
                     // return error to the user
                     provedReq.setRequestStatus(RequestStatus.REJECTED);
-- 
1.8.3.1


From 3abf731d9e6f02ac8d315978d31c28c2f9c85db9 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 26 Apr 2017 01:27:17 +0200
Subject: [PATCH 04/27] Added AuditEvent attributes.

The AuditEvent class has been modified to support variable number
of event attributes which can be used to generate more flexible
audit log entries.

https://pagure.io/dogtagpki/issue/2655

Change-Id: I565062bd7d635c0cbff0e6a7e71477648c9d3212
---
 .../com/netscape/certsrv/logging/AuditEvent.java   | 24 ++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
index 7a4aa9b..9ba9271 100644
--- a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
@@ -18,7 +18,9 @@
 package com.netscape.certsrv.logging;
 
 import java.text.MessageFormat;
+import java.util.LinkedHashMap;
 import java.util.Locale;
+import java.util.Map;
 
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.MessageFormatter;
@@ -265,6 +267,7 @@ public class AuditEvent implements IBundleLogEvent {
     private static final String INVALID_LOG_LEVEL = "log level: {0} is invalid, should be 0-6";
 
     protected Object mParams[] = null;
+    protected Map<String, Object> attributes = new LinkedHashMap<>();
 
     private String mEventType = null;
     private String mMessage = null;
@@ -574,4 +577,25 @@ public class AuditEvent implements IBundleLogEvent {
         } else
             return toContent();
     }
+
+    public void setAttribute(String name, Object value) {
+        attributes.put(name, value);
+    }
+
+    public String getAttributeList() {
+
+        StringBuilder sb = new StringBuilder();
+
+        for (String name : attributes.keySet()) {
+            Object value = attributes.get(name);
+
+            sb.append("[");
+            sb.append(name);
+            sb.append("=");
+            sb.append(value);
+            sb.append("]");
+        }
+
+        return sb.toString();
+    }
 }
-- 
1.8.3.1


From cec9efefe027ed4e7592827889eb3b487e7e485a Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 26 Apr 2017 20:04:46 +0200
Subject: [PATCH 05/27] Added ConfigTrustedPublicKeyEvent.

A new ConfigTrustedPublicKeyEvent class of has been added to
encapsulate the CONFIG_TRUSTED_PUBLIC_KEY events.

https://pagure.io/dogtagpki/issue/2641

Change-Id: I2fb4b46dfd63daf3c0c08dc08b3dbac9108ec908
---
 .../com/netscape/certsrv/logging/AuditEvent.java   |   2 -
 .../logging/event/ConfigTrustedPublicKeyEvent.java |  42 ++++
 .../cms/servlet/admin/CMSAdminServlet.java         | 218 +++++++--------------
 3 files changed, 114 insertions(+), 148 deletions(-)
 create mode 100644 base/common/src/com/netscape/certsrv/logging/event/ConfigTrustedPublicKeyEvent.java

diff --git a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
index 9ba9271..ff5d344 100644
--- a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
@@ -63,8 +63,6 @@ public class AuditEvent implements IBundleLogEvent {
             "LOGGING_SIGNED_AUDIT_CONFIG_SIGNED_AUDIT_3";
     public final static String CONFIG_ENCRYPTION =
             "LOGGING_SIGNED_AUDIT_CONFIG_ENCRYPTION_3";
-    public final static String CONFIG_TRUSTED_PUBLIC_KEY =
-            "LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY_3";
     public final static String CONFIG_DRM =
             "LOGGING_SIGNED_AUDIT_CONFIG_DRM_3";
     public final static String SELFTESTS_EXECUTION =
diff --git a/base/common/src/com/netscape/certsrv/logging/event/ConfigTrustedPublicKeyEvent.java b/base/common/src/com/netscape/certsrv/logging/event/ConfigTrustedPublicKeyEvent.java
new file mode 100644
index 0000000..b0dd781
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/event/ConfigTrustedPublicKeyEvent.java
@@ -0,0 +1,42 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2017 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.logging.event;
+
+import com.netscape.certsrv.logging.AuditEvent;
+
+public class ConfigTrustedPublicKeyEvent extends AuditEvent {
+
+    private static final long serialVersionUID = 1L;
+
+    public final static String LOGGING_PROPERTY =
+            "LOGGING_SIGNED_AUDIT_CONFIG_TRUSTED_PUBLIC_KEY_3";
+
+    public ConfigTrustedPublicKeyEvent(
+            String subjectID,
+            String outcome,
+            String params) {
+
+        super(LOGGING_PROPERTY);
+
+        setParameters(new Object[] {
+                subjectID,
+                outcome,
+                params
+        });
+    }
+}
diff --git a/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java b/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
index f8bc34a..8d28408 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/admin/CMSAdminServlet.java
@@ -62,6 +62,7 @@ import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
 import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
 import com.netscape.certsrv.logging.AuditEvent;
 import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.event.ConfigTrustedPublicKeyEvent;
 import com.netscape.certsrv.ocsp.IOCSPAuthority;
 import com.netscape.certsrv.ra.IRegistrationAuthority;
 import com.netscape.certsrv.security.ICryptoSubsystem;
@@ -1434,7 +1435,7 @@ public final class CMSAdminServlet extends AdminServlet {
     private void issueImportCert(HttpServletRequest req,
             HttpServletResponse resp) throws ServletException,
             IOException, EBaseException {
-        String auditMessage = null;
+
         String auditSubjectID = auditSubjectID();
 
         // ensure that any low-level exceptions are reported
@@ -1484,14 +1485,11 @@ public final class CMSAdminServlet extends AdminServlet {
                 nicknameWithoutTokenName = nickname.substring(index + 1);
                 oldtokenname = nickname.substring(0, index);
             } else {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 throw new EBaseException(CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
             }
@@ -1504,14 +1502,11 @@ public final class CMSAdminServlet extends AdminServlet {
             } else if (index > 0 && (index < (canickname.length() - 1))) {
                 canicknameWithoutTokenName = canickname.substring(index + 1);
             } else {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 throw new EBaseException(CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
             }
@@ -1524,14 +1519,11 @@ public final class CMSAdminServlet extends AdminServlet {
             KeyPair pair = null;
 
             if (nickname.equals("")) {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 throw new EBaseException(CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
             }
@@ -1771,40 +1763,30 @@ public final class CMSAdminServlet extends AdminServlet {
             properties.clear();
             properties = null;
 
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.SUCCESS,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             mConfig.commit(true);
             sendResponse(SUCCESS, null, null, resp);
         } catch (EBaseException eAudit1) {
             CMS.debug("CMSAdminServlet: issueImportCert: EBaseException thrown: " + eAudit1.toString());
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit1;
         } catch (IOException eAudit2) {
             CMS.debug("CMSAdminServlet: issueImportCert: IOException thrown: " + eAudit2.toString());
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit2;
@@ -1890,14 +1872,11 @@ public final class CMSAdminServlet extends AdminServlet {
             try {
                 if (pkcs == null || pkcs.equals("")) {
                     if (certpath == null || certpath.equals("")) {
-                        // store a message in the signed audit log file
-                        auditMessage = CMS.getLogMessage(
-                                AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                        audit(new ConfigTrustedPublicKeyEvent(
                                 auditSubjectID,
                                 ILogger.FAILURE,
-                                auditParams(req));
-
-                        audit(auditMessage);
+                                auditParams(req)));
 
                         EBaseException ex = new EBaseException(
                                 CMS.getLogMessage("BASE_INVALID_FILE_PATH"));
@@ -1924,14 +1903,11 @@ public final class CMSAdminServlet extends AdminServlet {
                     }
                 }
             } catch (IOException ee) {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 throw new EBaseException(
                         CMS.getLogMessage("BASE_OPEN_FILE_FAILED"));
@@ -1954,14 +1930,11 @@ public final class CMSAdminServlet extends AdminServlet {
                 tokenName = nickname.substring(0, index);
                 nicknameWithoutTokenName = nickname.substring(index + 1);
             } else {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 throw new EBaseException(
                         CMS.getLogMessage("BASE_CERT_NOT_FOUND"));
@@ -2203,14 +2176,10 @@ public final class CMSAdminServlet extends AdminServlet {
                 audit(auditMessage);
             }
 
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.SUCCESS,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             mConfig.commit(true);
             if (verified == true) {
@@ -2220,26 +2189,20 @@ public final class CMSAdminServlet extends AdminServlet {
                         null, resp);
             }
         } catch (EBaseException eAudit1) {
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit1;
         } catch (IOException eAudit2) {
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit2;
@@ -2275,7 +2238,7 @@ public final class CMSAdminServlet extends AdminServlet {
     private void importXCert(HttpServletRequest req,
             HttpServletResponse resp) throws ServletException,
             IOException, EBaseException {
-        String auditMessage = null;
+
         String auditSubjectID = auditSubjectID();
 
         // ensure that any low-level exceptions are reported
@@ -2309,14 +2272,11 @@ public final class CMSAdminServlet extends AdminServlet {
             try {
                 if (b64Cert == null || b64Cert.equals("")) {
                     if (certpath == null || certpath.equals("")) {
-                        // store a message in the signed audit log file
-                        auditMessage = CMS.getLogMessage(
-                                AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                        audit(new ConfigTrustedPublicKeyEvent(
                                 auditSubjectID,
                                 ILogger.FAILURE,
-                                auditParams(req));
-
-                        audit(auditMessage);
+                                auditParams(req)));
 
                         EBaseException ex = new EBaseException(
                                 CMS.getLogMessage("BASE_INVALID_FILE_PATH"));
@@ -2342,14 +2302,11 @@ public final class CMSAdminServlet extends AdminServlet {
                     }
                 }
             } catch (IOException ee) {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 throw new EBaseException(
                         CMS.getLogMessage("BASE_OPEN_FILE_FAILED"));
@@ -2376,14 +2333,11 @@ public final class CMSAdminServlet extends AdminServlet {
                 //this will import into internal ldap crossCerts entry
                 ccps.importCert(bCert);
             } catch (Exception e) {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 sendResponse(1, "xcert importing failure:" + e.toString(),
                              null, resp);
@@ -2395,14 +2349,11 @@ public final class CMSAdminServlet extends AdminServlet {
                 // db to publishing directory, if turned on
                 ccps.publishCertPairs();
             } catch (EBaseException e) {
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+                audit(new ConfigTrustedPublicKeyEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
-                            auditParams(req));
-
-                audit(auditMessage);
+                            auditParams(req)));
 
                 sendResponse(1, "xcerts publishing failure:" + e.toString(), null, resp);
                 return;
@@ -2416,37 +2367,27 @@ public final class CMSAdminServlet extends AdminServlet {
             results.put(Constants.PR_NICKNAME, "FBCA cross-signed cert");
             results.put(Constants.PR_CERT_CONTENT, content);
 
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.SUCCESS,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             sendResponse(SUCCESS, null, results, resp);
         } catch (EBaseException eAudit1) {
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit1;
         } catch (IOException eAudit2) {
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit2;
@@ -2929,7 +2870,7 @@ public final class CMSAdminServlet extends AdminServlet {
     public void setRootCertTrust(HttpServletRequest req,
             HttpServletResponse resp) throws ServletException,
             IOException, EBaseException {
-        String auditMessage = null;
+
         String auditSubjectID = auditSubjectID();
         String nickname = req.getParameter(Constants.PR_NICK_NAME);
         String serialno = req.getParameter(Constants.PR_SERIAL_NUMBER);
@@ -2943,25 +2884,20 @@ public final class CMSAdminServlet extends AdminServlet {
         try {
             jssSubSystem.setRootCertTrust(nickname, serialno, issuername, trust);
         } catch (EBaseException e) {
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
+                        auditParams(req)));
 
-            audit(auditMessage);
             // rethrow the specific exception to be handled later
             throw e;
         }
 
-        // store a message in the signed audit log file
-        auditMessage = CMS.getLogMessage(
-                    AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+        audit(new ConfigTrustedPublicKeyEvent(
                     auditSubjectID,
                     ILogger.SUCCESS,
-                    auditParams(req));
-
-        audit(auditMessage);
+                    auditParams(req)));
 
         sendResponse(SUCCESS, null, null, resp);
     }
@@ -2982,7 +2918,7 @@ public final class CMSAdminServlet extends AdminServlet {
     private void trustCACert(HttpServletRequest req,
             HttpServletResponse resp) throws ServletException,
             IOException, EBaseException {
-        String auditMessage = null;
+
         String auditSubjectID = auditSubjectID();
 
         CMS.debug("CMSAdminServlet: trustCACert()");
@@ -3010,38 +2946,28 @@ public final class CMSAdminServlet extends AdminServlet {
                 }
             }
 
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.SUCCESS,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             //sendResponse(SUCCESS, null, null, resp);
             sendResponse(RESTART, null, null, resp);
         } catch (EBaseException eAudit1) {
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit1;
         } catch (IOException eAudit2) {
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        AuditEvent.CONFIG_TRUSTED_PUBLIC_KEY,
+
+            audit(new ConfigTrustedPublicKeyEvent(
                         auditSubjectID,
                         ILogger.FAILURE,
-                        auditParams(req));
-
-            audit(auditMessage);
+                        auditParams(req)));
 
             // rethrow the specific exception to be handled later
             throw eAudit2;
-- 
1.8.3.1


From 439ee21719064e60fb691c48aafdbc7fa722c8b7 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 26 Apr 2017 01:32:12 +0200
Subject: [PATCH 06/27] Refactored CertRequestProcessedEvent to use AuditEvent
 attributes.

The CertRequestProcessedEvent constructors have been modified to
log the info attributes using the new AuditEvent attributes.

The logging property for CERT_REQUEST_PROCESSED event has been
modified to accept a list of attributes as a single string instead
of individual info attributes.

The CERT_REQUEST_PROCESSED constant in AuditEvent has been replaced
with a constant in CertRequestProcessedEvent class which points to
the new logging property.

https://pagure.io/dogtagpki/issue/2655

Change-Id: I981212af7fca58916c73ccdeba9919a4d051af3c
---
 .../com/netscape/certsrv/logging/AuditEvent.java   |  2 --
 .../logging/event/CertRequestProcessedEvent.java   | 27 ++++++++++++++--------
 base/server/cmsbundle/src/LogMessages.properties   |  2 +-
 3 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
index ff5d344..523b204 100644
--- a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
@@ -103,8 +103,6 @@ public class AuditEvent implements IBundleLogEvent {
             "LOGGING_SIGNED_AUDIT_NON_PROFILE_CERT_REQUEST_5";
     public final static String PROFILE_CERT_REQUEST =
             "LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST_5";
-    public final static String CERT_REQUEST_PROCESSED =
-            "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
     public final static String CERT_STATUS_CHANGE_REQUEST =
             "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
     public final static String CERT_STATUS_CHANGE_REQUEST_PROCESSED =
diff --git a/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java b/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
index a17f7d5..5155672 100644
--- a/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
@@ -30,6 +30,9 @@ public class CertRequestProcessedEvent extends AuditEvent {
 
     private static final long serialVersionUID = 1L;
 
+    private final static String LOGGING_PROPERTY =
+            "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED";
+
     public final static String SIGNED_AUDIT_CERT_REQUEST_REASON = "requestNotes";
 
     public CertRequestProcessedEvent(
@@ -39,14 +42,16 @@ public class CertRequestProcessedEvent extends AuditEvent {
             String infoName,
             String infoValue) {
 
-        super(CERT_REQUEST_PROCESSED);
+        super(LOGGING_PROPERTY);
+
+        setAttribute("InfoName", infoName);
+        setAttribute("InfoValue", infoValue);
 
         setParameters(new Object[] {
                 subjectID,
                 outcome,
                 requesterID,
-                infoName,
-                infoValue
+                getAttributeList()
         });
     }
 
@@ -57,14 +62,16 @@ public class CertRequestProcessedEvent extends AuditEvent {
             String infoName,
             X509CertImpl x509cert) {
 
-        super(CERT_REQUEST_PROCESSED);
+        super(LOGGING_PROPERTY);
+
+        setAttribute("InfoName", infoName);
+        setAttribute("InfoValue", auditInfoCertValue(x509cert));
 
         setParameters(new Object[] {
                 subjectID,
                 outcome,
                 requesterID,
-                infoName,
-                auditInfoCertValue(x509cert)
+                getAttributeList()
         });
     }
 
@@ -75,14 +82,16 @@ public class CertRequestProcessedEvent extends AuditEvent {
             String infoName,
             IRequest request) {
 
-        super(CERT_REQUEST_PROCESSED);
+        super(LOGGING_PROPERTY);
+
+        setAttribute("InfoName", infoName);
+        setAttribute("InfoValue", auditInfoValue(request));
 
         setParameters(new Object[] {
                 subjectID,
                 outcome,
                 requesterID,
-                infoName,
-                auditInfoValue(request)
+                getAttributeList()
         });
     }
 
diff --git a/base/server/cmsbundle/src/LogMessages.properties b/base/server/cmsbundle/src/LogMessages.properties
index d3ac06a..1a5b37a 100644
--- a/base/server/cmsbundle/src/LogMessages.properties
+++ b/base/server/cmsbundle/src/LogMessages.properties
@@ -2088,7 +2088,7 @@ LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST_5=<type=PROFILE_CERT_REQUEST>:[AuditEv
 # InfoValue must contain the certificate (in case of success), a reject reason in
 #        text, or a cancel reason in text
 #
-LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5=<type=CERT_REQUEST_PROCESSED>:[AuditEvent=CERT_REQUEST_PROCESSED][SubjectID={0}][Outcome={1}][ReqID={2}][InfoName={3}][InfoValue={4}] certificate request processed
+LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED=<type=CERT_REQUEST_PROCESSED>:[AuditEvent=CERT_REQUEST_PROCESSED][SubjectID={0}][Outcome={1}][ReqID={2}]{3} certificate request processed
 #
 # LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST
 # - used when a certificate status change request (e.g. revocation)
-- 
1.8.3.1


From 3edee861f0f31910020825a4bdc18f36017b6a26 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 26 Apr 2017 02:02:34 +0200
Subject: [PATCH 07/27] Added certificate serial number for
 CERT_REQUEST_PROCESSED.

The CertRequestProcessedEvent constructor that takes a certificate
object was modified to log the certificate serial number instead of
the base64-encoded certificate data.

https://pagure.io/dogtagpki/issue/2655

Change-Id: I67f33a7d435d0e5accdb646bdd20bae99d123472
---
 .../com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java  | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java b/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
index 5155672..d095ab6 100644
--- a/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/event/CertRequestProcessedEvent.java
@@ -64,8 +64,7 @@ public class CertRequestProcessedEvent extends AuditEvent {
 
         super(LOGGING_PROPERTY);
 
-        setAttribute("InfoName", infoName);
-        setAttribute("InfoValue", auditInfoCertValue(x509cert));
+        setAttribute("CertSerialNum", x509cert.getSerialNumber());
 
         setParameters(new Object[] {
                 subjectID,
-- 
1.8.3.1


From 641180a465d7fdf12a978c9c458e39bf6829cac2 Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Tue, 16 May 2017 12:58:17 -0600
Subject: [PATCH 08/27] Added FIPS class to pkispawn

Bugzilla Bug #1450143 - CA installation with HSM in FIPS mode fails
dogtagpki Pagure Issue #2684 - CA installation with HSM in FIPS mode fails
---
 .../python/pki/server/deployment/__init__.py       |  2 ++
 .../python/pki/server/deployment/pkihelper.py      | 41 ++++++++++++++++++++++
 .../python/pki/server/deployment/pkimessages.py    |  4 +++
 .../server/deployment/scriptlets/finalization.py   | 10 ++++--
 base/server/sbin/pkispawn                          | 10 ++++++
 5 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/base/server/python/pki/server/deployment/__init__.py b/base/server/python/pki/server/deployment/__init__.py
index 3d719de..709fe70 100644
--- a/base/server/python/pki/server/deployment/__init__.py
+++ b/base/server/python/pki/server/deployment/__init__.py
@@ -55,6 +55,7 @@ class PKIDeployer:
         self.symlink = None
         self.war = None
         self.password = None
+        self.fips = None
         self.hsm = None
         self.certutil = None
         self.modutil = None
@@ -99,6 +100,7 @@ class PKIDeployer:
         self.symlink = util.Symlink(self)
         self.war = util.War(self)
         self.password = util.Password(self)
+        self.fips = util.FIPS(self)
         self.hsm = util.HSM(self)
         self.certutil = util.Certutil(self)
         self.modutil = util.Modutil(self)
diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index a1345de..cf2a748 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -2172,6 +2172,47 @@ class Password:
         return token_pwd
 
 
+class FIPS:
+    """PKI Deployment FIPS class"""
+
+    def __init__(self, deployer):
+        self.mdict = deployer.mdict
+
+    def is_fips_enabled(self, critical_failure=False):
+        try:
+            # Always initialize FIPS mode as NOT enabled
+            self.mdict['pki_fips_mode_enabled'] = False
+
+            # Check to see if FIPS is enabled on this system
+            command = ["sysctl", "crypto.fips_enabled", "-bn"]
+
+            # Execute this "sysctl" command.
+            with open(os.devnull, "w") as fnull:
+                output = subprocess.check_output(command, stderr=fnull,
+                                                 close_fds=True)
+                if (output != "0"):
+                    # Set FIPS mode as enabled
+                    self.mdict['pki_fips_mode_enabled'] = True
+                    config.pki_log.info(log.PKIHELPER_FIPS_MODE_IS_ENABLED,
+                                        extra=config.PKI_INDENTATION_LEVEL_3)
+                    return True
+                else:
+                    config.pki_log.info(log.PKIHELPER_FIPS_MODE_IS_NOT_ENABLED,
+                                        extra=config.PKI_INDENTATION_LEVEL_3)
+                    return False
+        except subprocess.CalledProcessError as exc:
+            config.pki_log.error(log.PKI_SUBPROCESS_ERROR_1, exc,
+                                 extra=config.PKI_INDENTATION_LEVEL_2)
+            if critical_failure:
+                raise
+        except OSError as exc:
+            config.pki_log.error(log.PKI_OSERROR_1, exc,
+                                 extra=config.PKI_INDENTATION_LEVEL_2)
+            if critical_failure:
+                raise
+        return False
+
+
 class HSM:
     """PKI Deployment HSM class"""
 
diff --git a/base/server/python/pki/server/deployment/pkimessages.py b/base/server/python/pki/server/deployment/pkimessages.py
index c8821bb..52c8e62 100644
--- a/base/server/python/pki/server/deployment/pkimessages.py
+++ b/base/server/python/pki/server/deployment/pkimessages.py
@@ -222,6 +222,10 @@ PKIHELPER_GROUP_ADD_2 = "adding GID '%s' for group '%s' . . ."
 PKIHELPER_GROUP_ADD_DEFAULT_2 = "adding default GID '%s' for group '%s' . . ."
 PKIHELPER_GROUP_ADD_GID_KEYERROR_1 = "KeyError:  pki_gid %s"
 PKIHELPER_GROUP_ADD_KEYERROR_1 = "KeyError:  pki_group %s"
+PKIHELPER_FIPS_MODE_IS_ENABLED = "FIPS mode is enabled on this operating "\
+    "system."
+PKIHELPER_FIPS_MODE_IS_NOT_ENABLED = "FIPS mode is NOT enabled on this "\
+    "operating system."
 PKIHELPER_HSM_CLONES_MUST_SHARE_HSM_MASTER_PRIVATE_KEYS = \
     "Since clones using Hardware Security Modules (HSMs) must share their "\
     "master's private keys, the 'pki_clone_pkcs12_path' and "\
diff --git a/base/server/python/pki/server/deployment/scriptlets/finalization.py b/base/server/python/pki/server/deployment/scriptlets/finalization.py
index 75bb80e..ef750b9 100644
--- a/base/server/python/pki/server/deployment/scriptlets/finalization.py
+++ b/base/server/python/pki/server/deployment/scriptlets/finalization.py
@@ -58,8 +58,14 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         if config.str2bool(deployer.mdict['pki_restart_configured_instance']):
             deployer.systemd.restart()
             # wait for startup
-            # (must use 'http' protocol due to potential FIPS configuration)
-            status = deployer.instance.wait_for_startup(60, False)
+            status = None
+            if deployer.fips.is_fips_enabled():
+                # must use 'http' protocol when FIPS mode is enabled
+                status = deployer.instance.wait_for_startup(
+                    60, secure_connection=False)
+            else:
+                status = deployer.instance.wait_for_startup(
+                    60, secure_connection=True)
             if status is None:
                 config.pki_log.error(
                     "server failed to restart",
diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn
index e6e337b..9394b8e 100755
--- a/base/server/sbin/pkispawn
+++ b/base/server/sbin/pkispawn
@@ -756,6 +756,16 @@ def print_final_install_information(mdict):
               "      is a clone." %
               (deployer.subsystem_name, mdict['pki_instance_name']))
 
+    if mdict['pki_fips_mode_enabled']:
+        print()
+        print("      This %s subsystem of the '%s' instance\n"
+              "      has FIPS mode enabled on this operating system." %
+              (deployer.subsystem_name, mdict['pki_instance_name']))
+        print()
+        print("      REMINDER:  Don't forget to update the appropriate FIPS\n"
+              "                 algorithms in server.xml in the '%s' instance."
+              % mdict['pki_instance_name'])
+
     print(log.PKI_CHECK_STATUS_MESSAGE % mdict['pki_instance_name'])
     print(log.PKI_INSTANCE_RESTART_MESSAGE % mdict['pki_instance_name'])
 
-- 
1.8.3.1


From dcbe7ce08fcf9512a6cf1ecf22ed080c0085e28a Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 02:53:59 +0200
Subject: [PATCH 10/27] Fixed audit event outcome for agent-rejected cert
 request.

The outcome of CERT_REQUEST_PROCESSED event has been changed to
Failure when the certificate request is rejected by an agent.

https://pagure.io/dogtagpki/issue/2693

Change-Id: I530de4fe08ba97a8676d56a6aaf6c11ab7c36e40
---
 base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
index 4494d2c..d8d8803 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
@@ -311,7 +311,7 @@ public class RequestProcessor extends CertProcessor {
 
         audit(new CertRequestProcessedEvent(
                 auditSubjectID,
-                ILogger.SUCCESS,
+                ILogger.FAILURE,
                 auditRequesterID,
                 ILogger.SIGNED_AUDIT_REJECTION,
                 req));
-- 
1.8.3.1


From e54873d6dbb95e82632f888b90dc6d0d7836ad4d Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 17:43:00 +0200
Subject: [PATCH 11/27] Fixed audit event outcome for agent-canceled cert
 request.

The outcome of CERT_REQUEST_PROCESSED event has been changed to
Failure when the certificate request is canceled by an agent.

https://pagure.io/dogtagpki/issue/2694

Change-Id: Iad25a135851188cc97106d81800e3b8443a2970a
---
 base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
index d8d8803..df5aae0 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/RequestProcessor.java
@@ -281,7 +281,7 @@ public class RequestProcessor extends CertProcessor {
 
         audit(new CertRequestProcessedEvent(
                 auditSubjectID,
-                ILogger.SUCCESS,
+                ILogger.FAILURE,
                 auditRequesterID,
                 ILogger.SIGNED_AUDIT_CANCELLATION,
                 req));
-- 
1.8.3.1


From c6ed9679acba5d0072a16878ecf98e0843ab6a3a Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 19:25:20 +0200
Subject: [PATCH 12/27] Refactored UpdateCRL.process() (part 1).

The UpdateCRL.process() has been refactored to reduce deeply
nested if-statements with early return.

https://pagure.io/dogtagpki/issue/2651

Change-Id: I507bf72e28c3ba0ab98f24466bac2a40f1e6b198
---
 base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
index d873b1a..1182922 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
@@ -331,7 +331,11 @@ public class UpdateCRL extends CMSServlet {
         header.addStringValue("crlIssuingPoint", crlIssuingPointId);
         IPublisherProcessor lpm = mCA.getPublisherProcessor();
 
-        if (crlIssuingPoint != null) {
+        if (crlIssuingPoint == null) {
+            CMS.debug("UpdateCRL: no CRL issuing point");
+            return;
+        }
+
             if (clearCache != null && clearCache.equals("true") &&
                     crlIssuingPoint.isCRLGenerationEnabled() &&
                     crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
@@ -523,7 +527,5 @@ public class UpdateCRL extends CMSServlet {
                     header.addStringValue("crlUpdate", "Scheduled");
                 }
             }
-        }
-        return;
     }
 }
-- 
1.8.3.1


From 69d5dc82f8664d1eb5dfcdcec615088127c0ad97 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 19:40:51 +0200
Subject: [PATCH 13/27] Refactored UpdateCRL.process() (part 2).

The UpdateCRL.process() has been refactored to reduce deeply
nested if-statements with early return.

https://pagure.io/dogtagpki/issue/2651

Change-Id: I5591bf08e617614ca7def5ce5fff61e0925e4fc5
---
 .../com/netscape/cms/servlet/cert/UpdateCRL.java   | 32 +++++++++++-----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
index 1182922..8669361 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
@@ -343,11 +343,25 @@ public class UpdateCRL extends CMSServlet {
                                 == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
                 crlIssuingPoint.clearCRLCache();
             }
-            if (waitForUpdate != null && waitForUpdate.equals("true") &&
+            if (!(waitForUpdate != null && waitForUpdate.equals("true") &&
                     crlIssuingPoint.isCRLGenerationEnabled() &&
                     crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
                     crlIssuingPoint.isCRLIssuingPointInitialized()
-                                == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+                                == ICRLIssuingPoint.CRL_IP_INITIALIZED)) {
+                if (crlIssuingPoint.isCRLIssuingPointInitialized() != ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+                    header.addStringValue("crlUpdate", "notInitialized");
+                } else if (crlIssuingPoint.isCRLUpdateInProgress()
+                           != ICRLIssuingPoint.CRL_UPDATE_DONE ||
+                           crlIssuingPoint.isManualUpdateSet()) {
+                    header.addStringValue("crlUpdate", "inProgress");
+                } else if (!crlIssuingPoint.isCRLGenerationEnabled()) {
+                    header.addStringValue("crlUpdate", "Disabled");
+                } else {
+                    crlIssuingPoint.setManualUpdate(signatureAlgorithm);
+                    header.addStringValue("crlUpdate", "Scheduled");
+                }
+                return;
+            }
                 if (test != null && test.equals("true") &&
                         crlIssuingPoint.isCRLCacheTestingEnabled() &&
                         (!mTesting.contains(crlIssuingPointId))) {
@@ -513,19 +527,5 @@ public class UpdateCRL extends CMSServlet {
                         }
                     }
                 }
-            } else {
-                if (crlIssuingPoint.isCRLIssuingPointInitialized() != ICRLIssuingPoint.CRL_IP_INITIALIZED) {
-                    header.addStringValue("crlUpdate", "notInitialized");
-                } else if (crlIssuingPoint.isCRLUpdateInProgress()
-                           != ICRLIssuingPoint.CRL_UPDATE_DONE ||
-                           crlIssuingPoint.isManualUpdateSet()) {
-                    header.addStringValue("crlUpdate", "inProgress");
-                } else if (!crlIssuingPoint.isCRLGenerationEnabled()) {
-                    header.addStringValue("crlUpdate", "Disabled");
-                } else {
-                    crlIssuingPoint.setManualUpdate(signatureAlgorithm);
-                    header.addStringValue("crlUpdate", "Scheduled");
-                }
-            }
     }
 }
-- 
1.8.3.1


From ce9e6f1704d6c821429faafc778358202e1a233e Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 19:43:06 +0200
Subject: [PATCH 14/27] Refactored UpdateCRL.process() (part 3).

The UpdateCRL.process() has been refactored to reduce deeply
nested if-statements with early return.

https://pagure.io/dogtagpki/issue/2651

Change-Id: Ie3aa5f9154eec78e994cf89cc33616d2c5cbaf47
---
 base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
index 8669361..ca4a5bf 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
@@ -436,14 +436,17 @@ public class UpdateCRL extends CMSServlet {
 
                     mTesting.remove(crlIssuingPointId);
                     CMS.debug("CRL test finished.");
+                    return;
                 } else if (test != null && test.equals("true") &&
                            crlIssuingPoint.isCRLCacheTestingEnabled() &&
                            mTesting.contains(crlIssuingPointId)) {
                     header.addStringValue("crlUpdate", "testingInProgress");
+                    return;
                 } else if (test != null && test.equals("true") &&
                            (!crlIssuingPoint.isCRLCacheTestingEnabled())) {
                     header.addStringValue("crlUpdate", "testingNotEnabled");
-                } else {
+                    return;
+                }
                     try {
                         EBaseException publishError = null;
 
@@ -526,6 +529,5 @@ public class UpdateCRL extends CMSServlet {
                             throw e;
                         }
                     }
-                }
     }
 }
-- 
1.8.3.1


From 75f588c291c1ab27e1e2b4edaa4c254a8bbc21a2 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 19:45:39 +0200
Subject: [PATCH 15/27] Reformatted UpdateCRL.process().

The UpdateCRL.process() has been reformatted to adjust the
indentations after refactoring.

https://pagure.io/dogtagpki/issue/2651

Change-Id: Ic67376678d442b9e2a79f9375aef61eab99d1b5c
---
 .../com/netscape/cms/servlet/cert/UpdateCRL.java   | 348 ++++++++++-----------
 1 file changed, 174 insertions(+), 174 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
index ca4a5bf..7faecf1 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
@@ -336,198 +336,198 @@ public class UpdateCRL extends CMSServlet {
             return;
         }
 
-            if (clearCache != null && clearCache.equals("true") &&
-                    crlIssuingPoint.isCRLGenerationEnabled() &&
-                    crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
-                    crlIssuingPoint.isCRLIssuingPointInitialized()
-                                == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
-                crlIssuingPoint.clearCRLCache();
+        if (clearCache != null && clearCache.equals("true") &&
+                crlIssuingPoint.isCRLGenerationEnabled() &&
+                crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
+                crlIssuingPoint.isCRLIssuingPointInitialized()
+                            == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+            crlIssuingPoint.clearCRLCache();
+        }
+        if (!(waitForUpdate != null && waitForUpdate.equals("true") &&
+                crlIssuingPoint.isCRLGenerationEnabled() &&
+                crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
+                crlIssuingPoint.isCRLIssuingPointInitialized()
+                            == ICRLIssuingPoint.CRL_IP_INITIALIZED)) {
+            if (crlIssuingPoint.isCRLIssuingPointInitialized() != ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+                header.addStringValue("crlUpdate", "notInitialized");
+            } else if (crlIssuingPoint.isCRLUpdateInProgress()
+                       != ICRLIssuingPoint.CRL_UPDATE_DONE ||
+                       crlIssuingPoint.isManualUpdateSet()) {
+                header.addStringValue("crlUpdate", "inProgress");
+            } else if (!crlIssuingPoint.isCRLGenerationEnabled()) {
+                header.addStringValue("crlUpdate", "Disabled");
+            } else {
+                crlIssuingPoint.setManualUpdate(signatureAlgorithm);
+                header.addStringValue("crlUpdate", "Scheduled");
             }
-            if (!(waitForUpdate != null && waitForUpdate.equals("true") &&
-                    crlIssuingPoint.isCRLGenerationEnabled() &&
-                    crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
-                    crlIssuingPoint.isCRLIssuingPointInitialized()
-                                == ICRLIssuingPoint.CRL_IP_INITIALIZED)) {
-                if (crlIssuingPoint.isCRLIssuingPointInitialized() != ICRLIssuingPoint.CRL_IP_INITIALIZED) {
-                    header.addStringValue("crlUpdate", "notInitialized");
-                } else if (crlIssuingPoint.isCRLUpdateInProgress()
-                           != ICRLIssuingPoint.CRL_UPDATE_DONE ||
-                           crlIssuingPoint.isManualUpdateSet()) {
-                    header.addStringValue("crlUpdate", "inProgress");
-                } else if (!crlIssuingPoint.isCRLGenerationEnabled()) {
-                    header.addStringValue("crlUpdate", "Disabled");
-                } else {
-                    crlIssuingPoint.setManualUpdate(signatureAlgorithm);
-                    header.addStringValue("crlUpdate", "Scheduled");
+            return;
+        }
+        if (test != null && test.equals("true") &&
+                crlIssuingPoint.isCRLCacheTestingEnabled() &&
+                (!mTesting.contains(crlIssuingPointId))) {
+            CMS.debug("CRL test started.");
+            mTesting.add(crlIssuingPointId);
+            BigInteger addLen = null;
+            BigInteger startFrom = null;
+            if (add != null && add.length() > 0 &&
+                    from != null && from.length() > 0) {
+                try {
+                    addLen = new BigInteger(add);
+                    startFrom = new BigInteger(from);
+                } catch (Exception e) {
                 }
-                return;
             }
-                if (test != null && test.equals("true") &&
-                        crlIssuingPoint.isCRLCacheTestingEnabled() &&
-                        (!mTesting.contains(crlIssuingPointId))) {
-                    CMS.debug("CRL test started.");
-                    mTesting.add(crlIssuingPointId);
-                    BigInteger addLen = null;
-                    BigInteger startFrom = null;
-                    if (add != null && add.length() > 0 &&
-                            from != null && from.length() > 0) {
-                        try {
-                            addLen = new BigInteger(add);
-                            startFrom = new BigInteger(from);
-                        } catch (Exception e) {
-                        }
-                    }
-                    if (addLen != null && startFrom != null) {
-                        Date revocationDate = CMS.getCurrentDate();
-                        String err = null;
-
-                        CRLExtensions entryExts = crlEntryExtensions(reason, invalidity);
-
-                        BigInteger serialNumber = startFrom;
-                        BigInteger counter = addLen;
-                        BigInteger stepBy = null;
-                        if (by != null && by.length() > 0) {
-                            try {
-                                stepBy = new BigInteger(by);
-                            } catch (Exception e) {
-                            }
-                        }
+            if (addLen != null && startFrom != null) {
+                Date revocationDate = CMS.getCurrentDate();
+                String err = null;
 
-                        long t1 = System.currentTimeMillis();
-                        long t2 = 0;
-
-                        while (counter.compareTo(BigInteger.ZERO) > 0) {
-                            RevokedCertImpl revokedCert =
-                                    new RevokedCertImpl(serialNumber, revocationDate, entryExts);
-                            crlIssuingPoint.addRevokedCert(serialNumber, revokedCert);
-                            serialNumber = serialNumber.add(BigInteger.ONE);
-                            counter = counter.subtract(BigInteger.ONE);
-
-                            if ((counter.compareTo(BigInteger.ZERO) == 0) ||
-                                    (stepBy != null && ((counter.mod(stepBy)).compareTo(BigInteger.ZERO) == 0))) {
-                                t2 = System.currentTimeMillis();
-                                long t0 = t2 - t1;
-                                t1 = t2;
-                                try {
-                                    if (signatureAlgorithm != null) {
-                                        crlIssuingPoint.updateCRLNow(signatureAlgorithm);
-                                    } else {
-                                        crlIssuingPoint.updateCRLNow();
-                                    }
-                                } catch (Throwable e) {
-                                    counter = BigInteger.ZERO;
-                                    err = e.toString();
-                                }
-                                if (results != null && results.equals("1")) {
-                                    addInfo(argSet, crlIssuingPoint, t0);
-                                }
-                            }
-                        }
-                        if (err != null) {
-                            header.addStringValue("crlUpdate", "Failure");
-                            header.addStringValue("error", err);
-                        } else {
-                            header.addStringValue("crlUpdate", "Success");
-                        }
-                    } else {
-                        CMS.debug("CRL test error: missing parameters.");
-                        header.addStringValue("crlUpdate", "missingParameters");
-                    }
+                CRLExtensions entryExts = crlEntryExtensions(reason, invalidity);
 
-                    mTesting.remove(crlIssuingPointId);
-                    CMS.debug("CRL test finished.");
-                    return;
-                } else if (test != null && test.equals("true") &&
-                           crlIssuingPoint.isCRLCacheTestingEnabled() &&
-                           mTesting.contains(crlIssuingPointId)) {
-                    header.addStringValue("crlUpdate", "testingInProgress");
-                    return;
-                } else if (test != null && test.equals("true") &&
-                           (!crlIssuingPoint.isCRLCacheTestingEnabled())) {
-                    header.addStringValue("crlUpdate", "testingNotEnabled");
-                    return;
-                }
+                BigInteger serialNumber = startFrom;
+                BigInteger counter = addLen;
+                BigInteger stepBy = null;
+                if (by != null && by.length() > 0) {
                     try {
-                        EBaseException publishError = null;
+                        stepBy = new BigInteger(by);
+                    } catch (Exception e) {
+                    }
+                }
 
+                long t1 = System.currentTimeMillis();
+                long t2 = 0;
+
+                while (counter.compareTo(BigInteger.ZERO) > 0) {
+                    RevokedCertImpl revokedCert =
+                            new RevokedCertImpl(serialNumber, revocationDate, entryExts);
+                    crlIssuingPoint.addRevokedCert(serialNumber, revokedCert);
+                    serialNumber = serialNumber.add(BigInteger.ONE);
+                    counter = counter.subtract(BigInteger.ONE);
+
+                    if ((counter.compareTo(BigInteger.ZERO) == 0) ||
+                            (stepBy != null && ((counter.mod(stepBy)).compareTo(BigInteger.ZERO) == 0))) {
+                        t2 = System.currentTimeMillis();
+                        long t0 = t2 - t1;
+                        t1 = t2;
                         try {
-                            long now1 = System.currentTimeMillis();
-
                             if (signatureAlgorithm != null) {
                                 crlIssuingPoint.updateCRLNow(signatureAlgorithm);
                             } else {
                                 crlIssuingPoint.updateCRLNow();
                             }
+                        } catch (Throwable e) {
+                            counter = BigInteger.ZERO;
+                            err = e.toString();
+                        }
+                        if (results != null && results.equals("1")) {
+                            addInfo(argSet, crlIssuingPoint, t0);
+                        }
+                    }
+                }
+                if (err != null) {
+                    header.addStringValue("crlUpdate", "Failure");
+                    header.addStringValue("error", err);
+                } else {
+                    header.addStringValue("crlUpdate", "Success");
+                }
+            } else {
+                CMS.debug("CRL test error: missing parameters.");
+                header.addStringValue("crlUpdate", "missingParameters");
+            }
 
-                            long now2 = System.currentTimeMillis();
+            mTesting.remove(crlIssuingPointId);
+            CMS.debug("CRL test finished.");
+            return;
+        } else if (test != null && test.equals("true") &&
+                   crlIssuingPoint.isCRLCacheTestingEnabled() &&
+                   mTesting.contains(crlIssuingPointId)) {
+            header.addStringValue("crlUpdate", "testingInProgress");
+            return;
+        } else if (test != null && test.equals("true") &&
+                   (!crlIssuingPoint.isCRLCacheTestingEnabled())) {
+            header.addStringValue("crlUpdate", "testingNotEnabled");
+            return;
+        }
+        try {
+            EBaseException publishError = null;
 
-                            header.addStringValue("time", "" + (now2 - now1));
-                        } catch (EErrorPublishCRL e) {
-                            publishError = e;
-                        }
+            try {
+                long now1 = System.currentTimeMillis();
 
-                        if (lpm != null && lpm.isCRLPublishingEnabled()) {
-                            Enumeration<ILdapRule> rules = lpm.getRules(IPublisherProcessor.PROP_LOCAL_CRL);
-                            if (rules != null && rules.hasMoreElements()) {
-                                if (publishError != null) {
-                                    header.addStringValue("crlPublished", "Failure");
-                                    header.addStringValue("error", publishError.toString(locale));
-                                } else {
-                                    header.addStringValue("crlPublished", "Success");
-                                }
-                            }
-                        }
+                if (signatureAlgorithm != null) {
+                    crlIssuingPoint.updateCRLNow(signatureAlgorithm);
+                } else {
+                    crlIssuingPoint.updateCRLNow();
+                }
 
-                        // for audit log
-                        SessionContext sContext = SessionContext.getContext();
-                        String agentId = (String) sContext.get(SessionContext.USER_ID);
-                        IAuthToken authToken = (IAuthToken) sContext.get(SessionContext.AUTH_TOKEN);
-                        String authMgr = AuditFormat.NOAUTH;
+                long now2 = System.currentTimeMillis();
 
-                        if (authToken != null) {
-                            authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
-                        }
-                        long endTime = CMS.getCurrentDate().getTime();
-
-                        if (crlIssuingPoint.getNextUpdate() != null) {
-                            mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
-                                    AuditFormat.LEVEL,
-                                    AuditFormat.CRLUPDATEFORMAT,
-                                    new Object[] {
-                                            AuditFormat.FROMAGENT + " agentID: " + agentId,
-                                            authMgr,
-                                            "completed",
-                                            crlIssuingPoint.getId(),
-                                            crlIssuingPoint.getCRLNumber(),
-                                            crlIssuingPoint.getLastUpdate(),
-                                            crlIssuingPoint.getNextUpdate(),
-                                            Long.toString(crlIssuingPoint.getCRLSize())
-                                                    + " time: " + (endTime - startTime) }
-                                    );
-                        } else {
-                            mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
-                                    AuditFormat.LEVEL,
-                                    AuditFormat.CRLUPDATEFORMAT,
-                                    new Object[] {
-                                            AuditFormat.FROMAGENT + " agentID: " + agentId,
-                                            authMgr,
-                                            "completed",
-                                            crlIssuingPoint.getId(),
-                                            crlIssuingPoint.getCRLNumber(),
-                                            crlIssuingPoint.getLastUpdate(),
-                                            "not set",
-                                            Long.toString(crlIssuingPoint.getCRLSize())
-                                                    + " time: " + (endTime - startTime) }
-                                    );
-                        }
-                    } catch (EBaseException e) {
-                        log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_UPDATE_CRL", e.toString()));
-                        if ((lpm != null) && lpm.isCRLPublishingEnabled() && (e instanceof ELdapException)) {
-                            header.addStringValue("crlPublished", "Failure");
-                            header.addStringValue("error", e.toString(locale));
-                        } else {
-                            throw e;
-                        }
+                header.addStringValue("time", "" + (now2 - now1));
+            } catch (EErrorPublishCRL e) {
+                publishError = e;
+            }
+
+            if (lpm != null && lpm.isCRLPublishingEnabled()) {
+                Enumeration<ILdapRule> rules = lpm.getRules(IPublisherProcessor.PROP_LOCAL_CRL);
+                if (rules != null && rules.hasMoreElements()) {
+                    if (publishError != null) {
+                        header.addStringValue("crlPublished", "Failure");
+                        header.addStringValue("error", publishError.toString(locale));
+                    } else {
+                        header.addStringValue("crlPublished", "Success");
                     }
+                }
+            }
+
+            // for audit log
+            SessionContext sContext = SessionContext.getContext();
+            String agentId = (String) sContext.get(SessionContext.USER_ID);
+            IAuthToken authToken = (IAuthToken) sContext.get(SessionContext.AUTH_TOKEN);
+            String authMgr = AuditFormat.NOAUTH;
+
+            if (authToken != null) {
+                authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
+            }
+            long endTime = CMS.getCurrentDate().getTime();
+
+            if (crlIssuingPoint.getNextUpdate() != null) {
+                mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+                        AuditFormat.LEVEL,
+                        AuditFormat.CRLUPDATEFORMAT,
+                        new Object[] {
+                                AuditFormat.FROMAGENT + " agentID: " + agentId,
+                                authMgr,
+                                "completed",
+                                crlIssuingPoint.getId(),
+                                crlIssuingPoint.getCRLNumber(),
+                                crlIssuingPoint.getLastUpdate(),
+                                crlIssuingPoint.getNextUpdate(),
+                                Long.toString(crlIssuingPoint.getCRLSize())
+                                        + " time: " + (endTime - startTime) }
+                        );
+            } else {
+                mLogger.log(ILogger.EV_AUDIT, ILogger.S_OTHER,
+                        AuditFormat.LEVEL,
+                        AuditFormat.CRLUPDATEFORMAT,
+                        new Object[] {
+                                AuditFormat.FROMAGENT + " agentID: " + agentId,
+                                authMgr,
+                                "completed",
+                                crlIssuingPoint.getId(),
+                                crlIssuingPoint.getCRLNumber(),
+                                crlIssuingPoint.getLastUpdate(),
+                                "not set",
+                                Long.toString(crlIssuingPoint.getCRLSize())
+                                        + " time: " + (endTime - startTime) }
+                        );
+            }
+        } catch (EBaseException e) {
+            log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_UPDATE_CRL", e.toString()));
+            if ((lpm != null) && lpm.isCRLPublishingEnabled() && (e instanceof ELdapException)) {
+                header.addStringValue("crlPublished", "Failure");
+                header.addStringValue("error", e.toString(locale));
+            } else {
+                throw e;
+            }
+        }
     }
 }
-- 
1.8.3.1


From 3c43b1119ca978c296a38a9fe404e1c0cdcdab63 Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Mon, 15 May 2017 18:15:36 -0700
Subject: [PATCH 16/27] Tocket2673- CMC: allow enrollment key signed
 (self-signed) CMC with identity proof

This patch implements the self-signed CMC requests, where the request is signed by the public key of the underlying request (PKCS#10 or CRMF). The scenario for when this method is used is when there was no existing signing cert for the user has been issued before, and once it is issued, it can be used to sign subsequent cert requests by the same user. The new enrollment profile introduced is : caFullCMCSelfSignedCert.cfg The new option introduced to both CRMFPopClient and PKCS10Client is "-y" which will add the required SubjectKeyIdentifier to the underlying request. When a CMC request is self-signed, no auditSubjectID is available until Identification Proof (v2) is verified, however, the cert subject DN is recorded in log as soon as it was available for additional information. Auditing is adjusted. More will come in the next couple CMC patches.
---
 base/ca/shared/conf/CS.cfg                         |   9 +-
 .../shared/profiles/ca/caFullCMCSelfSignedCert.cfg |  85 ++++
 base/ca/shared/webapps/ca/WEB-INF/web.xml          |  28 ++
 .../certsrv/authentication/IAuthManager.java       |   1 +
 .../certsrv/authentication/IAuthSubsystem.java     |   5 +
 .../com/netscape/certsrv/logging/AuditEvent.java   |  12 +-
 .../src/com/netscape/cmstools/CMCRequest.java      | 166 ++++++-
 .../src/com/netscape/cmstools/CRMFPopClient.java   |  32 ++
 .../src/com/netscape/cmstools/PKCS10Client.java    |  87 ++--
 .../cms/authentication/CMCUserSignedAuth.java      | 543 +++++++++++++--------
 .../netscape/cms/profile/common/EnrollProfile.java | 223 +++++++--
 .../netscape/cms/profile/def/CAEnrollDefault.java  |  37 +-
 .../def/SubjectKeyIdentifierExtDefault.java        |  21 +-
 .../netscape/cms/profile/input/EnrollInput.java    |  19 +-
 .../cms/servlet/processors/CRMFProcessor.java      |  35 +-
 .../servlet/profile/ProfileSubmitCMCServlet.java   |  49 +-
 base/server/cmsbundle/src/LogMessages.properties   |  24 +-
 .../com/netscape/cmscore/security/KeyCertUtil.java |  12 +-
 .../com/netscape/cmsutil/crypto/CryptoUtil.java    | 181 ++++++-
 base/util/src/netscape/security/pkcs/PKCS10.java   |  31 +-
 .../netscape/security/pkcs/PKCS10Attributes.java   |   2 +
 21 files changed, 1204 insertions(+), 398 deletions(-)
 create mode 100644 base/ca/shared/profiles/ca/caFullCMCSelfSignedCert.cfg

diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
index 3eb5b1b..f6297a3 100644
--- a/base/ca/shared/conf/CS.cfg
+++ b/base/ca/shared/conf/CS.cfg
@@ -735,7 +735,6 @@ ca.publish.rule.instance.LdapXCertRule.predicate=
 ca.publish.rule.instance.LdapXCertRule.publisher=LdapCrossCertPairPublisher
 ca.publish.rule.instance.LdapXCertRule.type=xcert
 cmc.cert.confirmRequired=false
-cmc.lraPopWitness.verify.allow=false
 cmc.popLinkWitnessRequired=false
 cmc.revokeCert.verify=true
 cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret
@@ -908,11 +907,11 @@ log.instance.SignedAudit._001=## Signed Audit Logging
 log.instance.SignedAudit._002=##
 log.instance.SignedAudit._003=##
 log.instance.SignedAudit._004=## Available Audit events:
-log.instance.SignedAudit._005=## AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,CMC_USER_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,SECURITY_DOMAIN_UPDATE,CONFIG_SERIAL_NUMBER,AUTHORITY_CONFIG,ACCESS_SESSION_ESTABLISH_FAILURE,ACCESS_SESSION_ESTABLISH_SUCCESS,ACCESS_SESSION_TERMINATED
+log.instance.SignedAudit._005=## AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CMC_PROOF_OF_IDENTIFICATION,CMC_ID_POP_LINK_WITNESS,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS,CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,SECURITY_DOMAIN_UPDATE,CONFIG_SERIAL_NUMBER,AUTHORITY_CONFIG,ACCESS_SESSION_ESTABLISH_FAILURE,ACCESS_SESSION_ESTABLISH_SUCCESS,ACCESS_SESSION_TERMINATED
 log.instance.SignedAudit._006=##
 log.instance.SignedAudit.bufferSize=512
 log.instance.SignedAudit.enable=true
-log.instance.SignedAudit.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,CMC_USER_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,SECURITY_DOMAIN_UPDATE,CONFIG_SERIAL_NUMBER,AUTHORITY_CONFIG,ACCESS_SESSION_ESTABLISH_FAILURE,ACCESS_SESSION_ESTABLISH_SUCCESS,ACCESS_SESSION_TERMINATED
+log.instance.SignedAudit.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,PRIVATE_KEY_ARCHIVE_REQUEST,PRIVATE_KEY_ARCHIVE_REQUEST_PROCESSED,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_SUCCESS,PRIVATE_KEY_EXPORT_REQUEST_PROCESSED_FAILURE,KEY_RECOVERY_REQUEST,KEY_RECOVERY_REQUEST_ASYNC,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_REQUEST_PROCESSED,KEY_RECOVERY_REQUEST_PROCESSED_ASYNC,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,PROFILE_CERT_REQUEST,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CMC_PROOF_OF_IDENTIFICATION,CMC_ID_POP_LINK_WITNESS,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS,CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_FAILURE,SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,SERVER_SIDE_KEYGEN_REQUEST,COMPUTE_SESSION_KEY_REQUEST,COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,DIVERSIFY_KEY_REQUEST,DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,ENCRYPT_DATA_REQUEST,ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,OCSP_ADD_CA_REQUEST,OCSP_ADD_CA_REQUEST_PROCESSED,OCSP_REMOVE_CA_REQUEST,OCSP_REMOVE_CA_REQUEST_PROCESSED_SUCCESS,OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE,COMPUTE_RANDOM_DATA_REQUEST,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_SUCCESS,COMPUTE_RANDOM_DATA_REQUEST_PROCESSED_FAILURE,CIMC_CERT_VERIFICATION,SECURITY_DOMAIN_UPDATE,CONFIG_SERIAL_NUMBER,AUTHORITY_CONFIG,ACCESS_SESSION_ESTABLISH_FAILURE,ACCESS_SESSION_ESTABLISH_SUCCESS,ACCESS_SESSION_TERMINATED
 log.instance.SignedAudit.expirationTime=0
 log.instance.SignedAudit.fileName=[PKI_INSTANCE_PATH]/logs/[PKI_SUBSYSTEM_TYPE]/signedAudit/ca_audit
 log.instance.SignedAudit.flushInterval=5
@@ -971,7 +970,7 @@ oidmap.pse.oid=2.16.840.1.113730.1.18
 oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
 oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
 os.userid=nobody
-profile.list=caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caDirBasedDualCert,caECDualCert,AdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caSubsystemCert,caOtherCert,caCACert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caAgentFileSigning,caCMCUserCert,caFullCMCUserCert,caFullCMCUserSignedCert,caSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caSigningUserCert,caSigningECUserCert,caEncECUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
+profile.list=caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caDirBasedDualCert,caECDualCert,AdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caSubsystemCert,caOtherCert,caCACert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caAgentFileSigning,caCMCUserCert,caFullCMCUserCert,caFullCMCUserSignedCert,caFullCMCSelfSignedCert,caSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caSigningUserCert,caSigningECUserCert,caEncECUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
 profile.caUUIDdeviceCert.class_id=caEnrollImpl
 profile.caUUIDdeviceCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caUUIDdeviceCert.cfg
 profile.caManualRenewal.class_id=caEnrollImpl
@@ -1018,6 +1017,8 @@ profile.caFullCMCUserCert.class_id=caEnrollImpl
 profile.caFullCMCUserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caFullCMCUserCert.cfg
 profile.caFullCMCUserSignedCert.class_id=caEnrollImpl
 profile.caFullCMCUserSignedCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caFullCMCUserSignedCert.cfg
+profile.caFullCMCSelfSignedCert.class_id=caEnrollImpl
+profile.caFullCMCSelfSignedCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caFullCMCSelfSignedCert.cfg
 profile.caInternalAuthOCSPCert.class_id=caEnrollImpl
 profile.caInternalAuthOCSPCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caInternalAuthOCSPCert.cfg
 profile.caInternalAuthAuditSigningCert.class_id=caEnrollImpl
diff --git a/base/ca/shared/profiles/ca/caFullCMCSelfSignedCert.cfg b/base/ca/shared/profiles/ca/caFullCMCSelfSignedCert.cfg
new file mode 100644
index 0000000..db3fbd6
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caFullCMCSelfSignedCert.cfg
@@ -0,0 +1,85 @@
+desc=This certificate profile is for enrolling user certificates by using the self-signed CMC certificate request
+enable=true
+enableBy=admin
+name=Self-Signed CMC User Certificate Enrollment
+visible=false
+auth.instance_id=CMCUserSignedAuth
+input.list=i1,i2
+input.i1.class_id=cmcCertReqInputImpl
+input.i2.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=certOutputImpl
+policyset.list=cmcUserCertSet
+policyset.cmcUserCertSet.list=1,2,3,4,5,6,7,8
+policyset.cmcUserCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.cmcUserCertSet.1.constraint.name=Subject Name Constraint
+policyset.cmcUserCertSet.1.constraint.params.accept=true
+policyset.cmcUserCertSet.1.constraint.params.pattern=.*
+policyset.cmcUserCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.cmcUserCertSet.1.default.name=Subject Name Default
+policyset.cmcUserCertSet.1.default.params.name=
+policyset.cmcUserCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.cmcUserCertSet.2.constraint.name=Validity Constraint
+policyset.cmcUserCertSet.2.constraint.params.notAfterCheck=false
+policyset.cmcUserCertSet.2.constraint.params.notBeforeCheck=false
+policyset.cmcUserCertSet.2.constraint.params.range=365
+policyset.cmcUserCertSet.2.default.class_id=validityDefaultImpl
+policyset.cmcUserCertSet.2.default.name=Validity Default
+policyset.cmcUserCertSet.2.default.params.range=180
+policyset.cmcUserCertSet.2.default.params.startTime=0
+policyset.cmcUserCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.cmcUserCertSet.3.constraint.name=Key Constraint
+policyset.cmcUserCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp521
+policyset.cmcUserCertSet.3.constraint.params.keyType=-
+policyset.cmcUserCertSet.3.default.class_id=userKeyDefaultImpl
+policyset.cmcUserCertSet.3.default.name=Key Default
+policyset.cmcUserCertSet.4.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.4.constraint.name=No Constraint
+policyset.cmcUserCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.cmcUserCertSet.4.default.name=Authority Key Identifier Default
+policyset.cmcUserCertSet.5.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.5.constraint.name=No Constraint
+policyset.cmcUserCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.cmcUserCertSet.5.default.name=AIA Extension Default
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.cmcUserCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.cmcUserCertSet.5.default.params.authInfoAccessCritical=false
+policyset.cmcUserCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.cmcUserCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.cmcUserCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.cmcUserCertSet.6.default.name=Key Usage Default
+policyset.cmcUserCertSet.6.default.params.keyUsageCritical=true
+policyset.cmcUserCertSet.6.default.params.keyUsageCrlSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.cmcUserCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.cmcUserCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.cmcUserCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.cmcUserCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.cmcUserCertSet.7.constraint.class_id=noConstraintImpl
+policyset.cmcUserCertSet.7.constraint.name=No Constraint
+policyset.cmcUserCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.cmcUserCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.cmcUserCertSet.7.default.params.exKeyUsageCritical=false
+policyset.cmcUserCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.cmcUserCertSet.8.constraint.class_id=signingAlgConstraintImpl
+policyset.cmcUserCertSet.8.constraint.name=No Constraint
+policyset.cmcUserCertSet.8.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,MD5withRSA,MD2withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withRSA,SHA384withEC,SHA512withEC
+policyset.cmcUserCertSet.8.default.class_id=signingAlgDefaultImpl
+policyset.cmcUserCertSet.8.default.name=Signing Alg
+policyset.cmcUserCertSet.8.default.params.signingAlg=-
diff --git a/base/ca/shared/webapps/ca/WEB-INF/web.xml b/base/ca/shared/webapps/ca/WEB-INF/web.xml
index dc61ab3..a550142 100644
--- a/base/ca/shared/webapps/ca/WEB-INF/web.xml
+++ b/base/ca/shared/webapps/ca/WEB-INF/web.xml
@@ -1576,6 +1576,29 @@
    </servlet>
 
    <servlet>
+      <servlet-name>  caProfileSubmitSelfSignedCMCFull  </servlet-name>
+      <servlet-class> com.netscape.cms.servlet.profile.ProfileSubmitCMCServlet  </servlet-class>
+             <init-param><param-name>  GetClientCert  </param-name>
+                         <param-value> false       </param-value> </init-param>
+             <init-param><param-name>  cert_request_type  </param-name>
+                         <param-value> cmc         </param-value> </init-param>
+             <init-param><param-name>  profileId   </param-name>
+                         <param-value> caFullCMCSelfSignedCert </param-value> </init-param>
+             <init-param><param-name>  AuthzMgr    </param-name>
+                         <param-value> BasicAclAuthz </param-value> </init-param>
+             <init-param><param-name>  authorityId  </param-name>
+                         <param-value> ca          </param-value> </init-param>
+             <init-param><param-name>  ID          </param-name>
+                         <param-value> caProfileSubmitSelfSignedCMCFull </param-value> </init-param>
+             <init-param><param-name>  templatePath  </param-name>
+                         <param-value> /ee/ca/ProfileSubmit.template </param-value> </init-param>
+             <init-param><param-name>  resourceID  </param-name>
+                         <param-value> certServer.ee.profile </param-value> </init-param>
+             <init-param><param-name>  interface   </param-name>
+                         <param-value> ee          </param-value> </init-param>
+   </servlet>
+
+   <servlet>
       <servlet-name>  caProfileList  </servlet-name>
       <servlet-class> com.netscape.cms.servlet.profile.ProfileListServlet  </servlet-class>
              <init-param><param-name>  GetClientCert  </param-name>
@@ -2284,6 +2307,11 @@
       <url-pattern>   /ee/ca/profileSubmitUserSignedCMCFull  </url-pattern>
    </servlet-mapping>
 
+   <servlet-mapping>
+      <servlet-name>  caProfileSubmitSelfSignedCMCFull  </servlet-name>
+      <url-pattern>   /ee/ca/profileSubmitSelfSignedCMCFull  </url-pattern>
+   </servlet-mapping>
+
    <servlet-mapping>  
       <servlet-name>  caProfileList  </servlet-name>
       <url-pattern>   /ee/ca/profileList  </url-pattern>
diff --git a/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java b/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java
index 21639e2..7d30d2e 100644
--- a/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java
+++ b/base/common/src/com/netscape/certsrv/authentication/IAuthManager.java
@@ -33,6 +33,7 @@ public interface IAuthManager {
 
     /* standard credential for CMC request signing cert */
     public static final String CRED_CMC_SIGNING_CERT = "cmcSigningCert";
+    public static final String CRED_CMC_SELF_SIGNED = "cmcSelfSigned";
 
     /**
      * Standard credential for client cert's serial number from revocation.
diff --git a/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java b/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java
index e1ccc2d..9089527 100644
--- a/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java
+++ b/base/common/src/com/netscape/certsrv/authentication/IAuthSubsystem.java
@@ -119,6 +119,11 @@ public interface IAuthSubsystem extends ISubsystem {
     public static final String CMCAUTH_AUTHMGR_ID = "CMCAuth";
 
     /**
+     * Constant for CMC user-signed authentication manager ID.
+     */
+    public static final String CMC_USER_SIGNED_AUTH_AUTHMGR_ID = "CMCUserSignedAuth";
+
+    /**
      * Authenticate the given credentials using the given manager name.
      *
      * @param authCred The authentication credentials
diff --git a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
index 523b204..059363e 100644
--- a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
@@ -125,7 +125,11 @@ public class AuditEvent implements IBundleLogEvent {
     public final static String CERT_PROFILE_APPROVAL =
             "LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL_4";
     public final static String PROOF_OF_POSSESSION =
-            "LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_2";
+            "LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_3";
+    public final static String CMC_PROOF_OF_IDENTIFICATION =
+            "LOGGING_SIGNED_AUDIT_CMC_PROOF_OF_IDENTIFICATION_3";
+    public final static String CMC_ID_POP_LINK_WITNESS =
+            "LOGGING_SIGNED_AUDIT_CMC_ID_POP_LINK_WITNESS_3";
 
     public final static String CRL_RETRIEVAL =
             "LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL_3";
@@ -143,8 +147,10 @@ public class AuditEvent implements IBundleLogEvent {
             "LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE_3";
     public final static String CMC_SIGNED_REQUEST_SIG_VERIFY =
             "LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY_5";
-    public final static String CMC_USER_SIGNED_REQUEST_SIG_VERIFY =
-            "LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_5";
+    public final static String CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS =
+            "LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS_5";
+    public final static String CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE =
+            "LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE_6";
 
     public final static String COMPUTE_RANDOM_DATA_REQUEST =
             "LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST_2";
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
index ac523ad..6e27cb1 100644
--- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
@@ -103,6 +103,9 @@ import com.netscape.cmsutil.util.HMACDigest;
 import com.netscape.cmsutil.util.Utils;
 
 import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
 import netscape.security.x509.X500Name;
 import netscape.security.x509.X509CertImpl;
 
@@ -121,6 +124,7 @@ public class CMCRequest {
     public static final int ARGC = 1;
     public static final String HEADER = "-----BEGIN";
     public static final String TRAILER = "-----END";
+    public static SubjectKeyIdentifierExtension skiExtn = null;
 
     void cleanArgs(String[] s) {
 
@@ -193,7 +197,7 @@ public class CMCRequest {
     }
 
     /**
-     * signData signs the request PKIData
+     * signData signs the request PKIData using existing cert
      *
      * @param signerCert the certificate of the authorized signer of the CMC revocation request.
      * @param nickname the nickname of the certificate inside the token.
@@ -212,6 +216,15 @@ public class CMCRequest {
         SignedData req = null;
         System.out.println(method + "begins: ");
 
+        if (signerCert == null ||
+                tokenName == null ||
+                nickname == null ||
+                manager == null ||
+                pkidata == null) {
+            System.out.println(method + "method parameters cannot be null");
+            System.exit(1);
+        }
+
         try {
             java.security.PrivateKey privKey = null;
             SignerIdentifier si = null;
@@ -232,7 +245,72 @@ public class CMCRequest {
             privKey = getPrivateKey(tokenName, nickname);
             if (privKey != null)
                 System.out.println(method + " got signer privKey");
+            else {
+                System.out.println(method + " signer privKey not foudn on token");
+                System.exit(1);
+            }
+
+            org.mozilla.jss.crypto.X509Certificate[] certChain = manager.buildCertificateChain(signerCert);
+            req = createSignedData(privKey, si, certChain, pkidata);
+
+            System.out.println(method + "signed request generated.");
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+
+        return req;
+    }
+
+    /*
+     * signData self-signs the PKIData using the private key that matches
+     * the public key in the request
+     */
+    static SignedData signData(
+            java.security.PrivateKey privKey,
+            PKIData pkidata) {
+        String method = "signData for selfSign: ";
+        System.out.println(method + "begins: ");
+        SignedData req = null;
+
+        if (privKey == null ||
+                pkidata == null) {
+            System.out.println(method + "method parameters cannot be null");
+            System.exit(1);
+        }
+
+        KeyIdentifier keyIdObj = null;
+        try {
+            keyIdObj = (KeyIdentifier) skiExtn.get(SubjectKeyIdentifierExtension.KEY_ID);
+            SignerIdentifier si = new SignerIdentifier(
+                    SignerIdentifier.SUBJECT_KEY_IDENTIFIER,
+                    null, new OCTET_STRING(keyIdObj.getIdentifier()));
+            req = createSignedData(privKey, si, null /*certChain*/, pkidata);
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        return req;
+    }
 
+    static SignedData createSignedData(
+            java.security.PrivateKey privKey,
+            SignerIdentifier signerId,
+            org.mozilla.jss.crypto.X509Certificate[] certChain,
+            PKIData pkidata) {
+
+        String method = "createSignedData: ";
+        System.out.println(method + "begins");
+        if (privKey == null ||
+                signerId == null ||
+                pkidata == null) {
+            // certChain could be null
+            System.out.println(method + "method parameters cannot be null");
+            System.exit(1);
+        }
+
+        SignedData req = null;
+        try {
             EncapsulatedContentInfo ci = new EncapsulatedContentInfo(OBJECT_IDENTIFIER.id_cct_PKIData, pkidata);
             DigestAlgorithm digestAlg = null;
             SignatureAlgorithm signAlg = getSigningAlgFromPrivate(privKey);
@@ -251,11 +329,18 @@ public class CMCRequest {
                 pkidata.encode(ostream);
                 digest = SHADigest.digest(ostream.toByteArray());
             } catch (NoSuchAlgorithmException e) {
-                System.out.println(e); System.exit(1);}
+                System.out.println(e);
+                System.exit(1);
+            }
             System.out.println(method + "digest created for pkidata");
 
-            SignerInfo signInfo = new SignerInfo(si, null, null, OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg,
+            SignerInfo signInfo = new SignerInfo(signerId, null, null,
+                    OBJECT_IDENTIFIER.id_cct_PKIData, digest, signAlg,
                     (org.mozilla.jss.crypto.PrivateKey) privKey);
+
+            String digestAlgName = signInfo.getDigestEncryptionAlgorithm().toString();
+            System.out.println(method + "digest algorithm =" + digestAlgName);
+
             SET signInfos = new SET();
             signInfos.addElement(signInfo);
 
@@ -266,21 +351,20 @@ public class CMCRequest {
                 digestAlgs.addElement(ai);
             }
 
-            org.mozilla.jss.crypto.X509Certificate[] agentChain = manager.buildCertificateChain(signerCert);
             SET certs = new SET();
-
-            for (int i = 0; i < agentChain.length; i++) {
-                ANY cert = new ANY(agentChain[i].getEncoded());
-                certs.addElement(cert);
+            if (certChain != null) {
+                System.out.println(method + "building cert chain");
+                for (int i = 0; i < certChain.length; i++) {
+                    ANY cert = new ANY(certChain[i].getEncoded());
+                    certs.addElement(cert);
+                }
             }
 
             req = new SignedData(digestAlgs, ci, certs, null, signInfos);
-            System.out.println(method + "signed request generated.");
         } catch (Exception e) {
             e.printStackTrace();
             System.exit(1);
         }
-
         return req;
     }
 
@@ -325,6 +409,7 @@ public class CMCRequest {
      * @return request in PKIData
      */
     static PKIData createPKIData(
+            String selfSign,
             String[] rValue, String format, String transactionMgtEnable,
             String transactionMgtId,
             String identificationEnable, String identification,
@@ -387,13 +472,26 @@ public class CMCRequest {
                         }
                         certReqMsg = (CertReqMsg) crmfMsgs.elementAt(0);
 
+                        CertRequest certReq = certReqMsg.getCertReq();
+                        CertTemplate certTemplate = certReq.getCertTemplate();
+                        if (selfSign.equals("true")) {
+                            skiExtn = (SubjectKeyIdentifierExtension) CryptoUtil.getExtensionFromCertTemplate(
+                                    certTemplate,
+                                    PKIXExtensions.SubjectKey_Id);
+                            if (skiExtn != null) {
+                                System.out.println(method +
+                                        " SubjectKeyIdentifier extension found in self-signed request");
+                            } else {
+                                System.out.println(method +
+                                        " SubjectKeyIdentifier extension missing in self-signed request");
+                                System.exit(1);
+                            }
+                        }
                         if (popLinkWitnessV2Enable.equals("true")) {
                             System.out.println(method +
                                     "popLinkWitnessV2 enabled. reconstructing crmf");
                             //crmf reconstruction to include PopLinkWitnessV2 control
-                            CertRequest certReq = certReqMsg.getCertReq();
                             INTEGER certReqId = certReq.getCertReqId();
-                            CertTemplate certTemplate = certReq.getCertTemplate();
                             SEQUENCE controls = certReq.getControls();
                             controls.addElement(new AVA(OBJECT_IDENTIFIER.id_cmc_popLinkWitnessV2,
                                     popLinkWitnessV2Control));
@@ -449,6 +547,22 @@ public class CMCRequest {
                             System.out.println(method + " Excception:" + e2.toString());
                             System.exit(1);
                         }
+
+                        if (selfSign.equals("true")) {
+                            try {
+                                skiExtn = (SubjectKeyIdentifierExtension) CryptoUtil.getExtensionFromPKCS10(
+                                        pkcs, "SubjectKeyIdentifier");
+                            } catch (IOException e) {
+                                System.out.println(method + "getting SubjectKeyIdentifiere..." + e);
+                            }
+
+                            if (skiExtn != null) {
+                                System.out.println(method + " SubjectKeyIdentifier extension found");
+                            } else {
+                                System.out.println(method + " SubjectKeyIdentifier extension missing");
+                                System.exit(1);
+                            }
+                        }
                         ByteArrayInputStream crInputStream = new ByteArrayInputStream(
                                 pkcs.toByteArray());
                         CertificationRequest cr = (CertificationRequest) CertificationRequest.getTemplate()
@@ -661,8 +775,13 @@ public class CMCRequest {
         System.out.println("");
         System.out.println("#nickname: nickname for agent certificate which will be used");
         System.out.println("#to sign the CMC full request.");
+        System.out.println("#selfSign: if selfSign is true, the CMC request will be");
+        System.out.println("#signed with the pairing private key of the request;");
+        System.out.println("#and in which case the nickname will be ignored");
         System.out.println("nickname=CMS Agent Certificate");
         System.out.println("");
+        System.out.println("selfSign=false");
+        System.out.println("");
         System.out.println("#dbdir: directory for cert8.db, key3.db and secmod.db");
         System.out.println("dbdir=./");
         System.out.println("");
@@ -1700,6 +1819,7 @@ public class CMCRequest {
         String popLinkWitnessV2Enable = "false", popLinkWitnessV2keyGenAlg = "SHA256", popLinkWitnessV2macAlg = "SHA256";
         String popLinkWitnessEnable = "false";
         String bodyPartIDs = null, lraPopWitnessEnable = "false";
+        String selfSign = "false";
 
         System.out.println("");
 
@@ -1760,6 +1880,8 @@ public class CMCRequest {
                         decryptedPopEnable = val;
                     } else if (name.equals("encryptedPopResponseFile")) {
                         encryptedPopResponseFile = val;
+                    } else if (name.equals("request.selfSign")) {
+                        selfSign = val;
                     } else if (name.equals("request.privKeyId")) {
                         privKeyId = val;
                     } else if (name.equals("decryptedPopRequestFile")) {
@@ -1846,7 +1968,7 @@ public class CMCRequest {
             printUsage();
         }
 
-        if (nickname == null) {
+        if (!selfSign.equals("true") && nickname == null) {
             System.out.println("Missing nickname.");
             printUsage();
         }
@@ -1898,14 +2020,14 @@ public class CMCRequest {
                 System.out.println("got signerCert: "+ certname.toString());
             }
 
-            //cfu
             ContentInfo cmcblob = null;
             PKIData pkidata = null;
             PrivateKey privk = null;
-            if (decryptedPopEnable.equalsIgnoreCase("true") ||
+            if (selfSign.equalsIgnoreCase("true") ||
+                    decryptedPopEnable.equalsIgnoreCase("true") ||
                     popLinkWitnessV2Enable.equalsIgnoreCase("true")) {
                 if (privKeyId == null) {
-                    System.out.println("ecryptedPop.enable or popLinkWitnessV2 true, but privKeyId not specified.");
+                    System.out.println("selfSign or ecryptedPop.enable or popLinkWitnessV2 true, but privKeyId not specified.");
                     printUsage();
                 } else {
                     System.out.println("got request privKeyId: " + privKeyId);
@@ -2095,6 +2217,7 @@ public class CMCRequest {
 
                 // create the request PKIData
                 pkidata = createPKIData(
+                        selfSign,
                         requests,
                         format, transactionMgtEnable, transactionMgtId,
                         identificationEnable, identification,
@@ -2114,7 +2237,16 @@ public class CMCRequest {
             }
 
             // sign the request
-            SignedData signedData = signData(signerCert, tokenName, nickname, cm, pkidata);
+            SignedData signedData = null;
+            if (selfSign.equalsIgnoreCase("true")) {
+                // selfSign signes with private key
+                System.out.println("selfSign is true...");
+                signedData = signData(privk, pkidata);
+            } else {
+                // none selfSign signes with  existing cert
+                System.out.println("selfSign is false...");
+                signedData = signData(signerCert, tokenName, nickname, cm, pkidata);
+            }
             if (signedData == null) {
                 System.out.println("signData() returns null. Exiting with error");
                 System.exit(1);
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
index d0e5c27..0057a1d 100644
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
@@ -86,6 +86,8 @@ import com.netscape.cmsutil.util.HMACDigest;
 import com.netscape.cmsutil.util.Utils;
 
 import netscape.security.util.WrappingParams;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
 import netscape.security.x509.X500Name;
 
 /**
@@ -196,6 +198,8 @@ public class CRMFPopClient {
         option.setArgName("keySet");
         options.addOption(option);
 
+        options.addOption("y", false, "for Self-signed cmc.");
+
         options.addOption("v", "verbose", false, "Run in verbose mode.");
         options.addOption(null, "help", false, "Show help message.");
 
@@ -214,6 +218,9 @@ public class CRMFPopClient {
         System.out.println("  -k <true|false>              Attribute value encoding in subject DN (default: false)");
         System.out.println("                               - true: enabled");
         System.out.println("                               - false: disabled");
+        System.out.println("  -y <true|false>              Add SubjectKeyIdentifier extension in case of self-signed CMC requests (default: false)");
+        System.out.println("                               - true: enabled");
+        System.out.println("                               - false: disabled");
         System.out.println("  -a <rsa|ec>                  Key algorithm (default: rsa)");
         System.out.println("                               - rsa: RSA");
         System.out.println("                               - ec: ECC");
@@ -320,6 +327,8 @@ public class CRMFPopClient {
         int sensitive = Integer.parseInt(cmd.getOptionValue("s", "-1"));
         int extractable = Integer.parseInt(cmd.getOptionValue("e", "-1"));
 
+        boolean self_sign = cmd.hasOption("y");
+
         // get the key wrapping mechanism
         boolean keyWrap = true;
         if (cmd.hasOption("g")) {
@@ -516,6 +525,7 @@ public class CRMFPopClient {
 
             if (verbose) System.out.println("Creating certificate request");
             CertRequest certRequest = client.createCertRequest(
+                    self_sign,
                     token, transportCert, algorithm, keyPair,
                     subject, archivalMechanism, wrappingKeySet);
 
@@ -629,6 +639,19 @@ public class CRMFPopClient {
             Name subject,
             String archivalMechanism,
             String wrappingKeySet) throws Exception {
+        return createCertRequest(false, token, transportCert, algorithm, keyPair,
+            subject, archivalMechanism, wrappingKeySet);
+    }
+
+    public CertRequest createCertRequest(
+            boolean self_sign,
+            CryptoToken token,
+            X509Certificate transportCert,
+            String algorithm,
+            KeyPair keyPair,
+            Name subject,
+            String archivalMechanism,
+            String wrappingKeySet) throws Exception {
         EncryptionAlgorithm encryptAlg = null;
 
         if (wrappingKeySet == null) {
@@ -663,6 +686,15 @@ public class CRMFPopClient {
         seq.addElement(new AVA(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr));
         */
 
+        if (self_sign) { // per rfc 5272
+            System.out.println("CRMFPopClient: self_sign true. Generating SubjectKeyIdentifier extension.");
+            KeyIdentifier subjKeyId = CryptoUtil.createKeyIdentifier(keyPair);
+            OBJECT_IDENTIFIER oid = new OBJECT_IDENTIFIER(PKIXExtensions.SubjectKey_Id.toString());
+            SEQUENCE extns = new SEQUENCE();
+            extns.addElement(new AVA(oid, new OCTET_STRING(subjKeyId.getIdentifier())));
+            certTemplate.setExtensions(extns);
+        }
+
         return new CertRequest(new INTEGER(1), certTemplate, seq);
     }
 
diff --git a/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java b/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java
index fd1d087..795c24b 100644
--- a/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java
+++ b/base/java-tools/src/com/netscape/cmstools/PKCS10Client.java
@@ -17,19 +17,15 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.cmstools;
 
-import java.io.ByteArrayOutputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.security.KeyPair;
-import java.security.PublicKey;
 
 import org.mozilla.jss.CryptoManager;
 import org.mozilla.jss.asn1.BMPString;
-import org.mozilla.jss.asn1.INTEGER;
 import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
 import org.mozilla.jss.asn1.PrintableString;
-import org.mozilla.jss.asn1.SET;
 import org.mozilla.jss.asn1.TeletexString;
 import org.mozilla.jss.asn1.UTF8String;
 import org.mozilla.jss.asn1.UniversalString;
@@ -37,20 +33,17 @@ import org.mozilla.jss.crypto.CryptoToken;
 import org.mozilla.jss.crypto.KeyPairAlgorithm;
 import org.mozilla.jss.crypto.KeyPairGenerator;
 import org.mozilla.jss.crypto.PrivateKey;
-import org.mozilla.jss.crypto.SignatureAlgorithm;
-import org.mozilla.jss.pkcs10.CertificationRequest;
-import org.mozilla.jss.pkcs10.CertificationRequestInfo;
 import org.mozilla.jss.pkix.primitive.AVA;
 import org.mozilla.jss.pkix.primitive.Name;
-import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
 import org.mozilla.jss.util.Password;
 
 import com.netscape.cmsutil.crypto.CryptoUtil;
-import com.netscape.cmsutil.util.Utils;
 
 import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.Extensions;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
 import netscape.security.x509.X500Name;
-import netscape.security.x509.X509Key;
 
 /**
  * Generates an ECC or RSA key pair in the security database, constructs a
@@ -91,6 +84,8 @@ public class PKCS10Client {
                 "    -x <true for SSL cert that does ECDH ECDSA; false otherwise; default false>\n");
         System.out.println(
                 "   available ECC curve names (if provided by the crypto module): nistp256 (secp256r1),nistp384 (secp384r1),nistp521 (secp521r1),nistk163 (sect163k1),sect163r1,nistb163 (sect163r2),sect193r1,sect193r2,nistk233 (sect233k1),nistb233 (sect233r1),sect239k1,nistk283 (sect283k1),nistb283 (sect283r1),nistk409 (sect409k1),nistb409 (sect409r1),nistk571 (sect571k1),nistb571 (sect571r1),secp160k1,secp160r1,secp160r2,secp192k1,nistp192 (secp192r1, prime192v1),secp224k1,nistp224 (secp224r1),secp256k1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3,c2pnb163v1,c2pnb163v2,c2pnb163v3,c2pnb176v1,c2tnb191v1,c2tnb191v2,c2tnb191v3,c2pnb208w1,c2tnb239v1,c2tnb239v2,c2tnb239v3,c2pnb272w1,c2pnb304w1,c2tnb359w1,c2pnb368w1,c2tnb431r1,secp112r1,secp112r2,secp128r1,secp128r2,sect113r1,sect113r2,sect131r1,sect131r2\n");
+        System.out.println(
+                "In addition: -y <true for adding SubjectKeyIdentifier extensionfor self-signed cmc requests; false otherwise; default false>\n");
     }
 
     public static void main(String args[]) throws Exception {
@@ -105,6 +100,8 @@ public class PKCS10Client {
         boolean ec_ssl_ecdh = false;
         int rsa_keylen = 2048;
 
+        boolean self_sign = false;
+
         if (args.length < 4) {
             printUsage();
             System.exit(1);
@@ -171,6 +168,12 @@ public class PKCS10Client {
                 subjectName = args[i+1];
             } else if (name.equals("-h")) {
                 tokenName = args[i+1];
+            } else if (name.equals("-y")) {
+                String temp = args[i+1];
+                if (temp.equals("true"))
+                    self_sign = true;
+                else
+                    self_sign = false;
             } else {
                 System.out.println("Unrecognized argument(" + i + "): "
                     + name);
@@ -273,55 +276,29 @@ public class PKCS10Client {
             Attribute attr = new Attribute(OBJECT_IDENTIFIER.id_cmc_idPOPLinkWitness, ostr);
             ***/
 
-            SET attributes = new SET();
-            //attributes.addElement(attr);
-            Name n = getJssName(enable_encoding, subjectName);
-            SubjectPublicKeyInfo subjectPub = new SubjectPublicKeyInfo(pair.getPublic());
-            System.out.println("PKCS10Client: pair.getPublic() called.");
-            CertificationRequestInfo certReqInfo =
-                new CertificationRequestInfo(new INTEGER(0), n, subjectPub, attributes);
-            System.out.println("PKCS10Client: CertificationRequestInfo() created.");
 
-            String b64E = "";
-            if (alg.equals("rsa")) {
-                CertificationRequest certRequest = null;
-                certRequest = new CertificationRequest(certReqInfo,
-                pair.getPrivate(), SignatureAlgorithm.RSASignatureWithSHA256Digest);
-                System.out.println("PKCS10Client: CertificationRequest created.");
+            Extensions extns = new Extensions();
+            if (self_sign) { // per rfc 5272
+                System.out.println("PKCS10Client: self_sign true. Generating SubjectKeyIdentifier extension.");
+                KeyIdentifier subjKeyId = CryptoUtil.createKeyIdentifier(pair);
+                SubjectKeyIdentifierExtension extn = new SubjectKeyIdentifierExtension(false,
+                        subjKeyId.getIdentifier());
+                extns.add(extn);
+            }
 
-                ByteArrayOutputStream bos = new ByteArrayOutputStream();
-                certRequest.encode(bos);
-                byte[] bb = bos.toByteArray();
+            String b64E = "";
+            PKCS10 certReq = CryptoUtil.createCertificationRequest(
+                    subjectName, pair, extns);
 
-                System.out.println("PKCS10Client: calling Utils.b64encode.");
-                b64E = Utils.base64encode(bb);
-                System.out.println("PKCS10Client: b64encode completes.");
-            } else { // "ec"
+            if (certReq == null) {
+                System.out.println("PKCS10Client: cert request null");
+                System.exit(1);
+            } else
+                System.out.println("PKCS10Client: CertificationRequest created.");
+            byte[] certReqb = certReq.toByteArray();
+            b64E = CryptoUtil.base64Encode(certReqb);
 
-                CryptoToken t = cm.getThreadToken();
-                System.out.println("PKCS10Client: token is: "+ t.getName());
-                PublicKey pubk =  pair.getPublic();
-                if (pubk == null) {
-                    System.out.println("PKCS10Client: pubk null.");
-                    System.exit(1);
-                }
-                X509Key xKey = null;
-                byte pubk_encoded[] =  pubk.getEncoded();
-                xKey = CryptoUtil.getPublicX509ECCKey(pubk_encoded);
-                System.out.println("PKCS10Client: calling CryptoUtil.createCertificationRequest");
-                PKCS10 certReq = CryptoUtil.createCertificationRequest(
-                    subjectName, xKey, (org.mozilla.jss.crypto.PrivateKey) pair.getPrivate(),
-                    "SHA256withEC");
-
-                System.out.println("PKCS10Client: created cert request");
-                if (certReq == null) {
-                    System.out.println("PKCS10Client: cert request null");
-                    System.exit(1);
-                } else
-                    System.out.println("PKCS10Client: cert request not null");
-                byte[] certReqb = certReq.toByteArray();
-                b64E = CryptoUtil.base64Encode(certReqb);
-            }
+            System.out.println("PKCS10Client: b64encode completes.");
 
             // print out keyid to be used in cmc popLinkWitnessV2
             PrivateKey privateKey = (PrivateKey) pair.getPrivate();
diff --git a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
index a72ce58..2128c1e 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/CMCUserSignedAuth.java
@@ -39,6 +39,7 @@ import java.util.Vector;
 import org.mozilla.jss.CryptoManager;
 import org.mozilla.jss.CryptoManager.NotInitializedException;
 import org.mozilla.jss.asn1.ASN1Util;
+import org.mozilla.jss.asn1.BIT_STRING;
 import org.mozilla.jss.asn1.INTEGER;
 import org.mozilla.jss.asn1.InvalidBERException;
 import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
@@ -66,6 +67,7 @@ import org.mozilla.jss.pkix.crmf.CertRequest;
 import org.mozilla.jss.pkix.crmf.CertTemplate;
 import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
 import org.mozilla.jss.pkix.primitive.Name;
+import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo;
 
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.authentication.AuthToken;
@@ -90,6 +92,9 @@ import com.netscape.cmsutil.crypto.CryptoUtil;
 import com.netscape.cmsutil.util.Utils;
 
 import netscape.security.pkcs.PKCS10;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
 import netscape.security.x509.X500Name;
 import netscape.security.x509.X509CertImpl;
 import netscape.security.x509.X509CertInfo;
@@ -103,14 +108,15 @@ import netscape.security.x509.X509Key;
 /**
  * User Signed CMC authentication plug-in
  * note:
- *  - this version differs from CMCAuth in that it allows non-agent users
- *  to sign own cmc requests;  It is expected to be used with
- *  CMCUserSignedSubjectNameDefault and CMCUserSignedSubjectNameConstraint
- *  so that the resulting cert will bear the same subjectDN of that of the CMC
- *  signing cert
- *  - it originates from CMCAuth with modification for user-signed cmc
+ * - this version differs from CMCAuth in that it allows non-agent users
+ * to sign own cmc requests; It is expected to be used with
+ * CMCUserSignedSubjectNameDefault and CMCUserSignedSubjectNameConstraint
+ * so that the resulting cert will bear the same subjectDN of that of the CMC
+ * signing cert
+ * - it originates from CMCAuth with modification for user-signed cmc
+ *
  * @author cfu - user signed cmc authentication
- * <P>
+ *         <P>
  *
  * @version $Revision$, $Date$
  */
@@ -121,6 +127,12 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
     // default parameters //
     ////////////////////////
 
+    // only one request for self-signed
+    boolean selfSigned = false;
+    SubjectKeyIdentifierExtension selfsign_skiExtn = null;
+    PK11PubKey selfsign_pubK = null;
+    byte[] selfsign_digest = null;
+
     /////////////////////////////
     // IAuthManager parameters //
     /////////////////////////////
@@ -144,8 +156,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
      * for instances of this implementation can be configured through the
      * console.
      */
-    protected static String[] mConfigParams =
-            new String[] {};
+    protected static String[] mConfigParams = new String[] {};
 
     /* authentication plug-in values */
 
@@ -171,7 +182,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
 
         mExtendedPluginInfo
                 .add(IExtendedPluginInfo.HELP_TEXT +
-                    ";Authenticate the CMC request. The \"Authentication Instance ID\" must be named \"CMCUserSignedAuth\"");
+                        ";Authenticate the CMC request. The \"Authentication Instance ID\" must be named \"CMCUserSignedAuth\"");
         mExtendedPluginInfo.add(IExtendedPluginInfo.HELP_TOKEN +
                 ";configuration-authentication");
     }
@@ -185,10 +196,8 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
 
     /* signed audit parameters */
     private ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
-    private final static String SIGNED_AUDIT_ENROLLMENT_REQUEST_TYPE =
-            "enrollment";
-    private final static String SIGNED_AUDIT_REVOCATION_REQUEST_TYPE =
-            "revocation";
+    private final static String SIGNED_AUDIT_ENROLLMENT_REQUEST_TYPE = "enrollment";
+    private final static String SIGNED_AUDIT_REVOCATION_REQUEST_TYPE = "revocation";
 
     /////////////////////
     // default methods //
@@ -228,7 +237,8 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
      * <P>
      *
      * <ul>
-     * <li>signed.audit LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY used when CMC (user-pre-signed) cert
+     * <li>signed.audit LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY used when CMC
+     *  (user-pre-signed or self-signed) cert
      * requests or revocation requests are submitted and signature is verified
      * </ul>
      *
@@ -245,6 +255,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
     public IAuthToken authenticate(IAuthCredentials authCred) throws EMissingCredential, EInvalidCredentials,
             EBaseException {
         String method = "CMCUserSignedAuth: authenticate: ";
+        String msg = "";
         CMS.debug(method + "begins");
 
         String auditMessage = null;
@@ -273,40 +284,19 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
             if (cmc == null) {
                 CMS.debug(method + " Authentication failed. Missing CMC.");
 
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                        AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
-                        auditSubjectID,
-                        ILogger.FAILURE,
-                        auditReqType,
-                        auditCertSubject,
-                        auditSignerInfo);
-
-                audit(auditMessage);
-
                 throw new EMissingCredential(CMS.getUserMessage(
                         "CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CMC));
             }
 
             if (cmc.equals("")) {
-                log(ILogger.LL_FAILURE,
-                        "cmc : attempted login with empty CMC.");
-
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                        AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
-                        auditSubjectID,
-                        ILogger.FAILURE,
-                        auditReqType,
-                        auditCertSubject,
-                        auditSignerInfo);
-
-                audit(auditMessage);
-
-                throw new EInvalidCredentials(CMS.getUserMessage(
-                        "CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+                msg = "attempted login with empty cert_request in authCred.";
+                CMS.debug(method + msg);
+
+                throw new EInvalidCredentials(msg);
             }
 
+            SessionContext auditContext = SessionContext.getExistingContext();
+
             // authenticate by checking CMC.
 
             // everything OK.
@@ -330,84 +320,88 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                     asciiBASE64Blob = cmc;
 
                 byte[] cmcBlob = CMS.AtoB(asciiBASE64Blob);
-                ByteArrayInputStream cmcBlobIn = new
-                                                 ByteArrayInputStream(cmcBlob);
+                ByteArrayInputStream cmcBlobIn = new ByteArrayInputStream(cmcBlob);
 
                 org.mozilla.jss.pkix.cms.ContentInfo cmcReq =
-                        (org.mozilla.jss.pkix.cms.ContentInfo)
-                        org.mozilla.jss.pkix.cms.ContentInfo.getTemplate().decode(
+                        (org.mozilla.jss.pkix.cms.ContentInfo) org.mozilla.jss.pkix.cms.ContentInfo
+                        .getTemplate().decode(
                                 cmcBlobIn);
 
                 if (!cmcReq.getContentType().equals(
                         org.mozilla.jss.pkix.cms.ContentInfo.SIGNED_DATA) ||
                         !cmcReq.hasContent()) {
-                    // store a message in the signed audit log file
-                    auditMessage = CMS.getLogMessage(
-                            AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
-                            auditSubjectID,
-                            ILogger.FAILURE,
-                            auditReqType,
-                            auditCertSubject,
-                            auditSignerInfo);
 
-                    audit(auditMessage);
-
-                    // throw new ECMSGWException(CMSGWResources.NO_CMC_CONTENT);
-
-                    throw new EBaseException("NO_CMC_CONTENT");
+                    cmcBlobIn.close();
+                    msg = "cmc rquest content type is not ContentInfo.SIGNED_DATA";
+                    CMS.debug(msg);
+                    throw new EBaseException(msg);
                 }
 
-                SignedData cmcFullReq = (SignedData)
-                                        cmcReq.getInterpretedContent();
+                SignedData cmcFullReq = (SignedData) cmcReq.getInterpretedContent();
+
+                String userid = ILogger.UNIDENTIFIED;
+                String uid = ILogger.UNIDENTIFIED;
 
                 IConfigStore cmc_config = CMS.getConfigStore();
-                boolean checkSignerInfo =
-                        cmc_config.getBoolean("cmc.signerInfo.verify", true);
-                String userid = "defUser";
-                String uid = "defUser";
+                boolean checkSignerInfo = cmc_config.getBoolean("cmc.signerInfo.verify", true);
                 if (checkSignerInfo) {
-                    IAuthToken userToken = verifySignerInfo(authToken, cmcFullReq);
+                    // selfSigned will be set in verifySignerInfo if applicable
+                    IAuthToken userToken = verifySignerInfo(auditContext, authToken, cmcFullReq);
                     if (userToken == null) {
-                        CMS.debug(method + " authenticate() userToken null");
-                        throw new EBaseException(method + " verifySignerInfo failure");
+                        msg = "userToken null; verifySignerInfo failure";
+                        CMS.debug(method + msg);
+                        throw new EBaseException(msg);
+                    } else {
+                        if (selfSigned) {
+                            CMS.debug(method
+                                    + " self-signed cmc request will not have user identification info at this point.");
+                            auditSignerInfo = "selfSigned";
+                        } else {
+                            CMS.debug(method + "signed with user cert");
+                            userid = userToken.getInString("userid");
+                            uid = userToken.getInString("cn");
+                            if (userid == null && uid == null) {
+                                msg = " verifySignerInfo failure... missing userid and cn";
+                                CMS.debug(method + msg);
+                                throw new EBaseException(msg);
+                            }
+                            // reset value of auditSignerInfo
+                            if (uid != null && !uid.equals(ILogger.UNIDENTIFIED)) {
+                                CMS.debug(method + "setting auditSignerInfo to uid:" + uid.trim());
+                                auditSignerInfo = uid.trim();
+                                auditSubjectID = uid.trim();
+                                authToken.set(IAuthToken.USER_ID, auditSubjectID);
+                            } else if (userid != null && !userid.equals(ILogger.UNIDENTIFIED)) {
+                                CMS.debug(method + "setting auditSignerInfo to userid:" + userid);
+                                auditSignerInfo = userid.trim();
+                                auditSubjectID = userid.trim();
+                                authToken.set(IAuthToken.USER_ID, auditSubjectID);
+                            }
+                        }
                     }
-                    userid = userToken.getInString("userid");
-                    uid = userToken.getInString("cn");
                 } else {
-                    CMS.debug(method + " authenticate() signerInfo verification bypassed");
-                }
-                // reset value of auditSignerInfo
-                if (uid != null) {
-                    auditSignerInfo = uid.trim();
+                    CMS.debug(method + " signerInfo verification bypassed");
                 }
 
                 EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
+                SET sis = cmcFullReq.getSignerInfos();
+                // only one SignerInfo for selfSigned
+                org.mozilla.jss.pkix.cms.SignerInfo selfsign_signerInfo =
+                        (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(0);
 
                 OBJECT_IDENTIFIER id = ci.getContentType();
 
                 if (!id.equals(OBJECT_IDENTIFIER.id_cct_PKIData) ||
                         !ci.hasContent()) {
-                    // store a message in the signed audit log file
-                    auditMessage = CMS.getLogMessage(
-                            AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
-                            auditSubjectID,
-                            ILogger.FAILURE,
-                            auditReqType,
-                            auditCertSubject,
-                            auditSignerInfo);
-
-                    audit(auditMessage);
+                    msg = "request EncapsulatedContentInfo content type not OBJECT_IDENTIFIER.id_cct_PKIData";
+                    CMS.debug(method + msg);
 
-                    //  throw new ECMSGWException(
-                    // CMSGWResources.NO_PKIDATA);
-
-                    throw new EBaseException("NO_PKIDATA");
+                    throw new EBaseException(msg);
                 }
 
                 OCTET_STRING content = ci.getContent();
 
-                ByteArrayInputStream s = new
-                        ByteArrayInputStream(content.toByteArray());
+                ByteArrayInputStream s = new ByteArrayInputStream(content.toByteArray());
                 PKIData pkiData = (PKIData) (new PKIData.Template()).decode(s);
 
                 SEQUENCE reqSequence = pkiData.getReqSequence();
@@ -426,13 +420,12 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
 
                     if (controlSize > 0) {
                         for (int i = 0; i < controlSize; i++) {
-                            TaggedAttribute taggedAttribute =
-                                    (TaggedAttribute) controlSequence.elementAt(i);
+                            TaggedAttribute taggedAttribute = (TaggedAttribute) controlSequence.elementAt(i);
                             OBJECT_IDENTIFIER type = taggedAttribute.getType();
 
                             if (type.equals(
                                     OBJECT_IDENTIFIER.id_cmc_revokeRequest)) {
-/* TODO: user-signed revocation to be handled in next ticket
+                                /* TODO: user-signed revocation to be handled in next ticket
                                 // if( i ==1 ) {
                                 //     taggedAttribute.getType() ==
                                 //       OBJECT_IDENTIFIER.id_cmc_revokeRequest
@@ -479,10 +472,13 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                                     Integer IntObject = Integer.valueOf((int) reasonCode);
                                     authToken.set(REASON_CODE, IntObject);
 
-                                    authToken.set("uid", uid);
-                                    authToken.set("userid", userid);
+
+                                    //authToken.set("uid", uid);
+                                    //authToken.set("userid", userid);
+
                                 }
-*/
+                                */
+
                             }
                         }
 
@@ -499,8 +495,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
 
                     for (int i = 0; i < numReqs; i++) {
                         // decode message.
-                        TaggedRequest taggedRequest =
-                                (TaggedRequest) reqSequence.elementAt(i);
+                        TaggedRequest taggedRequest = (TaggedRequest) reqSequence.elementAt(i);
 
                         TaggedRequest.Type type = taggedRequest.getType();
 
@@ -508,18 +503,15 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                             CMS.debug(method + " type is PKCS10");
                             authToken.set("cert_request_type", "cmc-pkcs10");
 
-                            TaggedCertificationRequest tcr =
-                                    taggedRequest.getTcr();
+                            TaggedCertificationRequest tcr = taggedRequest.getTcr();
                             int p10Id = tcr.getBodyPartID().intValue();
 
                             reqIdArray[i] = String.valueOf(p10Id);
 
-                            CertificationRequest p10 =
-                                    tcr.getCertificationRequest();
+                            CertificationRequest p10 = tcr.getCertificationRequest();
 
                             // transfer to sun class
-                            ByteArrayOutputStream ostream =
-                                    new ByteArrayOutputStream();
+                            ByteArrayOutputStream ostream = new ByteArrayOutputStream();
 
                             p10.encode(ostream);
                             boolean sigver = true;
@@ -533,8 +525,8 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                             try {
                                 cm = CryptoManager.getInstance();
                                 if (sigver == true) {
-                                    String tokenName =
-                                        CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
+                                    String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token",
+                                            CryptoUtil.INTERNAL_TOKEN_NAME);
                                     savedToken = cm.getThreadToken();
                                     signToken = CryptoUtil.getCryptoToken(tokenName);
                                     if (!savedToken.getName().equals(signToken.getName())) {
@@ -543,65 +535,92 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                                     }
                                 }
 
-                                PKCS10 pkcs10 =
-                                        new PKCS10(ostream.toByteArray(), sigver);
+                                PKCS10 pkcs10 = new PKCS10(ostream.toByteArray(), sigver);
+                                // reset value of auditCertSubject
+                                X500Name tempName = pkcs10.getSubjectName();
+                                CMS.debug(method + "request subject name=" + tempName.toString());
+                                if (tempName != null) {
+                                    auditCertSubject = tempName.toString().trim();
+                                    if (auditCertSubject.equals("")) {
+                                        auditCertSubject = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+                                    }
+                                    authToken.set(AuthToken.TOKEN_CERT_SUBJECT,
+                                            auditCertSubject/*tempName.toString()*/);
+                                }
+
+                                if (selfSigned) {
+                                    // prepare for checking SKI extension
+                                    try {
+                                        selfsign_skiExtn = (SubjectKeyIdentifierExtension) CryptoUtil
+                                                .getExtensionFromPKCS10(pkcs10, "SubjectKeyIdentifier");
+                                        if (selfsign_skiExtn != null)
+                                            CMS.debug(method + "SubjectKeyIdentifierExtension found:");
+                                        else {
+                                            msg = "missing SubjectKeyIdentifierExtension in request";
+                                            CMS.debug(method + msg);
+                                            throw new EBaseException(msg);
+                                        }
+                                    } catch (IOException e) {
+                                        msg = method + "SubjectKeyIdentifierExtension not found:" + e;
+                                        CMS.debug(msg);
+                                        throw new EBaseException(msg);
+                                    } catch (Exception e) {
+                                        msg = method + "SubjectKeyIdentifierExtension not found:" + e;
+                                        CMS.debug(msg);
+                                        throw new EBaseException(msg);
+                                    }
+
+                                    X509Key pubKey = pkcs10.getSubjectPublicKeyInfo();
+                                    PrivateKey.Type keyType = null;
+                                    String alg = pubKey.getAlgorithm();
+
+                                    if (alg.equals("RSA")) {
+                                        CMS.debug(method + "signing key alg=RSA");
+                                        keyType = PrivateKey.RSA;
+                                        selfsign_pubK = PK11PubKey.fromRaw(keyType, pubKey.getKey());
+                                    } else if (alg.equals("EC")) {
+                                        CMS.debug(method + "signing key alg=EC");
+                                        keyType = PrivateKey.EC;
+                                        byte publicKeyData[] = (pubKey).getEncoded();
+                                        selfsign_pubK = PK11ECPublicKey.fromSPKI(/*keyType,*/ publicKeyData);
+                                    } else {
+                                        msg = "unsupported signature algorithm: " + alg;
+                                        CMS.debug(method + msg);
+                                        throw new EInvalidCredentials(msg);
+                                    }
+                                    CMS.debug(method + "public key retrieved");
+                                    verifySelfSignedCMC(selfsign_signerInfo, id);
+
+                                } //selfSigned
 
                                 // xxx do we need to do anything else?
-                                X509CertInfo certInfo =
-                                        CMS.getDefaultX509CertInfo();
+                                X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
 
                                 // fillPKCS10(certInfo,pkcs10,authToken,null);
 
                                 // authToken.set(
                                 //     pkcs10.getSubjectPublicKeyInfo());
 
-                                X500Name tempName = pkcs10.getSubjectName();
-
-                                // reset value of auditCertSubject
-                                if (tempName != null) {
-                                    auditCertSubject =
-                                            tempName.toString().trim();
-                                    if (auditCertSubject.equals("")) {
-                                        auditCertSubject =
-                                                ILogger.SIGNED_AUDIT_EMPTY_VALUE;
-                                    }
-                                    authToken.set(AuthToken.TOKEN_CERT_SUBJECT,
-                                              tempName.toString());
-                                }
-
+                                /*
                                 authToken.set("uid", uid);
                                 authToken.set("userid", userid);
+                                */
 
                                 certInfoArray[i] = certInfo;
                             } catch (Exception e) {
-                                // store a message in the signed audit log file
-                                auditMessage = CMS.getLogMessage(
-                                        AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
-                                        auditSubjectID,
-                                        ILogger.FAILURE,
-                                        auditReqType,
-                                        auditCertSubject,
-                                        auditSignerInfo);
-
-                                audit(auditMessage);
-
-                                //throw new ECMSGWException(
-                                //CMSGWResources.ERROR_PKCS101, e.toString());
-
                                 e.printStackTrace();
                                 throw new EBaseException(e.toString());
                             } finally {
-                                if ((sigver == true) && (tokenSwitched == true)){
+                                if ((sigver == true) && (tokenSwitched == true)) {
                                     cm.setThreadToken(savedToken);
                                 }
-                             }
+                            }
                         } else if (type.equals(TaggedRequest.CRMF)) {
 
                             CMS.debug(method + " type is CRMF");
                             authToken.set("cert_request_type", "cmc-crmf");
                             try {
-                                CertReqMsg crm =
-                                        taggedRequest.getCrm();
+                                CertReqMsg crm = taggedRequest.getCrm();
                                 CertRequest certReq = crm.getCertReq();
                                 INTEGER reqID = certReq.getCertReqId();
                                 reqIdArray[i] = reqID.toString();
@@ -609,70 +628,82 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                                 Name name = template.getSubject();
 
                                 // xxx do we need to do anything else?
-                                X509CertInfo certInfo =
-                                        CMS.getDefaultX509CertInfo();
+                                X509CertInfo certInfo = CMS.getDefaultX509CertInfo();
 
                                 // reset value of auditCertSubject
                                 if (name != null) {
                                     String ss = name.getRFC1485();
 
+                                    CMS.debug(method + "setting auditCertSubject to: " + ss);
                                     auditCertSubject = ss;
                                     if (auditCertSubject.equals("")) {
-                                        auditCertSubject =
-                                                ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+                                        auditCertSubject = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
                                     }
 
                                     authToken.set(AuthToken.TOKEN_CERT_SUBJECT, ss);
-                                    authToken.set("uid", uid);
-                                    authToken.set("userid", userid);
+                                    //authToken.set("uid", uid);
+                                    //authToken.set("userid", userid);
                                 }
                                 certInfoArray[i] = certInfo;
-                            } catch (Exception e) {
-                                // store a message in the signed audit log file
-                                auditMessage = CMS.getLogMessage(
-                                        AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
-                                        auditSubjectID,
-                                        ILogger.FAILURE,
-                                        auditReqType,
-                                        auditCertSubject,
-                                        auditSignerInfo);
 
-                                audit(auditMessage);
+                                if (selfSigned) {
+                                    selfsign_skiExtn =
+                                            (SubjectKeyIdentifierExtension) CryptoUtil
+                                            .getExtensionFromCertTemplate(template, PKIXExtensions.SubjectKey_Id);
+                                    if (selfsign_skiExtn != null) {
+                                        CMS.debug(method +
+                                                "SubjectKeyIdentifierExtension found");
+                                    } else {
+                                        CMS.debug(method +
+                                                "SubjectKeyIdentifierExtension not found");
+                                    }
+
+                                    // get public key for verifying signature later
+                                    SubjectPublicKeyInfo pkinfo = template.getPublicKey();
+                                    PrivateKey.Type keyType = null;
+                                    String alg = pkinfo.getAlgorithm();
+                                    BIT_STRING bitString = pkinfo.getSubjectPublicKey();
+                                    byte[] publicKeyData = bitString.getBits();
+                                    if (alg.equals("RSA")) {
+                                        CMS.debug(method + "signing key alg=RSA");
+                                        keyType = PrivateKey.RSA;
+                                        selfsign_pubK = PK11PubKey.fromRaw(keyType, publicKeyData);
+                                    } else if (alg.equals("EC")) {
+                                        CMS.debug(method + "signing key alg=EC");
+                                        keyType = PrivateKey.EC;
+                                        selfsign_pubK = PK11ECPublicKey.fromSPKI(/*keyType,*/ publicKeyData);
+                                    } else {
+                                        msg = "unsupported signature algorithm: " + alg;
+                                        CMS.debug(method + msg);
+                                        throw new EInvalidCredentials(msg);
+                                    }
+                                    CMS.debug(method + "public key retrieved");
 
-                                //throw new ECMSGWException(
-                                //CMSGWResources.ERROR_PKCS101, e.toString());
+                                    verifySelfSignedCMC(selfsign_signerInfo, id);
+                                } //selfSigned
 
+                            } catch (Exception e) {
                                 e.printStackTrace();
+                                cmcBlobIn.close();
+                                s.close();
                                 throw new EBaseException(e.toString());
                             }
                         }
 
-                        // authToken.set(AgentAuthentication.CRED_CERT, new
-                        //     com.netscape.certsrv.usrgrp.Certificates(
-                        //     x509Certs));
                     }
                 }
+
+                authToken.set("uid", uid);
+                authToken.set("userid", userid);
             } catch (Exception e) {
                 CMS.debug(method + e);
-                // store a message in the signed audit log file
-                auditMessage = CMS.getLogMessage(
-                        AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
-                        auditSubjectID,
-                        ILogger.FAILURE,
-                        auditReqType,
-                        auditCertSubject,
-                        auditSignerInfo);
-
-                audit(auditMessage);
-
                 //Debug.printStackTrace(e);
-                throw new EInvalidCredentials(CMS.getUserMessage(
-                        "CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+                throw new EInvalidCredentials(e.toString());
             }
 
             // store a message in the signed audit log file
             auditMessage = CMS.getLogMessage(
-                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS,
                     auditSubjectID,
                     ILogger.SUCCESS,
                     auditReqType,
@@ -687,12 +718,13 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
             CMS.debug(method + eAudit1);
             // store a message in the signed audit log file
             auditMessage = CMS.getLogMessage(
-                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
                     auditSubjectID,
                     ILogger.FAILURE,
                     auditReqType,
                     auditCertSubject,
-                    auditSignerInfo);
+                    auditSignerInfo,
+                    eAudit1.toString());
 
             audit(auditMessage);
 
@@ -702,12 +734,13 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
             CMS.debug(method + eAudit2);
             // store a message in the signed audit log file
             auditMessage = CMS.getLogMessage(
-                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
                     auditSubjectID,
                     ILogger.FAILURE,
                     auditReqType,
                     auditCertSubject,
-                    auditSignerInfo);
+                    auditSignerInfo,
+                    eAudit2.toString());
 
             audit(auditMessage);
 
@@ -717,17 +750,70 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
             CMS.debug(method + eAudit3);
             // store a message in the signed audit log file
             auditMessage = CMS.getLogMessage(
-                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY,
+                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
                     auditSubjectID,
                     ILogger.FAILURE,
                     auditReqType,
                     auditCertSubject,
-                    auditSignerInfo);
+                    auditSignerInfo,
+                    eAudit3.toString());
 
             audit(auditMessage);
 
             // rethrow the specific exception to be handled later
             throw eAudit3;
+        } catch (Exception eAudit4) {
+            CMS.debug(method + eAudit4);
+            // store a message in the signed audit log file
+            auditMessage = CMS.getLogMessage(
+                    AuditEvent.CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE,
+                    auditSubjectID,
+                    ILogger.FAILURE,
+                    auditReqType,
+                    auditCertSubject,
+                    auditSignerInfo,
+                    eAudit4.toString());
+
+            audit(auditMessage);
+
+            // rethrow the specific exception to be handled later
+            throw eAudit4;
+        }
+    }
+
+    /*
+    * verifySelfSignedCMC() verifies the following
+    * a. the required (per RFC 5272) SKI extension in the request matches that in the
+    *    SignerIdentifier
+    * b. the signature in the request
+    */
+    protected void verifySelfSignedCMC(
+            org.mozilla.jss.pkix.cms.SignerInfo signerInfo,
+            OBJECT_IDENTIFIER id)
+            throws EBaseException {
+        String method = "CMCUserSignedAuth: verifySelfSignedCMC: ";
+        CMS.debug(method + "begins");
+        try {
+            SignerIdentifier sid = signerInfo.getSignerIdentifier();
+            OCTET_STRING subjKeyId = sid.getSubjectKeyIdentifier();
+            KeyIdentifier keyIdObj =
+                    (KeyIdentifier) selfsign_skiExtn.get(SubjectKeyIdentifierExtension.KEY_ID);
+            boolean match = CryptoUtil.compare(subjKeyId.toByteArray(), keyIdObj.getIdentifier());
+            if (match) {
+                CMS.debug(method +
+                        " SignerIdentifier SUBJECT_KEY_IDENTIFIER matches SKI of request");
+            } else {
+                CMS.debug(method +
+                        " SignerIdentifier SUBJECT_KEY_IDENTIFIER failed to match");
+                throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+            }
+            // verify sig using public key in request
+            CMS.debug(method + "verifying request signature with public key");
+            signerInfo.verify(selfsign_digest, id, selfsign_pubK);
+            CMS.debug(method + " signature verified");
+        } catch (Exception e) {
+            CMS.debug(method + e.toString());
+            throw new EBaseException(method + e.toString());
         }
     }
 
@@ -825,10 +911,24 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                 level, "CMC User Signed Authentication: " + msg);
     }
 
-    protected IAuthToken verifySignerInfo(AuthToken authToken, SignedData cmcFullReq) throws EBaseException {
+    /**
+     * User-signed CMC requests can be signed in two ways:
+     * a. signed with previously issued user signing cert
+     * b. self-signed with the private key paired with the public key in
+     * the request
+     *
+     * In case "a", the resulting authToke would contain
+     * (IAuthManager.CRED_CMC_SIGNING_CERT, signing cert serial number)
+     * In case "b", the resulting authToke would not contain the attribute
+     * IAuthManager.CRED_CMC_SIGNING_CERT
+     */
+    protected IAuthToken verifySignerInfo(
+            SessionContext auditContext, // to capture info in case of failure
+            AuthToken authToken,
+            SignedData cmcFullReq)
+            throws EBaseException {
         String method = "CMCUserSignedAuth: verifySignerInfo: ";
         CMS.debug(method + "begins");
-
         EncapsulatedContentInfo ci = cmcFullReq.getContentInfo();
         OBJECT_IDENTIFIER id = ci.getContentType();
         OCTET_STRING content = ci.getContent();
@@ -849,13 +949,10 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
             //if request key is used for signing, there MUST be only one signerInfo
             //object in the signedData object.
             for (int i = 0; i < numDig; i++) {
-                AlgorithmIdentifier dai =
-                        (AlgorithmIdentifier) dais.elementAt(i);
-                String name =
-                        DigestAlgorithm.fromOID(dai.getOID()).toString();
+                AlgorithmIdentifier dai = (AlgorithmIdentifier) dais.elementAt(i);
+                String name = DigestAlgorithm.fromOID(dai.getOID()).toString();
 
-                MessageDigest md =
-                        MessageDigest.getInstance(name);
+                MessageDigest md = MessageDigest.getInstance(name);
 
                 byte[] digest = md.digest(content.toByteArray());
 
@@ -867,6 +964,7 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
 
             for (int i = 0; i < numSis; i++) {
                 org.mozilla.jss.pkix.cms.SignerInfo si = (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(i);
+                //selfsign_SignerInfo = (org.mozilla.jss.pkix.cms.SignerInfo) sis.elementAt(i);
 
                 String name = si.getDigestAlgorithm().toString();
                 byte[] digest = digs.get(name);
@@ -879,11 +977,14 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                     digest = md.digest(ostream.toByteArray());
 
                 }
+
                 // signed  by  previously certified signature key
                 SignerIdentifier sid = si.getSignerIdentifier();
-                // TODO: need to handle signing key being the matching key from
-                // the request
                 if (sid.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) {
+                    CMS.debug(method + "SignerIdentifier type: ISSUER_AND_SERIALNUMBER");
+                    selfSigned = false;
+                    CMS.debug(method + "selfSigned is false");
+
                     IssuerAndSerialNumber issuerAndSerialNumber = sid.getIssuerAndSerialNumber();
                     // find from the certs in the signedData
                     java.security.cert.X509Certificate cert = null;
@@ -899,14 +1000,12 @@ public class CMCUserSignedAuth implements IAuthManager, IExtendedPluginInfo,
                             Name issuer = certI.getIssuer();
 
                             byte[] issuerB = ASN1Util.encode(issuer);
-CMS.debug(method + "issuer = " + new String(issuerB));
                             INTEGER sn = certI.getSerialNumber();
                             // if this cert is the signer cert, not a cert in the chain
                             if (new String(issuerB).equals(new String(
                                     ASN1Util.encode(issuerAndSerialNumber.getIssuer())))
                                     && sn.toString().equals(issuerAndSerialNumber.getSerialNumber().toString())) {
-                                ByteArrayOutputStream os = new
-                                        ByteArrayOutputStream();
+                                ByteArrayOutputStream os = new ByteArrayOutputStream();
 
                                 certJss.encode(os);
                                 certByteArray = os.toByteArray();
@@ -919,13 +1018,23 @@ CMS.debug(method + "issuer = " + new String(issuerB));
 
                             }
                         }
+
                         CMS.debug(method + "start checking signature");
+                        String CN = null;
                         if (cert == null) {
                             // find from certDB
                             CMS.debug(method + "verifying signature");
                             si.verify(digest, id);
                         } else {
                             CMS.debug(method + "found signing cert... verifying");
+
+                            //capture auditSubjectID first in case of failure
+                            netscape.security.x509.X500Name tempPrincipal =
+                                    (X500Name) x509Certs[0].getSubjectDN();
+                            CN = tempPrincipal.getCommonName(); //tempToken.get("userid");
+                            CMS.debug(method + " Principal name = " + CN);
+                            auditContext.put(SessionContext.USER_ID, CN);
+
                             PublicKey signKey = cert.getPublicKey();
                             PrivateKey.Type keyType = null;
                             String alg = signKey.getAlgorithm();
@@ -942,21 +1051,24 @@ CMS.debug(method + "issuer = " + new String(issuerB));
                                 pubK = PK11ECPublicKey.fromSPKI(/*keyType,*/ publicKeyData);
                             } else {
                                 CMS.debug(method + "unsupported signature algorithm: " + alg);
-                                throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
+                                s.close();
+                                throw new EInvalidCredentials(
+                                        CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
                             }
 
-                            String tokenName =
-                                CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
+                            String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token",
+                                    CryptoUtil.INTERNAL_TOKEN_NAME);
                             // by default JSS will use internal crypto token
                             if (!CryptoUtil.isInternalToken(tokenName)) {
                                 savedToken = cm.getThreadToken();
                                 signToken = CryptoUtil.getCryptoToken(tokenName);
-                                if(signToken != null) {
+                                if (signToken != null) {
                                     cm.setThreadToken(signToken);
                                     tokenSwitched = true;
-                                    CMS.debug(method + "verifySignerInfo token switched:"+ tokenName);
+                                    CMS.debug(method + "verifySignerInfo token switched:" + tokenName);
                                 } else {
-                                    CMS.debug(method + "verifySignerInfo token not found:"+ tokenName+ ", trying internal");
+                                    CMS.debug(method + "verifySignerInfo token not found:" + tokenName
+                                            + ", trying internal");
                                 }
                             }
 
@@ -967,6 +1079,7 @@ CMS.debug(method + "issuer = " + new String(issuerB));
                         // verify signer's certificate using the revocator
                         if (!cm.isCertValid(certByteArray, true, CryptoManager.CertUsage.SSLClient)) {
                             CMS.debug(method + "CMC signature failed to be verified");
+                            s.close();
                             throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
                         } else {
                             CMS.debug(method + "CMC signature verified; but signer not yet;");
@@ -974,23 +1087,38 @@ CMS.debug(method + "issuer = " + new String(issuerB));
                         // At this point, the signature has been verified;
 
                         IAuthToken tempToken = new AuthToken(null);
+/*
                         netscape.security.x509.X500Name tempPrincipal = (X500Name) x509Certs[0].getSubjectDN();
                         String CN = tempPrincipal.getCommonName(); //tempToken.get("userid");
                         CMS.debug(method + " Principal name = " + CN);
+*/
 
                         BigInteger certSerial = x509Certs[0].getSerialNumber();
                         CMS.debug(method + " verified cert serial=" + certSerial.toString());
                         authToken.set(IAuthManager.CRED_CMC_SIGNING_CERT, certSerial.toString());
                         tempToken.set("cn", CN);
 
+                        s.close();
                         return tempToken;
 
+                    } else {
+                        CMS.debug(method + "no certificate found in cmcFullReq");
                     }
-
+                } else if (sid.getType().equals(SignerIdentifier.SUBJECT_KEY_IDENTIFIER)) {
+                    CMS.debug(method + "SignerIdentifier type: SUBJECT_KEY_IDENTIFIER");
+                    CMS.debug(method + "selfSigned is true");
+                    selfSigned = true;
+                    selfsign_digest = digest;
+
+                    IAuthToken tempToken = new AuthToken(null);
+                    authToken.set(IAuthManager.CRED_CMC_SELF_SIGNED, "true");
+                    s.close();
+                    return tempToken;
                 } else {
                     CMS.debug(method + "unsupported SignerIdentifier type");
                 }
-            }
+            } //for
+
         } catch (InvalidBERException e) {
             CMS.debug(method + e.toString());
         } catch (IOException e) {
@@ -1001,7 +1129,7 @@ CMS.debug(method + "issuer = " + new String(issuerB));
             CMS.debug(method + e.toString());
             throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL"));
         } finally {
-            if ((tokenSwitched == true) && (savedToken != null)){
+            if ((tokenSwitched == true) && (savedToken != null)) {
                 cm.setThreadToken(savedToken);
                 CMS.debug(method + "verifySignerInfo token restored");
             }
@@ -1123,8 +1251,7 @@ CMS.debug(method + "issuer = " + new String(issuerB));
         SessionContext auditContext = SessionContext.getExistingContext();
 
         if (auditContext != null) {
-            subjectID = (String)
-                    auditContext.get(SessionContext.USER_ID);
+            subjectID = (String) auditContext.get(SessionContext.USER_ID);
 
             if (subjectID != null) {
                 subjectID = subjectID.trim();
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
index 7d52fc8..1443a0a 100644
--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
+++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java
@@ -110,6 +110,8 @@ import netscape.security.x509.CertificateVersion;
 import netscape.security.x509.CertificateX509Key;
 import netscape.security.x509.Extension;
 import netscape.security.x509.Extensions;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
 import netscape.security.x509.X500Name;
 import netscape.security.x509.X509CertImpl;
 import netscape.security.x509.X509CertInfo;
@@ -656,6 +658,8 @@ public abstract class EnrollProfile extends BasicProfile
         String msg = ""; // for capturing debug and throw info
         //CMS.debug(method + " Start parseCMC(): " + certreq);
         CMS.debug(method + "starts");
+        String auditMessage = "";
+        String auditSubjectID = auditSubjectID();
 
         /* cert request must not be null */
         if (certreq == null) {
@@ -742,22 +746,27 @@ public abstract class EnrollProfile extends BasicProfile
 
                             msg = " id_cmc_identification attribute value not found in";
                             CMS.debug(method + msg);
+/*
                             throw new EProfileException(
                                     CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST") +
                                             msg);
+*/
+                        } else {
+                            ident_s = (UTF8String) (ASN1Util.decode(UTF8String.getTemplate(),
+                                    ASN1Util.encode(ident.elementAt(0))));
                         }
-                        ident_s = (UTF8String) (ASN1Util.decode(UTF8String.getTemplate(),
-                                ASN1Util.encode(ident.elementAt(0))));
-                        if (ident_s == null) {
+                        if (ident == null && ident_s == null) {
                             msg = " id_cmc_identification contains invalid content";
                             CMS.debug(method + msg);
                             SEQUENCE bpids = getRequestBpids(reqSeq);
                             context.put("identification", bpids);
 
                             CMS.debug(method + msg);
+/*
                             throw new EProfileException(
                                     CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST") +
                                             msg);
+*/
                         }
                     }
 
@@ -776,19 +785,27 @@ public abstract class EnrollProfile extends BasicProfile
                         }
                     } else if (id_cmc_identityProofV2 && (attr != null)) {
                         // either V2 or not V2; can't be both
-                        CMS.debug(method + "not pre-signed CMC request; calling verifyIdentityProofV2;");
-                        if (!id_cmc_identification) {
+                        CMS.debug(method +
+                                "not pre-signed CMC request; calling verifyIdentityProofV2;");
+                        if (!id_cmc_identification || ident_s == null) {
                             SEQUENCE bpids = getRequestBpids(reqSeq);
                             context.put("identification", bpids);
                             context.put("identityProofV2", bpids);
                             msg = "id_cmc_identityProofV2 missing id_cmc_identification";
                             CMS.debug(method + msg);
+                            auditMessage = CMS.getLogMessage(
+                                    AuditEvent.CMC_PROOF_OF_IDENTIFICATION,
+                                    auditSubjectID,
+                                    ILogger.FAILURE,
+                                    method + msg);
+                            audit(auditMessage);
+
                             throw new EProfileException(
                                     CMS.getUserMessage(locale, "CMS_PROFILE_INVALID_REQUEST") +
                                             msg);
                         }
 
-                        boolean valid = verifyIdentityProofV2(attr, ident_s,
+                        boolean valid = verifyIdentityProofV2(context, attr, ident_s,
                                 reqSeq);
                         if (!valid) {
                             SEQUENCE bpids = getRequestBpids(reqSeq);
@@ -815,10 +832,18 @@ public abstract class EnrollProfile extends BasicProfile
                                     "CMS_POI_VERIFICATION_ERROR") + msg);
                         } else {
                             CMS.debug(method + "passed verifyIdentityProof; Proof of Identity successful;");
+                            // in case it was set
+                            auditSubjectID = auditSubjectID();
                         }
                     } else {
                         msg = "not pre-signed CMC request; missing Proof of Identification control";
                         CMS.debug(method + msg);
+                        auditMessage = CMS.getLogMessage(
+                                AuditEvent.CMC_PROOF_OF_IDENTIFICATION,
+                                auditSubjectID,
+                                ILogger.FAILURE,
+                                method + msg);
+                        audit(auditMessage);
                         throw new EProfileException(CMS.getUserMessage(locale,
                                 "CMS_POI_VERIFICATION_ERROR") + ":" + method + msg);
                     }
@@ -837,6 +862,13 @@ public abstract class EnrollProfile extends BasicProfile
                         } else { //decPopVals == null
                             msg = "id_cmc_decryptedPOP contains invalid DecryptedPOP";
                             CMS.debug(method + msg);
+                            auditMessage = CMS.getLogMessage(
+                                    AuditEvent.PROOF_OF_POSSESSION,
+                                    auditSubjectID,
+                                    ILogger.SUCCESS,
+                                    method + msg);
+                            audit(auditMessage);
+
                             SEQUENCE bpids = getRequestBpids(reqSeq);
                             context.put("decryptedPOP", bpids);
                         }
@@ -877,6 +909,11 @@ public abstract class EnrollProfile extends BasicProfile
                 String configName = "cmc.popLinkWitnessRequired";
                 CMS.debug(method + "getting :" + configName);
                 popLinkWitnessRequired = CMS.getConfigStore().getBoolean(configName, false);
+                if (popLinkWitnessRequired) {
+                    CMS.debug(method + "popLinkWitness(V2) required");
+                } else {
+                    CMS.debug(method + "popLinkWitness(V2) not required");
+                }
             } catch (Exception e) {
                 // unlikely to get here
                 msg = method + " Failed to retrieve cmc.popLinkWitnessRequired";
@@ -897,8 +934,16 @@ public abstract class EnrollProfile extends BasicProfile
                             !context.containsKey("POPLinkWitnessV2") &&
                             !context.containsKey("POPLinkWitness")) {
                         CMS.debug(method + "popLinkWitness(V2) required");
-                        if (randomSeed == null) {
-                            CMS.debug(method + "no randomSeed found");
+                        if (randomSeed == null || ident_s == null) {
+                            msg = "no randomSeed or identification found needed for popLinkWitness(V2)";
+                            CMS.debug(method + msg);
+                            auditMessage = CMS.getLogMessage(
+                                    AuditEvent.CMC_ID_POP_LINK_WITNESS,
+                                    auditSubjectID,
+                                    ILogger.FAILURE,
+                                    method + msg);
+                            audit(auditMessage);
+
                             context.put("POPLinkWitnessV2", bpids);
                             return null;
                         }
@@ -913,11 +958,26 @@ public abstract class EnrollProfile extends BasicProfile
                             else if (context.containsKey("POPLinkWitness"))
                                 msg = " in POPLinkWitness";
                             else
-                                msg = " unspecified failure from verifyPOPLinkWitness";
+                                msg = " failure from verifyPOPLinkWitness";
 
+                            msg = msg + ": ident_s=" + ident_s;
                             CMS.debug(method + msg);
+                            auditMessage = CMS.getLogMessage(
+                                    AuditEvent.CMC_ID_POP_LINK_WITNESS,
+                                    auditSubjectID,
+                                    ILogger.FAILURE,
+                                    method + msg);
+                            audit(auditMessage);
                             throw new EProfileException(CMS.getUserMessage(locale,
                                     "CMS_POP_LINK_WITNESS_VERIFICATION_ERROR") + msg);
+                        } else {
+                            msg = ": ident_s=" + ident_s;
+                            auditMessage = CMS.getLogMessage(
+                                    AuditEvent.CMC_ID_POP_LINK_WITNESS,
+                                    auditSubjectID,
+                                    ILogger.SUCCESS,
+                                    method + msg);
+                            audit(auditMessage);
                         }
                     }
                 } //for
@@ -1441,22 +1501,37 @@ public abstract class EnrollProfile extends BasicProfile
      * @author cfu
      */
     private boolean verifyIdentityProofV2(
+            SessionContext sessionContext,
             TaggedAttribute attr,
             UTF8String ident,
             SEQUENCE reqSeq) {
         String method = "EnrollProfile:verifyIdentityProofV2: ";
+        String msg = "";
         CMS.debug(method + " begins");
+        boolean verified = false;
+        String auditMessage = method;
+
         if ((attr == null) ||
                 (ident == null) ||
                 (reqSeq == null)) {
             CMS.debug(method + "method parameters cannot be null");
+            // this is internal error
             return false;
         }
 
         String ident_string = ident.toString();
+        String auditAttemptedCred = null;
 
         SET vals = attr.getValues(); // getting the IdentityProofV2 structure
         if (vals.size() < 1) {
+            msg = " invalid TaggedAttribute in request";
+            CMS.debug(method + msg);
+            auditMessage = CMS.getLogMessage(
+                    AuditEvent.CMC_PROOF_OF_IDENTIFICATION,
+                    auditAttemptedCred,
+                    ILogger.FAILURE,
+                    method + msg);
+            audit(auditMessage);
             return false;
         }
 
@@ -1464,18 +1539,33 @@ public abstract class EnrollProfile extends BasicProfile
         ISharedToken tokenClass = getSharedTokenClass(configName);
 
         if (tokenClass == null) {
-            CMS.debug(method + " Failed to retrieve shared secret plugin class");
+            msg = " Failed to retrieve shared secret plugin class";
+            CMS.debug(method + msg);
+            auditMessage = CMS.getLogMessage(
+                    AuditEvent.CMC_PROOF_OF_IDENTIFICATION,
+                    auditAttemptedCred,
+                    ILogger.FAILURE,
+                    method + msg);
+            audit(auditMessage);
             return false;
         }
 
         String token = null;
-        if (ident_string != null)
+        if (ident_string != null) {
+            auditAttemptedCred = ident_string;
             token = tokenClass.getSharedToken(ident_string);
-        else
+        } else
             token = tokenClass.getSharedToken(mCMCData);
 
         if (token == null) {
-            CMS.debug(method + " Failed to retrieve shared secret");
+            msg = " Failed to retrieve shared secret";
+            CMS.debug(method + msg);
+            auditMessage = CMS.getLogMessage(
+                    AuditEvent.CMC_PROOF_OF_IDENTIFICATION,
+                    auditAttemptedCred,
+                    ILogger.FAILURE,
+                    method + msg);
+            audit(auditMessage);
             return false;
         }
 
@@ -1493,26 +1583,64 @@ public abstract class EnrollProfile extends BasicProfile
 
             OCTET_STRING witness = idV2val.getWitness();
             if (witness == null) {
-                CMS.debug(method + " witness reurned by idV2val.getWitness is null");
-                return false;
+                msg = " witness reurned by idV2val.getWitness is null";
+                CMS.debug(method + msg);
+                throw new EBaseException(msg);
             }
 
             byte[] witness_bytes = witness.toByteArray();
             byte[] request_bytes = ASN1Util.encode(reqSeq); // PKIData reqSequence field
-            return verifyDigest(
+            verified = verifyDigest(
                     (ident_string != null) ? (token + ident_string).getBytes() : token.getBytes(),
                     request_bytes,
                     witness_bytes,
                     hashAlg, macAlg);
+
+            String authMgrID =
+                    (String) sessionContext.get(SessionContext.AUTH_MANAGER_ID);
+            String auditSubjectID = null;
+
+            if (verified) {
+                // update auditSubjectID
+                if (sessionContext != null) {
+                    auditSubjectID = (String)
+                            sessionContext.get(SessionContext.USER_ID);
+                    CMS.debug(method + "current auditSubjectID was:"+ auditSubjectID);
+                    CMS.debug(method + "identity verified. Updating auditSubjectID");
+                    CMS.debug(method + "updated auditSubjectID is:"+ ident_string);
+                    auditSubjectID = ident_string;
+                    sessionContext.put(SessionContext.USER_ID, auditSubjectID);
+                } else { //very unlikely
+                    CMS.debug(method + "sessionContext null; cannot update auditSubjectID");
+                }
+
+                auditMessage = CMS.getLogMessage(
+                        AuditEvent.CMC_PROOF_OF_IDENTIFICATION,
+                        auditSubjectID,
+                        ILogger.SUCCESS,
+                        "method=" + method);
+                audit(auditMessage);
+            } else {
+                throw new EBaseException("failed to verify");
+            }
+            return verified;
         } catch (Exception e) {
             CMS.debug(method + " Failed with Exception: " + e.toString());
+            auditMessage = CMS.getLogMessage(
+                    AuditEvent.CMC_PROOF_OF_IDENTIFICATION,
+                    auditAttemptedCred,
+                    ILogger.FAILURE,
+                    method + e.toString());
+            audit(auditMessage);
             return false;
         }
 
     } // verifyIdentityProofV2
 
-    private boolean verifyIdentityProof(TaggedAttribute attr, SEQUENCE reqSeq) {
+    private boolean verifyIdentityProof(
+            TaggedAttribute attr, SEQUENCE reqSeq) {
         String method = "verifyIdentityProof: ";
+        boolean verified = false;
 
         SET vals = attr.getValues();
         if (vals.size() < 1)
@@ -1537,7 +1665,11 @@ public abstract class EnrollProfile extends BasicProfile
             byte[] b = ostr.toByteArray();
             byte[] text = ASN1Util.encode(reqSeq);
 
-            return verifyDigest(token.getBytes(), text, b);
+            verified = verifyDigest(token.getBytes(), text, b);
+            if (verified) {// update auditSubjectID
+                //placeholder. Should probably just disable this v1 method
+            }
+            return verified;
     }
 
     public void fillTaggedRequest(Locale locale, TaggedRequest tagreq, X509CertInfo info,
@@ -1592,13 +1724,22 @@ public abstract class EnrollProfile extends BasicProfile
 
                 p10.encode(ostream);
                 PKCS10 pkcs10 = new PKCS10(ostream.toByteArray(), sigver);
+                if (sigver) {
+                    auditMessage = CMS.getLogMessage(
+                            AuditEvent.PROOF_OF_POSSESSION,
+                            auditSubjectID,
+                            ILogger.SUCCESS,
+                            "method="+method);
+                    audit(auditMessage);
+                }
 
                 req.setExtData("bodyPartId", tcr.getBodyPartID());
                 fillPKCS10(locale, pkcs10, info, req);
             } catch (Exception e) {
                 CMS.debug(method + e);
                 // this will throw
-                popFailed(locale, auditSubjectID, auditMessage, e);
+                if (sigver)
+                    popFailed(locale, auditSubjectID, auditMessage, e);
             }  finally {
                 if ((sigver == true) && (tokenSwitched == true)){
                     cm.setThreadToken(savedToken);
@@ -1787,8 +1928,9 @@ public abstract class EnrollProfile extends BasicProfile
     public void fillCertReqMsg(Locale locale, CertReqMsg certReqMsg, X509CertInfo info,
             IRequest req)
             throws EProfileException {
+        String method = "EnrollProfile: fillCertReqMsg: ";
         try {
-            CMS.debug("Start parseCertReqMsg ");
+            CMS.debug(method + "Start parseCertReqMsg ");
             CertRequest certReq = certReqMsg.getCertReq();
             req.setExtData("bodyPartId", certReq.getCertReqId());
             // handle PKIArchiveOption (key archival)
@@ -1897,12 +2039,20 @@ public abstract class EnrollProfile extends BasicProfile
                     extensions = new CertificateExtensions();
                 int numexts = certTemplate.numExtensions();
 
+                /*
+                 * there seems to be an issue with constructor in Extension
+                 * when feeding SubjectKeyIdentifierExtension;
+                 * Special-case it
+                 */
+                OBJECT_IDENTIFIER SKIoid =
+                        new OBJECT_IDENTIFIER(PKIXExtensions.SubjectKey_Id.toString());
                 for (int j = 0; j < numexts; j++) {
                     org.mozilla.jss.pkix.cert.Extension jssext =
                             certTemplate.extensionAt(j);
                     boolean isCritical = jssext.getCritical();
                     org.mozilla.jss.asn1.OBJECT_IDENTIFIER jssoid =
                             jssext.getExtnId();
+                    CMS.debug(method + "found extension:" + jssoid.toString());
                     long[] numbers = jssoid.getNumbers();
                     int[] oidNumbers = new int[numbers.length];
 
@@ -1919,8 +2069,14 @@ public abstract class EnrollProfile extends BasicProfile
                     jssvalue.encode(jssvalueout);
                     byte[] extValue = jssvalueout.toByteArray();
 
-                    Extension ext =
-                            new Extension(oid, isCritical, extValue);
+                    Extension ext = null;
+                    if (jssoid.equals(SKIoid)) {
+                        CMS.debug(method + "found SUBJECT_KEY_IDENTIFIER extension");
+                        ext = new SubjectKeyIdentifierExtension(false,
+                                jssext.getExtnValue().toByteArray());
+                    } else {
+                        new Extension(oid, isCritical, extValue);
+                    }
 
                     extensions.parseExtension(ext);
                 }
@@ -2042,12 +2198,12 @@ public abstract class EnrollProfile extends BasicProfile
                     DerInputStream extIn = new DerInputStream(extB);
                     CertificateExtensions exts = new CertificateExtensions(extIn);
                     if (exts != null) {
-                        CMS.debug(method + "Set extensions " + exts);
+                        CMS.debug(method + "PKCS10 found extensions " + exts);
                         // info.set(X509CertInfo.EXTENSIONS, exts);
                         req.setExtData(REQUEST_EXTENSIONS, exts);
                     }
                 } else {
-                    CMS.debug(method + "PKCS10 extension Not Found");
+                    CMS.debug(method + "PKCS10 no extension found");
                 }
             }
 
@@ -2406,7 +2562,7 @@ public abstract class EnrollProfile extends BasicProfile
         String method = "EnrollProfile: verifyPOP: ";
         CMS.debug(method + "for signing keys begins.");
 
-        String auditMessage = null;
+        String auditMessage = method;
         String auditSubjectID = auditSubjectID();
 
         if (!certReqMsg.hasPop()) {
@@ -2437,7 +2593,8 @@ public abstract class EnrollProfile extends BasicProfile
             auditMessage = CMS.getLogMessage(
                     AuditEvent.PROOF_OF_POSSESSION,
                     auditSubjectID,
-                    ILogger.SUCCESS);
+                    ILogger.SUCCESS,
+                    "method="+method);
             audit(auditMessage);
         } catch (Exception e) {
             CMS.debug(method + "Unable to verify POP: " + e);
@@ -2446,19 +2603,21 @@ public abstract class EnrollProfile extends BasicProfile
         CMS.debug(method + "done.");
     }
 
-    private void popFailed(Locale locale, String auditSubjectID, String auditMessage)
+    private void popFailed(Locale locale, String auditSubjectID, String msg)
             throws EProfileException {
-        popFailed(locale, auditSubjectID, auditMessage, null);
+        popFailed(locale, auditSubjectID, msg, null);
     }
-    private void popFailed(Locale locale, String auditSubjectID, String auditMessage, Exception e)
+    private void popFailed(Locale locale, String auditSubjectID, String msg, Exception e)
             throws EProfileException {
 
+            if (e != null)
+                msg = msg + e.toString();
             // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
+            String auditMessage = CMS.getLogMessage(
                     AuditEvent.PROOF_OF_POSSESSION,
                     auditSubjectID,
-                    ILogger.FAILURE);
-
+                    ILogger.FAILURE,
+                    msg);
             audit(auditMessage);
 
             if (e != null) {
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/CAEnrollDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/CAEnrollDefault.java
index 14484e0..635c044 100644
--- a/base/server/cms/src/com/netscape/cms/profile/def/CAEnrollDefault.java
+++ b/base/server/cms/src/com/netscape/cms/profile/def/CAEnrollDefault.java
@@ -25,6 +25,7 @@ import java.security.cert.CertificateException;
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.cmsutil.crypto.CryptoUtil;
 
 import netscape.security.x509.CertificateX509Key;
 import netscape.security.x509.KeyIdentifier;
@@ -46,30 +47,29 @@ public abstract class CAEnrollDefault extends EnrollDefault {
     }
 
     public KeyIdentifier getKeyIdentifier(X509CertInfo info) {
+        String method = "CAEnrollDefault: getKeyIdentifier: ";
         try {
             CertificateX509Key ckey = (CertificateX509Key)
                     info.get(X509CertInfo.KEY);
             X509Key key = (X509Key) ckey.get(CertificateX509Key.KEY);
-            MessageDigest md = MessageDigest.getInstance("SHA-1");
-
-            md.update(key.getKey());
-            byte[] hash = md.digest();
+            byte[] hash = CryptoUtil.generateKeyIdentifier(key.getKey());
+            if (hash == null) {
+                CMS.debug(method +
+                    "CryptoUtil.generateKeyIdentifier returns null");
+                return null;
+            }
 
             return new KeyIdentifier(hash);
         } catch (IOException e) {
-            CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
-                    e.toString());
+            CMS.debug(method + e.toString());
         } catch (CertificateException e) {
-            CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
-                    e.toString());
-        } catch (NoSuchAlgorithmException e) {
-            CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
-                    e.toString());
+            CMS.debug(method + e.toString());
         }
         return null;
     }
 
     public KeyIdentifier getCAKeyIdentifier(ICertificateAuthority ca) throws EBaseException {
+        String method = "CAEnrollDefault: getCAKeyIdentifier: ";
         X509CertImpl caCert = ca.getCACert();
         if (caCert == null) {
             // during configuration, we dont have the CA certificate
@@ -89,16 +89,11 @@ public abstract class CAEnrollDefault extends EnrollDefault {
             }
         }
 
-        try {
-            MessageDigest md = MessageDigest.getInstance("SHA-1");
-
-            md.update(key.getKey());
-            byte[] hash = md.digest();
-
-            return new KeyIdentifier(hash);
-        } catch (NoSuchAlgorithmException e) {
-            CMS.debug("AuthorityKeyIdentifierExtDefault: getKeyId " +
-                    e.toString());
+        byte[] hash = CryptoUtil.generateKeyIdentifier(key.getKey());
+        if (hash == null) {
+            CMS.debug(method +
+                "CryptoUtil.generateKeyIdentifier returns null");
+            return null;
         }
         return null;
     }
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
index a8f6a74..d787575 100644
--- a/base/server/cms/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
+++ b/base/server/cms/src/com/netscape/cms/profile/def/SubjectKeyIdentifierExtDefault.java
@@ -37,6 +37,7 @@ import com.netscape.certsrv.property.Descriptor;
 import com.netscape.certsrv.property.EPropertyException;
 import com.netscape.certsrv.property.IDescriptor;
 import com.netscape.certsrv.request.IRequest;
+import com.netscape.cmsutil.crypto.CryptoUtil;
 
 /**
  * This class implements an enrollment default policy
@@ -195,22 +196,26 @@ public class SubjectKeyIdentifierExtDefault extends EnrollExtDefault {
     }
 
     public KeyIdentifier getKeyIdentifier(X509CertInfo info) {
+        String method = "SubjectKeyIdentifierExtDefault: getKeyIdentifier: ";
         try {
             CertificateX509Key infokey = (CertificateX509Key)
                     info.get(X509CertInfo.KEY);
             X509Key key = (X509Key) infokey.get(CertificateX509Key.KEY);
-            MessageDigest md = MessageDigest.getInstance("SHA-1");
 
-            md.update(key.getKey());
-            byte[] hash = md.digest();
+            // "SHA-1" is default for CryptoUtil.generateKeyIdentifier.
+            // you could specify different algorithm with the alg parameter
+            // like this:
+            //byte[] hash = CryptoUtil.generateKeyIdentifier(key.getKey(), "SHA-256");
+            byte[] hash = CryptoUtil.generateKeyIdentifier(key.getKey());
 
+            if (hash == null) {
+                CMS.debug(method +
+                    "CryptoUtil.generateKeyIdentifier returns null");
+                return null;
+            }
             return new KeyIdentifier(hash);
-        } catch (NoSuchAlgorithmException e) {
-            CMS.debug("SubjectKeyIdentifierExtDefault: getKeyIdentifier " +
-                    e.toString());
         } catch (Exception e) {
-            CMS.debug("SubjectKeyIdentifierExtDefault: getKeyIdentifier " +
-                    e.toString());
+            CMS.debug(method + e.toString());
         }
         return null;
     }
diff --git a/base/server/cms/src/com/netscape/cms/profile/input/EnrollInput.java b/base/server/cms/src/com/netscape/cms/profile/input/EnrollInput.java
index 84a6398..2affaf3 100644
--- a/base/server/cms/src/com/netscape/cms/profile/input/EnrollInput.java
+++ b/base/server/cms/src/com/netscape/cms/profile/input/EnrollInput.java
@@ -179,26 +179,27 @@ public abstract class EnrollInput implements IProfileInput {
 
     public void verifyPOP(Locale locale, CertReqMsg certReqMsg)
             throws EProfileException {
+        String method = "EnrollInput: verifyPOP: ";
         CMS.debug("EnrollInput ::in verifyPOP");
 
         String auditMessage = null;
         String auditSubjectID = auditSubjectID();
 
         if (!certReqMsg.hasPop()) {
-            CMS.debug("CertReqMsg has not POP, return");
+            CMS.debug(method + "CertReqMsg has not POP, return");
             return;
         }
         ProofOfPossession pop = certReqMsg.getPop();
         ProofOfPossession.Type popType = pop.getType();
 
         if (popType != ProofOfPossession.SIGNATURE) {
-            CMS.debug("not POP SIGNATURE, return");
+            CMS.debug(method + "not POP SIGNATURE, return");
             return;
         }
 
         try {
             if (CMS.getConfigStore().getBoolean("cms.skipPOPVerify", false)) {
-                CMS.debug("skipPOPVerify on, return");
+                CMS.debug(method + "skipPOPVerify on, return");
                 return;
             }
             CMS.debug("POP verification begins:");
@@ -207,10 +208,10 @@ public abstract class EnrollInput implements IProfileInput {
             CryptoToken verifyToken = null;
             String tokenName = CMS.getConfigStore().getString("ca.requestVerify.token", CryptoUtil.INTERNAL_TOKEN_NAME);
             if (CryptoUtil.isInternalToken(tokenName)) {
-                CMS.debug("POP verification using internal token");
+                CMS.debug(method + "POP verification using internal token");
                 certReqMsg.verify();
             } else {
-                CMS.debug("POP verification using token:" + tokenName);
+                CMS.debug(method + "POP verification using token:" + tokenName);
                 verifyToken = CryptoUtil.getCryptoToken(tokenName);
                 certReqMsg.verify(verifyToken);
             }
@@ -219,18 +220,20 @@ public abstract class EnrollInput implements IProfileInput {
             auditMessage = CMS.getLogMessage(
                     AuditEvent.PROOF_OF_POSSESSION,
                     auditSubjectID,
-                    ILogger.SUCCESS);
+                    ILogger.SUCCESS,
+                    "method="+method);
             audit(auditMessage);
         } catch (Exception e) {
 
-            CMS.debug("Failed POP verify! " + e.toString());
+            CMS.debug(method + "Failed POP verify! " + e.toString());
             CMS.debug(e);
 
             // store a message in the signed audit log file
             auditMessage = CMS.getLogMessage(
                     AuditEvent.PROOF_OF_POSSESSION,
                     auditSubjectID,
-                    ILogger.FAILURE);
+                    ILogger.FAILURE,
+                    method + e.toString());
 
             audit(auditMessage);
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/processors/CRMFProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/processors/CRMFProcessor.java
index 70a4a42..c57c532 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/processors/CRMFProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/processors/CRMFProcessor.java
@@ -23,17 +23,6 @@ import java.io.IOException;
 import java.security.InvalidKeyException;
 import java.security.cert.CertificateException;
 
-import netscape.security.util.ObjectIdentifier;
-import netscape.security.x509.CertificateExtensions;
-import netscape.security.x509.CertificateSubjectName;
-import netscape.security.x509.CertificateValidity;
-import netscape.security.x509.CertificateVersion;
-import netscape.security.x509.CertificateX509Key;
-import netscape.security.x509.Extension;
-import netscape.security.x509.X500Name;
-import netscape.security.x509.X509CertInfo;
-import netscape.security.x509.X509Key;
-
 import org.mozilla.jss.asn1.INTEGER;
 import org.mozilla.jss.asn1.InvalidBERException;
 import org.mozilla.jss.asn1.SEQUENCE;
@@ -56,6 +45,17 @@ import com.netscape.certsrv.request.IRequest;
 import com.netscape.cms.servlet.base.CMSServlet;
 import com.netscape.cms.servlet.common.ECMSGWException;
 
+import netscape.security.util.ObjectIdentifier;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
 /**
  * Process CRMF requests, according to RFC 2511
  * See http://www.ietf.org/rfc/rfc2511.txt
@@ -98,6 +98,7 @@ public class CRMFProcessor extends PKIProcessor {
      */
     private void verifyPOP(CertReqMsg certReqMsg)
             throws EBaseException {
+        String method = "CRMFProcessor: verifyPOP: ";
         String auditMessage = null;
         String auditSubjectID = auditSubjectID();
 
@@ -118,7 +119,8 @@ public class CRMFProcessor extends PKIProcessor {
                         auditMessage = CMS.getLogMessage(
                                 AuditEvent.PROOF_OF_POSSESSION,
                                 auditSubjectID,
-                                ILogger.SUCCESS);
+                                ILogger.SUCCESS,
+                                "method=" + method);
 
                         audit(auditMessage);
                     } catch (Exception e) {
@@ -131,7 +133,8 @@ public class CRMFProcessor extends PKIProcessor {
                         auditMessage = CMS.getLogMessage(
                                 AuditEvent.PROOF_OF_POSSESSION,
                                 auditSubjectID,
-                                ILogger.FAILURE);
+                                ILogger.FAILURE,
+                                method + e.toString());
 
                         audit(auditMessage);
 
@@ -148,7 +151,8 @@ public class CRMFProcessor extends PKIProcessor {
                     auditMessage = CMS.getLogMessage(
                             AuditEvent.PROOF_OF_POSSESSION,
                             auditSubjectID,
-                            ILogger.FAILURE);
+                            ILogger.FAILURE,
+                            method + "required POP missing");
 
                     audit(auditMessage);
 
@@ -161,7 +165,8 @@ public class CRMFProcessor extends PKIProcessor {
             auditMessage = CMS.getLogMessage(
                     AuditEvent.PROOF_OF_POSSESSION,
                     auditSubjectID,
-                    ILogger.FAILURE);
+                    ILogger.FAILURE,
+                    method + eAudit1.toString());
 
             audit(auditMessage);
         }
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
index 0e101ed..93039a4 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java
@@ -39,12 +39,16 @@ import org.mozilla.jss.pkix.cmc.OtherInfo;
 import org.mozilla.jss.pkix.cmc.TaggedAttribute;
 
 import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.EInvalidCredentials;
+import com.netscape.certsrv.authentication.EMissingCredential;
 import com.netscape.certsrv.authentication.IAuthManager;
 import com.netscape.certsrv.authentication.IAuthToken;
 import com.netscape.certsrv.authorization.AuthzToken;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.SessionContext;
 import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.event.AuthFailEvent;
+import com.netscape.certsrv.logging.event.AuthSuccessEvent;
 import com.netscape.certsrv.logging.event.CertRequestProcessedEvent;
 import com.netscape.certsrv.profile.EDeferException;
 import com.netscape.certsrv.profile.EProfileException;
@@ -143,6 +147,7 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
 
     public IAuthToken authenticate(IProfileAuthenticator authenticator,
             HttpServletRequest request) throws EBaseException {
+        String method = "ProfileSubmitCMCServlet: authenticate: ";
         AuthCredentials credentials = new AuthCredentials();
 
         // build credential
@@ -158,15 +163,47 @@ public class ProfileSubmitCMCServlet extends ProfileServlet {
                     credentials.set(authName, request.getParameter(authName));
             }
         }
-        IAuthToken authToken = authenticator.authenticate(credentials);
 
+        IAuthToken authToken = null;
+        String auditSubjectID = null;
+        String authMgrID = authenticator.getName();
         SessionContext sc = SessionContext.getContext();
-        if (sc != null) {
-            sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName());
-            String userid = authToken.getInString(IAuthToken.USER_ID);
-            if (userid != null) {
-                sc.put(SessionContext.USER_ID, userid);
+
+        try {
+            authToken = authenticator.authenticate(credentials);
+            if (sc != null) {
+                sc.put(SessionContext.AUTH_MANAGER_ID, authMgrID);
+                auditSubjectID = authToken.getInString(IAuthToken.USER_ID);
+                if (auditSubjectID != null) {
+                    CMS.debug(method + "setting auditSubjectID in SessionContext:" +
+                            auditSubjectID);
+                    sc.put(SessionContext.USER_ID, auditSubjectID);
+                } else {
+                    CMS.debug(method + "no auditSubjectID found in authToken");
+                }
+            }
+
+            if (!auditSubjectID.equals(ILogger.UNIDENTIFIED) &&
+                    !auditSubjectID.equals(ILogger.NONROLEUSER)) {
+                audit(new AuthSuccessEvent(
+                        auditSubjectID,
+                        ILogger.SUCCESS,
+                        authMgrID));
+            }
+
+        } catch (EBaseException e) {
+            CMS.debug(method + e);
+            String attempted_auditSubjectID = null;
+            if (sc != null) {
+                attempted_auditSubjectID =
+                        (String) sc.get(SessionContext.USER_ID);
             }
+            audit(new AuthFailEvent(
+                    auditSubjectID,
+                    ILogger.FAILURE,
+                    authMgrID,
+                    attempted_auditSubjectID));
+            throw(e);
         }
 
         return authToken;
diff --git a/base/server/cmsbundle/src/LogMessages.properties b/base/server/cmsbundle/src/LogMessages.properties
index 1a5b37a..6bc2d82 100644
--- a/base/server/cmsbundle/src/LogMessages.properties
+++ b/base/server/cmsbundle/src/LogMessages.properties
@@ -2181,9 +2181,18 @@ LOGGING_SIGNED_AUDIT_AUTH_SUCCESS_3=<type=AUTH_SUCCESS>:[AuditEvent=AUTH_SUCCESS
 LOGGING_SIGNED_AUDIT_CERT_PROFILE_APPROVAL_4=<type=CERT_PROFILE_APPROVAL>:[AuditEvent=CERT_PROFILE_APPROVAL][SubjectID={0}][Outcome={1}][ProfileID={2}][Op={3}] certificate approval
 #
 # LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION
-# - used when proof of possession is checked during certificate enrollment
+# - used for proof of possession during certificate enrollment processing
 #
-LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_2=<type=PROOF_OF_POSSESSION>:[AuditEvent=PROOF_OF_POSSESSION][SubjectID={0}][Outcome={1}] checking proof of possession
+LOGGING_SIGNED_AUDIT_PROOF_OF_POSSESSION_3=<type=PROOF_OF_POSSESSION>:[AuditEvent=PROOF_OF_POSSESSION][SubjectID={0}][Outcome={1}][Info={2}] proof of possession
+# LOGGING_SIGNED_AUDIT_CMC_PROOF_OF_IDENTIFICATION
+# - used for proof of identification during CMC request processing
+# - In case of success, "SubjectID" is the actual identified identification;
+# - In case of failure, "SubjectID" is the attempted identification
+#
+LOGGING_SIGNED_AUDIT_CMC_PROOF_OF_IDENTIFICATION_3=<type=CMC_PROOF_OF_IDENTIFICATION>:[AuditEvent=CMC_PROOF_OF_IDENTIFICATION][SubjectID={0}][Outcome={1}][Info={2}] proof of identification in CMC request
+# - used for identification and POP linking verification during CMC request processing
+#
+LOGGING_SIGNED_AUDIT_CMC_ID_POP_LINK_WITNESS_3=<type=CMC_ID_POP_LINK_WITNESS>:[AuditEvent=CMC_ID_POP_LINK_WITNESS][SubjectID={0}][Outcome={1}][Info={2}] Identification Proof of Possession linking witness verification
 #
 # LOGGING_SIGNED_AUDIT_CRL_RETRIEVAL
 # - used when CRLs are retrieved by the OCSP Responder
@@ -2235,7 +2244,16 @@ LOGGING_SIGNED_AUDIT_OCSP_REMOVE_CA_REQUEST_PROCESSED_FAILURE_3=<type=OCSP_REMOV
 # SignerInfo must be a unique String representation for the signer
 #
 LOGGING_SIGNED_AUDIT_CMC_SIGNED_REQUEST_SIG_VERIFY_5=<type=CMC_SIGNED_REQUEST_SIG_VERIFY>:[AuditEvent=CMC_SIGNED_REQUEST_SIG_VERIFY][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][SignerInfo={4}] agent pre-approved CMC request signature verification
-LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_5=<type=CMC_USER_SIGNED_REQUEST_SIG_VERIFY>:[AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][SignerInfo={4}] User signed CMC request signature verification
+#
+# LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY
+# - used when CMC (user-signed or self-signed) certificate requests or revocation requests
+#   are submitted and signature is verified
+# ReqType must be the request type (enrollment, or revocation)
+# CertSubject must be the certificate subject name of the certificate request
+# SignerInfo must be a unique String representation for the signer
+#
+LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS_5=<type=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS>:[AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_SUCCESS][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][SignerInfo={4}] User signed CMC request signature verification success
+LOGGING_SIGNED_AUDIT_CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE_6=<type=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE>:[AuditEvent=CMC_USER_SIGNED_REQUEST_SIG_VERIFY_FAILURE][SubjectID={0}][Outcome={1}][ReqType={2}][CertSubject={3}][SignerInfo={4}][info={5}] User signed CMC request signature verification failure
 
 # LOGGING_SIGNED_AUDIT_COMPUTE_RANDOM_DATA_REQUEST 
 # - used for TPS to TKS to get random challenge data
diff --git a/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java b/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java
index 6dabd0c..177d540 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java
@@ -1032,13 +1032,17 @@ public class KeyCertUtil {
 
     public static KeyIdentifier createKeyIdentifier(KeyPair keypair)
             throws NoSuchAlgorithmException, InvalidKeyException {
-        MessageDigest md = MessageDigest.getInstance("SHA-1");
         X509Key subjectKeyInfo = convertPublicKeyToX509Key(
                 keypair.getPublic());
 
-        //md.update(subjectKeyInfo.getEncoded());
-        md.update(subjectKeyInfo.getKey());
-        return new KeyIdentifier(md.digest());
+        byte[] hash = CryptoUtil.generateKeyIdentifier(subjectKeyInfo.getKey());
+
+        if (hash == null) {
+            CMS.debug("KeyCertUtil: createKeyIdentifier " +
+                "CryptoUtil.generateKeyIdentifier returns null");
+            return null;
+        }
+        return new KeyIdentifier(hash);
     }
 
     public static BigInteger getSerialNumber(LDAPConnection conn, String baseDN)
diff --git a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
index e529a0f..8b8c443 100644
--- a/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
+++ b/base/util/src/com/netscape/cmsutil/crypto/CryptoUtil.java
@@ -27,6 +27,7 @@ import java.net.SocketException;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
+import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.PublicKey;
@@ -127,6 +128,7 @@ import netscape.security.util.DerValue;
 import netscape.security.util.ObjectIdentifier;
 import netscape.security.util.WrappingParams;
 import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CertAttrSet;
 import netscape.security.x509.CertificateAlgorithmId;
 import netscape.security.x509.CertificateChain;
 import netscape.security.x509.CertificateExtensions;
@@ -136,7 +138,11 @@ import netscape.security.x509.CertificateSubjectName;
 import netscape.security.x509.CertificateValidity;
 import netscape.security.x509.CertificateVersion;
 import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.Extension;
 import netscape.security.x509.Extensions;
+import netscape.security.x509.KeyIdentifier;
+import netscape.security.x509.PKIXExtensions;
+import netscape.security.x509.SubjectKeyIdentifierExtension;
 import netscape.security.x509.X500Name;
 import netscape.security.x509.X500Signer;
 import netscape.security.x509.X509CertImpl;
@@ -1536,10 +1542,33 @@ public class CryptoUtil {
      * This createCertificationRequest() allows extensions to be added to the CSR
      */
     public static PKCS10 createCertificationRequest(String subjectName,
+            KeyPair keyPair, Extensions exts)
+            throws NoSuchAlgorithmException, NoSuchProviderException,
+            InvalidKeyException, IOException, CertificateException,
+            SignatureException {
+        String method = "CryptoUtil: createCertificationRequest: ";
+
+        String alg = "SHA256withRSA";
+        PublicKey pubk = keyPair.getPublic();
+        X509Key key = convertPublicKeyToX509Key(pubk);
+        if (pubk instanceof RSAPublicKey) {
+            alg = "SHA256withRSA";
+        } else if (isECCKey(key)) {
+            alg = "SHA256withEC";
+        } else {
+            throw new NoSuchAlgorithmException(method + alg);
+        }
+
+        return createCertificationRequest(
+                subjectName, key, (org.mozilla.jss.crypto.PrivateKey) keyPair.getPrivate(),
+                alg, exts);
+    }
+
+    public static PKCS10 createCertificationRequest(String subjectName,
             X509Key pubk, PrivateKey prik, String alg, Extensions exts)
             throws NoSuchAlgorithmException, NoSuchProviderException,
-                InvalidKeyException, IOException, CertificateException,
-                SignatureException {
+            InvalidKeyException, IOException, CertificateException,
+            SignatureException {
         X509Key key = pubk;
         java.security.Signature sig = java.security.Signature.getInstance(alg,
                 "Mozilla-JSS");
@@ -1548,11 +1577,12 @@ public class CryptoUtil {
         PKCS10 pkcs10 = null;
 
         if (exts != null && !exts.isEmpty()) {
-            PKCS10Attribute attr = new
-                    PKCS10Attribute(PKCS9Attribute.EXTENSION_REQUEST_OID,
-                            exts);
+            PKCS10Attribute attr = new PKCS10Attribute(PKCS9Attribute.EXTENSION_REQUEST_OID,
+                    exts);
             PKCS10Attributes attrs = new PKCS10Attributes();
 
+            System.out.println("PKCS10: createCertificationRequest: adding attribute name =" +
+                    attr.getAttributeValue().getName());
             attrs.setAttribute(attr.getAttributeValue().getName(), attr);
 
             pkcs10 = new PKCS10(key, attrs);
@@ -1566,6 +1596,51 @@ public class CryptoUtil {
         return pkcs10;
     }
 
+    public static KeyIdentifier createKeyIdentifier(KeyPair keypair)
+            throws NoSuchAlgorithmException, InvalidKeyException {
+        String method = "CryptoUtil: createKeyIdentifier: ";
+        System.out.println(method + "begins");
+
+        X509Key subjectKeyInfo = convertPublicKeyToX509Key(
+                keypair.getPublic());
+
+        byte[] hash = generateKeyIdentifier(subjectKeyInfo.getKey());
+
+        if (hash == null) {
+            System.out.println(method +
+                    "generateKeyIdentifier returns null");
+            return null;
+        }
+        return new KeyIdentifier(hash);
+    }
+
+    public static byte[] generateKeyIdentifier(byte[] rawKey) {
+        return generateKeyIdentifier(rawKey, null);
+    }
+
+    public static byte[] generateKeyIdentifier(byte[] rawKey, String alg) {
+        String method = "CryptoUtil: generateKeyIdentifier: ";
+        String msg = "";
+        if (alg == null) {
+            alg = "SHA-1";
+        }
+        try {
+            MessageDigest md = MessageDigest.getInstance(alg);
+
+            md.update(rawKey);
+            byte[] hash = md.digest();
+
+            return hash;
+        } catch (NoSuchAlgorithmException e) {
+            msg = method + e;
+            System.out.println(msg);
+        } catch (Exception e) {
+            msg = method + e;
+            System.out.println(msg);
+        }
+        return null;
+    }
+
     /**
      * Creates a PKCS#10 request.
      */
@@ -1611,6 +1686,102 @@ public class CryptoUtil {
         return pkcs10;
     }
 
+    /*
+     * get extention from  PKCS10 request
+     */
+    public static netscape.security.x509.Extension getExtensionFromPKCS10(PKCS10 pkcs10, String extnName)
+            throws IOException, CertificateException {
+        Extension extn = null;
+
+        String method = "CryptoUtiil: getExtensionFromPKCS10: ";
+        System.out.println(method + "begins");
+
+        PKCS10Attributes attributeSet = pkcs10.getAttributes();
+        if (attributeSet == null) {
+            System.out.println(method + "attributeSet not found");
+            return null;
+        }
+        PKCS10Attribute attr = attributeSet.getAttribute("extensions");
+        if (attr == null) {
+            System.out.println(method + "extensions attribute not found");
+            return null;
+        }
+        System.out.println(method + attr.toString());
+
+        CertAttrSet cas = attr.getAttributeValue();
+        if (cas == null) {
+            System.out.println(method + "CertAttrSet not found in PKCS10Attribute");
+            return null;
+        }
+
+        Enumeration<String> en = cas.getAttributeNames();
+        while (en.hasMoreElements()) {
+            String name = en.nextElement();
+            System.out.println(method + " checking extension in request:" + name);
+            if (name.equals(extnName)) {
+                System.out.println(method + "extension matches");
+                extn = (Extension)cas.get(name);
+            }
+        }
+
+        System.out.println(method + "ends");
+        return extn;
+    }
+
+    /*
+     * get extension from CRMF cert request (CertTemplate)
+     */
+    public static netscape.security.x509.Extension getExtensionFromCertTemplate(CertTemplate certTemplate, ObjectIdentifier csOID) {
+        //ObjectIdentifier csOID = PKIXExtensions.SubjectKey_Id;
+        OBJECT_IDENTIFIER jssOID =
+                new OBJECT_IDENTIFIER(csOID.toString());
+/*
+        return getExtensionFromCertTemplate(certTemplate, jssOID);
+    }
+    public static netscape.security.x509.Extension getExtensionFromCertTemplate(CertTemplate certTemplate, org.mozilla.jss.asn1.OBJECT_IDENTIFIER jssOID) {
+*/
+
+        String method = "CryptoUtil: getSKIExtensionFromCertTemplate: ";
+        Extension extn = null;
+
+       /*
+        * there seems to be an issue with constructor in Extension
+        * when feeding SubjectKeyIdentifierExtension;
+        * Special-case it
+        */
+        OBJECT_IDENTIFIER SKIoid =
+                new OBJECT_IDENTIFIER(PKIXExtensions.SubjectKey_Id.toString());
+
+        if (certTemplate.hasExtensions()) {
+            int numexts = certTemplate.numExtensions();
+            for (int j = 0; j < numexts; j++) {
+                 org.mozilla.jss.pkix.cert.Extension jssext =
+                         certTemplate.extensionAt(j);
+                 org.mozilla.jss.asn1.OBJECT_IDENTIFIER extnoid =
+                         jssext.getExtnId();
+                 System.out.println(method + "checking extension in request:" + extnoid.toString());
+                 if (extnoid.equals(jssOID)) {
+                     System.out.println(method + "extension found");
+                     try {
+                       if (jssOID.equals(SKIoid)) {
+                         extn =
+                             new SubjectKeyIdentifierExtension(false, jssext.getExtnValue().toByteArray());
+                       } else {
+                         extn =
+                             new netscape.security.x509.Extension(csOID, false, jssext.getExtnValue().toByteArray());
+                       }
+                     } catch (IOException e) {
+                       System.out.println(method + e);
+                     }
+                 }
+            }
+        } else {
+            System.out.println(method + "no extension found");
+        }
+
+        return extn;
+    }
+
     public static void unTrustCert(InternalCertificate cert) {
         // remove TRUSTED_CA
         int flag = cert.getSSLTrust();
diff --git a/base/util/src/netscape/security/pkcs/PKCS10.java b/base/util/src/netscape/security/pkcs/PKCS10.java
index 0702e82..10933b0 100644
--- a/base/util/src/netscape/security/pkcs/PKCS10.java
+++ b/base/util/src/netscape/security/pkcs/PKCS10.java
@@ -123,6 +123,13 @@ public class PKCS10 {
         byte sigData[];
         Signature sig;
 
+        String method = "PKCS10: PKCS10: ";
+        String msg = "";
+
+        System.out.println(method + "begins");
+        if (data == null) {
+            throw new IllegalArgumentException(method + "param data cann't be null");
+        }
         certificateRequest = data;
 
         //
@@ -131,9 +138,12 @@ public class PKCS10 {
         //
         in = new DerInputStream(data);
         seq = in.getSequence(3);
+        if (seq == null) {
+            throw new IllegalArgumentException(method + "in.getSequence null");
+        }
 
         if (seq.length != 3)
-            throw new IllegalArgumentException("not a PKCS #10 request");
+            throw new IllegalArgumentException(method + "not a PKCS #10 request");
 
         data = seq[0].toByteArray(); // reusing this variable
         certRequestInfo = seq[0].toByteArray(); // make a copy
@@ -152,20 +162,22 @@ public class PKCS10 {
         */
 
         subject = new X500Name(seq[0].data);
+        msg = "Request Subject: " + subject + ": ";
 
         byte val1[] = seq[0].data.getDerValue().toByteArray();
         subjectPublicKeyInfo = X509Key.parse(new DerValue(val1));
         PublicKey publicKey = X509Key.parsePublicKey(new DerValue(val1));
         if (publicKey == null) {
-            System.out.println("PKCS10: publicKey null");
-            throw new SignatureException ("publicKey null");
+            System.out.println(method + msg + "publicKey null");
+            throw new SignatureException (method + msg + "publicKey null");
         }
 
         // Cope with a somewhat common illegal PKCS #10 format
-        if (seq[0].data.available() != 0)
+        if (seq[0].data.available() != 0) {
             attributeSet = new PKCS10Attributes(seq[0].data);
-        else
+        } else {
             attributeSet = new PKCS10Attributes();
+        }
 
         //
         // OK, we parsed it all ... validate the signature using the
@@ -202,14 +214,15 @@ public class PKCS10 {
                 sig.initVerify(publicKey);
                 sig.update(data);
                 if (!sig.verify(sigData)) {
-                System.out.println("PKCS10: sig.verify() failed");
-                    throw new SignatureException("Invalid PKCS #10 signature");
+                    System.out.println(method + msg + "sig.verify() failed");
+                        throw new SignatureException(method + msg + "Invalid PKCS #10 signature");
                 }
             }
         } catch (InvalidKeyException e) {
-            System.out.println("PKCS10: "+ e.toString());
-            throw new SignatureException("invalid key");
+            System.out.println(method + msg + e.toString());
+            throw new SignatureException(method + msg + "invalid key");
         }
+        System.out.println(method + "ends");
     }
 
     public PKCS10(byte data[])
diff --git a/base/util/src/netscape/security/pkcs/PKCS10Attributes.java b/base/util/src/netscape/security/pkcs/PKCS10Attributes.java
index 4c97218..45d5695 100644
--- a/base/util/src/netscape/security/pkcs/PKCS10Attributes.java
+++ b/base/util/src/netscape/security/pkcs/PKCS10Attributes.java
@@ -66,6 +66,8 @@ public class PKCS10Attributes extends Vector<PKCS10Attribute> implements DerEnco
             for (int i = 0; i < attrs.length; i++) {
                 PKCS10Attribute attr = new PKCS10Attribute(attrs[i]);
                 addElement(attr);
+                System.out.println("PKCS10Attributes: adding attribute: " +
+                        attr.getAttributeValue().getName());
                 map.put(attr.getAttributeValue().getName(), attr);
             }
         }
-- 
1.8.3.1


From 8751cd2c5cc0c41c5d85724fddfd5d872ad994ed Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 16:30:52 +0200
Subject: [PATCH 17/27] Fixed CERT_REQUEST_PROCESSED events in
 ConnectorServlet.

The code that generates CERT_REQUEST_PROCESSED events in
ConnectorServlet.processRequest() has been moved into a finally-
clause that wraps around IRequestQueue.processRequest() to ensure
that the events are generated properly.

If a cert was issued for the request that has just been processed
the event outcome is a Success, otherwise it's a Failure.

Any exception thrown by the IRequestQueue.processRequest() will be
passed to the ConnectorServlet.processRequest()'s callers.

https://pagure.io/dogtagpki/issue/2690

Change-Id: I07454afb75328fbee3e50e5852adb5085be0613e
---
 .../cms/servlet/connector/ConnectorServlet.java       | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
index eeb640e..82f3071 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
@@ -617,6 +617,8 @@ public class ConnectorServlet extends CMSServlet {
             try {
                 queue.processRequest(thisreq);
 
+            } finally {
+
                 if (isProfileRequest(thisreq)) {
 
                     X509CertImpl x509cert = thisreq.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
@@ -629,28 +631,17 @@ public class ConnectorServlet extends CMSServlet {
                                 auditRequesterID,
                                 ILogger.SIGNED_AUDIT_ACCEPTANCE,
                                 x509cert));
-                    }
-                }
 
-            } catch (EBaseException eAudit1) {
-                if (isProfileRequest(thisreq)) {
-
-                    X509CertImpl x509cert = thisreq.getExtDataInCert(IEnrollProfile.REQUEST_ISSUED_CERT);
-
-                    if (x509cert != null) {
+                    } else {
 
                         audit(new CertRequestProcessedEvent(
                                 auditSubjectID,
                                 ILogger.FAILURE,
                                 auditRequesterID,
-                                ILogger.SIGNED_AUDIT_ACCEPTANCE,
-                                x509cert));
+                                ILogger.SIGNED_AUDIT_REJECTION,
+                                ILogger.SIGNED_AUDIT_EMPTY_VALUE));
                     }
                 }
-
-                // rethrow EBaseException to primary catch clause
-                // within this method
-                throw eAudit1;
             }
 
             replymsg = CMS.getHttpPKIMessage();
-- 
1.8.3.1


From 579ed7eed16c9fc6e02928f71656d2a326d68c22 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 16 May 2017 02:42:12 +0200
Subject: [PATCH 18/27] Added CertStatusChangeRequestProcessedEvent.

A new CertStatusChangeRequestProcessedEvent class has been added to
encapsulate the CERT_STATUS_CHANGE_REQUEST_PROCESSED events.

https://pagure.io/dogtagpki/issue/2636

Change-Id: I41cf0ce94b176a2036b9f1f433212bf3c414fb0b
---
 .../com/netscape/certsrv/logging/AuditEvent.java   |  2 -
 .../CertStatusChangeRequestProcessedEvent.java     | 52 ++++++++++++++++++++
 .../cms/servlet/cert/CMCRevReqServlet.java         | 55 +++++++++-------------
 .../com/netscape/cms/servlet/cert/DoRevokeTPS.java | 33 +++++--------
 .../netscape/cms/servlet/cert/DoUnrevokeTPS.java   | 17 +++----
 .../cms/servlet/cert/RevocationProcessor.java      |  8 ++--
 6 files changed, 98 insertions(+), 69 deletions(-)
 create mode 100644 base/common/src/com/netscape/certsrv/logging/event/CertStatusChangeRequestProcessedEvent.java

diff --git a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
index 059363e..21cac27 100644
--- a/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
+++ b/base/common/src/com/netscape/certsrv/logging/AuditEvent.java
@@ -105,8 +105,6 @@ public class AuditEvent implements IBundleLogEvent {
             "LOGGING_SIGNED_AUDIT_PROFILE_CERT_REQUEST_5";
     public final static String CERT_STATUS_CHANGE_REQUEST =
             "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_5";
-    public final static String CERT_STATUS_CHANGE_REQUEST_PROCESSED =
-            "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
 
     public final static String AUTHZ_SUCCESS =
             "LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS_4";
diff --git a/base/common/src/com/netscape/certsrv/logging/event/CertStatusChangeRequestProcessedEvent.java b/base/common/src/com/netscape/certsrv/logging/event/CertStatusChangeRequestProcessedEvent.java
new file mode 100644
index 0000000..f583ad2
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/logging/event/CertStatusChangeRequestProcessedEvent.java
@@ -0,0 +1,52 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2017 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.logging.event;
+
+import com.netscape.certsrv.logging.AuditEvent;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.RequestStatus;
+
+public class CertStatusChangeRequestProcessedEvent extends AuditEvent {
+
+    private static final long serialVersionUID = 1L;
+
+    public final static String LOGGING_PROPERTY =
+            "LOGGING_SIGNED_AUDIT_CERT_STATUS_CHANGE_REQUEST_PROCESSED_7";
+
+    public CertStatusChangeRequestProcessedEvent(
+            String subjectID,
+            String outcome,
+            String requesterID,
+            String serialNumber,
+            String requestType,
+            String reasonNum,
+            RequestStatus approvalStatus) {
+
+        super(LOGGING_PROPERTY);
+
+        setParameters(new Object[] {
+                subjectID,
+                outcome,
+                requesterID,
+                serialNumber,
+                requestType,
+                reasonNum,
+                approvalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : approvalStatus.toString()
+        });
+    }
+}
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
index f4d7f8f..24ba494 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CMCRevReqServlet.java
@@ -31,13 +31,6 @@ import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import netscape.security.x509.CRLExtensions;
-import netscape.security.x509.CRLReasonExtension;
-import netscape.security.x509.InvalidityDateExtension;
-import netscape.security.x509.RevocationReason;
-import netscape.security.x509.RevokedCertImpl;
-import netscape.security.x509.X509CertImpl;
-
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.authentication.AuthToken;
 import com.netscape.certsrv.authentication.EMissingCredential;
@@ -56,6 +49,7 @@ import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
 import com.netscape.certsrv.logging.AuditEvent;
 import com.netscape.certsrv.logging.AuditFormat;
 import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.event.CertStatusChangeRequestProcessedEvent;
 import com.netscape.certsrv.publish.IPublisherProcessor;
 import com.netscape.certsrv.ra.IRegistrationAuthority;
 import com.netscape.certsrv.request.IRequest;
@@ -69,6 +63,13 @@ import com.netscape.cms.servlet.common.CMSTemplateParams;
 import com.netscape.cms.servlet.common.ECMSGWException;
 import com.netscape.cmsutil.util.Utils;
 
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.InvalidityDateExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X509CertImpl;
+
 /**
  * Revoke a certificate with a CMC-formatted revocation request
  *
@@ -810,17 +811,15 @@ public class CMCRevReqServlet extends CMSServlet {
             if (auditApprovalStatus == RequestStatus.COMPLETE ||
                     auditApprovalStatus == RequestStatus.REJECTED ||
                     auditApprovalStatus == RequestStatus.CANCELED) {
-                auditMessage = CMS.getLogMessage(
-                        AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                audit(new CertStatusChangeRequestProcessedEvent(
                         auditSubjectID,
                         ILogger.SUCCESS,
                         auditRequesterID,
                         auditSerialNumber,
                         auditRequestType,
                         auditReasonNum,
-                        auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                audit(auditMessage);
+                        auditApprovalStatus));
             }
 
         } catch (CertificateException e) {
@@ -844,17 +843,15 @@ public class CMCRevReqServlet extends CMSServlet {
                 if (auditApprovalStatus == RequestStatus.COMPLETE ||
                         auditApprovalStatus == RequestStatus.REJECTED ||
                         auditApprovalStatus == RequestStatus.CANCELED) {
-                    auditMessage = CMS.getLogMessage(
-                            AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                    audit(new CertStatusChangeRequestProcessedEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
                             auditRequesterID,
                             auditSerialNumber,
                             auditRequestType,
                             auditReasonNum,
-                            auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                    audit(auditMessage);
+                            auditApprovalStatus));
                 }
             }
 
@@ -882,17 +879,15 @@ public class CMCRevReqServlet extends CMSServlet {
                 if (auditApprovalStatus == RequestStatus.COMPLETE ||
                         auditApprovalStatus == RequestStatus.REJECTED ||
                         auditApprovalStatus == RequestStatus.CANCELED) {
-                    auditMessage = CMS.getLogMessage(
-                            AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                    audit(new CertStatusChangeRequestProcessedEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
                             auditRequesterID,
                             auditSerialNumber,
                             auditRequestType,
                             auditReasonNum,
-                            auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                    audit(auditMessage);
+                            auditApprovalStatus));
                 }
             }
 
@@ -921,17 +916,15 @@ public class CMCRevReqServlet extends CMSServlet {
                 if (auditApprovalStatus == RequestStatus.COMPLETE ||
                         auditApprovalStatus == RequestStatus.REJECTED ||
                         auditApprovalStatus == RequestStatus.CANCELED) {
-                    auditMessage = CMS.getLogMessage(
-                            AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                    audit(new CertStatusChangeRequestProcessedEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
                             auditRequesterID,
                             auditSerialNumber,
                             auditRequestType,
                             auditReasonNum,
-                            auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                    audit(auditMessage);
+                            auditApprovalStatus));
                 }
             }
 
@@ -957,17 +950,15 @@ public class CMCRevReqServlet extends CMSServlet {
                 if (auditApprovalStatus == RequestStatus.COMPLETE ||
                         auditApprovalStatus == RequestStatus.REJECTED ||
                         auditApprovalStatus == RequestStatus.CANCELED) {
-                    auditMessage = CMS.getLogMessage(
-                            AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                    audit(new CertStatusChangeRequestProcessedEvent(
                             auditSubjectID,
                             ILogger.FAILURE,
                             auditRequesterID,
                             auditSerialNumber,
                             auditRequestType,
                             auditReasonNum,
-                            auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                    audit(auditMessage);
+                            auditApprovalStatus));
                 }
             }
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java b/base/server/cms/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
index 68ac6da..a9a6238 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/DoRevokeTPS.java
@@ -49,6 +49,7 @@ import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
 import com.netscape.certsrv.logging.AuditEvent;
 import com.netscape.certsrv.logging.AuditFormat;
 import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.event.CertStatusChangeRequestProcessedEvent;
 import com.netscape.certsrv.publish.IPublisherProcessor;
 import com.netscape.certsrv.request.IRequest;
 import com.netscape.certsrv.request.IRequestQueue;
@@ -557,17 +558,15 @@ public class DoRevokeTPS extends CMSServlet {
                     if (auditApprovalStatus == RequestStatus.COMPLETE ||
                             auditApprovalStatus == RequestStatus.REJECTED ||
                             auditApprovalStatus == RequestStatus.CANCELED) {
-                        auditMessage = CMS.getLogMessage(
-                                    AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                        audit(new CertStatusChangeRequestProcessedEvent(
                                     auditSubjectID,
                                     ILogger.FAILURE,
                                     auditRequesterID,
                                     auditSerialNumber,
                                     auditRequestType,
                                     auditReasonNum,
-                                    auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                        audit(auditMessage);
+                                    auditApprovalStatus));
                     }
 
                     return;
@@ -748,17 +747,15 @@ public class DoRevokeTPS extends CMSServlet {
             if (auditApprovalStatus == RequestStatus.COMPLETE ||
                     auditApprovalStatus == RequestStatus.REJECTED ||
                     auditApprovalStatus == RequestStatus.CANCELED) {
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                audit(new CertStatusChangeRequestProcessedEvent(
                             auditSubjectID,
                             ILogger.SUCCESS,
                             auditRequesterID,
                             auditSerialNumber,
                             auditRequestType,
                             auditReasonNum,
-                            auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                audit(auditMessage);
+                            auditApprovalStatus));
             }
         } catch (EBaseException e) {
             log(ILogger.LL_FAILURE, "error " + e);
@@ -783,17 +780,15 @@ public class DoRevokeTPS extends CMSServlet {
                 if (auditApprovalStatus == RequestStatus.COMPLETE ||
                         auditApprovalStatus == RequestStatus.REJECTED ||
                         auditApprovalStatus == RequestStatus.CANCELED) {
-                    auditMessage = CMS.getLogMessage(
-                                AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                    audit(new CertStatusChangeRequestProcessedEvent(
                                 auditSubjectID,
                                 ILogger.FAILURE,
                                 auditRequesterID,
                                 auditSerialNumber,
                                 auditRequestType,
                                 auditReasonNum,
-                                auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                    audit(auditMessage);
+                                auditApprovalStatus));
                 }
             }
 
@@ -822,17 +817,15 @@ public class DoRevokeTPS extends CMSServlet {
                 if (auditApprovalStatus == RequestStatus.COMPLETE ||
                         auditApprovalStatus == RequestStatus.REJECTED ||
                         auditApprovalStatus == RequestStatus.CANCELED) {
-                    auditMessage = CMS.getLogMessage(
-                                AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                    audit(new CertStatusChangeRequestProcessedEvent(
                                 auditSubjectID,
                                 ILogger.FAILURE,
                                 auditRequesterID,
                                 auditSerialNumber,
                                 auditRequestType,
                                 auditReasonNum,
-                                auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                    audit(auditMessage);
+                                auditApprovalStatus));
                 }
             }
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java b/base/server/cms/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
index 30bde76..36a6802 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/DoUnrevokeTPS.java
@@ -46,6 +46,7 @@ import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
 import com.netscape.certsrv.logging.AuditEvent;
 import com.netscape.certsrv.logging.AuditFormat;
 import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.event.CertStatusChangeRequestProcessedEvent;
 import com.netscape.certsrv.publish.IPublisherProcessor;
 import com.netscape.certsrv.request.IRequest;
 import com.netscape.certsrv.request.IRequestQueue;
@@ -461,17 +462,15 @@ public class DoUnrevokeTPS extends CMSServlet {
             if (auditApprovalStatus == RequestStatus.COMPLETE ||
                     auditApprovalStatus == RequestStatus.REJECTED ||
                     auditApprovalStatus == RequestStatus.CANCELED) {
-                auditMessage = CMS.getLogMessage(
-                            AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                audit(new CertStatusChangeRequestProcessedEvent(
                             auditSubjectID,
                             ILogger.SUCCESS,
                             auditRequesterID,
                             auditSerialNumber,
                             auditRequestType,
                             auditReasonNum,
-                            auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                audit(auditMessage);
+                            auditApprovalStatus));
             }
 
         } catch (EBaseException eAudit1) {
@@ -495,17 +494,15 @@ public class DoUnrevokeTPS extends CMSServlet {
                 if (auditApprovalStatus == RequestStatus.COMPLETE ||
                         auditApprovalStatus == RequestStatus.REJECTED ||
                         auditApprovalStatus == RequestStatus.CANCELED) {
-                    auditMessage = CMS.getLogMessage(
-                                AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+
+                    audit(new CertStatusChangeRequestProcessedEvent(
                                 auditSubjectID,
                                 ILogger.FAILURE,
                                 auditRequesterID,
                                 auditSerialNumber,
                                 auditRequestType,
                                 auditReasonNum,
-                                auditApprovalStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : auditApprovalStatus.toString());
-
-                    audit(auditMessage);
+                                auditApprovalStatus));
                 }
             }
         }
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/RevocationProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/RevocationProcessor.java
index b90966e..570aea2 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/RevocationProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/RevocationProcessor.java
@@ -39,6 +39,7 @@ import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
 import com.netscape.certsrv.logging.AuditEvent;
 import com.netscape.certsrv.logging.AuditFormat;
 import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.logging.event.CertStatusChangeRequestProcessedEvent;
 import com.netscape.certsrv.publish.IPublisherProcessor;
 import com.netscape.certsrv.request.IRequest;
 import com.netscape.certsrv.request.IRequestQueue;
@@ -505,17 +506,14 @@ public class RevocationProcessor extends CertProcessor {
                 || requestStatus == RequestStatus.REJECTED
                 || requestStatus == RequestStatus.CANCELED)) return;
 
-        String auditMessage = CMS.getLogMessage(
-                AuditEvent.CERT_STATUS_CHANGE_REQUEST_PROCESSED,
+        auditor.log(new CertStatusChangeRequestProcessedEvent(
                 auditor.getSubjectID(),
                 status,
                 requestID == null ? ILogger.UNIDENTIFIED : requestID.toString(),
                 serialNumber == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : serialNumber.toHexString(),
                 requestType,
                 String.valueOf(revocationReason.toInt()),
-                requestStatus == null ? ILogger.SIGNED_AUDIT_EMPTY_VALUE : requestStatus.toString());
-
-        auditor.log(auditMessage);
+                requestStatus));
     }
 
     public void log(int level, String message) {
-- 
1.8.3.1


From 0b32d55d6c41dcdfbd63840a6681b12ad6675946 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 22:06:38 +0200
Subject: [PATCH 19/27] Refactored RevocationRequestListener.accept().

The RevocationRequestListener.accept() has been refactored to
reduce deeply nested if-statements with early return.

https://pagure.io/dogtagpki/issue/2651

Change-Id: I11dac11f05a4e3626043f4cfa56feacf01e6d5dd
---
 base/ca/src/com/netscape/ca/CRLIssuingPoint.java | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/base/ca/src/com/netscape/ca/CRLIssuingPoint.java b/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
index a593eb8..d105386 100644
--- a/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
+++ b/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
@@ -3068,10 +3068,13 @@ public class CRLIssuingPoint implements ICRLIssuingPoint, Runnable {
         public void accept(IRequest r) {
             String requestType = r.getRequestType();
 
-            if (requestType.equals(IRequest.REVOCATION_REQUEST) ||
+            if (!(requestType.equals(IRequest.REVOCATION_REQUEST) ||
                     requestType.equals(IRequest.UNREVOCATION_REQUEST) ||
                     requestType.equals(IRequest.CLA_CERT4CRL_REQUEST) ||
-                    requestType.equals(IRequest.CLA_UNCERT4CRL_REQUEST)) {
+                    requestType.equals(IRequest.CLA_UNCERT4CRL_REQUEST))) {
+                return;
+            }
+
                 CMS.debug("Revocation listener called.");
                 // check if serial number is in begin/end range if set.
                 if (mBeginSerial != null || mEndSerial != null) {
@@ -3136,7 +3139,6 @@ public class CRLIssuingPoint implements ICRLIssuingPoint, Runnable {
                                         CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())));
                     }
                 }
-            }
         }
     }
 }
-- 
1.8.3.1


From 0af026413a65386a0e8c8aba81fe667412ef7f0d Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 17 May 2017 22:12:19 +0200
Subject: [PATCH 20/27] Reformatted RevocationRequestListener.accept().

The RevocationRequestListener.accept() has been reformatted to
adjust the indentations after refactoring.

https://pagure.io/dogtagpki/issue/2651

Change-Id: Ia94667b88dd48e3e0cf28ee3dd7eb5a5b4dee4b3
---
 base/ca/src/com/netscape/ca/CRLIssuingPoint.java | 142 +++++++++++------------
 1 file changed, 71 insertions(+), 71 deletions(-)

diff --git a/base/ca/src/com/netscape/ca/CRLIssuingPoint.java b/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
index d105386..64101d7 100644
--- a/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
+++ b/base/ca/src/com/netscape/ca/CRLIssuingPoint.java
@@ -31,23 +31,6 @@ import java.util.StringTokenizer;
 import java.util.TimeZone;
 import java.util.Vector;
 
-import netscape.security.util.BitArray;
-import netscape.security.x509.AlgorithmId;
-import netscape.security.x509.CRLExtensions;
-import netscape.security.x509.CRLNumberExtension;
-import netscape.security.x509.CRLReasonExtension;
-import netscape.security.x509.DeltaCRLIndicatorExtension;
-import netscape.security.x509.Extension;
-import netscape.security.x509.FreshestCRLExtension;
-import netscape.security.x509.IssuingDistributionPoint;
-import netscape.security.x509.IssuingDistributionPointExtension;
-import netscape.security.x509.RevocationReason;
-import netscape.security.x509.RevokedCertImpl;
-import netscape.security.x509.RevokedCertificate;
-import netscape.security.x509.X509CRLImpl;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509ExtensionException;
-
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.IConfigStore;
@@ -83,6 +66,23 @@ import com.netscape.cmscore.dbs.CertRecord;
 import com.netscape.cmscore.dbs.CertificateRepository;
 import com.netscape.cmscore.util.Debug;
 
+import netscape.security.util.BitArray;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.x509.CRLNumberExtension;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.DeltaCRLIndicatorExtension;
+import netscape.security.x509.Extension;
+import netscape.security.x509.FreshestCRLExtension;
+import netscape.security.x509.IssuingDistributionPoint;
+import netscape.security.x509.IssuingDistributionPointExtension;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.RevokedCertificate;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509ExtensionException;
+
 /**
  * This class encapsulates CRL issuing mechanism. CertificateAuthority
  * contains a map of CRLIssuingPoint indexed by string ids. Each issuing
@@ -3075,70 +3075,70 @@ public class CRLIssuingPoint implements ICRLIssuingPoint, Runnable {
                 return;
             }
 
-                CMS.debug("Revocation listener called.");
-                // check if serial number is in begin/end range if set.
-                if (mBeginSerial != null || mEndSerial != null) {
-                    CMS.debug(
-                            "Checking if serial number is between " +
-                                    mBeginSerial + " and " + mEndSerial);
-                    BigInteger[] serialNos =
-                            r.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
+            CMS.debug("Revocation listener called.");
+            // check if serial number is in begin/end range if set.
+            if (mBeginSerial != null || mEndSerial != null) {
+                CMS.debug(
+                        "Checking if serial number is between " +
+                                mBeginSerial + " and " + mEndSerial);
+                BigInteger[] serialNos =
+                        r.getExtDataInBigIntegerArray(IRequest.OLD_SERIALS);
 
-                    if (serialNos == null || serialNos.length == 0) {
-                        X509CertImpl oldCerts[] =
-                                r.getExtDataInCertArray(IRequest.OLD_CERTS);
+                if (serialNos == null || serialNos.length == 0) {
+                    X509CertImpl oldCerts[] =
+                            r.getExtDataInCertArray(IRequest.OLD_CERTS);
 
-                        if (oldCerts == null || oldCerts.length == 0)
-                            return;
-                        serialNos = new BigInteger[oldCerts.length];
-                        for (int i = 0; i < oldCerts.length; i++) {
-                            serialNos[i] = oldCerts[i].getSerialNumber();
-                        }
+                    if (oldCerts == null || oldCerts.length == 0)
+                        return;
+                    serialNos = new BigInteger[oldCerts.length];
+                    for (int i = 0; i < oldCerts.length; i++) {
+                        serialNos[i] = oldCerts[i].getSerialNumber();
                     }
+                }
 
-                    boolean inRange = false;
+                boolean inRange = false;
 
-                    for (int i = 0; i < serialNos.length; i++) {
-                        if ((mBeginSerial == null ||
-                                serialNos[i].compareTo(mBeginSerial) >= 0) &&
-                                (mEndSerial == null ||
-                                serialNos[i].compareTo(mEndSerial) <= 0)) {
-                            inRange = true;
-                        }
-                    }
-                    if (!inRange) {
-                        return;
+                for (int i = 0; i < serialNos.length; i++) {
+                    if ((mBeginSerial == null ||
+                            serialNos[i].compareTo(mBeginSerial) >= 0) &&
+                            (mEndSerial == null ||
+                            serialNos[i].compareTo(mEndSerial) <= 0)) {
+                        inRange = true;
                     }
                 }
+                if (!inRange) {
+                    return;
+                }
+            }
 
-                if (mAlwaysUpdate) {
-                    try {
-                        updateCRLNow();
-                        r.setExtData(mCrlUpdateStatus, IRequest.RES_SUCCESS);
-                        if (mPublisherProcessor != null) {
-                            r.setExtData(mCrlPublishStatus, IRequest.RES_SUCCESS);
-                        }
-                    } catch (EErrorPublishCRL e) {
-                        // error already logged in updateCRLNow();
-                        r.setExtData(mCrlUpdateStatus, IRequest.RES_SUCCESS);
-                        if (mPublisherProcessor != null) {
-                            r.setExtData(mCrlPublishStatus, IRequest.RES_ERROR);
-                            r.setExtData(mCrlPublishError, e);
-                        }
-                    } catch (EBaseException e) {
-                        log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_UPDATE_CRL", e.toString()));
-                        r.setExtData(mCrlUpdateStatus, IRequest.RES_ERROR);
-                        r.setExtData(mCrlUpdateError, e);
-                    } catch (Exception e) {
-                        log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_UPDATE_CRL", e.toString()));
-                        if (Debug.on())
-                            Debug.printStackTrace(e);
-                        r.setExtData(mCrlUpdateStatus, IRequest.RES_ERROR);
-                        r.setExtData(mCrlUpdateError,
-                                new EBaseException(
-                                        CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())));
+            if (mAlwaysUpdate) {
+                try {
+                    updateCRLNow();
+                    r.setExtData(mCrlUpdateStatus, IRequest.RES_SUCCESS);
+                    if (mPublisherProcessor != null) {
+                        r.setExtData(mCrlPublishStatus, IRequest.RES_SUCCESS);
+                    }
+                } catch (EErrorPublishCRL e) {
+                    // error already logged in updateCRLNow();
+                    r.setExtData(mCrlUpdateStatus, IRequest.RES_SUCCESS);
+                    if (mPublisherProcessor != null) {
+                        r.setExtData(mCrlPublishStatus, IRequest.RES_ERROR);
+                        r.setExtData(mCrlPublishError, e);
                     }
+                } catch (EBaseException e) {
+                    log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_UPDATE_CRL", e.toString()));
+                    r.setExtData(mCrlUpdateStatus, IRequest.RES_ERROR);
+                    r.setExtData(mCrlUpdateError, e);
+                } catch (Exception e) {
+                    log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_CA_ISSUING_UPDATE_CRL", e.toString()));
+                    if (Debug.on())
+                        Debug.printStackTrace(e);
+                    r.setExtData(mCrlUpdateStatus, IRequest.RES_ERROR);
+                    r.setExtData(mCrlUpdateError,
+                            new EBaseException(
+                                    CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())));
                 }
+            }
         }
     }
 }
-- 
1.8.3.1


From ea036b22d7d15cefb8f7a56e9c9781b545dec8ee Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Wed, 17 May 2017 17:17:42 -0600
Subject: [PATCH 21/27] Correct section headings in user deployment
 configuration file

Bugzilla Bug #1447144 - CA brought down during separate KRA instance creation
dogtagpki Pagure Issue #2674 - CA brought down during separate KRA instance
                               creation
---
 base/server/sbin/pkispawn | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn
index 9394b8e..9e2ebc8 100755
--- a/base/server/sbin/pkispawn
+++ b/base/server/sbin/pkispawn
@@ -30,9 +30,12 @@ if not hasattr(sys, "hexversion") or sys.hexversion < 0x020700f0:
     print("Please upgrade to at least Python 2.7.0.")
     sys.exit(1)
 try:
+    import fileinput
     import ldap
     import os
     import requests
+    import time
+    from time import strftime as date
     import traceback
     import pki
     from pki.server.deployment import pkiconfig as config
@@ -105,6 +108,8 @@ def main(argv):
         interactive = True
         parser.indent = 0
         print(log.PKISPAWN_INTERACTIVE_INSTALLATION)
+    else:
+        sanitize_user_deployment_cfg(config.user_deployment_cfg)
 
     # Only run this program as "root".
     if not os.geteuid() == 0:
@@ -574,6 +579,40 @@ def main(argv):
         print_final_install_information(parser.mdict)
 
 
+def sanitize_user_deployment_cfg(cfg):
+    # Generate a timestamp
+    ticks = time.time()
+    timestamp = date('%Y%m%d%H%M%S', time.localtime(ticks))
+
+    # Correct any section headings in the user's configuration file
+    for line in fileinput.FileInput(cfg, inplace=1, backup='.' + timestamp):
+        # Remove extraneous leading and trailing whitespace from all lines
+        line = line.strip()
+        # Normalize section headings to match '/etc/pki/default.cfg'
+        if line.startswith("["):
+            if line.upper().startswith("[DEFAULT"):
+                line = "[DEFAULT]"
+            elif line.upper().startswith("[TOMCAT"):
+                line = "[Tomcat]"
+            elif line.upper().startswith("[CA"):
+                line = "[CA]"
+            elif line.upper().startswith("[KRA"):
+                line = "[KRA]"
+            elif line.upper().startswith("[OCSP"):
+                line = "[OCSP]"
+            elif line.upper().startswith("[RA"):
+                line = "[RA]"
+            elif line.upper().startswith("[TKS"):
+                line = "[TKS]"
+            elif line.upper().startswith("[TPS"):
+                line = "[TPS]"
+            else:
+                # Notify user of the existence of an invalid section heading
+                sys.stderr.write("'%s' contains an invalid section "
+                                 "heading called '%s'!\n" % (cfg, line))
+        print(line)
+
+
 def start_logging():
     # Enable 'pkispawn' logging.
     config.pki_log_dir = config.pki_root_prefix + \
-- 
1.8.3.1


From 202c747564868432df93c6cf272fcd9d2979d8d8 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Fri, 19 May 2017 00:09:29 +0200
Subject: [PATCH 22/27] Added debug logs for UpdateCRL servlet.

Some debug logs have been added into UpdateCRL servlet to improve
code clarity.

https://pagure.io/dogtagpki/issue/2651

Change-Id: I4dc92d574b8ce93f2964663d36ca28851e400839
---
 .../com/netscape/cms/servlet/cert/UpdateCRL.java   | 46 ++++++++++++++++++++--
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
index 7faecf1..b4d9d29 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/UpdateCRL.java
@@ -294,6 +294,7 @@ public class UpdateCRL extends CMSServlet {
             String signatureAlgorithm,
             Locale locale)
             throws EBaseException {
+
         long startTime = CMS.getCurrentDate().getTime();
         String waitForUpdate =
                 req.getParameter("waitForUpdate");
@@ -322,6 +323,7 @@ public class UpdateCRL extends CMSServlet {
                     crlIssuingPointId = null;
             }
         }
+
         if (crlIssuingPointId == null) {
             crlIssuingPointId = ICertificateAuthority.PROP_MASTER_CRL;
         }
@@ -336,39 +338,61 @@ public class UpdateCRL extends CMSServlet {
             return;
         }
 
+        CMS.debug("UpdateCRL: CRL issuing point: " + crlIssuingPoint.getId());
+
         if (clearCache != null && clearCache.equals("true") &&
                 crlIssuingPoint.isCRLGenerationEnabled() &&
                 crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
                 crlIssuingPoint.isCRLIssuingPointInitialized()
                             == ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+
+            CMS.debug("UpdateCRL: clearing CRL cache");
             crlIssuingPoint.clearCRLCache();
         }
+
         if (!(waitForUpdate != null && waitForUpdate.equals("true") &&
                 crlIssuingPoint.isCRLGenerationEnabled() &&
                 crlIssuingPoint.isCRLUpdateInProgress() == ICRLIssuingPoint.CRL_UPDATE_DONE &&
                 crlIssuingPoint.isCRLIssuingPointInitialized()
                             == ICRLIssuingPoint.CRL_IP_INITIALIZED)) {
+
             if (crlIssuingPoint.isCRLIssuingPointInitialized() != ICRLIssuingPoint.CRL_IP_INITIALIZED) {
+
+                CMS.debug("UpdateCRL: CRL issuing point not initialized");
                 header.addStringValue("crlUpdate", "notInitialized");
+
             } else if (crlIssuingPoint.isCRLUpdateInProgress()
                        != ICRLIssuingPoint.CRL_UPDATE_DONE ||
                        crlIssuingPoint.isManualUpdateSet()) {
+
+                CMS.debug("UpdateCRL: CRL update in progress");
                 header.addStringValue("crlUpdate", "inProgress");
+
             } else if (!crlIssuingPoint.isCRLGenerationEnabled()) {
+
+                CMS.debug("UpdateCRL: CRL update disabled");
                 header.addStringValue("crlUpdate", "Disabled");
+
             } else {
+
+                CMS.debug("UpdateCRL: scheduling CRL update");
                 crlIssuingPoint.setManualUpdate(signatureAlgorithm);
                 header.addStringValue("crlUpdate", "Scheduled");
             }
+
             return;
         }
+
         if (test != null && test.equals("true") &&
                 crlIssuingPoint.isCRLCacheTestingEnabled() &&
                 (!mTesting.contains(crlIssuingPointId))) {
-            CMS.debug("CRL test started.");
+
+            CMS.debug("UpdateCRL: CRL test started");
+
             mTesting.add(crlIssuingPointId);
             BigInteger addLen = null;
             BigInteger startFrom = null;
+
             if (add != null && add.length() > 0 &&
                     from != null && from.length() > 0) {
                 try {
@@ -377,6 +401,7 @@ public class UpdateCRL extends CMSServlet {
                 } catch (Exception e) {
                 }
             }
+
             if (addLen != null && startFrom != null) {
                 Date revocationDate = CMS.getCurrentDate();
                 String err = null;
@@ -386,6 +411,7 @@ public class UpdateCRL extends CMSServlet {
                 BigInteger serialNumber = startFrom;
                 BigInteger counter = addLen;
                 BigInteger stepBy = null;
+
                 if (by != null && by.length() > 0) {
                     try {
                         stepBy = new BigInteger(by);
@@ -397,6 +423,7 @@ public class UpdateCRL extends CMSServlet {
                 long t2 = 0;
 
                 while (counter.compareTo(BigInteger.ZERO) > 0) {
+
                     RevokedCertImpl revokedCert =
                             new RevokedCertImpl(serialNumber, revocationDate, entryExts);
                     crlIssuingPoint.addRevokedCert(serialNumber, revokedCert);
@@ -405,9 +432,11 @@ public class UpdateCRL extends CMSServlet {
 
                     if ((counter.compareTo(BigInteger.ZERO) == 0) ||
                             (stepBy != null && ((counter.mod(stepBy)).compareTo(BigInteger.ZERO) == 0))) {
+
                         t2 = System.currentTimeMillis();
                         long t0 = t2 - t1;
                         t1 = t2;
+
                         try {
                             if (signatureAlgorithm != null) {
                                 crlIssuingPoint.updateCRLNow(signatureAlgorithm);
@@ -418,35 +447,43 @@ public class UpdateCRL extends CMSServlet {
                             counter = BigInteger.ZERO;
                             err = e.toString();
                         }
+
                         if (results != null && results.equals("1")) {
                             addInfo(argSet, crlIssuingPoint, t0);
                         }
                     }
                 }
+
                 if (err != null) {
                     header.addStringValue("crlUpdate", "Failure");
                     header.addStringValue("error", err);
                 } else {
                     header.addStringValue("crlUpdate", "Success");
                 }
+
             } else {
-                CMS.debug("CRL test error: missing parameters.");
+                CMS.debug("UpdateCRL: CRL test error: missing parameters");
                 header.addStringValue("crlUpdate", "missingParameters");
             }
 
             mTesting.remove(crlIssuingPointId);
-            CMS.debug("CRL test finished.");
+            CMS.debug("UpdateCRL: CRL test finished");
             return;
+
         } else if (test != null && test.equals("true") &&
                    crlIssuingPoint.isCRLCacheTestingEnabled() &&
                    mTesting.contains(crlIssuingPointId)) {
             header.addStringValue("crlUpdate", "testingInProgress");
             return;
+
         } else if (test != null && test.equals("true") &&
                    (!crlIssuingPoint.isCRLCacheTestingEnabled())) {
             header.addStringValue("crlUpdate", "testingNotEnabled");
             return;
         }
+
+        CMS.debug("UpdateCRL: updating CRL");
+
         try {
             EBaseException publishError = null;
 
@@ -462,6 +499,7 @@ public class UpdateCRL extends CMSServlet {
                 long now2 = System.currentTimeMillis();
 
                 header.addStringValue("time", "" + (now2 - now1));
+
             } catch (EErrorPublishCRL e) {
                 publishError = e;
             }
@@ -487,6 +525,7 @@ public class UpdateCRL extends CMSServlet {
             if (authToken != null) {
                 authMgr = authToken.getInString(AuthToken.TOKEN_AUTHMGR_INST_NAME);
             }
+
             long endTime = CMS.getCurrentDate().getTime();
 
             if (crlIssuingPoint.getNextUpdate() != null) {
@@ -520,6 +559,7 @@ public class UpdateCRL extends CMSServlet {
                                         + " time: " + (endTime - startTime) }
                         );
             }
+
         } catch (EBaseException e) {
             log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSGW_ERR_UPDATE_CRL", e.toString()));
             if ((lpm != null) && lpm.isCRLPublishingEnabled() && (e instanceof ELdapException)) {
-- 
1.8.3.1


From e1fd9685e5442e5e2efa9a26e07bf45274b6fb93 Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Fri, 19 May 2017 09:47:47 -0600
Subject: [PATCH 23/27] Fixed hardcoded values in ca CS.cfg

- Bugzilla Bug #1452123 -  CA CS.cfg shows default port
- dogtagpki Pagure Issue #2696 - CA CS.cfg shows default port
---
 base/ca/shared/conf/CS.cfg | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
index f6297a3..8f9af5c 100644
--- a/base/ca/shared/conf/CS.cfg
+++ b/base/ca/shared/conf/CS.cfg
@@ -290,7 +290,7 @@ ca.Policy.impl.SubjectDirectoryAttributesExt.class=com.netscape.cms.policy.exten
 ca.Policy.impl.SubjectKeyIdentifierExt.class=com.netscape.cms.policy.extensions.SubjectKeyIdentifierExt
 ca.Policy.impl.UniqueSubjectNameConstraints.class=com.netscape.cms.policy.constraints.UniqueSubjectNameConstraints
 ca.Policy.impl.ValidityConstraints.class=com.netscape.cms.policy.constraints.ValidityConstraints
-ca.Policy.rule.AuthInfoAccessExt.ad0_location=http://[PKI_HOSTNAME]:8080/ocsp
+ca.Policy.rule.AuthInfoAccessExt.ad0_location=http://[PKI_HOSTNAME]:[PKI_UNSECURE_PORT]/ocsp
 ca.Policy.rule.AuthInfoAccessExt.ad0_location_type=URL
 ca.Policy.rule.AuthInfoAccessExt.ad0_method=ocsp
 ca.Policy.rule.AuthInfoAccessExt.enable=false
@@ -773,8 +773,8 @@ cmsgateway._027=##       'cmsgateway.enableAdminEnroll=false' should have
 cmsgateway._028=##       already been reset.
 cmsgateway._029=##
 cmsgateway.enableAdminEnroll=false
-https.port=8443
-http.port=8080
+https.port=[PKI_SECURE_PORT]
+http.port=[PKI_UNSECURE_PORT]
 dbs.enableSerialManagement=[PKI_ENABLE_RANDOM_SERIAL_NUMBERS]
 dbs.enableRandomSerialNumbers=[PKI_ENABLE_RANDOM_SERIAL_NUMBERS]
 dbs.randomSerialNumberCounter=0
-- 
1.8.3.1


From f30be692453ccb323f874e5a751e2381cbb4ebb0 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Fri, 19 May 2017 21:35:00 +0200
Subject: [PATCH 24/27] Added debug logs for JssSubsystem.

Some debug logs have been added into JssSubsystem to improve code
clarity.

https://pagure.io/dogtagpki/issue/2695

Change-Id: Ice54cf5cfe1eb4984509b83a1098cd69819e37bc
---
 .../netscape/cmscore/security/JssSubsystem.java    | 31 ++++++++++++++--------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
index dab9ac9..9031a92 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
@@ -264,12 +264,15 @@ public final class JssSubsystem implements ICryptoSubsystem {
      */
     public void init(ISubsystem owner, IConfigStore config)
             throws EBaseException {
+
+        CMS.debug("JssSubsystem: initializing JSS subsystem");
+
         mLogger = CMS.getLogger();
 
         if (mInited) {
             // This used to throw an exeception (e.g. - on Solaris).
             // If JSS is already initialized simply return.
-            CMS.debug("JssSubsystem already inited.. returning.");
+            CMS.debug("JssSubsystem: already initialized");
             return;
         }
 
@@ -277,9 +280,11 @@ public final class JssSubsystem implements ICryptoSubsystem {
 
         // If disabled, just return
         boolean enabled = config.getBoolean(PROP_ENABLE, true);
+        CMS.debug("JssSubsystem: enabled: " + enabled);
 
-        if (!enabled)
+        if (!enabled) {
             return;
+        }
 
         try {
             devRandomInputStream = new FileInputStream("/dev/urandom");
@@ -287,28 +292,28 @@ public final class JssSubsystem implements ICryptoSubsystem {
             // XXX - add new exception
         }
 
-        // get hardcoded password (for debugging.
-        String pw;
+        // get debugging password from config file
+        String pw = config.getString(PASSWORD_ALIAS, null);
 
-        if ((pw = config.getString(PASSWORD_ALIAS, null)) != null) {
-            // hardcoded password in config file
+        if (pw != null) {
+            CMS.debug("JssSubsystem: use debug password");
             mPWCB = new Password(pw.toCharArray());
-            CMS.debug("JssSubsystem init() got password from hardcoded in config");
         }
 
-        String certDir;
-
-        certDir = config.getString(CONFIG_DIR, null);
+        String certDir = config.getString(CONFIG_DIR, null);
+        CMS.debug("JssSubsystem: NSS database: " + certDir);
 
         CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues(certDir, "", "", "secmod.db");
-
         vals.removeSunProvider = false;
         vals.installJSSProvider = true;
+
         try {
+            CMS.debug("JssSubsystem: initializing CryptoManager");
             CryptoManager.initialize(vals);
         } catch (AlreadyInitializedException e) {
             // do nothing
         } catch (Exception e) {
+            CMS.debug(e);
             String[] params = { mId, e.toString() };
             EBaseException ex = new EBaseException(CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
 
@@ -317,9 +322,11 @@ public final class JssSubsystem implements ICryptoSubsystem {
         }
 
         try {
+            CMS.debug("JssSubsystem: initializing SSL");
             mCryptoManager = CryptoManager.getInstance();
             initSSL();
         } catch (CryptoManager.NotInitializedException e) {
+            CMS.debug(e);
             String[] params = { mId, e.toString() };
             EBaseException ex = new EBaseException(CMS.getUserMessage("CMS_BASE_CREATE_SERVICE_FAILED", params));
 
@@ -328,6 +335,8 @@ public final class JssSubsystem implements ICryptoSubsystem {
         }
 
         mInited = true;
+
+        CMS.debug("JssSubsystem: initialization complete");
     }
 
     public String getCipherVersion() throws EBaseException {
-- 
1.8.3.1


From 62841380c6400023cf973e273ab974352885fabd Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Sat, 20 May 2017 04:06:17 +0200
Subject: [PATCH 25/27] Fixed problem with --ignore-banner option.

The pki CLI has been modified to parse the --ignore-banner option
properly and pass it only to Java-based CLI commands.

https://pagure.io/dogtagpki/issue/2683

Change-Id: Ifc3e98f74682a2fb4daeea16e86f495515a2d1f5
---
 base/common/python/pki/cli/main.py | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/base/common/python/pki/cli/main.py b/base/common/python/pki/cli/main.py
index 268547b..f201c1d 100644
--- a/base/common/python/pki/cli/main.py
+++ b/base/common/python/pki/cli/main.py
@@ -44,6 +44,7 @@ class PKICLI(pki.cli.CLI):
         self.password = None
         self.password_file = None
         self.token = None
+        self.ignore_banner = False
 
         self.add_module(pki.cli.pkcs12.PKCS12CLI())
 
@@ -96,6 +97,9 @@ class PKICLI(pki.cli.CLI):
         if self.token and self.token != 'internal':
             cmd.extend(['--token', self.token])
 
+        if self.ignore_banner:
+            cmd.extend(['--ignore-banner'])
+
         if self.verbose:
             cmd.extend(['--verbose'])
 
@@ -157,6 +161,12 @@ class PKICLI(pki.cli.CLI):
                 pki_options.append(args[i + 1])
                 i = i + 2
 
+            # check ignore banner option
+            elif args[i] == '--ignore-banner':
+                self.ignore_banner = True
+                pki_options.append(args[i])
+                i = i + 1
+
             # check verbose option
             elif args[i] == '-v' or args[i] == '--verbose':
                 self.set_verbose(True)
-- 
1.8.3.1


From 8aafe1d4345f8b8d20b2f87c68b2e6be4eee18eb Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Fri, 19 May 2017 11:55:14 -0700
Subject: [PATCH 26/27] Ticket#2618 feature: pre-signed CMC renewal request

This patch provides the feature implementation to allow CA to process pre-signed CMC renewal requests. In the world of CMC, renewal request are full CMC requests that are signed by previously issued signing certificate.
The implementation approach is to use the caFullCMCUserSignedCert with the enhanced profile constraint: UniqueKeyConstraint.
UniqueKeyConstraint has been updated to disallow renewal of same key shared by a revoked certificate.  It also saves the origNotAfter of the newest certificate sharing the same key in the request to be used by the RenewGracePeriodConstraint. To not interfere with the existing "renewal by serial" flow, if an existing origNotAfter is found, it is not overwritten.
The profile caFullCMCUserSignedCert.cfg has been updated to have both UniqueKeyConstraint and RenewGracePeriodConstraint.  They must be placed in the correct order. By default in the UniqueKeyConstraint the constraint parameter allowSameKeyRenewal=true.
---
 .../shared/profiles/ca/caFullCMCUserSignedCert.cfg |  13 ++-
 .../src/com/netscape/cmstools/CMCRequest.java      |  14 ++-
 .../constraint/RenewGracePeriodConstraint.java     |  26 +++--
 .../profile/constraint/UniqueKeyConstraint.java    | 123 ++++++++++++++++-----
 4 files changed, 132 insertions(+), 44 deletions(-)

diff --git a/base/ca/shared/profiles/ca/caFullCMCUserSignedCert.cfg b/base/ca/shared/profiles/ca/caFullCMCUserSignedCert.cfg
index 229a3cd..63a4bca 100644
--- a/base/ca/shared/profiles/ca/caFullCMCUserSignedCert.cfg
+++ b/base/ca/shared/profiles/ca/caFullCMCUserSignedCert.cfg
@@ -10,12 +10,23 @@ input.i2.class_id=submitterInfoInputImpl
 output.list=o1
 output.o1.class_id=certOutputImpl
 policyset.list=cmcUserCertSet
-policyset.cmcUserCertSet.list=1,2,3,4,5,6,7,8
+policyset.cmcUserCertSet.list=1,9,10,2,3,4,5,6,7,8
 policyset.cmcUserCertSet.1.constraint.class_id=cmcUserSignedSubjectNameConstraintImpl
 policyset.cmcUserCertSet.1.constraint.name=CMC User Signed Subject Name Constraint
 policyset.cmcUserCertSet.1.default.class_id=cmcUserSignedSubjectNameDefaultImpl
 policyset.cmcUserCertSet.1.default.name=User Signed Subject Name Default
 policyset.cmcUserCertSet.1.default.params.name=
+policyset.cmcUserCertSet.9.constraint.class_id=uniqueKeyConstraintImpl
+policyset.cmcUserCertSet.9.constraint.name=Unique Key Constraint
+policyset.cmcUserCertSet.9.constraint.params.allowSameKeyRenewal=true
+policyset.cmcUserCertSet.9.default.class_id=noDefaultImpl
+policyset.cmcUserCertSet.9.default.name=No Default
+policyset.cmcUserCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.cmcUserCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.cmcUserCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.cmcUserCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.cmcUserCertSet.10.default.class_id=noDefaultImpl
+policyset.cmcUserCertSet.10.default.name=No Default
 policyset.cmcUserCertSet.2.constraint.class_id=validityConstraintImpl
 policyset.cmcUserCertSet.2.constraint.name=Validity Constraint
 policyset.cmcUserCertSet.2.constraint.params.notAfterCheck=false
diff --git a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
index 6e27cb1..9c41403 100644
--- a/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
+++ b/base/java-tools/src/com/netscape/cmstools/CMCRequest.java
@@ -2014,10 +2014,12 @@ public class CMCRequest {
                 certname.append(tokenName);
                 certname.append(":");
             }
-            certname.append(nickname);
-            signerCert = cm.findCertByNickname(certname.toString());
-            if (signerCert != null) {
-                System.out.println("got signerCert: "+ certname.toString());
+            if (!selfSign.equals("true") && nickname != null) {
+                certname.append(nickname);
+                signerCert = cm.findCertByNickname(certname.toString());
+                if (signerCert != null) {
+                    System.out.println("got signerCert: "+ certname.toString());
+                }
             }
 
             ContentInfo cmcblob = null;
@@ -2239,11 +2241,11 @@ public class CMCRequest {
             // sign the request
             SignedData signedData = null;
             if (selfSign.equalsIgnoreCase("true")) {
-                // selfSign signes with private key
+                // selfSign signs with private key
                 System.out.println("selfSign is true...");
                 signedData = signData(privk, pkidata);
             } else {
-                // none selfSign signes with  existing cert
+                // none selfSign signs with  existing cert
                 System.out.println("selfSign is false...");
                 signedData = signData(signerCert, tokenName, nickname, cm, pkidata);
             }
diff --git a/base/server/cms/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java b/base/server/cms/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
index d140396..a5f7994 100644
--- a/base/server/cms/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
+++ b/base/server/cms/src/com/netscape/cms/profile/constraint/RenewGracePeriodConstraint.java
@@ -87,14 +87,16 @@ public class RenewGracePeriodConstraint extends EnrollConstraint {
 
     public void validate(IRequest req, X509CertInfo info)
             throws ERejectException {
+        String method = "RenewGracePeriodConstraint: validate: ";
+        String msg = "";
+
         String origExpDate_s = req.getExtDataInString("origNotAfter");
-        // probably not for renewal
-        if (origExpDate_s == null) {
+        if (origExpDate_s == null) { // probably not for renewal
+            CMS.debug(method + " original cert expiration date not found...return without validation");
             return;
-        } else {
-            CMS.debug("validate RenewGracePeriod: original cert expiration date found... renewing");
+        } else { //should occur when it's renewal
+            CMS.debug(method + " original cert expiration date found... validating");
         }
-        CMS.debug("ValidilityConstraint: validateRenewGraceperiod begins");
         BigInteger origExpDate_BI = new BigInteger(origExpDate_s);
         Date origExpDate = new Date(origExpDate_BI.longValue());
         String renew_grace_before_s = getConfig(CONFIG_RENEW_GRACE_BEFORE);
@@ -122,7 +124,7 @@ public class RenewGracePeriodConstraint extends EnrollConstraint {
 
         Date current = CMS.getCurrentDate();
         long millisDiff = origExpDate.getTime() - current.getTime();
-        CMS.debug("validateRenewGracePeriod: millisDiff="
+        CMS.debug(method + " millisDiff="
                 + millisDiff + " origExpDate=" + origExpDate.getTime() + " current=" + current.getTime());
 
         /*
@@ -134,17 +136,17 @@ public class RenewGracePeriodConstraint extends EnrollConstraint {
          */
         if (millisDiff >= 0) {
             if ((renew_grace_before > 0) && (millisDiff > renew_grace_before_BI.longValue())) {
+                msg = renew_grace_before + " days before and " +
+                        renew_grace_after + " days after original cert expiration date";
                 throw new ERejectException(CMS.getUserMessage(getLocale(req),
-                        "CMS_PROFILE_RENEW_OUTSIDE_GRACE_PERIOD",
-                        renew_grace_before + " days before and " +
-                                renew_grace_after + " days after original cert expiration date"));
+                        "CMS_PROFILE_RENEW_OUTSIDE_GRACE_PERIOD", msg));
             }
         } else {
             if ((renew_grace_after > 0) && ((0 - millisDiff) > renew_grace_after_BI.longValue())) {
+                msg = renew_grace_before + " days before and " +
+                        renew_grace_after + " days after original cert expiration date";
                 throw new ERejectException(CMS.getUserMessage(getLocale(req),
-                        "CMS_PROFILE_RENEW_OUTSIDE_GRACE_PERIOD",
-                        renew_grace_before + " days before and " +
-                                renew_grace_after + " days after original cert expiration date"));
+                        "CMS_PROFILE_RENEW_OUTSIDE_GRACE_PERIOD", msg));
             }
         }
     }
diff --git a/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java b/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
index 869f0e2..33cc7a9 100644
--- a/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
+++ b/base/server/cms/src/com/netscape/cms/profile/constraint/UniqueKeyConstraint.java
@@ -17,16 +17,11 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.cms.profile.constraint;
 
+import java.math.BigInteger;
+import java.util.Date;
 import java.util.Enumeration;
 import java.util.Locale;
 
-import netscape.security.x509.CertificateSubjectName;
-import netscape.security.x509.CertificateX509Key;
-import netscape.security.x509.X500Name;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509CertInfo;
-import netscape.security.x509.X509Key;
-
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.base.IConfigStore;
 import com.netscape.certsrv.ca.ICertificateAuthority;
@@ -41,6 +36,13 @@ import com.netscape.certsrv.property.IDescriptor;
 import com.netscape.certsrv.request.IRequest;
 import com.netscape.cms.profile.def.NoDefault;
 
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.CertificateX509Key;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
+import netscape.security.x509.X509Key;
+
 /**
  * This constraint is to check for publickey uniqueness.
  * The config param "allowSameKeyRenewal" enables the
@@ -102,9 +104,29 @@ public class UniqueKeyConstraint extends EnrollConstraint {
     /**
      * Validates the request. The request is not modified
      * during the validation.
+     *
+     * It will try to capture orig cert expiration info for renewal later.
+     * Renewal can be either renewal with same key or new key.
+     *
+     * In case of renewing with same key, the old cert record
+     * can be retrieved and used to fill original info such as
+     * original expiration date for use with RenewGracePeriodConstraint.
+     *
+     * In case of renewing with new key, it would be no different from
+     * regular enrollment
+     *
+     * Search by ICertRecord.ATTR_X509CERT_PUBLIC_KEY_DATA
+     * would tell us if its reusing the same key or not.
+     * If any cert with the same key in the repository is found
+     * to be revoked, then the request is rejected
+     *
+     * This contraint has to go before the RenewGracePeriodConstraint,
+     * but after any of the SubjectName Default and Constraint
      */
     public void validate(IRequest request, X509CertInfo info)
             throws ERejectException {
+        String method = "UniqueKeyConstraint: validate: ";
+        String msg = "";
         boolean rejected = false;
         int size = 0;
         ICertRecordList list;
@@ -114,6 +136,8 @@ public class UniqueKeyConstraint extends EnrollConstraint {
         getConfigBoolean(CONFIG_REVOKE_DUPKEY_CERT);
         */
         mAllowSameKeyRenewal = getConfigBoolean(CONFIG_ALLOW_SAME_KEY_RENEWAL);
+        msg = msg + ": allowSameKeyRenewal=" + mAllowSameKeyRenewal + ";";
+        CMS.debug(method + msg);
 
         try {
             CertificateX509Key infokey = (CertificateX509Key)
@@ -131,18 +155,18 @@ public class UniqueKeyConstraint extends EnrollConstraint {
 
         } catch (Exception e) {
             throw new ERejectException(
-                        CMS.getUserMessage(
-                                getLocale(request),
-                                "CMS_PROFILE_INTERNAL_ERROR", e.toString()));
+                    CMS.getUserMessage(
+                            getLocale(request),
+                            "CMS_PROFILE_INTERNAL_ERROR", method + e.toString()));
         }
 
         /*
          * It does not matter if the corresponding cert's status
-         * is valid or not, we don't want a key that was once
-         * generated before
+         * is valid or not, if mAllowSameKeyRenewal is false,
+         * we don't want a key that was once generated before
          */
         if (size > 0) {
-            CMS.debug("UniqueKeyConstraint: found existing cert with duplicate key.");
+            CMS.debug(method + "found existing cert with same key");
 
             /*
                 The following code revokes the existing certs that have
@@ -189,45 +213,94 @@ public class UniqueKeyConstraint extends EnrollConstraint {
 
                         sjname_in_req =
                                 (X500Name) subName.get(CertificateSubjectName.DN_NAME);
-                        CMS.debug("UniqueKeyConstraint: cert request subject DN =" + sjname_in_req.toString());
+                        CMS.debug(method +" cert request subject DN =" + sjname_in_req.toString());
                         Enumeration<ICertRecord> e = list.getCertRecords(0, size - 1);
+                        Date latestOrigNotAfter = null;
+                        Date origNotAfter = null;
+                        boolean first = true;
                         while (e != null && e.hasMoreElements()) {
                             ICertRecord rec = e.nextElement();
-                            X509CertImpl cert = rec.getCertificate();
+                            BigInteger serial = rec.getSerialNumber();
+
+                            if (rec.getStatus().equals(ICertRecord.STATUS_REVOKED)
+                                    || rec.getStatus().equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
+                                msg = msg + "revoked cert cannot be renewed: serial=" + serial.toString() + ";";
+                                CMS.debug(method + msg);
+                                rejected = true;
+                                // this has to break
+                                break;
+                            }
+                            if (!rec.getStatus().equals(ICertRecord.STATUS_VALID)
+                                    && !rec.getStatus().equals(ICertRecord.STATUS_EXPIRED)) {
+                                CMS.debug(method + "invalid cert cannot be renewed; continue:" + serial.toString());
+                                // can still find another one to renew
+                                continue;
+                            }
+                            // only VALID or EXPIRED certs could have reached here
+                            X509CertImpl origCert = rec.getCertificate();
                             String certDN =
-                                    cert.getSubjectDN().toString();
-                            CMS.debug("UniqueKeyConstraint: cert retrieved from ldap has subject DN =" + certDN);
+                                    origCert.getSubjectDN().toString();
+                            CMS.debug(method + " cert retrieved from ldap has subject DN =" + certDN);
 
                             sjname_in_db = new X500Name(certDN);
 
                             if (sjname_in_db.equals(sjname_in_req) == false) {
+                                msg = msg + "subject name not match in same key renewal;";
                                 rejected = true;
                                 break;
                             } else {
-                                rejected = false;
+                                CMS.debug("subject name match in same key renewal");
                             }
+
+                            // find the latest expiration date to keep for
+                            // Renewal Grace Period Constraint later
+                            origNotAfter = origCert.getNotAfter();
+                            CMS.debug(method + "origNotAfter =" + origNotAfter.toString());
+                            if (first) {
+                                latestOrigNotAfter = origNotAfter;
+                                first = false;
+                            } else if (latestOrigNotAfter.before(origNotAfter)) {
+                                CMS.debug(method + "newer cert found");
+                                latestOrigNotAfter = origNotAfter;
+                            }
+
+                            // yes, this could be overwritten by later
+                            // found cert(s) that has violations
+                            rejected = false;
                         } // while
+
+                        if (latestOrigNotAfter != null) {
+                            String existingOrigExpDate_s = request.getExtDataInString("origNotAfter");
+                            if (existingOrigExpDate_s != null) {
+                                // make sure not to interfere with renewal by serial
+                                CMS.debug(method +
+                                        " original cert expiration date already exists. Not overriding.");
+                            } else {
+                                // set origNotAfter for RenewGracePeriodConstraint
+                                CMS.debug(method + "setting latest original cert expiration in request");
+                                request.setExtData("origNotAfter", BigInteger.valueOf(latestOrigNotAfter.getTime()));
+                            }
+                        }
                     } else { //subName is null
+                        msg =  msg +"subject name not found in cert request info;";
                         rejected = true;
                     }
                 } catch (Exception ex1) {
-                    CMS.debug("UniqueKeyConstraint: error in allowSameKeyRenewal: " + ex1.toString());
+                    CMS.debug(method +  msg + ex1.toString());
                     rejected = true;
                 } // try
 
             } else {
+                msg = msg + "found existing cert with same key;";
                 rejected = true;
             }// allowSameKeyRenewal
         } // (size > 0)
 
         if (rejected == true) {
-            CMS.debug("UniqueKeyConstraint: rejected");
-            throw new ERejectException(
-                           CMS.getUserMessage(
-                                   getLocale(request),
-                                   "CMS_PROFILE_DUPLICATE_KEY"));
+            CMS.debug(method + " rejected");
+            throw new ERejectException(msg);
         } else {
-            CMS.debug("UniqueKeyConstraint: approved");
+            CMS.debug(method + " approved");
         }
     }
 
-- 
1.8.3.1


From b66409ba4a9ffa8cb58f643e891a4a50a67fb29a Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Sat, 20 May 2017 00:06:41 +0200
Subject: [PATCH 27/27] Added configurable random number generator in
 JssSubsystem.

The JssSubsystem has been modified to provide a configurable
random number generator which uses PK11SecureRandom from JSS by
default.

The CertificateRepository has been modified to use the new random
number generator to generate random serial number.

https://pagure.io/dogtagpki/issue/2695

Change-Id: I3289adbd0543000e64404fe23d00c44f32795f75
---
 .../cmscore/dbs/CertificateRepository.java         | 32 +++++++++++-----------
 .../netscape/cmscore/security/JssSubsystem.java    | 27 ++++++++++++++++++
 2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java
index 8406f36..9a333fe 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java
@@ -19,27 +19,18 @@ package com.netscape.cmscore.dbs;
 
 import java.io.Serializable;
 import java.math.BigInteger;
+import java.security.SecureRandom;
 import java.security.cert.Certificate;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Random;
 import java.util.Vector;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 
-import netscape.ldap.LDAPAttributeSet;
-import netscape.ldap.LDAPEntry;
-import netscape.ldap.LDAPSearchResults;
-import netscape.security.x509.CertificateValidity;
-import netscape.security.x509.RevokedCertImpl;
-import netscape.security.x509.X500Name;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509CertInfo;
-
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.IConfigStore;
@@ -62,6 +53,16 @@ import com.netscape.certsrv.dbs.certdb.RenewableCertificateCollection;
 import com.netscape.certsrv.dbs.repository.IRepository;
 import com.netscape.certsrv.dbs.repository.IRepositoryRecord;
 import com.netscape.certsrv.logging.ILogger;
+import com.netscape.cmscore.security.JssSubsystem;
+
+import netscape.ldap.LDAPAttributeSet;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPSearchResults;
+import netscape.security.x509.CertificateValidity;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509CertInfo;
 
 /**
  * A class represents a certificate repository. It
@@ -99,7 +100,6 @@ public class CertificateRepository extends Repository
     private int mTransitMaxRecords = 1000000;
     private int mTransitRecordPageSize = 200;
 
-    private Random mRandom = null;
     private int mBitLength = 0;
     private BigInteger mRangeSize = null;
     private int mMinRandomBitLength = 4;
@@ -169,11 +169,7 @@ public class CertificateRepository extends Repository
     }
 
     private BigInteger getRandomNumber() throws EBaseException {
-        BigInteger randomNumber = null;
 
-        if (mRandom == null) {
-            mRandom = new Random();
-        }
         super.initCacheIfNeeded();
 
         if (mRangeSize == null) {
@@ -189,7 +185,11 @@ public class CertificateRepository extends Repository
             CMS.debug("CertificateRepository: getRandomNumber:  Range size is too small to support random certificate serial numbers.");
             throw new EBaseException ("Range size is too small to support random certificate serial numbers.");
         }
-        randomNumber = new BigInteger((mBitLength), mRandom);
+
+        JssSubsystem jssSubsystem = (JssSubsystem) CMS.getSubsystem(JssSubsystem.ID);
+        SecureRandom random = jssSubsystem.getRandomNumberGenerator();
+
+        BigInteger randomNumber = new BigInteger(mBitLength, random);
         randomNumber = (randomNumber.multiply(mRangeSize)).shiftRight(mBitLength);
         CMS.debug("CertificateRepository: getRandomNumber  randomNumber="+randomNumber);
 
diff --git a/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
index 9031a92..d346a12 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/security/JssSubsystem.java
@@ -32,6 +32,7 @@ import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.Principal;
 import java.security.PublicKey;
+import java.security.SecureRandom;
 import java.security.SignatureException;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
@@ -116,6 +117,7 @@ public final class JssSubsystem implements ICryptoSubsystem {
     private boolean mInited = false;
     private ILogger mLogger = null;
     private CryptoManager mCryptoManager = null;
+    private SecureRandom random;
 
     protected PasswordCallback mPWCB = null;
 
@@ -334,11 +336,36 @@ public final class JssSubsystem implements ICryptoSubsystem {
             throw ex;
         }
 
+        // read jss.random.* properties
+        // by default use PK11SecureRandom from JSS
+        // see http://pki.fedoraproject.org/wiki/Random_Number_Generator
+
+        IConfigStore randomConfig = config.getSubStore("random");
+        CMS.debug("JssSubsystem: random:");
+
+        String algorithm = randomConfig.getString("algorithm", "pkcs11prng");
+        CMS.debug("JssSubsystem: - algorithm: " + algorithm);
+
+        String provider = randomConfig.getString("provider", "Mozilla-JSS");
+        CMS.debug("JssSubsystem: - provider: " + provider);
+
+        try {
+            random = SecureRandom.getInstance(algorithm, provider);
+
+        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+            CMS.debug(e);
+            throw new EBaseException(e);
+        }
+
         mInited = true;
 
         CMS.debug("JssSubsystem: initialization complete");
     }
 
+    public SecureRandom getRandomNumberGenerator() {
+        return random;
+    }
+
     public String getCipherVersion() throws EBaseException {
         return "cipherdomestic";
     }
-- 
1.8.3.1