Blob Blame History Raw
From cc97f8628b23f8ea75308bb97a31307cb4f162b9 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 23 Jun 2015 12:23:15 -0400
Subject: [PATCH 01/21] Fixed selftests log message.

The SelfTestSubsystem has been modified to display a 'successful'
message only if all tests have passed. If a test fails, it will
log a failure, subsequent tests will not be executed, and the
subsystem will shutdown immediately.

The runSelfTest() in various tests have been cleaned up to throw
the original exception to help troubleshooting. The unused
RAPresence test has been removed.

https://fedorahosted.org/pki/ticket/1249
---
 .../com/netscape/certsrv/selftests/ISelfTest.java  |   5 +-
 .../certsrv/selftests/ISelfTestSubsystem.java      |   5 +-
 .../src/com/netscape/cms/selftests/ASelfTest.java  |   5 +-
 .../com/netscape/cms/selftests/ca/CAPresence.java  |  97 +++-----
 .../com/netscape/cms/selftests/ca/CAValidity.java  | 102 ++++----
 .../selftests/common/SystemCertsVerification.java  |  35 ++-
 .../netscape/cms/selftests/kra/KRAPresence.java    |  84 +++----
 .../netscape/cms/selftests/ocsp/OCSPPresence.java  | 123 ++++------
 .../netscape/cms/selftests/ocsp/OCSPValidity.java  | 127 ++++------
 .../com/netscape/cms/selftests/ra/RAPresence.java  | 261 --------------------
 .../cms/selftests/tks/TKSKnownSessionKey.java      |  56 +++--
 .../cms/servlet/admin/CMSAdminServlet.java         |   6 +-
 .../cmscore/selftests/SelfTestSubsystem.java       | 271 ++++++++++-----------
 .../server/tps/selftests/TPSPresence.java          |  38 ++-
 .../server/tps/selftests/TPSValidity.java          |  43 ++--
 15 files changed, 449 insertions(+), 809 deletions(-)
 delete mode 100644 base/server/cms/src/com/netscape/cms/selftests/ra/RAPresence.java

diff --git a/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java b/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java
index 24ad623..0ffc74b 100644
--- a/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java
+++ b/base/common/src/com/netscape/certsrv/selftests/ISelfTest.java
@@ -126,8 +126,7 @@ public interface ISelfTest {
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException;
+    public void runSelfTest(ILogEventListener logger) throws Exception;
 }
diff --git a/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java b/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java
index 214ee17..29adde0 100644
--- a/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java
+++ b/base/common/src/com/netscape/certsrv/selftests/ISelfTestSubsystem.java
@@ -206,10 +206,9 @@ public interface ISelfTestSubsystem
      * <P>
      *
      * @exception EMissingSelfTestException subsystem has missing name
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTestsAtStartup()
-            throws EMissingSelfTestException, ESelfTestException;
+    public void runSelfTestsAtStartup() throws Exception;
 
     //
     // methods associated with the list of self test instances
diff --git a/base/server/cms/src/com/netscape/cms/selftests/ASelfTest.java b/base/server/cms/src/com/netscape/cms/selftests/ASelfTest.java
index e77ece5..c77514f 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/ASelfTest.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/ASelfTest.java
@@ -186,8 +186,7 @@ public abstract class ASelfTest
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public abstract void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException;
+    public abstract void runSelfTest(ILogEventListener logger) throws Exception;
 }
