This is part 2 of:
https://fedorahosted.org/pki/ticket/2298 [non-TMS] for key archival/recovery, not to record certain data in ldap and logs

This patch allows one to exclude certain ldap attributes from the enrollment records for crmf requests
(both CRMF, and CMC CRMF).  The following are the highlights:
* CRMF Manual approval profile is disabled: caDualCert.cfg
- By default, if ca.excludedLDAPattrs.enabled is true, then this profile will not work, as the crmf requests
    are not written to ldap record for agents to act on
* ca.excludedLDAPattrs.attrs can be used to configure the attribute list to be excluded * a new CRMF "auto approval" (directory based, needs to be setup) is provided * By default, the following fields are no longer written to the ldap record in case of CRMF: (note: the code deliberately use literal strings on purpose for the reason that the exact literal strings need to be spelled out
in ca.excludedLDAPattrs.attrs if the admin chooses to override the default)
           "req_x509info",
           "publickey",
            "req_extensions",
            "cert_request",
            "req_archive_options",
            "req_key"
* a sleepOneMinute() method is added for debugging purpose. It is not called in the final code, but is left there for future debugging purpose * code was fixed so that in KRA request will display subject name even though the x509info is missing from request * cmc requests did not have request type in records, so they had to be added for differentiation

The following have been tested:
* CRMF auto enroll
* CRMF manual enroll/approval
* CMC-CRMF enroll
*  both CA and KRA interla ldap are exampled for correct data exclusion

Note: CRMF could potentially not include key archival option, however, I am not going to differentiate them at the moment. An earlier prototype I had built attempted to do that and the signing cert's record isn't excluded for attrs write while it's CRMF request is the same as that of its encryption cert counterpart within the same request. Due to this factor (multiple cert reqs with the same request blob), I am treating them the same for exclusion.

thanks,
Christina

From a95da0485758d5385fde425e3d5132aa2d3275a4 Mon Sep 17 00:00:00 2001
From: Christina Fu <c...@redhat.com>
Date: Thu, 16 Jun 2016 15:44:58 -0700
Subject: [PATCH] Ticket #2298 exclude some ldap record attributes with key
 archival This is part 2 of: https://fedorahosted.org/pki/ticket/2298 [non-TMS]
 for key archival/recovery, not to record certain data in ldap and logs

This patch allows one to exclude certain ldap attributes from the enrollment records for crmf requests
(both CRMF, and CMC CRMF).  The following are the highlights:
* CRMF Manual approval profile is disabled: caDualCert.cfg
  - By default, if ca.excludedLDAPattrs.enabled is true, then this profile will not work, as the crmf requests
    are not written to ldap record for agents to act on
* ca.excludedLDAPattrs.attrs can be used to configure the attribute list to be excluded
* a new CRMF "auto approval" (directory based, needs to be setup) is provided
* By default, the following fields are no longer written to the ldap record in case of CRMF:
(note: the code deliberately use literal strings on purpose for the reason that the exact literal strings need to be spelled out
in ca.excludedLDAPattrs.attrs if the admin chooses to override the default)
           "req_x509info",
           "publickey",
            "req_extensions",
            "cert_request",
            "req_archive_options",
            "req_key"
* a sleepOneMinute() method is added for debugging purpose.  It is not called in the final code, but is left there for future debugging purpose
* code was fixed so that in KRA request will display subject name even though the x509info is missing from request
* cmc requests did not have request type in records, so they had to be added for differentiation

The following have been tested:
* CRMF auto enroll
* CRMF manual enroll/approval
* CMC-CRMF enroll
* both CA and KRA interla ldap are exampled for correct data exclusion

