Blame SOURCES/pki-core-rhel-7-9-rhcs-9-7-beta.patch

b1e4e4
From a4f203666bc157bc2bcc09c7f1abd19d987d77ec Mon Sep 17 00:00:00 2001
b1e4e4
From: jmagne <jmagne@redhat.com>
b1e4e4
Date: Thu, 16 Apr 2020 10:23:08 -0700
b1e4e4
Subject: [PATCH 1/6] Fix Bug 1809273 - CRL generation performs an unindexed
b1e4e4
 search. (#378)
b1e4e4
b1e4e4
This fix right now will take care of new installations only.
b1e4e4
b1e4e4
Co-authored-by: Jack Magne <jmagne@test.host.com>
b1e4e4
(cherry picked from commit e587f9557620a737fea3f3e1b14ec58e2957edb5)
b1e4e4
---
b1e4e4
 base/ca/shared/conf/CS.cfg                                |  2 +-
b1e4e4
 base/ca/shared/conf/crlcaissuer.ldif                      | 15 +++++++++++++++
b1e4e4
 base/ca/shared/conf/crlcaissuertasks.ldif                 |  7 +++++++
b1e4e4
 .../netscape/cms/servlet/csadmin/ConfigurationUtils.java  | 11 +++++++++++
b1e4e4
 4 files changed, 34 insertions(+), 1 deletion(-)
b1e4e4
 create mode 100644 base/ca/shared/conf/crlcaissuer.ldif
b1e4e4
 create mode 100644 base/ca/shared/conf/crlcaissuertasks.ldif
b1e4e4
b1e4e4
diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
b1e4e4
index ce76cff..741d4aa 100644
b1e4e4
--- a/base/ca/shared/conf/CS.cfg
b1e4e4
+++ b/base/ca/shared/conf/CS.cfg
b1e4e4
@@ -830,7 +830,7 @@ preop.internaldb.ldif=/usr/share/pki/server/conf/database.ldif
b1e4e4
 preop.internaldb.data_ldif=/usr/share/pki/ca/conf/db.ldif,/usr/share/pki/ca/conf/acl.ldif
b1e4e4
 preop.internaldb.index_ldif=/usr/share/pki/ca/conf/index.ldif
b1e4e4
 preop.internaldb.manager_ldif=/usr/share/pki/server/conf/manager.ldif
b1e4e4
-preop.internaldb.post_ldif=/usr/share/pki/ca/conf/vlv.ldif,/usr/share/pki/ca/conf/vlvtasks.ldif
b1e4e4
+preop.internaldb.post_ldif=/usr/share/pki/ca/conf/vlv.ldif,/usr/share/pki/ca/conf/vlvtasks.ldif,/usr/share/pki/ca/conf/crlcaissuer.ldif,/usr/share/pki/ca/conf/crlcaissuertasks.ldif
b1e4e4
 preop.internaldb.wait_dn=cn=index1160589769, cn=index, cn=tasks, cn=config
b1e4e4
 preop.internaldb.index_task_ldif=/usr/share/pki/ca/conf/indextasks.ldif
b1e4e4
 preop.internaldb.index_wait_dn=cn=index1160589770,cn=index,cn=tasks,cn=config
b1e4e4
diff --git a/base/ca/shared/conf/crlcaissuer.ldif b/base/ca/shared/conf/crlcaissuer.ldif
b1e4e4
new file mode 100644
b1e4e4
index 0000000..2fec1a0
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/ca/shared/conf/crlcaissuer.ldif
b1e4e4
@@ -0,0 +1,15 @@
b1e4e4
+dn: cn=allRevokedCertsByIssuer-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
b1e4e4
+objectClass: top
b1e4e4
+objectClass: vlvSearch
b1e4e4
+cn: allRevokedCertsByIssuer-{instanceId}
b1e4e4
+vlvBase: ou=certificateRepository,ou=ca,{rootSuffix}
b1e4e4
+vlvScope: 1
b1e4e4
+vlvFilter: (&(certStatus=REVOKED)(|(!(issuerName=*))(issuerName={caIssuerDN}))) 
b1e4e4
+
b1e4e4
+dn: cn=allRevokedCertsByIssuer-{instanceId}Index, cn=allRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config
b1e4e4
+objectClass: top
b1e4e4
+objectClass: vlvIndex
b1e4e4
+cn: allRevokedCertsByIssuer-{instanceId}Index
b1e4e4
+vlvSort: serialno
b1e4e4
+vlvEnabled: 0
b1e4e4
+vlvUses: 0
b1e4e4
diff --git a/base/ca/shared/conf/crlcaissuertasks.ldif b/base/ca/shared/conf/crlcaissuertasks.ldif
b1e4e4
new file mode 100644
b1e4e4
index 0000000..888e113
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/ca/shared/conf/crlcaissuertasks.ldif
b1e4e4
@@ -0,0 +1,7 @@
b1e4e4
+dn: cn=index1160589779, cn=index, cn=tasks, cn=config
b1e4e4
+objectclass: top
b1e4e4
+objectclass: extensibleObject
b1e4e4
+cn: index1160589779
b1e4e4
+ttl: 10
b1e4e4
+nsinstance: {database}
b1e4e4
+nsindexVLVAttribute: allRevokedCertsByIssuer-{instanceId}
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b1e4e4
index aca4827..2510191 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
b1e4e4
@@ -1701,6 +1701,8 @@ public class ConfigurationUtils {
b1e4e4
             EBaseException {
b1e4e4
         IConfigStore cs = CMS.getConfigStore();
b1e4e4
 
b1e4e4
+        String caIssuerName = null;
b1e4e4
+
b1e4e4
         CMS.debug("importLDIFS: param=" + param);
b1e4e4
         String v = cs.getString(param);
b1e4e4
 
b1e4e4
@@ -1712,6 +1714,11 @@ public class ConfigurationUtils {
b1e4e4
         String dbuser = cs.getString("preop.internaldb.dbuser",
b1e4e4
                 "uid=" + DBUSER + ",ou=people," + baseDN);
b1e4e4
 
b1e4e4
+        if("ca".equalsIgnoreCase(cstype)) {
b1e4e4
+            caIssuerName = cs.getString("preop.cert.signing.dn", null);
b1e4e4
+            CMS.debug("importLDIFS(): ca issuer name = " + caIssuerName);
b1e4e4
+        }
b1e4e4
+
b1e4e4
         String configDir = instancePath + File.separator + cstype.toLowerCase() + File.separator + "conf";
b1e4e4
 
b1e4e4
         StringTokenizer tokenizer = new StringTokenizer(v, ",");
b1e4e4
@@ -1755,6 +1762,10 @@ public class ConfigurationUtils {
b1e4e4
                             ps.print(database);
b1e4e4
                         } else if (tok.equals("dbuser")) {
b1e4e4
                             ps.print(dbuser);
b1e4e4
+                        } else if (tok.equals("caIssuerDN") ) {
b1e4e4
+                            if(caIssuerName != null) {
b1e4e4
+                                ps.print(caIssuerName); 
b1e4e4
+                            }
b1e4e4
                         }
b1e4e4
                         if ((s.length() + 1) == n1) {
b1e4e4
                             endOfline = true;
b1e4e4
-- 
b1e4e4
1.8.3.1
b1e4e4
b1e4e4
b1e4e4
From 944862c63e3f8fb4647b4728d9006e795c6ddc8d Mon Sep 17 00:00:00 2001
b1e4e4
From: Alexander Scheel <ascheel@redhat.com>
b1e4e4
Date: Fri, 17 Apr 2020 10:46:43 -0400
b1e4e4
Subject: [PATCH 2/6] Add TPS Auditor group
b1e4e4
b1e4e4
Resolves: bz#1549307
b1e4e4
b1e4e4
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
b1e4e4
(cherry picked from commit b27cdf487b4dcbc9d16275f1b911643f3b03de57)
b1e4e4
---
b1e4e4
 base/tps/shared/conf/db.ldif | 6 ++++++
b1e4e4
 1 file changed, 6 insertions(+)
b1e4e4
b1e4e4
diff --git a/base/tps/shared/conf/db.ldif b/base/tps/shared/conf/db.ldif
b1e4e4
index a88e66b..6661d8b 100644
b1e4e4
--- a/base/tps/shared/conf/db.ldif
b1e4e4
+++ b/base/tps/shared/conf/db.ldif
b1e4e4
@@ -41,6 +41,12 @@ objectClass: groupOfUniqueNames
b1e4e4
 cn: Administrators
b1e4e4
 description: Administrators for TPS
b1e4e4
 
b1e4e4
+dn: cn=Auditors,ou=Groups,{rootSuffix}
b1e4e4
+objectClass: top
b1e4e4
+objectClass: groupOfUniqueNames
b1e4e4
+cn: Auditors
b1e4e4
+description: People who can read the signed audit logs for TPS
b1e4e4
+
b1e4e4
 dn: cn=TPS Operators,ou=Groups,{rootSuffix}
b1e4e4
 objectClass: top
b1e4e4
 objectClass: groupOfUniqueNames
b1e4e4
-- 
b1e4e4
1.8.3.1
b1e4e4
b1e4e4
b1e4e4
From b3d46362c83ff2aa8447aa579722d0be209ab590 Mon Sep 17 00:00:00 2001
b1e4e4
From: Christina Fu <cfu@redhat.com>
b1e4e4
Date: Fri, 20 Mar 2020 18:58:26 -0400
b1e4e4
Subject: [PATCH 3/6] Bug 1794213 Server-Side Kyegen Enrollment
b1e4e4
b1e4e4
This patch contains the code that provides the Server-Side Keygen Enrollment feature.
b1e4e4
b1e4e4
Some limitations for this release:
b1e4e4
  - It currently only supports RSA keys.
b1e4e4
  - You need to import the KRA's transport cert into CA's nssdb with the nickname
b1e4e4
       "KRA Transport Certificate"
b1e4e4
      then restart the CA.
b1e4e4
  - Currently, the UI (Javascript) keyType and keySize pulldown menu needs some work
b1e4e4
       (ProfileSelect.template)
b1e4e4
  - Some more error checking and cleanup needed (will be done before actual push)
b1e4e4
b1e4e4
-----
b1e4e4
This patch contains mainly the following pieces:
b1e4e4
b1e4e4
input:
b1e4e4
  The new input plugin ServerKeygenInput.java, which is supposed
b1e4e4
to work with the modification in ProfileSelect.template to
b1e4e4
   - accept the p12 passwd that will be used to compose the p12 once the keys are generated on KRA and cert issued by the CA.
b1e4e4
   - accept the keyType: RSA/ECC
b1e4e4
   - accept the keySize: RSA key sizes or ECC curves
b1e4e4
b1e4e4
Profile:
b1e4e4
  - The new default plugin: ServerKeygenUserKeyDefault.java, which inserts temporary fake keys so code won't blow up down the road; Such fake key will be replaced later when KRA generates the new keys
b1e4e4
  - The new caServerKeygen_UserCert.cfg profile which utilizes the new input and output
b1e4e4
b1e4e4
output:
b1e4e4
  The new output plugin PKCS12Output.java, which contains the p12 to be sent
b1e4e4
back to the browser when the request has been approved.
b1e4e4
b1e4e4
What's expected:
b1e4e4
  Once working, if you go to EE and click on (currently) the first profile:
b1e4e4
"Manual User Dual-User Certificate Enrollment using server-side key generation",
b1e4e4
one should expect to be able to specify the p12 password, p12 password
b1e4e4
again (verified by the Javascript), the key type (RSA/ECC), key size/curve,
b1e4e4
the subject name info, and the requestor info.
b1e4e4
  Once filled out and submit, the request should go into the request queue
b1e4e4
waiting to be approved.
b1e4e4
During approval, the keys should be generated on KRA, archived, and pkcs#12 returned.
b1e4e4
b1e4e4
Finally:
b1e4e4
Server-side key generation for enrollment is not intended to be a solution
b1e4e4
for all.  It's mainly for encryption keys, unless the site administrator
b1e4e4
 doesn't care about archiving signing keys.
b1e4e4
b1e4e4
https://bugzilla.redhat.com/show_bug.cgi?id=1794213
b1e4e4
(cherry picked from commit 3e38d8cfae018a2a2ad69247c9d1b3e347b21ee0)
b1e4e4
---
b1e4e4
 base/ca/shared/conf/CS.cfg                         |   4 +-
b1e4e4
 base/ca/shared/conf/registry.cfg                   |  15 +-
b1e4e4
 .../shared/profiles/ca/caServerKeygen_UserCert.cfg | 103 ++++++
b1e4e4
 .../shared/webapps/ca/ee/ca/ProfileSelect.template |  25 +-
b1e4e4
 base/common/src/com/netscape/certsrv/apps/CMS.java |   1 +
b1e4e4
 .../certsrv/cert/CertEnrollmentRequest.java        |  15 +
b1e4e4
 .../netscape/certsrv/profile/IEnrollProfile.java   |   6 +
b1e4e4
 .../com/netscape/certsrv/profile/ProfileData.java  |   3 +-
b1e4e4
 .../com/netscape/certsrv/property/IDescriptor.java |   2 +
b1e4e4
 .../src/com/netscape/certsrv/request/IRequest.java |   6 +
b1e4e4
 .../src/com/netscape/kra/AsymKeyGenService.java    |  69 ++++
b1e4e4
 base/kra/src/com/netscape/kra/KRAService.java      |   2 +-
b1e4e4
 base/kra/src/com/netscape/kra/RecoveryService.java |  84 ++++-
b1e4e4
 .../cms/profile/common/CAEnrollProfile.java        | 171 ++++++++-
b1e4e4
 .../profile/def/ServerKeygenUserKeyDefault.java    | 385 +++++++++++++++++++++
b1e4e4
 .../cms/profile/input/ServerKeygenInput.java       | 115 ++++++
b1e4e4
 .../netscape/cms/profile/output/PKCS12Output.java  | 110 ++++++
b1e4e4
 .../com/netscape/cms/servlet/base/CMSServlet.java  |   4 +
b1e4e4
 .../cms/servlet/connector/ConnectorServlet.java    |  48 ++-
b1e4e4
 .../cms/servlet/profile/ProfileProcessServlet.java |  31 +-
b1e4e4
 base/server/cmsbundle/src/UserMessages.properties  |  13 +-
b1e4e4
 .../netscape/cmscore/connector/HttpPKIMessage.java |   5 +
b1e4e4
 .../cmscore/connector/RequestTransfer.java         |   4 +-
b1e4e4
 23 files changed, 1198 insertions(+), 23 deletions(-)
b1e4e4
 create mode 100644 base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg
b1e4e4
 create mode 100644 base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
 create mode 100644 base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java
b1e4e4
 create mode 100644 base/server/cms/src/com/netscape/cms/profile/output/PKCS12Output.java
b1e4e4
b1e4e4
diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
b1e4e4
index 741d4aa..004efdc 100644
b1e4e4
--- a/base/ca/shared/conf/CS.cfg
b1e4e4
+++ b/base/ca/shared/conf/CS.cfg
b1e4e4
@@ -976,7 +976,7 @@ oidmap.pse.oid=2.16.840.1.113730.1.18
b1e4e4
 oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
b1e4e4
 oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
b1e4e4
 os.userid=nobody
b1e4e4
-profile.list=caCMCserverCert,caCMCECserverCert,caCMCECsubsystemCert,caCMCsubsystemCert,caCMCauditSigningCert,caCMCcaCert,caCMCocspCert,caCMCkraTransportCert,caCMCkraStorageCert,caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caDirBasedDualCert,AdminCert,ECAdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caECServerCert,caSubsystemCert,caECSubsystemCert,caOtherCert,caCACert,caCMCcaCert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caECDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caECAgentServerCert,caAgentFileSigning,caCMCUserCert,caCMCECUserCert,caFullCMCUserCert,caECFullCMCUserCert,caFullCMCUserSignedCert,caECFullCMCUserSignedCert,caFullCMCSharedTokenCert,caECFullCMCSharedTokenCert,caSimpleCMCUserCert,caECSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caECAdminCert,caInternalAuthServerCert,caECInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caECInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caSigningUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
b1e4e4
+profile.list=caCMCserverCert,caCMCECserverCert,caCMCECsubsystemCert,caCMCsubsystemCert,caCMCauditSigningCert,caCMCcaCert,caCMCocspCert,caCMCkraTransportCert,caCMCkraStorageCert,caServerKeygen_UserCert,caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caDirBasedDualCert,AdminCert,ECAdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caECServerCert,caSubsystemCert,caECSubsystemCert,caOtherCert,caCACert,caCMCcaCert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caECDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caECAgentServerCert,caAgentFileSigning,caCMCUserCert,caCMCECUserCert,caFullCMCUserCert,caECFullCMCUserCert,caFullCMCUserSignedCert,caECFullCMCUserSignedCert,caFullCMCSharedTokenCert,caECFullCMCSharedTokenCert,caSimpleCMCUserCert,caECSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caECAdminCert,caInternalAuthServerCert,caECInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caECInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caSigningUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
b1e4e4
 profile.caUUIDdeviceCert.class_id=caEnrollImpl
b1e4e4
 profile.caUUIDdeviceCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caUUIDdeviceCert.cfg
b1e4e4
 profile.caManualRenewal.class_id=caEnrollImpl
b1e4e4
@@ -1131,6 +1131,8 @@ profile.caStorageCert.class_id=caEnrollImpl
b1e4e4
 profile.caStorageCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caStorageCert.cfg
b1e4e4
 profile.caTransportCert.class_id=caEnrollImpl
b1e4e4
 profile.caTransportCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caTransportCert.cfg
b1e4e4
+profile.caServerKeygen_UserCert.class_id=caEnrollImpl
b1e4e4
+profile.caServerKeygen_UserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caServerKeygen_UserCert.cfg
b1e4e4
 profile.caUserCert.class_id=caEnrollImpl
b1e4e4
 profile.caUserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caUserCert.cfg
b1e4e4
 profile.caECUserCert.class_id=caEnrollImpl
b1e4e4
diff --git a/base/ca/shared/conf/registry.cfg b/base/ca/shared/conf/registry.cfg
b1e4e4
index a78af86..66348a6 100644
b1e4e4
--- a/base/ca/shared/conf/registry.cfg
b1e4e4
+++ b/base/ca/shared/conf/registry.cfg
b1e4e4
@@ -57,7 +57,7 @@ constraintPolicy.uniqueKeyConstraintImpl.name=Unique Public Key Constraint
b1e4e4
 constraintPolicy.externalProcessConstraintImpl.class=com.netscape.cms.profile.constraint.ExternalProcessConstraint
b1e4e4
 constraintPolicy.externalProcessConstraintImpl.desc=External Process Constraint
b1e4e4
 constraintPolicy.externalProcessConstraintImpl.name=External Process Constraint
b1e4e4
-defaultPolicy.ids=noDefaultImpl,genericExtDefaultImpl,autoAssignDefaultImpl,subjectNameDefaultImpl,validityDefaultImpl,randomizedValidityDefaultImpl,caValidityDefaultImpl,subjectKeyIdentifierExtDefaultImpl,authorityKeyIdentifierExtDefaultImpl,basicConstraintsExtDefaultImpl,keyUsageExtDefaultImpl,nsCertTypeExtDefaultImpl,extendedKeyUsageExtDefaultImpl,ocspNoCheckExtDefaultImpl,issuerAltNameExtDefaultImpl,subjectAltNameExtDefaultImpl,userSubjectNameDefaultImpl,cmcUserSignedSubjectNameDefaultImpl,signingAlgDefaultImpl,userKeyDefaultImpl,userValidityDefaultImpl,userExtensionDefaultImpl,userSigningAlgDefaultImpl,authTokenSubjectNameDefaultImpl,subjectInfoAccessExtDefaultImpl,authInfoAccessExtDefaultImpl,nscCommentExtDefaultImpl,freshestCRLExtDefaultImpl,crlDistributionPointsExtDefaultImpl,policyConstraintsExtDefaultImpl,policyMappingsExtDefaultImpl,nameConstraintsExtDefaultImpl,certificateVersionDefaultImpl,certificatePoliciesExtDefaultImpl,subjectDirAttributesExtDefaultImpl,privateKeyPeriodExtDefaultImpl,inhibitAnyPolicyExtDefaultImpl,imageDefaultImpl,nsTokenDeviceKeySubjectNameDefaultImpl,nsTokenUserKeySubjectNameDefaultImpl,authzRealmDefaultImpl,commonNameToSANDefaultImpl
b1e4e4
+defaultPolicy.ids=noDefaultImpl,genericExtDefaultImpl,autoAssignDefaultImpl,subjectNameDefaultImpl,validityDefaultImpl,randomizedValidityDefaultImpl,caValidityDefaultImpl,subjectKeyIdentifierExtDefaultImpl,authorityKeyIdentifierExtDefaultImpl,basicConstraintsExtDefaultImpl,keyUsageExtDefaultImpl,nsCertTypeExtDefaultImpl,extendedKeyUsageExtDefaultImpl,ocspNoCheckExtDefaultImpl,issuerAltNameExtDefaultImpl,subjectAltNameExtDefaultImpl,userSubjectNameDefaultImpl,cmcUserSignedSubjectNameDefaultImpl,signingAlgDefaultImpl,userKeyDefaultImpl,userValidityDefaultImpl,userExtensionDefaultImpl,userSigningAlgDefaultImpl,authTokenSubjectNameDefaultImpl,subjectInfoAccessExtDefaultImpl,authInfoAccessExtDefaultImpl,nscCommentExtDefaultImpl,freshestCRLExtDefaultImpl,crlDistributionPointsExtDefaultImpl,policyConstraintsExtDefaultImpl,policyMappingsExtDefaultImpl,nameConstraintsExtDefaultImpl,certificateVersionDefaultImpl,certificatePoliciesExtDefaultImpl,subjectDirAttributesExtDefaultImpl,privateKeyPeriodExtDefaultImpl,inhibitAnyPolicyExtDefaultImpl,imageDefaultImpl,nsTokenDeviceKeySubjectNameDefaultImpl,nsTokenUserKeySubjectNameDefaultImpl,authzRealmDefaultImpl,commonNameToSANDefaultImpl,serverKeygenUserKeyDefaultImpl
b1e4e4
 defaultPolicy.autoAssignDefaultImpl.class=com.netscape.cms.profile.def.AutoAssignDefault
b1e4e4
 defaultPolicy.autoAssignDefaultImpl.desc=Auto Request Assignment Default
b1e4e4
 defaultPolicy.autoAssignDefaultImpl.name=Auto Request Assignment Default
b1e4e4
@@ -82,6 +82,9 @@ defaultPolicy.cmcUserSignedSubjectNameDefaultImpl.name=CMC User Signed Subject N
b1e4e4
 defaultPolicy.userKeyDefaultImpl.class=com.netscape.cms.profile.def.UserKeyDefault
b1e4e4
 defaultPolicy.userKeyDefaultImpl.desc=User Supplied Key Default
b1e4e4
 defaultPolicy.userKeyDefaultImpl.name=User Supplied Key Default
b1e4e4
+defaultPolicy.serverKeygenUserKeyDefaultImpl.class=com.netscape.cms.profile.def.ServerKeygenUserKeyDefault
b1e4e4
+defaultPolicy.serverKeygenUserKeyDefaultImpl.desc=Server-Side Keygen Default
b1e4e4
+defaultPolicy.serverKeygenUserKeyDefaultImpl.name=Server-Side Keygen Default
b1e4e4
 defaultPolicy.userValidityDefaultImpl.class=com.netscape.cms.profile.def.UserValidityDefault
b1e4e4
 defaultPolicy.userValidityDefaultImpl.desc=User Supplied Validity Default
b1e4e4
 defaultPolicy.userValidityDefaultImpl.name=User Supplied Validity Default
b1e4e4
@@ -197,7 +200,10 @@ profile.caServerCertEnrollImpl.name=Server Certificate Enrollment Profile
b1e4e4
 profile.caUserCertEnrollImpl.class=com.netscape.cms.profile.common.UserCertCAEnrollProfile
b1e4e4
 profile.caUserCertEnrollImpl.desc=Certificate Authority User Certificate Enrollment Profile
b1e4e4
 profile.caUserCertEnrollImpl.name=User Certificate Enrollment Profile
b1e4e4
-profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,encKeyGenInputImpl,signKeyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl,subjectAltNameExtInputImpl
b1e4e4
+profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,encKeyGenInputImpl,signKeyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl,subjectAltNameExtInputImpl,serverKeygenInputImpl
b1e4e4
+profileInput.serverKeygenInputImpl.class=com.netscape.cms.profile.input.ServerKeygenInput
b1e4e4
+profileInput.serverKeygenInputImpl.desc=Server-Side Keygen Input
b1e4e4
+profileInput.serverKeygenInputImpl.name=Server-Side Keygen Input
b1e4e4
 profileInput.subjectAltNameExtInputImpl.class=com.netscape.cms.profile.input.SubjectAltNameExtInput
b1e4e4
 profileInput.subjectAltNameExtInputImpl.desc=SAN Input
b1e4e4
 profileInput.subjectAltNameExtInputImpl.name=SAN Input
b1e4e4
@@ -246,7 +252,7 @@ profileInput.subjectDNInputImpl.name=Subject DN Input
b1e4e4
 profileInput.subjectNameInputImpl.class=com.netscape.cms.profile.input.SubjectNameInput
b1e4e4
 profileInput.subjectNameInputImpl.desc=Subject Name Input
b1e4e4
 profileInput.subjectNameInputImpl.name=Subject Name Input
b1e4e4
-profileOutput.ids=certOutputImpl,cmmfOutputImpl,pkcs7OutputImpl,nsNKeyOutputImpl
b1e4e4
+profileOutput.ids=certOutputImpl,cmmfOutputImpl,pkcs7OutputImpl,nsNKeyOutputImpl,pkcs12OutputImpl
b1e4e4
 profileOutput.certOutputImpl.class=com.netscape.cms.profile.output.CertOutput
b1e4e4
 profileOutput.certOutputImpl.desc=Certificate Output
b1e4e4
 profileOutput.certOutputImpl.name=Certificate Output
b1e4e4
@@ -259,6 +265,9 @@ profileOutput.nsNKeyOutputImpl.name=nsNKeyOutputImpl
b1e4e4
 profileOutput.pkcs7OutputImpl.class=com.netscape.cms.profile.output.PKCS7Output
b1e4e4
 profileOutput.pkcs7OutputImpl.desc=PKCS7 Output
b1e4e4
 profileOutput.pkcs7OutputImpl.name=PKCS7 Output
b1e4e4
+profileOutput.pkcs12OutputImpl.class=com.netscape.cms.profile.output.PKCS12Output
b1e4e4
+profileOutput.pkcs12OutputImpl.desc=PKCS12 Output
b1e4e4
+profileOutput.pkcs12OutputImpl.name=PKCS12 Output
b1e4e4
 profileUpdater.ids=subsystemGroupUpdaterImpl
b1e4e4
 profileUpdater.subsystemGroupUpdaterImpl.class=com.netscape.cms.profile.updater.SubsystemGroupUpdater
b1e4e4
 profileUpdater.subsystemGroupUpdaterImpl.desc=Updater for Subsystem Group
b1e4e4
diff --git a/base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg b/base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg
b1e4e4
new file mode 100644
b1e4e4
index 0000000..0f2b3dc
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg
b1e4e4
@@ -0,0 +1,103 @@
b1e4e4
+desc=This certificate profile is for enrolling user certificates using server-side Key generation.
b1e4e4
+visible=true
b1e4e4
+enable=true
b1e4e4
+enableBy=admin
b1e4e4
+name=Manual User Dual-Use Certificate Enrollment using server-side Key generation
b1e4e4
+auth.class_id=
b1e4e4
+input.list=i1,i2,i3
b1e4e4
+input.i1.class_id=serverKeygenInputImpl
b1e4e4
+input.i2.class_id=subjectNameInputImpl
b1e4e4
+input.i3.class_id=submitterInfoInputImpl
b1e4e4
+output.list=o1
b1e4e4
+output.o1.class_id=pkcs12OutputImpl
b1e4e4
+policyset.list=userCertSet
b1e4e4
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9
b1e4e4
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
b1e4e4
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
b1e4e4
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
b1e4e4
+policyset.userCertSet.1.constraint.params.accept=true
b1e4e4
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
b1e4e4
+policyset.userCertSet.1.default.name=Subject Name Default
b1e4e4
+policyset.userCertSet.1.default.params.name=
b1e4e4
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
b1e4e4
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
b1e4e4
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
b1e4e4
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
b1e4e4
+policyset.userCertSet.10.default.class_id=noDefaultImpl
b1e4e4
+policyset.userCertSet.10.default.name=No Default
b1e4e4
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
b1e4e4
+policyset.userCertSet.2.constraint.name=Validity Constraint
b1e4e4
+policyset.userCertSet.2.constraint.params.range=365
b1e4e4
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
b1e4e4
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
b1e4e4
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
b1e4e4
+policyset.userCertSet.2.default.name=Validity Default
b1e4e4
+policyset.userCertSet.2.default.params.range=180
b1e4e4
+policyset.userCertSet.2.default.params.startTime=0
b1e4e4
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
b1e4e4
+policyset.userCertSet.3.constraint.name=Key Constraint
b1e4e4
+policyset.userCertSet.3.constraint.params.keyType=RSA
b1e4e4
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
b1e4e4
+policyset.userCertSet.3.default.class_id=serverKeygenUserKeyDefaultImpl
b1e4e4
+policyset.userCertSet.3.default.name=Server-Side Keygen Default
b1e4e4
+policyset.userCertSet.3.default.params.keyType=RSA
b1e4e4
+policyset.userCertSet.3.default.params.keySize=2048
b1e4e4
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
b1e4e4
+policyset.userCertSet.4.constraint.name=No Constraint
b1e4e4
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
b1e4e4
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
b1e4e4
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
b1e4e4
+policyset.userCertSet.5.constraint.name=No Constraint
b1e4e4
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
b1e4e4
+policyset.userCertSet.5.default.name=AIA Extension Default
b1e4e4
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
b1e4e4
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
b1e4e4
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
b1e4e4
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
b1e4e4
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
b1e4e4
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
b1e4e4
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
b1e4e4
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
b1e4e4
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
b1e4e4
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
b1e4e4
+policyset.userCertSet.6.default.name=Key Usage Default
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageCritical=true
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
b1e4e4
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
b1e4e4
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
b1e4e4
+policyset.userCertSet.7.constraint.name=No Constraint
b1e4e4
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
b1e4e4
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
b1e4e4
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
b1e4e4
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
b1e4e4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
b1e4e4
+policyset.userCertSet.8.constraint.name=No Constraint
b1e4e4
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
b1e4e4
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
b1e4e4
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
b1e4e4
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
b1e4e4
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
b1e4e4
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
b1e4e4
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
b1e4e4
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
b1e4e4
+policyset.userCertSet.9.constraint.name=No Constraint
b1e4e4
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withEC,SHA256withEC,SHA384withRSA,SHA384withEC,SHA512withEC
b1e4e4
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
b1e4e4
+policyset.userCertSet.9.default.name=Signing Alg
b1e4e4
+policyset.userCertSet.9.default.params.signingAlg=-
b1e4e4
diff --git a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
b1e4e4
index 666d20f..350cb9b 100644
b1e4e4
--- a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
b1e4e4
+++ b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
b1e4e4
@@ -109,6 +109,15 @@ if (isNaN(majorVersion)) {
b1e4e4
    majorVersion = parseInt(navigator.appVersion, 10);
b1e4e4
 }
b1e4e4
 
b1e4e4
+function passwdValidate()
b1e4e4
+{
b1e4e4
+
b1e4e4
+    if (document.forms[0].serverSideKeygenP12Passwd.value != document.forms[0].p12PasswordAgain.value) {
b1e4e4
+        alert("Passwords do not match");
b1e4e4
+        return false;
b1e4e4
+    }
b1e4e4
+    return true;
b1e4e4
+}
b1e4e4
 
b1e4e4
 function isIE() {
b1e4e4
    if ( "ActiveXObject" in window ) {
b1e4e4
@@ -535,7 +544,7 @@ function setCRMFRequest()
b1e4e4
   } else if (typeof(crypto) != "undefined" && typeof(crypto.version) != "undefined") {
b1e4e4
     document.writeln('<form name="ReqForm" onSubmit="return validate();" method="post" action="' + uri + '">');
b1e4e4
   } else {
b1e4e4
-    document.writeln('<form name="ReqForm" method="post" action="' + uri + '">');
b1e4e4
+    document.writeln('<form name="ReqForm" method="post" onSubmit="return passwdValidate()" action="' + uri + '">');
b1e4e4
    }
b1e4e4
 </script>
b1e4e4
 
b1e4e4
@@ -741,6 +750,20 @@ for (var m = 0; m < inputPluginListSet.length; m++) {
b1e4e4
     document.writeln('');
b1e4e4
     if (inputListSet[n].inputSyntax == 'string') {
b1e4e4
       document.writeln('<input type=text name=' + inputListSet[n].inputId + '>');
b1e4e4
+    } else if (inputListSet[n].inputSyntax == 'server_side_keygen_request_type') {
b1e4e4
+        // get PKCS#12 password
b1e4e4
+        document.writeln('');
b1e4e4
+        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif">PKCS #12 Password:</font>');
b1e4e4
+        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif"><input type=password name="serverSideKeygenP12Passwd" value="" AutoComplete=off ></font>');
b1e4e4
+        document.writeln('');
b1e4e4
+
b1e4e4
+        document.writeln('');
b1e4e4
+        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif">PKCS #12 Password again:</font>');
b1e4e4
+        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif"><input type=password name="p12PasswordAgain" value="" AutoComplete=off ></font>');
b1e4e4
+        document.writeln('<SELECT NAME="keyType">'+getKeyTypesOptionsForKeyGen()+'</SELECT>  <SELECT NAME=\"cryptprovider\"></SELECT>');
b1e4e4
+        document.writeln('<SELECT NAME="keySize">'+keyLengthsCurvesOptions("")+'</SELECT>  <SELECT NAME=\"cryptprovider\"></SELECT>');
b1e4e4
+        document.writeln('');
b1e4e4
+
b1e4e4
     } else if (inputListSet[n].inputSyntax == 'cert_request') {
b1e4e4
       document.writeln('<textarea cols=60 rows=10 name=' + inputListSet[n].inputId + '></textarea>');
b1e4e4
     } else if (inputListSet[n].inputSyntax == 'cert_request_type') {
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java
b1e4e4
index 8efa3b7..1dace42 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/apps/CMS.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/apps/CMS.java
b1e4e4
@@ -1550,6 +1550,7 @@ public final class CMS {
b1e4e4
                 name.equalsIgnoreCase("uPasswd") ||
b1e4e4
                 name.equalsIgnoreCase("PASSWORD_CACHE_ADD") ||
b1e4e4
                 name.startsWith("p12Password") ||
b1e4e4
+                name.startsWith("serverSideKeygenP12Passwd") ||
b1e4e4
                 name.equalsIgnoreCase("host_challenge") ||
b1e4e4
                 name.equalsIgnoreCase("card_challenge") ||
b1e4e4
                 name.equalsIgnoreCase("card_cryptogram") ||
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java b/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java
b1e4e4
index e3ea69c..00d1040 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java
b1e4e4
@@ -57,10 +57,14 @@ public class CertEnrollmentRequest extends ResourceMessage {
b1e4e4
     private static final String PROFILE_ID = "profileId";
b1e4e4
     private static final String RENEWAL = "renewal";
b1e4e4
     private static final String SERIAL_NUM = "serial_num";
b1e4e4
+    private static final String SERVERSIDE_KEYGEN_P12_PASSWD = "serverSideKeygenP12Passwd";
b1e4e4
 
b1e4e4
     @XmlElement(name="ProfileID")
b1e4e4
     protected String profileId;
b1e4e4
 
b1e4e4
+    @XmlElement(name="ServerSideKeygenP12Passwd")
b1e4e4
+    protected String serverSideKeygenP12Passwd;
b1e4e4
+
b1e4e4
     @XmlElement(name="Renewal")
b1e4e4
     protected boolean renewal;
b1e4e4
 
b1e4e4
@@ -89,6 +93,8 @@ public class CertEnrollmentRequest extends ResourceMessage {
b1e4e4
         String renewalStr = form.getFirst(RENEWAL);
b1e4e4
         serialNum = new CertId(form.getFirst(SERIAL_NUM));
b1e4e4
         renewal = new Boolean(renewalStr);
b1e4e4
+
b1e4e4
+        serverSideKeygenP12Passwd = form.getFirst(SERVERSIDE_KEYGEN_P12_PASSWD);
b1e4e4
     }
b1e4e4
 
b1e4e4
     /**
b1e4e4
@@ -213,6 +219,7 @@ public class CertEnrollmentRequest extends ResourceMessage {
b1e4e4
         if (serialNum != null) ret.put(SERIAL_NUM, serialNum.toHexString());
b1e4e4
         if (remoteHost != null) ret.put("remoteHost", remoteHost);
b1e4e4
         if (remoteAddr != null) ret.put("remoteAddr", remoteAddr);
b1e4e4
+        if (serverSideKeygenP12Passwd != null) ret.put(SERVERSIDE_KEYGEN_P12_PASSWD, serverSideKeygenP12Passwd);
b1e4e4
 
b1e4e4
         for (ProfileInput input: inputs) {
b1e4e4
             for (ProfileAttribute attr : input.getAttributes()) {
b1e4e4
@@ -299,6 +306,9 @@ public class CertEnrollmentRequest extends ResourceMessage {
b1e4e4
         result = prime * result + ((remoteHost == null) ? 0 : remoteHost.hashCode());
b1e4e4
         result = prime * result + (renewal ? 1231 : 1237);
b1e4e4
         result = prime * result + ((serialNum == null) ? 0 : serialNum.hashCode());
b1e4e4
+
b1e4e4
+//cfu?
b1e4e4
+        result = prime * result + ((serverSideKeygenP12Passwd == null) ? 0 : serverSideKeygenP12Passwd.hashCode());
b1e4e4
         return result;
b1e4e4
     }
b1e4e4
 
b1e4e4
@@ -343,6 +353,11 @@ public class CertEnrollmentRequest extends ResourceMessage {
b1e4e4
                 return false;
b1e4e4
         } else if (!serialNum.equals(other.serialNum))
b1e4e4
             return false;
b1e4e4
+        if (serverSideKeygenP12Passwd == null) {
b1e4e4
+            if (other.serverSideKeygenP12Passwd != null)
b1e4e4
+                return false;
b1e4e4
+        } else if (!serverSideKeygenP12Passwd.equals(other.serverSideKeygenP12Passwd))
b1e4e4
+            return false;
b1e4e4
         return true;
b1e4e4
     }
b1e4e4
 
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
b1e4e4
index 34543cb..8002540 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
b1e4e4
@@ -148,6 +148,12 @@ public interface IEnrollProfile extends IProfile {
b1e4e4
     public static final String REQUEST_ISSUED_CERT = "req_issued_cert";
b1e4e4
 
b1e4e4
     /**
b1e4e4
+     * Name of request attribute that stores the issued P12 from server-side keygen.
b1e4e4
+     * 

b1e4e4
+     */
b1e4e4
+    public static final String REQUEST_ISSUED_P12 = "req_issued_p12";
b1e4e4
+
b1e4e4
+    /**
b1e4e4
      * Name of request attribute that stores the transport certificate.
b1e4e4
      * 

b1e4e4
      * The value is of type String including base64 encoded certificate.
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/profile/ProfileData.java b/base/common/src/com/netscape/certsrv/profile/ProfileData.java
b1e4e4
index 4b35fee..7d3623a 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/profile/ProfileData.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/profile/ProfileData.java
b1e4e4
@@ -313,4 +313,5 @@ public class ProfileData {
b1e4e4
         data.setXMLOutput(false);
b1e4e4
     }
b1e4e4
 
b1e4e4
-}
b1e4e4
\ No newline at end of file
b1e4e4
+}
b1e4e4
+
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/property/IDescriptor.java b/base/common/src/com/netscape/certsrv/property/IDescriptor.java
b1e4e4
index 830ecdb..4de6bb3 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/property/IDescriptor.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/property/IDescriptor.java
b1e4e4
@@ -45,6 +45,8 @@ public interface IDescriptor {
b1e4e4
     public static String DUAL_KEYGEN_REQUEST_TYPE = "dual_keygen_request_type";
b1e4e4
     public static String CERT_REQUEST = "cert_request";
b1e4e4
     public static String CERT_REQUEST_TYPE = "cert_request_type";
b1e4e4
+    public static String SERVER_SIDE_KEYGEN_REQUEST_TYPE = "server_side_keygen_request_type";
b1e4e4
+    public static String SERVER_SIDE_KEYGEN_PKCS12 = "server_side_keygen_p12";
b1e4e4
     public static String CHOICE = "choice"; // choice of strings
b1e4e4
     public static String DN = "dn";
b1e4e4
     public static String IP = "ip";
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/request/IRequest.java b/base/common/src/com/netscape/certsrv/request/IRequest.java
b1e4e4
index cfc4ca0..47dde82 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/request/IRequest.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/request/IRequest.java
b1e4e4
@@ -197,6 +197,12 @@ public interface IRequest extends Serializable {
b1e4e4
     public static final String KEY_GEN_USAGES = "keyGenUsages";
b1e4e4
     public static final String KEY_GEN_TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
b1e4e4
 
b1e4e4
+    // Server-side Keygen enrollment
b1e4e4
+    //public static final String SERVER_SIDE_KEYGEN_ENROLL = "serverSideKeygenEnroll";
b1e4e4
+    public static final String SSK_STAGE = "serverSideKeygenStage";
b1e4e4
+    public static final String SSK_STAGE_KEYGEN = "serverSideKeygenStage_keygen";
b1e4e4
+    public static final String SSK_STAGE_KEY_RETRIEVE = "serverSideKeygenStage_key_retrieve";
b1e4e4
+
b1e4e4
     // requestor type values.
b1e4e4
     public static final String REQUESTOR_EE = "EE";
b1e4e4
     public static final String REQUESTOR_RA = "RA";
b1e4e4
diff --git a/base/kra/src/com/netscape/kra/AsymKeyGenService.java b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b1e4e4
index 6571044..dca6ebc 100644
b1e4e4
--- a/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b1e4e4
+++ b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b1e4e4
@@ -19,6 +19,7 @@ package com.netscape.kra;
b1e4e4
 
b1e4e4
 import java.math.BigInteger;
b1e4e4
 import java.security.KeyPair;
b1e4e4
+import java.util.Enumeration;
b1e4e4
 
b1e4e4
 import org.mozilla.jss.crypto.KeyPairGeneratorSpi;
b1e4e4
 import org.mozilla.jss.crypto.PrivateKey;
b1e4e4
@@ -42,6 +43,7 @@ import com.netscape.certsrv.security.IStorageKeyUnit;
b1e4e4
 import com.netscape.cms.logging.Logger;
b1e4e4
 import com.netscape.cms.logging.SignedAuditLogger;
b1e4e4
 import com.netscape.cmscore.dbs.KeyRecord;
b1e4e4
+import com.netscape.cmsutil.crypto.CryptoUtil;
b1e4e4
 
b1e4e4
 import netscape.security.util.WrappingParams;
b1e4e4
 
b1e4e4
@@ -72,8 +74,24 @@ public class AsymKeyGenService implements IService {
b1e4e4
 
b1e4e4
     @Override
b1e4e4
     public boolean serviceRequest(IRequest request) throws EBaseException {
b1e4e4
+        String method = "AsymKeyGenService:serviceRequest: ";
b1e4e4
         IConfigStore configStore = CMS.getConfigStore();
b1e4e4
+
b1e4e4
+        boolean isSSKeygen = false;
b1e4e4
+        String isSSKeygenStr = request.getExtDataInString("isServerSideKeygen");
b1e4e4
+        if ((isSSKeygenStr != null) && isSSKeygenStr.equalsIgnoreCase("true")) {
b1e4e4
+            CMS.debug(method + "isServerSideKeygen = true");
b1e4e4
+            isSSKeygen = true;
b1e4e4
+        } else {
b1e4e4
+            CMS.debug(method + "isServerSideKeygen = false");
b1e4e4
+        }
b1e4e4
+
b1e4e4
         String clientKeyId = request.getExtDataInString(IRequest.SECURITY_DATA_CLIENT_KEY_ID);
b1e4e4
+        if (clientKeyId != null)
b1e4e4
+            CMS.debug(method + "clientKeyId = " + clientKeyId);
b1e4e4
+        else
b1e4e4
+            CMS.debug(method + "clientKeyId not found");
b1e4e4
+
b1e4e4
         String algorithm = request.getExtDataInString(IRequest.KEY_GEN_ALGORITHM);
b1e4e4
 
b1e4e4
         String keySizeStr = request.getExtDataInString(IRequest.KEY_GEN_SIZE);
b1e4e4
@@ -159,6 +177,35 @@ public class AsymKeyGenService implements IService {
b1e4e4
             throw new EBaseException("Failed to generate asymmetric key!");
b1e4e4
         }
b1e4e4
 
b1e4e4
+        if (isSSKeygen) {
b1e4e4
+            byte[] publicKeyData = null;
b1e4e4
+            String pubKeyStr = "";
b1e4e4
+            try {
b1e4e4
+                publicKeyData = kp.getPublic().getEncoded();
b1e4e4
+                if (publicKeyData == null) {
b1e4e4
+                    request.setExtData(IRequest.RESULT, Integer.valueOf(4));
b1e4e4
+                    CMS.debug(method + " failed getting publickey encoded");
b1e4e4
+                    return false;
b1e4e4
+                } else {
b1e4e4
+                    //CMS.debug(method + "public key binary length ="+ publicKeyData.length);
b1e4e4
+                    if (algorithm.equals("EC")) {
b1e4e4
+                        /* url encode */
b1e4e4
+                        pubKeyStr = com.netscape.cmsutil.util.Utils.SpecialEncode(publicKeyData);
b1e4e4
+                        CMS.debug(method + " EC pubKeyStr special encoded");
b1e4e4
+                    } else {
b1e4e4
+                        pubKeyStr = CryptoUtil.base64Encode(publicKeyData);
b1e4e4
+                    }
b1e4e4
+
b1e4e4
+                    //CMS.debug(method + "public key length =" + pubKeyStr.length());
b1e4e4
+                    request.setExtData("public_key", pubKeyStr);
b1e4e4
+                }
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                CMS.debug(method + e);
b1e4e4
+                request.setExtData(IRequest.RESULT, Integer.valueOf(4));
b1e4e4
+                return false;
b1e4e4
+            }
b1e4e4
+        }
b1e4e4
+
b1e4e4
         byte[] privateSecurityData = null;
b1e4e4
         WrappingParams params = null;
b1e4e4
 
b1e4e4
@@ -194,6 +241,7 @@ public class AsymKeyGenService implements IService {
b1e4e4
         record.set(KeyRecord.ATTR_STATUS, STATUS_ACTIVE);
b1e4e4
         record.set(KeyRecord.ATTR_KEY_SIZE, keySize);
b1e4e4
         request.setExtData(ATTR_KEY_RECORD, serialNo);
b1e4e4
+        request.setExtData("serialNumber", serialNo);
b1e4e4
 
b1e4e4
         if (realm != null) {
b1e4e4
             record.set(KeyRecord.ATTR_REALM, realm);
b1e4e4
@@ -212,7 +260,28 @@ public class AsymKeyGenService implements IService {
b1e4e4
         auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.SUCCESS, request.getRequestId(),
b1e4e4
                 clientKeyId, new KeyId(serialNo), "None");
b1e4e4
         request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
b1e4e4
+
b1e4e4
+        if (isSSKeygen) {
b1e4e4
+
b1e4e4
+            Enumeration<String> ereq = request.getExtDataKeys();
b1e4e4
+
b1e4e4
+            /* cfu
b1e4e4
+            CMS.debug(method + "let's find out what's in the request");
b1e4e4
+            while (ereq.hasMoreElements()) {
b1e4e4
+                String reqKey = ereq.nextElement();
b1e4e4
+                String reqVal = request.getExtDataInString(reqKey);
b1e4e4
+                if (reqVal != null) {
b1e4e4
+                    CMS.debug(method + reqKey + ": " + reqVal);
b1e4e4
+                } else {
b1e4e4
+                    CMS.debug(method + reqKey + ": no value");
b1e4e4
+                }
b1e4e4
+            }
b1e4e4
+            */
b1e4e4
+
b1e4e4
+            request.setExtData("delayLDAPCommit", "false");
b1e4e4
+        }
b1e4e4
         kra.getRequestQueue().updateRequest(request);
b1e4e4
+
b1e4e4
         return true;
b1e4e4
     }
b1e4e4
 
b1e4e4
diff --git a/base/kra/src/com/netscape/kra/KRAService.java b/base/kra/src/com/netscape/kra/KRAService.java
b1e4e4
index f57b293..91ee5f9 100644
b1e4e4
--- a/base/kra/src/com/netscape/kra/KRAService.java
b1e4e4
+++ b/base/kra/src/com/netscape/kra/KRAService.java
b1e4e4
@@ -50,7 +50,7 @@ public class KRAService implements IService {
b1e4e4
     public final static String SECURITY_DATA_RECOVERY = IRequest.SECURITY_DATA_RECOVERY_REQUEST;
b1e4e4
     public final static String SYMKEY_GENERATION = IRequest.SYMKEY_GENERATION_REQUEST;
b1e4e4
     public final static String ASYMKEY_GENERATION = IRequest.ASYMKEY_GENERATION_REQUEST;
b1e4e4
-
b1e4e4
+    //public final static String SERVER_SIDE_KEYGEN_ENROLL = IRequest.SERVER_SIDE_KEYGEN_ENROLL;
b1e4e4
 
b1e4e4
     // private variables
b1e4e4
     private IKeyRecoveryAuthority mKRA = null;
b1e4e4
diff --git a/base/kra/src/com/netscape/kra/RecoveryService.java b/base/kra/src/com/netscape/kra/RecoveryService.java
b1e4e4
index 96ee73b..4f2add9 100644
b1e4e4
--- a/base/kra/src/com/netscape/kra/RecoveryService.java
b1e4e4
+++ b/base/kra/src/com/netscape/kra/RecoveryService.java
b1e4e4
@@ -38,8 +38,12 @@ import org.mozilla.jss.asn1.SEQUENCE;
b1e4e4
 import org.mozilla.jss.asn1.SET;
b1e4e4
 import org.mozilla.jss.crypto.CryptoToken;
b1e4e4
 import org.mozilla.jss.crypto.EncryptionAlgorithm;
b1e4e4
+import org.mozilla.jss.crypto.IVParameterSpec;
b1e4e4
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
b1e4e4
+import org.mozilla.jss.crypto.KeyWrapper;
b1e4e4
 import org.mozilla.jss.crypto.PBEAlgorithm;
b1e4e4
 import org.mozilla.jss.crypto.PrivateKey;
b1e4e4
+import org.mozilla.jss.crypto.SymmetricKey;
b1e4e4
 import org.mozilla.jss.pkcs12.AuthenticatedSafes;
b1e4e4
 import org.mozilla.jss.pkcs12.CertBag;
b1e4e4
 import org.mozilla.jss.pkcs12.PFX;
b1e4e4
@@ -85,8 +89,7 @@ import netscape.security.x509.X509Key;
b1e4e4
  * End Entity recovery will send RA or CA a response where stores the recovered key.
b1e4e4
  *
b1e4e4
  * @author thomask (original)
b1e4e4
- * @author cfu (non-RSA keys; private keys secure handling);
b1e4e4
- * @version $Revision$, $Date$
b1e4e4
+ * @author cfu (non-RSA keys; private keys secure handling; server-side keygen enrollment);
b1e4e4
  */
b1e4e4
 public class RecoveryService implements IService {
b1e4e4
 
b1e4e4
@@ -139,15 +142,69 @@ public class RecoveryService implements IService {
b1e4e4
         String tokName = "";
b1e4e4
         CryptoToken ct = null;
b1e4e4
         Boolean allowEncDecrypt_recovery = false;
b1e4e4
+        boolean isSSKeygen = false;
b1e4e4
+        String serverKeygenP12Pass = null;
b1e4e4
 
b1e4e4
+        X509Certificate transportCert =
b1e4e4
+                request.getExtDataInCert(ATTR_TRANSPORT_CERT);
b1e4e4
+        String transportCertNick = null;
b1e4e4
         try {
b1e4e4
             cm = CryptoManager.getInstance();
b1e4e4
             config = CMS.getConfigStore();
b1e4e4
             tokName = config.getString("kra.storageUnit.hardware", CryptoUtil.INTERNAL_TOKEN_NAME);
b1e4e4
+
b1e4e4
+            // default to "KRA transport certificate" would require one to
b1e4e4
+            // change the nickname for existing KRA transport cert
b1e4e4
+            transportCertNick = config.getString("kra.cert.transport.nickname", "KRA transport certificate");
b1e4e4
+            CMS.debug("RecoveryService: serviceRequest: KRA transport cert nickname: " + transportCertNick);
b1e4e4
             CMS.debug("RecoveryService: serviceRequest: token: " + tokName);
b1e4e4
             ct = CryptoUtil.getCryptoToken(tokName);
b1e4e4
 
b1e4e4
             allowEncDecrypt_recovery = config.getBoolean("kra.allowEncDecrypt.recovery", false);
b1e4e4
+
b1e4e4
+            String isSSKeygenStr = request.getExtDataInString("isServerSideKeygen");
b1e4e4
+            if (isSSKeygenStr != null && isSSKeygenStr.equalsIgnoreCase("true")) {
b1e4e4
+                CMS.debug("RecoveryService: serviceRequest: isSSKengen=" + isSSKeygenStr);
b1e4e4
+                isSSKeygen = true;
b1e4e4
+                CryptoToken token = CryptoUtil.getKeyStorageToken("internal");
b1e4e4
+
b1e4e4
+                // serverKeygenP12Pass = request.getExtDataInString("serverSideKeygenP12Passwd");
b1e4e4
+                byte[] sessionWrappedPassphrase = (byte[]) request.getExtDataInByteArray("serverSideKeygenP12PasswdEnc");
b1e4e4
+                byte[] transWrappedSessionKey = (byte[]) request.getExtDataInByteArray("serverSideKeygenP12PasswdTransSession");
b1e4e4
+
b1e4e4
+                // unwrap session key
b1e4e4
+                /* TODO: get nickname from config */
b1e4e4
+                org.mozilla.jss.crypto.X509Certificate transCert =
b1e4e4
+                        cm.findCertByNickname(transportCertNick);
b1e4e4
+                PrivateKey transPrivateKey =
b1e4e4
+                        (org.mozilla.jss.crypto.PrivateKey) cm.findPrivKeyByCert(transCert);
b1e4e4
+                if (transPrivateKey != null)
b1e4e4
+                    CMS.debug("RecoveryService: serviceRequest: found private key");
b1e4e4
+
b1e4e4
+                // key size and alg must match with serverKeygenUserKeyDefault.java
b1e4e4
+
b1e4e4
+                SymmetricKey unwrappedSessionKey =
b1e4e4
+                        CryptoUtil.unwrap(token,  SymmetricKey.AES, 128,
b1e4e4
+                        SymmetricKey.Usage.UNWRAP,
b1e4e4
+                        transPrivateKey,
b1e4e4
+                        transWrappedSessionKey,
b1e4e4
+                        KeyWrapAlgorithm.RSA);
b1e4e4
+
b1e4e4
+                if (unwrappedSessionKey == null)
b1e4e4
+                    CMS.debug("RecoveryService: serviceRequest: unwrappedSessionKey null");
b1e4e4
+
b1e4e4
+                // decrypt p12 passphrase
b1e4e4
+                EncryptionAlgorithm encryptAlgorithm =
b1e4e4
+                        EncryptionAlgorithm.AES_128_CBC_PAD;
b1e4e4
+                byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
b1e4e4
+                IVParameterSpec ivps = new IVParameterSpec(iv);
b1e4e4
+                byte[] passphrase = CryptoUtil.decryptUsingSymmetricKey(token,
b1e4e4
+                        ivps, sessionWrappedPassphrase, unwrappedSessionKey,
b1e4e4
+                        encryptAlgorithm);
b1e4e4
+                serverKeygenP12Pass = new String(passphrase, "UTF-8");
b1e4e4
+                // TODO: do this after it's done being used later:
b1e4e4
+                // CryptoUtil.obscureBytes(serverKeygenP12Pass, "random");
b1e4e4
+            }
b1e4e4
         } catch (Exception e) {
b1e4e4
             CMS.debug("RecoveryService exception: use internal token :"
b1e4e4
                     + e.toString());
b1e4e4
@@ -173,8 +230,14 @@ public class RecoveryService implements IService {
b1e4e4
                 request.getRequestId());
b1e4e4
 
b1e4e4
         if (params == null) {
b1e4e4
-            // possibly we are in recovery mode
b1e4e4
-            return true;
b1e4e4
+            //cfu
b1e4e4
+            if (isSSKeygen) {
b1e4e4
+                params = new Hashtable<String, Object>();
b1e4e4
+                params.put(RecoveryService.ATTR_TRANSPORT_PWD, serverKeygenP12Pass);
b1e4e4
+            } else {
b1e4e4
+                // possibly we are in recovery mode
b1e4e4
+                return true;
b1e4e4
+            }
b1e4e4
         }
b1e4e4
 
b1e4e4
         // retrieve based on serial no
b1e4e4
@@ -185,6 +248,7 @@ public class RecoveryService implements IService {
b1e4e4
             statsSub.startTiming("get_key");
b1e4e4
         }
b1e4e4
         KeyRecord keyRecord = (KeyRecord) mStorage.readKeyRecord(serialno);
b1e4e4
+
b1e4e4
         if (statsSub != null) {
b1e4e4
             statsSub.endTiming("get_key");
b1e4e4
         }
b1e4e4
@@ -221,8 +285,6 @@ public class RecoveryService implements IService {
b1e4e4
 
b1e4e4
         // Unwrap the archived private key
b1e4e4
         byte privateKeyData[] = null;
b1e4e4
-        X509Certificate transportCert =
b1e4e4
-                request.getExtDataInCert(ATTR_TRANSPORT_CERT);
b1e4e4
 
b1e4e4
         if (transportCert == null) {
b1e4e4
             if (statsSub != null) {
b1e4e4
@@ -314,6 +376,14 @@ public class RecoveryService implements IService {
b1e4e4
                 mKRA.getStorageKeyUnit().logout();
b1e4e4
             }
b1e4e4
         }
b1e4e4
+
b1e4e4
+        // cfu
b1e4e4
+        if (isSSKeygen) {
b1e4e4
+            CMS.debug("RecoveryService: putting p12 in request");
b1e4e4
+            byte[] p12b = (byte[])params.get(ATTR_PKCS12);
b1e4e4
+            // IEnrollProfile.REQUEST_ISSUED_P12
b1e4e4
+            request.setExtData("req_issued_p12" /*ATTR_PKCS12*/, p12b);
b1e4e4
+        }
b1e4e4
         mKRA.log(ILogger.LL_INFO, "key " +
b1e4e4
                 serialno.toString() +
b1e4e4
                 " recovered");
b1e4e4
@@ -540,7 +610,7 @@ public class RecoveryService implements IService {
b1e4e4
                     pass,
b1e4e4
                     /* NSS has a bug that causes any AES CBC encryption
b1e4e4
                      * to use AES-256, but AlgorithmID contains chosen
b1e4e4
-                     * alg.  To avoid mismatch, use AES_256_CBC. */
b1e4e4
+                     * alg.  To avoid mismatch, use AES_128_CBC. */
b1e4e4
                     EncryptionAlgorithm.AES_256_CBC,
b1e4e4
                     0 /* iterations (use default) */,
b1e4e4
                     priKey);
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
b1e4e4
index 6e1981f..2c539f0 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
b1e4e4
@@ -17,6 +17,9 @@
b1e4e4
 // --- END COPYRIGHT BLOCK ---
b1e4e4
 package com.netscape.cms.profile.common;
b1e4e4
 
b1e4e4
+import java.io.ByteArrayInputStream;
b1e4e4
+import java.io.IOException;
b1e4e4
+import java.security.cert.CertificateException;
b1e4e4
 import java.util.Enumeration;
b1e4e4
 
b1e4e4
 import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
b1e4e4
@@ -40,7 +43,9 @@ import com.netscape.certsrv.request.RequestId;
b1e4e4
 import com.netscape.certsrv.request.RequestStatus;
b1e4e4
 import com.netscape.cms.logging.Logger;
b1e4e4
 import com.netscape.cms.logging.SignedAuditLogger;
b1e4e4
+import com.netscape.cmsutil.crypto.CryptoUtil;
b1e4e4
 
b1e4e4
+import netscape.security.x509.CertificateX509Key;
b1e4e4
 import netscape.security.x509.X500Name;
b1e4e4
 import netscape.security.x509.X509CertImpl;
b1e4e4
 import netscape.security.x509.X509CertInfo;
b1e4e4
@@ -49,7 +54,7 @@ import netscape.security.x509.X509CertInfo;
b1e4e4
  * This class implements a Certificate Manager enrollment
b1e4e4
  * profile.
b1e4e4
  *
b1e4e4
- * @version $Revision$, $Date$
b1e4e4
+ * @author cfu - Server-Side Keygen Enrollment implementation
b1e4e4
  */
b1e4e4
 public class CAEnrollProfile extends EnrollProfile {
b1e4e4
 
b1e4e4
@@ -77,7 +82,7 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
 
b1e4e4
     public void execute(IRequest request)
b1e4e4
             throws EProfileException, ERejectException {
b1e4e4
-
b1e4e4
+        String method = "CAEnrollProfile: execute: ";
b1e4e4
         long startTime = CMS.getCurrentDate().getTime();
b1e4e4
 
b1e4e4
         if (!isEnable()) {
b1e4e4
@@ -99,12 +104,78 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
             throw new EProfileException("No CA Service");
b1e4e4
         }
b1e4e4
 
b1e4e4
+        //cfu: if isServerSideKeygen, send keygen request to KRA
b1e4e4
+        boolean isSSKeygen = false;
b1e4e4
+        String isSSKeygenStr = request.getExtDataInString("isServerSideKeygen");
b1e4e4
+        if (isSSKeygenStr != null && isSSKeygenStr.equalsIgnoreCase("true")) {
b1e4e4
+            CMS.debug(method + "isServerSideKeygen = true");
b1e4e4
+            isSSKeygen = true;
b1e4e4
+        } else {
b1e4e4
+            CMS.debug(method + "isServerSideKeygen = false");
b1e4e4
+        }
b1e4e4
+
b1e4e4
         // if PKI Archive Option present, send this request
b1e4e4
         // to DRM
b1e4e4
         byte optionsData[] = request.getExtDataInByteArray(REQUEST_ARCHIVE_OPTIONS);
b1e4e4
+        if (isSSKeygen) { // cfu
b1e4e4
+            request.setExtData(IRequest.SSK_STAGE, IRequest.SSK_STAGE_KEYGEN);
b1e4e4
+            try {
b1e4e4
+                IConnector kraConnector = caService.getKRAConnector();
b1e4e4
+
b1e4e4
+                if (kraConnector == null) {
b1e4e4
+                    String message = "KRA connector not configured";
b1e4e4
+                    CMS.debug(method + message);
b1e4e4
+                } else {
b1e4e4
+                    CMS.debug(method + "request");
b1e4e4
+                    kraConnector.send(request);
b1e4e4
+
b1e4e4
+                    // check response
b1e4e4
+                    if (!request.isSuccess()) {
b1e4e4
+                        String message = "serverSide Keygen request failed";
b1e4e4
+                        CMS.debug(method + message);
b1e4e4
+
b1e4e4
+                        if (getLocale(request) != null &&
b1e4e4
+                                request.getError(getLocale(request)) != null) {
b1e4e4
+
b1e4e4
+                            if ((request.getError(getLocale(request))).equals(CMS.getUserMessage("CMS_KRA_INVALID_TRANSPORT_CERT"))) { //Todo
b1e4e4
+                                CMS.debug(method + "set request status: REJECTED");
b1e4e4
+                                request.setRequestStatus(RequestStatus.REJECTED);
b1e4e4
+                                ca.getRequestQueue().updateRequest(request);
b1e4e4
+                            }
b1e4e4
+                            throw new ERejectException(
b1e4e4
+                                    request.getError(getLocale(request)));
b1e4e4
+                        } else {
b1e4e4
+                            throw new ERejectException(CMS.getUserMessage("CMS_CA_SEND_KRA_REQUEST")+ " check KRA log for detail");
b1e4e4
+                        }
b1e4e4
+                    }
b1e4e4
+/*
b1e4e4
+                        signedAuditLogger.log(SecurityDataArchivalRequestEvent.createSuccessEvent(
b1e4e4
+                                auditSubjectID,
b1e4e4
+                                auditRequesterID,
b1e4e4
+                                requestId,
b1e4e4
+                                null));
b1e4e4
+*/
b1e4e4
+                }
b1e4e4
+            } catch (Exception e) {
b1e4e4
+
b1e4e4
+                CMS.debug(method + e);
b1e4e4
+
b1e4e4
+/*
b1e4e4
+                    signedAuditLogger.log(SecurityDataArchivalRequestEvent.createFailureEvent(
b1e4e4
+                            auditSubjectID,
b1e4e4
+                            auditRequesterID,
b1e4e4
+                            requestId,
b1e4e4
+                            null,
b1e4e4
+                            e));
b1e4e4
+*/
b1e4e4
 
b1e4e4
-        // do not archive keys for renewal requests
b1e4e4
-        if ((optionsData != null) && (!request.getRequestType().equals(IRequest.RENEWAL_REQUEST))) {
b1e4e4
+                if (e instanceof ERejectException) {
b1e4e4
+                    throw (ERejectException) e;
b1e4e4
+                }
b1e4e4
+                throw new EProfileException(e);
b1e4e4
+            }
b1e4e4
+        } else if ((optionsData != null) && (!request.getRequestType().equals(IRequest.RENEWAL_REQUEST))) {
b1e4e4
+            // do not archive keys for renewal requests
b1e4e4
             PKIArchiveOptions options = toPKIArchiveOptions(optionsData);
b1e4e4
 
b1e4e4
             if (options != null) {
b1e4e4
@@ -184,6 +255,29 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
 
b1e4e4
         // process certificate issuance
b1e4e4
         X509CertInfo info = request.getExtDataInCertInfo(REQUEST_CERTINFO);
b1e4e4
+
b1e4e4
+        if (isSSKeygen) { // cfu
b1e4e4
+            try {
b1e4e4
+                String pubKeyStr = request.getExtDataInString("public_key");
b1e4e4
+                CMS.debug(method + "pubKeyStr = " + pubKeyStr);
b1e4e4
+                byte[] pubKeyB = CryptoUtil.base64Decode(pubKeyStr);
b1e4e4
+                CertificateX509Key certKey = new CertificateX509Key(
b1e4e4
+                    new ByteArrayInputStream(pubKeyB));
b1e4e4
+                Object oj = info.get(X509CertInfo.KEY);
b1e4e4
+                if (oj != null) {
b1e4e4
+                    info.delete(X509CertInfo.KEY);
b1e4e4
+                    CMS.debug(method + " fake key deleted");
b1e4e4
+                }
b1e4e4
+                info.set(X509CertInfo.KEY, certKey);
b1e4e4
+            } catch (IOException e) {
b1e4e4
+                CMS.debug(method + e);
b1e4e4
+                throw new EProfileException(e);
b1e4e4
+            } catch (CertificateException e) {
b1e4e4
+                CMS.debug(method + e);
b1e4e4
+                throw new EProfileException(e);
b1e4e4
+            }
b1e4e4
+        }
b1e4e4
+
b1e4e4
         // #615460 - added audit log (transaction)
b1e4e4
         SessionContext sc = SessionContext.getExistingContext();
b1e4e4
         sc.put("profileId", getId());
b1e4e4
@@ -209,6 +303,75 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
 
b1e4e4
         request.setExtData(REQUEST_ISSUED_CERT, theCert);
b1e4e4
 
b1e4e4
+        //cfu: cert issued, now retrieve p12
b1e4e4
+        if (isSSKeygen) {
b1e4e4
+            CMS.debug(method + "onto SSK_STAGE_KEY_RETRIEVE");
b1e4e4
+            request.setExtData(IRequest.SSK_STAGE, IRequest.SSK_STAGE_KEY_RETRIEVE);
b1e4e4
+            request.setExtData("requestType", "recovery");
b1e4e4
+            request.setExtData("cert", theCert); //recognized by kra
b1e4e4
+            try {
b1e4e4
+                IConnector kraConnector = caService.getKRAConnector();
b1e4e4
+
b1e4e4
+                if (kraConnector == null) {
b1e4e4
+                    String message = "KRA connector not configured";
b1e4e4
+                    CMS.debug(method + message);
b1e4e4
+                } else {
b1e4e4
+                    CMS.debug(method + "request");
b1e4e4
+                    kraConnector.send(request);
b1e4e4
+
b1e4e4
+                    // check response
b1e4e4
+                    if (!request.isSuccess()) {
b1e4e4
+                        String message = "serverSide Keygen request failed";
b1e4e4
+                        CMS.debug(method + message);
b1e4e4
+
b1e4e4
+                        if (getLocale(request) != null &&
b1e4e4
+                                request.getError(getLocale(request)) != null) {
b1e4e4
+
b1e4e4
+                            if ((request.getError(getLocale(request))).equals(CMS.getUserMessage("CMS_KRA_INVALID_TRANSPORT_CERT"))) { //Todo
b1e4e4
+                                CMS.debug(method + "set request status: REJECTED");
b1e4e4
+                                request.setRequestStatus(RequestStatus.REJECTED);
b1e4e4
+                                ca.getRequestQueue().updateRequest(request);
b1e4e4
+                            }
b1e4e4
+                            throw new ERejectException(
b1e4e4
+                                    request.getError(getLocale(request)));
b1e4e4
+                        } else {
b1e4e4
+                            throw new ERejectException(CMS.getUserMessage("CMS_CA_SEND_KRA_REQUEST")+ " check KRA log for detail");
b1e4e4
+                        }
b1e4e4
+                    }
b1e4e4
+/*
b1e4e4
+                        signedAuditLogger.log(SecurityDataArchivalRequestEvent.createSuccessEvent(
b1e4e4
+                                auditSubjectID,
b1e4e4
+                                auditRequesterID,
b1e4e4
+                                requestId,
b1e4e4
+                                null));
b1e4e4
+*/
b1e4e4
+                }
b1e4e4
+            } catch (Exception e) {
b1e4e4
+
b1e4e4
+                CMS.debug(method + e);
b1e4e4
+/*
b1e4e4
+                    signedAuditLogger.log(SecurityDataArchivalRequestEvent.createFailureEvent(
b1e4e4
+                            auditSubjectID,
b1e4e4
+                            auditRequesterID,
b1e4e4
+                            requestId,
b1e4e4
+                            null,
b1e4e4
+                            e));
b1e4e4
+*/
b1e4e4
+
b1e4e4
+                if (e instanceof ERejectException) {
b1e4e4
+                    throw (ERejectException) e;
b1e4e4
+                }
b1e4e4
+                throw new EProfileException(e);
b1e4e4
+            }
b1e4e4
+            CMS.debug(method + "isSSKeygen: response received from KRA");
b1e4e4
+            byte p12bytes[] = request.getExtDataInByteArray("pkcs12");
b1e4e4
+            if (p12bytes != null) {
b1e4e4
+                CMS.debug(method + "p12bytes not null");
b1e4e4
+            } else {
b1e4e4
+                CMS.debug(method + "p12bytes null");
b1e4e4
+            }
b1e4e4
+        }
b1e4e4
+
b1e4e4
         long endTime = CMS.getCurrentDate().getTime();
b1e4e4
 
b1e4e4
         String initiative = AuditFormat.FROMAGENT
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
new file mode 100644
b1e4e4
index 0000000..e82ee24
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
@@ -0,0 +1,385 @@
b1e4e4
+// --- BEGIN COPYRIGHT BLOCK ---
b1e4e4
+// This program is free software; you can redistribute it and/or modify
b1e4e4
+// it under the terms of the GNU General Public License as published by
b1e4e4
+// the Free Software Foundation; version 2 of the License.
b1e4e4
+//
b1e4e4
+// This program is distributed in the hope that it will be useful,
b1e4e4
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
b1e4e4
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b1e4e4
+// GNU General Public License for more details.
b1e4e4
+//
b1e4e4
+// You should have received a copy of the GNU General Public License along
b1e4e4
+// with this program; if not, write to the Free Software Foundation, Inc.,
b1e4e4
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b1e4e4
+//
b1e4e4
+// (C) 2007 Red Hat, Inc.
b1e4e4
+// All rights reserved.
b1e4e4
+// --- END COPYRIGHT BLOCK ---
b1e4e4
+package com.netscape.cms.profile.def;
b1e4e4
+
b1e4e4
+import java.io.ByteArrayInputStream;
b1e4e4
+import java.math.BigInteger;
b1e4e4
+import java.security.interfaces.DSAParams;
b1e4e4
+import java.util.Locale;
b1e4e4
+import java.util.Vector;
b1e4e4
+import java.security.KeyPair;
b1e4e4
+import java.security.PublicKey;
b1e4e4
+
b1e4e4
+import netscape.security.provider.DSAPublicKey;
b1e4e4
+import netscape.security.provider.RSAPublicKey;
b1e4e4
+import netscape.security.x509.AlgorithmId;
b1e4e4
+import netscape.security.x509.CertificateX509Key;
b1e4e4
+import netscape.security.x509.X509CertImpl;
b1e4e4
+import netscape.security.x509.X509CertInfo;
b1e4e4
+import netscape.security.x509.X509Key;
b1e4e4
+
b1e4e4
+import com.netscape.certsrv.apps.CMS;
b1e4e4
+import com.netscape.certsrv.base.IConfigStore;
b1e4e4
+import com.netscape.certsrv.profile.EProfileException;
b1e4e4
+import com.netscape.certsrv.profile.IEnrollProfile;
b1e4e4
+import com.netscape.certsrv.profile.IProfile;
b1e4e4
+import com.netscape.certsrv.property.Descriptor;
b1e4e4
+import com.netscape.certsrv.property.EPropertyException;
b1e4e4
+import com.netscape.certsrv.property.IDescriptor;
b1e4e4
+import com.netscape.certsrv.request.IRequest;
b1e4e4
+import com.netscape.cmsutil.crypto.CryptoUtil;
b1e4e4
+import com.netscape.cmsutil.util.Utils;
b1e4e4
+
b1e4e4
+import org.mozilla.jss.CryptoManager;
b1e4e4
+import org.mozilla.jss.crypto.CryptoToken;
b1e4e4
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
b1e4e4
+import org.mozilla.jss.crypto.IVParameterSpec;
b1e4e4
+import org.mozilla.jss.crypto.KeyGenAlgorithm;
b1e4e4
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
b1e4e4
+import org.mozilla.jss.crypto.SymmetricKey;
b1e4e4
+import org.mozilla.jss.crypto.X509Certificate;
b1e4e4
+
b1e4e4
+/**
b1e4e4
+ * This class implements an enrollment default policy
b1e4e4
+ * for Server-Side keygen enrollment.
b1e4e4
+ * It accepts usre-supplied key type and size to be passed onto KRA
b1e4e4
+ *
b1e4e4
+ * @author Christina Fu
b1e4e4
+ */
b1e4e4
+public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
+
b1e4e4
+    public static final String CONFIG_LEN = "keySize";
b1e4e4
+    public static final String CONFIG_TYPE = "keyType";
b1e4e4
+    public static final String VAL_LEN = "LEN";
b1e4e4
+    public static final String VAL_TYPE = "TYPE";
b1e4e4
+
b1e4e4
+    private static final String TEMP_PUBKEY_1024 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBz6H2rT2r1RpHdr3JyYr7thSjfwWPbIJ6U09NziHSekLsNZQKsjdLS/LPCfe/aXkhpzPztlx++tkPucpt/xT0exp08feAPIE+Y6gVoyXzEw+Ztz+Zez9Y1cQWxAyp7z11flytjL+4zBGDXmEoe3ZlQvij9DGypPjBC9PhWm0lBwIDAQAB";
b1e4e4
+    private static final String TEMP_PUBKEY_2048 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4Ha+CxWDPAHEl9+u57U3UCw8bfG/ZN3cVTrQgj/p8ak12NYUWt0ZI/xCcLj7gKwFPbNMTDwzizRPZuxKJT7fHgW8a1BQDUL2VGfx7O0A7KlLqcpVc6VKsQx5caP3hrB38Q5xnTKeVee9cBrd8An+veZ2QV6mHLEU8iMCN2No/t1oO+aYje42XloNRblXVQAOYW+3aMCam2kIKWUqLvA3Sbf2BPR2x5SSZRPHJt3hQCheara5j+nHLQ8paRvVlT+ghgyX5N3BwiPmvC+e9iUaaofj+DxrGX3cTo5hehG2b71sY3xdC5OIhEGRfkAqIAEw6eaU6a/ymNsByRgVByfQaQIDAQAB";
b1e4e4
+    private static final String TEMP_PUBKEY_3072 = "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAm0yQ0y+8YOTWkye5qFuqNI/qC4wtjEjNnoZaqSZUOJLg6ZRDlsZoOiblJpw65rPjaPcSp/inqYfCCA5mISYaqfcoB80LCnw1+DAv8tcvwUtytQYXHVj2gbyuVHaBgD4n4j/wFV80sF3OTQcPKYmeTfWRtv2xZQMK9rYfa8Le+DAZyOWPk4+RtTIRPa5R9arLqE+ONgUcrD3NvewOdsCrT7flJnFdx8TGl5ftxVWYlHRSg+wEB8pQZlw0BSDlQGHXIRjBKT2+iCkYzuKPWpMbu42PnBaQTcvjD3cl8MjLQcZp6v39bU1Du0C0LYunhvIWidwKnCOGOYu+a0VKuHxH8odjFdPoWGmP+orllkwSZzhWayYJxGpJJQlWcM05uD6qDF67WQnuYsliVH4LNiSjf/iPSpr0tzDXOtdeVsiQgO9wYYlnooBtd1xfTmkILwt3j9ZXeBtmt4lLYxbLo2ZCzkFqCCdu5FfcFgxjPaRaW0bQHKuP1woGk0rDUUbuqr+PAgMBAAE=";
b1e4e4
+    private static final String TEMP_PUBKEY_4096 = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs3xoddtoCQrDpPK/45DpN/wPHO/6qrsbEDnwEnSkcLz51WHb7+CEUP9oxuE8vPn9JXcLdZkgPcmfMVibSUEJVUCXPibGTqAJ/7RAAm+/FhdL02N57hpgLzbIPbIaTP00z/jbTqR4a0uV49fnEPqrhA/KoUmOn3eoiAPAB5xNSauFOmMZXv2gr4akNxvSiZ/59ddYF+DBEFSs4ufCqIqBWYAMMo78eskgm/ZUyv7OZzG+8c1nncdnrNk/JtXauANu8NUQXX2qllmEOioY6gnalpR26fwOscjkvHDTvRQmSIqceWdd5P6OMHJwzTVG8d4b0f150o1RTzU3gvg9/qXvbOGcnH2TXZjYi02mhyXgPrimZepKyDr2LjeAEZbfAAXecaMhjrDZEkDZNFWe4eoG2JuE34TODeiCLMBql6VTgOvCFW3to32aBwNLpCV4hi5rKLnPMlf8Tz0zYvGqDeCp4zzy6C9tosiYfHIkVU/AVqK9PoY0RsLnBzHOV7Jl2VgHr8Ro+C66+leajssAemK8swcj2AZEOuVLlsdCvguUn6XUyDqI3tIfnoLK690hG1znuIWzFZzzivZ5ZwgfxguCly9zDArc7i6YHxOR2lcUrM0VfHmyHpE9JNfarEgAPS59ASG7y14LOvp4yYKNz10TtetwkSfpcjqiuWHtIDi9sjMCAwEAAQ==";
b1e4e4
+
b1e4e4
+    public ServerKeygenUserKeyDefault() {
b1e4e4
+        super();
b1e4e4
+        addConfigName(CONFIG_TYPE);
b1e4e4
+        addConfigName(CONFIG_LEN);
b1e4e4
+        addValueName(VAL_TYPE);
b1e4e4
+        addValueName(VAL_LEN);
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public void init(IProfile profile, IConfigStore config)
b1e4e4
+            throws EProfileException {
b1e4e4
+        super.init(profile, config);
b1e4e4
+    }
b1e4e4
+
b1e4e4
+/*
b1e4e4
+    public void setConfig(String name, String value)
b1e4e4
+            throws EPropertyException {
b1e4e4
+        super.setConfig(name, value);
b1e4e4
+    }
b1e4e4
+*/
b1e4e4
+
b1e4e4
+    public IDescriptor getConfigDescriptor(Locale locale, String name) {
b1e4e4
+        if (name.equals(CONFIG_TYPE)) {
b1e4e4
+            return new Descriptor(IDescriptor.STRING,
b1e4e4
+                    null,
b1e4e4
+                    "RSA",
b1e4e4
+                    CMS.getUserMessage(locale,
b1e4e4
+                            "CMS_PROFILE_SERVER_KEYGEN_KEYTYPE"));
b1e4e4
+        } else if (name.equals(CONFIG_LEN)) {
b1e4e4
+            return new Descriptor(IDescriptor.STRING,
b1e4e4
+                    null,
b1e4e4
+                    "2048",
b1e4e4
+                    CMS.getUserMessage(locale,
b1e4e4
+                            "CMS_PROFILE_SERVER_KEYGEN_KEYSIZE"));
b1e4e4
+        } else  {
b1e4e4
+            return null;
b1e4e4
+        }
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public IDescriptor getValueDescriptor(Locale locale, String name) {
b1e4e4
+        if (name.equals(VAL_LEN)) {
b1e4e4
+            return new Descriptor(IDescriptor.STRING,
b1e4e4
+                    IDescriptor.READONLY,
b1e4e4
+                    null,
b1e4e4
+                    CMS.getUserMessage(locale, "CMS_PROFILE_KEY_LEN"));
b1e4e4
+        } else if (name.equals(VAL_TYPE)) {
b1e4e4
+            return new Descriptor(IDescriptor.STRING,
b1e4e4
+                    IDescriptor.READONLY,
b1e4e4
+                    null,
b1e4e4
+                    CMS.getUserMessage(locale, "CMS_PROFILE_KEY_TYPE"));
b1e4e4
+        } else {
b1e4e4
+            return null;
b1e4e4
+        }
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public void setValue(String name, Locale locale,
b1e4e4
+            X509CertInfo info, String value)
b1e4e4
+            throws EPropertyException {
b1e4e4
+        // this default rule is readonly
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public String getValue(String name, Locale locale,
b1e4e4
+            X509CertInfo info)
b1e4e4
+            throws EPropertyException {
b1e4e4
+        CMS.debug("ServerKeygenUserKeyDefault: getValue name=" + name);
b1e4e4
+        if (name == null) {
b1e4e4
+            throw new EPropertyException(CMS.getUserMessage(
b1e4e4
+                        locale, "CMS_INVALID_PROPERTY", name));
b1e4e4
+        }
b1e4e4
+
b1e4e4
+        if (name.equals(VAL_LEN)) {
b1e4e4
+            CertificateX509Key ck = null;
b1e4e4
+
b1e4e4
+            try {
b1e4e4
+                ck = (CertificateX509Key)
b1e4e4
+                        info.get(X509CertInfo.KEY);
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                // nothing
b1e4e4
+            }
b1e4e4
+            X509Key k = null;
b1e4e4
+
b1e4e4
+            try {
b1e4e4
+                k = (X509Key)
b1e4e4
+                        ck.get(CertificateX509Key.KEY);
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                // nothing
b1e4e4
+            }
b1e4e4
+            if (k == null) {
b1e4e4
+                throw new EPropertyException(CMS.getUserMessage(
b1e4e4
+                            locale, "CMS_PROFILE_KEY_NOT_FOUND"));
b1e4e4
+            }
b1e4e4
+            try {
b1e4e4
+                if (k.getAlgorithm().equals("RSA")) {
b1e4e4
+                    return Integer.toString(getRSAKeyLen(k));
b1e4e4
+                } else if (k.getAlgorithm().equals("EC")) {
b1e4e4
+                    Vector<String> vect = CryptoUtil.getECKeyCurve(k);
b1e4e4
+                    if (vect != null)
b1e4e4
+                        return vect.toString();
b1e4e4
+                    else
b1e4e4
+                        return null;
b1e4e4
+                } else {
b1e4e4
+                    return Integer.toString(getDSAKeyLen(k));
b1e4e4
+                }
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                CMS.debug("ServerKeygenUserKeyDefault: getValue " + e.toString());
b1e4e4
+                throw new EPropertyException(CMS.getUserMessage(
b1e4e4
+                            locale, "CMS_INVALID_PROPERTY", name));
b1e4e4
+            }
b1e4e4
+        } else if (name.equals(VAL_TYPE)) {
b1e4e4
+            CertificateX509Key ck = null;
b1e4e4
+
b1e4e4
+            try {
b1e4e4
+                ck = (CertificateX509Key)
b1e4e4
+                        info.get(X509CertInfo.KEY);
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                // nothing
b1e4e4
+            }
b1e4e4
+            X509Key k = null;
b1e4e4
+
b1e4e4
+            try {
b1e4e4
+                k = (X509Key)
b1e4e4
+                        ck.get(CertificateX509Key.KEY);
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                // nothing
b1e4e4
+            }
b1e4e4
+            if (k == null) {
b1e4e4
+                throw new EPropertyException(CMS.getUserMessage(
b1e4e4
+                            locale, "CMS_PROFILE_KEY_NOT_FOUND"));
b1e4e4
+            }
b1e4e4
+            return k.getAlgorithm() + " - " +
b1e4e4
+                    k.getAlgorithmId().getOID().toString();
b1e4e4
+        } else {
b1e4e4
+            throw new EPropertyException(CMS.getUserMessage(
b1e4e4
+                        locale, "CMS_INVALID_PROPERTY", name));
b1e4e4
+        }
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public String getText(Locale locale) {
b1e4e4
+        String params[] = {
b1e4e4
+                getConfig(CONFIG_TYPE),
b1e4e4
+                getConfig(CONFIG_LEN)
b1e4e4
+            };
b1e4e4
+        CMS.debug("ServerKeygenUserKeyDefault: getText ");
b1e4e4
+        if (locale == null)
b1e4e4
+            CMS.debug("ServerKeygenUserKeyDefault: getText: locale null ");
b1e4e4
+
b1e4e4
+        return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_SERVER_KEYGEN_USER_KEY_INFO", params);
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public int getRSAKeyLen(X509Key key) throws Exception {
b1e4e4
+        X509Key newkey = null;
b1e4e4
+
b1e4e4
+        try {
b1e4e4
+            newkey = new X509Key(AlgorithmId.get("RSA"),
b1e4e4
+                        key.getKey());
b1e4e4
+        } catch (Exception e) {
b1e4e4
+            CMS.debug("ServerKeygenUserKeyDefault: getRSAKey " + e.toString());
b1e4e4
+            throw e;
b1e4e4
+        }
b1e4e4
+        RSAPublicKey rsaKey = new RSAPublicKey(newkey.getEncoded());
b1e4e4
+
b1e4e4
+        return rsaKey.getKeySize();
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public int getDSAKeyLen(X509Key key) throws Exception {
b1e4e4
+        // Check DSAKey parameters.
b1e4e4
+        // size refers to the p parameter.
b1e4e4
+        DSAPublicKey dsaKey = new DSAPublicKey(key.getEncoded());
b1e4e4
+        DSAParams keyParams = dsaKey.getParams();
b1e4e4
+        BigInteger p = keyParams.getP();
b1e4e4
+        int len = p.bitLength();
b1e4e4
+
b1e4e4
+        return len;
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Populates the request with this policy default.
b1e4e4
+     */
b1e4e4
+    public void populate(IRequest request, X509CertInfo info)
b1e4e4
+            throws EProfileException {
b1e4e4
+        CertificateX509Key certKey = null;
b1e4e4
+        String method = "ServerKeygenUserKeyDefault: populate: ";
b1e4e4
+        CMS.debug(method + "in here");
b1e4e4
+
b1e4e4
+        // trigger serverSide keygen enrollment
b1e4e4
+        try {
b1e4e4
+            // Todo: remove debug test print; encrypt the passwd
b1e4e4
+            String p12passwd = request.getExtDataInString("serverSideKeygenP12Passwd");
b1e4e4
+            if (p12passwd == null || p12passwd.length() == 0) {
b1e4e4
+                CMS.debug(method + "p12passwd not found");
b1e4e4
+                throw new EPropertyException(CMS.getUserMessage("CMS_PASSWORD_EMPTY_PASSWORD"));
b1e4e4
+            }
b1e4e4
+
b1e4e4
+            // Encrypt the password before putting it back in
b1e4e4
+            String transportCertStr = null;
b1e4e4
+            CryptoManager cm = CryptoManager.getInstance();
b1e4e4
+            org.mozilla.jss.crypto.X509Certificate transCert = null;
b1e4e4
+            try {
b1e4e4
+                transCert = cm.findCertByNickname("KRA Transport Certificate");
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                CMS.debug(method + "'KRA transport certificate' not found in nssdb; need to be manually setup for Server-Side keygen enrollment");
b1e4e4
+                throw new EPropertyException(CMS.getUserMessage("CMS_MISSING_KRA_TRANSPORT_CERT_IN_CA_NSSDB"));
b1e4e4
+
b1e4e4
+                /* future; cert nickname can't be controlled yet at import in jss
b1e4e4
+                CMS.debug(method + "KRA transport certificate not found in nssdb; getting from CS.cfg");
b1e4e4
+                transportCertStr = CMS.getConfigStore().getString("ca.connector.KRA.transportCert", "");
b1e4e4
+                CMS.debug(method + "transportCert found in CS.cfg: " + transportCertStr);
b1e4e4
+
b1e4e4
+                byte[] transportCertB = Utils.base64decode(transportCertStr);
b1e4e4
+                CMS.debug(method + "transportCertB.length=" + transportCertB.length);
b1e4e4
+                // hmmm, can't yet control the nickname
b1e4e4
+                transCert = cm.importCACertPackage(transportCertB);
b1e4e4
+                CMS.debug(method + "KRA transport certificate imported");
b1e4e4
+                */
b1e4e4
+            }
b1e4e4
+
b1e4e4
+            {
b1e4e4
+                // todo: make things configurable in CS.cfg or profile
b1e4e4
+                CryptoToken ct =
b1e4e4
+                    CryptoUtil.getCryptoToken(CryptoUtil.INTERNAL_TOKEN_NAME);
b1e4e4
+                if (ct == null)
b1e4e4
+                    CMS.debug(method + "crypto token null");
b1e4e4
+
b1e4e4
+                EncryptionAlgorithm encryptAlgorithm =
b1e4e4
+                        EncryptionAlgorithm.AES_128_CBC_PAD;
b1e4e4
+                KeyWrapAlgorithm wrapAlgorithm = KeyWrapAlgorithm.RSA;
b1e4e4
+
b1e4e4
+                SymmetricKey sessionKey = CryptoUtil.generateKey(
b1e4e4
+                        ct,
b1e4e4
+                        KeyGenAlgorithm.AES,
b1e4e4
+                        128,
b1e4e4
+                        null,
b1e4e4
+                        true);
b1e4e4
+
b1e4e4
+                byte[] iv = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
b1e4e4
+                byte[] sessionWrappedPassphrase = CryptoUtil.encryptUsingSymmetricKey(
b1e4e4
+                        ct,
b1e4e4
+                        sessionKey,
b1e4e4
+                        p12passwd.getBytes("UTF-8"),
b1e4e4
+                        encryptAlgorithm,
b1e4e4
+                        new IVParameterSpec(iv));
b1e4e4
+
b1e4e4
+                CMS.debug(method + "sessionWrappedPassphrase.length=" + sessionWrappedPassphrase.length);
b1e4e4
+
b1e4e4
+                byte[] transWrappedSessionKey = CryptoUtil.wrapUsingPublicKey(
b1e4e4
+                        ct,
b1e4e4
+                        transCert.getPublicKey(),
b1e4e4
+                        sessionKey,
b1e4e4
+                        wrapAlgorithm);
b1e4e4
+                CMS.debug(method + " transWrappedSessionKey.length =" +transWrappedSessionKey.length);
b1e4e4
+
b1e4e4
+                // store in request to pass to kra
b1e4e4
+                request.setExtData("serverSideKeygenP12PasswdEnc",
b1e4e4
+                        sessionWrappedPassphrase);
b1e4e4
+                request.setExtData("serverSideKeygenP12PasswdTransSession",
b1e4e4
+                        transWrappedSessionKey);
b1e4e4
+                // delete the plain text one
b1e4e4
+                request.deleteExtData("serverSideKeygenP12Passwd");
b1e4e4
+            }
b1e4e4
+
b1e4e4
+            //
b1e4e4
+            request.setExtData("isServerSideKeygen", "true");
b1e4e4
+            CryptoToken token = cm.getInternalKeyStorageToken();
b1e4e4
+
b1e4e4
+            String keySizeStr = request.getExtDataInString("keySize");
b1e4e4
+            int keySize = 1024;
b1e4e4
+            if (keySizeStr != null) {
b1e4e4
+                CMS.debug("ServerKeygenUserKeyDefault: populate: keySize in request: " + keySizeStr);
b1e4e4
+                keySize = Integer.parseInt(keySizeStr);
b1e4e4
+            } else {
b1e4e4
+                CMS.debug("ServerKeygenUserKeyDefault: populate: keySize in request null;  default to 2048");
b1e4e4
+            }
b1e4e4
+            request.setExtData(IRequest.KEY_GEN_ALGORITHM, "RSA");
b1e4e4
+            request.setExtData(IRequest.KEY_GEN_SIZE, keySize);
b1e4e4
+
b1e4e4
+            /*
b1e4e4
+             * it is necessary to  put in a static fake key here to prevent
b1e4e4
+             * issue; The fake key will be replaced later once KRA generates
b1e4e4
+             * the real keys
b1e4e4
+             */
b1e4e4
+            String pubKeyStr = "";
b1e4e4
+            switch (keySize) {
b1e4e4
+                case 1024:
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_1024;
b1e4e4
+                    break;
b1e4e4
+                case 2048:
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_2048;
b1e4e4
+                    break;
b1e4e4
+                case 3072:
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_3072;
b1e4e4
+                    break;
b1e4e4
+                case 4096:
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_4096;
b1e4e4
+                    break;
b1e4e4
+                default:
b1e4e4
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: unsupported keySize: " + keySize);
b1e4e4
+                    break;
b1e4e4
+            }
b1e4e4
+            byte[] certKeyData = CryptoUtil.base64Decode(pubKeyStr);
b1e4e4
+            if (certKeyData != null) {
b1e4e4
+                certKey = new CertificateX509Key(
b1e4e4
+                        new ByteArrayInputStream(certKeyData));
b1e4e4
+            } else {
b1e4e4
+                CMS.debug("ServerKeygenUserKeyDefault: populate: serverKeygen to be implemented ");
b1e4e4
+            }
b1e4e4
+            info.set(X509CertInfo.KEY, certKey);
b1e4e4
+        } catch (Exception e) {
b1e4e4
+            CMS.debug("ServerKeygenUserKeyDefault: populate " + e.toString());
b1e4e4
+        }
b1e4e4
+    }
b1e4e4
+}
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java b/base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java
b1e4e4
new file mode 100644
b1e4e4
index 0000000..fb460d0
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java
b1e4e4
@@ -0,0 +1,115 @@
b1e4e4
+// --- BEGIN COPYRIGHT BLOCK ---
b1e4e4
+// This program is free software; you can redistribute it and/or modify
b1e4e4
+// it under the terms of the GNU General Public License as published by
b1e4e4
+// the Free Software Foundation; version 2 of the License.
b1e4e4
+//
b1e4e4
+// This program is distributed in the hope that it will be useful,
b1e4e4
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
b1e4e4
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b1e4e4
+// GNU General Public License for more details.
b1e4e4
+//
b1e4e4
+// You should have received a copy of the GNU General Public License along
b1e4e4
+// with this program; if not, write to the Free Software Foundation, Inc.,
b1e4e4
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b1e4e4
+//
b1e4e4
+// (C) 2020 Red Hat, Inc.
b1e4e4
+// All rights reserved.
b1e4e4
+// --- END COPYRIGHT BLOCK ---
b1e4e4
+package com.netscape.cms.profile.input;
b1e4e4
+
b1e4e4
+import java.util.Locale;
b1e4e4
+import java.util.Map;
b1e4e4
+
b1e4e4
+import com.netscape.certsrv.apps.CMS;
b1e4e4
+import com.netscape.certsrv.base.IConfigStore;
b1e4e4
+import com.netscape.certsrv.profile.EProfileException;
b1e4e4
+import com.netscape.certsrv.property.Descriptor;
b1e4e4
+import com.netscape.certsrv.property.IDescriptor;
b1e4e4
+import com.netscape.certsrv.request.IRequest;
b1e4e4
+import com.netscape.certsrv.profile.IProfile;
b1e4e4
+import com.netscape.certsrv.profile.IProfileContext;
b1e4e4
+import com.netscape.certsrv.profile.IProfileInput;
b1e4e4
+
b1e4e4
+/**
b1e4e4
+ * This class implements input for the Server-Side Keygen Enrollment
b1e4e4
+ * 

b1e4e4
+ *
b1e4e4
+ * @author Christina Fu
b1e4e4
+ */
b1e4e4
+public class ServerKeygenInput extends EnrollInput implements IProfileInput {
b1e4e4
+
b1e4e4
+    public static final String P12PASSWORD = "serverSideKeygenP12Passwd";
b1e4e4
+/*
b1e4e4
+    public static final String KEY_TYPE = "keyType";
b1e4e4
+    public static final String KEY_SIZE = "keySize";
b1e4e4
+*/
b1e4e4
+
b1e4e4
+    public ServerKeygenInput() {
b1e4e4
+        addValueName(P12PASSWORD);
b1e4e4
+/*
b1e4e4
+        addValueName(KEY_TYPE);
b1e4e4
+        addValueName(KEY_SIZE);
b1e4e4
+*/
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Initializes this default policy.
b1e4e4
+     */
b1e4e4
+    public void init(IProfile profile, IConfigStore config)
b1e4e4
+            throws EProfileException {
b1e4e4
+        super.init(profile, config);
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Retrieves the localizable name of this policy.
b1e4e4
+     */
b1e4e4
+    public String getName(Locale locale) {
b1e4e4
+        return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SERVER_KEYGEN_NAME");
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Retrieves the localizable description of this policy.
b1e4e4
+     */
b1e4e4
+    public String getText(Locale locale) {
b1e4e4
+        return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SERVER_KEYGEN_TEXT");
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public String getConfig(String name) {
b1e4e4
+        String config = super.getConfig(name);
b1e4e4
+        if (config == null || config.equals(""))
b1e4e4
+            return "true";
b1e4e4
+        return config;
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Populates the request with this policy default.
b1e4e4
+     */
b1e4e4
+    public void populate(IProfileContext ctx, IRequest request)
b1e4e4
+            throws EProfileException {
b1e4e4
+        //
b1e4e4
+        CMS.debug("ServerKeygenP12PasswordInput:populate: cfu");
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Retrieves the descriptor of the given value
b1e4e4
+     * parameter by name.
b1e4e4
+     */
b1e4e4
+    public IDescriptor getValueDescriptor(Locale locale, String name) {
b1e4e4
+        if (name.equals(P12PASSWORD)) {
b1e4e4
+            return new Descriptor(IDescriptor.SERVER_SIDE_KEYGEN_REQUEST_TYPE, null,
b1e4e4
+                    null,
b1e4e4
+                    CMS.getUserMessage(locale, "CMS_PROFILE_SERVER_KEYGEN_P12PASSWD"));
b1e4e4
+/*
b1e4e4
+        } else if (name.equals(KEY_TYPE)) {
b1e4e4
+            return new Descriptor(IDescriptor.STRING, null,
b1e4e4
+                    null,
b1e4e4
+                    CMS.getUserMessage(locale, "CMS_PROFILE_SERVER_KEYGEN_KEY_TYPE"));
b1e4e4
+        } else if (name.equals(KEY_SIZE)) {
b1e4e4
+            return new Descriptor(IDescriptor.STRING, null,
b1e4e4
+                    null,
b1e4e4
+                    CMS.getUserMessage(locale, "CMS_PROFILE_SERVER_KEYGEN_KEY_SIZE"));
b1e4e4
+*/
b1e4e4
+        }
b1e4e4
+        return null;
b1e4e4
+    }
b1e4e4
+}
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/output/PKCS12Output.java b/base/server/cms/src/com/netscape/cms/profile/output/PKCS12Output.java
b1e4e4
new file mode 100644
b1e4e4
index 0000000..837fdc9
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/output/PKCS12Output.java
b1e4e4
@@ -0,0 +1,110 @@
b1e4e4
+// --- BEGIN COPYRIGHT BLOCK ---
b1e4e4
+// This program is free software; you can redistribute it and/or modify
b1e4e4
+// it under the terms of the GNU General Public License as published by
b1e4e4
+// the Free Software Foundation; version 2 of the License.
b1e4e4
+//
b1e4e4
+// This program is distributed in the hope that it will be useful,
b1e4e4
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
b1e4e4
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b1e4e4
+// GNU General Public License for more details.
b1e4e4
+//
b1e4e4
+// You should have received a copy of the GNU General Public License along
b1e4e4
+// with this program; if not, write to the Free Software Foundation, Inc.,
b1e4e4
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b1e4e4
+//
b1e4e4
+// (C) 2020 Red Hat, Inc.
b1e4e4
+// All rights reserved.
b1e4e4
+// --- END COPYRIGHT BLOCK ---
b1e4e4
+package com.netscape.cms.profile.output;
b1e4e4
+
b1e4e4
+import java.io.ByteArrayOutputStream;
b1e4e4
+import java.security.cert.X509Certificate;
b1e4e4
+import java.util.Locale;
b1e4e4
+import java.util.Map;
b1e4e4
+
b1e4e4
+import org.mozilla.jss.asn1.INTEGER;
b1e4e4
+import org.mozilla.jss.netscape.security.util.Utils;
b1e4e4
+import org.mozilla.jss.netscape.security.x509.CertificateChain;
b1e4e4
+import org.mozilla.jss.netscape.security.x509.X509CertImpl;
b1e4e4
+
b1e4e4
+import com.netscape.certsrv.ca.ICertificateAuthority;
b1e4e4
+import com.netscape.certsrv.apps.CMS;
b1e4e4
+import com.netscape.certsrv.profile.EProfileException;
b1e4e4
+import com.netscape.certsrv.profile.IProfile;
b1e4e4
+import com.netscape.certsrv.profile.IProfileContext;
b1e4e4
+import com.netscape.certsrv.profile.IProfileOutput;
b1e4e4
+import com.netscape.certsrv.property.Descriptor;
b1e4e4
+import com.netscape.certsrv.property.IDescriptor;
b1e4e4
+import com.netscape.certsrv.request.IRequest;
b1e4e4
+import com.netscape.cms.profile.common.EnrollProfile;
b1e4e4
+import com.netscape.cmsutil.crypto.CryptoUtil;
b1e4e4
+
b1e4e4
+/**
b1e4e4
+ * This class implements the output plugin that outputs
b1e4e4
+ * PKCS12 response for the issued certificate for Server-side keygen enrollment.
b1e4e4
+ *
b1e4e4
+ * Christina Fu
b1e4e4
+ */
b1e4e4
+public class PKCS12Output extends EnrollOutput {
b1e4e4
+
b1e4e4
+    public static final String VAL_P12_RESPONSE = "p12_response";
b1e4e4
+
b1e4e4
+    public PKCS12Output() {
b1e4e4
+        addValueName(VAL_P12_RESPONSE);
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Retrieves the localizable name of this policy.
b1e4e4
+     */
b1e4e4
+    public String getName(Locale locale) {
b1e4e4
+        return CMS.getUserMessage(locale, "CMS_PROFILE_OUTPUT_PKCS12");
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Retrieves the localizable description of this policy.
b1e4e4
+     */
b1e4e4
+    public String getText(Locale locale) {
b1e4e4
+        return CMS.getUserMessage(locale, "CMS_PROFILE_OUTPUT_PKCS12_TEXT");
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Populates the request with this policy default.
b1e4e4
+     */
b1e4e4
+    public void populate(IProfileContext ctx, IRequest request)
b1e4e4
+            throws EProfileException {
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    /**
b1e4e4
+     * Retrieves the descriptor of the given value
b1e4e4
+     * parameter by name.
b1e4e4
+     */
b1e4e4
+    public IDescriptor getValueDescriptor(Locale locale, String name) {
b1e4e4
+        if (name.equals(VAL_P12_RESPONSE)) {
b1e4e4
+            return new Descriptor(IDescriptor.SERVER_SIDE_KEYGEN_PKCS12, null,
b1e4e4
+                    null,
b1e4e4
+                    CMS.getUserMessage(locale,
b1e4e4
+                            "CMS_PROFILE_OUTPUT_PKCS12"));
b1e4e4
+        }
b1e4e4
+        return null;
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public String getValue(String name, Locale locale, IRequest request)
b1e4e4
+            throws EProfileException {
b1e4e4
+
b1e4e4
+        if (name.equals(VAL_P12_RESPONSE)) {
b1e4e4
+            try {
b1e4e4
+                byte pkcs12[] = request.getExtDataInByteArray(
b1e4e4
+                        EnrollProfile.REQUEST_ISSUED_P12);
b1e4e4
+                if (pkcs12 != null) {
b1e4e4
+                    CMS.debug("PKCS12Output:getValue: found p12");
b1e4e4
+                    String pkcs12Str = Utils.base64encodeSingleLine(pkcs12);
b1e4e4
+                    return pkcs12Str;
b1e4e4
+                }
b1e4e4
+            } catch (Exception e) {
b1e4e4
+                return null;
b1e4e4
+            }
b1e4e4
+        }
b1e4e4
+        return null;
b1e4e4
+    }
b1e4e4
+
b1e4e4
+}
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
b1e4e4
index 0c65702..145fd5f 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
b1e4e4
@@ -573,6 +573,7 @@ public abstract class CMSServlet extends HttpServlet {
b1e4e4
 
b1e4e4
     protected void outputArgBlockAsXML(XMLObject xmlObj, Node parent,
b1e4e4
                                        String argBlockName, IArgBlock argBlock) {
b1e4e4
+        CMS.debug("CMSServlet:outputArgBlockAsXML: begins");
b1e4e4
         Node argBlockContainer = xmlObj.createContainer(parent, argBlockName);
b1e4e4
 
b1e4e4
         if (argBlock != null) {
b1e4e4
@@ -584,9 +585,11 @@ public abstract class CMSServlet extends HttpServlet {
b1e4e4
                 xmlObj.addItemToContainer(argBlockContainer, name, val);
b1e4e4
             }
b1e4e4
         }
b1e4e4
+        CMS.debug("CMSServlet:outputArgBlockAsXML: ends");
b1e4e4
     }
b1e4e4
 
b1e4e4
     protected void outputXML(HttpServletResponse httpResp, CMSTemplateParams params) {
b1e4e4
+        CMS.debug("CMSServlet:outputXML: begins");
b1e4e4
         XMLObject xmlObj = null;
b1e4e4
         try {
b1e4e4
             xmlObj = new XMLObject();
b1e4e4
@@ -613,6 +616,7 @@ public abstract class CMSServlet extends HttpServlet {
b1e4e4
         } catch (Exception e) {
b1e4e4
             CMS.debug("failed in outputing XML " + e);
b1e4e4
         }
b1e4e4
+        CMS.debug("CMSServlet:outputXML: ends");
b1e4e4
     }
b1e4e4
 
b1e4e4
     protected void renderTemplate(
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
b1e4e4
index 8741a75..b369fc8 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
b1e4e4
@@ -28,6 +28,7 @@ import java.security.cert.Certificate;
b1e4e4
 import java.security.cert.CertificateException;
b1e4e4
 import java.security.cert.X509Certificate;
b1e4e4
 import java.util.Enumeration;
b1e4e4
+import java.util.Hashtable;
b1e4e4
 
b1e4e4
 import javax.servlet.ServletConfig;
b1e4e4
 import javax.servlet.ServletException;
b1e4e4
@@ -62,6 +63,7 @@ import com.netscape.certsrv.request.RequestId;
b1e4e4
 import com.netscape.certsrv.request.RequestStatus;
b1e4e4
 import com.netscape.cms.servlet.base.CMSServlet;
b1e4e4
 import com.netscape.cms.servlet.common.CMSRequest;
b1e4e4
+//import com.netscape.kra.RecoveryService;
b1e4e4
 
b1e4e4
 import netscape.security.x509.CRLExtensions;
b1e4e4
 import netscape.security.x509.CRLReasonExtension;
b1e4e4
@@ -81,7 +83,7 @@ import netscape.security.x509.X509CertInfo;
b1e4e4
  * process requests from remote authority -
b1e4e4
  * service request or return status.
b1e4e4
  *
b1e4e4
- * @version $Revision$, $Date$
b1e4e4
+ * @author cfu - Server-Side Keygen Enrollment implementation
b1e4e4
  */
b1e4e4
 public class ConnectorServlet extends CMSServlet {
b1e4e4
 
b1e4e4
@@ -506,8 +508,27 @@ public class ConnectorServlet extends CMSServlet {
b1e4e4
                 }
b1e4e4
             }
b1e4e4
 
b1e4e4
-            // if not found process request.
b1e4e4
+/*
b1e4e4
+            // cfu: let's find out what's in the request
b1e4e4
+            Enumeration<String> ereq = thisreq.getExtDataKeys();
b1e4e4
+
b1e4e4
+            while (ereq.hasMoreElements()) {
b1e4e4
+                String reqKey = ereq.nextElement();
b1e4e4
+                String reqVal = thisreq.getExtDataInString(reqKey);
b1e4e4
+                if (reqVal != null) {
b1e4e4
+                    CMS.debug("ConnectorServlet: - " + reqKey + ": " + reqVal);
b1e4e4
+                } else {
b1e4e4
+                    CMS.debug("ConnectorServlet: - " + reqKey + ": no value");
b1e4e4
+                }
b1e4e4
+            }
b1e4e4
+*/
b1e4e4
+
b1e4e4
             thisreq = queue.newRequest(msg.getReqType());
b1e4e4
+            // if not found process request.
b1e4e4
+/*cfu
b1e4e4
+            CMS.debug("ConnectorServlet: created reqType=" +msg.getReqType()+
b1e4e4
+                   " requestId=" + thisreq.getRequestId().toString() + " requestStatus=" + thisreq.getRequestStatus().toString());
b1e4e4
+*/
b1e4e4
             CMS.debug("ConnectorServlet: created requestId=" +
b1e4e4
                     thisreq.getRequestId().toString());
b1e4e4
             thisreq.setSourceId(srcid);
b1e4e4
@@ -520,6 +541,29 @@ public class ConnectorServlet extends CMSServlet {
b1e4e4
             //        own special try/catch block.
b1e4e4
             msg.toRequest(thisreq);
b1e4e4
 
b1e4e4
+            boolean isSSKeygen = false;
b1e4e4
+            String isSSKeygenStr = thisreq.getExtDataInString("isServerSideKeygen");
b1e4e4
+            if ((isSSKeygenStr != null) && isSSKeygenStr.equalsIgnoreCase("true")) {
b1e4e4
+                String method = "ConnectorServlet:isServerSideKeygen: ";
b1e4e4
+                CMS.debug("ConnectorServlet:isServerSideKeygen = true");
b1e4e4
+                isSSKeygen = true;
b1e4e4
+                String sskKeygenStage = thisreq.getExtDataInString(IRequest.SSK_STAGE);
b1e4e4
+                if (sskKeygenStage!= null && sskKeygenStage.equalsIgnoreCase(IRequest.SSK_STAGE_KEYGEN)) {
b1e4e4
+                    CMS.debug(method + "Stage=" + sskKeygenStage);
b1e4e4
+                    thisreq.setRequestType("asymkeyGenRequest"); //IRequest.ASYMKEY_GENERATION_REQUEST
b1e4e4
+                } else if (sskKeygenStage.equalsIgnoreCase(IRequest.SSK_STAGE_KEY_RETRIEVE)) {
b1e4e4
+                    CMS.debug(method + "Stage=" + sskKeygenStage);
b1e4e4
+                    thisreq.setRequestType("recovery"); //IRequest.KEYRECOVERY_REQUEST
b1e4e4
+                }
b1e4e4
+                String clientKeyId = thisreq.getExtDataInString(IRequest.SECURITY_DATA_CLIENT_KEY_ID);
b1e4e4
+                if (clientKeyId != null)
b1e4e4
+                    CMS.debug(method + "clientKeyId = " + clientKeyId);
b1e4e4
+                else
b1e4e4
+                    CMS.debug(method + "clientKeyId not found");
b1e4e4
+            } else {
b1e4e4
+                CMS.debug("ConnectorServlet:isServerSideKeygen = false");
b1e4e4
+            }
b1e4e4
+
b1e4e4
             if (isProfileRequest(thisreq)) {
b1e4e4
                 X509CertInfo info =
b1e4e4
                                     thisreq.getExtDataInCertInfo(
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
index 00fcbb3..ea2183f 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
@@ -18,6 +18,8 @@
b1e4e4
 package com.netscape.cms.servlet.profile;
b1e4e4
 
b1e4e4
 import java.util.Locale;
b1e4e4
+import java.io.IOException;
b1e4e4
+import java.io.OutputStream;
b1e4e4
 
b1e4e4
 import javax.servlet.ServletConfig;
b1e4e4
 import javax.servlet.ServletException;
b1e4e4
@@ -47,6 +49,8 @@ import com.netscape.cms.servlet.cert.RequestProcessor;
b1e4e4
 import com.netscape.cms.servlet.common.CMSRequest;
b1e4e4
 import com.netscape.cms.servlet.common.CMSTemplate;
b1e4e4
 
b1e4e4
+import org.mozilla.jss.netscape.security.util.Utils;
b1e4e4
+
b1e4e4
 /**
b1e4e4
  * This servlet approves profile-based request.
b1e4e4
  *
b1e4e4
@@ -170,7 +174,32 @@ public class ProfileProcessServlet extends ProfileServlet {
b1e4e4
             args.set(ARG_OUTPUT_LIST, outputlist);
b1e4e4
         }
b1e4e4
 
b1e4e4
-        outputTemplate(request, response, args);
b1e4e4
+        try { //cfu
b1e4e4
+            CMS.debug("ProfileProcessServlet:cfu: p12 output process begins");
b1e4e4
+            String p12Str = req.getExtDataInString("req_issued_p12");
b1e4e4
+            if (p12Str == null) {
b1e4e4
+                // not server-side keygen
b1e4e4
+                CMS.debug("ProfileProcessServlet:cfu: no p12; not server-side keygen");
b1e4e4
+                outputTemplate(request, response, args);
b1e4e4
+            } else {
b1e4e4
+                // found pkcs12 blob
b1e4e4
+                byte[] p12blob = null;
b1e4e4
+                HttpServletResponse p12_response = cmsReq.getHttpResp();
b1e4e4
+                CMS.debug("ProfileProcessServlet:cfu: found p12 =" +
b1e4e4
+                    p12Str/*ing.toString()*/);
b1e4e4
+                p12blob = Utils.base64decode(p12Str/*ing.toString()*/);
b1e4e4
+                OutputStream bos = p12_response.getOutputStream();
b1e4e4
+                p12_response.setContentType("application/x-pkcs12");
b1e4e4
+                p12_response.setContentLength(p12blob.length);
b1e4e4
+                bos.write(p12blob);
b1e4e4
+                bos.flush();
b1e4e4
+                bos.close();
b1e4e4
+            }
b1e4e4
+        } catch (IOException e) {
b1e4e4
+            CMS.debug(e);
b1e4e4
+            setError(args, e.getMessage(), request, response);
b1e4e4
+            return;
b1e4e4
+        }
b1e4e4
     }
b1e4e4
 
b1e4e4
     private void setError(ArgSet args, String reason, HttpServletRequest request, HttpServletResponse response)
b1e4e4
diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties
b1e4e4
index e5e6ecc..608d29a 100644
b1e4e4
--- a/base/server/cmsbundle/src/UserMessages.properties
b1e4e4
+++ b/base/server/cmsbundle/src/UserMessages.properties
b1e4e4
@@ -79,6 +79,7 @@ CMS_BASE_INVALID_PROPERTY=Cannot convert property {0}
b1e4e4
 CMS_BASE_INVALID_PROPERTY_1=Cannot convert value of property {0} to a {1}. Expected format is {2}
b1e4e4
 CMS_BASE_LOAD_FAILED=Failed to load {0}
b1e4e4
 CMS_BASE_LOAD_FAILED_1=Failed to load {0}. Error {1}
b1e4e4
+CMS_MISSING_KRA_TRANSPORT_CERT_IN_CA_NSSDB=KRA Transport Certificate needs to be imported into the CA nssdb for Server-Side Kegen Enrollment
b1e4e4
 CMS_BASE_PERMISSION_DENIED=Permission denied
b1e4e4
 CMS_BASE_INVALID_ATTRIBUTE=Invalid attribute {0}
b1e4e4
 CMS_BASE_REQUEST_IN_BAD_STATE=Request is in a bad state
b1e4e4
@@ -843,6 +844,8 @@ CMS_PROFILE_VALIDITY_NOT_BEFORE_GRACE_PERIOD=Grace period for Not Before being s
b1e4e4
 CMS_PROFILE_VALIDITY_RANGE=Validity Range
b1e4e4
 CMS_PROFILE_VALIDITY_RANGE_UNIT=Validity Range Unit: year, month, day (default), hour, minute
b1e4e4
 CMS_PROFILE_VALIDITY_START_TIME=Relative Start Time (in seconds)
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_KEYTYPE=Server-side keygen key type
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_KEYSIZE=Server-side keygen key size
b1e4e4
 CMS_PROFILE_NOT_BEFORE_RANDOM_BITS=Not Before Random Bits
b1e4e4
 CMS_PROFILE_NOT_AFTER_RANDOM_BITS=Not After Random Bits
b1e4e4
 CMS_PROFILE_BYPASS_CA_NOTAFTER=Bypass CA notAfter constraint
b1e4e4
@@ -998,6 +1001,7 @@ CMS_PROFILE_DEF_INHIBIT_ANY_POLICY_EXT=This default populates an Inhibit Any-Pol
b1e4e4
 CMS_PROFILE_INHIBIT_ANY_POLICY_WRONG_SKIP_CERTS=The value for skipped certificates must be an integer.
b1e4e4
 CMS_PROFILE_DEF_USER_EXT=This default populates a User-Supplied Extension ({0}) to the request.
b1e4e4
 CMS_PROFILE_DEF_USER_KEY=This default populates a User-Supplied Certificate Key to the request.
b1e4e4
+CMS_PROFILE_DEF_SERVER_KEYGEN_USER_KEY_INFO=This default triggers server-side keygen and then populates the Certificate Key to the request.
b1e4e4
 CMS_PROFILE_DEF_USER_SIGNING_ALGORITHM=This default populates a User-Supplied Certificate Signing Algorithm to the request.
b1e4e4
 CMS_PROFILE_DEF_AUTHZ_REALM=This default populates an authorization realm.
b1e4e4
 CMS_PROFILE_DEF_USER_SUBJECT_NAME=This default populates a User-Supplied Certificate Subject Name to the request.
b1e4e4
@@ -1028,6 +1032,7 @@ CMS_PROFILE_REQUESTOR_EMAIL=Requestor Email
b1e4e4
 CMS_PROFILE_REQUESTOR_PHONE=Requestor Phone
b1e4e4
 CMS_PROFILE_REQ_SAN_TYPE=Request Subject Alternative Name Extension Type
b1e4e4
 CMS_PROFILE_REQ_SAN_PATTERN=Request Subject Alternative Name Extension Pattern
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_P12PASSWORD=Server-Side Key Generation PKCS#12 Password
b1e4e4
 CMS_PROFILE_SN_UID=UID
b1e4e4
 CMS_PROFILE_SN_EMAIL=Email
b1e4e4
 CMS_PROFILE_SN_CN=Common Name
b1e4e4
@@ -1043,9 +1048,13 @@ CMS_PROFILE_INPUT_CERT_REQ=Certificate Request
b1e4e4
 CMS_PROFILE_INPUT_KEYGEN_REQ=Key Generation Request
b1e4e4
 CMS_PROFILE_INPUT_KEYGEN_REQ_TYPE=Key Generation Request Type
b1e4e4
 CMS_PROFILE_INPUT_FILE_SIGNING_NAME=File Signing Input
b1e4e4
-CMS_PROFILE_INPUT_FILE_SIGNING_TEXT=File Signing Input
b1e4e4
 CMS_PROFILE_INPUT_FILE_SIGNING_URL=URL Of File Being Signed
b1e4e4
 CMS_PROFILE_INPUT_FILE_SIGNING_TEXT=Text Being Signed
b1e4e4
+CMS_PROFILE_INPUT_SERVER_KEYGEN_NAME=Server-Side Key Generation
b1e4e4
+CMS_PROFILE_INPUT_SERVER_KEYGEN_TEXT=Server-Side Key Generation
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_P12PASSWD=Server-Side Key Generation P12 Password
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_KEY_TYPE=Server-Side Key Generation KEY TYPE
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_KEY_SIZE=Server-Side Key Generation KEY SIZE
b1e4e4
 CMS_PROFILE_INPUT_SUBJECT_ALT_NAME_EXT_NAME=Subject Alternative Name Extension Information
b1e4e4
 CMS_PROFILE_INPUT_SUBJECT_ALT_NAME_EXT_TEXT=Subject Alternative Name Extension Information
b1e4e4
 CMS_PROFILE_IMAGE=Image
b1e4e4
@@ -1094,6 +1103,8 @@ CMS_PROFILE_OUTPUT_CERT_B64=Certificate Base-64 Encoded
b1e4e4
 CMS_PROFILE_OUTPUT_CMMF_B64=CMMF Base-64 Encoded
b1e4e4
 CMS_PROFILE_OUTPUT_PKCS7_B64=PKCS #7 Base-64 Encoded
b1e4e4
 CMS_PROFILE_OUTPUT_DER_B64=DER Base 64 Encoded
b1e4e4
+CMS_PROFILE_OUTPUT_PKCS12=PKCS#12
b1e4e4
+CMS_PROFILE_OUTPUT_PKCS12_TEXT=PKCS#12
b1e4e4
 #######################################################
b1e4e4
 # Self Tests
b1e4e4
 #
b1e4e4
diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java
b1e4e4
index ac780b4..b73230a 100644
b1e4e4
--- a/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java
b1e4e4
+++ b/base/server/cmscore/src/com/netscape/cmscore/connector/HttpPKIMessage.java
b1e4e4
@@ -75,6 +75,11 @@ public class HttpPKIMessage implements IHttpPKIMessage {
b1e4e4
         reqStatus = r.getRequestStatus().toString();
b1e4e4
         reqRealm = r.getRealm();
b1e4e4
 
b1e4e4
+/*
b1e4e4
+        CMS.debug("HttpPKIMessage.fromRequest:" + "requestType= " + reqType +
b1e4e4
+                " requestId=" + r.getRequestId().toString() +
b1e4e4
+                " requestStatus=" + reqStatus + " instance=" + r);
b1e4e4
+*/
b1e4e4
         CMS.debug("HttpPKIMessage.fromRequest: requestId="
b1e4e4
                 + r.getRequestId().toString() + " requestStatus=" + reqStatus + " instance=" + r);
b1e4e4
 
b1e4e4
diff --git a/base/server/cmscore/src/com/netscape/cmscore/connector/RequestTransfer.java b/base/server/cmscore/src/com/netscape/cmscore/connector/RequestTransfer.java
b1e4e4
index 9f77920..a533527 100644
b1e4e4
--- a/base/server/cmscore/src/com/netscape/cmscore/connector/RequestTransfer.java
b1e4e4
+++ b/base/server/cmscore/src/com/netscape/cmscore/connector/RequestTransfer.java
b1e4e4
@@ -83,15 +83,17 @@ public class RequestTransfer {
b1e4e4
                 if (k.equals("AUTH_TOKEN"))
b1e4e4
                     continue;
b1e4e4
                 //CMS.debug("RequestTransfer: attribute=" + k);
b1e4e4
-                if (k.equals("requestStatus")) {
b1e4e4
+                if (k.equalsIgnoreCase("requestStatus")) {
b1e4e4
                     CMS.debug("RequestTransfer : requestStatus=" +
b1e4e4
                             r.getExtDataInString("requestStatus"));
b1e4e4
                 }
b1e4e4
+                //CMS.debug("RequestTransfer: profile request; transfer name:"+k);
b1e4e4
                 v.addElement(k);
b1e4e4
             }
b1e4e4
             CMS.debug("RequestTransfer: attribute size=" + v.size());
b1e4e4
             return v.toArray(new String[v.size()]);
b1e4e4
         } else {
b1e4e4
+            //CMS.debug("RequestTransfer: not profile request; returning default transferAttributes");
b1e4e4
             return transferAttributes;
b1e4e4
         }
b1e4e4
     }
b1e4e4
-- 
b1e4e4
1.8.3.1
b1e4e4
b1e4e4
b1e4e4
From f963ff3ce187c5607dd2507a8ecf0d89a9356766 Mon Sep 17 00:00:00 2001
b1e4e4
From: Dinesh Prasanth M K <dmoluguw@redhat.com>
b1e4e4
Date: Thu, 16 Apr 2020 21:14:48 -0400
b1e4e4
Subject: [PATCH 4/6] Fix Javascript and backend to populate the WebUI for
b1e4e4
 ServerSideKeygen
b1e4e4
b1e4e4
This patch:
b1e4e4
b1e4e4
- Uses javascript to fill up the web UI request for ServerSide Keygen request profile
b1e4e4
b1e4e4
- Provides 2 drop down boxes: KeyType and Keysize. KeySize autoupdates based on
b1e4e4
  the KeyType selected. Example: RSA -> 1024, 2048,.. ; ECC -> nistp521, nistp256
b1e4e4
b1e4e4
- The keyType and keySize are read from the profile's attr:
b1e4e4
  policyset.userCertSet.3.constraint.params.keyParameters
b1e4e4
b1e4e4
File wise changes:
b1e4e4
b1e4e4
- ServerKeygenInput.java sends 2 new fields (keyType and keyRequest) to the request, to be
b1e4e4
  displayed on the webUI
b1e4e4
b1e4e4
- ProfileSelect.template carries the javascript changes. Note that there are 2 new if
b1e4e4
  conditions included: "server_side_keygen_key_type" and "server_side_keygen_key_size".
b1e4e4
  This ensures that it doesn't meddle with other profile web UIs
b1e4e4
b1e4e4
- IDescriptor.java and UserMessages.properties carry the appropriate String values to
b1e4e4
  be displayed/requested from user.
b1e4e4
b1e4e4
Signed-off-by: Dinesh Prasanth M K <dmoluguw@redhat.com>
b1e4e4
(cherry picked from commit 3fa7a49aee3afda2ac1bb077e4062bfd57e96f44)
b1e4e4
---
b1e4e4
 .../shared/webapps/ca/ee/ca/ProfileSelect.template | 33 ++++++++++---
b1e4e4
 .../com/netscape/certsrv/property/IDescriptor.java |  2 +
b1e4e4
 .../profile/def/ServerKeygenUserKeyDefault.java    | 55 ++++++++++++++++++----
b1e4e4
 .../cms/profile/input/ServerKeygenInput.java       | 14 +++---
b1e4e4
 base/server/cmsbundle/src/UserMessages.properties  |  4 +-
b1e4e4
 5 files changed, 83 insertions(+), 25 deletions(-)
b1e4e4
b1e4e4
diff --git a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
b1e4e4
index 350cb9b..be2caef 100644
b1e4e4
--- a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
b1e4e4
+++ b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template
b1e4e4
@@ -315,6 +315,10 @@ function keyLengthsCurvesOptions (keyPurpose)
b1e4e4
               if (keyPurpose.length == 0 || (keyPurpose.length > 0 && policySetListSet[i].setId.indexOf(keyPurpose) > -1)) {
b1e4e4
                 keyType = policySetListSet[i].policySet[j].constraintSet[k].value;
b1e4e4
               }
b1e4e4
+            } else {
b1e4e4
+              if (document.getElementById("keyTypeId").value != "undefined") {
b1e4e4
+                keyType = document.getElementById("keyTypeId").value;
b1e4e4
+              }
b1e4e4
             }
b1e4e4
           }
b1e4e4
 
b1e4e4
@@ -346,6 +350,8 @@ function keyLengthsCurvesOptions (keyPurpose)
b1e4e4
                  value != "nistp256" && value != "nistp384" && value != "nistp521" &&
b1e4e4
                  value != "ECDSA_P256" && value != "ECDSA_P384" && value != "ECDSA_P521") {
b1e4e4
           included = false;
b1e4e4
+      } else if (keyType == "EC" && isNumeric(value)) {
b1e4e4
+        included = false;
b1e4e4
       }
b1e4e4
 
b1e4e4
       if (included) {
b1e4e4
@@ -377,6 +383,18 @@ function keyLengthsCurvesOptions (keyPurpose)
b1e4e4
   return options;
b1e4e4
 }
b1e4e4
 
b1e4e4
+function updateKeyLengthsCurvesOptions() {
b1e4e4
+  // get the keySize select element via its known id
b1e4e4
+  var cSelect = document.getElementById("keySizeId");
b1e4e4
+
b1e4e4
+  // remove the current options from the select tag
b1e4e4
+  var len=cSelect.options.length;
b1e4e4
+  while (cSelect.options.length > 0) {
b1e4e4
+    cSelect.remove(0);
b1e4e4
+  }
b1e4e4
+  cSelect.innerHTML = keyLengthsCurvesOptions("");
b1e4e4
+}
b1e4e4
+
b1e4e4
 function isNumeric(sText)
b1e4e4
 {
b1e4e4
    var validChars = "0123456789";
b1e4e4
@@ -753,17 +771,18 @@ for (var m = 0; m < inputPluginListSet.length; m++) {
b1e4e4
     } else if (inputListSet[n].inputSyntax == 'server_side_keygen_request_type') {
b1e4e4
         // get PKCS#12 password
b1e4e4
         document.writeln('');
b1e4e4
-        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif">PKCS #12 Password:</font>');
b1e4e4
-        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif"><input type=password name="serverSideKeygenP12Passwd" value="" AutoComplete=off ></font>');
b1e4e4
+        document.writeln('<font size="-1" face="PrimaSans BT, Verdana, sans-serif">PKCS #12 Password:</font>');
b1e4e4
+        document.writeln('<font size="-1" face="PrimaSans BT, Verdana, sans-serif"><input type=password name="serverSideKeygenP12Passwd" value="" AutoComplete=off ></font>');
b1e4e4
         document.writeln('');
b1e4e4
 
b1e4e4
         document.writeln('');
b1e4e4
-        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif">PKCS #12 Password again:</font>');
b1e4e4
-        document.write('<font size="-1" face="PrimaSans BT, Verdana, sans-serif"><input type=password name="p12PasswordAgain" value="" AutoComplete=off ></font>');
b1e4e4
-        document.writeln('<SELECT NAME="keyType">'+getKeyTypesOptionsForKeyGen()+'</SELECT>  <SELECT NAME=\"cryptprovider\"></SELECT>');
b1e4e4
-        document.writeln('<SELECT NAME="keySize">'+keyLengthsCurvesOptions("")+'</SELECT>  <SELECT NAME=\"cryptprovider\"></SELECT>');
b1e4e4
+        document.writeln('<font size="-1" face="PrimaSans BT, Verdana, sans-serif">PKCS #12 Password again:</font>');
b1e4e4
+        document.writeln('<font size="-1" face="PrimaSans BT, Verdana, sans-serif"><input type=password name="p12PasswordAgain" value="" AutoComplete=off ></font>');
b1e4e4
         document.writeln('');
b1e4e4
-
b1e4e4
+    } else if (inputListSet[n].inputSyntax == 'server_side_keygen_key_type') {
b1e4e4
+      document.writeln('<SELECT NAME="keyType" ID="keyTypeId" onChange=\"updateKeyLengthsCurvesOptions()\">'+getKeyTypesOptionsForKeyGen() + '</SELECT> ';;
b1e4e4
+    } else if (inputListSet[n].inputSyntax == 'server_side_keygen_key_size') {
b1e4e4
+      document.writeln('<SELECT NAME="keySize" ID="keySizeId">'+keyLengthsCurvesOptions("")+'</SELECT> ';;
b1e4e4
     } else if (inputListSet[n].inputSyntax == 'cert_request') {
b1e4e4
       document.writeln('<textarea cols=60 rows=10 name=' + inputListSet[n].inputId + '></textarea>');
b1e4e4
     } else if (inputListSet[n].inputSyntax == 'cert_request_type') {
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/property/IDescriptor.java b/base/common/src/com/netscape/certsrv/property/IDescriptor.java
b1e4e4
index 4de6bb3..8eed7ae 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/property/IDescriptor.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/property/IDescriptor.java
b1e4e4
@@ -47,6 +47,8 @@ public interface IDescriptor {
b1e4e4
     public static String CERT_REQUEST_TYPE = "cert_request_type";
b1e4e4
     public static String SERVER_SIDE_KEYGEN_REQUEST_TYPE = "server_side_keygen_request_type";
b1e4e4
     public static String SERVER_SIDE_KEYGEN_PKCS12 = "server_side_keygen_p12";
b1e4e4
+    public static String SERVER_SIDE_KEYGEN_KEY_TYPE = "server_side_keygen_key_type";
b1e4e4
+    public static String SERVER_SIDE_KEYGEN_KEY_SIZE = "server_side_keygen_key_size";
b1e4e4
     public static String CHOICE = "choice"; // choice of strings
b1e4e4
     public static String DN = "dn";
b1e4e4
     public static String IP = "ip";
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
index e82ee24..13a8dec 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
@@ -336,22 +336,61 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
             request.setExtData("isServerSideKeygen", "true");
b1e4e4
             CryptoToken token = cm.getInternalKeyStorageToken();
b1e4e4
 
b1e4e4
-            String keySizeStr = request.getExtDataInString("keySize");
b1e4e4
-            int keySize = 1024;
b1e4e4
-            if (keySizeStr != null) {
b1e4e4
-                CMS.debug("ServerKeygenUserKeyDefault: populate: keySize in request: " + keySizeStr);
b1e4e4
-                keySize = Integer.parseInt(keySizeStr);
b1e4e4
+            String keyTypeStr = request.getExtDataInString("keyType");
b1e4e4
+            String keyType = "RSA";
b1e4e4
+            int keySize = 2048;
b1e4e4
+            String curveName = "nistp521";
b1e4e4
+
b1e4e4
+            // Populate the keyType and keySize/keyCurve
b1e4e4
+
b1e4e4
+            if (keyTypeStr != null && !keyTypeStr.isEmpty()) {
b1e4e4
+                CMS.debug("ServerKeygenUserKeyDefault: populate: keyType in request: " + keyTypeStr);
b1e4e4
+                keyType = keyTypeStr;
b1e4e4
             } else {
b1e4e4
-                CMS.debug("ServerKeygenUserKeyDefault: populate: keySize in request null;  default to 2048");
b1e4e4
+                CMS.debug("ServerKeygenUserKeyDefault: populate: keyType in request null; default to RSA");
b1e4e4
+            }
b1e4e4
+
b1e4e4
+            String keySizeCurveStr = request.getExtDataInString("keySize");
b1e4e4
+
b1e4e4
+            if (keyType.contentEquals("RSA")) {
b1e4e4
+                if (keySizeCurveStr != null && !keySizeCurveStr.isEmpty()) {
b1e4e4
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: keySize in request: " + keySizeCurveStr);
b1e4e4
+                    keySize = Integer.parseInt(keySizeCurveStr);
b1e4e4
+                } else {
b1e4e4
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: keySize in request null;  default to" + keySize);
b1e4e4
+                }
b1e4e4
+                // Do things when RSA is selected
b1e4e4
+            } else if (keyType.contentEquals("EC")) {
b1e4e4
+                // TODO: dmoluguw: Fix the following to generate right Key ECC keys
b1e4e4
+
b1e4e4
+                if (keySizeCurveStr != null && !keySizeCurveStr.isEmpty()) {
b1e4e4
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: keyCurve in request: " + keySizeCurveStr);
b1e4e4
+                    curveName = keySizeCurveStr;
b1e4e4
+                } else {
b1e4e4
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: keySize in request null;  default to" + curveName);
b1e4e4
+                }
b1e4e4
+                // Do things when EC is selected
b1e4e4
+            } else {
b1e4e4
+                throw new Exception("Unsupported keyType: " + keyType);
b1e4e4
+            }
b1e4e4
+            request.setExtData(IRequest.KEY_GEN_ALGORITHM, keyType);
b1e4e4
+            if(keyType.contentEquals("RSA")) {
b1e4e4
+                request.setExtData(IRequest.KEY_GEN_SIZE, keySize);
b1e4e4
+            }
b1e4e4
+            else if (keyType.contentEquals("EC")) {
b1e4e4
+                // TODO: Check whether IRequest.KEY_GEN_SIZE can accept string value
b1e4e4
+                request.setExtData(IRequest.KEY_GEN_SIZE, curveName);
b1e4e4
             }
b1e4e4
-            request.setExtData(IRequest.KEY_GEN_ALGORITHM, "RSA");
b1e4e4
-            request.setExtData(IRequest.KEY_GEN_SIZE, keySize);
b1e4e4
 
b1e4e4
             /*
b1e4e4
              * it is necessary to  put in a static fake key here to prevent
b1e4e4
              * issue; The fake key will be replaced later once KRA generates
b1e4e4
              * the real keys
b1e4e4
              */
b1e4e4
+
b1e4e4
+            // dmoluguw: TODO: The below values seem to be for development purposes,
b1e4e4
+            // and will probably work only with keyType="RSA"
b1e4e4
+
b1e4e4
             String pubKeyStr = "";
b1e4e4
             switch (keySize) {
b1e4e4
                 case 1024:
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java b/base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java
b1e4e4
index fb460d0..29890f4 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/input/ServerKeygenInput.java
b1e4e4
@@ -39,17 +39,17 @@ import com.netscape.certsrv.profile.IProfileInput;
b1e4e4
 public class ServerKeygenInput extends EnrollInput implements IProfileInput {
b1e4e4
 
b1e4e4
     public static final String P12PASSWORD = "serverSideKeygenP12Passwd";
b1e4e4
-/*
b1e4e4
+
b1e4e4
     public static final String KEY_TYPE = "keyType";
b1e4e4
     public static final String KEY_SIZE = "keySize";
b1e4e4
-*/
b1e4e4
+
b1e4e4
 
b1e4e4
     public ServerKeygenInput() {
b1e4e4
         addValueName(P12PASSWORD);
b1e4e4
-/*
b1e4e4
+
b1e4e4
         addValueName(KEY_TYPE);
b1e4e4
         addValueName(KEY_SIZE);
b1e4e4
-*/
b1e4e4
+
b1e4e4
     }
b1e4e4
 
b1e4e4
     /**
b1e4e4
@@ -99,16 +99,14 @@ public class ServerKeygenInput extends EnrollInput implements IProfileInput {
b1e4e4
             return new Descriptor(IDescriptor.SERVER_SIDE_KEYGEN_REQUEST_TYPE, null,
b1e4e4
                     null,
b1e4e4
                     CMS.getUserMessage(locale, "CMS_PROFILE_SERVER_KEYGEN_P12PASSWD"));
b1e4e4
-/*
b1e4e4
         } else if (name.equals(KEY_TYPE)) {
b1e4e4
-            return new Descriptor(IDescriptor.STRING, null,
b1e4e4
+            return new Descriptor(IDescriptor.SERVER_SIDE_KEYGEN_KEY_TYPE, null,
b1e4e4
                     null,
b1e4e4
                     CMS.getUserMessage(locale, "CMS_PROFILE_SERVER_KEYGEN_KEY_TYPE"));
b1e4e4
         } else if (name.equals(KEY_SIZE)) {
b1e4e4
-            return new Descriptor(IDescriptor.STRING, null,
b1e4e4
+            return new Descriptor(IDescriptor.SERVER_SIDE_KEYGEN_KEY_SIZE, null,
b1e4e4
                     null,
b1e4e4
                     CMS.getUserMessage(locale, "CMS_PROFILE_SERVER_KEYGEN_KEY_SIZE"));
b1e4e4
-*/
b1e4e4
         }
b1e4e4
         return null;
b1e4e4
     }
b1e4e4
diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties
b1e4e4
index 608d29a..2c57c59 100644
b1e4e4
--- a/base/server/cmsbundle/src/UserMessages.properties
b1e4e4
+++ b/base/server/cmsbundle/src/UserMessages.properties
b1e4e4
@@ -1053,8 +1053,8 @@ CMS_PROFILE_INPUT_FILE_SIGNING_TEXT=Text Being Signed
b1e4e4
 CMS_PROFILE_INPUT_SERVER_KEYGEN_NAME=Server-Side Key Generation
b1e4e4
 CMS_PROFILE_INPUT_SERVER_KEYGEN_TEXT=Server-Side Key Generation
b1e4e4
 CMS_PROFILE_SERVER_KEYGEN_P12PASSWD=Server-Side Key Generation P12 Password
b1e4e4
-CMS_PROFILE_SERVER_KEYGEN_KEY_TYPE=Server-Side Key Generation KEY TYPE
b1e4e4
-CMS_PROFILE_SERVER_KEYGEN_KEY_SIZE=Server-Side Key Generation KEY SIZE
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_KEY_TYPE=Server-Side Key Generation Key Type
b1e4e4
+CMS_PROFILE_SERVER_KEYGEN_KEY_SIZE=Server-Side Key Generation Key Size
b1e4e4
 CMS_PROFILE_INPUT_SUBJECT_ALT_NAME_EXT_NAME=Subject Alternative Name Extension Information
b1e4e4
 CMS_PROFILE_INPUT_SUBJECT_ALT_NAME_EXT_TEXT=Subject Alternative Name Extension Information
b1e4e4
 CMS_PROFILE_IMAGE=Image
b1e4e4
-- 
b1e4e4
1.8.3.1
b1e4e4
b1e4e4
b1e4e4
From 92b79cf422ab780edb65b28e0e77e13037f60fd6 Mon Sep 17 00:00:00 2001
b1e4e4
From: Jack Magne <jmagne@test.host.com>
b1e4e4
Date: Fri, 17 Apr 2020 18:05:14 -0400
b1e4e4
Subject: [PATCH 5/6] Bug 1794213- change p12 filename & transport cert
b1e4e4
 nickname for Server-Side Kyegen Enrollment This patch provides the following
b1e4e4
 fixes:  - changes the p12 filename from "profileProcess" to
b1e4e4
 "serverKeyGenCert.p12"  - transport cert nickname config
b1e4e4
b1e4e4
https://bugzilla.redhat.com/show_bug.cgi?id=1794213
b1e4e4
(cherry picked from commit a7b6d8e834f95f16478f6ae7b30b964f28693361)
b1e4e4
---
b1e4e4
 .../src/com/netscape/certsrv/system/KRAConnectorInfo.java  | 14 ++++++++++++++
b1e4e4
 .../org/dogtagpki/server/kra/rest/KRAInstallerService.java |  5 ++++-
b1e4e4
 .../netscape/cms/servlet/admin/KRAConnectorProcessor.java  |  3 +++
b1e4e4
 .../com/netscape/cms/servlet/csadmin/UpdateConnector.java  |  1 +
b1e4e4
 .../cms/servlet/profile/ProfileProcessServlet.java         |  1 +
b1e4e4
 5 files changed, 23 insertions(+), 1 deletion(-)
b1e4e4
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/system/KRAConnectorInfo.java b/base/common/src/com/netscape/certsrv/system/KRAConnectorInfo.java
b1e4e4
index a8caca6..b22909c 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/system/KRAConnectorInfo.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/system/KRAConnectorInfo.java
b1e4e4
@@ -36,6 +36,7 @@ public class KRAConnectorInfo {
b1e4e4
     private static final String HOST = "host";
b1e4e4
     private static final String PORT = "port";
b1e4e4
     private static final String TRANSPORT_CERT= "transportCert";
b1e4e4
+    private static final String TRANSPORT_CERT_NICKNAME="transportCertNickname";
b1e4e4
     private static final String URI = "uri";
b1e4e4
     private static final String TIMEOUT = "timeout";
b1e4e4
     private static final String LOCAL = "local";
b1e4e4
@@ -51,6 +52,9 @@ public class KRAConnectorInfo {
b1e4e4
     String transportCert;
b1e4e4
 
b1e4e4
     @XmlElement
b1e4e4
+    String transportCertNickname;
b1e4e4
+
b1e4e4
+    @XmlElement
b1e4e4
     String uri;
b1e4e4
 
b1e4e4
     @XmlElement
b1e4e4
@@ -74,6 +78,7 @@ public class KRAConnectorInfo {
b1e4e4
         timeout = form.getFirst(TIMEOUT);
b1e4e4
         local = form.getFirst(LOCAL);
b1e4e4
         enable = form.getFirst(ENABLE);
b1e4e4
+        transportCertNickname = form.getFirst(TRANSPORT_CERT_NICKNAME);
b1e4e4
     }
b1e4e4
 
b1e4e4
     public String getHost() {
b1e4e4
@@ -100,6 +105,14 @@ public class KRAConnectorInfo {
b1e4e4
         this.transportCert = transportCert;
b1e4e4
     }
b1e4e4
 
b1e4e4
+    public void setTransportCertNickname(String transportCertNickname) {
b1e4e4
+        this.transportCertNickname = transportCertNickname;
b1e4e4
+    }
b1e4e4
+
b1e4e4
+    public String getTransportCertNickname() {
b1e4e4
+       return transportCertNickname;
b1e4e4
+    }
b1e4e4
+
b1e4e4
     public String getUri() {
b1e4e4
         return uri;
b1e4e4
     }
b1e4e4
@@ -156,6 +169,7 @@ public class KRAConnectorInfo {
b1e4e4
         info.setPort("8443");
b1e4e4
         info.setTimeout("30");
b1e4e4
         info.setUri("");
b1e4e4
+        info.setTransportCertNickname("KRA Transport Certificate");
b1e4e4
         info.setTransportCert(
b1e4e4
             "MIIDnDCCAoSgAwIBAgIBDzANBgkqhkiG9w0BAQsFADBGMSMwIQYDVQQKExpyZWRo" +
b1e4e4
             "YXQuY29tIFNlY3VyaXR5IERvbWFpbjEfMB0GA1UEAxMWQ0EgU2lnbmluZyBDZXJ0" +
b1e4e4
diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KRAInstallerService.java b/base/kra/src/org/dogtagpki/server/kra/rest/KRAInstallerService.java
b1e4e4
index 7759dcc..35ae7b8 100644
b1e4e4
--- a/base/kra/src/org/dogtagpki/server/kra/rest/KRAInstallerService.java
b1e4e4
+++ b/base/kra/src/org/dogtagpki/server/kra/rest/KRAInstallerService.java
b1e4e4
@@ -93,7 +93,8 @@ public class KRAInstallerService extends SystemConfigService {
b1e4e4
         String kraPort = CMS.getAgentPort();
b1e4e4
         String transportCert = cs.getString("kra.transport.cert", "");
b1e4e4
         String sessionId = CMS.getConfigSDSessionId();
b1e4e4
-
b1e4e4
+        String transportCertNickname = cs.getString("kra.cert.transport.nickname");
b1e4e4
+        CMS.debug("KRAInstallerService: transportCert nickname: " + transportCertNickname);
b1e4e4
         MultivaluedMap<String, String> content = new MultivaluedHashMap<String, String>();
b1e4e4
         content.putSingle("ca.connector.KRA.enable", "true");
b1e4e4
         content.putSingle("ca.connector.KRA.local", "false");
b1e4e4
@@ -102,8 +103,10 @@ public class KRAInstallerService extends SystemConfigService {
b1e4e4
         content.putSingle("ca.connector.KRA.host", kraHost);
b1e4e4
         content.putSingle("ca.connector.KRA.port", kraPort);
b1e4e4
         content.putSingle("ca.connector.KRA.transportCert", transportCert);
b1e4e4
+        content.putSingle("ca.connector.KRA.transportCertNickname",transportCertNickname);
b1e4e4
         content.putSingle("sessionID", sessionId);
b1e4e4
 
b1e4e4
+        CMS.debug("KRAnstallerService: content: " + content);
b1e4e4
         String c = ConfigurationUtils.post(caHost, caPort, true, "/ca/admin/ca/updateConnector", content, null, null);
b1e4e4
         if (c == null || c.equals("")) {
b1e4e4
             CMS.debug("KRAInstallerService: Unable to configure KRA connector: No response from CA");
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/admin/KRAConnectorProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/admin/KRAConnectorProcessor.java
b1e4e4
index 2fd5d53..46d4324 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/admin/KRAConnectorProcessor.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/admin/KRAConnectorProcessor.java
b1e4e4
@@ -183,6 +183,7 @@ public class KRAConnectorProcessor extends CAProcessor {
b1e4e4
             }
b1e4e4
         }
b1e4e4
 
b1e4e4
+        CMS.debug("KRAConnectorInfo: " + info);
b1e4e4
         // connector does not exist, or existing connector is the same host/port and we are replacing it
b1e4e4
         cs.putString(PREFIX + ".host", info.getHost());
b1e4e4
         cs.putString(PREFIX + ".port", info.getPort());
b1e4e4
@@ -191,6 +192,7 @@ public class KRAConnectorProcessor extends CAProcessor {
b1e4e4
         cs.putString(PREFIX + ".timeout", info.getTimeout() != null ?  info.getTimeout() : "30");
b1e4e4
         cs.putString(PREFIX + ".uri", info.getUri() != null ? info.getUri() : "/kra/agent/kra/connector");
b1e4e4
         cs.putString(PREFIX + ".transportCert", info.getTransportCert());
b1e4e4
+        cs.putString(PREFIX + ".transportCertNickname", info.getTransportCertNickname());
b1e4e4
 
b1e4e4
         String nickname = cs.getString("ca.subsystem.nickname", "");
b1e4e4
         String tokenname = cs.getString("ca.subsystem.tokenname", "");
b1e4e4
@@ -219,6 +221,7 @@ public class KRAConnectorProcessor extends CAProcessor {
b1e4e4
         info.setTimeout(cs.getString(PREFIX + ".timeout"));
b1e4e4
         info.setUri(cs.getString(PREFIX + ".uri"));
b1e4e4
         info.setTransportCert(cs.getString(PREFIX + ".transportCert"));
b1e4e4
+        info.setTransportCertNickname(cs.getString(PREFIX + ".transportCertNickname"));
b1e4e4
 
b1e4e4
         return info;
b1e4e4
     }
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java
b1e4e4
index b2d081f..6a2c25f 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateConnector.java
b1e4e4
@@ -71,6 +71,7 @@ public class UpdateConnector extends CMSServlet {
b1e4e4
         info.setPort(httpReq.getParameter(KRAConnectorProcessor.PREFIX + ".port"));
b1e4e4
         info.setTimeout(httpReq.getParameter(KRAConnectorProcessor.PREFIX + ".timeout"));
b1e4e4
         info.setTransportCert(httpReq.getParameter(KRAConnectorProcessor.PREFIX + ".transportCert"));
b1e4e4
+        info.setTransportCertNickname(httpReq.getParameter(KRAConnectorProcessor.PREFIX + ".transportCertNickname"));
b1e4e4
         info.setUri(httpReq.getParameter(KRAConnectorProcessor.PREFIX + ".uri"));
b1e4e4
         info.setLocal(httpReq.getParameter(KRAConnectorProcessor.PREFIX + ".local"));
b1e4e4
         info.setEnable(httpReq.getParameter(KRAConnectorProcessor.PREFIX + ".enable"));
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
index ea2183f..f71d754 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
@@ -191,6 +191,7 @@ public class ProfileProcessServlet extends ProfileServlet {
b1e4e4
                 OutputStream bos = p12_response.getOutputStream();
b1e4e4
                 p12_response.setContentType("application/x-pkcs12");
b1e4e4
                 p12_response.setContentLength(p12blob.length);
b1e4e4
+                p12_response.setHeader("Content-disposition", "attachment; filename="+  "serverKeyGenCert.p12");
b1e4e4
                 bos.write(p12blob);
b1e4e4
                 bos.flush();
b1e4e4
                 bos.close();
b1e4e4
-- 
b1e4e4
1.8.3.1
b1e4e4
b1e4e4
b1e4e4
From e7e1cea36fb616a5f5059453c53d30678e813622 Mon Sep 17 00:00:00 2001
b1e4e4
From: Christina Fu <cfu@redhat.com>
b1e4e4
Date: Fri, 17 Apr 2020 17:43:53 -0700
b1e4e4
Subject: [PATCH 6/6] Bug 1794213 adds EC Support and audit for Server-Side
b1e4e4
 Kyegen Enrollment
b1e4e4
b1e4e4
This patch
b1e4e4
  - adds EC support for the Server-Side Kyegen Enrollment feature.
b1e4e4
  - adds auditng
b1e4e4
  - fixes key record so that Archiver and Owner Name are not null.
b1e4e4
  - fixes missing request records
b1e4e4
b1e4e4
Note: the new audit events implemented are
b1e4e4
   - SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST
b1e4e4
   - SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST_PROCESSED
b1e4e4
   - SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST
b1e4e4
   - SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST_PROCESSED
b1e4e4
where SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST_PROCESSED is not yet added
b1e4e4
b1e4e4
https://bugzilla.redhat.com/show_bug.cgi?id=1794213
b1e4e4
(cherry picked from commit 3649e4b3143a35a51c367c71b31d2aa8d9b4e507)
b1e4e4
---
b1e4e4
 .../shared/profiles/ca/caServerKeygen_UserCert.cfg |   6 +-
b1e4e4
 .../certsrv/kra/IKeyRecoveryAuthority.java         |   2 +
b1e4e4
 .../ServerSideKeygenEnrollKeyRetrievalEvent.java   |  43 +++++
b1e4e4
 ...SideKeygenEnrollKeyRetrievalProcessedEvent.java |  46 ++++++
b1e4e4
 .../event/ServerSideKeygenEnrollKeygenEvent.java   |  43 +++++
b1e4e4
 ...ServerSideKeygenEnrollKeygenProcessedEvent.java |  47 ++++++
b1e4e4
 .../src/com/netscape/kra/AsymKeyGenService.java    | 183 +++++++++++++++------
b1e4e4
 .../src/com/netscape/kra/KeyRecoveryAuthority.java |  15 +-
b1e4e4
 base/kra/src/com/netscape/kra/RecoveryService.java |  21 ++-
b1e4e4
 .../cms/profile/common/CAEnrollProfile.java        |  80 +++++----
b1e4e4
 .../profile/def/ServerKeygenUserKeyDefault.java    |  77 ++++++---
b1e4e4
 .../com/netscape/cms/servlet/base/CMSServlet.java  |   4 -
b1e4e4
 .../cms/servlet/connector/ConnectorServlet.java    |  49 ++++--
b1e4e4
 .../cms/servlet/profile/ProfileProcessServlet.java |   7 +-
b1e4e4
 base/server/cmsbundle/src/audit-events.properties  |  53 ++++++
b1e4e4
 .../netscape/cmscore/request/ARequestQueue.java    |   4 +-
b1e4e4
 16 files changed, 548 insertions(+), 132 deletions(-)
b1e4e4
 create mode 100644 base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalEvent.java
b1e4e4
 create mode 100644 base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalProcessedEvent.java
b1e4e4
 create mode 100644 base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenEvent.java
b1e4e4
 create mode 100644 base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenProcessedEvent.java
b1e4e4
b1e4e4
diff --git a/base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg b/base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg
b1e4e4
index 0f2b3dc..b449163 100644
b1e4e4
--- a/base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg
b1e4e4
+++ b/base/ca/shared/profiles/ca/caServerKeygen_UserCert.cfg
b1e4e4
@@ -36,8 +36,8 @@ policyset.userCertSet.2.default.params.range=180
b1e4e4
 policyset.userCertSet.2.default.params.startTime=0
b1e4e4
 policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
b1e4e4
 policyset.userCertSet.3.constraint.name=Key Constraint
b1e4e4
-policyset.userCertSet.3.constraint.params.keyType=RSA
b1e4e4
-policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096
b1e4e4
+policyset.userCertSet.3.constraint.params.keyType=-
b1e4e4
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp384,nistp521
b1e4e4
 policyset.userCertSet.3.default.class_id=serverKeygenUserKeyDefaultImpl
b1e4e4
 policyset.userCertSet.3.default.name=Server-Side Keygen Default
b1e4e4
 policyset.userCertSet.3.default.params.keyType=RSA
b1e4e4
@@ -97,7 +97,7 @@ policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
b1e4e4
 policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
b1e4e4
 policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
b1e4e4
 policyset.userCertSet.9.constraint.name=No Constraint
b1e4e4
-policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withEC,SHA256withEC,SHA384withRSA,SHA384withEC,SHA512withEC
b1e4e4
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withEC,SHA256withEC,SHA384withRSA,SHA384withEC,SHA512withEC,SHA256withRSA/PSS,SHA384withRSA/PSS,SHA512withRSA/PSS
b1e4e4
 policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
b1e4e4
 policyset.userCertSet.9.default.name=Signing Alg
b1e4e4
 policyset.userCertSet.9.default.params.signingAlg=-
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java b/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
b1e4e4
index 4f709e9..97c65eb 100644
b1e4e4
--- a/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java
b1e4e4
@@ -354,4 +354,6 @@ public interface IKeyRecoveryAuthority extends ISubsystem {
b1e4e4
      */
b1e4e4
     public KeyPair generateKeyPair(String alg, int keySize, String keyCurve,
b1e4e4
             PQGParams pqg, KeyPairGeneratorSpi.Usage[] usageList) throws EBaseException;
b1e4e4
+    public KeyPair generateKeyPair(String alg, int keySize, String keyCurve,
b1e4e4
+            PQGParams pqg, KeyPairGeneratorSpi.Usage[] usageList, boolean temporary) throws EBaseException;
b1e4e4
 }
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalEvent.java b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalEvent.java
b1e4e4
new file mode 100644
b1e4e4
index 0000000..59534e3
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalEvent.java
b1e4e4
@@ -0,0 +1,43 @@
b1e4e4
+// --- BEGIN COPYRIGHT BLOCK ---
b1e4e4
+// This program is free software; you can redistribute it and/or modify
b1e4e4
+// it under the terms of the GNU General Public License as published by
b1e4e4
+// the Free Software Foundation; version 2 of the License.
b1e4e4
+//
b1e4e4
+// This program is distributed in the hope that it will be useful,
b1e4e4
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
b1e4e4
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b1e4e4
+// GNU General Public License for more details.
b1e4e4
+//
b1e4e4
+// You should have received a copy of the GNU General Public License along
b1e4e4
+// with this program; if not, write to the Free Software Foundation, Inc.,
b1e4e4
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b1e4e4
+//
b1e4e4
+// (C) 2020 Red Hat, Inc.
b1e4e4
+// All rights reserved.
b1e4e4
+// --- END COPYRIGHT BLOCK ---
b1e4e4
+package com.netscape.certsrv.logging.event;
b1e4e4
+
b1e4e4
+import com.netscape.certsrv.logging.SignedAuditEvent;
b1e4e4
+import com.netscape.certsrv.request.RequestId;
b1e4e4
+
b1e4e4
+public class ServerSideKeygenEnrollKeyRetrievalEvent extends SignedAuditEvent {
b1e4e4
+
b1e4e4
+    private static final long serialVersionUID = 1L;
b1e4e4
+
b1e4e4
+    private static final String LOGGING_PROPERTY =
b1e4e4
+            "LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST";
b1e4e4
+
b1e4e4
+    public ServerSideKeygenEnrollKeyRetrievalEvent(
b1e4e4
+            String subjectID,
b1e4e4
+            String outcome,
b1e4e4
+            RequestId requestID,
b1e4e4
+            String clientID) {
b1e4e4
+
b1e4e4
+        super(LOGGING_PROPERTY);
b1e4e4
+
b1e4e4
+        setAttribute("SubjectID", subjectID);
b1e4e4
+        setAttribute("Outcome", outcome);
b1e4e4
+        setAttribute("RequestID", requestID);
b1e4e4
+        setAttribute("ClientID", clientID);
b1e4e4
+    }
b1e4e4
+}
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalProcessedEvent.java b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalProcessedEvent.java
b1e4e4
new file mode 100644
b1e4e4
index 0000000..603ed74
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeyRetrievalProcessedEvent.java
b1e4e4
@@ -0,0 +1,46 @@
b1e4e4
+// --- BEGIN COPYRIGHT BLOCK ---
b1e4e4
+// This program is free software; you can redistribute it and/or modify
b1e4e4
+// it under the terms of the GNU General Public License as published by
b1e4e4
+// the Free Software Foundation; version 2 of the License.
b1e4e4
+//
b1e4e4
+// This program is distributed in the hope that it will be useful,
b1e4e4
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
b1e4e4
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b1e4e4
+// GNU General Public License for more details.
b1e4e4
+//
b1e4e4
+// You should have received a copy of the GNU General Public License along
b1e4e4
+// with this program; if not, write to the Free Software Foundation, Inc.,
b1e4e4
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b1e4e4
+//
b1e4e4
+// (C) 2020 Red Hat, Inc.
b1e4e4
+// All rights reserved.
b1e4e4
+// --- END COPYRIGHT BLOCK ---
b1e4e4
+package com.netscape.certsrv.logging.event;
b1e4e4
+
b1e4e4
+import com.netscape.certsrv.logging.SignedAuditEvent;
b1e4e4
+import com.netscape.certsrv.request.RequestId;
b1e4e4
+
b1e4e4
+public class ServerSideKeygenEnrollKeyRetrievalProcessedEvent extends SignedAuditEvent {
b1e4e4
+
b1e4e4
+    private static final long serialVersionUID = 1L;
b1e4e4
+
b1e4e4
+    private static final String LOGGING_PROPERTY =
b1e4e4
+            "LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST_PROCESSED";
b1e4e4
+
b1e4e4
+    public ServerSideKeygenEnrollKeyRetrievalProcessedEvent(
b1e4e4
+            String subjectID,
b1e4e4
+            String outcome,
b1e4e4
+            RequestId requestID,
b1e4e4
+            String clientID,
b1e4e4
+            String failureReason) {
b1e4e4
+
b1e4e4
+        super(LOGGING_PROPERTY);
b1e4e4
+
b1e4e4
+        setAttribute("SubjectID", subjectID);
b1e4e4
+        setAttribute("Outcome", outcome);
b1e4e4
+        setAttribute("RequestID", requestID);
b1e4e4
+        setAttribute("ClientID", clientID);
b1e4e4
+        setAttribute("FailureReason", failureReason);
b1e4e4
+    }
b1e4e4
+}
b1e4e4
+
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenEvent.java b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenEvent.java
b1e4e4
new file mode 100644
b1e4e4
index 0000000..90e8330
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenEvent.java
b1e4e4
@@ -0,0 +1,43 @@
b1e4e4
+// --- BEGIN COPYRIGHT BLOCK ---
b1e4e4
+// This program is free software; you can redistribute it and/or modify
b1e4e4
+// it under the terms of the GNU General Public License as published by
b1e4e4
+// the Free Software Foundation; version 2 of the License.
b1e4e4
+//
b1e4e4
+// This program is distributed in the hope that it will be useful,
b1e4e4
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
b1e4e4
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b1e4e4
+// GNU General Public License for more details.
b1e4e4
+//
b1e4e4
+// You should have received a copy of the GNU General Public License along
b1e4e4
+// with this program; if not, write to the Free Software Foundation, Inc.,
b1e4e4
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b1e4e4
+//
b1e4e4
+// (C) 2020 Red Hat, Inc.
b1e4e4
+// All rights reserved.
b1e4e4
+// --- END COPYRIGHT BLOCK ---
b1e4e4
+package com.netscape.certsrv.logging.event;
b1e4e4
+
b1e4e4
+import com.netscape.certsrv.logging.SignedAuditEvent;
b1e4e4
+import com.netscape.certsrv.request.RequestId;
b1e4e4
+
b1e4e4
+public class ServerSideKeygenEnrollKeygenEvent extends SignedAuditEvent {
b1e4e4
+
b1e4e4
+    private static final long serialVersionUID = 1L;
b1e4e4
+
b1e4e4
+    private static final String LOGGING_PROPERTY =
b1e4e4
+            "LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST";
b1e4e4
+
b1e4e4
+    public ServerSideKeygenEnrollKeygenEvent(
b1e4e4
+            String subjectID,
b1e4e4
+            String outcome,
b1e4e4
+            RequestId requestID,
b1e4e4
+            String clientKeyID) {
b1e4e4
+
b1e4e4
+        super(LOGGING_PROPERTY);
b1e4e4
+
b1e4e4
+        setAttribute("SubjectID", subjectID);
b1e4e4
+        setAttribute("Outcome", outcome);
b1e4e4
+        setAttribute("RequestID", requestID);
b1e4e4
+        setAttribute("ClientKeyID", clientKeyID);
b1e4e4
+    }
b1e4e4
+}
b1e4e4
diff --git a/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenProcessedEvent.java b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenProcessedEvent.java
b1e4e4
new file mode 100644
b1e4e4
index 0000000..13adb32
b1e4e4
--- /dev/null
b1e4e4
+++ b/base/common/src/com/netscape/certsrv/logging/event/ServerSideKeygenEnrollKeygenProcessedEvent.java
b1e4e4
@@ -0,0 +1,47 @@
b1e4e4
+// --- BEGIN COPYRIGHT BLOCK ---
b1e4e4
+// This program is free software; you can redistribute it and/or modify
b1e4e4
+// it under the terms of the GNU General Public License as published by
b1e4e4
+// the Free Software Foundation; version 2 of the License.
b1e4e4
+//
b1e4e4
+// This program is distributed in the hope that it will be useful,
b1e4e4
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
b1e4e4
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
b1e4e4
+// GNU General Public License for more details.
b1e4e4
+//
b1e4e4
+// You should have received a copy of the GNU General Public License along
b1e4e4
+// with this program; if not, write to the Free Software Foundation, Inc.,
b1e4e4
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
b1e4e4
+//
b1e4e4
+// (C) 2020 Red Hat, Inc.
b1e4e4
+// All rights reserved.
b1e4e4
+// --- END COPYRIGHT BLOCK ---
b1e4e4
+package com.netscape.certsrv.logging.event;
b1e4e4
+
b1e4e4
+import com.netscape.certsrv.dbs.keydb.KeyId;
b1e4e4
+import com.netscape.certsrv.logging.SignedAuditEvent;
b1e4e4
+import com.netscape.certsrv.request.RequestId;
b1e4e4
+
b1e4e4
+public class ServerSideKeygenEnrollKeygenProcessedEvent extends SignedAuditEvent {
b1e4e4
+
b1e4e4
+    private static final long serialVersionUID = 1L;
b1e4e4
+
b1e4e4
+    private static final String LOGGING_PROPERTY =
b1e4e4
+            "LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST_PROCESSED";
b1e4e4
+
b1e4e4
+    public ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+            String subjectID,
b1e4e4
+            String outcome,
b1e4e4
+            RequestId requestID,
b1e4e4
+            String clientID,
b1e4e4
+            String failureReason) {
b1e4e4
+
b1e4e4
+        super(LOGGING_PROPERTY);
b1e4e4
+
b1e4e4
+        setAttribute("SubjectID", subjectID);
b1e4e4
+        setAttribute("Outcome", outcome);
b1e4e4
+        setAttribute("RequestID", requestID);
b1e4e4
+        setAttribute("ClientID", clientID);
b1e4e4
+        setAttribute("FailureReason", failureReason);
b1e4e4
+    }
b1e4e4
+}
b1e4e4
+
b1e4e4
diff --git a/base/kra/src/com/netscape/kra/AsymKeyGenService.java b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b1e4e4
index dca6ebc..61f86ff 100644
b1e4e4
--- a/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b1e4e4
+++ b/base/kra/src/com/netscape/kra/AsymKeyGenService.java
b1e4e4
@@ -36,6 +36,7 @@ import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
b1e4e4
 import com.netscape.certsrv.logging.ILogger;
b1e4e4
 import com.netscape.certsrv.logging.LogEvent;
b1e4e4
 import com.netscape.certsrv.logging.event.AsymKeyGenerationProcessedEvent;
b1e4e4
+import com.netscape.certsrv.logging.event.ServerSideKeygenEnrollKeygenProcessedEvent;
b1e4e4
 import com.netscape.certsrv.request.IRequest;
b1e4e4
 import com.netscape.certsrv.request.IService;
b1e4e4
 import com.netscape.certsrv.request.RequestId;
b1e4e4
@@ -55,6 +56,7 @@ import netscape.security.util.WrappingParams;
b1e4e4
  * The public key is stored in the publicKeyData attribute of the record.
b1e4e4
  *
b1e4e4
  * @author akoneru
b1e4e4
+ * @author cfu Server-Side Keygen Enrollment support
b1e4e4
  *
b1e4e4
  */
b1e4e4
 public class AsymKeyGenService implements IService {
b1e4e4
@@ -77,6 +79,8 @@ public class AsymKeyGenService implements IService {
b1e4e4
         String method = "AsymKeyGenService:serviceRequest: ";
b1e4e4
         IConfigStore configStore = CMS.getConfigStore();
b1e4e4
 
b1e4e4
+        String owner = request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER);
b1e4e4
+        String auditSubjectID = owner;
b1e4e4
         boolean isSSKeygen = false;
b1e4e4
         String isSSKeygenStr = request.getExtDataInString("isServerSideKeygen");
b1e4e4
         if ((isSSKeygenStr != null) && isSSKeygenStr.equalsIgnoreCase("true")) {
b1e4e4
@@ -93,9 +97,37 @@ public class AsymKeyGenService implements IService {
b1e4e4
             CMS.debug(method + "clientKeyId not found");
b1e4e4
 
b1e4e4
         String algorithm = request.getExtDataInString(IRequest.KEY_GEN_ALGORITHM);
b1e4e4
-
b1e4e4
         String keySizeStr = request.getExtDataInString(IRequest.KEY_GEN_SIZE);
b1e4e4
-        int keySize = Integer.valueOf(keySizeStr);
b1e4e4
+        int keySize = 2048;
b1e4e4
+        boolean isEC = false;
b1e4e4
+        String errmsg ="";
b1e4e4
+
b1e4e4
+        if (algorithm.toUpperCase().equals("RSA"))
b1e4e4
+            keySize = Integer.valueOf(keySizeStr);
b1e4e4
+        else {
b1e4e4
+            isEC = true;
b1e4e4
+            switch (keySizeStr) {
b1e4e4
+               case "nistp256":
b1e4e4
+                    keySize = 256;
b1e4e4
+                    break;
b1e4e4
+                case "nistp384":
b1e4e4
+                    keySize = 384;
b1e4e4
+                    break;
b1e4e4
+                case "nistp521":
b1e4e4
+                    keySize = 521;
b1e4e4
+                    break;
b1e4e4
+                default:
b1e4e4
+                    CMS.debug(method + "unknown EC key curve name: " + keySizeStr);
b1e4e4
+                    errmsg = "unknown EC key curve name: " + keySizeStr;
b1e4e4
+                    signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        errmsg));
b1e4e4
+                    throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: " + errmsg);
b1e4e4
+            }
b1e4e4
+        }
b1e4e4
 
b1e4e4
         String realm = request.getRealm();
b1e4e4
 
b1e4e4
@@ -149,8 +181,6 @@ public class AsymKeyGenService implements IService {
b1e4e4
         CMS.debug("AsymKeyGenService.serviceRequest. Request id: " + request.getRequestId());
b1e4e4
         CMS.debug("AsymKeyGenService.serviceRequest algorithm: " + algorithm);
b1e4e4
 
b1e4e4
-        String owner = request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER);
b1e4e4
-        String auditSubjectID = owner;
b1e4e4
 
b1e4e4
         // Generating the asymmetric keys
b1e4e4
         KeyPair kp = null;
b1e4e4
@@ -159,22 +189,44 @@ public class AsymKeyGenService implements IService {
b1e4e4
             kp = kra.generateKeyPair(
b1e4e4
                     algorithm.toUpperCase(),
b1e4e4
                     keySize,
b1e4e4
-                    null, // keyCurve for ECC, not yet supported
b1e4e4
+                    isEC? keySizeStr:null, // keyCurve for ECC
b1e4e4
                     null, // PQG not yet supported
b1e4e4
-                    usageList
b1e4e4
+                    usageList,
b1e4e4
+                    true /* temporary */
b1e4e4
                  );
b1e4e4
 
b1e4e4
         } catch (EBaseException e) {
b1e4e4
             CMS.debugStackTrace();
b1e4e4
-            auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
-                    clientKeyId, null, "Failed to generate asymmetric key: " + e.getMessage());
b1e4e4
-            throw new EBaseException("Errors in generating Asymmetric key: " + e, e);
b1e4e4
+            if (isSSKeygen) {
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        e.getMessage()));
b1e4e4
+                throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: " + e, e);
b1e4e4
+            } else {
b1e4e4
+                auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
+                        clientKeyId, null, "Failed to generate asymmetric key: " + e.getMessage());
b1e4e4
+                throw new EBaseException("Errors in generating Asymmetric key: " + e, e);
b1e4e4
+            }
b1e4e4
         }
b1e4e4
 
b1e4e4
         if (kp == null) {
b1e4e4
-            auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
-                    clientKeyId, null, "Failed to generate asymmetric key");
b1e4e4
-            throw new EBaseException("Failed to generate asymmetric key!");
b1e4e4
+            if (isSSKeygen) {
b1e4e4
+                errmsg = "key generation failure";
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        errmsg));
b1e4e4
+                throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: "+ errmsg);
b1e4e4
+            } else {
b1e4e4
+                auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
+                        clientKeyId, null, "Failed to generate asymmetric key");
b1e4e4
+                throw new EBaseException("Failed to generate asymmetric key!");
b1e4e4
+            }
b1e4e4
         }
b1e4e4
 
b1e4e4
         if (isSSKeygen) {
b1e4e4
@@ -184,17 +236,18 @@ public class AsymKeyGenService implements IService {
b1e4e4
                 publicKeyData = kp.getPublic().getEncoded();
b1e4e4
                 if (publicKeyData == null) {
b1e4e4
                     request.setExtData(IRequest.RESULT, Integer.valueOf(4));
b1e4e4
-                    CMS.debug(method + " failed getting publickey encoded");
b1e4e4
-                    return false;
b1e4e4
+                    errmsg = " failed getting publickey encoded";
b1e4e4
+                    CMS.debug(method + errmsg);
b1e4e4
+                    signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        errmsg));
b1e4e4
+                    throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: "+ errmsg);
b1e4e4
                 } else {
b1e4e4
                     //CMS.debug(method + "public key binary length ="+ publicKeyData.length);
b1e4e4
-                    if (algorithm.equals("EC")) {
b1e4e4
-                        /* url encode */
b1e4e4
-                        pubKeyStr = com.netscape.cmsutil.util.Utils.SpecialEncode(publicKeyData);
b1e4e4
-                        CMS.debug(method + " EC pubKeyStr special encoded");
b1e4e4
-                    } else {
b1e4e4
-                        pubKeyStr = CryptoUtil.base64Encode(publicKeyData);
b1e4e4
-                    }
b1e4e4
+                    pubKeyStr = CryptoUtil.base64Encode(publicKeyData);
b1e4e4
 
b1e4e4
                     //CMS.debug(method + "public key length =" + pubKeyStr.length());
b1e4e4
                     request.setExtData("public_key", pubKeyStr);
b1e4e4
@@ -202,7 +255,13 @@ public class AsymKeyGenService implements IService {
b1e4e4
             } catch (Exception e) {
b1e4e4
                 CMS.debug(method + e);
b1e4e4
                 request.setExtData(IRequest.RESULT, Integer.valueOf(4));
b1e4e4
-                return false;
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        e.getMessage()));
b1e4e4
+                throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: " + e, e);
b1e4e4
             }
b1e4e4
         }
b1e4e4
 
b1e4e4
@@ -214,23 +273,46 @@ public class AsymKeyGenService implements IService {
b1e4e4
             privateSecurityData = storageUnit.wrap((PrivateKey) kp.getPrivate(), params);
b1e4e4
         } catch (Exception e) {
b1e4e4
             CMS.debug("Failed to generate security data to archive: " + e);
b1e4e4
-            auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
+            if (isSSKeygen) {
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        e.getMessage()));
b1e4e4
+                throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: " + e, e);
b1e4e4
+            } else {
b1e4e4
+                auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
                     clientKeyId, null, CMS.getUserMessage("CMS_KRA_INVALID_PRIVATE_KEY"));
b1e4e4
-            throw new EBaseException("Failed to generate security data to archive!", e);
b1e4e4
+                throw new EBaseException("Failed to generate security data to archive!", e);
b1e4e4
+            }
b1e4e4
         }
b1e4e4
 
b1e4e4
+        if (owner == null)
b1e4e4
+            owner = request.getExtDataInString("auth_token-userdn");
b1e4e4
         KeyRecord record = new KeyRecord(null, kp.getPublic().getEncoded(), privateSecurityData,
b1e4e4
-                owner, algorithm, owner);
b1e4e4
+                isSSKeygen? clientKeyId:owner, algorithm, owner);
b1e4e4
 
b1e4e4
         IKeyRepository storage = kra.getKeyRepository();
b1e4e4
         BigInteger serialNo = storage.getNextSerialNumber();
b1e4e4
 
b1e4e4
         if (serialNo == null) {
b1e4e4
-            kra.log(ILogger.LL_FAILURE,
b1e4e4
+            if (isSSKeygen) {
b1e4e4
+                errmsg = "Failed to get next Key ID";
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        errmsg));
b1e4e4
+                throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: "+ errmsg);
b1e4e4
+            } else {
b1e4e4
+                kra.log(ILogger.LL_FAILURE,
b1e4e4
                     CMS.getLogMessage("CMSCORE_KRA_GET_NEXT_SERIAL"));
b1e4e4
-            auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
+                auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
                     clientKeyId, null, "Failed to get next Key ID");
b1e4e4
-            throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
b1e4e4
+                throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
b1e4e4
+            }
b1e4e4
         }
b1e4e4
 
b1e4e4
         // Storing the public key and private key.
b1e4e4
@@ -250,36 +332,37 @@ public class AsymKeyGenService implements IService {
b1e4e4
         try {
b1e4e4
             record.setWrappingParams(params, allowEncDecrypt_archival);
b1e4e4
         } catch (Exception e) {
b1e4e4
-            auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
+            if (isSSKeygen) {
b1e4e4
+                errmsg = "Failed to store wrapping params";
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Failure",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        e.getMessage() + errmsg));
b1e4e4
+                throw new EBaseException("Errors in ServerSideKeygenEnroll generating Asymmetric key: " + errmsg, e);
b1e4e4
+            } else {
b1e4e4
+                auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.FAILURE, request.getRequestId(),
b1e4e4
                     clientKeyId, null, "Failed to store wrapping params");
b1e4e4
-            throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
b1e4e4
+                throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
b1e4e4
+            }
b1e4e4
         }
b1e4e4
 
b1e4e4
         storage.addKeyRecord(record);
b1e4e4
 
b1e4e4
-        auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.SUCCESS, request.getRequestId(),
b1e4e4
+        if (isSSKeygen) {
b1e4e4
+            signedAuditLogger.log(new ServerSideKeygenEnrollKeygenProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Success",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        null));
b1e4e4
+        } else {
b1e4e4
+            auditAsymKeyGenRequestProcessed(auditSubjectID, ILogger.SUCCESS, request.getRequestId(),
b1e4e4
                 clientKeyId, new KeyId(serialNo), "None");
b1e4e4
+        }
b1e4e4
         request.setExtData(IRequest.RESULT, IRequest.RES_SUCCESS);
b1e4e4
 
b1e4e4
-        if (isSSKeygen) {
b1e4e4
-
b1e4e4
-            Enumeration<String> ereq = request.getExtDataKeys();
b1e4e4
-
b1e4e4
-            /* cfu
b1e4e4
-            CMS.debug(method + "let's find out what's in the request");
b1e4e4
-            while (ereq.hasMoreElements()) {
b1e4e4
-                String reqKey = ereq.nextElement();
b1e4e4
-                String reqVal = request.getExtDataInString(reqKey);
b1e4e4
-                if (reqVal != null) {
b1e4e4
-                    CMS.debug(method + reqKey + ": " + reqVal);
b1e4e4
-                } else {
b1e4e4
-                    CMS.debug(method + reqKey + ": no value");
b1e4e4
-                }
b1e4e4
-            }
b1e4e4
-            */
b1e4e4
-
b1e4e4
-            request.setExtData("delayLDAPCommit", "false");
b1e4e4
-        }
b1e4e4
         kra.getRequestQueue().updateRequest(request);
b1e4e4
 
b1e4e4
         return true;
b1e4e4
diff --git a/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
b1e4e4
index 05c7e71..34e329b 100644
b1e4e4
--- a/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
b1e4e4
+++ b/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java
b1e4e4
@@ -1728,6 +1728,10 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove
b1e4e4
 
b1e4e4
     public KeyPair generateKeyPair(String alg, int keySize, String keyCurve,
b1e4e4
             PQGParams pqg, KeyPairGeneratorSpi.Usage[] usageList) throws EBaseException {
b1e4e4
+        return generateKeyPair(alg, keySize, keyCurve, pqg, usageList, false);
b1e4e4
+    }
b1e4e4
+    public KeyPair generateKeyPair(String alg, int keySize, String keyCurve,
b1e4e4
+            PQGParams pqg, KeyPairGeneratorSpi.Usage[] usageList, boolean temp) throws EBaseException {
b1e4e4
         KeyPairAlgorithm kpAlg = null;
b1e4e4
 
b1e4e4
         if (alg.equals("RSA"))
b1e4e4
@@ -1738,7 +1742,7 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove
b1e4e4
             kpAlg = KeyPairAlgorithm.DSA;
b1e4e4
 
b1e4e4
         try {
b1e4e4
-            KeyPair kp = generateKeyPair(kpAlg, keySize, keyCurve, pqg, usageList);
b1e4e4
+            KeyPair kp = generateKeyPair(kpAlg, keySize, keyCurve, pqg, usageList, temp);
b1e4e4
 
b1e4e4
             return kp;
b1e4e4
         } catch (InvalidParameterException e) {
b1e4e4
@@ -1761,6 +1765,13 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove
b1e4e4
             KeyPairGeneratorSpi.Usage[] usageList )
b1e4e4
             throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
b1e4e4
             InvalidParameterException, PQGParamGenException {
b1e4e4
+        return generateKeyPair(kpAlg, keySize, keyCurve, pqg, usageList, true);
b1e4e4
+    }
b1e4e4
+    public KeyPair generateKeyPair(
b1e4e4
+            KeyPairAlgorithm kpAlg, int keySize, String keyCurve, PQGParams pqg,
b1e4e4
+            KeyPairGeneratorSpi.Usage[] usageList, boolean temp)
b1e4e4
+            throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
b1e4e4
+            InvalidParameterException, PQGParamGenException {
b1e4e4
 
b1e4e4
         CryptoToken token = getKeygenToken();
b1e4e4
 
b1e4e4
@@ -1780,7 +1791,7 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove
b1e4e4
         KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
b1e4e4
         IConfigStore config = CMS.getConfigStore();
b1e4e4
         IConfigStore kgConfig = config.getSubStore("kra.keygen");
b1e4e4
-        boolean tp = false;
b1e4e4
+        boolean tp = temp;
b1e4e4
         boolean sp = false;
b1e4e4
         boolean ep = false;
b1e4e4
         if ((kgConfig != null) && (!kgConfig.equals(""))) {
b1e4e4
diff --git a/base/kra/src/com/netscape/kra/RecoveryService.java b/base/kra/src/com/netscape/kra/RecoveryService.java
b1e4e4
index 4f2add9..fc6edeb 100644
b1e4e4
--- a/base/kra/src/com/netscape/kra/RecoveryService.java
b1e4e4
+++ b/base/kra/src/com/netscape/kra/RecoveryService.java
b1e4e4
@@ -170,7 +170,13 @@ public class RecoveryService implements IService {
b1e4e4
 
b1e4e4
                 // serverKeygenP12Pass = request.getExtDataInString("serverSideKeygenP12Passwd");
b1e4e4
                 byte[] sessionWrappedPassphrase = (byte[]) request.getExtDataInByteArray("serverSideKeygenP12PasswdEnc");
b1e4e4
+                if (sessionWrappedPassphrase == null) {
b1e4e4
+                    throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR" + "Server-Side Keygen Enroll Key Retrieval: sessionWrappedPassphrase not found in Request"));
b1e4e4
+                }
b1e4e4
                 byte[] transWrappedSessionKey = (byte[]) request.getExtDataInByteArray("serverSideKeygenP12PasswdTransSession");
b1e4e4
+                if (transWrappedSessionKey == null) {
b1e4e4
+                    throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR" + "Server-Side Keygen Enroll Key Retrieval: transWrappedSessionKey not found in Request"));
b1e4e4
+                }
b1e4e4
 
b1e4e4
                 // unwrap session key
b1e4e4
                 /* TODO: get nickname from config */
b1e4e4
@@ -190,8 +196,10 @@ public class RecoveryService implements IService {
b1e4e4
                         transWrappedSessionKey,
b1e4e4
                         KeyWrapAlgorithm.RSA);
b1e4e4
 
b1e4e4
-                if (unwrappedSessionKey == null)
b1e4e4
+                if (unwrappedSessionKey == null) {
b1e4e4
                     CMS.debug("RecoveryService: serviceRequest: unwrappedSessionKey null");
b1e4e4
+                    throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_ERROR" + "Server-Side Keygen Enroll Key Retrieval: CryptoUtil.unwrap failed on unwrappedSessionKey"));
b1e4e4
+                }
b1e4e4
 
b1e4e4
                 // decrypt p12 passphrase
b1e4e4
                 EncryptionAlgorithm encryptAlgorithm =
b1e4e4
@@ -230,7 +238,6 @@ public class RecoveryService implements IService {
b1e4e4
                 request.getRequestId());
b1e4e4
 
b1e4e4
         if (params == null) {
b1e4e4
-            //cfu
b1e4e4
             if (isSSKeygen) {
b1e4e4
                 params = new Hashtable<String, Object>();
b1e4e4
                 params.put(RecoveryService.ATTR_TRANSPORT_PWD, serverKeygenP12Pass);
b1e4e4
@@ -671,6 +678,16 @@ public class RecoveryService implements IService {
b1e4e4
             }
b1e4e4
         }
b1e4e4
 
b1e4e4
+        /* TODO
b1e4e4
+        if (isSSKeygen) {
b1e4e4
+            signedAuditLogger.log(new ServerSideKeygenEnrollKeyRetrievalProcessedEvent(
b1e4e4
+                        auditSubjectID,
b1e4e4
+                        "Success",
b1e4e4
+                        request.getRequestId(),
b1e4e4
+                        clientKeyId,
b1e4e4
+                        null));
b1e4e4
+        }
b1e4e4
+        */
b1e4e4
         // update request
b1e4e4
         mKRA.getRequestQueue().updateRequest(request);
b1e4e4
     }
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
b1e4e4
index 2c539f0..138a2ec 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
b1e4e4
@@ -35,6 +35,9 @@ import com.netscape.certsrv.connector.IConnector;
b1e4e4
 import com.netscape.certsrv.logging.AuditFormat;
b1e4e4
 import com.netscape.certsrv.logging.ILogger;
b1e4e4
 import com.netscape.certsrv.logging.event.SecurityDataArchivalRequestEvent;
b1e4e4
+import com.netscape.certsrv.logging.event.ServerSideKeygenEnrollKeygenEvent;
b1e4e4
+import com.netscape.certsrv.logging.event.ServerSideKeygenEnrollKeyRetrievalEvent;
b1e4e4
+import com.netscape.certsrv.profile.IEnrollProfile;
b1e4e4
 import com.netscape.certsrv.profile.EProfileException;
b1e4e4
 import com.netscape.certsrv.profile.ERejectException;
b1e4e4
 import com.netscape.certsrv.profile.IProfileUpdater;
b1e4e4
@@ -45,6 +48,7 @@ import com.netscape.cms.logging.Logger;
b1e4e4
 import com.netscape.cms.logging.SignedAuditLogger;
b1e4e4
 import com.netscape.cmsutil.crypto.CryptoUtil;
b1e4e4
 
b1e4e4
+import netscape.security.x509.CertificateSubjectName;
b1e4e4
 import netscape.security.x509.CertificateX509Key;
b1e4e4
 import netscape.security.x509.X500Name;
b1e4e4
 import netscape.security.x509.X509CertImpl;
b1e4e4
@@ -104,7 +108,7 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
             throw new EProfileException("No CA Service");
b1e4e4
         }
b1e4e4
 
b1e4e4
-        //cfu: if isServerSideKeygen, send keygen request to KRA
b1e4e4
+        // if isServerSideKeygen, send keygen request to KRA
b1e4e4
         boolean isSSKeygen = false;
b1e4e4
         String isSSKeygenStr = request.getExtDataInString("isServerSideKeygen");
b1e4e4
         if (isSSKeygenStr != null && isSSKeygenStr.equalsIgnoreCase("true")) {
b1e4e4
@@ -114,10 +118,20 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
             CMS.debug(method + "isServerSideKeygen = false");
b1e4e4
         }
b1e4e4
 
b1e4e4
+        // prepare for auditing
b1e4e4
+        CertificateSubjectName reqSubj =
b1e4e4
+                request.getExtDataInCertSubjectName(IEnrollProfile.REQUEST_SUBJECT_NAME);
b1e4e4
+        String clientId = "unknown serverKeyGenUser";
b1e4e4
+        if (reqSubj != null) {
b1e4e4
+            X500Name xN = reqSubj.getX500Name();
b1e4e4
+            clientId = xN.toString();
b1e4e4
+            CMS.debug(method + "clientId = " + clientId);
b1e4e4
+        }
b1e4e4
+
b1e4e4
         // if PKI Archive Option present, send this request
b1e4e4
         // to DRM
b1e4e4
         byte optionsData[] = request.getExtDataInByteArray(REQUEST_ARCHIVE_OPTIONS);
b1e4e4
-        if (isSSKeygen) { // cfu
b1e4e4
+        if (isSSKeygen) { // Server-Side Keygen enrollment
b1e4e4
             request.setExtData(IRequest.SSK_STAGE, IRequest.SSK_STAGE_KEYGEN);
b1e4e4
             try {
b1e4e4
                 IConnector kraConnector = caService.getKRAConnector();
b1e4e4
@@ -148,26 +162,23 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
                             throw new ERejectException(CMS.getUserMessage("CMS_CA_SEND_KRA_REQUEST")+ " check KRA log for detail");
b1e4e4
                         }
b1e4e4
                     }
b1e4e4
-/*
b1e4e4
-                        signedAuditLogger.log(SecurityDataArchivalRequestEvent.createSuccessEvent(
b1e4e4
-                                auditSubjectID,
b1e4e4
-                                auditRequesterID,
b1e4e4
-                                requestId,
b1e4e4
-                                null));
b1e4e4
-*/
b1e4e4
+                    // TODO: perhaps have Server-Side Keygen enrollment audit
b1e4e4
+                    // event, or expand AsymKeyGenerationEvent
b1e4e4
+                    signedAuditLogger.log(new ServerSideKeygenEnrollKeygenEvent(
b1e4e4
+                            auditSubjectID,
b1e4e4
+                            "Success",
b1e4e4
+                            requestId,
b1e4e4
+                            clientId));
b1e4e4
                 }
b1e4e4
             } catch (Exception e) {
b1e4e4
 
b1e4e4
                 CMS.debug(method + e);
b1e4e4
 
b1e4e4
-/*
b1e4e4
-                    signedAuditLogger.log(SecurityDataArchivalRequestEvent.createFailureEvent(
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeygenEvent(
b1e4e4
                             auditSubjectID,
b1e4e4
-                            auditRequesterID,
b1e4e4
+                            "Failure",
b1e4e4
                             requestId,
b1e4e4
-                            null,
b1e4e4
-                            e));
b1e4e4
-*/
b1e4e4
+                            clientId));
b1e4e4
 
b1e4e4
                 if (e instanceof ERejectException) {
b1e4e4
                     throw (ERejectException) e;
b1e4e4
@@ -256,17 +267,22 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
         // process certificate issuance
b1e4e4
         X509CertInfo info = request.getExtDataInCertInfo(REQUEST_CERTINFO);
b1e4e4
 
b1e4e4
-        if (isSSKeygen) { // cfu
b1e4e4
+        if (isSSKeygen) {
b1e4e4
             try {
b1e4e4
                 String pubKeyStr = request.getExtDataInString("public_key");
b1e4e4
-                CMS.debug(method + "pubKeyStr = " + pubKeyStr);
b1e4e4
+                if (pubKeyStr == null) {
b1e4e4
+                    throw new EProfileException("Server-Side Keygen enrollment failed to retrieve public_key from KRA");
b1e4e4
+                }
b1e4e4
+                //CMS.debug(method + "pubKeyStr = " + pubKeyStr);
b1e4e4
                 byte[] pubKeyB = CryptoUtil.base64Decode(pubKeyStr);
b1e4e4
                 CertificateX509Key certKey = new CertificateX509Key(
b1e4e4
                     new ByteArrayInputStream(pubKeyB));
b1e4e4
                 Object oj = info.get(X509CertInfo.KEY);
b1e4e4
                 if (oj != null) {
b1e4e4
+                    // a placeholder temporary fake key was put in
b1e4e4
+                    // ServerKeygenUserKeyDefault
b1e4e4
                     info.delete(X509CertInfo.KEY);
b1e4e4
-                    CMS.debug(method + " fake key deleted");
b1e4e4
+                    //CMS.debug(method + " fake key deleted");
b1e4e4
                 }
b1e4e4
                 info.set(X509CertInfo.KEY, certKey);
b1e4e4
             } catch (IOException e) {
b1e4e4
@@ -303,10 +319,11 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
 
b1e4e4
         request.setExtData(REQUEST_ISSUED_CERT, theCert);
b1e4e4
 
b1e4e4
-        //cfu: cert issued, now retrieve p12
b1e4e4
+        // cert issued, now retrieve p12
b1e4e4
         if (isSSKeygen) {
b1e4e4
             CMS.debug(method + "onto SSK_STAGE_KEY_RETRIEVE");
b1e4e4
             request.setExtData(IRequest.SSK_STAGE, IRequest.SSK_STAGE_KEY_RETRIEVE);
b1e4e4
+            request.setExtData(IRequest.REQ_STATUS, "begin");
b1e4e4
             request.setExtData("requestType", "recovery");
b1e4e4
             request.setExtData("cert", theCert); //recognized by kra
b1e4e4
             try {
b1e4e4
@@ -338,25 +355,22 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
                             throw new ERejectException(CMS.getUserMessage("CMS_CA_SEND_KRA_REQUEST")+ " check KRA log for detail");
b1e4e4
                         }
b1e4e4
                     }
b1e4e4
-/*
b1e4e4
-                        signedAuditLogger.log(SecurityDataArchivalRequestEvent.createSuccessEvent(
b1e4e4
+
b1e4e4
+                    signedAuditLogger.log(new ServerSideKeygenEnrollKeyRetrievalEvent(
b1e4e4
                                 auditSubjectID,
b1e4e4
-                                auditRequesterID,
b1e4e4
+                                "Success",
b1e4e4
                                 requestId,
b1e4e4
-                                null));
b1e4e4
-*/
b1e4e4
+                                clientId));
b1e4e4
                 }
b1e4e4
             } catch (Exception e) {
b1e4e4
 
b1e4e4
                 CMS.debug(method + e);
b1e4e4
-/*
b1e4e4
-                    signedAuditLogger.log(SecurityDataArchivalRequestEvent.createFailureEvent(
b1e4e4
+
b1e4e4
+                signedAuditLogger.log(new ServerSideKeygenEnrollKeyRetrievalEvent(
b1e4e4
                             auditSubjectID,
b1e4e4
-                            auditRequesterID,
b1e4e4
+                            "Failure",
b1e4e4
                             requestId,
b1e4e4
-                            null,
b1e4e4
-                            e));
b1e4e4
-*/
b1e4e4
+                            clientId));
b1e4e4
 
b1e4e4
                 if (e instanceof ERejectException) {
b1e4e4
                     throw (ERejectException) e;
b1e4e4
@@ -364,12 +378,6 @@ public class CAEnrollProfile extends EnrollProfile {
b1e4e4
                 throw new EProfileException(e);
b1e4e4
             }
b1e4e4
             CMS.debug(method + "isSSKeygen: response received from KRA");
b1e4e4
-            byte p12bytes[] = request.getExtDataInByteArray("pkcs12");
b1e4e4
-            if (p12bytes != null) {
b1e4e4
-                CMS.debug(method + "p12bytes not null");
b1e4e4
-            } else {
b1e4e4
-                CMS.debug(method + "p12bytes null");
b1e4e4
-            }
b1e4e4
         }
b1e4e4
 
b1e4e4
         long endTime = CMS.getCurrentDate().getTime();
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
index 13a8dec..1e2a787 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
b1e4e4
@@ -20,6 +20,7 @@ package com.netscape.cms.profile.def;
b1e4e4
 import java.io.ByteArrayInputStream;
b1e4e4
 import java.math.BigInteger;
b1e4e4
 import java.security.interfaces.DSAParams;
b1e4e4
+import java.util.Enumeration;
b1e4e4
 import java.util.Locale;
b1e4e4
 import java.util.Vector;
b1e4e4
 import java.security.KeyPair;
b1e4e4
@@ -29,6 +30,8 @@ import netscape.security.provider.DSAPublicKey;
b1e4e4
 import netscape.security.provider.RSAPublicKey;
b1e4e4
 import netscape.security.x509.AlgorithmId;
b1e4e4
 import netscape.security.x509.CertificateX509Key;
b1e4e4
+import netscape.security.x509.CertificateSubjectName;
b1e4e4
+import netscape.security.x509.X500Name;
b1e4e4
 import netscape.security.x509.X509CertImpl;
b1e4e4
 import netscape.security.x509.X509CertInfo;
b1e4e4
 import netscape.security.x509.X509Key;
b1e4e4
@@ -54,6 +57,8 @@ import org.mozilla.jss.crypto.KeyWrapAlgorithm;
b1e4e4
 import org.mozilla.jss.crypto.SymmetricKey;
b1e4e4
 import org.mozilla.jss.crypto.X509Certificate;
b1e4e4
 
b1e4e4
+import com.netscape.certsrv.logging.ILogger;
b1e4e4
+
b1e4e4
 /**
b1e4e4
  * This class implements an enrollment default policy
b1e4e4
  * for Server-Side keygen enrollment.
b1e4e4
@@ -68,10 +73,14 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
     public static final String VAL_LEN = "LEN";
b1e4e4
     public static final String VAL_TYPE = "TYPE";
b1e4e4
 
b1e4e4
-    private static final String TEMP_PUBKEY_1024 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBz6H2rT2r1RpHdr3JyYr7thSjfwWPbIJ6U09NziHSekLsNZQKsjdLS/LPCfe/aXkhpzPztlx++tkPucpt/xT0exp08feAPIE+Y6gVoyXzEw+Ztz+Zez9Y1cQWxAyp7z11flytjL+4zBGDXmEoe3ZlQvij9DGypPjBC9PhWm0lBwIDAQAB";
b1e4e4
-    private static final String TEMP_PUBKEY_2048 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4Ha+CxWDPAHEl9+u57U3UCw8bfG/ZN3cVTrQgj/p8ak12NYUWt0ZI/xCcLj7gKwFPbNMTDwzizRPZuxKJT7fHgW8a1BQDUL2VGfx7O0A7KlLqcpVc6VKsQx5caP3hrB38Q5xnTKeVee9cBrd8An+veZ2QV6mHLEU8iMCN2No/t1oO+aYje42XloNRblXVQAOYW+3aMCam2kIKWUqLvA3Sbf2BPR2x5SSZRPHJt3hQCheara5j+nHLQ8paRvVlT+ghgyX5N3BwiPmvC+e9iUaaofj+DxrGX3cTo5hehG2b71sY3xdC5OIhEGRfkAqIAEw6eaU6a/ymNsByRgVByfQaQIDAQAB";
b1e4e4
-    private static final String TEMP_PUBKEY_3072 = "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAm0yQ0y+8YOTWkye5qFuqNI/qC4wtjEjNnoZaqSZUOJLg6ZRDlsZoOiblJpw65rPjaPcSp/inqYfCCA5mISYaqfcoB80LCnw1+DAv8tcvwUtytQYXHVj2gbyuVHaBgD4n4j/wFV80sF3OTQcPKYmeTfWRtv2xZQMK9rYfa8Le+DAZyOWPk4+RtTIRPa5R9arLqE+ONgUcrD3NvewOdsCrT7flJnFdx8TGl5ftxVWYlHRSg+wEB8pQZlw0BSDlQGHXIRjBKT2+iCkYzuKPWpMbu42PnBaQTcvjD3cl8MjLQcZp6v39bU1Du0C0LYunhvIWidwKnCOGOYu+a0VKuHxH8odjFdPoWGmP+orllkwSZzhWayYJxGpJJQlWcM05uD6qDF67WQnuYsliVH4LNiSjf/iPSpr0tzDXOtdeVsiQgO9wYYlnooBtd1xfTmkILwt3j9ZXeBtmt4lLYxbLo2ZCzkFqCCdu5FfcFgxjPaRaW0bQHKuP1woGk0rDUUbuqr+PAgMBAAE=";
b1e4e4
-    private static final String TEMP_PUBKEY_4096 = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs3xoddtoCQrDpPK/45DpN/wPHO/6qrsbEDnwEnSkcLz51WHb7+CEUP9oxuE8vPn9JXcLdZkgPcmfMVibSUEJVUCXPibGTqAJ/7RAAm+/FhdL02N57hpgLzbIPbIaTP00z/jbTqR4a0uV49fnEPqrhA/KoUmOn3eoiAPAB5xNSauFOmMZXv2gr4akNxvSiZ/59ddYF+DBEFSs4ufCqIqBWYAMMo78eskgm/ZUyv7OZzG+8c1nncdnrNk/JtXauANu8NUQXX2qllmEOioY6gnalpR26fwOscjkvHDTvRQmSIqceWdd5P6OMHJwzTVG8d4b0f150o1RTzU3gvg9/qXvbOGcnH2TXZjYi02mhyXgPrimZepKyDr2LjeAEZbfAAXecaMhjrDZEkDZNFWe4eoG2JuE34TODeiCLMBql6VTgOvCFW3to32aBwNLpCV4hi5rKLnPMlf8Tz0zYvGqDeCp4zzy6C9tosiYfHIkVU/AVqK9PoY0RsLnBzHOV7Jl2VgHr8Ro+C66+leajssAemK8swcj2AZEOuVLlsdCvguUn6XUyDqI3tIfnoLK690hG1znuIWzFZzzivZ5ZwgfxguCly9zDArc7i6YHxOR2lcUrM0VfHmyHpE9JNfarEgAPS59ASG7y14LOvp4yYKNz10TtetwkSfpcjqiuWHtIDi9sjMCAwEAAQ==";
b1e4e4
+    //  DO NOT REMOVE
b1e4e4
+    private static final String TEMP_PUBKEY_RSA_1024 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBz6H2rT2r1RpHdr3JyYr7thSjfwWPbIJ6U09NziHSekLsNZQKsjdLS/LPCfe/aXkhpzPztlx++tkPucpt/xT0exp08feAPIE+Y6gVoyXzEw+Ztz+Zez9Y1cQWxAyp7z11flytjL+4zBGDXmEoe3ZlQvij9DGypPjBC9PhWm0lBwIDAQAB";
b1e4e4
+    private static final String TEMP_PUBKEY_RSA_2048 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4Ha+CxWDPAHEl9+u57U3UCw8bfG/ZN3cVTrQgj/p8ak12NYUWt0ZI/xCcLj7gKwFPbNMTDwzizRPZuxKJT7fHgW8a1BQDUL2VGfx7O0A7KlLqcpVc6VKsQx5caP3hrB38Q5xnTKeVee9cBrd8An+veZ2QV6mHLEU8iMCN2No/t1oO+aYje42XloNRblXVQAOYW+3aMCam2kIKWUqLvA3Sbf2BPR2x5SSZRPHJt3hQCheara5j+nHLQ8paRvVlT+ghgyX5N3BwiPmvC+e9iUaaofj+DxrGX3cTo5hehG2b71sY3xdC5OIhEGRfkAqIAEw6eaU6a/ymNsByRgVByfQaQIDAQAB";
b1e4e4
+    private static final String TEMP_PUBKEY_RSA_3072 = "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAm0yQ0y+8YOTWkye5qFuqNI/qC4wtjEjNnoZaqSZUOJLg6ZRDlsZoOiblJpw65rPjaPcSp/inqYfCCA5mISYaqfcoB80LCnw1+DAv8tcvwUtytQYXHVj2gbyuVHaBgD4n4j/wFV80sF3OTQcPKYmeTfWRtv2xZQMK9rYfa8Le+DAZyOWPk4+RtTIRPa5R9arLqE+ONgUcrD3NvewOdsCrT7flJnFdx8TGl5ftxVWYlHRSg+wEB8pQZlw0BSDlQGHXIRjBKT2+iCkYzuKPWpMbu42PnBaQTcvjD3cl8MjLQcZp6v39bU1Du0C0LYunhvIWidwKnCOGOYu+a0VKuHxH8odjFdPoWGmP+orllkwSZzhWayYJxGpJJQlWcM05uD6qDF67WQnuYsliVH4LNiSjf/iPSpr0tzDXOtdeVsiQgO9wYYlnooBtd1xfTmkILwt3j9ZXeBtmt4lLYxbLo2ZCzkFqCCdu5FfcFgxjPaRaW0bQHKuP1woGk0rDUUbuqr+PAgMBAAE=";
b1e4e4
+    private static final String TEMP_PUBKEY_RSA_4096 = "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs3xoddtoCQrDpPK/45DpN/wPHO/6qrsbEDnwEnSkcLz51WHb7+CEUP9oxuE8vPn9JXcLdZkgPcmfMVibSUEJVUCXPibGTqAJ/7RAAm+/FhdL02N57hpgLzbIPbIaTP00z/jbTqR4a0uV49fnEPqrhA/KoUmOn3eoiAPAB5xNSauFOmMZXv2gr4akNxvSiZ/59ddYF+DBEFSs4ufCqIqBWYAMMo78eskgm/ZUyv7OZzG+8c1nncdnrNk/JtXauANu8NUQXX2qllmEOioY6gnalpR26fwOscjkvHDTvRQmSIqceWdd5P6OMHJwzTVG8d4b0f150o1RTzU3gvg9/qXvbOGcnH2TXZjYi02mhyXgPrimZepKyDr2LjeAEZbfAAXecaMhjrDZEkDZNFWe4eoG2JuE34TODeiCLMBql6VTgOvCFW3to32aBwNLpCV4hi5rKLnPMlf8Tz0zYvGqDeCp4zzy6C9tosiYfHIkVU/AVqK9PoY0RsLnBzHOV7Jl2VgHr8Ro+C66+leajssAemK8swcj2AZEOuVLlsdCvguUn6XUyDqI3tIfnoLK690hG1znuIWzFZzzivZ5ZwgfxguCly9zDArc7i6YHxOR2lcUrM0VfHmyHpE9JNfarEgAPS59ASG7y14LOvp4yYKNz10TtetwkSfpcjqiuWHtIDi9sjMCAwEAAQ==";
b1e4e4
+    private static final String TEMP_PUBKEY_EC_NISTP256 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEw67JdXDj1J3wwvLTYtzpyUArev/Ra2QEsHo+q5P3VcDrr0HqJGXsj5/vH7bPe4WG5OkgxmL5BiBpKpTmJMxNLg==";
b1e4e4
+    private static final String TEMP_PUBKEY_EC_NISTP384 = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEdjuCVoP3qykxs97Wjk2k/cEE6fza0N0Y8JRzLYNrFtOti4zKNpvYcteaYTWLKYGOUEgGuOBV9lWjEbZSH5n+AqKf+JLaTu+Qytsr9OnBu3L4r18yNdWQQo/LlaLkr5on";
b1e4e4
+    private static final String TEMP_PUBKEY_EC_NISTP521 = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAnGS6GRhXMwgKu+0G7BHWbu99h4KoZi4vzKvJ+QmoApZbaU0A83ayHhKp6c5mubgZY7Vq1/msGxju89QqOf25nNwBOl9Y0IYG+/LMSjtSR1rU+MI00iyrjx3GgnC0lbxZD6KiPqMNlx5h4oyiy6d+xYfIweSF+QYVm53s4Q4OWVEhz54=";
b1e4e4
 
b1e4e4
     public ServerKeygenUserKeyDefault() {
b1e4e4
         super();
b1e4e4
@@ -254,11 +263,10 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
             throws EProfileException {
b1e4e4
         CertificateX509Key certKey = null;
b1e4e4
         String method = "ServerKeygenUserKeyDefault: populate: ";
b1e4e4
-        CMS.debug(method + "in here");
b1e4e4
+        CMS.debug(method + "begins");
b1e4e4
 
b1e4e4
         // trigger serverSide keygen enrollment
b1e4e4
         try {
b1e4e4
-            // Todo: remove debug test print; encrypt the passwd
b1e4e4
             String p12passwd = request.getExtDataInString("serverSideKeygenP12Passwd");
b1e4e4
             if (p12passwd == null || p12passwd.length() == 0) {
b1e4e4
                 CMS.debug(method + "p12passwd not found");
b1e4e4
@@ -270,7 +278,8 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
             CryptoManager cm = CryptoManager.getInstance();
b1e4e4
             org.mozilla.jss.crypto.X509Certificate transCert = null;
b1e4e4
             try {
b1e4e4
-                transCert = cm.findCertByNickname("KRA Transport Certificate");
b1e4e4
+                String transportNickname = CMS.getConfigStore().getString("ca.connector.KRA.transportCertNickname", "KRA Transport Certificate");
b1e4e4
+                transCert = cm.findCertByNickname(transportNickname);
b1e4e4
             } catch (Exception e) {
b1e4e4
                 CMS.debug(method + "'KRA transport certificate' not found in nssdb; need to be manually setup for Server-Side keygen enrollment");
b1e4e4
                 throw new EPropertyException(CMS.getUserMessage("CMS_MISSING_KRA_TRANSPORT_CERT_IN_CA_NSSDB"));
b1e4e4
@@ -323,7 +332,17 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
                         wrapAlgorithm);
b1e4e4
                 CMS.debug(method + " transWrappedSessionKey.length =" +transWrappedSessionKey.length);
b1e4e4
 
b1e4e4
+                CertificateSubjectName reqSubj =
b1e4e4
+                        request.getExtDataInCertSubjectName(IEnrollProfile.REQUEST_SUBJECT_NAME);
b1e4e4
+                String subj = "unknown serverKeyGenUser";
b1e4e4
+                if (reqSubj != null) {
b1e4e4
+                    X500Name xN = reqSubj.getX500Name();
b1e4e4
+                    subj = xN.toString();
b1e4e4
+                    CMS.debug(method + "subj = " + subj);
b1e4e4
+                }
b1e4e4
                 // store in request to pass to kra
b1e4e4
+                request.setExtData(IRequest.SECURITY_DATA_CLIENT_KEY_ID,
b1e4e4
+                        subj);
b1e4e4
                 request.setExtData("serverSideKeygenP12PasswdEnc",
b1e4e4
                         sessionWrappedPassphrase);
b1e4e4
                 request.setExtData("serverSideKeygenP12PasswdTransSession",
b1e4e4
@@ -339,7 +358,7 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
             String keyTypeStr = request.getExtDataInString("keyType");
b1e4e4
             String keyType = "RSA";
b1e4e4
             int keySize = 2048;
b1e4e4
-            String curveName = "nistp521";
b1e4e4
+            String curveName = "nistp256";
b1e4e4
 
b1e4e4
             // Populate the keyType and keySize/keyCurve
b1e4e4
 
b1e4e4
@@ -350,6 +369,7 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
                 CMS.debug("ServerKeygenUserKeyDefault: populate: keyType in request null; default to RSA");
b1e4e4
             }
b1e4e4
 
b1e4e4
+            boolean isEC = false;
b1e4e4
             String keySizeCurveStr = request.getExtDataInString("keySize");
b1e4e4
 
b1e4e4
             if (keyType.contentEquals("RSA")) {
b1e4e4
@@ -361,6 +381,7 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
                 }
b1e4e4
                 // Do things when RSA is selected
b1e4e4
             } else if (keyType.contentEquals("EC")) {
b1e4e4
+                isEC = true;
b1e4e4
                 // TODO: dmoluguw: Fix the following to generate right Key ECC keys
b1e4e4
 
b1e4e4
                 if (keySizeCurveStr != null && !keySizeCurveStr.isEmpty()) {
b1e4e4
@@ -383,31 +404,49 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
b1e4e4
             }
b1e4e4
 
b1e4e4
             /*
b1e4e4
-             * it is necessary to  put in a static fake key here to prevent
b1e4e4
-             * issue; The fake key will be replaced later once KRA generates
b1e4e4
-             * the real keys
b1e4e4
+             * DO NOT REMOVE
b1e4e4
+             * currently, it is necessary to  put in a static placeholder fake
b1e4e4
+             * key here to prevent issue; The fake key will be replaced later
b1e4e4
+             * once KRA generates the real keys
b1e4e4
+             *
b1e4e4
+             * TODO: perhaps find out how to get around not breaking
b1e4e4
+             * the code without fake keys
b1e4e4
              */
b1e4e4
 
b1e4e4
-            // dmoluguw: TODO: The below values seem to be for development purposes,
b1e4e4
-            // and will probably work only with keyType="RSA"
b1e4e4
-
b1e4e4
             String pubKeyStr = "";
b1e4e4
-            switch (keySize) {
b1e4e4
+            if (!isEC) {
b1e4e4
+              switch (keySize) {
b1e4e4
                 case 1024:
b1e4e4
-                    pubKeyStr = TEMP_PUBKEY_1024;
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_RSA_1024;
b1e4e4
                     break;
b1e4e4
                 case 2048:
b1e4e4
-                    pubKeyStr = TEMP_PUBKEY_2048;
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_RSA_2048;
b1e4e4
                     break;
b1e4e4
                 case 3072:
b1e4e4
-                    pubKeyStr = TEMP_PUBKEY_3072;
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_RSA_3072;
b1e4e4
                     break;
b1e4e4
                 case 4096:
b1e4e4
-                    pubKeyStr = TEMP_PUBKEY_4096;
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_RSA_4096;
b1e4e4
                     break;
b1e4e4
                 default:
b1e4e4
                     CMS.debug("ServerKeygenUserKeyDefault: populate: unsupported keySize: " + keySize);
b1e4e4
                     break;
b1e4e4
+              }
b1e4e4
+            } else {
b1e4e4
+              switch (curveName) {
b1e4e4
+                case "nistp256":
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_EC_NISTP256;
b1e4e4
+                    break;
b1e4e4
+                case "nistp384":
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_EC_NISTP384;
b1e4e4
+                    break;
b1e4e4
+                case "nistp521":
b1e4e4
+                    pubKeyStr = TEMP_PUBKEY_EC_NISTP521;
b1e4e4
+                    break;
b1e4e4
+                default:
b1e4e4
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: unsupported cureveName: " + curveName);
b1e4e4
+                    break;
b1e4e4
+              }
b1e4e4
             }
b1e4e4
             byte[] certKeyData = CryptoUtil.base64Decode(pubKeyStr);
b1e4e4
             if (certKeyData != null) {
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
b1e4e4
index 145fd5f..0c65702 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/base/CMSServlet.java
b1e4e4
@@ -573,7 +573,6 @@ public abstract class CMSServlet extends HttpServlet {
b1e4e4
 
b1e4e4
     protected void outputArgBlockAsXML(XMLObject xmlObj, Node parent,
b1e4e4
                                        String argBlockName, IArgBlock argBlock) {
b1e4e4
-        CMS.debug("CMSServlet:outputArgBlockAsXML: begins");
b1e4e4
         Node argBlockContainer = xmlObj.createContainer(parent, argBlockName);
b1e4e4
 
b1e4e4
         if (argBlock != null) {
b1e4e4
@@ -585,11 +584,9 @@ public abstract class CMSServlet extends HttpServlet {
b1e4e4
                 xmlObj.addItemToContainer(argBlockContainer, name, val);
b1e4e4
             }
b1e4e4
         }
b1e4e4
-        CMS.debug("CMSServlet:outputArgBlockAsXML: ends");
b1e4e4
     }
b1e4e4
 
b1e4e4
     protected void outputXML(HttpServletResponse httpResp, CMSTemplateParams params) {
b1e4e4
-        CMS.debug("CMSServlet:outputXML: begins");
b1e4e4
         XMLObject xmlObj = null;
b1e4e4
         try {
b1e4e4
             xmlObj = new XMLObject();
b1e4e4
@@ -616,7 +613,6 @@ public abstract class CMSServlet extends HttpServlet {
b1e4e4
         } catch (Exception e) {
b1e4e4
             CMS.debug("failed in outputing XML " + e);
b1e4e4
         }
b1e4e4
-        CMS.debug("CMSServlet:outputXML: ends");
b1e4e4
     }
b1e4e4
 
b1e4e4
     protected void renderTemplate(
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
b1e4e4
index b369fc8..5d39f24 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
b1e4e4
@@ -450,17 +450,20 @@ public class ConnectorServlet extends CMSServlet {
b1e4e4
         try {
b1e4e4
             IRequestQueue queue = mAuthority.getRequestQueue();
b1e4e4
             String srcid = source + ":" + msg.getReqId();
b1e4e4
+            CMS.debug("ConnectorServlet:processRequest: srcid =" + srcid);
b1e4e4
 
b1e4e4
             // find request in request queue and return result.
b1e4e4
             RequestId thisreqid = queue.findRequestBySourceId(srcid);
b1e4e4
             IRequest thisreq = null;
b1e4e4
 
b1e4e4
             if (thisreqid != null) {
b1e4e4
+                CMS.debug("ConnectorServlet:processRequest: thisreqid not null:" + thisreqid);
b1e4e4
                 thisreq = queue.findRequest(thisreqid);
b1e4e4
                 if (thisreq == null) {
b1e4e4
                     // strange case.
b1e4e4
                     String errormsg = "Cannot find request in request queue " +
b1e4e4
                             thisreqid;
b1e4e4
+                    CMS.debug("ConnectorServlet:processRequest: " + errormsg);
b1e4e4
 
b1e4e4
                     mAuthority.log(ILogger.LL_FAILURE,
b1e4e4
                             CMS.getLogMessage(
b1e4e4
@@ -484,8 +487,18 @@ public class ConnectorServlet extends CMSServlet {
b1e4e4
 
b1e4e4
                     throw new EBaseException(errormsg);
b1e4e4
                 } else {
b1e4e4
-                    mAuthority.log(ILogger.LL_INFO,
b1e4e4
-                            "Found request " + thisreqid + " for " + srcid);
b1e4e4
+                    String errormsg = "Found request " + thisreqid + " for " + srcid;
b1e4e4
+                    // for Server-Side Keygen, it could be the 2nd trip
b1e4e4
+                    // where stage was Request.SSK_STAGE_KEYGEN going on
b1e4e4
+                    // IRequest.SSK_STAGE_KEY_RETRIEVE
b1e4e4
+                    String sskKeygenStage = thisreq.getExtDataInString(IRequest.SSK_STAGE);
b1e4e4
+                    if (sskKeygenStage!= null && sskKeygenStage.equalsIgnoreCase(IRequest.SSK_STAGE_KEYGEN)) {
b1e4e4
+                        CMS.debug("ConnectorServlet:processRequest: Stage=" + sskKeygenStage);
b1e4e4
+                    } else {
b1e4e4
+
b1e4e4
+                    mAuthority.log(ILogger.LL_INFO, errormsg);
b1e4e4
+                    CMS.debug("ConnectorServlet:processRequest: " + errormsg);
b1e4e4
+
b1e4e4
                     replymsg = CMS.getHttpPKIMessage();
b1e4e4
                     replymsg.fromRequest(thisreq);
b1e4e4
 
b1e4e4
@@ -505,13 +518,14 @@ public class ConnectorServlet extends CMSServlet {
b1e4e4
                     //        does not yet matter at this point!
b1e4e4
 
b1e4e4
                     return replymsg;
b1e4e4
+                    }
b1e4e4
                 }
b1e4e4
             }
b1e4e4
 
b1e4e4
-/*
b1e4e4
-            // cfu: let's find out what's in the request
b1e4e4
+            thisreq = queue.newRequest(msg.getReqType());
b1e4e4
+            /* cfu: let's find out what's in the request
b1e4e4
+            CMS.debug("ConnectorServlet: cfu see what's in request");
b1e4e4
             Enumeration<String> ereq = thisreq.getExtDataKeys();
b1e4e4
-
b1e4e4
             while (ereq.hasMoreElements()) {
b1e4e4
                 String reqKey = ereq.nextElement();
b1e4e4
                 String reqVal = thisreq.getExtDataInString(reqKey);
b1e4e4
@@ -521,14 +535,9 @@ public class ConnectorServlet extends CMSServlet {
b1e4e4
                     CMS.debug("ConnectorServlet: - " + reqKey + ": no value");
b1e4e4
                 }
b1e4e4
             }
b1e4e4
-*/
b1e4e4
+            */
b1e4e4
 
b1e4e4
-            thisreq = queue.newRequest(msg.getReqType());
b1e4e4
             // if not found process request.
b1e4e4
-/*cfu
b1e4e4
-            CMS.debug("ConnectorServlet: created reqType=" +msg.getReqType()+
b1e4e4
-                   " requestId=" + thisreq.getRequestId().toString() + " requestStatus=" + thisreq.getRequestStatus().toString());
b1e4e4
-*/
b1e4e4
             CMS.debug("ConnectorServlet: created requestId=" +
b1e4e4
                     thisreq.getRequestId().toString());
b1e4e4
             thisreq.setSourceId(srcid);
b1e4e4
@@ -540,6 +549,24 @@ public class ConnectorServlet extends CMSServlet {
b1e4e4
             //        then this code does NOT need to be contained within its
b1e4e4
             //        own special try/catch block.
b1e4e4
             msg.toRequest(thisreq);
b1e4e4
+            // reset CA's request dbStatus and requestStatus got inadvertantly
b1e4e4
+            // transferred over
b1e4e4
+            thisreq.setExtData("dbStatus", "NOT_UPDATED");
b1e4e4
+            thisreq.setExtData(IRequest.REQ_STATUS, "begin");
b1e4e4
+
b1e4e4
+            /* cfu: let's find out what's in the request again
b1e4e4
+            CMS.debug("ConnectorServlet: cfu see again what's in request");
b1e4e4
+            ereq = thisreq.getExtDataKeys();
b1e4e4
+            while (ereq.hasMoreElements()) {
b1e4e4
+                String reqKey = ereq.nextElement();
b1e4e4
+                String reqVal = thisreq.getExtDataInString(reqKey);
b1e4e4
+                if (reqVal != null) {
b1e4e4
+                    CMS.debug("ConnectorServlet: - " + reqKey + ": " + reqVal);
b1e4e4
+                } else {
b1e4e4
+                    CMS.debug("ConnectorServlet: - " + reqKey + ": no value");
b1e4e4
+                }
b1e4e4
+            }
b1e4e4
+            */
b1e4e4
 
b1e4e4
             boolean isSSKeygen = false;
b1e4e4
             String isSSKeygenStr = thisreq.getExtDataInString("isServerSideKeygen");
b1e4e4
diff --git a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
index f71d754..3bc1853 100644
b1e4e4
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileProcessServlet.java
b1e4e4
@@ -179,15 +179,14 @@ public class ProfileProcessServlet extends ProfileServlet {
b1e4e4
             String p12Str = req.getExtDataInString("req_issued_p12");
b1e4e4
             if (p12Str == null) {
b1e4e4
                 // not server-side keygen
b1e4e4
-                CMS.debug("ProfileProcessServlet:cfu: no p12; not server-side keygen");
b1e4e4
+                // CMS.debug("ProfileProcessServlet:cfu: no p12; not server-side keygen");
b1e4e4
                 outputTemplate(request, response, args);
b1e4e4
             } else {
b1e4e4
                 // found pkcs12 blob
b1e4e4
+                CMS.debug("ProfileProcessServlet: found p12 " /* + p12Str*/);
b1e4e4
                 byte[] p12blob = null;
b1e4e4
                 HttpServletResponse p12_response = cmsReq.getHttpResp();
b1e4e4
-                CMS.debug("ProfileProcessServlet:cfu: found p12 =" +
b1e4e4
-                    p12Str/*ing.toString()*/);
b1e4e4
-                p12blob = Utils.base64decode(p12Str/*ing.toString()*/);
b1e4e4
+                p12blob = Utils.base64decode(p12Str);
b1e4e4
                 OutputStream bos = p12_response.getOutputStream();
b1e4e4
                 p12_response.setContentType("application/x-pkcs12");
b1e4e4
                 p12_response.setContentLength(p12blob.length);
b1e4e4
diff --git a/base/server/cmsbundle/src/audit-events.properties b/base/server/cmsbundle/src/audit-events.properties
b1e4e4
index 0ff7b4e..d3ac517 100644
b1e4e4
--- a/base/server/cmsbundle/src/audit-events.properties
b1e4e4
+++ b/base/server/cmsbundle/src/audit-events.properties
b1e4e4
@@ -633,6 +633,59 @@ LOGGING_SIGNED_AUDIT_SELFTESTS_EXECUTION_2=<type=SELFTESTS_EXECUTION>:[AuditEven
b1e4e4
 # Available Audit Events - Enabled by default: Yes
b1e4e4
 #########################################################################
b1e4e4
 #
b1e4e4
+# Event: SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST
b1e4e4
+# Description: This event is used when Server-Side Keygen enrollment keygen request is made.
b1e4e4
+# Applicable subsystems: CA
b1e4e4
+# Enabled by default: Yes
b1e4e4
+# Fields:
b1e4e4
+# - SubjectID:
b1e4e4
+# - Outcome:
b1e4e4
+# - RequestID:
b1e4e4
+# - ClientID:
b1e4e4
+#
b1e4e4
+LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST=<type=SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST>:[AuditEvent=SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST]{0} Server-Side Keygen enrollment keygen request made
b1e4e4
+#
b1e4e4
+# Event: SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST_PROCESSED
b1e4e4
+# Description: This event is used when a request to do Server-Side Keygen enrollment keygen has been processed
b1e4e4
+#   is processed.
b1e4e4
+# Applicable subsystems: KRA
b1e4e4
+# Enabled by default: Yes
b1e4e4
+# Fields:
b1e4e4
+# - SubjectID:
b1e4e4
+# - Outcome:
b1e4e4
+# - RequestID:
b1e4e4
+# - ClientID:
b1e4e4
+# - FailureReason:
b1e4e4
+#
b1e4e4
+LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST_PROCESSED=<type=SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST_PROCESSED>:[AuditEvent=SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST_PROCESSED]{0} Server-Side Keygen enrollment keygen request processed
b1e4e4
+#
b1e4e4
+# Event: SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST
b1e4e4
+# Description: This event is used when Server-Side Keygen enrollment key retrieval request is made.
b1e4e4
+# Applicable subsystems: CA
b1e4e4
+# Enabled by default: Yes
b1e4e4
+# Fields:
b1e4e4
+# - SubjectID:
b1e4e4
+# - Outcome:
b1e4e4
+# - RequestID:
b1e4e4
+# - ClientID:
b1e4e4
+#
b1e4e4
+LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST=<type=SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST>:[AuditEvent=SERVER_SIDE_KEYGEN_ENROLL_KEYGEN_REQUEST]{0} Server-Side Keygen enrollment retrieval request made
b1e4e4
+#
b1e4e4
+# Event: SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST_PROCESSED
b1e4e4
+# Description: This event is used when a request to do Server-Side Keygen enrollment retrieval has been processed
b1e4e4
+#   is processed.
b1e4e4
+# Applicable subsystems: KRA
b1e4e4
+# Enabled by default: Yes
b1e4e4
+# Fields:
b1e4e4
+# - SubjectID:
b1e4e4
+# - Outcome:
b1e4e4
+# - RequestID:
b1e4e4
+# - ClientID:
b1e4e4
+# - FailureReason:
b1e4e4
+#
b1e4e4
+LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST_PROCESSED=<type=SERVER_SIDE_KEYGEN_ENROLL_KEY_RETRIEVAL_REQUEST_PROCESSED>:[AuditEvent=SERVER_SIDE_KEYGEN_ENROLL_RETRIEVAL_REQUEST_PROCESSED]{0} Server-Side Keygen enrollment retrieval request processed
b1e4e4
+#########
b1e4e4
+#
b1e4e4
 # Event: ASYMKEY_GENERATION_REQUEST
b1e4e4
 # Description: This event is used when asymmetric key generation request is made.
b1e4e4
 # Applicable subsystems: KRA
b1e4e4
diff --git a/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java b/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
b1e4e4
index 0851826..24c2f77 100644
b1e4e4
--- a/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
b1e4e4
+++ b/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
b1e4e4
@@ -568,10 +568,12 @@ public abstract class ARequestQueue
b1e4e4
 
b1e4e4
         // by default, write request to LDAP
b1e4e4
         if (delayLDAPCommit == null || !delayLDAPCommit.equals("true")) {
b1e4e4
+            CMS.debug("ARequestQueue: updateRequest(): delayLDAPCommit is false");
b1e4e4
             // TODO: use a state flag to determine whether to call
b1e4e4
             // addRequest or modifyRequest (see newRequest as well)
b1e4e4
             modifyRequest(r);
b1e4e4
-        } // else: delay the write to ldap
b1e4e4
+        }  else //: delay the write to ldap
b1e4e4
+            CMS.debug("ARequestQueue: updateRequest(): delayLDAPCommit is true");
b1e4e4
     }
b1e4e4
 
b1e4e4
     // PRIVATE functions
b1e4e4
-- 
b1e4e4
1.8.3.1
b1e4e4