diff --git a/base/server/cms/src/com/netscape/cms/selftests/ca/CAPresence.java b/base/server/cms/src/com/netscape/cms/selftests/ca/CAPresence.java
index 83caa00..ab491c7 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/ca/CAPresence.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/ca/CAPresence.java
@@ -191,72 +191,55 @@ public class CAPresence
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
-        ICertificateAuthority ca = null;
-        X509CertImpl caCert = null;
-        X509Key caPubKey = null;
-
-        ca = (ICertificateAuthority) CMS.getSubsystem(mCaSubId);
+    public void runSelfTest(ILogEventListener logger) throws Exception {
 
+        ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(mCaSubId);
         if (ca == null) {
             // log that the CA is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_CA_IS_NOT_PRESENT",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-
-            throw new ESelfTestException(logMessage);
-        } else {
-            // Retrieve the CA certificate
-            caCert = ca.getCACert();
-
-            if (caCert == null) {
-                // log that the CA is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_CA_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the CA certificate public key
-            try {
-                caPubKey = (X509Key) caCert.get(X509CertImpl.PUBLIC_KEY);
-
-                if (caPubKey == null) {
-                    // log that something is seriously wrong with the CA
-                    logMessage = CMS.getLogMessage("SELFTESTS_CA_IS_CORRUPT",
-                                                    getSelfTestName());
-
-                    mSelfTestSubsystem.log(logger,
-                                            logMessage);
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_CA_IS_NOT_PRESENT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-                    throw new ESelfTestException(logMessage);
-                }
-            } catch (CertificateParsingException e) {
-                // log that something is seriously wrong with the CA
-                mSelfTestSubsystem.log(logger,
-                                        e.toString());
+        // Retrieve the CA certificate
+        X509CertImpl caCert = ca.getCACert();
+        if (caCert == null) {
+            // log that the CA is not yet initialized
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_CA_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-                throw new ESelfTestException(e.toString());
-            }
+        // Retrieve the CA certificate public key
+        X509Key caPubKey;
+        try {
+            caPubKey = (X509Key) caCert.get(X509CertImpl.PUBLIC_KEY);
 
-            // log that the CA is present
-            logMessage = CMS.getLogMessage("SELFTESTS_CA_IS_PRESENT",
-                                            getSelfTestName());
+        } catch (CertificateParsingException e) {
+            // log that something is seriously wrong with the CA
+            mSelfTestSubsystem.log(logger, e.toString());
+            throw e;
+        }
 
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
+        if (caPubKey == null) {
+            // log that something is seriously wrong with the CA
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_CA_IS_CORRUPT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
         }
 
-        return;
+        // log that the CA is present
+        String logMessage = CMS.getLogMessage(
+                "SELFTESTS_CA_IS_PRESENT",
+                getSelfTestName());
+        mSelfTestSubsystem.log(logger, logMessage);
     }
 }
diff --git a/base/server/cms/src/com/netscape/cms/selftests/ca/CAValidity.java b/base/server/cms/src/com/netscape/cms/selftests/ca/CAValidity.java
index b1751ec..4d90be1 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/ca/CAValidity.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/ca/CAValidity.java
@@ -191,72 +191,56 @@ public class CAValidity
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
-        ICertificateAuthority ca = null;
-        X509CertImpl caCert = null;
-
-        ca = (ICertificateAuthority) CMS.getSubsystem(mCaSubId);
+    public void runSelfTest(ILogEventListener logger) throws Exception {
 
+        ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(mCaSubId);
         if (ca == null) {
             // log that the CA is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_CA_IS_NOT_PRESENT",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-
-            throw new ESelfTestException(logMessage);
-        } else {
-            // Retrieve the CA certificate
-            caCert = ca.getCACert();
-
-            if (caCert == null) {
-                // log that the CA is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_CA_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the CA validity period
-            try {
-                caCert.checkValidity();
-            } catch (CertificateNotYetValidException e) {
-                // log that the CA is not yet valid
-                logMessage = CMS.getLogMessage("SELFTESTS_CA_IS_NOT_YET_VALID",
-                                                getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            } catch (CertificateExpiredException e) {
-                // log that the CA is expired
-                logMessage = CMS.getLogMessage("SELFTESTS_CA_IS_EXPIRED",
-                                                getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_CA_IS_NOT_PRESENT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-            // log that the CA is valid
-            logMessage = CMS.getLogMessage("SELFTESTS_CA_IS_VALID",
-                                            getSelfTestName());
+        // Retrieve the CA certificate
+        X509CertImpl caCert = ca.getCACert();
+        if (caCert == null) {
+            // log that the CA is not yet initialized
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_CA_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
+        // Retrieve the CA validity period
+        try {
+            caCert.checkValidity();
+
+        } catch (CertificateNotYetValidException e) {
+            // log that the CA is not yet valid
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_CA_IS_NOT_YET_VALID",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw e;
+
+        } catch (CertificateExpiredException e) {
+            // log that the CA is expired
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_CA_IS_EXPIRED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw e;
         }
 
-        return;
+        // log that the CA is valid
+        String logMessage = CMS.getLogMessage(
+                "SELFTESTS_CA_IS_VALID",
+                getSelfTestName());
+        mSelfTestSubsystem.log(logger, logMessage);
     }
 }
diff --git a/base/server/cms/src/com/netscape/cms/selftests/common/SystemCertsVerification.java b/base/server/cms/src/com/netscape/cms/selftests/common/SystemCertsVerification.java
index f5b0939..5c1e97b 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/common/SystemCertsVerification.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/common/SystemCertsVerification.java
@@ -185,29 +185,22 @@ public class SystemCertsVerification
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
-        boolean rc = false;
-
-        rc = CMS.verifySystemCerts();
-        if (rc == true) {
-            logMessage = CMS.getLogMessage("SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_SUCCESS",
-                                                getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                        logMessage);
-        } else {
-            logMessage = CMS.getLogMessage("SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_FAILURE",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-            throw new ESelfTestException(logMessage);
+    public void runSelfTest(ILogEventListener logger) throws Exception {
+
+        boolean status = CMS.verifySystemCerts();
+        if (!status) {
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_FAILURE",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
         }
 
-        return;
+        String logMessage = CMS.getLogMessage(
+                "SELFTESTS_COMMON_SYSTEM_CERTS_VERIFICATION_SUCCESS",
+                getSelfTestName());
+        mSelfTestSubsystem.log(logger, logMessage);
     }
 }
diff --git a/base/server/cms/src/com/netscape/cms/selftests/kra/KRAPresence.java b/base/server/cms/src/com/netscape/cms/selftests/kra/KRAPresence.java
index 832d2b7..ff0c3fb 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/kra/KRAPresence.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/kra/KRAPresence.java
@@ -188,64 +188,46 @@ public class KRAPresence
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
-        IKeyRecoveryAuthority kra = null;
-        org.mozilla.jss.crypto.X509Certificate kraCert = null;
-        PublicKey kraPubKey = null;
-
-        kra = (IKeyRecoveryAuthority) CMS.getSubsystem(mSubId);
+    public void runSelfTest(ILogEventListener logger) throws Exception {
 
+        IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority) CMS.getSubsystem(mSubId);
         if (kra == null) {
             // log that the KRA is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_KRA_IS_NOT_PRESENT",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-
-            throw new ESelfTestException(logMessage);
-        } else {
-            // Retrieve the KRA certificate
-            kraCert = kra.getTransportCert();
-
-            if (kraCert == null) {
-                // log that the RA is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_KRA_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the KRA certificate public key
-            kraPubKey = kraCert.getPublicKey();
-
-            if (kraPubKey == null) {
-                // log that something is seriously wrong with the KRA
-                logMessage = CMS.getLogMessage("SELFTESTS_KRA_IS_CORRUPT",
-                                                getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_KRA_IS_NOT_PRESENT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-            // log that the KRA is present
-            logMessage = CMS.getLogMessage("SELFTESTS_KRA_IS_PRESENT",
-                                            getSelfTestName());
+        // Retrieve the KRA certificate
+        org.mozilla.jss.crypto.X509Certificate kraCert = kra.getTransportCert();
+        if (kraCert == null) {
+            // log that the RA is not yet initialized
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_KRA_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
+        // Retrieve the KRA certificate public key
+        PublicKey kraPubKey = kraCert.getPublicKey();
+        if (kraPubKey == null) {
+            // log that something is seriously wrong with the KRA
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_KRA_IS_CORRUPT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
         }
 
-        return;
+        // log that the KRA is present
+        String logMessage = CMS.getLogMessage(
+                "SELFTESTS_KRA_IS_PRESENT",
+                getSelfTestName());
+        mSelfTestSubsystem.log(logger, logMessage);
     }
 }
diff --git a/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java b/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java
index a3d9e3a..db9d237 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPPresence.java
@@ -192,89 +192,66 @@ public class OCSPPresence
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
-        IOCSPAuthority ocsp = null;
-        ISigningUnit ocspSigningUnit = null;
-        X509CertImpl ocspCert = null;
-        X509Key ocspPubKey = null;
-
-        ocsp = (IOCSPAuthority) CMS.getSubsystem(mOcspSubId);
+    public void runSelfTest(ILogEventListener logger) throws Exception {
 
+        IOCSPAuthority ocsp = (IOCSPAuthority) CMS.getSubsystem(mOcspSubId);
         if (ocsp == null) {
             // log that the OCSP is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_OCSP_IS_NOT_PRESENT",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-
-            throw new ESelfTestException(logMessage);
-        } else {
-            // Retrieve the OCSP signing unit
-            ocspSigningUnit = ocsp.getSigningUnit();
-
-            if (ocspSigningUnit == null) {
-                // log that the OCSP is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the OCSP certificate
-            ocspCert = ocspSigningUnit.getCertImpl();
-
-            if (ocspCert == null) {
-                // log that the OCSP is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the OCSP certificate public key
-            try {
-                ocspPubKey = (X509Key)
-                             ocspCert.get(X509CertImpl.PUBLIC_KEY);
-
-                if (ocspPubKey == null) {
-                    // log that something is seriously wrong with the OCSP
-                    logMessage = CMS.getLogMessage("SELFTESTS_OCSP_IS_CORRUPT",
-                                                    getSelfTestName());
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_NOT_PRESENT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-                    mSelfTestSubsystem.log(logger,
-                                            logMessage);
+        // Retrieve the OCSP signing unit
+        ISigningUnit ocspSigningUnit = ocsp.getSigningUnit();
+        if (ocspSigningUnit == null) {
+            // log that the OCSP is not yet initialized
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-                    throw new ESelfTestException(logMessage);
-                }
-            } catch (CertificateParsingException e) {
-                // log that something is seriously wrong with the OCSP
-                mSelfTestSubsystem.log(logger,
-                                        e.toString());
+        // Retrieve the OCSP certificate
+        X509CertImpl ocspCert = ocspSigningUnit.getCertImpl();
+        if (ocspCert == null) {
+            // log that the OCSP is not yet initialized
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-                throw new ESelfTestException(e.toString());
-            }
+        // Retrieve the OCSP certificate public key
+        X509Key ocspPubKey;
+        try {
+            ocspPubKey = (X509Key)ocspCert.get(X509CertImpl.PUBLIC_KEY);
 
-            // log that the OCSP is present
-            logMessage = CMS.getLogMessage("SELFTESTS_OCSP_IS_PRESENT",
-                                            getSelfTestName());
+        } catch (CertificateParsingException e) {
+            // log that something is seriously wrong with the OCSP
+            mSelfTestSubsystem.log(logger, e.toString());
+            throw e;
+        }
 
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
+        if (ocspPubKey == null) {
+            // log that something is seriously wrong with the OCSP
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_CORRUPT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
         }
 
-        return;
+        // log that the OCSP is present
+        String logMessage = CMS.getLogMessage(
+                "SELFTESTS_OCSP_IS_PRESENT",
+                getSelfTestName());
+        mSelfTestSubsystem.log(logger, logMessage);
     }
 }
diff --git a/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java b/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java
index 383779d..6aadf84 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/ocsp/OCSPValidity.java
@@ -192,89 +192,68 @@ public class OCSPValidity
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
+    public void runSelfTest(ILogEventListener logger) throws Exception {
         String logMessage = null;
-        IOCSPAuthority ocsp = null;
-        ISigningUnit ocspSigningUnit = null;
-        X509CertImpl ocspCert = null;
-
-        ocsp = (IOCSPAuthority) CMS.getSubsystem(mOcspSubId);
 
+        IOCSPAuthority ocsp = (IOCSPAuthority) CMS.getSubsystem(mOcspSubId);
         if (ocsp == null) {
             // log that the OCSP is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_OCSP_IS_NOT_PRESENT",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-
-            throw new ESelfTestException(logMessage);
-        } else {
-            // Retrieve the OCSP signing unit
-            ocspSigningUnit = ocsp.getSigningUnit();
-
-            if (ocspSigningUnit == null) {
-                // log that the OCSP is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the OCSP certificate
-            ocspCert = ocspSigningUnit.getCertImpl();
-
-            if (ocspCert == null) {
-                // log that the OCSP is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the OCSP validity period
-            try {
-                ocspCert.checkValidity();
-            } catch (CertificateNotYetValidException e) {
-                // log that the OCSP is not yet valid
-                logMessage = CMS.getLogMessage(
-                                 "SELFTESTS_OCSP_IS_NOT_YET_VALID",
-                                 getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            } catch (CertificateExpiredException e) {
-                // log that the OCSP is expired
-                logMessage = CMS.getLogMessage("SELFTESTS_OCSP_IS_EXPIRED",
-                                                getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
+            logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_NOT_PRESENT",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-                throw new ESelfTestException(logMessage);
-            }
+        // Retrieve the OCSP signing unit
+        ISigningUnit ocspSigningUnit = ocsp.getSigningUnit();
+        if (ocspSigningUnit == null) {
+            // log that the OCSP is not yet initialized
+            logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-            // log that the OCSP is valid
-            logMessage = CMS.getLogMessage("SELFTESTS_OCSP_IS_VALID",
-                                            getSelfTestName());
+        // Retrieve the OCSP certificate
+        X509CertImpl ocspCert = ocspSigningUnit.getCertImpl();
+        if (ocspCert == null) {
+            // log that the OCSP is not yet initialized
+            logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new Exception(logMessage);
+        }
 
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
+        // Retrieve the OCSP validity period
+        try {
+            ocspCert.checkValidity();
+
+        } catch (CertificateNotYetValidException e) {
+            // log that the OCSP is not yet valid
+            logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_NOT_YET_VALID",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw e;
+
+        } catch (CertificateExpiredException e) {
+            // log that the OCSP is expired
+            logMessage = CMS.getLogMessage(
+                    "SELFTESTS_OCSP_IS_EXPIRED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw e;
         }
 
-        return;
+        // log that the OCSP is valid
+        logMessage = CMS.getLogMessage(
+                "SELFTESTS_OCSP_IS_VALID",
+                getSelfTestName());
+        mSelfTestSubsystem.log(logger, logMessage);
     }
 }
diff --git a/base/server/cms/src/com/netscape/cms/selftests/ra/RAPresence.java b/base/server/cms/src/com/netscape/cms/selftests/ra/RAPresence.java
deleted file mode 100644
index 6facd80..0000000
--- a/base/server/cms/src/com/netscape/cms/selftests/ra/RAPresence.java
+++ /dev/null
@@ -1,261 +0,0 @@
-// --- 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) 2007 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-// package statement //
-///////////////////////
-
-package com.netscape.cms.selftests.ra;
-
-///////////////////////
-// import statements //
-///////////////////////
-
-import java.security.PublicKey;
-import java.util.Locale;
-
-import com.netscape.certsrv.apps.CMS;
-import com.netscape.certsrv.base.EBaseException;
-import com.netscape.certsrv.base.IConfigStore;
-import com.netscape.certsrv.logging.ILogEventListener;
-import com.netscape.certsrv.ra.IRegistrationAuthority;
-import com.netscape.certsrv.selftests.EDuplicateSelfTestException;
-import com.netscape.certsrv.selftests.EInvalidSelfTestException;
-import com.netscape.certsrv.selftests.EMissingSelfTestException;
-import com.netscape.certsrv.selftests.ESelfTestException;
-import com.netscape.certsrv.selftests.ISelfTestSubsystem;
-import com.netscape.cms.selftests.ASelfTest;
-
-//////////////////////
-// class definition //
-//////////////////////
-
-/**
- * This class implements a self test to check for RA presence.
- * <P>
- *
- * <PRE>
- * NOTE:  This self-test is for Registration Authorities prior to
- *        Netscape Certificate Management System 7.0.  It does NOT
- *        apply to the Registration Authority found in
- *        Red Hat Certificate System 7.3 or later (including
- *        ALL versions of Dogtag Certificate System).
- * </PRE>
- * <P>
- *
- * @deprecated
- * @author mharmsen
- * @author thomask
- * @version $Revision$, $Date$
- */
-public class RAPresence
-        extends ASelfTest {
-    ////////////////////////
-    // default parameters //
-    ////////////////////////
-
-    ///////////////////////////
-    // RAPresence parameters //
-    ///////////////////////////
-
-    // parameter information
-    public static final String PROP_RA_SUB_ID = "RaSubId";
-    private String mRaSubId = null;
-
-    /////////////////////
-    // default methods //
-    /////////////////////
-
-    ////////////////////////
-    // RAPresence methods //
-    ////////////////////////
-
-    /**
-     * Initializes this subsystem with the configuration store
-     * associated with this instance name.
-     * <P>
-     *
-     * @param subsystem the associated subsystem
-     * @param instanceName the name of this self test instance
-     * @param parameters configuration store (self test parameters)
-     * @exception EDuplicateSelfTestException subsystem has duplicate name/value
-     * @exception EInvalidSelfTestException subsystem has invalid name/value
-     * @exception EMissingSelfTestException subsystem has missing name/value
-     */
-    public void initSelfTest(ISelfTestSubsystem subsystem,
-                              String instanceName,
-                              IConfigStore parameters)
-            throws EDuplicateSelfTestException,
-            EInvalidSelfTestException,
-            EMissingSelfTestException {
-        super.initSelfTest(subsystem, instanceName, parameters);
-
-        // retrieve mandatory parameter(s)
-        try {
-            mRaSubId = mConfig.getString(PROP_RA_SUB_ID);
-            if (mRaSubId != null) {
-                mRaSubId = mRaSubId.trim();
-            } else {
-                mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
-                                        CMS.getLogMessage(
-                                                "SELFTESTS_MISSING_VALUES",
-                                                getSelfTestName(),
-                                                mPrefix
-                                                        + "."
-                                                        + PROP_RA_SUB_ID));
-
-                throw new EMissingSelfTestException(PROP_RA_SUB_ID);
-            }
-        } catch (EBaseException e) {
-            mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
-                                    CMS.getLogMessage(
-                                            "SELFTESTS_MISSING_NAME",
-                                            getSelfTestName(),
-                                            mPrefix
-                                                    + "."
-                                                    + PROP_RA_SUB_ID));
-
-            throw new EMissingSelfTestException(mPrefix,
-                                                 PROP_RA_SUB_ID,
-                                                 null);
-        }
-
-        // retrieve optional parameter(s)
-
-        return;
-    }
-
-    /**
-     * Notifies this subsystem if it is in execution mode.
-     * <P>
-     *
-     * @exception ESelfTestException failed to start
-     */
-    public void startupSelfTest()
-            throws ESelfTestException {
-        return;
-    }
-
-    /**
-     * Stops this subsystem. The subsystem may call shutdownSelfTest
-     * anytime after initialization.
-     * <P>
-     */
-    public void shutdownSelfTest() {
-        return;
-    }
-
-    /**
-     * Returns the name associated with this self test. This method may
-     * return null if the self test has not been intialized.
-     * <P>
-     *
-     * @return instanceName of this self test
-     */
-    public String getSelfTestName() {
-        return super.getSelfTestName();
-    }
-
-    /**
-     * Returns the root configuration storage (self test parameters)
-     * associated with this subsystem.
-     * <P>
-     *
-     * @return configuration store (self test parameters) of this subsystem
-     */
-    public IConfigStore getSelfTestConfigStore() {
-        return super.getSelfTestConfigStore();
-    }
-
-    /**
-     * Retrieves description associated with an individual self test.
-     * This method may return null.
-     * <P>
-     *
-     * @param locale locale of the client that requests the description
-     * @return description of self test
-     */
-    public String getSelfTestDescription(Locale locale) {
-        return CMS.getUserMessage(locale,
-                                   "CMS_SELFTESTS_RA_PRESENCE_DESCRIPTION");
-    }
-
-    /**
-     * Execute an individual self test.
-     * <P>
-     *
-     * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
-     */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
-        IRegistrationAuthority ra = null;
-        org.mozilla.jss.crypto.X509Certificate raCert = null;
-        PublicKey raPubKey = null;
-
-        ra = (IRegistrationAuthority) CMS.getSubsystem(mRaSubId);
-
-        if (ra == null) {
-            // log that the RA is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_RA_IS_NOT_PRESENT",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-
-            throw new ESelfTestException(logMessage);
-        } else {
-            // Retrieve the RA certificate
-            raCert = ra.getRACert();
-
-            if (raCert == null) {
-                // log that the RA is not yet initialized
-                logMessage = CMS.getLogMessage(
-                             "SELFTESTS_RA_IS_NOT_INITIALIZED",
-                             getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // Retrieve the RA certificate public key
-            raPubKey = raCert.getPublicKey();
-
-            if (raPubKey == null) {
-                // log that something is seriously wrong with the RA
-                logMessage = CMS.getLogMessage("SELFTESTS_RA_IS_CORRUPT",
-                                                getSelfTestName());
-
-                mSelfTestSubsystem.log(logger,
-                                        logMessage);
-
-                throw new ESelfTestException(logMessage);
-            }
-
-            // log that the RA is present
-            logMessage = CMS.getLogMessage("SELFTESTS_RA_IS_PRESENT",
-                                            getSelfTestName());
-
-            mSelfTestSubsystem.log(logger,
-                                    logMessage);
-        }
-
-        return;
-    }
-}
diff --git a/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java b/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
index d5e7c11..1686ba5 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
@@ -104,7 +104,7 @@ public class TKSKnownSessionKey
         mMacKey = getConfigByteArray("macKey", 16);
         mUseSoftToken = getConfigString("useSoftToken");
 
-        // AC: KDF SPEC CHANGE 
+        // AC: KDF SPEC CHANGE
         // read CUID for the KDD field
         mKDD = getConfigByteArray("CUID", 10);
         //
@@ -143,7 +143,7 @@ public class TKSKnownSessionKey
                     getSelfTestName(), mPrefix + ".nistSP800-108KdfUseCuidAsKdd"));
                 throw new EMissingSelfTestException("nistSP800-108KdfUseCuidAsKdd");
         }
-        
+
         String defKeySetMacKey = null;
         tks = CMS.getSubsystem(mTksSubId);
         if (tks != null) {
@@ -175,7 +175,7 @@ public class TKSKnownSessionKey
             if (mSessionKey == null) {
                 mSessionKey = SessionKey.ComputeSessionKey(mToken, mKeyName,
                                                             mCardChallenge, mHostChallenge,
-                                                            mKeyInfo, 
+                                                            mKeyInfo,
                                                             mNistSP800_108KdfOnKeyVersion,   // AC: KDF SPEC CHANGE - pass in configuration self-test value
                                                             mNistSP800_108KdfUseCuidAsKdd,   // AC: KDF SPEC CHANGE - pass in configuration self-test value
                                                             mCUID,
@@ -320,13 +320,12 @@ public class TKSKnownSessionKey
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        IConfigStore cs = CMS.getConfigStore();
-        String sharedSecretName;
+    public void runSelfTest(ILogEventListener logger) throws Exception {
+
         try {
+            IConfigStore cs = CMS.getConfigStore();
             boolean useNewNames = cs.getBoolean("tks.useNewSharedSecretNames", false);
             if (useNewNames) {
                 String tpsList = cs.getString("tps.list", "");
@@ -336,29 +335,39 @@ public class TKSKnownSessionKey
                 }
 
                 for (String tpsID : tpsList.split(",")) {
-                    sharedSecretName = cs.getString("tps." + tpsID + ".nickname", "");
+                    String sharedSecretName = cs.getString("tps." + tpsID + ".nickname", "");
                     if (!sharedSecretName.isEmpty()) {
                         CMS.debug("TKSKnownSessionKey: testing with key " + sharedSecretName);
-                        generateSessionKey(logger, sharedSecretName);
+                        generateSessionKey(sharedSecretName);
                     }
                 }
+
             } else {
                 // legacy systems
-                sharedSecretName = cs.getString("tks.tksSharedSymKeyName", "sharedSecret");
-                generateSessionKey(logger, sharedSecretName);
+                String sharedSecretName = cs.getString("tks.tksSharedSymKeyName", "sharedSecret");
+                generateSessionKey(sharedSecretName);
             }
-        } catch (EBaseException e) {
-            e.printStackTrace();
-            CMS.debug("TKSKnownSessionKey: failed to read config file to set up test");
-            String logMessage = CMS.getLogMessage("SELFTESTS_TKS_FAILED", getSelfTestName(), getSelfTestName());
+
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TKS_SUCCEEDED",
+                    getSelfTestName(),
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            CMS.debug("TKSKnownSessionKey self test SUCCEEDED");
+
+        } catch (Exception e) {
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TKS_FAILED",
+                    getSelfTestName(),
+                    getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw e;
         }
+
         return;
     }
 
-    private void generateSessionKey(ILogEventListener logger, String sharedSecretName) throws ESelfTestException {
-        String logMessage;
+    private void generateSessionKey(String sharedSecretName) throws Exception {
         String keySet = "defKeySet";
 
         byte[] sessionKey = SessionKey.ComputeSessionKey(
@@ -374,14 +383,7 @@ public class TKSKnownSessionKey
         // For FIPS compliance, the routine now returns a wrapped key, which can't be extracted and compared.
         if (sessionKey == null) {
             CMS.debug("TKSKnownSessionKey: generated no session key");
-            CMS.debug("TKSKnownSessionKey self test FAILED");
-            logMessage = CMS.getLogMessage("SELFTESTS_TKS_FAILED", getSelfTestName(), getSelfTestName());
-            mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
-        } else {
-            logMessage = CMS.getLogMessage("SELFTESTS_TKS_SUCCEEDED", getSelfTestName(), getSelfTestName());
-            mSelfTestSubsystem.log(logger, logMessage);
-            CMS.debug("TKSKnownSessionKey self test SUCCEEDED");
+            throw new Exception("No session key generated");
         }
     }
 }
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 b8cf27c..b6325b7 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
@@ -3248,7 +3248,11 @@ public final class CMSAdminServlet extends AdminServlet {
 
                         // store this information for console notification
                         content += "COMPLETED SUCCESSFULLY\n";
-                    } catch (ESelfTestException e) {
+
+                    } catch (Exception e) {
+
+                        CMS.debug(e);
+
                         // Check to see if the self test was critical:
                         if (mSelfTestSubsystem.isSelfTestCriticalOnDemand(
                                 instanceName)) {
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 ad1a1b0..d060f81 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/selftests/SelfTestSubsystem.java
@@ -530,7 +530,11 @@ public class SelfTestSubsystem
                     }
 
                     test.runSelfTest(mLogger);
-                } catch (ESelfTestException e) {
+
+                } catch (Exception e) {
+
+                    CMS.debug(e);
+
                     // Check to see if the self test was critical:
                     if (isSelfTestCriticalOnDemand(instanceName)) {
                         log(mLogger,
@@ -810,146 +814,76 @@ public class SelfTestSubsystem
      * </ul>
      *
      * @exception EMissingSelfTestException subsystem has missing name
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTestsAtStartup()
-            throws EMissingSelfTestException, ESelfTestException {
-        String auditMessage = null;
+    public void runSelfTestsAtStartup() throws Exception {
 
-        // ensure that any low-level exceptions are reported
-        // to the signed audit log and stored as failures
-        try {
-            if (CMS.debugOn()) {
-                CMS.debug("SelfTestSubsystem::runSelfTestsAtStartup():"
-                        + "  ENTERING . . .");
-            }
+        // log that execution of startup self tests has begun
+        log(mLogger,
+                CMS.getLogMessage(
+                        "CMSCORE_SELFTESTS_RUN_AT_STARTUP"));
 
-            // loop through all self test plugin instances
-            // specified to be executed at server startup
-            Enumeration<SelfTestOrderedInstance> instances = mStartupOrder.elements();
+        // loop through all self test plugin instances
+        // specified to be executed at server startup
+        Enumeration<SelfTestOrderedInstance> instances = mStartupOrder.elements();
 
-            while (instances.hasMoreElements()) {
-                SelfTestOrderedInstance instance = instances.nextElement();
+        while (instances.hasMoreElements()) {
+            SelfTestOrderedInstance instance = instances.nextElement();
 
-                String instanceFullName = null;
-                String instanceName = instance.getSelfTestName();
+            String instanceFullName = null;
+            String instanceName = instance.getSelfTestName();
 
-                if (instanceName != null) {
-                    instanceName = instanceName.trim();
-                    instanceFullName = getFullName(mPrefix,
-                                instanceName);
-                } else {
-                    log(mLogger,
-                            CMS.getLogMessage(
-                                    "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
+            if (instanceName == null) {
+                log(mLogger,
+                        CMS.getLogMessage(
+                                "CMSCORE_SELFTESTS_PROPERTY_NAME_IS_NULL"));
 
-                    // store a message in the signed audit log file
-                    auditMessage = CMS.getLogMessage(
-                                LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
-                                ILogger.SYSTEM_UID,
-                                ILogger.FAILURE);
+                throw new EMissingSelfTestException();
+            }
 
-                    audit(auditMessage);
+            instanceName = instanceName.trim();
+            instanceFullName = getFullName(mPrefix, instanceName);
 
-                    throw new EMissingSelfTestException();
-                }
+            if (!mSelfTestInstances.containsKey(instanceName)) {
+                // self test plugin instance property name is not present
+                log(mLogger,
+                        CMS.getLogMessage(
+                                "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
+                                instanceFullName));
 
-                if (mSelfTestInstances.containsKey(instanceName)) {
-                    ISelfTest test = mSelfTestInstances.get(instanceName);
-
-                    try {
-                        if (CMS.debugOn()) {
-                            CMS.debug("SelfTestSubsystem::runSelfTestsAtStartup():"
-                                    + "    running \""
-                                    + test.getSelfTestName()
-                                    + "\"");
-                        }
-
-                        test.runSelfTest(mLogger);
-                    } catch (ESelfTestException e) {
-                        // Check to see if the self test was critical:
-                        if (isSelfTestCriticalAtStartup(instanceName)) {
-                            log(mLogger,
-                                    CMS.getLogMessage(
-                                            "CMSCORE_SELFTESTS_RUN_AT_STARTUP_FAILED",
-                                            instanceFullName));
-
-                            // store a message in the signed audit log file
-                            auditMessage = CMS.getLogMessage(
-                                        LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
-                                        ILogger.SYSTEM_UID,
-                                        ILogger.FAILURE);
-
-                            audit(auditMessage);
-
-                            // shutdown the system gracefully
-                            CMS.shutdown();
-
-                            IConfigStore cs = CMS.getConfigStore();
-                            String instanceID = cs.get("instanceId");
-                            String subsystemID = cs.get("cs.type").toLowerCase();
-
-                            System.out.println("SelfTestSubsystem: Disabling \"" + subsystemID + "\" subsystem due to selftest failure.");
-
-                            try {
-                                ProcessBuilder pb = new ProcessBuilder("pki-server", "subsystem-disable", "-i", instanceID, subsystemID);
-                                Process process = pb.inheritIO().start();
-                                int rc = process.waitFor();
-
-                                if (rc != 0) {
-                                    System.out.println("SelfTestSubsystem: Unable to disable \"" + subsystemID + "\". RC: " + rc);
-                                }
-
-                            } catch (Exception e2) {
-                                e.printStackTrace();
-                            }
-
-                            return;
-                        }
-                    }
-                } else {
-                    // self test plugin instance property name is not present
-                    log(mLogger,
-                            CMS.getLogMessage(
-                                    "CMSCORE_SELFTESTS_PROPERTY_MISSING_NAME",
-                                    instanceFullName));
+                throw new EMissingSelfTestException(instanceFullName);
+            }
 
-                    // store a message in the signed audit log file
-                    auditMessage = CMS.getLogMessage(
-                                LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
-                                ILogger.SYSTEM_UID,
-                                ILogger.FAILURE);
+            ISelfTest test = mSelfTestInstances.get(instanceName);
 
-                    audit(auditMessage);
+            try {
+                CMS.debug("SelfTestSubsystem: running " + test.getSelfTestName());
+                test.runSelfTest(mLogger);
 
-                    throw new EMissingSelfTestException(instanceFullName);
-                }
-            }
+            } catch (Exception e) {
 
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
-                        ILogger.SYSTEM_UID,
-                        ILogger.SUCCESS);
+                CMS.debug(e);
 
-            audit(auditMessage);
+                // Check to see if the self test was critical:
+                if (!isSelfTestCriticalAtStartup(instanceName)) {
+                    continue;
+                }
+
+                log(mLogger,
+                        CMS.getLogMessage(
+                                "CMSCORE_SELFTESTS_RUN_AT_STARTUP_FAILED",
+                                instanceFullName));
 
-            if (CMS.debugOn()) {
-                CMS.debug("SelfTestSubsystem::runSelfTestsAtStartup():"
-                        + "  EXITING.");
+                throw e;
             }
-        } catch (EMissingSelfTestException eAudit1) {
-            // store a message in the signed audit log file
-            auditMessage = CMS.getLogMessage(
-                        LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
-                        ILogger.SYSTEM_UID,
-                        ILogger.FAILURE);
+        }
 
-            audit(auditMessage);
+        // log that execution of all "critical" startup self tests
+        // has completed "successfully"
+        log(mLogger,
+                CMS.getLogMessage(
+                        "CMSCORE_SELFTESTS_RUN_AT_STARTUP_SUCCEEDED"));
 
-            // rethrow the specific exception to be handled later
-            throw eAudit1;
-        }
     }
 
     public void log(int level, String msg) {
@@ -1831,39 +1765,88 @@ public class SelfTestSubsystem
      *
      * @exception EBaseException base CMS exception
      */
-    public void startup()
-            throws EBaseException {
+    public void startup() throws EBaseException {
+
         // loop through all self test plugin instances
         Enumeration<ISelfTest> instances = mSelfTestInstances.elements();
 
         while (instances.hasMoreElements()) {
             ISelfTest instance = instances.nextElement();
-
             instance.startupSelfTest();
         }
 
-        if (!CMS.isPreOpMode()) {
-            // run all self test plugin instances (designated at startup)
-            Enumeration<SelfTestOrderedInstance> selftests = mStartupOrder.elements();
+        if (CMS.isPreOpMode()) {
+            // do not run selftests in pre-op mode
+            return;
+        }
 
-            if (selftests.hasMoreElements()) {
-                // log that execution of startup self tests has begun
-                log(mLogger,
-                        CMS.getLogMessage(
-                                "CMSCORE_SELFTESTS_RUN_AT_STARTUP"));
+        // run all self test plugin instances (designated at startup)
+        Enumeration<SelfTestOrderedInstance> selftests = mStartupOrder.elements();
 
-                // execute all startup self tests
-                runSelfTestsAtStartup();
+        if (!selftests.hasMoreElements()) {
+            log(mLogger,
+                    CMS.getLogMessage(
+                            "CMSCORE_SELFTESTS_NOT_RUN_AT_STARTUP"));
+            return;
+        }
 
-                // log that execution of all "critical" startup self tests
-                // has completed "successfully"
-                log(mLogger,
-                        CMS.getLogMessage(
-                                "CMSCORE_SELFTESTS_RUN_AT_STARTUP_SUCCEEDED"));
-            } else {
-                log(mLogger,
-                        CMS.getLogMessage(
-                                "CMSCORE_SELFTESTS_NOT_RUN_AT_STARTUP"));
+        // ensure that any low-level exceptions are reported
+        // to the signed audit log and stored as failures
+        try {
+            // execute all startup self tests
+            runSelfTestsAtStartup();
+
+            // store a message in the signed audit log file
+            String auditMessage = CMS.getLogMessage(
+                        LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+                        ILogger.SYSTEM_UID,
+                        ILogger.SUCCESS);
+
+            audit(auditMessage);
+
+        } catch (EMissingSelfTestException e) {
+
+            // store a message in the signed audit log file
+            String auditMessage = CMS.getLogMessage(
+                        LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+                        ILogger.SYSTEM_UID,
+                        ILogger.FAILURE);
+
+            audit(auditMessage);
+
+            // rethrow the specific exception to be handled later
+            throw e;
+
+        } catch (Exception e) {
+
+            // store a message in the signed audit log file
+            String auditMessage = CMS.getLogMessage(
+                        LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION,
+                        ILogger.SYSTEM_UID,
+                        ILogger.FAILURE);
+
+            audit(auditMessage);
+
+            // shutdown the system gracefully
+            CMS.shutdown();
+
+            IConfigStore cs = CMS.getConfigStore();
+            String instanceID = cs.get("instanceId");
+            String subsystemID = cs.get("cs.type").toLowerCase();
+
+            System.out.println("SelfTestSubsystem: Disabling \"" + subsystemID + "\" subsystem due to selftest failure.");
+
+            try {
+                ProcessBuilder pb = new ProcessBuilder("pki-server", "subsystem-disable", "-i", instanceID, subsystemID);
+                Process process = pb.inheritIO().start();
+                int rc = process.waitFor();
+
+                if (rc != 0) {
+                    System.out.println("SelfTestSubsystem: Unable to disable \"" + subsystemID + "\". RC: " + rc);
+                }
+
+            } catch (Exception e2) {
+                e.printStackTrace();
             }
         }
     }
diff --git a/base/tps/src/org/dogtagpki/server/tps/selftests/TPSPresence.java b/base/tps/src/org/dogtagpki/server/tps/selftests/TPSPresence.java
index 65ac197..665f068 100644
--- a/base/tps/src/org/dogtagpki/server/tps/selftests/TPSPresence.java
+++ b/base/tps/src/org/dogtagpki/server/tps/selftests/TPSPresence.java
@@ -140,48 +140,60 @@ public class TPSPresence extends ASelfTest {
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
+    public void runSelfTest(ILogEventListener logger) throws Exception {
+
         TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(tpsSubId);
         if (tps == null) {
             // log that the TPS is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_NOT_PRESENT", getSelfTestName());
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_NOT_PRESENT",
+                    getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw new Exception(logMessage);
         }
 
         // Retrieve the TPS certificate
-        org.mozilla.jss.crypto.X509Certificate tpsCert = null;
+        org.mozilla.jss.crypto.X509Certificate tpsCert;
         try {
             tpsCert = tps.getSubsystemCert();
+
         } catch (Exception e) {
-            e.printStackTrace();
             // cert does not exist or is not yet configured
             // tpsCert will remain null
+            // log that the TPS is not yet initialized
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_NOT_INITIALIZED",
+                    getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw e;
         }
 
         if (tpsCert == null) {
             // log that the TPS is not yet initialized
-            logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_NOT_INITIALIZED",
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_NOT_INITIALIZED",
                     getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw new Exception(logMessage);
         }
 
         // Retrieve the TPS certificate public key
         PublicKey tpsPubKey = tpsCert.getPublicKey();
         if (tpsPubKey == null) {
             // log that something is seriously wrong with the TPS
-            logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_CORRUPT", getSelfTestName());
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_CORRUPT",
+                    getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw new Exception(logMessage);
         }
 
         // log that the TPS is present
-        logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_PRESENT", getSelfTestName());
+        String logMessage = CMS.getLogMessage(
+                "SELFTESTS_TPS_IS_PRESENT",
+                getSelfTestName());
         mSelfTestSubsystem.log(logger, logMessage);
     }
 }
diff --git a/base/tps/src/org/dogtagpki/server/tps/selftests/TPSValidity.java b/base/tps/src/org/dogtagpki/server/tps/selftests/TPSValidity.java
index f140d6e..28ac38d 100644
--- a/base/tps/src/org/dogtagpki/server/tps/selftests/TPSValidity.java
+++ b/base/tps/src/org/dogtagpki/server/tps/selftests/TPSValidity.java
@@ -144,54 +144,59 @@ public class TPSValidity extends ASelfTest {
      * <P>
      *
      * @param logger specifies logging subsystem
-     * @exception ESelfTestException self test exception
+     * @exception Exception self test exception
      */
-    public void runSelfTest(ILogEventListener logger)
-            throws ESelfTestException {
-        String logMessage = null;
-        TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(tpsSubId);
+    public void runSelfTest(ILogEventListener logger) throws Exception {
 
+        TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(tpsSubId);
         if (tps == null) {
             // log that the TPS is not installed
-            logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_NOT_PRESENT", getSelfTestName());
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_NOT_PRESENT",
+                    getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw new Exception(logMessage);
         }
 
         // Retrieve the TPS subsystem certificate
-        X509CertImpl tpsCert = null;
+        X509CertImpl tpsCert;
         try {
             tpsCert = new X509CertImpl(tps.getSubsystemCert().getEncoded());
         } catch (Exception e) {
             // certificate is not present or has not been configured
-            // tpsCert will remain null
-        }
-
-        if (tpsCert == null) {
             // log that the TPS is not yet initialized
-            logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_NOT_INITIALIZED",
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_NOT_INITIALIZED",
                     getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw e;
         }
 
         // Check the TPS validity period
         try {
             tpsCert.checkValidity();
+
         } catch (CertificateNotYetValidException e) {
             // log that the TPS is not yet valid
-            logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_NOT_YET_VALID", getSelfTestName());
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_NOT_YET_VALID",
+                    getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw e;
+
         } catch (CertificateExpiredException e) {
             // log that the TPS is expired
-            logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_EXPIRED", getSelfTestName());
+            String logMessage = CMS.getLogMessage(
+                    "SELFTESTS_TPS_IS_EXPIRED",
+                    getSelfTestName());
             mSelfTestSubsystem.log(logger, logMessage);
-            throw new ESelfTestException(logMessage);
+            throw e;
         }
 
         // log that the TPS is valid
-        logMessage = CMS.getLogMessage("SELFTESTS_TPS_IS_VALID", getSelfTestName());
+        String logMessage = CMS.getLogMessage(
+                "SELFTESTS_TPS_IS_VALID",
+                getSelfTestName());
         mSelfTestSubsystem.log(logger, logMessage);
     }
 }
-- 
1.8.3.1


From 9b62371172bbf0868e84e7f1d8d9ab48e5a0afff Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 24 Jun 2015 16:19:55 -0400
Subject: [PATCH 03/21] Fixed Modutil.is_security_module_registered().

Due to issues with HSM the Modutil.is_security_module_registered()
has been modified to the get the list of all registered modules
and then use it to check if a module is registered.

https://fedorahosted.org/pki/ticket/1444
---
 .../python/pki/server/deployment/pkihelper.py      | 90 +++++++++++-----------
 1 file changed, 45 insertions(+), 45 deletions(-)

diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index 42ca0d9..5bc4ffa 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -2688,56 +2688,56 @@ class Modutil:
     def __init__(self, deployer):
         self.mdict = deployer.mdict
 
-    def is_security_module_registered(self, path, modulename,
-                                      prefix=None, critical_failure=True):
-        status = False
-        try:
-            # Compose this "modutil" command
-            command = ["modutil"]
-            #   Provide a path to the NSS security databases
-            if path:
-                command.extend(["-dbdir", path])
-            else:
-                config.pki_log.error(
-                    log.PKIHELPER_MODUTIL_MISSING_PATH,
-                    extra=config.PKI_INDENTATION_LEVEL_2)
-                raise Exception(log.PKIHELPER_MODUTIL_MISSING_PATH)
-            #   Add optional security database prefix
-            if prefix is not None:
-                command.extend(["--dbprefix", prefix])
-            #   Append '-nocertdb' switch
-            command.extend(["-nocertdb"])
-            #   Specify a 'modulename'
-            if modulename:
-                command.extend(["-list", modulename])
-            else:
-                config.pki_log.error(
-                    log.PKIHELPER_MODUTIL_MISSING_MODULENAME,
-                    extra=config.PKI_INDENTATION_LEVEL_2)
-                raise Exception(log.PKIHELPER_MODUTIL_MISSING_MODULENAME)
-            # Display this "modutil" command
-            config.pki_log.info(
-                log.PKIHELPER_REGISTERED_SECURITY_MODULE_CHECK_1,
-                ' '.join(command),
+    def is_security_module_registered(self, path, modulename, prefix=None):
+
+        if not path:
+            config.pki_log.error(
+                log.PKIHELPER_MODUTIL_MISSING_PATH,
                 extra=config.PKI_INDENTATION_LEVEL_2)
-            # Execute this "modutil" command
-            subprocess.check_call(command)
-            # 'modulename' is already registered
-            status = True
-            config.pki_log.info(
-                log.PKIHELPER_REGISTERED_SECURITY_MODULE_1, modulename,
+            raise Exception(log.PKIHELPER_MODUTIL_MISSING_PATH)
+
+        if not modulename:
+            config.pki_log.error(
+                log.PKIHELPER_MODUTIL_MISSING_MODULENAME,
                 extra=config.PKI_INDENTATION_LEVEL_2)
-        except subprocess.CalledProcessError as exc:
-            # 'modulename' is not registered
+            raise Exception(log.PKIHELPER_MODUTIL_MISSING_MODULENAME)
+
+        command = [
+            'modutil',
+            '-list',
+            '-dbdir', path,
+            '-nocertdb']
+
+        if prefix:
+            command.extend(['--dbprefix', prefix])
+
+        config.pki_log.info(
+            log.PKIHELPER_REGISTERED_SECURITY_MODULE_CHECK_1,
+            ' '.join(command),
+            extra=config.PKI_INDENTATION_LEVEL_2)
+
+        # execute command
+        p = subprocess.Popen(command, stdout=subprocess.PIPE)
+        output = p.communicate()[0]
+
+        p.wait()
+        # ignore return code due to issues with HSM
+        # https://fedorahosted.org/pki/ticket/1444
+
+        # find modules from lines such as '1. NSS Internal PKCS #11 Module'
+        modules = re.findall(r'^ +\d+\. +(.*)$', output, re.MULTILINE)
+
+        if modulename not in modules:
             config.pki_log.info(
                 log.PKIHELPER_UNREGISTERED_SECURITY_MODULE_1, modulename,
                 extra=config.PKI_INDENTATION_LEVEL_2)
-        except OSError as exc:
-            config.pki_log.error(log.PKI_OSERROR_1, exc,
-                                 extra=config.PKI_INDENTATION_LEVEL_2)
-            if critical_failure:
-                raise
-        return status
+            return False
+
+        config.pki_log.info(
+            log.PKIHELPER_REGISTERED_SECURITY_MODULE_1, modulename,
+            extra=config.PKI_INDENTATION_LEVEL_2)
+        return True
+
 
     def register_security_module(self, path, modulename, libfile,
                                  prefix=None, critical_failure=True):
-- 
1.8.3.1


From c9180f086971dcf6f183ed5f627510f2183cc61e Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Mon, 29 Jun 2015 15:09:07 -0400
Subject: [PATCH 04/21] Updated pki-cert man page.

The man page for pki-cert has been modified to describe the file
format used to specify the search constraints.

https://fedorahosted.org/pki/ticket/995
---
 base/java-tools/man/man1/pki-cert.1 | 67 +++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/base/java-tools/man/man1/pki-cert.1 b/base/java-tools/man/man1/pki-cert.1
index ad2f566..ffa1fea 100644
--- a/base/java-tools/man/man1/pki-cert.1
+++ b/base/java-tools/man/man1/pki-cert.1
@@ -105,6 +105,73 @@ It is also possible to search for and list specific certificates by adding a sea
 
 .B pki ca-cert-find --issuedOnFrom 2012-06-15
 
+To list certificates with search constraints defined in a file:
+
+.B pki ca-cert-find --input <filename>
+
+where the file is in the following format:
+
+.IP
+.nf
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CertSearchRequest>
+
+    <serialNumberRangeInUse>true</serialNumberRangeInUse>
+    <serialFrom></serialFrom>
+    <serialTo></serialTo>
+
+    <subjectInUse>false</subjectInUse>
+    <eMail></eMail>
+    <commonName></commonName>
+    <userID></userID>
+    <orgUnit></orgUnit>
+    <org></org>
+    <locality></locality>
+    <state></state>
+    <country></country>
+
+    <matchExactly>false</matchExactly>
+
+    <status></status>
+
+    <revokedByInUse>false</revokedByInUse>
+    <revokedBy></revokedBy>
+
+    <revokedOnFrom>false</revokedOnFrom>
+    <revokedOnTo></revokedOnTo>
+
+    <revocationReasonInUse>false</revocationReasonInUse>
+    <revocationReason></revocationReason>
+
+    <issuedByInUse>false</issuedByInUse>
+    <issuedBy></issuedBy>
+
+    <issuedOnInUse>false</issuedOnInUse>
+    <issuedOnFrom></issuedOnFrom>
+    <issuedOnTo></issuedOnTo>
+
+    <validNotBeforeInUse>false</validNotBeforeInUse>
+    <validNotBeforeFrom></validNotBeforeFrom>
+    <validNotBeforeTo></validNotBeforeTo>
+
+    <validNotAfterInUse>false</validNotAfterInUse>
+    <validNotAfterFrom></validNotAfterFrom>
+    <validNotAfterTo></validNotAfterTo>
+
+    <validityLengthInUse>false</validityLengthInUse>
+    <validityOperation></validityOperation>
+    <validityCount></validityCount>
+    <validityUnit></validityUnit>
+
+    <certTypeInUse>false</certTypeInUse>
+    <certTypeSubEmailCA></certTypeSubEmailCA>
+    <certTypeSubSSLCA></certTypeSubSSLCA>
+    <certTypeSecureEmail></certTypeSecureEmail>
+
+</CertSearchRequest>
+.fi
+
+.PP
 To view a particular certificate:
 
 .B pki ca-cert-show <certificate ID>
-- 
1.8.3.1


From b9e461ca8a099b4535aa916886697c6eff01e431 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Mon, 29 Jun 2015 16:04:16 -0400
Subject: [PATCH 05/21] Updated pki man page.

The pki man page has been updated to describe results paging
parameters.

https://fedorahosted.org/pki/ticket/1122
---
 base/java-tools/man/man1/pki.1 | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/base/java-tools/man/man1/pki.1 b/base/java-tools/man/man1/pki.1
index 9e174e1..41ee3d3 100644
--- a/base/java-tools/man/man1/pki.1
+++ b/base/java-tools/man/man1/pki.1
@@ -220,6 +220,31 @@ Client-side password files generally store a password in an equals-sign-delimite
 .B foobar
    where:  token="internal" (default), password="foobar"
 
+.SS Results Paging
+
+Some commands (e.g. cert-find) may return multiple results. Since the number
+of results may be large, the results are split into multiple pages. By default
+the command will return only the first page (e.g. the first 20 results). To
+retrieve results from another page, additional paging parameters can be
+specified:
+
+.nf
+* start: index of the first result to return (default: 0)
+* size: number of results to return (default: 20)
+.fi
+
+For example, to retrieve the first page (index #0-#19):
+
+.B pki cert-find --start 0 --size 20
+
+To retrieve the second page (index #20-#39):
+
+.B pki cert-find --start 20 --size 20
+
+To retrieve the third page (index #40-#59):
+
+.B pki cert-find --start 40 --size 20
+
 .SH FILES
 .I /usr/bin/pki
 
-- 
1.8.3.1


From f0637352f12faed2727ee6dcd4661835bf9e2c40 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Mon, 29 Jun 2015 10:00:08 -0400
Subject: [PATCH 06/21] Cleaned up SystemConfigService.validateRequest().

The configure() in SystemConfigService method has been modified to
log only the error message in normal responses but log the full
stack trace when unexpected issues occur.

The validateData() in SystemConfigService has been renamed to
validateRequest() for clarity. The log messages have been modified
to include the invalid values entered in the request.
---
 .../cms/servlet/test/ConfigurationTest.java        |  2 +-
 .../certsrv/system/SystemConfigClient.java         |  2 +-
 .../certsrv/system/SystemConfigResource.java       |  2 +-
 .../dogtagpki/server/rest/SystemConfigService.java | 69 ++++++++++++----------
 4 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java b/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java
index bf4dc89..69994fa 100644
--- a/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java
+++ b/base/common/functional/src/com/netscape/cms/servlet/test/ConfigurationTest.java
@@ -76,7 +76,7 @@ public class ConfigurationTest {
         System.exit(1);
     }
 
-    public static void main(String args[]) throws NoSuchAlgorithmException, TokenException, IOException, InvalidBERException {
+    public static void main(String args[]) throws Exception {
         String host = null;
         String port = null;
         String cstype = null;
diff --git a/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java b/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java
index 242f005..8208915 100644
--- a/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java
+++ b/base/common/src/com/netscape/certsrv/system/SystemConfigClient.java
@@ -40,7 +40,7 @@ public class SystemConfigClient extends Client {
         configClient = createProxy(SystemConfigResource.class);
     }
 
-    public ConfigurationResponse configure(ConfigurationRequest data) {
+    public ConfigurationResponse configure(ConfigurationRequest data) throws Exception {
         return configClient.configure(data);
     }
 }
diff --git a/base/common/src/com/netscape/certsrv/system/SystemConfigResource.java b/base/common/src/com/netscape/certsrv/system/SystemConfigResource.java
index 0cebb60..9c570eb 100644
--- a/base/common/src/com/netscape/certsrv/system/SystemConfigResource.java
+++ b/base/common/src/com/netscape/certsrv/system/SystemConfigResource.java
@@ -29,5 +29,5 @@ public interface SystemConfigResource {
 
     @POST
     @Path("configure")
-    public ConfigurationResponse configure(ConfigurationRequest data);
+    public ConfigurationResponse configure(ConfigurationRequest data) throws Exception;
 }
diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
index 2de087b..75e3065 100644
--- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
@@ -111,28 +111,38 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
      * @see com.netscape.cms.servlet.csadmin.SystemConfigurationResource#configure(com.netscape.cms.servlet.csadmin.data.ConfigurationData)
      */
     @Override
-    public ConfigurationResponse configure(ConfigurationRequest request) {
+    public ConfigurationResponse configure(ConfigurationRequest request) throws Exception {
+
+        CMS.debug("SystemConfigService: configure()");
+
         try {
             ConfigurationResponse response = new ConfigurationResponse();
             configure(request, response);
             return response;
 
-        } catch (Throwable t) {
-            CMS.debug(t);
-            throw t;
+        } catch (PKIException e) { // normal responses
+            CMS.debug(e.getMessage()); // log the response
+            throw e;
+
+        } catch (Exception e) { // unexpected exceptions
+            CMS.debug(e); // show stack trace for troubleshooting
+            throw e;
+
+        } catch (Error e) { // system errors
+            CMS.debug(e); // show stack trace for troubleshooting
+            throw e;
         }
     }
 
-    public void configure(ConfigurationRequest data, ConfigurationResponse response) {
+    public void configure(ConfigurationRequest data, ConfigurationResponse response) throws Exception {
+
 
         if (csState.equals("1")) {
             throw new BadRequestException("System is already configured");
         }
 
-        CMS.debug("SystemConfigService(): configure() called");
-        CMS.debug(data.toString());
-
-        validateData(data);
+        CMS.debug("SystemConfigService: request: " + data);
+        validateRequest(data);
 
         Collection<String> certList = getCertList(data);
 
@@ -1020,22 +1030,15 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         }
     }
 
-    private void validateData(ConfigurationRequest data) {
-        // get required info from CS.cfg
-        String preopPin;
-        try {
-            preopPin = cs.getString("preop.pin");
-        } catch (Exception e) {
-            CMS.debug("validateData: Failed to get required config form CS.cfg");
-            e.printStackTrace();
-            throw new PKIException("Unable to retrieve required configuration from configuration files");
-        }
+    private void validateRequest(ConfigurationRequest data) throws Exception {
 
-        // get the preop pin and validate it
+        // validate installation pin
         String pin = data.getPin();
         if (pin == null) {
             throw new BadRequestException("No preop pin provided");
         }
+
+        String preopPin = cs.getString("preop.pin");
         if (!preopPin.equals(pin)) {
             throw new BadRequestException("Incorrect pin provided");
         }
@@ -1067,6 +1070,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
             if (data.getSecurityDomainName() == null) {
                 throw new BadRequestException("Security Domain Name is not provided");
             }
+
         } else if (domainType.equals(ConfigurationRequest.EXISTING_DOMAIN) ||
                    domainType.equals(ConfigurationRequest.NEW_SUBDOMAIN)) {
             if (data.getStandAlone()) {
@@ -1079,11 +1083,11 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
             }
 
             try {
-                @SuppressWarnings("unused")
-                URL admin_u = new URL(domainURI);  // check for invalid URL
+                new URL(domainURI);
             } catch (MalformedURLException e) {
-                throw new BadRequestException("Invalid security domain URI");
+                throw new BadRequestException("Invalid security domain URI: " + domainURI, e);
             }
+
             if ((data.getSecurityDomainUser() == null) || (data.getSecurityDomainPassword() == null)) {
                 throw new BadRequestException("Security domain user or password not provided");
             }
@@ -1109,11 +1113,13 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
                 throw new BadRequestException("Clone selected, but no clone URI provided");
             }
             try {
-                @SuppressWarnings("unused")
-                URL url = new URL(cloneUri); // check for invalid URL
+                URL url = new URL(cloneUri);
                 // confirm protocol is https
+                if (!"https".equals(url.getProtocol())) {
+                    throw new BadRequestException("Clone URI must use HTTPS protocol: " + cloneUri);
+                }
             } catch (MalformedURLException e) {
-                throw new BadRequestException("Invalid clone URI");
+                throw new BadRequestException("Invalid clone URI: " + cloneUri, e);
             }
 
             if (data.getToken().equals(ConfigurationRequest.TOKEN_DEFAULT)) {
@@ -1133,6 +1139,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
                     throw new BadRequestException("P12 password should not be provided since HSM clones must share their HSM master's private keys");
                 }
             }
+
         } else {
             data.setClone("false");
         }
@@ -1145,7 +1152,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         try {
             Integer.parseInt(data.getDsPort());  // check for errors
         } catch (NumberFormatException e) {
-            throw new BadRequestException("Internal database port is invalid");
+            throw new BadRequestException("Internal database port is invalid: " + data.getDsPort(), e);
         }
 
         String basedn = data.getBaseDN();
@@ -1173,7 +1180,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
             try {
                 Integer.parseInt(masterReplicationPort); // check for errors
             } catch (NumberFormatException e) {
-                throw new BadRequestException("Master replication port is invalid");
+                throw new BadRequestException("Master replication port is invalid: " + masterReplicationPort, e);
             }
         }
 
@@ -1181,8 +1188,8 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         if (cloneReplicationPort != null && cloneReplicationPort.length() > 0) {
             try {
                 Integer.parseInt(cloneReplicationPort); // check for errors
-            } catch (Exception e) {
-                throw new BadRequestException("Clone replication port is invalid");
+            } catch (NumberFormatException e) {
+                throw new BadRequestException("Clone replication port is invalid: " + cloneReplicationPort, e);
             }
         }
 
@@ -1293,7 +1300,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
             try {
                 Integer.parseInt(data.getAuthdbPort()); // check for errors
             } catch (NumberFormatException e) {
-                throw new BadRequestException("Authdb port is invalid");
+                throw new BadRequestException("Authentication Database port is invalid: " + data.getAuthdbPort(), e);
             }
 
             // TODO check connection with authdb
-- 
1.8.3.1


From 3937d69c1dd5f9ecd7940809b474097d63cb97b3 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Mon, 29 Jun 2015 13:29:41 -0400
Subject: [PATCH 07/21] Cleaned up SystemConfigService.configureClone().

The getCloningData() in SystemConfigService has been renamed to
configureClone(). Redundant try-catch blocks have been removed.
Some exception messages have been modified to include more info.
---
 .../dogtagpki/server/rest/SystemConfigService.java | 72 +++++++---------------
 .../server/tps/rest/TPSInstallerService.java       |  2 +-
 2 files changed, 23 insertions(+), 51 deletions(-)

diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
index 75e3065..73d24a7 100644
--- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
@@ -799,7 +799,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         }
     }
 
-    private void getCloningData(ConfigurationRequest data, Collection<String> certList, String token, String domainXML) {
+    private void configureClone(ConfigurationRequest data, Collection<String> certList, String token, String domainXML) throws Exception {
         for (String tag : certList) {
             if (tag.equals("sslserver")) {
                 cs.putBoolean("preop.cert." + tag + ".enable", true);
@@ -809,73 +809,45 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         }
 
         String cloneUri = data.getCloneUri();
-        URL url = null;
-        try {
-            url = new URL(cloneUri);
-        } catch (MalformedURLException e) {
-            // should not reach here as this check is done in validate()
-        }
+        URL url = new URL(cloneUri);
         String masterHost = url.getHost();
         int masterPort = url.getPort();
 
-        // check and store cloneURI information
-        boolean validCloneUri;
-        try {
-            validCloneUri = ConfigurationUtils.isValidCloneURI(domainXML, masterHost, masterPort);
-        } catch (Exception e) {
-            CMS.debug(e);
-            throw new PKIException("Error in determining whether clone URI is valid");
-        }
+        CMS.debug("SystemConfigService: validate clone URI: " + url);
+        boolean validCloneUri = ConfigurationUtils.isValidCloneURI(domainXML, masterHost, masterPort);
 
         if (!validCloneUri) {
             throw new BadRequestException(
-                    "Invalid clone URI provided.  Does not match the available subsystems in the security domain");
+                    "Clone URI does not match available subsystems: " + url);
         }
 
         if (csType.equals("CA")) {
-            try {
-                int masterAdminPort = ConfigurationUtils.getPortFromSecurityDomain(domainXML,
-                        masterHost, masterPort, "CA", "SecurePort", "SecureAdminPort");
-                ConfigurationUtils.importCertChain(masterHost, masterAdminPort, "/ca/admin/ca/getCertChain",
-                        "clone");
-            } catch (Exception e) {
-                CMS.debug(e);
-                throw new PKIException("Failed to import certificate chain from master" + e);
-            }
+            CMS.debug("SystemConfigService: import certificate chain from master");
+            int masterAdminPort = ConfigurationUtils.getPortFromSecurityDomain(domainXML,
+                    masterHost, masterPort, "CA", "SecurePort", "SecureAdminPort");
+            ConfigurationUtils.importCertChain(masterHost, masterAdminPort,
+                    "/ca/admin/ca/getCertChain", "clone");
         }
 
-        try {
-            CMS.debug("SystemConfigService.getCloningData(): get config entries");
-            ConfigurationUtils.getConfigEntriesFromMaster();
-        } catch (Exception e) {
-            CMS.debug(e);
-            throw new PKIException("Failed to obtain configuration entries from the master for cloning " + e);
-        }
+        CMS.debug("SystemConfigService: get configuration entries from master");
+        ConfigurationUtils.getConfigEntriesFromMaster();
 
         if (token.equals(ConfigurationRequest.TOKEN_DEFAULT)) {
-            CMS.debug("SystemConfigService.getCloningData(): restore certs from P12 file");
+            CMS.debug("SystemConfigService: restore certificates from P12 file");
             String p12File = data.getP12File();
             String p12Pass = data.getP12Password();
-            try {
-                ConfigurationUtils.restoreCertsFromP12(p12File, p12Pass);
-            } catch (Exception e) {
-                CMS.debug(e);
-                throw new PKIException("Failed to restore certificates from p12 file" + e);
-            }
+            ConfigurationUtils.restoreCertsFromP12(p12File, p12Pass);
+
         } else {
-            CMS.debug("SystemConfigService.getCloningData(): set permissions for certs stored in hardware");
-            try {
-                ConfigurationUtils.importAndSetCertPermissionsFromHSM();
-            } catch (Exception e) {
-                CMS.debug(e);
-                throw new PKIException("Failed to import certs from HSM and set permissions:" + e);
-            }
+            CMS.debug("SystemConfigService: import certificates from HSM and set permission");
+            ConfigurationUtils.importAndSetCertPermissionsFromHSM();
         }
 
-        CMS.debug("SystemConfigService.getCloningData(): verify certs");
+        CMS.debug("SystemConfigService: verify certificates");
         boolean cloneReady = ConfigurationUtils.isCertdbCloned();
+
         if (!cloneReady) {
-            CMS.debug("clone does not have all the certificates.");
+            CMS.debug("SystemConfigService: clone does not have all the certificates.");
             throw new PKIException("Clone does not have all the required certificates");
         }
     }
@@ -992,7 +964,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
     }
 
     public void configureSubsystem(ConfigurationRequest request,
-            Collection<String> certList, String token, String domainXML) {
+            Collection<String> certList, String token, String domainXML) throws Exception {
 
         cs.putString("preop.subsystem.name", request.getSubsystemName());
 
@@ -1004,7 +976,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         } else {
             cs.putString("preop.subsystem.select", "clone");
             cs.putString("subsystem.select", "Clone");
-            getCloningData(request, certList, token, domainXML);
+            configureClone(request, certList, token, domainXML);
         }
     }
 
diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java b/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java
index 9c4943b..fe4e124 100644
--- a/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java
+++ b/base/tps/src/org/dogtagpki/server/tps/rest/TPSInstallerService.java
@@ -44,7 +44,7 @@ public class TPSInstallerService extends SystemConfigService  {
 
     @Override
     public void configureSubsystem(ConfigurationRequest request,
-            Collection<String> certList, String token, String domainXML) {
+            Collection<String> certList, String token, String domainXML) throws Exception {
 
         super.configureSubsystem(request, certList, token, domainXML);
 
-- 
1.8.3.1


From 7c1af7f7dac89363c7923802ec759ccb84813bfb Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Mon, 29 Jun 2015 15:34:01 -0700
Subject: [PATCH 08/21] Ticket 1438 pkispawn: SSL_ForceHandshake issue for
 non-CA on HSM on both shared and nonshared tomcat instances

---
 .../python/pki/server/deployment/pkiparser.py      | 107 ++++++++++++++-------
 1 file changed, 72 insertions(+), 35 deletions(-)

diff --git a/base/server/python/pki/server/deployment/pkiparser.py b/base/server/python/pki/server/deployment/pkiparser.py
index 7e1813c..4b3dabb 100644
--- a/base/server/python/pki/server/deployment/pkiparser.py
+++ b/base/server/python/pki/server/deployment/pkiparser.py
@@ -921,41 +921,78 @@ class PKIConfigParser:
                 "tls1_0:tls1_2"
             self.mdict['TOMCAT_SSL_VERSION_RANGE_DATAGRAM_SLOT'] = \
                 "tls1_1:tls1_2"
-            self.mdict['TOMCAT_SSL_RANGE_CIPHERS_SLOT'] = \
-                "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \
-                "-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
-                "+TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA," + \
-                "+TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + \
-                "+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA," + \
-                "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \
-                "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \
-                "+TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \
-                "+TLS_RSA_WITH_AES_128_CBC_SHA," + \
-                "+TLS_RSA_WITH_AES_256_CBC_SHA," + \
-                "+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
-                "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \
-                "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
-                "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \
-                "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \
-                "+TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA," + \
-                "+TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + \
-                "+TLS_DHE_DSS_WITH_AES_256_CBC_SHA," + \
-                "+TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
-                "+TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + \
-                "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA," + \
-                "+TLS_DHE_RSA_WITH_AES_128_CBC_SHA256," + \
-                "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + \
-                "+TLS_RSA_WITH_AES_128_CBC_SHA256," + \
-                "+TLS_RSA_WITH_AES_256_CBC_SHA256," + \
-                "+TLS_RSA_WITH_AES_128_GCM_SHA256," + \
-                "+TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \
-                "+TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + \
-                "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + \
-                "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \
-                "+TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + \
-                "+TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256," + \
-                "+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \
-                "+TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"
+            if self.mdict['pki_ssl_server_key_type'] == "ecc":
+                self.mdict['TOMCAT_SSL_RANGE_CIPHERS_SLOT'] = \
+                    "+TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \
+                    "+TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "+TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "+TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + \
+                    "+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA," + \
+                    "+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \
+                    "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_RSA_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_RSA_WITH_AES_256_CBC_SHA," + \
+                    "+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \
+                    "+TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \
+                    "+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_DHE_DSS_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_DHE_RSA_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256," + \
+                    "-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + \
+                    "-TLS_RSA_WITH_AES_128_CBC_SHA256," + \
+                    "-TLS_RSA_WITH_AES_256_CBC_SHA256," + \
+                    "-TLS_RSA_WITH_AES_128_GCM_SHA256," + \
+                    "-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \
+                    "-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + \
+                    "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + \
+                    "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \
+                    "+TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + \
+                    "+TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256," + \
+                    "+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \
+                    "+TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"
+            else:
+                self.mdict['TOMCAT_SSL_RANGE_CIPHERS_SLOT'] = \
+                    "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \
+                    "+TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "+TLS_RSA_WITH_AES_128_CBC_SHA," + \
+                    "+TLS_RSA_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \
+                    "-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA," + \
+                    "-TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + \
+                    "-TLS_DHE_DSS_WITH_AES_256_CBC_SHA," + \
+                    "+TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," + \
+                    "+TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + \
+                    "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA," + \
+                    "+TLS_DHE_RSA_WITH_AES_128_CBC_SHA256," + \
+                    "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + \
+                    "+TLS_RSA_WITH_AES_128_CBC_SHA256," + \
+                    "+TLS_RSA_WITH_AES_256_CBC_SHA256," + \
+                    "+TLS_RSA_WITH_AES_128_GCM_SHA256," + \
+                    "+TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \
+                    "-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + \
+                    "-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + \
+                    "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \
+                    "-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + \
+                    "-TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256," + \
+                    "-TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \
+                    "-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"
             self.mdict['TOMCAT_SSL2_CIPHERS_SLOT'] = \
                 "-SSL2_RC4_128_WITH_MD5," + \
                 "-SSL2_RC4_128_EXPORT40_WITH_MD5," + \
-- 
1.8.3.1


From b253cad196f57e79a5aede53aceffede1c9edfbe Mon Sep 17 00:00:00 2001
From: Jack Magne <jmagne@localhost.localdomain>
Date: Wed, 1 Jul 2015 15:01:45 -0700
Subject: [PATCH 09/21] Ability to toggle profile usablity in Web vs CLI tools.

Ticket #1442.

This fix gives the command line enrollment commands the ability to enroll a cert against a profile
that has been marked as not visible but "enabled".

With the simple fix the following scenarios tested to work:

The "caUserCert" Profile was marked as not visible, but enabled.

1. pki -c Secret123 client-cert-request --profile caUserCert uid=jmagne
    This is the simplest form of user cert enrollment.

2. pki ca-cert-request-profile-show caUserCert --output testuser.xml
   pki ca-cert-request-submit testuser.xml

    The first command gives us the profile's xml file, which after modification is used to enroll.

3. pki -d ~/.dogtag/pki -c "" -n "PKI Administrator for localdomain" ca-profile-show caUserCert

    This one shows that we can view the contents of a non visible profile. Listing is not allowed.
    We felt this appropiate to allow a command line user to get the details of a non visible profile that
    they know aobut and want to use.
---
 base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
index 969cfd1..a11cb47 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
@@ -336,9 +336,8 @@ public class CertRequestService extends PKIService implements CertRequestResourc
         }
 
         if (! profile.isVisible()) {
-            CMS.debug("getEnrollmentTemplate(): attempt to get enrollment template for non-visible profile");
-            throw new BadRequestException("Cannot provide enrollment template for profile `" + profileId +
-                        "`.  Profile not marked as visible");
+            CMS.debug("getEnrollmentTemplate(): attempt to get enrollment template for non-visible profile. This is ok since command line enrollments should be able to use enabled but non visible profiles.");
+
         }
 
         CertEnrollmentRequest request = new CertEnrollmentRequest();
-- 
1.8.3.1


From 4af223feb262a707b65d4860f6e8552873306209 Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@pki.usersys.redhat.com>
Date: Thu, 2 Jul 2015 11:09:14 -0600
Subject: [PATCH 12/21] Limited Interactive Installation Support

- PKI TRAC Ticket #1441 - Lack of Interactive Installation Support
  (Cloning, Subordinates, Externals, HSMs, ECC)
---
 .../python/pki/server/deployment/pkimessages.py    | 19 ++++++
 base/server/sbin/pkispawn                          | 70 ++++++++++++----------
 2 files changed, 56 insertions(+), 33 deletions(-)

diff --git a/base/server/python/pki/server/deployment/pkimessages.py b/base/server/python/pki/server/deployment/pkimessages.py
index 6528407..ff3d370 100644
--- a/base/server/python/pki/server/deployment/pkimessages.py
+++ b/base/server/python/pki/server/deployment/pkimessages.py
@@ -146,6 +146,25 @@ REMINDER:
     Finally, if an optional '-p <prefix>' is defined, this value WILL NOT
     be prepended in front of the mandatory '-f <configuration_file>'.
 """ + PKI_VERBOSITY
+PKISPAWN_INTERACTIVE_INSTALLATION='''
+IMPORTANT:
+
+    Interactive installation currently only exists for very basic deployments!
+
+    For example, deployments intent upon using advanced features such as:
+
+        * Cloning,
+        * Elliptic Curve Cryptography (ECC),
+        * External CA,
+        * Hardware Security Module (HSM),
+        * Subordinate CA,
+        * etc.,
+
+    must provide the necessary override parameters in a separate
+    configuration file.
+
+    Run 'man pkispawn' for details.
+'''
 
 
 # PKI Deployment "Helper" Messages
diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn
index 893a22a..bebbf0b 100755
--- a/base/server/sbin/pkispawn
+++ b/base/server/sbin/pkispawn
@@ -125,8 +125,12 @@ def main(argv):
     parser.validate()
     interactive = False
 
-    while True:
+    if config.user_deployment_cfg is None:
+        interactive = True
+        parser.indent = 0
+        print log.PKISPAWN_INTERACTIVE_INSTALLATION
 
+    while True:
         # -s <subsystem>
         if args.pki_subsystem is None:
             interactive = True
@@ -215,38 +219,38 @@ def main(argv):
                              config.pki_subsystem,
                              'pki_client_admin_cert')
 
-            if parser.mdict['pki_hsm_enable'] == 'True':
-                use_hsm = 'Y'
-            else:
-                use_hsm = 'N'
-
-            use_hsm = parser.read_text(
-                'Using hardware security module (HSM) (Yes/No)',
-                default=use_hsm, options=['Yes', 'Y', 'No', 'N'],
-                sign='?', case_sensitive=False).lower()
-
-            if use_hsm == 'y' or use_hsm == 'yes':
-                # XXX:  Suppress interactive HSM installation
-                print "Interactive HSM installation is currently unsupported."
-                sys.exit(0)
-
-                # TBD:  Interactive HSM installation
-                # parser.set_property(config.pki_subsystem,
-                #                     'pki_hsm_enable',
-                #                     'True')
-                # modulename = parser.read_text(
-                #     'HSM Module Name (e. g. - nethsm)', allow_empty=False)
-                # parser.set_property(config.pki_subsystem,
-                #                     'pki_hsm_modulename',
-                #                     modulename)
-                # libfile = parser.read_text(
-                #     'HSM Lib File ' +
-                #     '(e. g. - /opt/nfast/toolkits/pkcs11/libcknfast.so)',
-                #     allow_empty=False)
-                # parser.set_property(config.pki_subsystem,
-                #                     'pki_hsm_libfile',
-                #                     libfile)
-            print
+            # if parser.mdict['pki_hsm_enable'] == 'True':
+            #     use_hsm = 'Y'
+            # else:
+            #     use_hsm = 'N'
+
+            # use_hsm = parser.read_text(
+            #     'Using hardware security module (HSM) (Yes/No)',
+            #     default=use_hsm, options=['Yes', 'Y', 'No', 'N'],
+            #     sign='?', case_sensitive=False).lower()
+
+            # if use_hsm == 'y' or use_hsm == 'yes':
+            #     # XXX:  Suppress interactive HSM installation
+            #     print "Interactive HSM installation is currently unsupported."
+            #     sys.exit(0)
+
+                  # TBD:  Interactive HSM installation
+                  # parser.set_property(config.pki_subsystem,
+                  #                     'pki_hsm_enable',
+                  #                     'True')
+                  # modulename = parser.read_text(
+                  #     'HSM Module Name (e. g. - nethsm)', allow_empty=False)
+                  # parser.set_property(config.pki_subsystem,
+                  #                     'pki_hsm_modulename',
+                  #                     modulename)
+                  # libfile = parser.read_text(
+                  #     'HSM Lib File ' +
+                  #     '(e. g. - /opt/nfast/toolkits/pkcs11/libcknfast.so)',
+                  #     allow_empty=False)
+                  # parser.set_property(config.pki_subsystem,
+                  #                     'pki_hsm_libfile',
+                  #                     libfile)
+            # print
 
             print "Directory Server:"
             while True:
-- 
1.8.3.1


From bbd2feaa1f0ca4c338ca490f191184f2bd5c1a41 Mon Sep 17 00:00:00 2001
From: Jack Magne <jmagne@localhost.localdomain>
Date: Tue, 30 Jun 2015 17:22:23 -0700
Subject: [PATCH 13/21] Unable to select ECC Curves from EE fix.

Ticket #1446:

Without the crypto object, the user is now presented with a very bared bones
keygen tag powered UI. ONe can only select a key strength and only use RSA.

This fix adds simple UI to make better use of the keygen tag:

1. Allows the use of ECC.
2. Gives simple info on how the key strengths map to RSA key size and
ECC curves.

When the user selects High, they get RSA 2043, and ECC nistp384.
When the user selects Medium, they get RSA 1024, and ECC nistp256.
---
 .../shared/webapps/ca/ee/ca/ProfileSelect.template | 81 +++++++++++++++++++++-
 1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
index 0e68e36..5075962 100644
--- a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
+++ b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
@@ -47,6 +47,71 @@ var key = new Object();
 key.type = "EC";
 keyList[1] = key;
 
+function getKeyStrengthTableForKeyGen() {
+
+  document.writeln("<table border='1'> <caption> KeyGen Key Strength Info </caption> <tr> <th> Key Type </th> <th> High Grade </th> <th> Medium Grade </th> </tr>");
+  document.writeln("<td> RSA </td> <td> 2048 </td> <td> 1024 </tr> </td>");
+  document.writeln("<td> ECC </td> <td> nistp384 </td> <td> nistp256 </td>");
+  document.writeln("</table>");
+
+}
+
+function getKeyTypesOptionsForKeyGen() {
+    var keyTypesDef = "RSA";
+    var keyTypes = null;
+    for (var i = 0; i < policySetListSet.length; i++) {
+      for (var j = 0; j < policySetListSet[i].policySet.length; j++) {
+        if (typeof(policySetListSet[i].policySet[j].constraintSet) != "undefined") {
+          for (var k = 0; k < policySetListSet[i].policySet[j].constraintSet.length; k++) {
+            if (policySetListSet[i].policySet[j].constraintSet[k].name == "keyType") {
+              if (policySetListSet[i].policySet[j].constraintSet[k].value == "-") {
+                  keyTypes = "RSA,EC";
+              } else {
+                 keyTypes = policySetListSet[i].policySet[j].constraintSet[k].value;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    if(keyTypes == null) {
+      keyTypes = keyTypesDef;
+    }
+
+    var keyTypesRet = keyTypes.split(",");
+    var options = "";
+    var optionLabel = "";
+    var selected = "";
+    for(types= 0 ; types < keyTypesRet.length ; types ++) {
+      if(keyTypesRet[types] == "EC") {
+        optionLabel = "ECC"; 
+      } else {
+        optionLabel = keyTypesRet[types];
+      }
+
+      if( types == 0 ) {
+          selected = "SELECTED";
+      } else {
+          selected = "";
+      }
+ 
+      options += '<OPTION value=' + '\"' + keyTypesRet[types] + '\" ' + selected + ' > ' + optionLabel + ' </OPTION> ';
+    }
+
+    return options;
+}
+
+function keyGenKeyTypeSelected(keygenObj,keyTypeSelectObj) {
+
+    if(keygenObj == null || keyTypeSelectObj == null)
+        return;
+
+    var selectedValue = keyTypeSelectObj.options[keyTypeSelectObj.selectedIndex].value;
+
+     keygenObj.setAttribute("keytype", selectedValue);
+}
+
 function keyTypeOptions (keyPurpose)
 {
   var keyType = "RSA";
@@ -682,7 +747,21 @@ for (var m = 0; m < inputPluginListSet.length; m++) {
         }
         document.writeln('<input type=hidden name=cert_request value="">');
       } else {
-        document.writeln('<KEYGEN name=' + inputListSet[n].inputId + '>');
+
+        getKeyStrengthTableForKeyGen();
+
+        var keyTypesOptions = getKeyTypesOptionsForKeyGen();
+
+        var keygendata = '<KEYGEN id=\"keygentag\" ' + ' name= ' + '\"' + inputListSet[n].inputId + '\" ' + ' KEYTYPE=\"EC\" KEYPARAMS=\"none\"   > '  ;
+        document.writeln(keygendata);
+
+        var keygenObj = document.getElementById("keygentag");
+        var selectKeyTypeData = '<SELECT id=\"keyTypeSelectedId\" name=\"selectKeyType\"  onChange=\"keyGenKeyTypeSelected(keygenObj,this);\"   > '   + keyTypesOptions + '</SELECT> ' ;
+
+        document.writeln(selectKeyTypeData);
+
+        var selectKeyTypeObject = document.getElementById("keyTypeSelectedId");
+        keyGenKeyTypeSelected(keygenObj,selectKeyTypeObject);
       }
     } else if (inputListSet[n].inputSyntax == 'dual_keygen_request_type') {
       keygen_request = 'true';
-- 
1.8.3.1


From 067cbce6c015a50f4a1747f8894b13c9052c2ed9 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 30 Jun 2015 22:49:11 -0400
Subject: [PATCH 14/21] Fixed pki help CLI.

A new findModules() method has been added to the CLI class to find
the list of modules handling a command. The list will be used by the
pki help CLI to find the proper man page for the specified command.
---
 .../src/com/netscape/cmstools/cert/CertCLI.java    |  5 ++
 .../src/com/netscape/cmstools/cli/CLI.java         | 72 ++++++++++++++++++++++
 .../src/com/netscape/cmstools/cli/HelpCLI.java     | 27 ++++++--
 .../src/com/netscape/cmstools/cli/MainCLI.java     |  5 ++
 .../com/netscape/cmstools/client/ClientCLI.java    |  5 ++
 .../src/com/netscape/cmstools/group/GroupCLI.java  |  5 ++
 .../netscape/cmstools/group/GroupMemberCLI.java    |  5 ++
 .../src/com/netscape/cmstools/key/KeyCLI.java      |  5 ++
 .../com/netscape/cmstools/logging/AuditCLI.java    |  5 ++
 .../com/netscape/cmstools/profile/ProfileCLI.java  |  5 ++
 .../cmstools/system/SecurityDomainCLI.java         |  5 ++
 .../src/com/netscape/cmstools/user/UserCLI.java    |  5 ++
 .../com/netscape/cmstools/user/UserCertCLI.java    |  5 ++
 13 files changed, 148 insertions(+), 6 deletions(-)

diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
index 9ffa3ad..e0924d3 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
@@ -67,6 +67,11 @@ public class CertCLI extends CLI {
         }
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-cert";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/CLI.java b/base/java-tools/src/com/netscape/cmstools/cli/CLI.java
index ed01edc..1338749 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/CLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/CLI.java
@@ -21,6 +21,7 @@ package com.netscape.cmstools.cli;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.cli.CommandLineParser;
@@ -113,6 +114,75 @@ public class CLI {
         return modules.remove(name);
     }
 
+    /**
+     * Find the list of modules that handle the specified command.
+     */
+    public List<CLI> findModules(String command) throws Exception {
+
+        List<CLI> results = new ArrayList<CLI>();
+
+        // split command into list of names:
+        // <names[0]>-<names[1]>-<names[2]>-...-<names[n-1]>
+        String[] names = command.split("-");
+
+        CLI current = this;
+        int i = 0;
+
+        // translate all names into modules starting from the beginning
+        while (i < names.length) {
+
+            String moduleName = null;
+            CLI module = null;
+            int j = i;
+
+            // find module that matches the shortest sequence of names
+            while (j < names.length) {
+
+                // construct module name
+                if (moduleName == null) {
+                    moduleName = names[j];
+                } else {
+                    moduleName = moduleName + "-" + names[j];
+                }
+
+                // find module with name <names[i]>-...-<names[j]>
+                module = current.getModule(moduleName);
+
+                if (module != null) {
+                    // module found, stop
+                    break;
+                }
+
+                // try again with longer sequence
+                j++;
+            }
+
+            if (module == null)
+                throw new Error("Invalid module \"" + moduleName + "\".");
+
+            // module found
+            results.add(module);
+
+            // repeat for the remaining parts
+            current = module;
+            i = j + 1;
+        }
+
+        return results;
+    }
+
+    /**
+     * Find the last module that handles the specified command.
+     */
+    public CLI findModule(String command) throws Exception {
+        List<CLI> modules = findModules(command);
+        return modules.get(modules.size() - 1);
+    }
+
+    public String getManPage() {
+        return null;
+    }
+
     public PKIClient getClient() {
         return client;
     }
@@ -182,6 +252,8 @@ public class CLI {
             System.exit(0);
         }
 
+        // TODO: Rewrite using findModules().
+
         // A command consists of parts joined by dashes: <part 1>-<part 2>-...-<part N>.
         // For example: cert-request-find
         String command = args[0];
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/HelpCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/HelpCLI.java
index 6b2a123..b348ffc 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/HelpCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/HelpCLI.java
@@ -18,6 +18,8 @@
 
 package com.netscape.cmstools.cli;
 
+import java.util.List;
+
 import org.apache.commons.cli.CommandLine;
 
 /**
@@ -51,19 +53,32 @@ public class HelpCLI extends CLI {
 
         String[] cmdArgs = cmd.getArgs();
 
-        String command;
+        String manPage = null;
         if (cmdArgs.length == 0) {
-            command = "pki";
+            // no command specified, show the pki man page
+            manPage = parent.getManPage();
 
         } else {
-            command = "pki-" + cmdArgs[0];
+            // find all modules handling the specified command
+            List<CLI> modules = parent.findModules(cmdArgs[0]);
+
+            // find the module that has a man page starting from the last one
+            for (int i = modules.size() - 1; i >= 0; i--) {
+                CLI module = modules.get(i);
+                manPage = module.getManPage();
+                if (manPage != null) break;
+            }
+
+            // if no module has a man page, show the pki man page
+            if (manPage == null)
+                manPage = parent.getManPage();
         }
 
         while (true) {
             // display man page for the command
             ProcessBuilder pb = new ProcessBuilder(
                     "/bin/man",
-                    command);
+                    manPage);
 
             pb.inheritIO();
             Process p = pb.start();
@@ -71,10 +86,10 @@ public class HelpCLI extends CLI {
 
             if (rc == 16) {
                 // man page not found, find the parent command
-                int i = command.lastIndexOf('-');
+                int i = manPage.lastIndexOf('-');
                 if (i >= 0) {
                     // parent command exists, try again
-                    command = command.substring(0, i);
+                    manPage = manPage.substring(0, i);
                     continue;
 
                 } else {
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index 1792922..77245ec 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -89,6 +89,11 @@ public class MainCLI extends CLI {
         return moduleName;
     }
 
+    @Override
+    public String getManPage() {
+        return "pki";
+    }
+
     public void printVersion() {
         Package pkg = MainCLI.class.getPackage();
         System.out.println("PKI Command-Line Interface "+pkg.getImplementationVersion());
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
index c9c7152..f09ea74 100644
--- a/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
@@ -50,6 +50,11 @@ public class ClientCLI extends CLI {
         }
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-client";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java b/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java
index 973e0ba..ca15130 100644
--- a/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/group/GroupCLI.java
@@ -54,6 +54,11 @@ public class GroupCLI extends CLI {
         }
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-group";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/group/GroupMemberCLI.java b/base/java-tools/src/com/netscape/cmstools/group/GroupMemberCLI.java
index e21d817..1df404b 100644
--- a/base/java-tools/src/com/netscape/cmstools/group/GroupMemberCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/group/GroupMemberCLI.java
@@ -40,6 +40,11 @@ public class GroupMemberCLI extends CLI {
         addModule(new GroupMemberRemoveCLI(this));
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-group-member";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
index fb324be..d83bcf2 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
@@ -65,6 +65,11 @@ public class KeyCLI extends CLI {
         }
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-key";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/logging/AuditCLI.java b/base/java-tools/src/com/netscape/cmstools/logging/AuditCLI.java
index 11e5300..531d920 100644
--- a/base/java-tools/src/com/netscape/cmstools/logging/AuditCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/logging/AuditCLI.java
@@ -41,6 +41,11 @@ public class AuditCLI extends CLI {
         addModule(new AuditShowCLI(this));
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-audit";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java b/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
index e9e2159..ecfa753 100644
--- a/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/profile/ProfileCLI.java
@@ -51,6 +51,11 @@ public class ProfileCLI extends CLI {
         }
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-ca-profile";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/system/SecurityDomainCLI.java b/base/java-tools/src/com/netscape/cmstools/system/SecurityDomainCLI.java
index b1a3597..0c2ed37 100644
--- a/base/java-tools/src/com/netscape/cmstools/system/SecurityDomainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/system/SecurityDomainCLI.java
@@ -47,6 +47,11 @@ public class SecurityDomainCLI extends CLI {
         }
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-securitydomain";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java
index 7a03d33..5382c47 100644
--- a/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/user/UserCLI.java
@@ -57,6 +57,11 @@ public class UserCLI extends CLI {
         }
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-user";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
diff --git a/base/java-tools/src/com/netscape/cmstools/user/UserCertCLI.java b/base/java-tools/src/com/netscape/cmstools/user/UserCertCLI.java
index ead915a..d8ea917 100644
--- a/base/java-tools/src/com/netscape/cmstools/user/UserCertCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/user/UserCertCLI.java
@@ -40,6 +40,11 @@ public class UserCertCLI extends CLI {
         addModule(new UserCertRemoveCLI(this));
     }
 
+    @Override
+    public String getManPage() {
+        return "pki-user-cert";
+    }
+
     public void execute(String[] args) throws Exception {
 
         client = parent.getClient();
-- 
1.8.3.1


From 433e1dba905f9d45f9eefcbf39e5b11ddfbfbc94 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Thu, 2 Jul 2015 18:33:48 -0400
Subject: [PATCH 15/21] Fixed NPE in key-archive CLI.

The pki CLI has been modified such that if the security database
location (-d) is not specified, the config.certDatabase will be
initialized with the default value (i.e. ~/.dogtag/nssdb). The
config.certDatabase is needed by the CLI to prepare the client
library for key archival operations.
---
 .../src/com/netscape/cmstools/cli/MainCLI.java      | 21 ++++++++-------------
 .../src/com/netscape/cmstools/key/KeyCLI.java       | 10 ++++++++--
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index 77245ec..4d63d9b 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -330,9 +330,14 @@ public class MainCLI extends CLI {
             }
         }
 
-        // store security database path
-        if (certDatabase != null)
+        if (certDatabase != null) {
+            // store user-provided security database location
             config.setCertDatabase(new File(certDatabase).getAbsolutePath());
+        } else {
+            // store default security database location
+            config.setCertDatabase(System.getProperty("user.home") +
+                    File.separator + ".dogtag" + File.separator + "nssdb");
+        }
 
         // store token name
         config.setTokenName(tokenName);
@@ -395,17 +400,7 @@ public class MainCLI extends CLI {
         list = cmd.getOptionValue("ignore-cert-status");
         convertCertStatusList(list, ignoredCertStatuses);
 
-        if (config.getCertDatabase() == null) {
-            // Use default client security database
-            this.certDatabase = new File(
-                    System.getProperty("user.home") + File.separator +
-                    ".dogtag" + File.separator + "nssdb");
-
-        } else {
-            // Use existing client security database
-            this.certDatabase = new File(config.getCertDatabase());
-        }
-
+        this.certDatabase = new File(config.getCertDatabase());
         if (verbose) System.out.println("Client security database: "+this.certDatabase.getAbsolutePath());
 
         String messageFormat = cmd.getOptionValue("message-format");
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
index d83bcf2..f242ece 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
@@ -81,14 +81,20 @@ public class KeyCLI extends CLI {
 
         // create new key client
         keyClient = new KeyClient(client, subsystem);
-        if (client.getConfig().getCertDatabase() != null && client.getConfig().getCertPassword() != null) {
+
+        // if security database password is specified,
+        // prepare key client for archival/retrieval
+        if (client.getConfig().getCertPassword() != null) {
+            // create crypto provider for key client
             keyClient.setCrypto(new NSSCryptoProvider(client.getConfig()));
 
-            // Set the transport cert for crypto operations
+            // download transport cert
             systemCertClient = new SystemCertClient(client, subsystem);
             String transportCert = systemCertClient.getTransportCert().getEncoded();
             transportCert = transportCert.substring(CertData.HEADER.length(),
                     transportCert.indexOf(CertData.FOOTER));
+
+            // set transport cert for key client
             keyClient.setTransportCert(transportCert);
         }
 
-- 
1.8.3.1


From cc8f6468bb9f509d16ed526e42d546aaa2ae9ed3 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 1 Jul 2015 14:41:51 -0400
Subject: [PATCH 16/21] Fixed fail-over in HttpConnection.

The HttpConnection class has been modified to support fail-over
and timeout more consistently. The targets are parsed into a list
during initialization. All direct calls to HttpClient.connect()
are replaced with a method that will connect to the first available
target. All connections are now created with a timeout (which by
default is 0).

https://fedorahosted.org/pki/ticket/891
---
 base/ca/src/com/netscape/ca/CAService.java         |   5 +-
 .../netscape/cmscore/connector/HttpConnection.java | 214 +++++++++++----------
 .../src/com/netscape/cmsutil/http/HttpClient.java  |  40 ++--
 .../netscape/cmsutil/http/JssSSLSocketFactory.java |  27 ++-
 .../com/netscape/cmsutil/net/ISocketFactory.java   |  10 +-
 5 files changed, 154 insertions(+), 142 deletions(-)

diff --git a/base/ca/src/com/netscape/ca/CAService.java b/base/ca/src/com/netscape/ca/CAService.java
index 6edaf2a..36f0bd5 100644
--- a/base/ca/src/com/netscape/ca/CAService.java
+++ b/base/ca/src/com/netscape/ca/CAService.java
@@ -435,9 +435,8 @@ public class CAService implements ICAService, IService {
             // send request to KRA first
             if (type.equals(IRequest.ENROLLMENT_REQUEST) &&
                     isPKIArchiveOptionPresent(request) && mKRAConnector != null) {
-                if (Debug.ON) {
-                    Debug.trace("*** Sending enrollment request to KRA");
-                }
+
+                CMS.debug("CAService: Sending enrollment request to KRA");
                 boolean sendStatus = mKRAConnector.send(request);
 
                 if (mArchivalRequired == true) {
diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java
index c179f4b..c480478 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpConnection.java
@@ -18,7 +18,9 @@
 package com.netscape.cmscore.connector;
 
 import java.io.IOException;
-import java.util.StringTokenizer;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
 
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.base.EBaseException;
@@ -33,50 +35,32 @@ import com.netscape.cmsutil.http.HttpResponse;
 import com.netscape.cmsutil.net.ISocketFactory;
 
 public class HttpConnection implements IHttpConnection {
+
     protected IRemoteAuthority mDest = null;
     protected HttpRequest mHttpreq = new HttpRequest();
     protected IRequestEncoder mReqEncoder = null;
     protected HttpClient mHttpClient = null;
 
-    protected boolean Connect(String host, HttpClient client) {
-        StringTokenizer st = new StringTokenizer(host, " ");
-        while (st.hasMoreTokens()) {
-            String hp = st.nextToken(); // host:port
-            StringTokenizer st1 = new StringTokenizer(hp, ":");
-            try {
-                String h = st1.nextToken();
-                int p = Integer.parseInt(st1.nextToken());
-                client.connect(h, p);
-                return true;
-            } catch (Exception e) {
-                // may want to log the failure
-            }
-            try {
-                Thread.sleep(5000); // 5 seconds
-            } catch (Exception e) {
-            }
+    int timeout = 0;
+    List<InetSocketAddress> targets;
 
-        }
-        return false;
-    }
+    public HttpConnection(IRemoteAuthority dest, ISocketFactory factory,
+            int timeout // seconds
+            ) {
 
-    public void setRequestURI(String uri)
-            throws EBaseException {
-        mHttpreq.setURI(uri);
-    }
+        CMS.debug("HttpConnection: Creating HttpConnection with timeout=" + timeout);
 
-    public String getRequestURI() {
-        return mHttpreq.getURI();
-    }
-
-    public HttpConnection(IRemoteAuthority dest, ISocketFactory factory) {
         mDest = dest;
         mReqEncoder = new HttpRequestEncoder();
         mHttpClient = new HttpClient(factory);
-        if (Debug.ON)
-            Debug.trace("Created HttpClient");
+
+        this.timeout = timeout;
+
+        targets = parseTarget(dest.getHost(), dest.getPort());
+
         try {
             mHttpreq.setMethod("POST");
+
             // in case of multi-uri, uri will be set right before send
             //   by calling setRequestURI(uri)
             if (mDest.getURI() != null)
@@ -89,62 +73,85 @@ public class HttpConnection implements IHttpConnection {
             }
 
             mHttpreq.setHeader("Connection", "Keep-Alive");
-            CMS.debug("HttpConnection: connecting to " + dest.getHost() + ":" + dest.getPort());
-            String host = dest.getHost();
-            // we could have a list of host names in the host parameters
-            // the format is, for example,
-            // "directory.knowledge.com:1050 people.catalog.com 199.254.1.2"
-            if (host != null && host.indexOf(' ') != -1) {
-                // try to do client-side failover
-                boolean connected = false;
-                do {
-                    connected = Connect(host, mHttpClient);
-                } while (!connected);
-            } else {
-                mHttpClient.connect(host, dest.getPort());
-            }
-            CMS.debug("HttpConnection: connected to " + dest.getHost() + ":" + dest.getPort());
+
+            connect();
+
         } catch (IOException e) {
             // server's probably down. that's fine. try later.
-            //System.out.println(
-            //"Can't connect to server in connection creation");
+            CMS.debug("HttpConnection: Unable to create connection: " + e);
         }
     }
 
-    /*
-     * @param op operation to determine the receiving servlet (multi-uri support)
-     */
-    public HttpConnection(IRemoteAuthority dest, ISocketFactory factory, int timeout) {
-        mDest = dest;
-        mReqEncoder = new HttpRequestEncoder();
-        mHttpClient = new HttpClient(factory);
-        CMS.debug("HttpConn:Created HttpConnection: factory " + factory + "client " + mHttpClient);
-        try {
-            mHttpreq.setMethod("POST");
-            // in case of multi-uri, uri will be set right before send
-            //   by calling setRequestURI(op)
-            if (mDest.getURI() != null)
-                mHttpreq.setURI(mDest.getURI());
+    public HttpConnection(IRemoteAuthority dest, ISocketFactory factory) {
+        this(dest, factory, 0);
+    }
 
-            String contentType = dest.getContentType();
-            if (contentType != null) {
-                CMS.debug("HttpConnection: setting Content-Type");
-                mHttpreq.setHeader("Content-Type", contentType );
-            }
+    List<InetSocketAddress> parseTarget(String target, int port) {
 
-            mHttpreq.setHeader("Connection", "Keep-Alive");
-            CMS.debug("HttpConnection: connecting to " + dest.getHost() + ":" + dest.getPort() + " timeout:" + timeout);
-            mHttpClient.connect(dest.getHost(), dest.getPort(), timeout);
-            CMS.debug("HttpConnection: connected to " + dest.getHost() + ":" + dest.getPort() + " timeout:" + timeout);
-        } catch (IOException e) {
-            // server's probably down. that's fine. try later.
-            //System.out.println(
-            //"Can't connect to server in connection creation");
-            CMS.debug("CMSConn:IOException in creating HttpConnection " + e.toString());
+        List<InetSocketAddress> results = new ArrayList<InetSocketAddress>();
+
+        if (target == null || target.indexOf(' ') < 0) {
+            // target is a single hostname
+
+            // add hostname and the global port to the results
+            results.add(new InetSocketAddress(target, port));
+            return results;
+        }
+
+        // target is a list of hostname:port, for example:
+        // "server1.example.com:8443 server2.example.com:8443"
+
+        for (String hostnamePort : target.split(" ")) {
+
+            // parse hostname and port, and ignore the global port
+            String[] parts = hostnamePort.split(":");
+            String hostname = parts[0];
+            port = Integer.parseInt(parts[1]);
+
+            // add hostname and port to the results
+            results.add(new InetSocketAddress(hostname, port));
         }
+
+        return results;
     }
 
-    // Insert end
+    void connect() throws IOException {
+
+        IOException exception = null;
+
+        // try all targets
+        for (InetSocketAddress target : targets) {
+
+            String hostname = target.getHostString();
+            int port = target.getPort();
+
+            try {
+                CMS.debug("HttpConnection: Connecting to " + hostname + ":" + port + " with timeout " + timeout + "s");
+
+                mHttpClient.connect(hostname, port, timeout * 1000);
+
+                CMS.debug("HttpConnection: Connected to " + hostname + ":" + port);
+                return;
+
+            } catch (IOException e) {
+                exception = e;
+                CMS.debug("HttpConnection: Unable to connect to " + hostname + ":" + port + ": " + e);
+                // try the next target immediately
+            }
+        }
+
+        // throw the last exception
+        throw exception;
+    }
+
+    public void setRequestURI(String uri)
+            throws EBaseException {
+        mHttpreq.setURI(uri);
+    }
+
+    public String getRequestURI() {
+        return mHttpreq.getURI();
+    }
     /**
      * sends a request to remote RA/CA, returning the result.
      *
@@ -207,16 +214,17 @@ public class HttpConnection implements IHttpConnection {
             CMS.debug("HttpConnection.send: with String content: null or empty");
             throw new EBaseException("HttpConnection.send: with String content: null or empty");
         }
-        // CMS.debug("HttpConnection.send: with String content: " + content);
+
+        CMS.debug("HttpConnection.send: with String content: " + content);
 
         resp = doSend(content);
         return resp;
     }
 
-    private HttpResponse doSend(String content)
-            throws EBaseException {
+    private HttpResponse doSend(String content) throws EBaseException {
+
         HttpResponse resp = null;
-        boolean reconnect = false;
+        boolean reconnected = false;
 
         if (getRequestURI() == null) {
             throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "URI not set in HttpRequest"));
@@ -229,18 +237,21 @@ public class HttpConnection implements IHttpConnection {
 
         try {
             if (!mHttpClient.connected()) {
-                mHttpClient.connect(mDest.getHost(), mDest.getPort());
-                CMS.debug("HttpConnection.doSend: reconnected to " + mDest.getHost() + ":" + mDest.getPort());
-                reconnect = true;
+                connect();
+                reconnected = true;
             }
+
         } catch (IOException e) {
+
+            CMS.debug(e);
+
             if (e.getMessage().indexOf("Peer's certificate issuer has been marked as not trusted") != -1) {
                 throw new EBaseException(
                         CMS.getUserMessage(
                                 "CMS_BASE_CONN_FAILED",
                                 "(This local authority cannot connect to the remote authority. The local authority's signing certificate must chain to a CA certificate trusted for client authentication in the certificate database. Use the certificate manager, or command line tool such as certutil to verify that the trust permissions of the local authority's issuer cert have 'CT' setting in the SSL client auth field.)"));
             }
-            CMS.debug("HttpConn:Couldn't reconnect " + e);
+
             throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "Couldn't reconnect " + e));
         }
 
@@ -249,28 +260,35 @@ public class HttpConnection implements IHttpConnection {
             try {
                 CMS.debug("HttpConnection.doSend: sending request");
                 resp = mHttpClient.send(mHttpreq);
+
             } catch (IOException e) {
-                CMS.debug("HttpConn: mHttpClient.send failed " + e.toString());
-                if (reconnect) {
-                    CMS.debug("HttpConnection.doSend:resend failed again. " + e);
-                    throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "resend failed again. " + e));
+
+                CMS.debug(e);
+
+                if (reconnected) {
+                    CMS.debug("HttpConnection.doSend: resend failed again.");
+                    throw new EBaseException(
+                            CMS.getUserMessage("CMS_BASE_CONN_FAILED", "resend failed again: " + e), e);
                 }
+
                 try {
                     CMS.debug("HttpConnection.doSend: trying a reconnect ");
-                    mHttpClient.connect(mDest.getHost(), mDest.getPort());
+                    connect();
+
                 } catch (IOException ex) {
                     CMS.debug("HttpConnection.doSend: reconnect for resend failed. " + ex);
-                    throw new EBaseException(CMS.getUserMessage("CMS_BASE_CONN_FAILED", "reconnect for resend failed."
-                            + ex));
+                    throw new EBaseException(
+                            CMS.getUserMessage("CMS_BASE_CONN_FAILED", "reconnect for resend failed: " + ex), e);
                 }
-                reconnect = true;
+
+                reconnected = true;
             }
         } //while
 
         // got reply; check status
         String statusStr = resp.getStatusCode();
 
-        CMS.debug("HttpConnection.doSend:server returned status " + statusStr);
+        CMS.debug("HttpConnection.doSend: server returned status " + statusStr);
         int statuscode = -1;
 
         try {
@@ -287,16 +305,18 @@ public class HttpConnection implements IHttpConnection {
                 // XXX what to do here.
                 String msg = "request no good " + statuscode + " " + resp.getReasonPhrase();
 
-                CMS.debug(msg);
+                CMS.debug("HttpConnection: " + msg);
                 throw new EBaseException(CMS.getUserMessage("CMS_BASE_AUTHENTICATE_FAILED", msg));
+
             } else {
                 // XXX what to do here.
-                String msg = "HttpConn:request no good " + statuscode + " " + resp.getReasonPhrase();
+                String msg = "HttpConnection: request no good " + statuscode + " " + resp.getReasonPhrase();
 
                 CMS.debug(msg);
                 throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", msg));
             }
         }
+
         return resp;
     }
 }
diff --git a/base/util/src/com/netscape/cmsutil/http/HttpClient.java b/base/util/src/com/netscape/cmsutil/http/HttpClient.java
index 438c70c..db042a7 100644
--- a/base/util/src/com/netscape/cmsutil/http/HttpClient.java
+++ b/base/util/src/com/netscape/cmsutil/http/HttpClient.java
@@ -59,22 +59,24 @@ public class HttpClient {
         mCertApprovalCallback = certApprovalCallback;
     }
 
-    public void connect(String host, int port)
-            throws IOException {
+    public void connect(String host, int port,
+            int timeout // milliseconds
+            ) throws IOException {
+
         if (mFactory != null) {
             if (mCertApprovalCallback == null) {
-                mSocket = mFactory.makeSocket(host, port);
+                mSocket = mFactory.makeSocket(host, port, timeout);
             } else {
-                mSocket = mFactory.makeSocket(host, port, mCertApprovalCallback, null);
+                mSocket = mFactory.makeSocket(host, port, mCertApprovalCallback, null, timeout);
             }
+
         } else {
             mSocket = new Socket(host, port);
+            mSocket.setSoTimeout(timeout);
         }
 
         if (mSocket == null) {
-            IOException e = new IOException("Couldn't make connection");
-
-            throw e;
+            throw new IOException("Couldn't make connection");
         }
 
         mInputStream = mSocket.getInputStream();
@@ -85,30 +87,10 @@ public class HttpClient {
         mConnected = true;
     }
 
-    // Inserted by beomsuk
-    public void connect(String host, int port, int timeout)
-            throws IOException {
-        if (mFactory != null) {
-            mSocket = mFactory.makeSocket(host, port, timeout);
-        } else {
-            mSocket = new Socket(host, port);
-        }
-
-        if (mSocket == null) {
-            IOException e = new IOException("Couldn't make connection");
-
-            throw e;
-        }
-
-        mInputStream = mSocket.getInputStream();
-        mOutputStream = mSocket.getOutputStream();
-        mInputStreamReader = new InputStreamReader(mInputStream, "UTF8");
-        mBufferedReader = new BufferedReader(mInputStreamReader);
-        mOutputStreamWriter = new OutputStreamWriter(mOutputStream, "UTF8");
-        mConnected = true;
+    public void connect(String host, int port) throws IOException {
+        connect(host, port, 0);
     }
 
-    // Insert end
     public boolean connected() {
         return mConnected;
     }
diff --git a/base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.java b/base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.java
index 166479d..8c70480 100644
--- a/base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.java
+++ b/base/util/src/com/netscape/cmsutil/http/JssSSLSocketFactory.java
@@ -48,13 +48,14 @@ public class JssSSLSocketFactory implements ISocketFactory {
 
     public Socket makeSocket(String host, int port)
             throws IOException, UnknownHostException {
-        return makeSocket(host, port, null, null);
+        return makeSocket(host, port, null, null, 0);
     }
 
     public Socket makeSocket(String host, int port,
             SSLCertificateApprovalCallback certApprovalCallback,
-            SSLClientCertificateSelectionCallback clientCertCallback)
-            throws IOException, UnknownHostException {
+            SSLClientCertificateSelectionCallback clientCertCallback,
+            int timeout // milliseconds
+            ) throws IOException, UnknownHostException {
 
         try {
             /*
@@ -63,6 +64,7 @@ public class JssSSLSocketFactory implements ISocketFactory {
             s = new SSLSocket(host, port, null, 0, certApprovalCallback,
                     clientCertCallback);
             s.setUseClientMode(true);
+            s.setSoTimeout(timeout);
 
             SSLHandshakeCompletedListener listener = null;
 
@@ -79,27 +81,34 @@ public class JssSSLSocketFactory implements ISocketFactory {
                 s.setClientCertNickname(mClientAuthCertNickname);
             }
             s.forceHandshake();
+
         } catch (org.mozilla.jss.crypto.ObjectNotFoundException e) {
-            throw new IOException(e.toString());
+            throw new IOException(e.toString(), e);
+
         } catch (org.mozilla.jss.crypto.TokenException e) {
-            throw new IOException(e.toString());
+            throw new IOException(e.toString(), e);
+
         } catch (UnknownHostException e) {
             throw e;
+
         } catch (IOException e) {
             throw e;
+
         } catch (Exception e) {
-            throw new IOException(e.toString());
+            throw new IOException(e.toString(), e);
         }
+
         return s;
     }
 
-    public Socket makeSocket(String host, int port, int timeout)
-            throws IOException, UnknownHostException {
+    public Socket makeSocket(String host, int port,
+            int timeout // milliseconds
+            ) throws IOException, UnknownHostException {
         Thread t = new ConnectAsync(this, host, port);
 
         t.start();
         try {
-            t.join(1000 * timeout);
+            t.join(timeout);
         } catch (InterruptedException e) {
         }
 
diff --git a/base/util/src/com/netscape/cmsutil/net/ISocketFactory.java b/base/util/src/com/netscape/cmsutil/net/ISocketFactory.java
index 18f6cac..0dd6963 100644
--- a/base/util/src/com/netscape/cmsutil/net/ISocketFactory.java
+++ b/base/util/src/com/netscape/cmsutil/net/ISocketFactory.java
@@ -28,11 +28,13 @@ public interface ISocketFactory {
     Socket makeSocket(String host, int port)
             throws IOException, UnknownHostException;
 
-    Socket makeSocket(String host, int port, int timeout)
-            throws IOException, UnknownHostException;
+    Socket makeSocket(String host, int port,
+            int timeout // milliseconds
+            ) throws IOException, UnknownHostException;
 
     Socket makeSocket(String host, int port,
             SSLCertificateApprovalCallback certApprovalCallback,
-            SSLClientCertificateSelectionCallback clientCertCallback)
-            throws IOException, UnknownHostException;
+            SSLClientCertificateSelectionCallback clientCertCallback,
+            int timeout // milliseconds
+            ) throws IOException, UnknownHostException;
 }
-- 
1.8.3.1


From 6db01bd091ce991322b004cdd74bf7c15c57fe8c Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Tue, 30 Jun 2015 18:46:33 -0700
Subject: [PATCH 17/21] Ticket 1447 pkispawn: findCertByNickname fails to find
 cert in creating shared tomcat subsystems on HSM

---
 .../src/org/dogtagpki/server/rest/SystemConfigService.java | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
index 73d24a7..e7a9960 100644
--- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java
@@ -345,6 +345,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
                     throw new BadRequestException("No data for '" + tag + "' was found!");
                 }
 
+                String tokenName = certData.getToken() != null ? certData.getToken() : token;
                 if (request.getStandAlone() && request.getStepTwo()) {
                     // Stand-alone PKI (Step 2)
                     if (tag.equals("external_signing")) {
@@ -355,7 +356,6 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
 
                             if (request.getIssuingCA().equals("External CA")) {
                                 String nickname = certData.getNickname() != null ? certData.getNickname() : "caSigningCert External CA";
-                                String tokenName = certData.getToken() != null ? certData.getToken() : token;
                                 Cert cert = new Cert(tokenName, nickname, tag);
                                 ConfigurationUtils.setExternalCACert(b64, csSubsystem, cs, cert);
 
@@ -387,7 +387,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
                     updateConfiguration(request, certData, "subsystem");
 
                     // get parameters needed for cloning
-                    updateCloneConfiguration(certData, "subsystem");
+                    updateCloneConfiguration(certData, "subsystem", tokenName);
                     continue;
                 }
 
@@ -439,7 +439,6 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
                     CMS.debug("configure(): step two selected.  keys will not be generated for '" + tag + "'");
                 }
 
-                String tokenName = certData.getToken() != null ? certData.getToken() : token;
                 Cert cert = new Cert(tokenName, nickname, tag);
                 cert.setDN(dn);
                 cert.setSubsystem(cs.getString("preop.cert." + tag + ".subsystem"));
@@ -529,11 +528,16 @@ public class SystemConfigService extends PKIService implements SystemConfigResou
         }
     }
 
-    private void updateCloneConfiguration(SystemCertData cdata, String tag) throws NotInitializedException,
+    private void updateCloneConfiguration(SystemCertData cdata, String tag, String tokenName) throws NotInitializedException,
             ObjectNotFoundException, TokenException {
         // TODO - some of these parameters may only be valid for RSA
         CryptoManager cryptoManager = CryptoManager.getInstance();
-        X509Certificate cert = cryptoManager.findCertByNickname(cdata.getNickname());
+        if (!tokenName.isEmpty())
+            CMS.debug("SystemConfigService:updateCloneConfiguration: tokenName=" + tokenName);
+        else
+            CMS.debug("SystemConfigService:updateCloneConfiguration: tokenName empty; using internal");
+
+        X509Certificate cert = cryptoManager.findCertByNickname(!tokenName.isEmpty()? tokenName + ":" + cdata.getNickname() :  cdata.getNickname());
         PublicKey pubk = cert.getPublicKey();
         byte[] exponent = CryptoUtil.getPublicExponent(pubk);
         byte[] modulus = CryptoUtil.getModulus(pubk);
-- 
1.8.3.1


From a3773d042de25120803154c96763de55bc0bd7c4 Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Mon, 6 Jul 2015 15:09:54 -0600
Subject: [PATCH 18/21] Note on overriding pki_client_dir when using an HSM

- PKI TRAC Ticket #1425 - pkispawn CA with HSM - if the config file has
  pki_client related params the dir is not created and the admin cert p12 file
  is stored nowhere
---
 base/server/man/man5/pki_default.cfg.5 | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/base/server/man/man5/pki_default.cfg.5 b/base/server/man/man5/pki_default.cfg.5
index f3db6a8..2c8dbbd 100644
--- a/base/server/man/man5/pki_default.cfg.5
+++ b/base/server/man/man5/pki_default.cfg.5
@@ -152,6 +152,9 @@ Set to True to back up the subsystem certificates and keys to a PKCS #12 file.
 .B pki_client_dir
 .IP
 This is the location where all client data used during the installation is stored.  At the end of the invocation of \fBpkispawn\fP, the administrative user's certificate and keys are stored in a PKCS #12 file in this location.
+.IP
+\fBNote:\fP
+When using an HSM, it is currently recommended to NOT specify a value for \fBpki_client_dir\fP that is different from the default value.
 .TP
 .B pki_client_database_dir,  pki_client_database_password
 .IP
-- 
1.8.3.1


From 02c50813a2f5054ad1b6b0a42e919e3ae1472fe0 Mon Sep 17 00:00:00 2001
From: Jack Magne <jmagne@localhost.localdomain>
Date: Mon, 6 Jul 2015 14:05:57 -0700
Subject: [PATCH 19/21] Omit OCSP from clone description.

Ticket #1358.
Also note that OCSP cloning is unsupported as of now.
---
 base/server/man/man8/pkispawn.8 | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/base/server/man/man8/pkispawn.8 b/base/server/man/man8/pkispawn.8
index 33c36e3..ef1857d 100644
--- a/base/server/man/man8/pkispawn.8
+++ b/base/server/man/man8/pkispawn.8
@@ -277,10 +277,10 @@ A cloned CA is a CA which uses the same signing, OCSP signing, and audit signing
 .PP
 Before the clone can be generated, the Directory Server must be created that is separate from the master CA's Directory Server.  The example assumes that the master CA and cloned CA are on different machines, and that their Directory Servers are on port 389.  In addition, the master's system certs and keys have been stored in a PKCS #12 file that is copied over to the clone subsystem in the location specified in <path_to_pkcs12_file>.  This file is created when the master CA is installed; it can also be generated using \fBPKCS12Export\fP.  The file needs to be readable by the user the Certificate Server runs as (by default, pkiuser) and be given the SELinux context pki_tomcat_cert_t.
 .PP
-.SS Installing a KRA, OCSP, or TKS clone
+.SS Installing a KRA or TKS clone (OCSP unsupported as of now)
 \x'-1'\fBpkispawn \-s <subsystem> \-f myconfig.txt\fR
 .PP
-where subsystem is KRA, OCSP, or TKS, and \fImyconfig.txt\fP contains the following text:
+where subsystem is KRA or TKS and \fImyconfig.txt\fP contains the following text:
 .IP
 .nf
 [DEFAULT]
@@ -302,9 +302,9 @@ pki_clone_uri=https://<master_kra_host>:<master_kra_https_port>
 pki_issuing_ca=https://<ca_hostname>:<ca_https_port>
 .fi
 .PP
-As with a CA clone, a KRA, OCSP, or TKS clone uses the same certificates and basic configuration as the original subsystem. The configuration points to the original subsystem to copy its configuration. This example also assumes that the CA is on a remote machine and specifies the CA and security domain information. 
+As with a CA clone, a KRA or TKS clone uses the same certificates and basic configuration as the original subsystem. The configuration points to the original subsystem to copy its configuration. This example also assumes that the CA is on a remote machine and specifies the CA and security domain information.
 .PP
-The subsystem section is [KRA], [OCSP], or [TKS].
+The subsystem section is [KRA] or [TKS].
 .SS Installing a subordinate CA
 \x'-1'\fBpkispawn \-s CA \-f myconfig.txt\fR
 .PP
-- 
1.8.3.1


From c48c52703c374c8e7e65c11fdeee9eeda464290f Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Sat, 4 Jul 2015 11:00:29 -0400
Subject: [PATCH 20/21] Verify raw profile config before accepting it

Creating or modifying a profile with bad profile data in the "raw"
format succeeds and saves the bad data.  After restart, the profile
cannot be loaded and attempting to use, modify or delete or recreate
the profile will fail.

Verify raw profile data by instantiating a temporary profile and
attempting to initialise it with the received configuration.

Fixes: https://fedorahosted.org/pki/ticket/1462
---
 .../dogtagpki/server/ca/rest/ProfileService.java   | 43 +++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
index f7d82b0..a1dba80 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java
@@ -81,6 +81,7 @@ import com.netscape.cms.servlet.base.PKIService;
 import com.netscape.cms.servlet.profile.PolicyConstraintFactory;
 import com.netscape.cms.servlet.profile.PolicyDefaultFactory;
 import com.netscape.cmscore.base.SimpleProperties;
+import com.netscape.cmscore.base.PropConfigStore;
 
 /**
  * @author alee
@@ -583,8 +584,27 @@ public class ProfileService extends PKIService implements ProfileResource {
             auditParams.put("class_id", classId);
 
             IPluginInfo info = registry.getPluginInfo("profile", classId);
+            String className = info.getClassName();
 
-            profile = ps.createProfile(profileId, classId, info.getClassName());
+            // create temporary profile to verify profile configuration
+            IProfile tempProfile;
+            try {
+                tempProfile = (IProfile) Class.forName(className).newInstance();
+            } catch (Exception e) {
+                throw new PKIException(
+                    "Error instantiating profile class: " + className);
+            }
+            tempProfile.setId(profileId);
+            try {
+                PropConfigStore tempConfig = new PropConfigStore(null);
+                tempConfig.load(new ByteArrayInputStream(data));
+                tempProfile.init(ps, tempConfig);
+            } catch (Exception e) {
+                throw new BadRequestException("Invalid profile data", e);
+            }
+
+            // no error thrown, proceed with profile creation
+            profile = ps.createProfile(profileId, classId, className);
             profile.getConfigStore().commit(false);
             profile.getConfigStore().load(new ByteArrayInputStream(data));
             ps.disableProfile(profileId);
@@ -698,6 +718,27 @@ public class ProfileService extends PKIService implements ProfileResource {
             simpleProperties.store(out, null);
             data = out.toByteArray();  // original data sans profileId, classId
 
+            // create temporary profile to verify profile configuration
+            String classId = ps.getProfileClassId(profileId);
+            String className =
+                registry.getPluginInfo("profile", classId).getClassName();
+            IProfile tempProfile;
+            try {
+                tempProfile = (IProfile) Class.forName(className).newInstance();
+            } catch (Exception e) {
+                throw new PKIException(
+                    "Error instantiating profile class: " + className);
+            }
+            tempProfile.setId(profileId);
+            try {
+                PropConfigStore tempConfig = new PropConfigStore(null);
+                tempConfig.load(new ByteArrayInputStream(data));
+                tempProfile.init(ps, tempConfig);
+            } catch (Exception e) {
+                throw new BadRequestException("Invalid profile data", e);
+            }
+
+            // no error thrown, so commit updated profile config
             profile.getConfigStore().load(new ByteArrayInputStream(data));
             ps.disableProfile(profileId);
             profile.getConfigStore().commit(false);
-- 
1.8.3.1


From ac5447a8e0bac5112882be700a17a9274e322adc Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Mon, 6 Jul 2015 13:31:22 -0400
Subject: [PATCH 21/21] Fixed default cert-find filter.

To improve the performance the default LDAP filter generated by
cert-find has been changed to (certStatus=*) to match an existing
VLV index.

https://fedorahosted.org/pki/ticket/1449
---
 .../org/dogtagpki/server/ca/rest/CertService.java  |  16 +-
 .../com/netscape/cmstools/cert/CertFindCLI.java    |   1 -
 .../netscape/cms/servlet/cert/FilterBuilder.java   | 248 +++++++++++----------
 3 files changed, 136 insertions(+), 129 deletions(-)

diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java
index ee974d4..e43909b 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java
@@ -367,15 +367,13 @@ public class CertService extends PKIService implements CertResource {
     }
 
     private String createSearchFilter(String status) {
-        String filter = "";
+        String filter;
 
-        if ((status == null)) {
-            filter = "(serialno=*)";
-            return filter;
-        }
+        if (status == null) {
+            filter = "(certstatus=*)"; // allCerts VLV
 
-        if (status != null) {
-            filter += "(certStatus=" + LDAPUtil.escapeFilter(status) + ")";
+        } else  {
+            filter = "(certStatus=" + LDAPUtil.escapeFilter(status) + ")";
         }
 
         return filter;
@@ -398,7 +396,7 @@ public class CertService extends PKIService implements CertResource {
         size       = size == null ? DEFAULT_SIZE : size;
 
         String filter = createSearchFilter(status);
-        CMS.debug("listCerts: filter is " + filter);
+        CMS.debug("CertService.listCerts: filter: " + filter);
 
         CertDataInfos infos = new CertDataInfos();
         try {
@@ -450,7 +448,9 @@ public class CertService extends PKIService implements CertResource {
 
         start = start == null ? 0 : start;
         size = size == null ? DEFAULT_SIZE : size;
+
         String filter = createSearchFilter(data);
+        CMS.debug("CertService.searchCerts: filter: " + filter);
 
         CertDataInfos infos = new CertDataInfos();
         try {
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java
index 8c7a4df..cb2d80e 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertFindCLI.java
@@ -254,7 +254,6 @@ public class CertFindCLI extends CLI {
 
         } else {
             searchData = new CertSearchRequest();
-            searchData.setSerialNumberRangeInUse(true);
         }
 
         String s = cmd.getOptionValue("start");
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/FilterBuilder.java b/base/server/cms/src/com/netscape/cms/servlet/cert/FilterBuilder.java
index 5c337af..be44c47 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/FilterBuilder.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/FilterBuilder.java
@@ -18,7 +18,9 @@
 
 package com.netscape.cms.servlet.cert;
 
+import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.List;
 import java.util.StringTokenizer;
 
 import com.netscape.certsrv.cert.CertSearchRequest;
@@ -30,210 +32,214 @@ import com.netscape.cmsutil.ldap.LDAPUtil;
  *
  */
 public class FilterBuilder {
-    private final static String MATCH_EXACTLY = "exact";
-    private String searchFilter = null;
-    private CertSearchRequest request = null;
+
+    private List<String> filters = new ArrayList<String>();
+    private CertSearchRequest request;
 
     public FilterBuilder(CertSearchRequest request) {
         this.request = request;
     }
 
     public String buildFilter() {
-        StringBuffer filter = new StringBuffer();
-        buildSerialNumberRangeFilter(filter);
-        buildSubjectFilter(filter);
-        buildStatusFilter(filter);
-        buildRevokedByFilter(filter);
-        buildRevokedOnFilter(filter);
-        buildRevocationReasonFilter(filter);
-        buildIssuedByFilter(filter);
-        buildIssuedOnFilter(filter);
-        buildValidNotBeforeFilter(filter);
-        buildValidNotAfterFilter(filter);
-        buildValidityLengthFilter(filter);
-        buildCertTypeFilter(filter);
-
-        searchFilter = filter.toString();
-
-        if (searchFilter != null && !searchFilter.equals("")) {
-            searchFilter = "(&" + searchFilter + ")";
-        }
 
-        return searchFilter;
+        buildSerialNumberRangeFilter();
+        buildSubjectFilter();
+        buildStatusFilter();
+        buildRevokedByFilter();
+        buildRevokedOnFilter();
+        buildRevocationReasonFilter();
+        buildIssuedByFilter();
+        buildIssuedOnFilter();
+        buildValidNotBeforeFilter();
+        buildValidNotAfterFilter();
+        buildValidityLengthFilter();
+        buildCertTypeFilter();
+
+        if (filters.size() == 0) {
+            return "(certstatus=*)"; // allCerts VLV
+
+        } else if (filters.size() == 1) {
+            return filters.get(0);
+
+        } else {
+            StringBuilder sb = new StringBuilder();
+            for (String filter : filters) {
+                sb.append(filter);
+            }
+            return "(&" + sb + ")";
+        }
     }
 
-    private void buildSerialNumberRangeFilter(StringBuffer filter) {
+    private void buildSerialNumberRangeFilter() {
 
-        if (!request.getSerialNumberRangeInUse()) {
-            return;
-        }
-        boolean changed = false;
         String serialFrom = request.getSerialFrom();
         if (serialFrom != null && !serialFrom.equals("")) {
-            filter.append("(certRecordId>=" + LDAPUtil.escapeFilter(serialFrom) + ")");
-            changed = true;
+            filters.add("(certRecordId>=" + LDAPUtil.escapeFilter(serialFrom) + ")");
         }
+
         String serialTo = request.getSerialTo();
         if (serialTo != null && !serialTo.equals("")) {
-            filter.append("(certRecordId<=" + LDAPUtil.escapeFilter(serialTo) + ")");
-            changed = true;
+            filters.add("(certRecordId<=" + LDAPUtil.escapeFilter(serialTo) + ")");
         }
-        if (!changed) {
-            filter.append("(certRecordId=*)");
-        }
-
     }
 
-    private void buildSubjectFilter(StringBuffer filter) {
+    private void buildSubjectFilter() {
+
         if (!request.getSubjectInUse()) {
             return;
         }
-        StringBuffer lf = new StringBuffer();
 
-        String matchStr = null;
+        StringBuffer lf = new StringBuffer();
         boolean match = request.getMatchExactly();
 
-        if (match == true) {
-            matchStr = MATCH_EXACTLY;
-        }
-
-        buildAVAFilter(request.getEmail(), "E", lf, matchStr);
-        buildAVAFilter(request.getCommonName(), "CN", lf, matchStr);
-        buildAVAFilter(request.getUserID(), "UID", lf, matchStr);
-        buildAVAFilter(request.getOrgUnit(), "OU", lf, matchStr);
-        buildAVAFilter(request.getOrg(), "O", lf, matchStr);
-        buildAVAFilter(request.getLocality(), "L", lf, matchStr);
-        buildAVAFilter(request.getState(), "ST", lf, matchStr);
-        buildAVAFilter(request.getCountry(), "C", lf, matchStr);
+        buildAVAFilter(request.getEmail(), "E", lf, match);
+        buildAVAFilter(request.getCommonName(), "CN", lf, match);
+        buildAVAFilter(request.getUserID(), "UID", lf, match);
+        buildAVAFilter(request.getOrgUnit(), "OU", lf, match);
+        buildAVAFilter(request.getOrg(), "O", lf, match);
+        buildAVAFilter(request.getLocality(), "L", lf, match);
+        buildAVAFilter(request.getState(), "ST", lf, match);
+        buildAVAFilter(request.getCountry(), "C", lf, match);
 
         if (lf.length() == 0) {
-            filter.append("("+ICertRecord.ATTR_X509CERT_SUBJECT+"=*)");
-            return;
-        }
-        if (matchStr != null && matchStr.equals(MATCH_EXACTLY)) {
-            filter.append("(&");
-            filter.append(lf);
-            filter.append(")");
+            filters.add("(" + ICertRecord.ATTR_X509CERT_SUBJECT + "=*)");
+
+        } else if (match) {
+            filters.add("(&" + lf + ")");
+
         } else {
-            filter.append("(|");
-            filter.append(lf);
-            filter.append(")");
+            filters.add("(|" + lf + ")");
         }
     }
 
-    private void buildStatusFilter(StringBuffer filter) {
+    private void buildStatusFilter() {
+
         String status = request.getStatus();
         if (status == null || status.equals("")) {
             return;
         }
-        filter.append("(certStatus=");
-        filter.append(LDAPUtil.escapeFilter(status));
-        filter.append(")");
+
+        filters.add("(certStatus=" + LDAPUtil.escapeFilter(status) + ")");
     }
 
-    private void buildRevokedByFilter(StringBuffer filter) {
+    private void buildRevokedByFilter() {
+
         if (!request.getRevokedByInUse()) {
             return;
         }
 
         String revokedBy = request.getRevokedBy();
         if (revokedBy == null || revokedBy.equals("")) {
-            filter.append("(certRevokedBy=*)");
+            filters.add("(certRevokedBy=*)");
+
         } else {
-            filter.append("(certRevokedBy=");
-            filter.append(LDAPUtil.escapeFilter(revokedBy));
-            filter.append(")");
+            filters.add("(certRevokedBy=" + LDAPUtil.escapeFilter(revokedBy) + ")");
         }
     }
 
     private void buildDateFilter(String prefix,
-            String outStr, long adjustment,
-            StringBuffer filter) {
+            String outStr, long adjustment) {
+
         if (prefix == null || prefix.length() == 0) return;
+
         long epoch = Long.parseLong(prefix);
         Calendar from = Calendar.getInstance();
         from.setTimeInMillis(epoch);
+
+        StringBuilder filter = new StringBuilder();
         filter.append("(");
         filter.append(LDAPUtil.escapeFilter(outStr));
         filter.append(Long.toString(from.getTimeInMillis() + adjustment));
         filter.append(")");
+
+        filters.add(filter.toString());
     }
 
-    private void buildRevokedOnFilter(StringBuffer filter) {
+    private void buildRevokedOnFilter() {
+
         if (!request.getRevokedOnInUse()) {
             return;
         }
-        buildDateFilter(request.getRevokedOnFrom(), "certRevokedOn>=", 0, filter);
-        buildDateFilter(request.getRevokedOnTo(), "certRevokedOn<=", 86399999, filter);
+
+        buildDateFilter(request.getRevokedOnFrom(), "certRevokedOn>=", 0);
+        buildDateFilter(request.getRevokedOnTo(), "certRevokedOn<=", 86399999);
     }
 
-    private void buildRevocationReasonFilter(StringBuffer filter) {
+    private void buildRevocationReasonFilter() {
+
         if (!request.getRevocationReasonInUse()) {
             return;
         }
+
         String reasons = request.getRevocationReason();
         if (reasons == null) {
             return;
         }
-        String queryCertFilter = null;
+
+        StringBuilder filter = new StringBuilder();
         StringTokenizer st = new StringTokenizer(reasons, ",");
         int count = st.countTokens();
         if (st.hasMoreTokens()) {
-            if (count >=2) filter.append("(|");
+            if (count >= 2) filter.append("(|");
             while (st.hasMoreTokens()) {
                 String token = st.nextToken();
-                if (queryCertFilter == null) {
-                    queryCertFilter = "";
-                }
                 filter.append("(x509cert.certRevoInfo=");
                 filter.append(LDAPUtil.escapeFilter(token));
                 filter.append(")");
             }
             if (count >= 2) filter.append(")");
         }
+
+        filters.add(filter.toString());
     }
 
-    private void buildIssuedByFilter(StringBuffer filter) {
+    private void buildIssuedByFilter() {
+
         if (!request.getIssuedByInUse()) {
             return;
         }
+
         String issuedBy = request.getIssuedBy();
         if (issuedBy == null || issuedBy.equals("")) {
-            filter.append("(certIssuedBy=*)");
+            filters.add("(certIssuedBy=*)");
         } else {
-            filter.append("(certIssuedBy=");
-            filter.append(LDAPUtil.escapeFilter(issuedBy));
-            filter.append(")");
+            filters.add("(certIssuedBy=" + LDAPUtil.escapeFilter(issuedBy) + ")");
         }
     }
 
-    private void buildIssuedOnFilter(StringBuffer filter) {
+    private void buildIssuedOnFilter() {
+
         if (!request.getIssuedOnInUse()) {
             return;
         }
-        buildDateFilter(request.getIssuedOnFrom(), "certCreateTime>=", 0, filter);
-        buildDateFilter(request.getIssuedOnTo(), "certCreateTime<=", 86399999, filter);
+
+        buildDateFilter(request.getIssuedOnFrom(), "certCreateTime>=", 0);
+        buildDateFilter(request.getIssuedOnTo(), "certCreateTime<=", 86399999);
     }
 
-    private void buildValidNotBeforeFilter(StringBuffer filter) {
+    private void buildValidNotBeforeFilter() {
+
         if (!request.getValidNotBeforeInUse()) {
             return;
         }
-        buildDateFilter(request.getValidNotBeforeFrom(), ICertRecord.ATTR_X509CERT_NOT_BEFORE+">=", 0, filter);
-        buildDateFilter(request.getValidNotBeforeTo(), ICertRecord.ATTR_X509CERT_NOT_BEFORE+"<=", 86399999, filter);
+
+        buildDateFilter(request.getValidNotBeforeFrom(), ICertRecord.ATTR_X509CERT_NOT_BEFORE+">=", 0);
+        buildDateFilter(request.getValidNotBeforeTo(), ICertRecord.ATTR_X509CERT_NOT_BEFORE+"<=", 86399999);
 
     }
 
-    private void buildValidNotAfterFilter(StringBuffer filter) {
+    private void buildValidNotAfterFilter() {
+
         if (!request.getValidNotAfterInUse()) {
             return;
         }
-        buildDateFilter(request.getValidNotAfterFrom(), ICertRecord.ATTR_X509CERT_NOT_AFTER+">=", 0, filter);
-        buildDateFilter(request.getValidNotAfterTo(), ICertRecord.ATTR_X509CERT_NOT_AFTER+"<=", 86399999, filter);
+
+        buildDateFilter(request.getValidNotAfterFrom(), ICertRecord.ATTR_X509CERT_NOT_AFTER+">=", 0);
+        buildDateFilter(request.getValidNotAfterTo(), ICertRecord.ATTR_X509CERT_NOT_AFTER+"<=", 86399999);
 
     }
 
-    private void buildValidityLengthFilter(StringBuffer filter) {
+    private void buildValidityLengthFilter() {
         if (!request.getValidityLengthInUse()) {
             return;
         }
@@ -242,70 +248,72 @@ public class FilterBuilder {
         Integer count = request.getValidityCount();
         Long unit = request.getValidityUnit();
 
+        StringBuilder filter = new StringBuilder();
         filter.append("(");
         filter.append(ICertRecord.ATTR_X509CERT_DURATION);
         filter.append(LDAPUtil.escapeFilter(op));
         filter.append(count * unit);
         filter.append(")");
+
+        filters.add(filter.toString());
     }
 
-    private void buildCertTypeFilter(StringBuffer filter) {
+    private void buildCertTypeFilter() {
+
         if (!request.getCertTypeInUse()) {
             return;
         }
+
         if (isOn(request.getCertTypeSSLClient())) {
-            filter.append("(x509cert.nsExtension.SSLClient=on)");
+            filters.add("(x509cert.nsExtension.SSLClient=on)");
         } else if (isOff(request.getCertTypeSSLClient())) {
-            filter.append("(x509cert.nsExtension.SSLClient=off)");
+            filters.add("(x509cert.nsExtension.SSLClient=off)");
         }
+
         if (isOn(request.getCertTypeSSLServer())) {
-            filter.append("(x509cert.nsExtension.SSLServer=on)");
+            filters.add("(x509cert.nsExtension.SSLServer=on)");
         } else if (isOff(request.getCertTypeSSLServer())) {
-            filter.append("(x509cert.nsExtension.SSLServer=off)");
+            filters.add("(x509cert.nsExtension.SSLServer=off)");
         }
+
         if (isOn(request.getCertTypeSecureEmail())) {
-            filter.append("(x509cert.nsExtension.SecureEmail=on)");
+            filters.add("(x509cert.nsExtension.SecureEmail=on)");
         } else if (isOff(request.getCertTypeSecureEmail())) {
-            filter.append("(x509cert.nsExtension.SecureEmail=off)");
+            filters.add("(x509cert.nsExtension.SecureEmail=off)");
         }
+
         if (isOn(request.getCertTypeSubSSLCA())) {
-            filter.append("(x509cert.nsExtension.SubordinateSSLCA=on)");
+            filters.add("(x509cert.nsExtension.SubordinateSSLCA=on)");
         } else if (isOff(request.getCertTypeSubSSLCA())) {
-            filter.append("(x509cert.nsExtension.SubordinateSSLCA=off)");
+            filters.add("(x509cert.nsExtension.SubordinateSSLCA=off)");
         }
+
         if (isOn(request.getCertTypeSubEmailCA())) {
-            filter.append("(x509cert.nsExtension.SubordinateEmailCA=on)");
+            filters.add("(x509cert.nsExtension.SubordinateEmailCA=on)");
         } else if (isOff(request.getCertTypeSubEmailCA())) {
-            filter.append("(x509cert.nsExtension.SubordinateEmailCA=off)");
+            filters.add("(x509cert.nsExtension.SubordinateEmailCA=off)");
         }
     }
 
     private boolean isOn(String value) {
-        String inUse = value;
-        if (inUse == null) {
-            return false;
-        }
-        if (inUse.equals("on")) {
+        if (value != null && value.equals("on")) {
             return true;
         }
         return false;
     }
 
     private boolean isOff(String value) {
-        String inUse = value;
-        if (inUse == null) {
-            return false;
-        }
-        if (inUse.equals("off")) {
+        if (value != null && value.equals("off")) {
             return true;
         }
         return false;
     }
 
     private void buildAVAFilter(String param,
-            String avaName, StringBuffer lf, String match) {
+            String avaName, StringBuffer lf, boolean match) {
+
         if (param != null && !param.equals("")) {
-            if (match != null && match.equals(MATCH_EXACTLY)) {
+            if (match) {
                 lf.append("(|");
                 lf.append("("+ICertRecord.ATTR_X509CERT_SUBJECT+"=*");
                 lf.append(avaName);
@@ -318,6 +326,7 @@ public class FilterBuilder {
                 lf.append(LDAPUtil.escapeFilter(LDAPUtil.escapeRDNValue(param)));
                 lf.append(")");
                 lf.append(")");
+
             } else {
                 lf.append("("+ICertRecord.ATTR_X509CERT_SUBJECT+"=*");
                 lf.append(avaName);
@@ -327,6 +336,5 @@ public class FilterBuilder {
                 lf.append("*)");
             }
         }
-
     }
 }
-- 
1.8.3.1