Note: CRMF could potentially not include key archival option, however, I am not going to differentiate them at the moment.  An earlier prototype I had built attempted to do that and the signing cert's record isn't excluded for attrs write while it's CRMF request is the same as that of its encryption cert counterpart within the same request.  Due to this factor (multiple cert reqs with the same request blob), I am treating them the same for exclusion.
---
 base/ca/shared/conf/CS.cfg                         |  4 +-
 .../ca/{caDualCert.cfg => caDirBasedDualCert.cfg}  |  6 +-
 base/ca/shared/profiles/ca/caDualCert.cfg          |  4 +-
 base/common/src/com/netscape/certsrv/apps/CMS.java | 13 +++
 .../src/com/netscape/certsrv/apps/ICMSEngine.java  |  6 ++
 .../com/netscape/cms/authentication/CMCAuth.java   |  3 +
 .../def/AuthorityKeyIdentifierExtDefault.java      |  4 +
 .../netscape/cms/profile/def/ValidityDefault.java  |  2 +-
 .../cms/servlet/request/CertReqParser.java         | 95 +++++++++++++++-------
 .../src/com/netscape/cmscore/apps/CMSEngine.java   | 77 ++++++++++++++++++
 .../netscape/cmscore/request/RequestRecord.java    | 35 +++++++-
 .../netscape/cmscore/app/CMSEngineDefaultStub.java | 14 ++++
 12 files changed, 226 insertions(+), 37 deletions(-)
 copy base/ca/shared/profiles/ca/{caDualCert.cfg => caDirBasedDualCert.cfg} (98%)

diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
index 989a3221f256a010f9f6225d5caf3eaed0d0385c..3634ba5b16ca35b0b1482f6d456bad88e18457e3 100644
--- a/base/ca/shared/conf/CS.cfg
+++ b/base/ca/shared/conf/CS.cfg
@@ -967,7 +967,7 @@ oidmap.pse.oid=2.16.840.1.113730.1.18
 oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
 oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
 os.userid=nobody
-profile.list=caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caECDualCert,AdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caSubsystemCert,caOtherCert,caCACert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caAgentFileSigning,caCMCUserCert,caFullCMCUserCert,caSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caEncECUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
+profile.list=caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caDirBasedDualCert,caECDualCert,AdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caSubsystemCert,caOtherCert,caCACert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caAgentFileSigning,caCMCUserCert,caFullCMCUserCert,caSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caEncECUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
 profile.caUUIDdeviceCert.class_id=caEnrollImpl
 profile.caUUIDdeviceCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caUUIDdeviceCert.cfg
 profile.caManualRenewal.class_id=caEnrollImpl
@@ -994,6 +994,8 @@ profile.caCMCUserCert.class_id=caEnrollImpl
 profile.caCMCUserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caCMCUserCert.cfg
 profile.caCrossSignedCACert.class_id=caEnrollImpl
 profile.caCrossSignedCACert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caCrossSignedCACert.cfg
+profile.caDirBasedDualCert.class_id=caEnrollImpl
+profile.caDirBasedDualCert.config=/var/lib/pki/pki-tomcat/ca/profiles/ca/caDirBasedDualCert.cfg
 profile.caDirPinUserCert.class_id=caEnrollImpl
 profile.caDirPinUserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caDirPinUserCert.cfg
 profile.caDirUserCert.class_id=caEnrollImpl
diff --git a/base/ca/shared/profiles/ca/caDualCert.cfg b/base/ca/shared/profiles/ca/caDirBasedDualCert.cfg
similarity index 98%
copy from base/ca/shared/profiles/ca/caDualCert.cfg
copy to base/ca/shared/profiles/ca/caDirBasedDualCert.cfg
index 87c6e6c9e3c754e53eb1ba7cd22467cea31fbe5b..48b8dacc9b07d5475735107966eacfbc34242aec 100644
--- a/base/ca/shared/profiles/ca/caDualCert.cfg
+++ b/base/ca/shared/profiles/ca/caDirBasedDualCert.cfg
@@ -2,8 +2,8 @@ desc=This certificate profile is for enrolling dual user certificates. It works
 visible=true
 enable=true
 enableBy=admin
-name=Manual User Signing & Encryption Certificates Enrollment
-auth.class_id=
+name=Directory-authenticated User Signing & Encryption Certificates Enrollment
+auth.instance_id=UserDirEnrollment
 input.list=i1,i2,i3
 input.i1.class_id=dualKeyGenInputImpl
 input.i2.class_id=subjectNameInputImpl
@@ -109,7 +109,7 @@ policyset.signingCertSet.2.constraint.params.notAfterCheck=false
 policyset.signingCertSet.2.default.class_id=validityDefaultImpl
 policyset.signingCertSet.2.default.name=Validity Default
 policyset.signingCertSet.2.default.params.range=180
-policyset.signingCertSet.2.default.params.startTime=0
+policyset.signingCertSet.2.default.params.startTime=60
 policyset.signingCertSet.3.constraint.class_id=keyConstraintImpl
 policyset.signingCertSet.3.constraint.name=Key Constraint
 policyset.signingCertSet.3.constraint.params.keyType=RSA
diff --git a/base/ca/shared/profiles/ca/caDualCert.cfg b/base/ca/shared/profiles/ca/caDualCert.cfg
index 87c6e6c9e3c754e53eb1ba7cd22467cea31fbe5b..9057e857cc7ab38fbc060111b73d4d8923a5d4f5 100644
--- a/base/ca/shared/profiles/ca/caDualCert.cfg
+++ b/base/ca/shared/profiles/ca/caDualCert.cfg
@@ -1,6 +1,6 @@
-desc=This certificate profile is for enrolling dual user certificates. It works only with Netscape 7.0 or later.
+desc=This certificate profile is for enrolling dual user certificates. It works only with Netscape 7.0 or later. This now is only allowed to work if ca.strippedldapRecords.enabled=false before this profile is enabled
 visible=true
-enable=true
+enable=false
 enableBy=admin
 name=Manual User Signing & Encryption Certificates Enrollment
 auth.class_id=
diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java
index 9bfa608f2b5fa843a8c5d099e9383df89f7390e6..bc82a986089e932604f860f067b46593bc17ab2c 100644
--- a/base/common/src/com/netscape/certsrv/apps/CMS.java
+++ b/base/common/src/com/netscape/certsrv/apps/CMS.java
@@ -1670,6 +1670,19 @@ public final class CMS {
         return _engine.getServerStatus();
     }
 
+    // for debug only
+    public static void sleepOneMinute() {
+        _engine.sleepOneMinute();
+    }
+
+    public static boolean isExcludedLdapAttrsEnabled() {
+        return _engine.isExcludedLdapAttrsEnabled();
+    }
+
+    public static boolean isExcludedLdapAttr(String key) {
+        return _engine.isExcludedLdapAttr(key);
+    }
+
     /**
      * Main driver to start CMS.
      */
diff --git a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
index aa6b9e32e26edec3e9c34d23f84db1684f31ebbd..f781c41301360692431969987cb754ba7a6ce5f4 100644
--- a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
+++ b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java
@@ -1167,4 +1167,10 @@ public interface ICMSEngine extends ISubsystem {
     public String getConfigSDSessionId();
 
     public String getServerStatus();
+
+    public void sleepOneMinute(); // for debug only
+
+    public boolean isExcludedLdapAttrsEnabled();
+
+    public boolean isExcludedLdapAttr(String key);
 }
diff --git a/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java b/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java
index f2bf402417961ebae442dc6019d13a8381f3352e..67938af5d1820c7403221af9fc832f8bc61da785 100644
--- a/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java
+++ b/base/server/cms/src/com/netscape/cms/authentication/CMCAuth.java
@@ -489,6 +489,8 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
 
                         if (type.equals(TaggedRequest.PKCS10)) {
                             CMS.debug("CMCAuth: type is PKCS10");
+                            authToken.set("cert_request_type", "cmc-pkcs10");
+
                             TaggedCertificationRequest tcr =
                                     taggedRequest.getTcr();
                             int p10Id = tcr.getBodyPartID().intValue();
@@ -581,6 +583,7 @@ public class CMCAuth implements IAuthManager, IExtendedPluginInfo,
                         } else if (type.equals(TaggedRequest.CRMF)) {
 
                             CMS.debug("CMCAuth: type is CRMF");
+                            authToken.set("cert_request_type", "cmc-crmf");
                             try {
                                 CertReqMsg crm =
                                         taggedRequest.getCrm();
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java
index e2208aba7c51a4ffd5914e039c38fee43343383e..9aaa29d7a417739c62c9c46968933253dbcddd89 100644
--- a/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java
+++ b/base/server/cms/src/com/netscape/cms/profile/def/AuthorityKeyIdentifierExtDefault.java
@@ -100,6 +100,10 @@ public class AuthorityKeyIdentifierExtDefault extends CAEnrollDefault {
             throw new EPropertyException(CMS.getUserMessage(
                         locale, "CMS_INVALID_PROPERTY", name));
         }
+        if (info == null) {
+            // info is null; possibly strippedldapRecords enabled
+            return null;
+        }
 
         AuthorityKeyIdentifierExtension ext =
                 (AuthorityKeyIdentifierExtension) getExtension(
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/ValidityDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/ValidityDefault.java
index ad4281b808f0a8ab1250717a74256a42b4527b4f..634d0709328d4157bbb7ff4cfa683d09a5bd0291 100644
--- a/base/server/cms/src/com/netscape/cms/profile/def/ValidityDefault.java
+++ b/base/server/cms/src/com/netscape/cms/profile/def/ValidityDefault.java
@@ -195,7 +195,7 @@ public class ValidityDefault extends EnrollDefault {
             } catch (Exception e) {
                 CMS.debug("ValidityDefault: getValue " + e.toString());
             }
-            throw new EPropertyException("Invalid valie");
+            throw new EPropertyException("Invalid value");
         } else if (name.equals(VAL_NOT_AFTER)) {
             SimpleDateFormat formatter =
                     new SimpleDateFormat(DATE_FORMAT);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/request/CertReqParser.java b/base/server/cms/src/com/netscape/cms/servlet/request/CertReqParser.java
index 03975ac4f081a0a0506d199b72e20fddce4620c6..64adebf6844303b28783617583b00a50cb12f111 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/request/CertReqParser.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/request/CertReqParser.java
@@ -30,6 +30,19 @@ import java.util.Hashtable;
 import java.util.Locale;
 import java.util.Vector;
 
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IArgBlock;
+import com.netscape.certsrv.base.IPrettyPrintFormat;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.common.CMSTemplate;
+import com.netscape.cms.servlet.common.CMSTemplateParams;
+import com.netscape.cms.servlet.common.RawJS;
+import com.netscape.cmsutil.util.Utils;
+
 import netscape.security.extensions.NSCertTypeExtension;
 import netscape.security.x509.AlgorithmId;
 import netscape.security.x509.BasicConstraintsExtension;
@@ -44,23 +57,11 @@ import netscape.security.x509.CertificateX509Key;
 import netscape.security.x509.Extension;
 import netscape.security.x509.RevocationReason;
 import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.X500Name;
 import netscape.security.x509.X509CertImpl;
 import netscape.security.x509.X509CertInfo;
 import netscape.security.x509.X509Key;
 
-import com.netscape.certsrv.apps.CMS;
-import com.netscape.certsrv.authentication.IAuthToken;
-import com.netscape.certsrv.base.EBaseException;
-import com.netscape.certsrv.base.IArgBlock;
-import com.netscape.certsrv.base.IPrettyPrintFormat;
-import com.netscape.certsrv.profile.IEnrollProfile;
-import com.netscape.certsrv.request.IRequest;
-import com.netscape.certsrv.request.RequestStatus;
-import com.netscape.cms.servlet.common.CMSTemplate;
-import com.netscape.cms.servlet.common.CMSTemplateParams;
-import com.netscape.cms.servlet.common.RawJS;
-import com.netscape.cmsutil.util.Utils;
-
 /**
  * Output a 'pretty print' of a certificate request
  *
@@ -102,6 +103,26 @@ public class CertReqParser extends ReqParser {
      */
     public void fillRequestIntoArg(Locale l, IRequest req, CMSTemplateParams argSet, IArgBlock arg)
             throws EBaseException {
+
+        // in case x509CertInfo is missing, at least add the subject for display
+        if (req.getExtDataInCertInfo("req_x509info"/*IRequest.CERT_INFO*/) == null
+                && req.getExtDataInCertInfo(IRequest.CERT_INFO) == null
+                && arg.getValueAsString("subject", "").equals("")) {
+            //CMS.debug("CertReqParser.fillRequestIntoArg: filling subject due to missing x509CertInfo in request");
+            try {
+                String subjectnamevalue = req.getExtDataInString("req_subject_name");
+                if (subjectnamevalue != null && !subjectnamevalue.equals("")) {
+                    X500Name name = new X500Name(Utils.base64decode(subjectnamevalue));
+                    CertificateSubjectName sbjName = new CertificateSubjectName(name);
+                    if (sbjName != null) {
+                        arg.addStringValue("subject", sbjName.toString());
+                    }
+                }
+            } catch (Exception ee) {
+                CMS.debug("CertReqParser.fillRequestIntoArg: Exception:" + ee.toString());
+            }
+        }
+
         if (req.getExtDataInCertInfoArray(IRequest.CERT_INFO) != null) {
             fillX509RequestIntoArg(l, req, argSet, arg);
         } else if (req.getExtDataInRevokedCertArray(IRequest.CERT_INFO) != null) {
@@ -609,9 +630,36 @@ public class CertReqParser extends ReqParser {
                 CMSTemplate.escapeJavaScriptStringHTML(v.toString()) + "\"";
     }
 
+    public String getCertSubjectDN(IRequest request) {
+        try {
+            String cert = request.getExtDataInString("cert");
+            if (cert == null) {
+                cert = request.getExtDataInString("req_issued_cert");
+            }
+
+            if (cert != null) {
+
+                X509CertImpl theCert = null;
+                try {
+                    theCert = new X509CertImpl(Utils.base64decode(cert));
+                } catch (CertificateException e) {
+                }
+
+                if (theCert != null) {
+                    String subject = theCert.getSubjectDN().toString();
+                    return subject;
+                }
+            }
+        } catch (Exception e) {
+            CMS.debug("CertReqParser: getCertSubjectDN " + e.toString());
+        }
+        return null;
+    }
+
     public String getRequestorDN(IRequest request) {
         try {
             X509CertInfo info = request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO);
+            if (info == null) return null;
             // retrieve the subject name
             CertificateSubjectName sn = (CertificateSubjectName)
                     info.get(X509CertInfo.SUBJECT);
@@ -661,28 +709,17 @@ public class CertReqParser extends ReqParser {
         if (profile != null) {
             arg.addStringValue("profile", profile);
             String requestorDN = getRequestorDN(req);
+            if (requestorDN == null) {
+                requestorDN = getCertSubjectDN(req);
+            }
 
             if (requestorDN != null) {
                 arg.addStringValue("subject", requestorDN);
             }
         } else if (IRequest.KEYRECOVERY_REQUEST.equals(reqType)) {
             arg.addStringValue("profile", "false");
-
-            String cert = req.getExtDataInString("cert");
-
-            if (cert != null) {
-
-                X509CertImpl theCert = null;
-                try {
-                    theCert = new X509CertImpl(Utils.base64decode(cert));
-                } catch (CertificateException e) {
-                }
-
-                if (theCert != null) {
-                    String subject = theCert.getSubjectDN().toString();
-                    arg.addStringValue("subject", subject);
-                }
-            }
+            String subjectDN = getCertSubjectDN(req);
+            arg.addStringValue("subject", subjectDN);
 
         } else { //TMS
             arg.addStringValue("profile", "false");
diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
index d68290195a92c90b0bb960b64a5f0bfc160ef0a7..77ae8208b78bd7db5451b0310abd6c4307400dc1 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java
@@ -31,9 +31,11 @@ import java.security.cert.X509CRL;
 import java.security.cert.X509Certificate;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Locale;
 import java.util.ResourceBundle;
 import java.util.StringTokenizer;
@@ -207,6 +209,7 @@ public class CMSEngine implements ICMSEngine {
     private CryptoManager mManager = null;
 
     private IConfigStore mConfig = null;
+    private boolean mExcludedLdapAttrsEnabled = true;
     // AutoSD : AutoShutdown
     private String mAutoSD_CrumbFile = null;
     private boolean mAutoSD_Restart = false;
@@ -1246,8 +1249,63 @@ public class CMSEngine implements ICMSEngine {
                 }
             }
         }
+
+        if (id.equals("ca") || id.equals("kra")) {
+            //excludedLdapAttrSet = new Hash(Arrays.asList(excludedLdapAttrs));
+
+            /*
+              figure out if any ldap attributes need exclusion in enrollment records
+              Default config:
+                ca.excludedLDAPattrs.enabled=true;
+                (ca.excludedLDAPattrs.attrs unspecified to take default)
+             */
+            mExcludedLdapAttrsEnabled = mConfig.getBoolean("ca.excludedLDAPattrs.enabled", true);
+            if (mExcludedLdapAttrsEnabled == true) {
+                CMS.debug("CMSEngine: initSubsystem: ca.excludedLDAPattrs.enabled: true");
+                excludedLdapAttrsList = Arrays.asList(excludedLdapAttrs);
+                String unparsedExcludedLdapAttrs = "";
+                try {
+                    unparsedExcludedLdapAttrs = mConfig.getString("ca.excludedLDAPattrs.attrs");
+                    CMS.debug("CMSEngine: initSubsystem: ca.excludedLDAPattrs.attrs =" + unparsedExcludedLdapAttrs);
+                } catch (Exception e) {
+                    CMS.debug("CMSEngine: initSubsystem: ca.excludedLDAPattrs.attrs unspecified, taking default");
+                }
+                if (!unparsedExcludedLdapAttrs.equals("")) {
+                    excludedLdapAttrsList = Arrays.asList(unparsedExcludedLdapAttrs.split(","));
+                    // overwrites the default
+                    //excludedLdapAttrSet = new HashSet(excludedLdapAttrsList);
+                }
+            } else {
+                CMS.debug("CMSEngine: initSubsystem: ca.excludedLDAPattrs.enabled: false");
+            }
+        }
     }
 
+    public boolean isExcludedLdapAttrsEnabled() {
+        return mExcludedLdapAttrsEnabled;
+    }
+
+    public boolean isExcludedLdapAttr(String key) {
+        if (isExcludedLdapAttrsEnabled()) {
+            return excludedLdapAttrsList.contains(key);
+        } else {
+            return false;
+        }
+    }
+
+    // default for ca.excludedLDAPattrs.enabled == true
+    // can be overwritten with ca.excludedLDAPattrs.attrs
+    public List<String> excludedLdapAttrsList = null;
+
+    public static String excludedLdapAttrs[] = {
+            "req_x509info",
+            "publickey",
+            "req_extensions",
+            "cert_request",
+            "req_archive_options",
+            "req_key"
+    };
+
     /**
      * sign some known data to determine if signing key is botched;
      * if so, proceed to graceful shutdown
@@ -2299,6 +2357,25 @@ public class CMSEngine implements ICMSEngine {
     public String getServerStatus() {
         return serverStatus;
     }
+
+    // for debug only
+    public void sleepOneMinute() {
+        boolean debugSleep = false;
+        try {
+            debugSleep = mConfig.getBoolean("debug.sleepOneMinute", false);
+        } catch (Exception e) {
+        }
+
+        /* debugSleep: sleep for one minute to check request on ldap*/
+        if (debugSleep == true) {
+            CMS.debug("debugSleep: about to sleep for one minute; check ldap");
+            try {
+                Thread.sleep(60000);
+            } catch (InterruptedException e) {
+                CMS.debug("debugSleep: sleep out:" + e.toString());
+            }
+        }
+    }
 }
 
 class WarningListener implements ILogEventListener {
diff --git a/base/server/cmscore/src/com/netscape/cmscore/request/RequestRecord.java b/base/server/cmscore/src/com/netscape/cmscore/request/RequestRecord.java
index a6e454dd1787f5f254f5304489f7e53fe4eced8e..8e01290cfa871aefeb076c258333762276879b8b 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/request/RequestRecord.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/request/RequestRecord.java
@@ -49,6 +49,8 @@ import com.netscape.cmscore.dbs.BigIntegerMapper;
 import com.netscape.cmscore.dbs.DateMapper;
 import com.netscape.cmscore.dbs.StringMapper;
 import com.netscape.cmscore.util.Debug;
+import netscape.security.x509.CertificateSubjectName;
+import netscape.security.x509.X509CertInfo;
 
 import netscape.ldap.LDAPAttribute;
 import netscape.ldap.LDAPAttributeSet;
@@ -243,11 +245,42 @@ public class RequestRecord
 
     protected static Hashtable<String, Object> loadExtDataFromRequest(IRequest r) throws EBaseException {
         Hashtable<String, Object> h = new Hashtable<String, Object>();
-
+        String reqType = r.getExtDataInString("cert_request_type");
+        if (reqType == null || reqType.equals("")) {
+            // where CMC puts it
+            reqType = r.getExtDataInString("auth_token.cert_request_type");
+        }
         Enumeration<String> e = r.getExtDataKeys();
         while (e.hasMoreElements()) {
             String key = e.nextElement();
             if (r.isSimpleExtDataValue(key)) {
+                if (key.equals("req_x509info")) {
+                    // extract subjectName if possible here
+                    // if already there, skip it
+                    String subjectName = r.getExtDataInString("req_subject_name");
+                    if (subjectName == null || subjectName.equals("")) {
+                        X509CertInfo info = r.getExtDataInCertInfo(IRequest.CERT_INFO);
+                        CMS.debug("RequestRecord.loadExtDataFromRequest: missing subject name. Processing extracting subjectName from req_x509info");
+                        try {
+                            CertificateSubjectName subjName = (CertificateSubjectName) info.get(X509CertInfo.SUBJECT);
+                            if (subjName != null) {
+                                CMS.debug("RequestRecord.loadExtDataFromRequest: got subjName");
+                                h.put("req_subject_name", subjName.toString());
+                            }
+                        } catch (Exception es) {
+                          //if failed, then no other way to get subject name.
+                          //so be it
+                        }
+                    }/* else { //this is the common case
+                        CMS.debug("RequestRecord.loadExtDataFromRequest: subject name already exists, no action needed");
+                    }*/
+                }
+                if (reqType != null &&
+                    (reqType.equals("crmf") || reqType.equals("cmc-crmf")) &&
+                        CMS.isExcludedLdapAttr(key)) {
+                    //CMS.debug("RequestRecord.loadExtDataFromRequest: found excluded attr; key=" + key);
+                    continue;
+                }
                 h.put(key, r.getExtDataInString(key));
             } else {
                 h.put(key, r.getExtDataInHashtable(key));
diff --git a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java
index 2b85eacacd688d744099189dabed02d91f1b9933..d2b7fe8b730df76ea20b3868b1ee4181b5dc4e6f 100644
--- a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java
+++ b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java
@@ -639,4 +639,18 @@ public class CMSEngineDefaultStub implements ICMSEngine {
     public String getServerStatus() {
         return null;
     }
+
+    @Override
+    public void sleepOneMinute() {
+    }
+
+    @Override
+    public boolean isExcludedLdapAttrsEnabled() {
+        return true;
+    }
+
+    @Override
+    public boolean isExcludedLdapAttr(String key) {
+        return false;
+    }
 }
-- 
2.4.3

_______________________________________________
Pki-devel mailing list
Pki-devel@redhat.com
https://www.redhat.com/mailman/listinfo/pki-devel

Reply via email to