diff --git a/.gitignore b/.gitignore index b341cc9..7e74580 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ /pki-core-10.2.4.tar.gz /pki-core-10.2.5.tar.gz /pki-core-10.2.6.tar.gz +/pki-core-10.3.0.a1.tar.gz diff --git a/pki-core-Add-Bound-Bind-Connection-To-Dirauth-Plugin.patch b/pki-core-Add-Bound-Bind-Connection-To-Dirauth-Plugin.patch deleted file mode 100644 index cefb52b..0000000 --- a/pki-core-Add-Bound-Bind-Connection-To-Dirauth-Plugin.patch +++ /dev/null @@ -1,311 +0,0 @@ -commit c13593770108b6d683ab3d3b43b92d67ac64a1ef -Author: Christina Fu -Date: Wed Aug 5 16:21:51 2015 -0700 - - Ticket 1531 Directory auth plugin requires LDAP anonymous binds - - - This patch adds a feature to allow a directory based authentication plugin - to use bound ldap conneciton instead of anonymous. - Two files need to be edited - 1. /conf/password.conf - add a "tag" and the password of the binding user dn to the file - e.g. externalLDAP=password123 - 2. /ca/CS.cfg - add the tag to cms.passwordlist: - e.g. cms.passwordlist=internaldb,replicationdb,externalLDAP - add the authPrefix of the auths entry for the authentication instance - e.g. externalLDAP.authPrefix=auths.instance.UserDirEnrollment - add relevant entries to the authentication instance - e.g. auths.instance.UserDirEnrollment.ldap.ldapBoundConn=true - auths.instance.UserDirEnrollment.ldap.ldapauth.authtype=BasicAuth - auths.instance.UserDirEnrollment.ldap.ldapauth.bindDN=uid=rhcs,ou=serviceaccounts,dc=EXAMPLE,dc=com - auths.instance.UserDirEnrollment.ldap.ldapauth.bindPWPrompt=externalLDAP - -diff --git a/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java -index a8a9528..d723a57 100644 ---- a/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java -+++ b/base/server/cms/src/com/netscape/cms/authentication/DirBasedAuthentication.java -@@ -84,6 +84,8 @@ public abstract class DirBasedAuthentication - protected static final String PROP_DNPATTERN = "dnpattern"; - protected static final String PROP_LDAPSTRINGATTRS = "ldapStringAttributes"; - protected static final String PROP_LDAPBYTEATTRS = "ldapByteAttributes"; -+ protected static final String PROP_LDAP_BOUND_CONN = "ldapBoundConn"; -+ protected static final String PROP_LDAP_BOUND_TAG = "ldapauth.bindPWPrompt"; - - // members - -@@ -110,6 +112,7 @@ public abstract class DirBasedAuthentication - /* whether to search for member= or member== */ - protected boolean mSearchGroupUserByUserdn = true; - -+ protected boolean mBoundConnEnable = false; - /* factory of anonymous ldap connections */ - protected ILdapConnFactory mConnFactory = null; - -@@ -130,6 +133,9 @@ public abstract class DirBasedAuthentication - /* the combined list of LDAP attriubutes to retrieve*/ - protected String[] mLdapAttrs = null; - -+ /* the password prompt (tag) for the userdn of a bound connection */ -+ protected String mTag; -+ - /* default dn pattern if left blank or not set in the config */ - protected static String DEFAULT_DNPATTERN = - "E=$attr.mail, CN=$attr.cn, O=$dn.o, C=$dn.c"; -@@ -255,6 +261,7 @@ public abstract class DirBasedAuthentication - mName = name; - mImplName = implName; - mConfig = config; -+ String method = "DirBasedAuthentication: init: "; - - /* initialize ldap server configuration */ - mLdapConfig = mConfig.getSubStore(PROP_LDAP); -@@ -263,22 +270,31 @@ public abstract class DirBasedAuthentication - if (mBaseDN == null || mBaseDN.trim().equals("")) - throw new EPropertyNotFound(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", "basedn")); - mGroupsEnable = mLdapConfig.getBoolean(PROP_GROUPS_ENABLE, false); -- CMS.debug("DirBasedAuthentication: mGroupsEnable=" + (mGroupsEnable ? "true" : "false")); -+ CMS.debug(method + " mGroupsEnable=" + (mGroupsEnable ? "true" : "false")); - mGroupsBaseDN = mLdapConfig.getString(PROP_GROUPS_BASEDN, mBaseDN); -- CMS.debug("DirBasedAuthentication: mGroupsBaseDN="+ mGroupsBaseDN); -+ CMS.debug(method + " mGroupsBaseDN="+ mGroupsBaseDN); - mGroups= mLdapConfig.getString(PROP_GROUPS, "ou=groups"); -- CMS.debug("DirBasedAuthentication: mGroups="+ mGroups); -+ CMS.debug(method + " mGroups="+ mGroups); - mGroupObjectClass = mLdapConfig.getString(PROP_GROUP_OBJECT_CLASS, "groupofuniquenames"); -- CMS.debug("DirBasedAuthentication: mGroupObjectClass="+ mGroupObjectClass); -+ CMS.debug(method + " mGroupObjectClass="+ mGroupObjectClass); - mUserIDName = mLdapConfig.getString(PROP_USERID_NAME, "uid"); -- CMS.debug("DirBasedAuthentication: mUserIDName="+ mUserIDName); -+ CMS.debug(method + " mUserIDName="+ mUserIDName); - mSearchGroupUserByUserdn = mLdapConfig.getBoolean(PROP_SEARCH_GROUP_USER_BY_USERDN, true); -- CMS.debug("DirBasedAuthentication: mSearchGroupUserByUserdn="+ mSearchGroupUserByUserdn); -+ CMS.debug(method + " mSearchGroupUserByUserdn="+ mSearchGroupUserByUserdn); - mGroupUserIDName = mLdapConfig.getString(PROP_GROUP_USERID_NAME, "cn"); -- CMS.debug("DirBasedAuthentication: mGroupUserIDName="+ mGroupUserIDName); -+ CMS.debug(method + " mGroupUserIDName="+ mGroupUserIDName); -+ } -+ mBoundConnEnable = mLdapConfig.getBoolean(PROP_LDAP_BOUND_CONN, false); -+ CMS.debug(method +" mBoundConnEnable =" + (mBoundConnEnable ? "true" : "false")); -+ if (mBoundConnEnable) { -+ mTag = mLdapConfig.getString(PROP_LDAP_BOUND_TAG); -+ CMS.debug(method + " getting ldap bound conn factory using id= " + mTag); -+ mConnFactory = CMS.getLdapBoundConnFactory(mTag); -+ } else { -+ mConnFactory = CMS.getLdapAnonConnFactory("DirBasedAuthentication"); - } -- mConnFactory = CMS.getLdapAnonConnFactory("DirBasedAuthentication"); -- mConnFactory.init(mLdapConfig); -+ if (mConnFactory != null) // else can try again later when needed -+ mConnFactory.init(mLdapConfig); - - /* initialize dn pattern */ - String pattern = mConfig.getString(PROP_DNPATTERN, null); -@@ -372,16 +388,34 @@ public abstract class DirBasedAuthentication - String userdn = null; - LDAPConnection conn = null; - AuthToken authToken = new AuthToken(this); -+ String method = "DirBasedAuthentication: authenticate:"; - -+ CMS.debug(method + " begins...mBoundConnEnable=" + mBoundConnEnable); - try { - if (mConnFactory == null) { -- conn = null; -+ CMS.debug(method + " mConnFactory null, getting conn factory"); -+ if (mBoundConnEnable) { -+ mTag = mLdapConfig.getString(PROP_LDAP_BOUND_TAG); -+ CMS.debug(method + " getting ldap bound conn factory using id= " + mTag); -+ mConnFactory = CMS.getLdapBoundConnFactory(mTag); -+ } else { -+ mConnFactory = CMS.getLdapAnonConnFactory("DirBasedAuthentication"); -+ } -+ if (mConnFactory != null) { -+ mConnFactory.init(mLdapConfig); -+ CMS.debug(method + " mConnFactory gotten, calling getConn"); -+ conn = mConnFactory.getConn(); -+ } - } else { -+ CMS.debug(method + " mConnFactory class name = " + mConnFactory.getClass().getName()); -+ CMS.debug(method + " mConnFactory not null, calling getConn"); - conn = mConnFactory.getConn(); - } - - // authenticate the user and get a user entry. -+ CMS.debug(method + " before authenticate() call"); - userdn = authenticate(conn, authCred, authToken); -+ CMS.debug(method + " after authenticate() call"); - authToken.set(USER_DN, userdn); - - // formulate the cert info. -diff --git a/base/server/cms/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java -index 2f9fc43..e731352 100644 ---- a/base/server/cms/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java -+++ b/base/server/cms/src/com/netscape/cms/authentication/UdnPwdDirAuthentication.java -@@ -134,10 +134,22 @@ public class UdnPwdDirAuthentication extends DirBasedAuthentication { - - return userdn; - } catch (ELdapException e) { -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - log(ILogger.LL_FAILURE, - "Couldn't get ldap connection. Error: " + e.toString()); - throw e; - } catch (LDAPException e) { -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - switch (e.getLDAPResultCode()) { - case LDAPException.NO_SUCH_OBJECT: - case LDAPException.LDAP_PARTIAL_RESULTS: -diff --git a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java -index 21e024f..26bfaab 100644 ---- a/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java -+++ b/base/server/cms/src/com/netscape/cms/authentication/UidPwdDirAuthentication.java -@@ -235,10 +235,22 @@ public class UidPwdDirAuthentication extends DirBasedAuthentication - return userdn; - } catch (ELdapException e) { - CMS.debug("Authenticating: User authentication failure: "+e); -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - log(ILogger.LL_FAILURE, CMS.getLogMessage("CANNOT_CONNECT_LDAP", e.toString())); - throw e; - } catch (LDAPException e) { - CMS.debug("Authenticating: User authentication failure: "+e); -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - switch (e.getLDAPResultCode()) { - case LDAPException.NO_SUCH_OBJECT: - case LDAPException.LDAP_PARTIAL_RESULTS: -diff --git a/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java -index ed20740..82331da 100644 ---- a/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java -+++ b/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java -@@ -247,9 +247,21 @@ public class UidPwdPinDirAuthentication extends DirBasedAuthentication - - return userdn; - } catch (ELdapException e) { -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - log(ILogger.LL_FAILURE, CMS.getLogMessage("CANNOT_CONNECT_LDAP", e.toString())); - throw e; - } catch (LDAPException e) { -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - switch (e.getLDAPResultCode()) { - case LDAPException.NO_SUCH_OBJECT: - case LDAPException.LDAP_PARTIAL_RESULTS: -diff --git a/base/server/cms/src/com/netscape/cms/authentication/UserPwdDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UserPwdDirAuthentication.java -index 7bcab25..a95dd86 100644 ---- a/base/server/cms/src/com/netscape/cms/authentication/UserPwdDirAuthentication.java -+++ b/base/server/cms/src/com/netscape/cms/authentication/UserPwdDirAuthentication.java -@@ -187,9 +187,21 @@ public class UserPwdDirAuthentication extends DirBasedAuthentication - - return userdn; - } catch (ELdapException e) { -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - log(ILogger.LL_FAILURE, CMS.getLogMessage("CANNOT_CONNECT_LDAP", e.toString())); - throw e; - } catch (LDAPException e) { -+ CMS.debug("Authenticating: closing bad connection"); -+ try { -+ conn.disconnect(); -+ } catch (Exception f) { -+ CMS.debug("Authenticating: conn.disconnect() exception =" + f.toString()); -+ } - switch (e.getLDAPResultCode()) { - case LDAPException.NO_SUCH_OBJECT: - case LDAPException.LDAP_PARTIAL_RESULTS: -diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java -index fa2c814..467836b 100644 ---- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java -+++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java -@@ -331,6 +331,7 @@ public class CMSEngine implements ICMSEngine { - } - - public void initializePasswordStore(IConfigStore config) throws EBaseException, IOException { -+ System.out.println("CMSEngine.initializePasswordStore() begins"); - // create and initialize mPasswordStore - getPasswordStore(); - -@@ -345,6 +346,7 @@ public class CMSEngine implements ICMSEngine { - String binddn; - String authType; - LdapConnInfo connInfo = null; -+ System.out.println("CMSEngine.initializePasswordStore(): tag=" + tag); - - if (tag.equals("internaldb")) { - authType = config.getString("internaldb.ldapauth.authtype", "BasicAuth"); -@@ -382,8 +384,43 @@ public class CMSEngine implements ICMSEngine { - binddn = config.getString("ca.publish.ldappublish.ldap.ldapauth.bindDN"); - - } else { -- // ignore any others for now -- continue; -+ /* -+ * This section assumes a generic format of -+ * .ldap.xxx -+ * where is specified under the tag substore -+ * -+ * e.g. if tag = "externalLDAP" -+ * cms.passwordlist=...,externalLDAP -+ * externalLDAP.authPrefix=auths.instance.UserDirEnrollment -+ * -+ * auths.instance.UserDirEnrollment.ldap.ldapauth.authtype=BasicAuth -+ * auths.instance.UserDirEnrollment.ldap.ldapauth.bindDN=cn=Corporate Directory Manager -+ * auths.instance.UserDirEnrollment.ldap.ldapauth.bindPWPrompt=externalLDAP -+ * auths.instance.UserDirEnrollment.ldap.ldapconn.host=host.example.com -+ * auths.instance.UserDirEnrollment.ldap.ldapconn.port=389 -+ * auths.instance.UserDirEnrollment.ldap.ldapconn.secureConn=false -+ */ -+ String authPrefix = config.getString(tag + ".authPrefix", null); -+ if (authPrefix == null) { -+ System.out.println("CMSEngine.initializePasswordStore(): authPrefix not found...skipping"); -+ continue; -+ } -+ System.out.println("CMSEngine.initializePasswordStore(): authPrefix=" + authPrefix); -+ authType = config.getString(authPrefix +".ldap.ldapauth.authtype", "BasicAuth"); -+ System.out.println("CMSEngine.initializePasswordStore(): authType " + authType); -+ if (!authType.equals("BasicAuth")) -+ continue; -+ -+ connInfo = new LdapConnInfo( -+ config.getString(authPrefix + ".ldap.ldapconn.host"), -+ config.getInteger(authPrefix + ".ldap.ldapconn.port"), -+ config.getBoolean(authPrefix + ".ldap.ldapconn.secureConn")); -+ -+ binddn = config.getString(authPrefix + ".ldap.ldapauth.bindDN", null); -+ if (binddn == null) { -+ System.out.println("CMSEngine.initializePasswordStore(): binddn not found...skipping"); -+ continue; -+ } - } - - do { diff --git a/pki-core-Add-Externalreg-revokeCert-Parameter.patch b/pki-core-Add-Externalreg-revokeCert-Parameter.patch deleted file mode 100644 index bf46bb4..0000000 --- a/pki-core-Add-Externalreg-revokeCert-Parameter.patch +++ /dev/null @@ -1,27 +0,0 @@ -commit 0e41c12d98f60fa4c2e704a6515b58a7706428f9 -Author: Jack Magne -Date: Tue Jul 28 17:51:34 2015 -0700 - - op.format.externalRegAddToToken.revokeCert parameter missing in TPS CS.cfg. - - It is true that his setting is not present. - The generic code that revokes certs for a format checks this value. - No harm in putting this value in the CS.cfg and setting it to false by - default for the externalRegAddToToken profile. No harm in giving the user - the way to use this feature , even if we decide it is not a good idea to revoke - certs associated with the external reg feature. - - (cherry picked from commit c4c28d6f581ba0fa136afaab5651e976f6f79d2c) - -diff --git a/base/tps/shared/conf/CS.cfg.in b/base/tps/shared/conf/CS.cfg.in -index fdc3510..732d143 100644 ---- a/base/tps/shared/conf/CS.cfg.in -+++ b/base/tps/shared/conf/CS.cfg.in -@@ -770,6 +770,7 @@ op.format.externalRegAddToToken.update.applet.encryption=true - op.format.externalRegAddToToken.update.applet.requiredVersion=1.4.54de790f - op.format.externalRegAddToToken.update.symmetricKeys.enable=false - op.format.externalRegAddToToken.update.symmetricKeys.requiredVersion=1 -+op.format.externalRegAddToToken.revokeCert=false - op.enroll.allowUnknownToken=true - op.enroll.mappingResolver=enrollProfileMappingResolver - op.enroll.soKey.cuidMustMatchKDD=false diff --git a/pki-core-Add-Reindex-Data-During-Cloning-No-Replication.patch b/pki-core-Add-Reindex-Data-During-Cloning-No-Replication.patch deleted file mode 100644 index 07ed98e..0000000 --- a/pki-core-Add-Reindex-Data-During-Cloning-No-Replication.patch +++ /dev/null @@ -1,512 +0,0 @@ -commit 7c4bc2480c0cb0b4bb816ec090e9673bdddce047 -Author: Ade Lee -Date: Wed Jul 29 14:23:35 2015 -0400 - - Add code to reindex data during cloning without replication - - When setting up a clone, indexes are added before the - replication agreements are set up and the consumer is initialized. - Thus, as data is replicated and added to the clone db, the - data is indexed. - - When cloning is done with the replication agreements already set - up and the data replicated, the existing data is not indexed and - cannot be accessed in searches. The data needs to be reindexed. - - Related to ticket 1414 - -diff --git a/base/ca/shared/conf/CS.cfg.in b/base/ca/shared/conf/CS.cfg.in -index 3d2dd5e..d6642a4 100644 ---- a/base/ca/shared/conf/CS.cfg.in -+++ b/base/ca/shared/conf/CS.cfg.in -@@ -828,6 +828,8 @@ preop.internaldb.index_ldif=/usr/share/pki/ca/conf/index.ldif - preop.internaldb.manager_ldif=/usr/share/pki/server/conf/manager.ldif - preop.internaldb.post_ldif=/usr/share/pki/ca/conf/vlv.ldif,/usr/share/pki/ca/conf/vlvtasks.ldif - preop.internaldb.wait_dn=cn=index1160589769, cn=index, cn=tasks, cn=config -+preop.internaldb.index_task_ldif=/usr/share/pki/ca/conf/indextasks.ldif -+preop.internaldb.index_wait_dn=cn=index1160589770,cn=index,cn=tasks,cn=config - internaldb.multipleSuffix.enable=false - jobsScheduler._000=## - jobsScheduler._001=## jobScheduler -diff --git a/base/ca/shared/conf/indextasks.ldif b/base/ca/shared/conf/indextasks.ldif -new file mode 100644 -index 0000000..4db159a ---- /dev/null -+++ b/base/ca/shared/conf/indextasks.ldif -@@ -0,0 +1,31 @@ -+dn: cn=index1160589770, cn=index, cn=tasks, cn=config -+objectclass: top -+objectclass: extensibleObject -+cn: index1160589770 -+ttl: 10 -+nsinstance: {database} -+nsIndexAttribute: revokedby:eq -+nsIndexAttribute: issuedby:eq -+nsIndexAttribute: publicKeyData:eq -+nsIndexAttribute: clientId:eq -+nsIndexAttribute: dataType:eq -+nsIndexAttribute: status:eq -+nsIndexAttribute: description:eq,pres -+nsIndexAttribute: serialno:eq,pres -+nsIndexAttribute: metaInfo:eq,pres -+nsIndexAttribute: certstatus:eq,pres -+nsIndexAttribute: requestid:eq,pres -+nsIndexAttribute: requesttype:eq,pres -+nsIndexAttribute: requeststate:eq,pres -+nsIndexAttribute: requestowner:eq,pres -+nsIndexAttribute: notbefore:eq,pres -+nsIndexAttribute: notafter:eq,pres -+nsIndexAttribute: duration:eq,pres -+nsIndexAttribute: dateOfCreate:eq,pres -+nsIndexAttribute: revokedOn:eq,pres -+nsIndexAttribute: archivedBy:eq,pres -+nsIndexAttribute: ownername:eq,pres,sub -+nsIndexAttribute: subjectname:eq,pres,sub -+nsIndexAttribute: requestsourceid:eq,pres,sub -+nsIndexAttribute: revInfo:eq,pres,sub -+nsIndexAttribute: extension:eq,pres,sub -diff --git a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java -index 0682ac9..7c6c339 100644 ---- a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java -+++ b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java -@@ -130,6 +130,9 @@ public class ConfigurationRequest { - protected String setupReplication; - - @XmlElement -+ protected String reindexData; -+ -+ @XmlElement - protected List systemCerts; - - @XmlElement -@@ -525,6 +528,18 @@ public class ConfigurationRequest { - this.setupReplication = setupReplication; - } - -+ public boolean getReindexData() { -+ // default to false -+ if (reindexData == null) { -+ return false; -+ } -+ return reindexData.equalsIgnoreCase("true"); -+ } -+ -+ public void setReindexData(String reindexData) { -+ this.reindexData = reindexData; -+ } -+ - /** - * @return the database - */ -@@ -946,7 +961,8 @@ public class ConfigurationRequest { - ", sharedDBUserDN=" + sharedDBUserDN + - ", createNewDB=" + createNewDB + - ", setupReplication=" + setupReplication + -- ", subordinateSecurityDomainName" + subordinateSecurityDomainName + -+ ", subordinateSecurityDomainName=" + subordinateSecurityDomainName + -+ ", reindexData=" + reindexData + - "]"; - } - -@@ -960,5 +976,4 @@ public class ConfigurationRequest { - return uri == null ? null : new URI(uri); - } - } -- - } -diff --git a/base/kra/shared/conf/CS.cfg.in b/base/kra/shared/conf/CS.cfg.in -index fae7713..64a369e 100644 ---- a/base/kra/shared/conf/CS.cfg.in -+++ b/base/kra/shared/conf/CS.cfg.in -@@ -236,6 +236,8 @@ preop.internaldb.index_ldif=/usr/share/pki/kra/conf/index.ldif - preop.internaldb.manager_ldif=/usr/share/pki/server/conf/manager.ldif - preop.internaldb.post_ldif=/usr/share/pki/kra/conf/vlv.ldif,/usr/share/pki/kra/conf/vlvtasks.ldif - preop.internaldb.wait_dn=cn=index1160527115, cn=index, cn=tasks, cn=config -+preop.internaldb.index_task_ldif=/usr/share/pki/kra/conf/indextasks.ldif -+preop.internaldb.index_wait_dn=cn=index1160589771,cn=index,cn=tasks,cn=config - internaldb.multipleSuffix.enable=false - jobsScheduler._000=## - jobsScheduler._001=## jobScheduler -diff --git a/base/kra/shared/conf/indextasks.ldif b/base/kra/shared/conf/indextasks.ldif -new file mode 100644 -index 0000000..41703a4 ---- /dev/null -+++ b/base/kra/shared/conf/indextasks.ldif -@@ -0,0 +1,31 @@ -+dn: cn=index1160589771, cn=index, cn=tasks, cn=config -+objectclass: top -+objectclass: extensibleObject -+cn: index1160589771 -+ttl: 10 -+nsinstance: {database} -+nsIndexAttribute: revokedby:eq -+nsIndexAttribute: issuedby:eq -+nsIndexAttribute: publicKeyData:eq -+nsIndexAttribute: clientId:eq -+nsIndexAttribute: dataType:eq -+nsIndexAttribute: status:eq -+nsIndexAttribute: description:eq,pres -+nsIndexAttribute: serialno:eq,pres -+nsIndexAttribute: metaInfo:eq,pres -+nsIndexAttribute: certstatus:eq,pres -+nsIndexAttribute: requestid:eq,pres -+nsIndexAttribute: requesttype:eq,pres -+nsIndexAttribute: requeststate:eq,pres -+nsIndexAttribute: requestowner:eq,pres -+nsIndexAttribute: notbefore:eq,pres -+nsIndexAttribute: notafter:eq,pres -+nsIndexAttribute: duration:eq,pres -+nsIndexAttribute: dateOfCreate:eq,pres -+nsIndexAttribute: revokedOn:eq,pres -+nsIndexAttribute: archivedBy:eq,pres -+nsIndexAttribute: ownername:eq,pres,sub -+nsIndexAttribute: subjectname:eq,pres,sub -+nsIndexAttribute: requestsourceid:eq,pres,sub -+nsIndexAttribute: revInfo:eq,pres,sub -+nsIndexAttribute: extension:eq,pres,sub -diff --git a/base/ocsp/shared/conf/CS.cfg.in b/base/ocsp/shared/conf/CS.cfg.in -index 9c878e8..0cbe20b 100644 ---- a/base/ocsp/shared/conf/CS.cfg.in -+++ b/base/ocsp/shared/conf/CS.cfg.in -@@ -195,6 +195,8 @@ preop.internaldb.index_ldif=/usr/share/pki/ocsp/conf/index.ldif - preop.internaldb.manager_ldif=/usr/share/pki/server/conf/manager.ldif - preop.internaldb.post_ldif= - preop.internaldb.wait_dn= -+preop.internaldb.index_task_ldif=/usr/share/pki/ocsp/conf/indextasks.ldif -+preop.internaldb.index_wait_dn=cn=index1160589772,cn=index,cn=tasks,cn=config - internaldb.multipleSuffix.enable=false - jss._000=## - jss._001=## JSS -diff --git a/base/ocsp/shared/conf/indextasks.ldif b/base/ocsp/shared/conf/indextasks.ldif -new file mode 100644 -index 0000000..1169d60 ---- /dev/null -+++ b/base/ocsp/shared/conf/indextasks.ldif -@@ -0,0 +1,31 @@ -+dn: cn=index1160589772, cn=index, cn=tasks, cn=config -+objectclass: top -+objectclass: extensibleObject -+cn: index1160589772 -+ttl: 10 -+nsinstance: {database} -+nsIndexAttribute: revokedby:eq -+nsIndexAttribute: issuedby:eq -+nsIndexAttribute: publicKeyData:eq -+nsIndexAttribute: clientId:eq -+nsIndexAttribute: dataType:eq -+nsIndexAttribute: status:eq -+nsIndexAttribute: description:eq,pres -+nsIndexAttribute: serialno:eq,pres -+nsIndexAttribute: metaInfo:eq,pres -+nsIndexAttribute: certstatus:eq,pres -+nsIndexAttribute: requestid:eq,pres -+nsIndexAttribute: requesttype:eq,pres -+nsIndexAttribute: requeststate:eq,pres -+nsIndexAttribute: requestowner:eq,pres -+nsIndexAttribute: notbefore:eq,pres -+nsIndexAttribute: notafter:eq,pres -+nsIndexAttribute: duration:eq,pres -+nsIndexAttribute: dateOfCreate:eq,pres -+nsIndexAttribute: revokedOn:eq,pres -+nsIndexAttribute: archivedBy:eq,pres -+nsIndexAttribute: ownername:eq,pres,sub -+nsIndexAttribute: subjectname:eq,pres,sub -+nsIndexAttribute: requestsourceid:eq,pres,sub -+nsIndexAttribute: revInfo:eq,pres,sub -+nsIndexAttribute: extension:eq,pres,sub -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 -index c8ab38c..a417be4 100644 ---- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java -+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java -@@ -88,6 +88,7 @@ import netscape.security.x509.X500Name; - import netscape.security.x509.X509CertImpl; - import netscape.security.x509.X509Key; - -+import org.apache.commons.lang.StringUtils; - import org.apache.velocity.context.Context; - import org.mozilla.jss.CryptoManager; - import org.mozilla.jss.CryptoManager.NicknameConflictException; -@@ -1346,6 +1347,7 @@ public class ConfigurationUtils { - boolean remove = cs.getBoolean("preop.database.removeData", false); - boolean createNewDB = cs.getBoolean("preop.database.createNewDB", true); - boolean setupReplication = cs.getBoolean("preop.database.setupReplication", true); -+ boolean reindexData = cs.getBoolean("preop.database.reindexData", false); - - IConfigStore dbCfg = cs.getSubStore("internaldb"); - ILdapConnFactory dbFactory = CMS.getLdapBoundConnFactory("ConfigurationUtils"); -@@ -1419,6 +1421,9 @@ public class ConfigurationUtils { - // On the other hand, if we are not setting up replication, then we - // are assuming that replication is already taken care of, and schema - // has already been replicated. No need to add. -+ -+ // Also, data will be replicated from master to clone -+ // so clone does not need the data - boolean replicateSchema = cs.getBoolean("preop.internaldb.replicateSchema", true); - if (!replicateSchema || !setupReplication) { - importLDIFS("preop.internaldb.schema.ldif", conn); -@@ -1427,9 +1432,15 @@ public class ConfigurationUtils { - - // add the index before replication, add VLV indexes afterwards - importLDIFS("preop.internaldb.index_ldif", conn); -+ -+ if (!setupReplication && reindexData) { -+ // data has already been replicated but not yet indexed - -+ // re-index here -+ populateIndexes(conn); -+ } - } else { -- // data will be replicated from the master to the clone -- // so clone does not need the data -+ // this is the normal non-clone case -+ // import schema, database, initial data and indexes - importLDIFS("preop.internaldb.schema.ldif", conn); - importLDIFS("preop.internaldb.ldif", conn); - importLDIFS("preop.internaldb.data_ldif", conn); -@@ -1444,6 +1455,51 @@ public class ConfigurationUtils { - } - } - -+ private static void populateIndexes(LDAPConnection conn) throws EPropertyNotFound, IOException, EBaseException { -+ CMS.debug("populateIndexes(): start"); -+ IConfigStore cs = CMS.getConfigStore(); -+ -+ importLDIFS("preop.internaldb.index_task_ldif", conn, false); -+ -+ /* For populating indexes, we need to check if the task has completed. -+ Presence of nsTaskExitCode means task is complete -+ */ -+ String wait_dn = cs.getString("preop.internaldb.index_wait_dn", ""); -+ if (!StringUtils.isEmpty(wait_dn)) { -+ wait_for_task(conn, wait_dn); -+ } -+ } -+ -+ private static void wait_for_task(LDAPConnection conn, String wait_dn) { -+ LDAPEntry task = null; -+ boolean taskComplete = false; -+ CMS.debug("Checking wait_dn " + wait_dn); -+ do { -+ try { -+ Thread.sleep(1000); -+ } catch (InterruptedException e) { -+ // restore the interrupted status -+ Thread.currentThread().interrupt(); -+ } -+ -+ try { -+ task = conn.read(wait_dn, (String[]) null); -+ if (task != null) { -+ LDAPAttribute attr = task.getAttribute("nsTaskExitCode"); -+ if (attr != null) { -+ taskComplete = true; -+ String val = (String) attr.getStringValues().nextElement(); -+ if (val.compareTo("0") != 0) { -+ CMS.debug("Error in populating indexes: nsTaskExitCode=" + val); -+ } -+ } -+ } -+ } catch (Exception le) { -+ CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + le.toString() + ")"); -+ } -+ } while (!taskComplete); -+ } -+ - private static void createBaseEntry(String baseDN, LDAPConnection conn) throws EBaseException { - try { - CMS.debug("Creating base DN: " + baseDN); -@@ -1624,7 +1680,11 @@ public class ConfigurationUtils { - } - } - -- public static void importLDIFS(String param, LDAPConnection conn) throws IOException, EPropertyNotFound, -+ public static void importLDIFS(String param, LDAPConnection conn) throws EPropertyNotFound, IOException, EBaseException { -+ importLDIFS(param, conn, true); -+ } -+ -+ public static void importLDIFS(String param, LDAPConnection conn, boolean suppressErrors) throws IOException, EPropertyNotFound, - EBaseException { - IConfigStore cs = CMS.getConfigStore(); - -@@ -1706,6 +1766,9 @@ public class ConfigurationUtils { - for (String error : errors) { - CMS.debug(error); - } -+ if (!suppressErrors) { -+ throw new EBaseException("LDAP Errors in importing " + filename); -+ } - } - } - } -@@ -1836,33 +1899,7 @@ public class ConfigurationUtils { - */ - String wait_dn = cs.getString("preop.internaldb.wait_dn", ""); - if (!wait_dn.equals("")) { -- LDAPEntry task = null; -- boolean taskComplete = false; -- CMS.debug("Checking wait_dn " + wait_dn); -- do { -- try { -- Thread.sleep(1000); -- } catch (InterruptedException e) { -- // restore the interrupted status -- Thread.currentThread().interrupt(); -- } -- -- try { -- task = conn.read(wait_dn, (String[]) null); -- if (task != null) { -- LDAPAttribute attr = task.getAttribute("nsTaskExitCode"); -- if (attr != null) { -- taskComplete = true; -- String val = (String) attr.getStringValues().nextElement(); -- if (val.compareTo("0") != 0) { -- CMS.debug("Error in populating local VLV indexes: nsTaskExitCode=" + val); -- } -- } -- } -- } catch (Exception le) { -- CMS.debug("Still checking wait_dn '" + wait_dn + "' (" + le.toString() + ")"); -- } -- } while (!taskComplete); -+ wait_for_task(conn, wait_dn); - } - } catch (Exception e) { - CMS.debug("populateVLVIndexes(): Exception thrown: " + e); -diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -index 31891ca..6e54147 100644 ---- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -@@ -649,6 +649,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou - cs.putString("preop.database.removeData", data.getRemoveData()); - cs.putBoolean("preop.database.createNewDB", data.getCreateNewDB()); - cs.putBoolean("preop.database.setupReplication", data.getSetupReplication()); -+ cs.putBoolean("preop.database.reindexData", data.getReindexData()); - } - - public void initializeDatabase(ConfigurationRequest data) { -diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg -index 26ffd0d..ddd2d83 100644 ---- a/base/server/etc/default.cfg -+++ b/base/server/etc/default.cfg -@@ -194,6 +194,7 @@ pki_clone_replication_master_port= - pki_clone_replication_clone_port= - pki_clone_replication_security=None - pki_clone_setup_replication=True -+pki_clone_reindex_data=False - pki_master_hostname=%(pki_security_domain_hostname)s - pki_master_https_port=%(pki_security_domain_https_port)s - pki_clone_uri=https://%(pki_master_hostname)s:%(pki_master_https_port)s -diff --git a/base/server/man/man5/pki_default.cfg.5 b/base/server/man/man5/pki_default.cfg.5 -index 17130ae..4e2c13b 100644 ---- a/base/server/man/man5/pki_default.cfg.5 -+++ b/base/server/man/man5/pki_default.cfg.5 -@@ -267,6 +267,14 @@ Location and password of the PKCS #12 file containing the system certificates fo - .IP - Defaults to True. If set to False, the installer does not set up replication agreements from the master to the clone as part of the subsystem configuration. In this case, it is expected that the top level suffix already exists, and that the data has already been replicated. This option is useful if you want to use other tools to create and manage your replication topology, or if the baseDN is already replicated as part of a top-level suffix. - .TP -+.B pki_clone_reindex_data -+.IP -+Defaults to False. This parameter is only relevant when \fBpki_clone_setup_replication\fP is -+set to False. In this case, it is expected that the database has been prepared and replicated -+as noted above. Part of that preparation could involve adding indexes and indexing the data. -+If you would like the Dogtag installer to add the indexes and reindex the data instead, set -+\fBpki_clone_reindex_data\fP to True. -+.TP - .B pki_clone_replication_master_port, pki_clone_replication_clone_port - .IP - Ports on which replication occurs. These are the ports on the master and clone databases respectively. Defaults to the internal database port. -diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py -index 93fa384..b6ee61b 100644 ---- a/base/server/python/pki/server/deployment/pkihelper.py -+++ b/base/server/python/pki/server/deployment/pkihelper.py -@@ -4264,6 +4264,7 @@ class ConfigClient: - data.cloneReplicationPort = \ - self.mdict['pki_clone_replication_clone_port'] - data.setupReplication = self.mdict['pki_clone_setup_replication'] -+ data.reindexData = self.mdict['pki_clone_reindex_data'] - - def set_hierarchy_parameters(self, data): - if self.subsystem == "CA": -diff --git a/base/tks/shared/conf/CS.cfg.in b/base/tks/shared/conf/CS.cfg.in -index f864e29..e63f07d 100644 ---- a/base/tks/shared/conf/CS.cfg.in -+++ b/base/tks/shared/conf/CS.cfg.in -@@ -187,6 +187,8 @@ preop.internaldb.index_ldif=/usr/share/pki/tks/conf/index.ldif - preop.internaldb.manager_ldif=/usr/share/pki/server/conf/manager.ldif - preop.internaldb.post_ldif= - preop.internaldb.wait_dn= -+preop.internaldb.index_task_ldif=/usr/share/pki/tks/conf/indextasks.ldif -+preop.internaldb.index_wait_dn=cn=index1160589773,cn=index,cn=tasks,cn=config - internaldb.multipleSuffix.enable=false - jss._000=## - jss._001=## JSS -diff --git a/base/tks/shared/conf/indextasks.ldif b/base/tks/shared/conf/indextasks.ldif -new file mode 100644 -index 0000000..749ac0a ---- /dev/null -+++ b/base/tks/shared/conf/indextasks.ldif -@@ -0,0 +1,31 @@ -+dn: cn=index1160589773, cn=index, cn=tasks, cn=config -+objectclass: top -+objectclass: extensibleObject -+cn: index1160589773 -+ttl: 10 -+nsinstance: {database} -+nsIndexAttribute: revokedby:eq -+nsIndexAttribute: issuedby:eq -+nsIndexAttribute: publicKeyData:eq -+nsIndexAttribute: clientId:eq -+nsIndexAttribute: dataType:eq -+nsIndexAttribute: status:eq -+nsIndexAttribute: description:eq,pres -+nsIndexAttribute: serialno:eq,pres -+nsIndexAttribute: metaInfo:eq,pres -+nsIndexAttribute: certstatus:eq,pres -+nsIndexAttribute: requestid:eq,pres -+nsIndexAttribute: requesttype:eq,pres -+nsIndexAttribute: requeststate:eq,pres -+nsIndexAttribute: requestowner:eq,pres -+nsIndexAttribute: notbefore:eq,pres -+nsIndexAttribute: notafter:eq,pres -+nsIndexAttribute: duration:eq,pres -+nsIndexAttribute: dateOfCreate:eq,pres -+nsIndexAttribute: revokedOn:eq,pres -+nsIndexAttribute: archivedBy:eq,pres -+nsIndexAttribute: ownername:eq,pres,sub -+nsIndexAttribute: subjectname:eq,pres,sub -+nsIndexAttribute: requestsourceid:eq,pres,sub -+nsIndexAttribute: revInfo:eq,pres,sub -+nsIndexAttribute: extension:eq,pres,sub -diff --git a/base/tps/shared/conf/CS.cfg.in b/base/tps/shared/conf/CS.cfg.in -index 732d143..7bbecee 100644 ---- a/base/tps/shared/conf/CS.cfg.in -+++ b/base/tps/shared/conf/CS.cfg.in -@@ -1629,6 +1629,8 @@ preop.internaldb.manager_ldif=/usr/share/pki/server/conf/manager.ldif - preop.internaldb.post_ldif=/usr/share/pki/tps/conf/vlv.ldif,/usr/share/pki/tps/conf/vlvtasks.ldif - preop.internaldb.schema.ldif=/usr/share/pki/server/conf/schema.ldif - preop.internaldb.wait_dn=cn=index1160528734, cn=index, cn=tasks, cn=config -+preop.internaldb.index_task_ldif=/usr/share/pki/tps/conf/indextasks.ldif -+preop.internaldb.index_wait_dn=cn=index1160589774,cn=index,cn=tasks,cn=config - preop.module.token=Internal Key Storage Token - preop.pin=[PKI_RANDOM_NUMBER] - preop.product.name=CS -diff --git a/base/tps/shared/conf/indextasks.ldif b/base/tps/shared/conf/indextasks.ldif -new file mode 100644 -index 0000000..b5106bb ---- /dev/null -+++ b/base/tps/shared/conf/indextasks.ldif -@@ -0,0 +1,14 @@ -+dn: cn=index1160589774, cn=index, cn=tasks, cn=config -+objectclass: top -+objectclass: extensibleObject -+cn: index1160589774 -+ttl: 10 -+nsinstance: {database} -+nsIndexAttribute: tokenUserID:eq,pres,sub -+nsIndexAttribute: tokenID:eq,pres,sub -+nsIndexAttribute: dateOfCreate:eq,pres,sub -+nsIndexAttribute: dateOfModify:eq,pres,sub -+nsIndexAttribute: userCertificate:eq -+nsIndexAttribute: tokenSerial:eq -+nsIndexAttribute: tokenKeyType:eq -+nsIndexAttribute: description:eq,pres diff --git a/pki-core-Added-CLI-to-update-cert-data-and-request-in-CS_cfg.patch b/pki-core-Added-CLI-to-update-cert-data-and-request-in-CS_cfg.patch deleted file mode 100644 index 1a5b62f..0000000 --- a/pki-core-Added-CLI-to-update-cert-data-and-request-in-CS_cfg.patch +++ /dev/null @@ -1,1104 +0,0 @@ -commit c3c7350e104897dccb0ef2e7e5b19db232c2b888 -Author: Endi S. Dewata -Date: Wed Sep 2 04:50:24 2015 +0200 - - Added CLI to update cert data and request in CS.cfg. - - A set of new pki-server commands have been added to simplify - updating the cert data and cert request stored in the CS.cfg with - the cert data and cert request stored in the NSS and LDAP database, - respectively. - - https://fedorahosted.org/pki/ticket/1551 - (cherry picked from commit 7ed1e32c574a2ee93a62297d16e07a7071e696d7) - -diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py -index 9777d22..d004465 100644 ---- a/base/server/python/pki/server/__init__.py -+++ b/base/server/python/pki/server/__init__.py -@@ -20,7 +20,11 @@ - # - - from lxml import etree -+import getpass - import grp -+import io -+import ldap -+import operator - import os - import pwd - import re -@@ -31,7 +35,7 @@ import pki - INSTANCE_BASE_DIR = '/var/lib/pki' - REGISTRY_DIR = '/etc/sysconfig/pki' - SUBSYSTEM_TYPES = ['ca', 'kra', 'ocsp', 'tks', 'tps'] -- -+SUBSYSTEM_CLASSES = {} - - class PKIServer(object): - -@@ -65,6 +69,7 @@ class PKISubsystem(object): - self.base_dir = instance.base_dir - - self.conf_dir = os.path.join(self.base_dir, 'conf') -+ self.cs_conf = os.path.join(self.conf_dir, 'CS.cfg') - - self.context_xml_template = os.path.join( - pki.SHARE_DIR, self.name, 'conf', 'Catalina', 'localhost', self.name + '.xml') -@@ -72,9 +77,62 @@ class PKISubsystem(object): - self.context_xml = os.path.join( - instance.conf_dir, 'Catalina', 'localhost', self.name + '.xml') - -+ self.config = {} -+ self.type = None -+ self.prefix = None -+ - # custom subsystem location - self.doc_base = os.path.join(self.base_dir, 'webapps', self.name) - -+ def load(self): -+ self.config.clear() -+ -+ lines = open(self.cs_conf).read().splitlines() -+ -+ for line in lines: -+ parts = line.split('=', 1) -+ name = parts[0] -+ value = parts[1] -+ self.config[name] = value -+ -+ self.type = self.config['cs.type'] -+ self.prefix = self.type.lower() -+ -+ def find_subsystem_certs(self): -+ certs = [] -+ -+ cert_ids = self.config['%s.cert.list' % self.name].split(',') -+ for cert_id in cert_ids: -+ cert = self.create_subsystem_cert_object(cert_id) -+ certs.append(cert) -+ -+ return certs -+ -+ def get_subsystem_cert(self, cert_id): -+ return self.create_subsystem_cert_object(cert_id) -+ -+ def create_subsystem_cert_object(self, cert_id): -+ cert = {} -+ cert['id'] = cert_id -+ cert['nickname'] = self.config.get('%s.%s.nickname' % (self.name, cert_id), None) -+ cert['token'] = self.config.get('%s.%s.tokenname' % (self.name, cert_id), None) -+ cert['data'] = self.config.get('%s.%s.cert' % (self.name, cert_id), None) -+ cert['request'] = self.config.get('%s.%s.certreq' % (self.name, cert_id), None) -+ return cert -+ -+ def update_subsystem_cert(self, cert): -+ cert_id = cert['id'] -+ self.config['%s.%s.nickname' % (self.name, cert_id)] = cert.get('nickname', None) -+ self.config['%s.%s.tokenname' % (self.name, cert_id)] = cert.get('token', None) -+ self.config['%s.%s.cert' % (self.name, cert_id)] = cert.get('data', None) -+ self.config['%s.%s.certreq' % (self.name, cert_id)] = cert.get('request', None) -+ -+ def save(self): -+ sorted_config = sorted(self.config.items(), key=operator.itemgetter(0)) -+ with io.open(self.cs_conf, 'wb') as f: -+ for (key, value) in sorted_config: -+ f.write('%s=%s\n' % (key, value)) -+ - def is_valid(self): - return os.path.exists(self.conf_dir) - -@@ -102,6 +160,21 @@ class PKISubsystem(object): - def disable(self): - self.instance.undeploy(self.name) - -+ def open_database(self, name='internaldb'): -+ -+ hostname = self.config['%s.ldapconn.host' % name] -+ port = self.config['%s.ldapconn.port' % name] -+ bind_dn = self.config['%s.ldapauth.bindDN' % name] -+ -+ # TODO: add support for other authentication -+ # mechanisms (e.g. client cert authentication, LDAPI) -+ bind_password = self.instance.get_password(name) -+ -+ con = ldap.initialize('ldap://%s:%s' % (hostname, port)) -+ con.simple_bind_s(bind_dn, bind_password) -+ -+ return con -+ - def __repr__(self): - return str(self.instance) + '/' + self.name - -@@ -119,6 +192,9 @@ class PKIInstance(object): - self.base_dir = os.path.join(pki.BASE_DIR, name) - - self.conf_dir = os.path.join(self.base_dir, 'conf') -+ self.password_conf = os.path.join(self.conf_dir, 'password.conf') -+ -+ self.nssdb_dir = os.path.join(self.base_dir, 'alias') - self.lib_dir = os.path.join(self.base_dir, 'lib') - - self.registry_dir = os.path.join(pki.server.REGISTRY_DIR, 'tomcat', self.name) -@@ -132,6 +208,8 @@ class PKIInstance(object): - self.uid = None - self.gid = None - -+ self.passwords = {} -+ - self.subsystems = [] - - def is_valid(self): -@@ -153,6 +231,7 @@ class PKIInstance(object): - return rc == 0 - - def load(self): -+ # load UID and GID - with open(self.registry_file, 'r') as registry: - lines = registry.readlines() - -@@ -168,11 +247,41 @@ class PKIInstance(object): - self.group = m.group(1) - self.gid = grp.getgrnam(self.group).gr_gid - -+ # load passwords -+ self.passwords.clear() -+ lines = open(self.password_conf).read().splitlines() -+ -+ for line in lines: -+ parts = line.split('=', 1) -+ name = parts[0] -+ value = parts[1] -+ self.passwords[name] = value -+ -+ # load subsystems - for subsystem_name in os.listdir(self.registry_dir): -- if subsystem_name in pki.server.SUBSYSTEM_TYPES: -- subsystem = PKISubsystem(self, subsystem_name) -+ if subsystem_name in SUBSYSTEM_TYPES: -+ if subsystem_name in SUBSYSTEM_CLASSES: -+ subsystem = SUBSYSTEM_CLASSES[subsystem_name](self) -+ else: -+ subsystem = PKISubsystem(self, subsystem_name) -+ subsystem.load() - self.subsystems.append(subsystem) - -+ def get_password(self, name): -+ if name in self.passwords: -+ return self.passwords[name] -+ -+ password = getpass.getpass(prompt='Enter password for %s: ' % name) -+ self.passwords[name] = password -+ -+ return password -+ -+ def get_subsystem(self, name): -+ for subsystem in self.subsystems: -+ if name == subsystem.name: -+ return subsystem -+ return None -+ - def is_deployed(self, webapp_name): - context_xml = os.path.join( - self.conf_dir, 'Catalina', 'localhost', webapp_name + '.xml') -diff --git a/base/server/python/pki/server/ca.py b/base/server/python/pki/server/ca.py -new file mode 100644 -index 0000000..70ebf4d ---- /dev/null -+++ b/base/server/python/pki/server/ca.py -@@ -0,0 +1,92 @@ -+#!/usr/bin/python -+# Authors: -+# Endi S. Dewata -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; version 2 of the License. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License along -+# with this program; if not, write to the Free Software Foundation, Inc., -+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+# -+# Copyright (C) 2015 Red Hat, Inc. -+# All rights reserved. -+# -+ -+from __future__ import absolute_import -+import ldap -+import ldap.filter -+ -+import pki -+import pki.server -+ -+ -+class CASubsystem(pki.server.PKISubsystem): -+ -+ def __init__(self, instance): -+ super(CASubsystem, self).__init__(instance, 'ca') -+ -+ def find_cert_requests(self, cert=None): -+ -+ base_dn = self.config['internaldb.basedn'] -+ -+ if cert: -+ escaped_value = ldap.filter.escape_filter_chars(cert) -+ search_filter = '(extdata-req--005fissued--005fcert=%s)' % escaped_value -+ -+ else: -+ search_filter = '(objectClass=*)' -+ -+ con = self.open_database() -+ -+ entries = con.search_s( -+ 'ou=ca,ou=requests,%s' % base_dn, -+ ldap.SCOPE_ONELEVEL, -+ search_filter, -+ None) -+ -+ con.unbind_s() -+ -+ requests = [] -+ for entry in entries: -+ requests.append(self.create_request_object(entry)) -+ -+ return requests -+ -+ def get_cert_requests(self, request_id): -+ -+ base_dn = self.config['internaldb.basedn'] -+ -+ con = self.open_database() -+ -+ entries = con.search_s( -+ 'cn=%s,ou=ca,ou=requests,%s' % (request_id, base_dn), -+ ldap.SCOPE_BASE, -+ '(objectClass=*)', -+ None) -+ -+ con.unbind_s() -+ -+ entry = entries[0] -+ return self.create_request_object(entry) -+ -+ def create_request_object(self, entry): -+ -+ attrs = entry[1] -+ -+ request = {} -+ request['id'] = attrs['cn'][0] -+ request['type'] = attrs['requestType'][0] -+ request['status'] = attrs['requestState'][0] -+ request['request'] = attrs['extdata-cert--005frequest'][0] -+ -+ return request -+ -+ -+pki.server.SUBSYSTEM_CLASSES['ca'] = CASubsystem -diff --git a/base/server/python/pki/server/cli/ca.py b/base/server/python/pki/server/cli/ca.py -new file mode 100644 -index 0000000..2ad8652 ---- /dev/null -+++ b/base/server/python/pki/server/cli/ca.py -@@ -0,0 +1,206 @@ -+#!/usr/bin/python -+# Authors: -+# Endi S. Dewata -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; version 2 of the License. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License along -+# with this program; if not, write to the Free Software Foundation, Inc., -+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+# -+# Copyright (C) 2015 Red Hat, Inc. -+# All rights reserved. -+# -+ -+from __future__ import absolute_import -+from __future__ import print_function -+import getopt -+import io -+import sys -+ -+import pki.cli -+import pki.server.ca -+ -+ -+class CACLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(CACLI, self).__init__( -+ 'ca', 'CA management commands') -+ -+ self.add_module(CACertCLI()) -+ -+ -+class CACertCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(CACertCLI, self).__init__( -+ 'cert', 'CA certificates management commands') -+ -+ self.add_module(CACertRequestCLI()) -+ -+ -+class CACertRequestCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(CACertRequestCLI, self).__init__( -+ 'request', 'CA certificate requests management commands') -+ -+ self.add_module(CACertRequestFindCLI()) -+ self.add_module(CACertRequestShowCLI()) -+ -+ @staticmethod -+ def print_request(request, details=False): -+ print(' Request ID: %s' % request['id']) -+ print(' Type: %s' % request['type']) -+ print(' Status: %s' % request['status']) -+ -+ if details: -+ print(' Request: %s' % request['request']) -+ -+ -+class CACertRequestFindCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(CACertRequestFindCLI, self).__init__( -+ 'find', 'Find CA certificate requests') -+ -+ def usage(self): -+ print('Usage: pki-server ca-cert-request-find [OPTIONS]') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' --cert Issued certificate.') -+ print(' --cert-file File containing issued certificate.') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() -+ -+ def execute(self, args): -+ -+ try: -+ opts, _ = getopt.gnu_getopt(args, 'i:v', [ -+ 'instance=', 'cert=', 'cert-file=', -+ 'verbose', 'help']) -+ -+ except getopt.GetoptError as e: -+ print('ERROR: ' + str(e)) -+ self.usage() -+ sys.exit(1) -+ -+ instance_name = 'pki-tomcat' -+ cert = None -+ -+ for o, a in opts: -+ if o in ('-i', '--instance'): -+ instance_name = a -+ -+ elif o == '--cert': -+ cert = a -+ -+ elif o == '--cert-file': -+ with io.open(a, 'rb') as f: -+ cert = f.read() -+ -+ elif o in ('-v', '--verbose'): -+ self.set_verbose(True) -+ -+ elif o == '--help': -+ self.print_help() -+ sys.exit() -+ -+ else: -+ print('ERROR: unknown option ' + o) -+ self.usage() -+ sys.exit(1) -+ -+ instance = pki.server.PKIInstance(instance_name) -+ instance.load() -+ -+ subsystem = instance.get_subsystem('ca') -+ results = subsystem.find_cert_requests(cert=cert) -+ -+ self.print_message('%s entries matched' % len(results)) -+ -+ first = True -+ for request in results: -+ if first: -+ first = False -+ else: -+ print() -+ -+ CACertRequestCLI.print_request(request) -+ -+ -+class CACertRequestShowCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(CACertRequestShowCLI, self).__init__( -+ 'show', 'Show CA certificate request') -+ -+ def usage(self): -+ print('Usage: pki-server ca-cert-request-show [OPTIONS]') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() -+ -+ def execute(self, args): -+ -+ try: -+ opts, args = getopt.gnu_getopt(args, 'i:v', [ -+ 'instance=', 'output-file=', -+ 'verbose', 'help']) -+ -+ except getopt.GetoptError as e: -+ print('ERROR: ' + str(e)) -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) != 1: -+ print('ERROR: missing request ID') -+ self.usage() -+ sys.exit(1) -+ -+ request_id = args[0] -+ instance_name = 'pki-tomcat' -+ output_file = None -+ -+ for o, a in opts: -+ if o in ('-i', '--instance'): -+ instance_name = a -+ -+ elif o == '--output-file': -+ output_file = a -+ -+ elif o in ('-v', '--verbose'): -+ self.set_verbose(True) -+ -+ elif o == '--help': -+ self.print_help() -+ sys.exit() -+ -+ else: -+ print('ERROR: unknown option ' + o) -+ self.usage() -+ sys.exit(1) -+ -+ instance = pki.server.PKIInstance(instance_name) -+ instance.load() -+ -+ subsystem = instance.get_subsystem('ca') -+ request = subsystem.get_cert_requests(request_id) -+ -+ if output_file: -+ with io.open(output_file, 'wb') as f: -+ f.write(request['request']) -+ -+ else: -+ CACertRequestCLI.print_request(request, details=True) -diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py -index 43eb564..fc89c27 100644 ---- a/base/server/python/pki/server/cli/subsystem.py -+++ b/base/server/python/pki/server/cli/subsystem.py -@@ -19,8 +19,12 @@ - # All rights reserved. - # - -+from __future__ import absolute_import -+from __future__ import print_function -+import base64 - import getopt --import os -+import nss.nss as nss -+import string - import sys - - import pki.cli -@@ -38,11 +42,13 @@ class SubsystemCLI(pki.cli.CLI): - self.add_module(SubsystemFindCLI()) - self.add_module(SubsystemShowCLI()) - -+ self.add_module(SubsystemCertCLI()) -+ - @staticmethod - def print_subsystem(subsystem): -- print ' Subsystem ID: %s' % subsystem.name -- print ' Instance ID: %s' % subsystem.instance.name -- print ' Enabled: %s' % subsystem.is_enabled() -+ print(' Subsystem ID: %s' % subsystem.name) -+ print(' Instance ID: %s' % subsystem.instance.name) -+ print(' Enabled: %s' % subsystem.is_enabled()) - - - class SubsystemFindCLI(pki.cli.CLI): -@@ -51,12 +57,12 @@ class SubsystemFindCLI(pki.cli.CLI): - super(SubsystemFindCLI, self).__init__('find', 'Find subsystems') - - def usage(self): -- print 'Usage: pki-server subsystem-find [OPTIONS]' -- print -- print ' -i, --instance Instance ID.' -- print ' -v, --verbose Run in verbose mode.' -- print ' --help Show help message.' -- print -+ print('Usage: pki-server subsystem-find [OPTIONS]') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() - - def execute(self, args): - -@@ -66,11 +72,11 @@ class SubsystemFindCLI(pki.cli.CLI): - 'verbose', 'help']) - - except getopt.GetoptError as e: -- print 'ERROR: ' + str(e) -+ print('ERROR: ' + str(e)) - self.usage() - sys.exit(1) - -- instance_name = None -+ instance_name = 'pki-tomcat' - - for o, a in opts: - if o in ('-i', '--instance'): -@@ -84,32 +90,17 @@ class SubsystemFindCLI(pki.cli.CLI): - sys.exit() - - else: -- print 'ERROR: unknown option ' + o -+ print('ERROR: unknown option ' + o) - self.usage() - sys.exit(1) - -- if not instance_name: -- print 'ERROR: missing instance ID' -- self.usage() -- sys.exit(1) -- - instance = pki.server.PKIInstance(instance_name) - instance.load() - -- results = [] -- -- for name in os.listdir(instance.base_dir): -- -- subsystem = pki.server.PKISubsystem(instance, name) -- if not subsystem.is_valid(): -- continue -- -- results.append(subsystem) -- -- self.print_message('%s entries matched' % len(results)) -+ self.print_message('%s entries matched' % len(instance.subsystems)) - - first = True -- for subsystem in results: -+ for subsystem in instance.subsystems: - if first: - first = False - else: -@@ -124,12 +115,12 @@ class SubsystemShowCLI(pki.cli.CLI): - super(SubsystemShowCLI, self).__init__('show', 'Show subsystem') - - def usage(self): -- print 'Usage: pki-server subsystem-show [OPTIONS] ' -- print -- print ' -i, --instance Instance ID.' -- print ' -v, --verbose Run in verbose mode.' -- print ' --help Show help message.' -- print -+ print('Usage: pki-server subsystem-show [OPTIONS] ') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() - - def execute(self, argv): - -@@ -139,17 +130,17 @@ class SubsystemShowCLI(pki.cli.CLI): - 'verbose', 'help']) - - except getopt.GetoptError as e: -- print 'ERROR: ' + str(e) -+ print('ERROR: ' + str(e)) - self.usage() - sys.exit(1) - - if len(args) != 1: -- print 'ERROR: missing subsystem ID' -+ print('ERROR: missing subsystem ID') - self.usage() - sys.exit(1) - - subsystem_name = args[0] -- instance_name = None -+ instance_name = 'pki-tomcat' - - for o, a in opts: - if o in ('-i', '--instance'): -@@ -163,19 +154,14 @@ class SubsystemShowCLI(pki.cli.CLI): - sys.exit() - - else: -- print 'ERROR: unknown option ' + o -+ print('ERROR: unknown option ' + o) - self.usage() - sys.exit(1) - -- if not instance_name: -- print 'ERROR: missing instance ID' -- self.usage() -- sys.exit(1) -- - instance = pki.server.PKIInstance(instance_name) - instance.load() - -- subsystem = pki.server.PKISubsystem(instance, subsystem_name) -+ subsystem = instance.get_subsystem(subsystem_name) - - SubsystemCLI.print_subsystem(subsystem) - -@@ -186,12 +172,12 @@ class SubsystemEnableCLI(pki.cli.CLI): - super(SubsystemEnableCLI, self).__init__('enable', 'Enable subsystem') - - def usage(self): -- print 'Usage: pki-server subsystem-enable [OPTIONS] ' -- print -- print ' -i, --instance Instance ID.' -- print ' -v, --verbose Run in verbose mode.' -- print ' --help Show help message.' -- print -+ print('Usage: pki-server subsystem-enable [OPTIONS] ') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() - - def execute(self, argv): - -@@ -201,17 +187,17 @@ class SubsystemEnableCLI(pki.cli.CLI): - 'verbose', 'help']) - - except getopt.GetoptError as e: -- print 'ERROR: ' + str(e) -+ print('ERROR: ' + str(e)) - self.usage() - sys.exit(1) - - if len(args) != 1: -- print 'ERROR: missing subsystem ID' -+ print('ERROR: missing subsystem ID') - self.usage() - sys.exit(1) - - subsystem_name = args[0] -- instance_name = None -+ instance_name = 'pki-tomcat' - - for o, a in opts: - if o in ('-i', '--instance'): -@@ -225,19 +211,14 @@ class SubsystemEnableCLI(pki.cli.CLI): - sys.exit() - - else: -- print 'ERROR: unknown option ' + o -+ print('ERROR: unknown option ' + o) - self.usage() - sys.exit(1) - -- if not instance_name: -- print 'ERROR: missing instance ID' -- self.usage() -- sys.exit(1) -- - instance = pki.server.PKIInstance(instance_name) - instance.load() - -- subsystem = pki.server.PKISubsystem(instance, subsystem_name) -+ subsystem = instance.get_subsystem(subsystem_name) - subsystem.enable() - - self.print_message('Enabled "%s" subsystem' % subsystem_name) -@@ -251,12 +232,12 @@ class SubsystemDisableCLI(pki.cli.CLI): - super(SubsystemDisableCLI, self).__init__('disable', 'Disable subsystem') - - def usage(self): -- print 'Usage: pki-server subsystem-disable [OPTIONS] ' -- print -- print ' -i, --instance Instance ID.' -- print ' -v, --verbose Run in verbose mode.' -- print ' --help Show help message.' -- print -+ print('Usage: pki-server subsystem-disable [OPTIONS] ') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() - - def execute(self, argv): - -@@ -266,17 +247,17 @@ class SubsystemDisableCLI(pki.cli.CLI): - 'verbose', 'help']) - - except getopt.GetoptError as e: -- print 'ERROR: ' + str(e) -+ print('ERROR: ' + str(e)) - self.usage() - sys.exit(1) - - if len(args) != 1: -- print 'ERROR: missing subsystem ID' -+ print('ERROR: missing subsystem ID') - self.usage() - sys.exit(1) - - subsystem_name = args[0] -- instance_name = None -+ instance_name = 'pki-tomcat' - - for o, a in opts: - if o in ('-i', '--instance'): -@@ -290,21 +271,267 @@ class SubsystemDisableCLI(pki.cli.CLI): - sys.exit() - - else: -- print 'ERROR: unknown option ' + o -+ print('ERROR: unknown option ' + o) - self.usage() - sys.exit(1) - -- if not instance_name: -- print 'ERROR: missing instance ID' -- self.usage() -- sys.exit(1) -- - instance = pki.server.PKIInstance(instance_name) - instance.load() - -- subsystem = pki.server.PKISubsystem(instance, subsystem_name) -+ subsystem = instance.get_subsystem(subsystem_name) - subsystem.disable() - - self.print_message('Disabled "%s" subsystem' % subsystem_name) - - SubsystemCLI.print_subsystem(subsystem) -+ -+ -+class SubsystemCertCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(SubsystemCertCLI, self).__init__( -+ 'cert', 'Subsystem certificate management commands') -+ -+ self.add_module(SubsystemCertFindCLI()) -+ self.add_module(SubsystemCertShowCLI()) -+ self.add_module(SubsystemCertUpdateCLI()) -+ -+ @staticmethod -+ def print_subsystem_cert(cert): -+ print(' Cert ID: %s' % cert['id']) -+ print(' Nickname: %s' % cert['nickname']) -+ print(' Token: %s' % cert['token']) -+ print(' Certificate: %s' % cert['data']) -+ print(' Request: %s' % cert['request']) -+ -+ -+class SubsystemCertFindCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(SubsystemCertFindCLI, self).__init__( -+ 'find', 'Find subsystem certificates') -+ -+ def usage(self): -+ print('Usage: pki-server subsystem-cert-find [OPTIONS] ') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() -+ -+ def execute(self, argv): -+ -+ try: -+ opts, args = getopt.getopt(argv, 'i:v', [ -+ 'instance=', -+ 'verbose', 'help']) -+ -+ except getopt.GetoptError as e: -+ print('ERROR: ' + str(e)) -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) != 1: -+ print('ERROR: missing subsystem ID') -+ self.usage() -+ sys.exit(1) -+ -+ subsystem_name = args[0] -+ instance_name = 'pki-tomcat' -+ -+ for o, a in opts: -+ if o in ('-i', '--instance'): -+ instance_name = a -+ -+ elif o in ('-v', '--verbose'): -+ self.set_verbose(True) -+ -+ elif o == '--help': -+ self.print_help() -+ sys.exit() -+ -+ else: -+ print('ERROR: unknown option ' + o) -+ self.usage() -+ sys.exit(1) -+ -+ instance = pki.server.PKIInstance(instance_name) -+ instance.load() -+ -+ subsystem = instance.get_subsystem(subsystem_name) -+ results = subsystem.find_subsystem_certs() -+ -+ self.print_message('%s entries matched' % len(results)) -+ -+ first = True -+ for cert in results: -+ if first: -+ first = False -+ else: -+ print() -+ -+ SubsystemCertCLI.print_subsystem_cert(cert) -+ -+ -+class SubsystemCertShowCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(SubsystemCertShowCLI, self).__init__( -+ 'show', 'Show subsystem certificate') -+ -+ def usage(self): -+ print('Usage: pki-server subsystem-cert-show [OPTIONS] ') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() -+ -+ def execute(self, argv): -+ -+ try: -+ opts, args = getopt.getopt(argv, 'i:v', [ -+ 'instance=', -+ 'verbose', 'help']) -+ -+ except getopt.GetoptError as e: -+ print('ERROR: ' + str(e)) -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) < 1: -+ print('ERROR: missing subsystem ID') -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) < 2: -+ print('ERROR: missing cert ID') -+ self.usage() -+ sys.exit(1) -+ -+ subsystem_name = args[0] -+ cert_id = args[1] -+ instance_name = 'pki-tomcat' -+ -+ for o, a in opts: -+ if o in ('-i', '--instance'): -+ instance_name = a -+ -+ elif o in ('-v', '--verbose'): -+ self.set_verbose(True) -+ -+ elif o == '--help': -+ self.print_help() -+ sys.exit() -+ -+ else: -+ print('ERROR: unknown option ' + o) -+ self.usage() -+ sys.exit(1) -+ -+ instance = pki.server.PKIInstance(instance_name) -+ instance.load() -+ -+ subsystem = instance.get_subsystem(subsystem_name) -+ subsystem_cert = subsystem.get_subsystem_cert(cert_id) -+ -+ SubsystemCertCLI.print_subsystem_cert(subsystem_cert) -+ -+ -+class SubsystemCertUpdateCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(SubsystemCertUpdateCLI, self).__init__( -+ 'update', 'Update subsystem certificate') -+ -+ def usage(self): -+ print('Usage: pki-server subsystem-cert-update [OPTIONS] ') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() -+ -+ def execute(self, argv): -+ -+ try: -+ opts, args = getopt.getopt(argv, 'i:v', [ -+ 'instance=', -+ 'verbose', 'help']) -+ -+ except getopt.GetoptError as e: -+ print('ERROR: ' + str(e)) -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) < 1: -+ print('ERROR: missing subsystem ID') -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) < 2: -+ print('ERROR: missing cert ID') -+ self.usage() -+ sys.exit(1) -+ -+ subsystem_name = args[0] -+ cert_id = args[1] -+ instance_name = 'pki-tomcat' -+ -+ for o, a in opts: -+ if o in ('-i', '--instance'): -+ instance_name = a -+ -+ elif o in ('-v', '--verbose'): -+ self.set_verbose(True) -+ -+ elif o == '--help': -+ self.print_help() -+ sys.exit() -+ -+ else: -+ print('ERROR: unknown option ' + o) -+ self.usage() -+ sys.exit(1) -+ -+ instance = pki.server.PKIInstance(instance_name) -+ instance.load() -+ -+ subsystem = instance.get_subsystem(subsystem_name) -+ subsystem_cert = subsystem.get_subsystem_cert(cert_id) -+ -+ # get cert data from NSS database -+ nss.nss_init(instance.nssdb_dir) -+ nss_cert = nss.find_cert_from_nickname(subsystem_cert['nickname']) -+ data = base64.b64encode(nss_cert.der_data) -+ del nss_cert -+ nss.nss_shutdown() -+ subsystem_cert['data'] = data -+ -+ # format cert data for LDAP database -+ lines = [data[i:i+64] for i in range(0, len(data), 64)] -+ data = string.join(lines, '\r\n') + '\r\n' -+ -+ # get cert request from local CA -+ # TODO: add support for remote CA -+ ca = instance.get_subsystem('ca') -+ results = ca.find_cert_requests(cert=data) -+ cert_request = results[-1] -+ request = cert_request['request'] -+ -+ # format cert request for CS.cfg -+ lines = request.splitlines() -+ if lines[0] == '-----BEGIN CERTIFICATE REQUEST-----': -+ lines = lines[1:] -+ if lines[-1] == '-----END CERTIFICATE REQUEST-----': -+ lines = lines[:-1] -+ request = string.join(lines, '') -+ subsystem_cert['request'] = request -+ -+ # store cert data and request in CS.cfg -+ subsystem.update_subsystem_cert(subsystem_cert) -+ subsystem.save() -+ -+ self.print_message('Updated "%s" subsystem certificate' % cert_id) -+ -+ SubsystemCertCLI.print_subsystem_cert(subsystem_cert) -diff --git a/base/server/python/pki/server/upgrade.py b/base/server/python/pki/server/upgrade.py -index c9426a0..f82ffe6 100644 ---- a/base/server/python/pki/server/upgrade.py -+++ b/base/server/python/pki/server/upgrade.py -@@ -220,6 +220,7 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): - if self.subsystemName: - subsystem = pki.server.PKISubsystem(instance, self.subsystemName) - subsystem.validate() -+ subsystem.load() - return [subsystem] - - subsystem_list = [] -@@ -232,6 +233,7 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): - if subsystemName in pki.server.SUBSYSTEM_TYPES: - subsystem = pki.server.PKISubsystem(instance, subsystemName) - subsystem.validate() -+ subsystem.load() - subsystem_list.append(subsystem) - else: - for subsystemName in pki.server.SUBSYSTEM_TYPES: -@@ -242,6 +244,7 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader): - if os.path.exists(registry_dir): - subsystem = pki.server.PKISubsystem(instance, subsystemName) - subsystem.validate() -+ subsystem.load() - subsystem_list.append(subsystem) - - subsystem_list.sort() -diff --git a/base/server/sbin/pki-server b/base/server/sbin/pki-server -index 627a476..cdfd98e 100644 ---- a/base/server/sbin/pki-server -+++ b/base/server/sbin/pki-server -@@ -23,6 +23,7 @@ import getopt - import sys - - import pki.cli -+import pki.server.cli.ca - import pki.server.cli.instance - import pki.server.cli.subsystem - import pki.server.cli.migrate -@@ -35,6 +36,7 @@ class PKIServerCLI(pki.cli.CLI): - - super(PKIServerCLI, self).__init__('pki-server', 'PKI server command-line interface') - -+ self.add_module(pki.server.cli.ca.CACLI()) - self.add_module(pki.server.cli.instance.InstanceCLI()) - self.add_module(pki.server.cli.subsystem.SubsystemCLI()) - self.add_module(pki.server.cli.migrate.MigrateCLI()) diff --git a/pki-core-Added-automatic-Tomcat-migration.patch b/pki-core-Added-automatic-Tomcat-migration.patch deleted file mode 100644 index 04b0846..0000000 --- a/pki-core-Added-automatic-Tomcat-migration.patch +++ /dev/null @@ -1,324 +0,0 @@ -From 1f55d6cb8acd09a7a79bf051357e8299295d82f8 Mon Sep 17 00:00:00 2001 -From: Matthew Harmsen -Date: Sun, 1 Nov 2015 23:18:53 -0700 -Subject: [PATCH] Added automatic Tomcat migration. - -The pki-server migrate command has been modified such that if there -is no specific Tomcat version specified it will use the current -Tomcat version. - -The top attribute in the CLI class was not functioning properly, -so it has been replaced with get_top_module() method. - -The getopt() invocations in pki-server subcommands have been -replaced with gnu_getopt() to allow intermixing options and -arguments. - -https://fedorahosted.org/pki/ticket/1310 - -(based upon Edewata patch c7bc6eb94aa64c89467f9394554f860dc485ad94) ---- - base/common/python/pki/cli.py | 7 +++++-- - base/server/python/pki/server/__init__.py | 18 +++++++++++++++++ - base/server/python/pki/server/cli/instance.py | 28 +++++++++++++------------- - base/server/python/pki/server/cli/migrate.py | 14 +++++++++---- - base/server/python/pki/server/cli/nuxwdog.py | 4 ++-- - base/server/python/pki/server/cli/subsystem.py | 14 ++++++------- - 6 files changed, 56 insertions(+), 29 deletions(-) - -diff --git a/base/common/python/pki/cli.py b/base/common/python/pki/cli.py -index 4379780..2c51056 100644 ---- a/base/common/python/pki/cli.py -+++ b/base/common/python/pki/cli.py -@@ -31,7 +31,6 @@ class CLI(object): - self.name = name - self.description = description - self.parent = None -- self.top = self - - self.verbose = False - self.debug = False -@@ -59,11 +58,15 @@ class CLI(object): - def add_module(self, module): - self.modules[module.name] = module - module.parent = self -- module.top = self.top - - def get_module(self, name): - return self.modules.get(name) - -+ def get_top_module(self): -+ if self.parent: -+ return self.parent.get_top_module() -+ return self -+ - def print_message(self, message): - print '-' * len(message) - print message -diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py -index 89d4acf..dbb18cd 100644 ---- a/base/server/python/pki/server/__init__.py -+++ b/base/server/python/pki/server/__init__.py -@@ -431,3 +431,21 @@ class PKIServerException(pki.PKIException): - - self.instance = instance - self.subsystem = subsystem -+ -+ -+class Tomcat(object): -+ -+ @classmethod -+ def get_major_version(self): -+ -+ # run "tomcat version" -+ output = subprocess.check_output(['/usr/sbin/tomcat', 'version']) -+ -+ # find "Server version: Apache Tomcat/." -+ match = re.search(r'^Server version:[^/]*/(\d+).*$', output, re.MULTILINE) -+ -+ if not match: -+ raise Exception('Unable to determine Tomcat version') -+ -+ # return major version -+ return match.group(1) -diff --git a/base/server/python/pki/server/cli/instance.py b/base/server/python/pki/server/cli/instance.py -index becad14..9f0788b 100644 ---- a/base/server/python/pki/server/cli/instance.py -+++ b/base/server/python/pki/server/cli/instance.py -@@ -63,7 +63,7 @@ class InstanceFindCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, _ = getopt.getopt(argv, 'i:v', [ -+ opts, _ = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -@@ -123,7 +123,7 @@ class InstanceShowCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -@@ -172,7 +172,7 @@ class InstanceStartCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -@@ -222,7 +222,7 @@ class InstanceStopCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -@@ -274,7 +274,7 @@ class InstanceMigrateCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'tomcat=', 'verbose', 'debug', 'help']) - - except getopt.GetoptError as e: -@@ -311,11 +311,12 @@ class InstanceMigrateCLI(pki.cli.CLI): - sys.exit(1) - - if not tomcat_version: -- print 'ERROR: missing Tomcat version' -- self.print_help() -- sys.exit(1) -+ tomcat_version = pki.server.Tomcat.get_major_version() -+ -+ if self.verbose: -+ print('Migrating to Tomcat %s' % tomcat_version) - -- module = self.top.find_module('migrate') -+ module = self.get_top_module().find_module('migrate') - module.set_verbose(self.verbose) - module.set_debug(self.debug) - -@@ -343,7 +344,7 @@ class InstanceNuxwdogEnableCLI(pki.cli.CLI): - - def execute(self, argv): - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -@@ -369,7 +370,7 @@ class InstanceNuxwdogEnableCLI(pki.cli.CLI): - self.print_help() - sys.exit(1) - -- #module = self.top.find_module('nuxwdog-enable') -+ module = self.get_top_module().find_module('nuxwdog-enable') - module = pki.server.cli.nuxwdog.NuxwdogEnableCLI() - module.set_verbose(self.verbose) - -@@ -397,7 +398,7 @@ class InstanceNuxwdogDisableCLI(pki.cli.CLI): - - def execute(self, argv): - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -@@ -423,8 +424,7 @@ class InstanceNuxwdogDisableCLI(pki.cli.CLI): - self.print_help() - sys.exit(1) - -- # module = self.top.find_module('nuxwdog-disable') -- module = pki.server.cli.nuxwdog.NuxwdogDisableCLI() -+ module = self.get_top_module().find_module('nuxwdog-disable') - module.set_verbose(self.verbose) - - instance = pki.server.PKIInstance(instance_name) -diff --git a/base/server/python/pki/server/cli/migrate.py b/base/server/python/pki/server/cli/migrate.py -index bb807d8..cb3ba8f 100644 ---- a/base/server/python/pki/server/cli/migrate.py -+++ b/base/server/python/pki/server/cli/migrate.py -@@ -48,7 +48,7 @@ class MigrateCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, _ = getopt.getopt(argv, 'i:v', [ -+ opts, _ = getopt.gnu_getopt(argv, 'i:v', [ - 'tomcat=', 'verbose', 'debug', 'help']) - - except getopt.GetoptError as e: -@@ -79,9 +79,10 @@ class MigrateCLI(pki.cli.CLI): - sys.exit(1) - - if not tomcat_version: -- print 'ERROR: missing Tomcat version' -- self.print_help() -- sys.exit(1) -+ tomcat_version = pki.server.Tomcat.get_major_version() -+ -+ if self.verbose: -+ print('Migrating to Tomcat %s' % tomcat_version) - - instances = pki.server.PKIServer.instances() - -@@ -97,6 +98,9 @@ class MigrateCLI(pki.cli.CLI): - - def migrate_instance(self, instance, tomcat_version): - -+ if self.verbose: -+ print('Migrating %s instance' % instance.name) -+ - server_xml = os.path.join(instance.conf_dir, 'server.xml') - self.migrate_server_xml(server_xml, tomcat_version) - -@@ -376,6 +380,8 @@ class MigrateCLI(pki.cli.CLI): - self.migrate_subsystem(subsystem, tomcat_version) - - def migrate_subsystem(self, subsystem, tomcat_version): -+ if self.verbose: -+ print('Migrating %s/%s subsystem' % (subsystem.instance.name, subsystem.name)) - - self.migrate_context_xml(subsystem.context_xml, tomcat_version) - -diff --git a/base/server/python/pki/server/cli/nuxwdog.py b/base/server/python/pki/server/cli/nuxwdog.py -index d6ef91e..5f14e61 100644 ---- a/base/server/python/pki/server/cli/nuxwdog.py -+++ b/base/server/python/pki/server/cli/nuxwdog.py -@@ -66,7 +66,7 @@ class NuxwdogEnableCLI(pki.cli.CLI): - - def execute(self, argv): - try: -- opts, _ = getopt.getopt(argv, 'i:v', [ -+ opts, _ = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -@@ -272,7 +272,7 @@ class NuxwdogDisableCLI(pki.cli.CLI): - - def execute(self, argv): - try: -- opts, _ = getopt.getopt(argv, 'i:v', [ -+ opts, _ = getopt.gnu_getopt(argv, 'i:v', [ - 'verbose', 'help']) - - except getopt.GetoptError as e: -diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py -index 19db203..cd0e856 100644 ---- a/base/server/python/pki/server/cli/subsystem.py -+++ b/base/server/python/pki/server/cli/subsystem.py -@@ -67,7 +67,7 @@ class SubsystemFindCLI(pki.cli.CLI): - def execute(self, args): - - try: -- opts, _ = getopt.getopt(args, 'i:v', [ -+ opts, _ = getopt.gnu_getopt(args, 'i:v', [ - 'instance=', - 'verbose', 'help']) - -@@ -125,7 +125,7 @@ class SubsystemShowCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'instance=', - 'verbose', 'help']) - -@@ -182,7 +182,7 @@ class SubsystemEnableCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'instance=', - 'verbose', 'help']) - -@@ -242,7 +242,7 @@ class SubsystemDisableCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'instance=', - 'verbose', 'help']) - -@@ -322,7 +322,7 @@ class SubsystemCertFindCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'instance=', - 'verbose', 'help']) - -@@ -390,7 +390,7 @@ class SubsystemCertShowCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'instance=', - 'verbose', 'help']) - -@@ -455,7 +455,7 @@ class SubsystemCertUpdateCLI(pki.cli.CLI): - def execute(self, argv): - - try: -- opts, args = getopt.getopt(argv, 'i:v', [ -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ - 'instance=', - 'verbose', 'help']) - --- -1.8.3.1 - diff --git a/pki-core-Added-default-subject-DN-for-pki-client-cert-request.patch b/pki-core-Added-default-subject-DN-for-pki-client-cert-request.patch deleted file mode 100644 index b495a0c..0000000 --- a/pki-core-Added-default-subject-DN-for-pki-client-cert-request.patch +++ /dev/null @@ -1,110 +0,0 @@ -commit 1c1b9a1069650a12394848520a1dfb4753f8be72 -Author: Endi S. Dewata -Date: Sun Sep 27 17:23:48 2015 +0200 - - Added default subject DN for pki client-cert-request. - - The pki client-cert-request CLI has been modified to generate a - default subject DN if it's not specified. The man page has been - updated accordingly. - - https://fedorahosted.org/pki/ticket/1463 - (cherry picked from commit 3292de07ed01f6230de34120bf9cd1b8d164610a) - -diff --git a/base/java-tools/man/man1/pki-client.1 b/base/java-tools/man/man1/pki-client.1 -index 65e6185..da5de7c 100644 ---- a/base/java-tools/man/man1/pki-client.1 -+++ b/base/java-tools/man/man1/pki-client.1 -@@ -21,7 +21,7 @@ pki-client \- Command-Line Interface for managing the security database on Certi - \fBpki\fR [CLI options] \fBclient\fR - \fBpki\fR [CLI options] \fBclient-init\fR [command options] - \fBpki\fR [CLI options] \fBclient-cert-find\fR [command options] --\fBpki\fR [CLI options] \fBclient-cert-request\fR [command options] -+\fBpki\fR [CLI options] \fBclient-cert-request\fR [subject DN] [command options] - \fBpki\fR [CLI options] \fBclient-cert-import\fR [nickname] [command options] - \fBpki\fR [CLI options] \fBclient-cert-mod\fR [command options] - \fBpki\fR [CLI options] \fBclient-cert-show\fR [command options] -@@ -47,7 +47,7 @@ This command is to create a new security database for the client. - This command is to list certificates in the client security database. - .RE - .PP --\fBpki\fR [CLI options] \fBclient-cert-request\fR [command options] -+\fBpki\fR [CLI options] \fBclient-cert-request\fR [subject DN] [command options] - .RS 4 - This command is to generate and submit a certificate request. - .RE -@@ -82,13 +82,22 @@ To create a new database execute the following command: - - .B pki -d -c client-init - --To view certificates in the security database: -+To list certificates in the security database: - - .B pki -d -c client-cert-find - - To request a certificate: - --.B pki -d -c client-cert-request -+.B pki -d -c client-cert-request [subject DN] -+ -+The subject DN requirement depends on the certificate profile being requested. -+Some profiles may require the user to provide a subject DN in a certain -+format. Some other profiles may generate their own subject DN. -+ -+Certain profiles may also require additional authentication. To authenticate, -+a username and a password can be specified using the --username and --password -+options, respectively. If the subject DN is not specififed the CLI may use the -+username to generate a default subject DN "UID=". - - To import a certificate from a file into the security database: - -diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java -index c08d156..938cc4b 100644 ---- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java -+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java -@@ -68,7 +68,7 @@ public class ClientCertRequestCLI extends CLI { - } - - public void printHelp() { -- formatter.printHelp(getFullName() + " [OPTIONS...]", options); -+ formatter.printHelp(getFullName() + " [Subject DN] [OPTIONS...]", options); - } - - public void createOptions() { -@@ -151,13 +151,22 @@ public class ClientCertRequestCLI extends CLI { - System.exit(-1); - } - -- if (cmdArgs.length < 1) { -- System.err.println("Error: Missing subject DN."); -- printHelp(); -- System.exit(-1); -- } -+ String certRequestUsername = cmd.getOptionValue("username"); -+ -+ String subjectDN; - -- String subjectDN = cmdArgs[0]; -+ if (cmdArgs.length == 0) { -+ if (certRequestUsername == null) { -+ System.err.println("Error: Missing subject DN or request username."); -+ printHelp(); -+ System.exit(-1); -+ } -+ -+ subjectDN = "UID=" + certRequestUsername; -+ -+ } else { -+ subjectDN = cmdArgs[0]; -+ } - - // pkcs10, crmf - String requestType = cmd.getOptionValue("type", "pkcs10"); -@@ -316,7 +325,6 @@ public class ClientCertRequestCLI extends CLI { - } - } - -- String certRequestUsername = cmd.getOptionValue("username"); - if (certRequestUsername != null) { - request.setAttribute("uid", certRequestUsername); - } diff --git a/pki-core-Added-support-for-directory-authenticated-profiles.patch b/pki-core-Added-support-for-directory-authenticated-profiles.patch deleted file mode 100644 index ec6622d..0000000 --- a/pki-core-Added-support-for-directory-authenticated-profiles.patch +++ /dev/null @@ -1,202 +0,0 @@ -commit 531f40aafd5a2359466abd2cb8782961daa14e65 -Author: Endi S. Dewata -Date: Sun Sep 27 17:23:48 2015 +0200 - - Added support for directory-authenticated profiles in CLI. - - The pki cert-request-submit and client-cert-request CLIs have been - modified to provide options to specify the username and password - for directory-authenticated certificate enrollments. - - https://fedorahosted.org/pki/ticket/1463 - (cherry picked from commit bb2861b5ee8c82bc5cfffa9a9a6f23bb4b3e4e80) - -diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java -index 608490b..3a91f87 100644 ---- a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java -+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java -@@ -1,5 +1,6 @@ - package com.netscape.cmstools.cert; - -+import java.io.Console; - import java.io.File; - import java.io.FileNotFoundException; - import java.util.Arrays; -@@ -8,6 +9,7 @@ import java.util.Scanner; - import javax.xml.bind.JAXBException; - - import org.apache.commons.cli.CommandLine; -+import org.apache.commons.cli.Option; - import org.apache.commons.cli.ParseException; - - import com.netscape.certsrv.cert.CertEnrollmentRequest; -@@ -22,6 +24,13 @@ public class CertRequestSubmitCLI extends CLI { - public CertRequestSubmitCLI(CertCLI certCLI) { - super("request-submit", "Submit certificate request", certCLI); - this.certCLI = certCLI; -+ -+ Option option = new Option(null, "username", true, "Username for request authentication"); -+ option.setArgName("username"); -+ options.addOption(option); -+ -+ option = new Option(null, "password", false, "Prompt password for request authentication"); -+ options.addOption(option); - } - - public void printHelp() { -@@ -29,7 +38,7 @@ public class CertRequestSubmitCLI extends CLI { - } - - @Override -- public void execute(String[] args) { -+ public void execute(String[] args) throws Exception { - // Always check for "--help" prior to parsing - if (Arrays.asList(args).contains("--help")) { - // Display usage -@@ -55,20 +64,22 @@ public class CertRequestSubmitCLI extends CLI { - System.exit(-1); - } - -- try { -- CertEnrollmentRequest erd = getEnrollmentRequest(cmdArgs[0]); -- CertRequestInfos cri = certCLI.certClient.enrollRequest(erd); -- MainCLI.printMessage("Submitted certificate request"); -- CertCLI.printCertRequestInfos(cri); -+ CertEnrollmentRequest request = getEnrollmentRequest(cmdArgs[0]); - -- } catch (FileNotFoundException e) { -- System.err.println("Error: " + e.getMessage()); -- System.exit(-1); -+ String certRequestUsername = cmd.getOptionValue("username"); -+ if (certRequestUsername != null) { -+ request.setAttribute("uid", certRequestUsername); -+ } - -- } catch (JAXBException e) { -- System.err.println("Error: " + e.getMessage()); -- System.exit(-1); -+ if (cmd.hasOption("password")) { -+ Console console = System.console(); -+ String certRequestPassword = new String(console.readPassword("Password: ")); -+ request.setAttribute("pwd", certRequestPassword); - } -+ -+ CertRequestInfos cri = certCLI.certClient.enrollRequest(request); -+ MainCLI.printMessage("Submitted certificate request"); -+ CertCLI.printCertRequestInfos(cri); - } - - private CertEnrollmentRequest getEnrollmentRequest(String fileName) throws JAXBException, FileNotFoundException { -diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java -index e6bd0d9..c08d156 100644 ---- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java -+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java -@@ -19,13 +19,13 @@ - package com.netscape.cmstools.client; - - import java.io.ByteArrayOutputStream; -+import java.io.Console; - import java.io.File; - import java.security.KeyPair; -+import java.util.HashMap; -+import java.util.Map; - import java.util.Vector; - --import netscape.ldap.util.DN; --import netscape.ldap.util.RDN; -- - import org.apache.commons.cli.CommandLine; - import org.apache.commons.cli.Option; - import org.apache.commons.io.FileUtils; -@@ -50,6 +50,9 @@ import com.netscape.cmstools.cli.MainCLI; - import com.netscape.cmsutil.util.Cert; - import com.netscape.cmsutil.util.Utils; - -+import netscape.ldap.util.DN; -+import netscape.ldap.util.RDN; -+ - /** - * @author Endi S. Dewata - */ -@@ -73,6 +76,13 @@ public class ClientCertRequestCLI extends CLI { - option.setArgName("request type"); - options.addOption(option); - -+ option = new Option(null, "username", true, "Username for request authentication"); -+ option.setArgName("username"); -+ options.addOption(option); -+ -+ option = new Option(null, "password", false, "Prompt password for request authentication"); -+ options.addOption(option); -+ - option = new Option(null, "attribute-encoding", false, "Enable Attribute encoding"); - options.addOption(option); - -@@ -265,20 +275,58 @@ public class ClientCertRequestCLI extends CLI { - } - } - -+ // parse subject DN and put the values in a map -+ DN dn = new DN(subjectDN); -+ Vector rdns = dn.getRDNs(); -+ -+ Map subjectAttributes = new HashMap(); -+ for (int i=0; i< rdns.size(); i++) { -+ RDN rdn = (RDN)rdns.elementAt(i); -+ String type = rdn.getTypes()[0].toLowerCase(); -+ String value = rdn.getValues()[0]; -+ subjectAttributes.put(type, value); -+ } -+ - ProfileInput sn = request.getInput("Subject Name"); - if (sn != null) { -- DN dn = new DN(subjectDN); -- Vector rdns = dn.getRDNs(); -- -- for (int i=0; i< rdns.size(); i++) { -- RDN rdn = (RDN)rdns.elementAt(i); -- String type = rdn.getTypes()[0].toLowerCase(); -- String value = rdn.getValues()[0]; -- ProfileAttribute uidAttr = sn.getAttribute("sn_" + type); -- uidAttr.setValue(value); -+ if (verbose) System.out.println("Subject Name:"); -+ -+ for (ProfileAttribute attribute : sn.getAttributes()) { -+ String name = attribute.getName(); -+ String value = null; -+ -+ if (name.equals("subject")) { -+ // get the whole subject DN -+ value = subjectDN; -+ -+ } else if (name.startsWith("sn_")) { -+ // get value from subject DN -+ value = subjectAttributes.get(name.substring(3)); -+ -+ } else { -+ // unknown attribute, ignore -+ if (verbose) System.out.println(" - " + name); -+ continue; -+ } -+ -+ if (value == null) continue; -+ -+ if (verbose) System.out.println(" - " + name + ": " + value); -+ attribute.setValue(value); - } - } - -+ String certRequestUsername = cmd.getOptionValue("username"); -+ if (certRequestUsername != null) { -+ request.setAttribute("uid", certRequestUsername); -+ } -+ -+ if (cmd.hasOption("password")) { -+ Console console = System.console(); -+ String certRequestPassword = new String(console.readPassword("Password: ")); -+ request.setAttribute("pwd", certRequestPassword); -+ } -+ - if (verbose) { - System.out.println("Sending certificate request."); - } diff --git a/pki-core-Added-support-for-existing-CA-case-CS9.patch b/pki-core-Added-support-for-existing-CA-case-CS9.patch deleted file mode 100644 index 79186a4..0000000 --- a/pki-core-Added-support-for-existing-CA-case-CS9.patch +++ /dev/null @@ -1,3429 +0,0 @@ -From e6d3af6fbea19d751e34f760a5fb7fb66dc90ab6 Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Thu, 12 Nov 2015 00:23:26 +0100 -Subject: [PATCH 1/9] Added pki-server subsystem-cert-export command. - -A new command has been added to export a system certificate, the -CSR, and the key. This command can be used to migrate a system -certificate into another instance. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit 9dce4a497f7c977a3c453972706eeb325bd33275) ---- - base/common/python/pki/nss.py | 336 +++++++++++++++++++++++++ - base/server/python/pki/server/__init__.py | 6 + - base/server/python/pki/server/cli/subsystem.py | 126 ++++++++++ - 3 files changed, 468 insertions(+) - create mode 100644 base/common/python/pki/nss.py - -diff --git a/base/common/python/pki/nss.py b/base/common/python/pki/nss.py -new file mode 100644 -index 0000000..f36b771 ---- /dev/null -+++ b/base/common/python/pki/nss.py -@@ -0,0 +1,336 @@ -+#!/usr/bin/python -+# Authors: -+# Endi S. Dewata -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; version 2 of the License. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License along -+# with this program; if not, write to the Free Software Foundation, Inc., -+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+# -+# Copyright (C) 2015 Red Hat, Inc. -+# All rights reserved. -+# -+ -+import base64 -+import os -+import shutil -+import subprocess -+import tempfile -+ -+ -+CSR_HEADER = '-----BEGIN NEW CERTIFICATE REQUEST-----' -+CSR_FOOTER = '-----END NEW CERTIFICATE REQUEST-----' -+ -+CERT_HEADER = '-----BEGIN CERTIFICATE-----' -+CERT_FOOTER = '-----END CERTIFICATE-----' -+ -+ -+def convert_data(data, input_format, output_format, header=None, footer=None): -+ -+ if input_format == 'base64' and output_format == 'pem': -+ -+ # split a single line into multiple lines -+ lines = [data[i:i+64] for i in range(0, len(data), 64)] -+ return '%s\n%s\n%s\n' % (header, '\n'.join(lines), footer) -+ -+ if input_format == 'pem' and output_format == 'base64': -+ -+ # join multiple lines into a single line -+ lines = [] -+ for line in data.splitlines(): -+ line = line.rstrip('\r\n') -+ if line == header: -+ continue -+ if line == footer: -+ continue -+ lines.append(line) -+ -+ return ''.join(lines) -+ -+ raise Exception('Unable to convert data from %s to %s' % (input_format, output_format)) -+ -+def convert_csr(csr_data, input_format, output_format): -+ -+ return convert_data(csr_data, input_format, output_format, CSR_HEADER, CSR_FOOTER) -+ -+def convert_cert(cert_data, input_format, output_format): -+ -+ return convert_data(cert_data, input_format, output_format, CERT_HEADER, CERT_FOOTER) -+ -+ -+class NSSDatabase(object): -+ -+ def __init__(self, directory, password=None, password_file=None): -+ self.directory = directory -+ -+ self.tmpdir = tempfile.mkdtemp() -+ -+ if password: -+ self.password_file = os.path.join(self.tmpdir, 'password.txt') -+ with open(self.password_file, 'w') as f: -+ f.write(password) -+ -+ elif password_file: -+ self.password_file = password_file -+ -+ else: -+ raise Exception('Missing NSS database password') -+ -+ def close(self): -+ shutil.rmtree(self.tmpdir) -+ -+ def add_cert(self, -+ nickname, cert_file, -+ trust_attributes='u,u,u'): -+ -+ subprocess.check_call([ -+ 'certutil', -+ '-A', -+ '-d', self.directory, -+ '-n', nickname, -+ '-i', cert_file, -+ '-t', trust_attributes -+ ]) -+ -+ def modify_cert(self, -+ nickname, -+ trust_attributes='u,u,u'): -+ -+ subprocess.check_call([ -+ 'certutil', -+ '-M', -+ '-d', self.directory, -+ '-n', nickname, -+ '-t', trust_attributes -+ ]) -+ -+ def create_noise(self, noise_file, size=2048): -+ -+ subprocess.check_call([ -+ 'openssl', -+ 'rand', -+ '-out', noise_file, -+ str(size) -+ ]) -+ -+ def create_request(self, -+ subject_dn, -+ noise_file, -+ request_file): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ binary_request_file = os.path.join(tmpdir, 'request.bin') -+ b64_request_file = os.path.join(tmpdir, 'request.b64') -+ -+ # generate binary request -+ subprocess.check_call([ -+ 'certutil', -+ '-R', -+ '-d', self.directory, -+ '-f', self.password_file, -+ '-s', subject_dn, -+ '-z', noise_file, -+ '-o', binary_request_file -+ ]) -+ -+ # encode binary request in base-64 -+ subprocess.check_call([ -+ 'BtoA', binary_request_file, b64_request_file]) -+ -+ # read base-64 request -+ with open(b64_request_file, 'r') as f: -+ b64_request = f.read() -+ -+ # add header and footer -+ with open(request_file, 'w') as f: -+ f.write('-----BEGIN NEW CERTIFICATE REQUEST-----\n') -+ f.write(b64_request) -+ f.write('-----END NEW CERTIFICATE REQUEST-----\n') -+ -+ finally: -+ shutil.rmtree(tmpdir) -+ -+ def create_self_signed_ca_cert(self, -+ subject_dn, -+ request_file, -+ cert_file, -+ serial='1', -+ validity=240): -+ -+ p = subprocess.Popen([ -+ 'certutil', -+ '-C', -+ '-x', -+ '-d', self.directory, -+ '-f', self.password_file, -+ '-c', subject_dn, -+ '-a', -+ '-i', request_file, -+ '-o', cert_file, -+ '-m', serial, -+ '-v', str(validity), -+ '--keyUsage', 'digitalSignature,nonRepudiation,certSigning,crlSigning,critical', -+ '-2', -+ '-3', -+ '--extSKID', -+ '--extAIA' -+ ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -+ -+ keystroke = '' -+ -+ # Is this a CA certificate [y/N]? -+ keystroke += 'y\n' -+ -+ # Enter the path length constraint, enter to skip [<0 for unlimited path]: -+ keystroke += '\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += 'y\n' -+ -+ # Enter value for the authKeyID extension [y/N]? -+ keystroke += 'y\n' -+ -+ # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId()) -+ # Enter value for the key identifier fields,enter to omit: -+ keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n' -+ -+ # Select one of the following general name type: -+ keystroke += '0\n' -+ -+ # Enter value for the authCertSerial field, enter to omit: -+ keystroke += '\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += '\n' -+ -+ # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId()) -+ # Adding Subject Key ID extension. -+ # Enter value for the key identifier fields,enter to omit: -+ keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += '\n' -+ -+ # Enter access method type for Authority Information Access extension: -+ keystroke += '2\n' -+ -+ # Select one of the following general name type: -+ keystroke += '7\n' -+ -+ # TODO: replace with actual hostname name and port number -+ # Enter data: -+ keystroke += 'http://server.example.com:8080/ca/ocsp\n' -+ -+ # Select one of the following general name type: -+ keystroke += '0\n' -+ -+ # Add another location to the Authority Information Access extension [y/N] -+ keystroke += '\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += '\n' -+ -+ p.communicate(keystroke) -+ -+ rc = p.wait() -+ -+ if rc: -+ raise Exception('Failed to generate self-signed CA certificate. RC: %d' + rc) -+ -+ def get_cert(self, nickname, output_format='pem'): -+ -+ if output_format == 'pem': -+ output_format_option = '-a' -+ -+ elif output_format == 'base64': -+ output_format_option = '-r' -+ -+ else: -+ raise Exception('Unsupported output format: %s' % output_format) -+ -+ cert_data = subprocess.check_output([ -+ 'certutil', -+ '-L', -+ '-d', self.directory, -+ '-n', nickname, -+ output_format_option -+ ]) -+ -+ if output_format == 'base64': -+ cert_data = base64.b64encode(cert_data) -+ -+ return cert_data -+ -+ def remove_cert(self, nickname): -+ -+ subprocess.check_call([ -+ 'certutil', -+ '-D', -+ '-d', self.directory, -+ '-n', nickname -+ ]) -+ -+ def import_pkcs12(self, pkcs12_file, pkcs12_password=None, pkcs12_password_file=None): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ if pkcs12_password: -+ password_file = os.path.join(tmpdir, 'password.txt') -+ with open(password_file, 'w') as f: -+ f.write(pkcs12_password) -+ -+ elif pkcs12_password_file: -+ password_file = pkcs12_password_file -+ -+ else: -+ raise Exception('Missing PKCS #12 password') -+ -+ subprocess.check_call([ -+ 'pk12util', -+ '-d', self.directory, -+ '-k', self.password_file, -+ '-i', pkcs12_file, -+ '-w', password_file -+ ]) -+ -+ finally: -+ shutil.rmtree(tmpdir) -+ -+ def export_pkcs12(self, pkcs12_file, nickname, pkcs12_password=None, pkcs12_password_file=None): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ if pkcs12_password: -+ password_file = os.path.join(tmpdir, 'password.txt') -+ with open(password_file, 'w') as f: -+ f.write(pkcs12_password) -+ -+ elif pkcs12_password_file: -+ password_file = pkcs12_password_file -+ -+ else: -+ raise Exception('Missing PKCS #12 password') -+ -+ subprocess.check_call([ -+ 'pk12util', -+ '-d', self.directory, -+ '-k', self.password_file, -+ '-o', pkcs12_file, -+ '-w', password_file, -+ '-n', nickname -+ ]) -+ -+ finally: -+ shutil.rmtree(tmpdir) -diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py -index dbb18cd..0cc2678 100644 ---- a/base/server/python/pki/server/__init__.py -+++ b/base/server/python/pki/server/__init__.py -@@ -33,6 +33,7 @@ import subprocess - import tempfile - - import pki -+import pki.nss - - INSTANCE_BASE_DIR = '/var/lib/pki' - REGISTRY_DIR = '/etc/sysconfig/pki' -@@ -303,6 +304,11 @@ class PKIInstance(object): - - return password - -+ def open_nssdb(self): -+ return pki.nss.NSSDatabase( -+ directory=self.nssdb_dir, -+ password=self.get_password('internal')) -+ - def get_subsystem(self, name): - for subsystem in self.subsystems: - if name == subsystem.name: -diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py -index cd0e856..cb27adc 100644 ---- a/base/server/python/pki/server/cli/subsystem.py -+++ b/base/server/python/pki/server/cli/subsystem.py -@@ -23,11 +23,13 @@ from __future__ import absolute_import - from __future__ import print_function - import base64 - import getopt -+import getpass - import nss.nss as nss - import string - import sys - - import pki.cli -+import pki.nss - import pki.server - - -@@ -294,6 +296,7 @@ class SubsystemCertCLI(pki.cli.CLI): - - self.add_module(SubsystemCertFindCLI()) - self.add_module(SubsystemCertShowCLI()) -+ self.add_module(SubsystemCertExportCLI()) - self.add_module(SubsystemCertUpdateCLI()) - - @staticmethod -@@ -438,6 +441,129 @@ class SubsystemCertShowCLI(pki.cli.CLI): - SubsystemCertCLI.print_subsystem_cert(subsystem_cert) - - -+class SubsystemCertExportCLI(pki.cli.CLI): -+ -+ def __init__(self): -+ super(SubsystemCertExportCLI, self).__init__( -+ 'export', 'Export subsystem certificate') -+ -+ def usage(self): -+ print('Usage: pki-server subsystem-cert-export [OPTIONS] ') -+ print() -+ print(' -i, --instance Instance ID (default: pki-tomcat).') -+ print(' --cert-file Output file to store the exported certificate in PEM format.') -+ print(' --csr-file Output file to store the exported CSR in PEM format.') -+ print(' --pkcs12-file Output file to store the exported certificate and key in PKCS #12 format.') -+ print(' --pkcs12-password Password for the PKCS #12 file.') -+ print(' --pkcs12-password-file Input file containing the password for the PKCS #12 file.') -+ print(' -v, --verbose Run in verbose mode.') -+ print(' --help Show help message.') -+ print() -+ -+ def execute(self, argv): -+ -+ try: -+ opts, args = getopt.gnu_getopt(argv, 'i:v', [ -+ 'instance=', 'cert-file=', 'csr-file=', -+ 'pkcs12-file=', 'pkcs12-password=', 'pkcs12-password-file=', -+ 'verbose', 'help']) -+ -+ except getopt.GetoptError as e: -+ print('ERROR: ' + str(e)) -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) < 1: -+ print('ERROR: missing subsystem ID') -+ self.usage() -+ sys.exit(1) -+ -+ if len(args) < 2: -+ print('ERROR: missing cert ID') -+ self.usage() -+ sys.exit(1) -+ -+ subsystem_name = args[0] -+ cert_id = args[1] -+ instance_name = 'pki-tomcat' -+ cert_file = None -+ csr_file = None -+ pkcs12_file = None -+ pkcs12_password = None -+ pkcs12_password_file = None -+ -+ for o, a in opts: -+ if o in ('-i', '--instance'): -+ instance_name = a -+ -+ elif o == '--cert-file': -+ cert_file = a -+ -+ elif o == '--csr-file': -+ csr_file = a -+ -+ elif o == '--pkcs12-file': -+ pkcs12_file = a -+ -+ elif o == '--pkcs12-password': -+ pkcs12_password = a -+ -+ elif o == '--pkcs12-password-file': -+ pkcs12_password_file = a -+ -+ elif o in ('-v', '--verbose'): -+ self.set_verbose(True) -+ -+ elif o == '--help': -+ self.print_help() -+ sys.exit() -+ -+ else: -+ print('ERROR: unknown option ' + o) -+ self.usage() -+ sys.exit(1) -+ -+ if not cert_file and not csr_file and not pkcs12_file: -+ print('ERROR: missing output file') -+ self.usage() -+ sys.exit(1) -+ -+ instance = pki.server.PKIInstance(instance_name) -+ instance.load() -+ -+ subsystem = instance.get_subsystem(subsystem_name) -+ subsystem_cert = subsystem.get_subsystem_cert(cert_id) -+ -+ if cert_file: -+ -+ cert_data = pki.nss.convert_cert(subsystem_cert['data'], 'base64', 'pem') -+ with open(cert_file, 'w') as f: -+ f.write(cert_data) -+ -+ if csr_file: -+ -+ csr_data = pki.nss.convert_csr(subsystem_cert['request'], 'base64', 'pem') -+ with open(csr_file, 'w') as f: -+ f.write(csr_data) -+ -+ if pkcs12_file: -+ -+ if not pkcs12_password and not pkcs12_password_file: -+ pkcs12_password = getpass.getpass(prompt='Enter password for PKCS #12 file: ') -+ -+ nssdb = instance.open_nssdb() -+ try: -+ nssdb.export_pkcs12( -+ pkcs12_file=pkcs12_file, -+ nickname=subsystem_cert['nickname'], -+ pkcs12_password=pkcs12_password, -+ pkcs12_password_file=pkcs12_password_file) -+ finally: -+ nssdb.close() -+ -+ self.print_message('Exported %s certificate' % cert_id) -+ -+ - class SubsystemCertUpdateCLI(pki.cli.CLI): - - def __init__(self): --- -2.5.0 - - -From 1f1b74695787a6905f6652fcc2ab168f39ee7f73 Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Fri, 13 Nov 2015 16:55:43 +0100 -Subject: [PATCH 2/9] Added CLI options to simplify submitting CSR. - -The pki ca-cert-request-submit command has been modified to -provide options to specify the profile name and the CSR which -will be used to create and populate the request object. This -way it's no longer necessary to download the request template -and insert the CSR manually. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit ec9c68d68eabff3784fcf6dabf2c6745734b3c9c) ---- - .../cmstools/cert/CertRequestSubmitCLI.java | 153 +++++++++++++++++++-- - 1 file changed, 144 insertions(+), 9 deletions(-) - -diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java -index 3a91f87..90b9577 100644 ---- a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java -+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java -@@ -4,9 +4,10 @@ import java.io.Console; - import java.io.File; - import java.io.FileNotFoundException; - import java.util.Arrays; -+import java.util.HashMap; -+import java.util.Map; - import java.util.Scanner; -- --import javax.xml.bind.JAXBException; -+import java.util.Vector; - - import org.apache.commons.cli.CommandLine; - import org.apache.commons.cli.Option; -@@ -14,9 +15,14 @@ import org.apache.commons.cli.ParseException; - - import com.netscape.certsrv.cert.CertEnrollmentRequest; - import com.netscape.certsrv.cert.CertRequestInfos; -+import com.netscape.certsrv.profile.ProfileAttribute; -+import com.netscape.certsrv.profile.ProfileInput; - import com.netscape.cmstools.cli.CLI; - import com.netscape.cmstools.cli.MainCLI; - -+import netscape.ldap.util.DN; -+import netscape.ldap.util.RDN; -+ - public class CertRequestSubmitCLI extends CLI { - - CertCLI certCLI; -@@ -25,12 +31,36 @@ public class CertRequestSubmitCLI extends CLI { - super("request-submit", "Submit certificate request", certCLI); - this.certCLI = certCLI; - -- Option option = new Option(null, "username", true, "Username for request authentication"); -+ Option option = new Option(null, "issuer-id", true, "Authority ID (host authority if omitted)"); -+ option.setArgName("ID"); -+ options.addOption(option); -+ -+ option = new Option(null, "issuer-dn", true, "Authority DN (host authority if omitted)"); -+ option.setArgName("DN"); -+ options.addOption(option); -+ -+ option = new Option(null, "username", true, "Username for request authentication"); - option.setArgName("username"); - options.addOption(option); - - option = new Option(null, "password", false, "Prompt password for request authentication"); - options.addOption(option); -+ -+ option = new Option(null, "profile", true, "Certificate profile"); -+ option.setArgName("profile"); -+ options.addOption(option); -+ -+ option = new Option(null, "request-type", true, "Request type (default: pkcs10)"); -+ option.setArgName("type"); -+ options.addOption(option); -+ -+ option = new Option(null, "csr-file", true, "File containing the CSR"); -+ option.setArgName("path"); -+ options.addOption(option); -+ -+ option = new Option(null, "subject", true, "Subject DN"); -+ option.setArgName("DN"); -+ options.addOption(option); - } - - public void printHelp() { -@@ -58,13 +88,119 @@ public class CertRequestSubmitCLI extends CLI { - - String[] cmdArgs = cmd.getArgs(); - -- if (cmdArgs.length < 1) { -- System.err.println("Error: No filename specified."); -+ String requestFilename = cmdArgs.length > 0 ? cmdArgs[0] : null; -+ String profileID = cmd.getOptionValue("profile"); -+ -+ if (requestFilename == null && profileID == null) { -+ System.err.println("Error: Missing request file or profile ID."); -+ printHelp(); -+ System.exit(-1); -+ } -+ -+ if (requestFilename != null && profileID != null) { -+ System.err.println("Error: Request file and profile ID are mutually exclusive."); - printHelp(); - System.exit(-1); - } - -- CertEnrollmentRequest request = getEnrollmentRequest(cmdArgs[0]); -+ String requestType = cmd.getOptionValue("request-type"); -+ -+ CertEnrollmentRequest request; -+ if (requestFilename == null) { // if no request file specified, generate new request from profile -+ -+ if (verbose) { -+ System.out.println("Retrieving " + profileID + " profile."); -+ } -+ -+ request = certCLI.certClient.getEnrollmentTemplate(profileID); -+ -+ // set default request type for new request -+ if (requestType == null) requestType = "pkcs10"; -+ -+ } else { // otherwise, load request from file -+ -+ if (verbose) { -+ System.out.println("Loading request from " + requestFilename + "."); -+ } -+ -+ String xml = loadFile(requestFilename); -+ request = CertEnrollmentRequest.fromXML(xml); -+ } -+ -+ if (requestType != null) { -+ -+ if (verbose) { -+ System.out.println("Request type: " + requestType); -+ } -+ -+ for (ProfileInput input : request.getInputs()) { -+ ProfileAttribute typeAttr = input.getAttribute("cert_request_type"); -+ if (typeAttr != null) { -+ typeAttr.setValue(requestType); -+ } -+ } -+ } -+ -+ String csrFilename = cmd.getOptionValue("csr-file"); -+ if (csrFilename != null) { -+ -+ String csr = loadFile(csrFilename); -+ -+ if (verbose) { -+ System.out.println("CSR:"); -+ System.out.println(csr); -+ } -+ -+ for (ProfileInput input : request.getInputs()) { -+ ProfileAttribute csrAttr = input.getAttribute("cert_request"); -+ if (csrAttr != null) { -+ csrAttr.setValue(csr); -+ } -+ } -+ } -+ -+ String subjectDN = cmd.getOptionValue("subject"); -+ if (subjectDN != null) { -+ DN dn = new DN(subjectDN); -+ Vector rdns = dn.getRDNs(); -+ -+ Map subjectAttributes = new HashMap(); -+ for (int i=0; i< rdns.size(); i++) { -+ RDN rdn = (RDN)rdns.elementAt(i); -+ String type = rdn.getTypes()[0].toLowerCase(); -+ String value = rdn.getValues()[0]; -+ subjectAttributes.put(type, value); -+ } -+ -+ ProfileInput sn = request.getInput("Subject Name"); -+ if (sn != null) { -+ if (verbose) System.out.println("Subject Name:"); -+ -+ for (ProfileAttribute attribute : sn.getAttributes()) { -+ String name = attribute.getName(); -+ String value = null; -+ -+ if (name.equals("subject")) { -+ // get the whole subject DN -+ value = subjectDN; -+ -+ } else if (name.startsWith("sn_")) { -+ // get value from subject DN -+ value = subjectAttributes.get(name.substring(3)); -+ -+ } else { -+ // unknown attribute, ignore -+ if (verbose) System.out.println(" - " + name); -+ continue; -+ } -+ -+ if (value == null) continue; -+ -+ if (verbose) System.out.println(" - " + name + ": " + value); -+ attribute.setValue(value); -+ } -+ } -+ } - - String certRequestUsername = cmd.getOptionValue("username"); - if (certRequestUsername != null) { -@@ -82,10 +218,9 @@ public class CertRequestSubmitCLI extends CLI { - CertCLI.printCertRequestInfos(cri); - } - -- private CertEnrollmentRequest getEnrollmentRequest(String fileName) throws JAXBException, FileNotFoundException { -+ private String loadFile(String fileName) throws FileNotFoundException { - try (Scanner scanner = new Scanner(new File(fileName))) { -- String xml = scanner.useDelimiter("\\A").next(); -- return CertEnrollmentRequest.fromXML(xml); -+ return scanner.useDelimiter("\\A").next(); - } - } - } --- -2.5.0 - - -From bc3363f0df7e4950adca2192e0b90b6cc2761a56 Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Sat, 7 Nov 2015 00:09:19 +0100 -Subject: [PATCH 3/9] Added mechanism to import existing CA certificate. - -The deployment procedure for external CA has been modified -such that it generates the CA CSR before starting the server. -This allows the same procedure to be used to import CA -certificate from an existing server. It also removes the -requirement to keep the server running while waiting to get -the CSR signed by an external CA. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit 20c985ae773b26f653cac6d22bd9d93923e18c8e) ---- - base/common/python/pki/nss.py | 247 ++++++++++++++++++--- - .../certsrv/system/ConfigurationRequest.java | 12 + - .../cms/servlet/csadmin/ConfigurationUtils.java | 101 +++++++++ - .../dogtagpki/server/rest/SystemConfigService.java | 38 +++- - base/server/etc/default.cfg | 10 +- - base/server/python/pki/server/__init__.py | 5 +- - .../python/pki/server/deployment/pkihelper.py | 70 +++--- - .../server/deployment/scriptlets/configuration.py | 128 ++++++++++- - .../server/deployment/scriptlets/finalization.py | 12 +- - 9 files changed, 557 insertions(+), 66 deletions(-) - -diff --git a/base/common/python/pki/nss.py b/base/common/python/pki/nss.py -index f36b771..196fe46 100644 ---- a/base/common/python/pki/nss.py -+++ b/base/common/python/pki/nss.py -@@ -32,12 +32,19 @@ CSR_FOOTER = '-----END NEW CERTIFICATE REQUEST-----' - CERT_HEADER = '-----BEGIN CERTIFICATE-----' - CERT_FOOTER = '-----END CERTIFICATE-----' - -+PKCS7_HEADER = '-----BEGIN PKCS7-----' -+PKCS7_FOOTER = '-----END PKCS7-----' -+ - - def convert_data(data, input_format, output_format, header=None, footer=None): - -+ if input_format == output_format: -+ return data -+ - if input_format == 'base64' and output_format == 'pem': - - # split a single line into multiple lines -+ data = data.rstrip('\r\n') - lines = [data[i:i+64] for i in range(0, len(data), 64)] - return '%s\n%s\n%s\n' % (header, '\n'.join(lines), footer) - -@@ -65,11 +72,32 @@ def convert_cert(cert_data, input_format, output_format): - - return convert_data(cert_data, input_format, output_format, CERT_HEADER, CERT_FOOTER) - -+def convert_pkcs7(pkcs7_data, input_format, output_format): -+ -+ return convert_data(pkcs7_data, input_format, output_format, PKCS7_HEADER, PKCS7_FOOTER) -+ -+def get_file_type(filename): -+ -+ with open(filename, 'r') as f: -+ data = f.read() -+ -+ if data.startswith(CSR_HEADER): -+ return 'csr' -+ -+ if data.startswith(CERT_HEADER): -+ return 'cert' -+ -+ if data.startswith(PKCS7_HEADER): -+ return 'pkcs7' -+ -+ return None -+ - - class NSSDatabase(object): - -- def __init__(self, directory, password=None, password_file=None): -+ def __init__(self, directory, token='internal', password=None, password_file=None): - self.directory = directory -+ self.token = token - - self.tmpdir = tempfile.mkdtemp() - -@@ -88,29 +116,38 @@ class NSSDatabase(object): - shutil.rmtree(self.tmpdir) - - def add_cert(self, -- nickname, cert_file, -- trust_attributes='u,u,u'): -+ nickname, -+ cert_file, -+ trust_attributes=',,'): - -- subprocess.check_call([ -+ cmd = [ - 'certutil', - '-A', - '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, - '-n', nickname, - '-i', cert_file, - '-t', trust_attributes -- ]) -+ ] -+ -+ subprocess.check_call(cmd) - - def modify_cert(self, - nickname, -- trust_attributes='u,u,u'): -+ trust_attributes): - -- subprocess.check_call([ -+ cmd = [ - 'certutil', - '-M', - '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, - '-n', nickname, - '-t', trust_attributes -- ]) -+ ] -+ -+ subprocess.check_call(cmd) - - def create_noise(self, noise_file, size=2048): - -@@ -123,27 +160,56 @@ class NSSDatabase(object): - - def create_request(self, - subject_dn, -- noise_file, -- request_file): -+ request_file, -+ noise_file=None, -+ key_type=None, -+ key_size=None, -+ curve=None, -+ hash_alg=None): - - tmpdir = tempfile.mkdtemp() - - try: -+ if not noise_file: -+ noise_file = os.path.join(tmpdir, 'noise.bin') -+ if key_size: -+ size = key_size -+ else: -+ size = 2048 -+ self.create_noise( -+ noise_file=noise_file, -+ size=size) -+ - binary_request_file = os.path.join(tmpdir, 'request.bin') -- b64_request_file = os.path.join(tmpdir, 'request.b64') - -- # generate binary request -- subprocess.check_call([ -+ cmd = [ - 'certutil', - '-R', - '-d', self.directory, -+ '-h', self.token, - '-f', self.password_file, - '-s', subject_dn, -- '-z', noise_file, -- '-o', binary_request_file -- ]) -+ '-o', binary_request_file, -+ '-z', noise_file -+ ] -+ -+ if key_type: -+ cmd.extend(['-k', key_type]) -+ -+ if key_size: -+ cmd.extend(['-g', str(key_size)]) -+ -+ if curve: -+ cmd.extend(['-q', curve]) -+ -+ if hash_alg: -+ cmd.extend(['-Z', hash_alg]) -+ -+ # generate binary request -+ subprocess.check_call(cmd) - - # encode binary request in base-64 -+ b64_request_file = os.path.join(tmpdir, 'request.b64') - subprocess.check_call([ - 'BtoA', binary_request_file, b64_request_file]) - -@@ -167,11 +233,12 @@ class NSSDatabase(object): - serial='1', - validity=240): - -- p = subprocess.Popen([ -+ cmd = [ - 'certutil', - '-C', - '-x', - '-d', self.directory, -+ '-h', self.token, - '-f', self.password_file, - '-c', subject_dn, - '-a', -@@ -184,7 +251,9 @@ class NSSDatabase(object): - '-3', - '--extSKID', - '--extAIA' -- ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -+ ] -+ -+ p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - keystroke = '' - -@@ -245,7 +314,7 @@ class NSSDatabase(object): - rc = p.wait() - - if rc: -- raise Exception('Failed to generate self-signed CA certificate. RC: %d' + rc) -+ raise Exception('Failed to generate self-signed CA certificate. RC: %d' % rc) - - def get_cert(self, nickname, output_format='pem'): - -@@ -258,13 +327,17 @@ class NSSDatabase(object): - else: - raise Exception('Unsupported output format: %s' % output_format) - -- cert_data = subprocess.check_output([ -+ cmd = [ - 'certutil', - '-L', - '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, - '-n', nickname, - output_format_option -- ]) -+ ] -+ -+ cert_data = subprocess.check_output(cmd) - - if output_format == 'base64': - cert_data = base64.b64encode(cert_data) -@@ -273,12 +346,127 @@ class NSSDatabase(object): - - def remove_cert(self, nickname): - -- subprocess.check_call([ -+ cmd = [ - 'certutil', - '-D', - '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, - '-n', nickname -- ]) -+ ] -+ -+ subprocess.check_call(cmd) -+ -+ def import_cert_chain(self, nickname, cert_chain_file, trust_attributes=None): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ file_type = get_file_type(cert_chain_file) -+ -+ if file_type == 'cert': # import single PEM cert -+ self.add_cert( -+ nickname=nickname, -+ cert_file=cert_chain_file, -+ trust_attributes=trust_attributes) -+ return self.get_cert( -+ nickname=nickname, -+ output_format='base64') -+ -+ elif file_type == 'pkcs7': # import PKCS #7 cert chain -+ return self.import_pkcs7( -+ pkcs7_file=cert_chain_file, -+ nickname=nickname, -+ trust_attributes=trust_attributes, -+ output_format='base64') -+ -+ else: # import PKCS #7 data without header/footer -+ with open(cert_chain_file, 'r') as f: -+ base64_data = f.read() -+ pkcs7_data = convert_pkcs7(base64_data, 'base64', 'pem') -+ -+ tmp_cert_chain_file = os.path.join(tmpdir, 'cert_chain.p7b') -+ with open(tmp_cert_chain_file, 'w') as f: -+ f.write(pkcs7_data) -+ -+ self.import_pkcs7( -+ pkcs7_file=tmp_cert_chain_file, -+ nickname=nickname, -+ trust_attributes=trust_attributes) -+ -+ return base64_data -+ -+ finally: -+ shutil.rmtree(tmpdir) -+ -+ def import_pkcs7(self, pkcs7_file, nickname, trust_attributes=None, output_format='pem'): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ # export certs from PKCS #7 into PEM output -+ output = subprocess.check_output([ -+ 'openssl', -+ 'pkcs7', -+ '-print_certs', -+ '-in', pkcs7_file -+ ]) -+ -+ # parse PEM output into separate PEM certificates -+ certs = [] -+ lines = [] -+ state = 'header' -+ -+ for line in output.splitlines(): -+ -+ if state == 'header': -+ if line != CERT_HEADER: -+ # ignore header lines -+ pass -+ else: -+ # save cert header -+ lines.append(line) -+ state = 'body' -+ -+ elif state == 'body': -+ if line != CERT_FOOTER: -+ # save cert body -+ lines.append(line) -+ else: -+ # save cert footer -+ lines.append(line) -+ -+ # construct PEM cert -+ cert = '\n'.join(lines) -+ certs.append(cert) -+ lines = [] -+ state = 'header' -+ -+ # import PEM certs into NSS database -+ counter = 1 -+ for cert in certs: -+ -+ cert_file = os.path.join(tmpdir, 'cert%d.pem' % counter) -+ with open(cert_file, 'w') as f: -+ f.write(cert) -+ -+ if counter == 1: -+ n = nickname -+ else: -+ n = '%s #%d' % (nickname, counter) -+ -+ self.add_cert(n, cert_file, trust_attributes) -+ -+ counter += 1 -+ -+ # convert PKCS #7 data to the requested format -+ with open(pkcs7_file, 'r') as f: -+ data = f.read() -+ -+ return convert_pkcs7(data, 'pem', output_format) -+ -+ finally: -+ shutil.rmtree(tmpdir) - - def import_pkcs12(self, pkcs12_file, pkcs12_password=None, pkcs12_password_file=None): - -@@ -296,13 +484,16 @@ class NSSDatabase(object): - else: - raise Exception('Missing PKCS #12 password') - -- subprocess.check_call([ -+ cmd = [ - 'pk12util', - '-d', self.directory, -+ '-h', self.token, - '-k', self.password_file, - '-i', pkcs12_file, - '-w', password_file -- ]) -+ ] -+ -+ subprocess.check_call(cmd) - - finally: - shutil.rmtree(tmpdir) -@@ -323,14 +514,16 @@ class NSSDatabase(object): - else: - raise Exception('Missing PKCS #12 password') - -- subprocess.check_call([ -+ cmd = [ - 'pk12util', - '-d', self.directory, - '-k', self.password_file, - '-o', pkcs12_file, - '-w', password_file, - '-n', nickname -- ]) -+ ] -+ -+ subprocess.check_call(cmd) - - finally: - shutil.rmtree(tmpdir) -diff --git a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java -index 7c6c339..8c9da6f 100644 ---- a/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java -+++ b/base/common/src/com/netscape/certsrv/system/ConfigurationRequest.java -@@ -178,6 +178,9 @@ public class ConfigurationRequest { - protected String adminCert; - - @XmlElement -+ protected Boolean external; -+ -+ @XmlElement - protected String standAlone; - - @XmlElement -@@ -754,6 +757,14 @@ public class ConfigurationRequest { - this.adminCert = adminCert; - } - -+ public Boolean isExternal() { -+ return external; -+ } -+ -+ public void setExternal(Boolean external) { -+ this.external = external; -+ } -+ - public boolean getStandAlone() { - return (standAlone != null && standAlone.equalsIgnoreCase("true")); - } -@@ -945,6 +956,7 @@ public class ConfigurationRequest { - ", adminCert=" + adminCert + - ", importAdminCert=" + importAdminCert + - ", generateServerCert=" + generateServerCert + -+ ", external=" + external + - ", standAlone=" + standAlone + - ", stepTwo=" + stepTwo + - ", authdbBaseDN=" + authdbBaseDN + -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 -index a981b9a..32e1027 100644 ---- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java -+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java -@@ -126,6 +126,7 @@ import com.netscape.certsrv.base.EBaseException; - import com.netscape.certsrv.base.EPropertyNotFound; - import com.netscape.certsrv.base.IConfigStore; - import com.netscape.certsrv.base.ISubsystem; -+import com.netscape.certsrv.base.MetaInfo; - import com.netscape.certsrv.base.PKIException; - import com.netscape.certsrv.base.ResourceNotFoundException; - import com.netscape.certsrv.ca.ICertificateAuthority; -@@ -133,6 +134,8 @@ import com.netscape.certsrv.client.ClientConfig; - import com.netscape.certsrv.client.PKIClient; - import com.netscape.certsrv.client.PKIConnection; - import com.netscape.certsrv.dbs.IDBSubsystem; -+import com.netscape.certsrv.dbs.certdb.ICertRecord; -+import com.netscape.certsrv.dbs.certdb.ICertificateRepository; - import com.netscape.certsrv.dbs.crldb.ICRLIssuingPointRecord; - import com.netscape.certsrv.key.KeyData; - import com.netscape.certsrv.ldap.ILdapConnFactory; -@@ -2266,6 +2269,54 @@ public class ConfigurationUtils { - certObj.setCertChain(certChainStr); - } - -+ public static KeyPair loadKeyPair(String nickname) throws Exception { -+ -+ CMS.debug("ConfigurationUtils: loadKeyPair(" + nickname + ")"); -+ -+ CryptoManager cm = CryptoManager.getInstance(); -+ -+ X509Certificate cert = cm.findCertByNickname(nickname); -+ PublicKey publicKey = cert.getPublicKey(); -+ PrivateKey privateKey = cm.findPrivKeyByCert(cert); -+ -+ return new KeyPair(publicKey, privateKey); -+ } -+ -+ public static void storeKeyPair(IConfigStore config, String tag, KeyPair pair) -+ throws TokenException, EBaseException { -+ -+ CMS.debug("ConfigurationUtils: storeKeyPair(" + tag + ")"); -+ -+ PublicKey publicKey = pair.getPublic(); -+ -+ if (publicKey instanceof RSAPublicKey) { -+ -+ RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey; -+ -+ byte modulus[] = rsaPublicKey.getModulus().toByteArray(); -+ config.putString(PCERT_PREFIX + tag + ".pubkey.modulus", -+ CryptoUtil.byte2string(modulus)); -+ -+ byte exponent[] = rsaPublicKey.getPublicExponent().toByteArray(); -+ config.putString(PCERT_PREFIX + tag + ".pubkey.exponent", -+ CryptoUtil.byte2string(exponent)); -+ -+ } else { // ECC -+ -+ CMS.debug("ConfigurationUtils: Public key class: " + publicKey.getClass().getName()); -+ byte encoded[] = publicKey.getEncoded(); -+ config.putString(PCERT_PREFIX + tag + ".pubkey.encoded", CryptoUtil.byte2string(encoded)); -+ } -+ -+ PrivateKey privateKey = (PrivateKey) pair.getPrivate(); -+ byte id[] = privateKey.getUniqueID(); -+ String kid = CryptoUtil.byte2string(id); -+ config.putString(PCERT_PREFIX + tag + ".privkey.id", kid); -+ -+ String keyAlgo = config.getString(PCERT_PREFIX + tag + ".signingalgorithm"); -+ setSigningAlgorithm(tag, keyAlgo, config); -+ } -+ - public static void createECCKeyPair(String token, String curveName, IConfigStore config, String ct) - throws NoSuchAlgorithmException, NoSuchTokenException, TokenException, - CryptoManager.NotInitializedException, EPropertyNotFound, EBaseException { -@@ -2830,6 +2881,20 @@ public class ConfigurationUtils { - } - } - -+ public static void loadCertRequest(IConfigStore config, String tag, Cert cert) throws Exception { -+ -+ CMS.debug("ConfigurationUtils.loadCertRequest(" + tag + ")"); -+ -+ String subjectDN = config.getString(PCERT_PREFIX + tag + ".dn"); -+ cert.setDN(subjectDN); -+ -+ String subsystem = config.getString(PCERT_PREFIX + tag + ".subsystem"); -+ String certreq = config.getString(subsystem + "." + tag + ".certreq"); -+ String formattedCertreq = CryptoUtil.reqFormat(certreq); -+ -+ cert.setRequest(formattedCertreq); -+ } -+ - public static void handleCertRequest(IConfigStore config, String certTag, Cert cert) throws EPropertyNotFound, - EBaseException, InvalidKeyException, NotInitializedException, TokenException, NoSuchAlgorithmException, - NoSuchProviderException, CertificateException, SignatureException, IOException { -@@ -2971,6 +3036,42 @@ public class ConfigurationUtils { - return pubk; - } - -+ public static void loadCert(IConfigStore config, Cert cert) throws Exception { -+ -+ String tag = cert.getCertTag(); -+ CMS.debug("ConfigurationUtils: loadCert(" + tag + ")"); -+ -+ CryptoManager cm = CryptoManager.getInstance(); -+ X509Certificate x509Cert = cm.findCertByNickname(cert.getNickname()); -+ -+ if (!x509Cert.getSubjectDN().equals(x509Cert.getIssuerDN())) { -+ CMS.debug("ConfigurationUtils: " + tag + " cert is not self-signed"); -+ -+ String subsystem = config.getString(PCERT_PREFIX + tag + ".subsystem"); -+ String certChain = config.getString(subsystem + ".external_ca_chain.cert"); -+ cert.setCertChain(certChain); -+ -+ return; -+ } -+ -+ CMS.debug("ConfigurationUtils: " + tag + " cert is self-signed"); -+ -+ // When importing existing self-signed CA certificate, create a -+ // certificate record to reserve the serial number. Otherwise it -+ // might conflict with system certificates to be created later. -+ -+ X509CertImpl x509CertImpl = new X509CertImpl(x509Cert.getEncoded()); -+ -+ ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem(ICertificateAuthority.ID); -+ ICertificateRepository cr = ca.getCertificateRepository(); -+ -+ BigInteger serialNo = x509Cert.getSerialNumber(); -+ MetaInfo meta = new MetaInfo(); -+ -+ ICertRecord record = cr.createCertRecord(serialNo, x509CertImpl, meta); -+ cr.addCertificateRecord(record); -+ } -+ - public static int handleCerts(Cert cert) throws IOException, EBaseException, CertificateException, - NotInitializedException, TokenException, InvalidKeyException { - String certTag = cert.getCertTag(); -diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -index a013868..697196a 100644 ---- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -@@ -20,6 +20,7 @@ package org.dogtagpki.server.rest; - import java.math.BigInteger; - import java.net.MalformedURLException; - import java.net.URL; -+import java.security.KeyPair; - import java.security.NoSuchAlgorithmException; - import java.security.PublicKey; - import java.util.ArrayList; -@@ -420,7 +421,13 @@ public class SystemConfigService extends PKIService implements SystemConfigResou - } - cs.commit(false); - -- if (!request.getStepTwo()) { -+ if (request.isExternal() && tag.equals("signing")) { // external/existing CA -+ // load key pair for existing and externally-signed signing cert -+ CMS.debug("SystemConfigService: loading signing cert key pair"); -+ KeyPair pair = ConfigurationUtils.loadKeyPair(certData.getNickname()); -+ ConfigurationUtils.storeKeyPair(cs, tag, pair); -+ -+ } else if (!request.getStepTwo()) { - if (keytype.equals("ecc")) { - String curvename = certData.getKeyCurveName() != null ? - certData.getKeyCurveName() : cs.getString("keys.ecc.curve.default"); -@@ -443,7 +450,15 @@ public class SystemConfigService extends PKIService implements SystemConfigResou - cert.setSubsystem(cs.getString("preop.cert." + tag + ".subsystem")); - cert.setType(cs.getString("preop.cert." + tag + ".type")); - -- if (!request.getStepTwo()) { -+ if (request.isExternal() && tag.equals("signing")) { // external/existing CA -+ -+ // update configuration for existing or externally-signed signing certificate -+ String certStr = cs.getString("ca." + tag + ".cert" ); -+ cert.setCert(certStr); -+ CMS.debug("SystemConfigService: certificate " + tag + ": " + certStr); -+ ConfigurationUtils.updateConfig(cs, tag); -+ -+ } else if (!request.getStepTwo()) { - ConfigurationUtils.configCert(null, null, null, cert); - - } else { -@@ -465,8 +480,16 @@ public class SystemConfigService extends PKIService implements SystemConfigResou - CMS.debug("Step 2: certStr for '" + tag + "' is " + certStr); - } - -- // Handle Cert Requests for everything EXCEPT Stand-alone PKI (Step 2) -- if (request.getStandAlone()) { -+ if (request.isExternal() && tag.equals("signing")) { // external/existing CA -+ -+ CMS.debug("SystemConfigService: Loading cert request for " + tag + " cert"); -+ ConfigurationUtils.loadCertRequest(cs, tag, cert); -+ -+ CMS.debug("SystemConfigService: Loading cert " + tag); -+ ConfigurationUtils.loadCert(cs, cert); -+ -+ } else if (request.getStandAlone()) { -+ // Handle Cert Requests for everything EXCEPT Stand-alone PKI (Step 2) - if (!request.getStepTwo()) { - // Stand-alone PKI (Step 1) - ConfigurationUtils.handleCertRequest(cs, tag, cert); -@@ -489,6 +512,13 @@ public class SystemConfigService extends PKIService implements SystemConfigResou - ConfigurationUtils.updateCloneConfig(); - } - -+ if (request.isExternal() && tag.equals("signing")) { // external/existing CA -+ CMS.debug("SystemConfigService: External CA has signing cert"); -+ hasSigningCert.setValue(true); -+ certs.add(cert); -+ continue; -+ } -+ - // to determine if we have the signing cert when using an external ca - // this will only execute on a ca or stand-alone pki - String b64 = certData.getCert(); -diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg -index ddd2d83..1c1ae92 100644 ---- a/base/server/etc/default.cfg -+++ b/base/server/etc/default.cfg -@@ -22,6 +22,7 @@ sensitive_parameters= - pki_client_pkcs12_password - pki_clone_pkcs12_password - pki_ds_password -+ pki_external_pkcs12_password - pki_one_time_pin - pki_pin - pki_replication_password -@@ -365,10 +366,13 @@ pki_req_ext_add=False - pki_req_ext_oid=1.3.6.1.4.1.311.20.2 - pki_req_ext_critical=False - pki_req_ext_data=1E0A00530075006200430041 --pki_external_csr_path=%(pki_instance_configuration_path)s/ca_signing.csr -+pki_external_csr_path= - pki_external_step_two=False --pki_external_ca_cert_chain_path=%(pki_instance_configuration_path)s/external_ca_chain.cert --pki_external_ca_cert_path=%(pki_instance_configuration_path)s/external_ca.cert -+pki_external_ca_cert_chain_path= -+pki_external_ca_cert_chain_nickname=caSigningCert External CA -+pki_external_ca_cert_path= -+pki_external_pkcs12_path= -+pki_external_pkcs12_password= - pki_import_admin_cert=False - pki_ocsp_signing_key_algorithm=SHA256withRSA - pki_ocsp_signing_key_size=2048 -diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py -index 0cc2678..5942115 100644 ---- a/base/server/python/pki/server/__init__.py -+++ b/base/server/python/pki/server/__init__.py -@@ -304,10 +304,11 @@ class PKIInstance(object): - - return password - -- def open_nssdb(self): -+ def open_nssdb(self, token='internal'): - return pki.nss.NSSDatabase( - directory=self.nssdb_dir, -- password=self.get_password('internal')) -+ token=token, -+ password=self.get_password(token)) - - def get_subsystem(self, name): - for subsystem in self.subsystems: -diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py -index b6ee61b..f349b74 100644 ---- a/base/server/python/pki/server/deployment/pkihelper.py -+++ b/base/server/python/pki/server/deployment/pkihelper.py -@@ -742,8 +742,7 @@ class ConfigurationFile: - # External CA - if not self.external_step_two: - # External CA (Step 1) -- self.confirm_data_exists("pki_external_csr_path") -- self.confirm_missing_file("pki_external_csr_path") -+ # The pki_external_csr_path is optional. - # generic extension support in CSR - for external CA - if self.add_req_ext: - self.confirm_data_exists("pki_req_ext_oid") -@@ -751,10 +750,9 @@ class ConfigurationFile: - self.confirm_data_exists("pki_req_ext_data") - else: - # External CA (Step 2) -- self.confirm_data_exists("pki_external_ca_cert_chain_path") -- self.confirm_file_exists("pki_external_ca_cert_chain_path") -- self.confirm_data_exists("pki_external_ca_cert_path") -- self.confirm_file_exists("pki_external_ca_cert_path") -+ # The pki_external_ca_cert_chain_path and -+ # pki_external_ca_cert_path are optional. -+ pass - elif not self.skip_configuration and self.standalone: - if not self.external_step_two: - # Stand-alone PKI Admin CSR (Step 1) -@@ -3779,17 +3777,7 @@ class ConfigClient: - if not isinstance(certs, types.ListType): - certs = [certs] - for cdata in certs: -- if (self.subsystem == "CA" and self.external and -- not self.external_step_two): -- # External CA (Step 1) -- if cdata['tag'].lower() == "signing": -- # Save 'External CA Signing Certificate' CSR (Step 1) -- self.save_system_csr( -- cdata['request'], -- log.PKI_CONFIG_EXTERNAL_CSR_SAVE, -- self.mdict['pki_external_csr_path']) -- return -- elif self.standalone and not self.external_step_two: -+ if self.standalone and not self.external_step_two: - # Stand-alone PKI (Step 1) - if cdata['tag'].lower() == "audit_signing": - # Save Stand-alone PKI 'Audit Signing Certificate' CSR -@@ -3956,8 +3944,17 @@ class ConfigClient: - data.token = self.mdict['pki_token_name'] - data.tokenPassword = self.mdict['pki_token_password'] - data.subsystemName = self.mdict['pki_subsystem_name'] -+ -+ data.external = self.external - data.standAlone = self.standalone -- data.stepTwo = self.external_step_two -+ -+ if self.standalone: -+ # standalone installation uses two-step process (ticket #1698) -+ data.stepTwo = self.external_step_two -+ -+ else: -+ # other installations use only one step in the configuration servlet -+ data.stepTwo = False - - # Cloning parameters - if self.mdict['pki_instance_type'] == "Tomcat": -@@ -4085,25 +4082,46 @@ class ConfigClient: - self.mdict['pki_req_ext_critical'] - cert1.req_ext_data = \ - self.mdict['pki_req_ext_data'] -- if self.external_step_two: -- # External CA (Step 2) or Stand-alone PKI (Step 2) -- if not self.subsystem == "CA": -- # Stand-alone PKI (Step 2) -- cert1 = pki.system.SystemCertData() -- cert1.tag = self.mdict['pki_ca_signing_tag'] -- # Load the External CA or Stand-alone PKI -+ -+ if self.external and self.external_step_two: # external/existing CA step 2 -+ -+ # If specified, load the externally-signed CA cert -+ if self.mdict['pki_external_ca_cert_path']: -+ self.load_system_cert( -+ cert1, -+ log.PKI_CONFIG_EXTERNAL_CA_LOAD, -+ self.mdict['pki_external_ca_cert_path']) -+ -+ # If specified, load the external CA cert chain -+ if self.mdict['pki_external_ca_cert_chain_path']: -+ self.load_system_cert_chain( -+ cert1, -+ log.PKI_CONFIG_EXTERNAL_CA_CHAIN_LOAD, -+ self.mdict['pki_external_ca_cert_chain_path']) -+ -+ systemCerts.append(cert1) -+ -+ elif self.standalone and self.external_step_two: # standalone KRA/OCSP step 2 -+ -+ cert1 = pki.system.SystemCertData() -+ cert1.tag = self.mdict['pki_ca_signing_tag'] -+ -+ # Load the stand-alone PKI - # 'External CA Signing Certificate' (Step 2) - self.load_system_cert( - cert1, - log.PKI_CONFIG_EXTERNAL_CA_LOAD, - self.mdict['pki_external_ca_cert_path']) -- # Load the External CA or Stand-alone PKI -+ -+ # Load the stand-alone PKI - # 'External CA Signing Certificate Chain' (Step 2) - self.load_system_cert_chain( - cert1, - log.PKI_CONFIG_EXTERNAL_CA_CHAIN_LOAD, - self.mdict['pki_external_ca_cert_chain_path']) -+ - systemCerts.append(cert1) -+ - elif self.subsystem == "CA": - # PKI CA or Subordinate CA - systemCerts.append(cert1) -diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py -index fbcb1cc..6539de8 100644 ---- a/base/server/python/pki/server/deployment/scriptlets/configuration.py -+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py -@@ -20,13 +20,18 @@ - # - - import json -+import re - - # PKI Deployment Imports - from .. import pkiconfig as config - from .. import pkimessages as log - from .. import pkiscriptlet --import pki.system -+ - import pki.encoder -+import pki.nss -+import pki.server -+import pki.system -+import pki.util - - - # PKI Deployment Configuration Scriptlet -@@ -80,6 +85,127 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - deployer.mdict['pki_client_secmod_database'], - password_file=deployer.mdict['pki_client_password_conf']) - -+ instance = pki.server.PKIInstance(deployer.mdict['pki_instance_name']) -+ instance.load() -+ -+ subsystem = instance.get_subsystem(deployer.mdict['pki_subsystem'].lower()) -+ -+ token = deployer.mdict['pki_token_name'] -+ nssdb = instance.open_nssdb(token) -+ -+ external = config.str2bool(deployer.mdict['pki_external']) -+ step_one = not config.str2bool(deployer.mdict['pki_external_step_two']) -+ step_two = not step_one -+ -+ try: -+ if external and step_one: # external/existing CA step 1 -+ -+ key_type = deployer.mdict['pki_ca_signing_key_type'] -+ key_alg = deployer.mdict['pki_ca_signing_key_algorithm'] -+ -+ if key_type == 'rsa': -+ key_size = int(deployer.mdict['pki_ca_signing_key_size']) -+ curve = None -+ -+ m = re.match(r'(.*)withRSA', key_alg) -+ if not m: -+ raise Exception('Invalid key algorithm: %s' % key_alg) -+ hash_alg = m.group(1) -+ -+ elif key_type == 'ec' or key_type == 'ecc': -+ key_type = 'ec' -+ key_size = None -+ curve = deployer.mdict['pki_ca_signing_key_size'] -+ -+ m = re.match(r'(.*)withEC', key_alg) -+ if not m: -+ raise Exception('Invalid key algorithm: %s' % key_alg) -+ hash_alg = m.group(1) -+ -+ else: -+ raise Exception('Invalid key type: %s' % key_type) -+ -+ # If filename specified, generate CA cert request and -+ # import it into CS.cfg. -+ request_file = deployer.mdict['pki_external_csr_path'] -+ if request_file: -+ nssdb.create_request( -+ subject_dn=deployer.mdict['pki_ca_signing_subject_dn'], -+ request_file=request_file, -+ key_type=key_type, -+ key_size=key_size, -+ curve=curve, -+ hash_alg=hash_alg) -+ with open(request_file) as f: -+ signing_csr = f.read() -+ signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64') -+ subsystem.config['ca.signing.certreq'] = signing_csr -+ -+ subsystem.save() -+ -+ elif external and step_two: # external/existing CA step 2 -+ -+ # If specified, import existing CA cert request into CS.cfg. -+ request_file = deployer.mdict['pki_external_csr_path'] -+ if request_file: -+ with open(request_file) as f: -+ signing_csr = f.read() -+ signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64') -+ subsystem.config['ca.signing.certreq'] = signing_csr -+ -+ # If specified, import external CA cert into NSS database. -+ external_ca_cert_chain_nickname = deployer.mdict['pki_external_ca_cert_chain_nickname'] -+ external_ca_cert_chain_file = deployer.mdict['pki_external_ca_cert_chain_path'] -+ if external_ca_cert_chain_file: -+ cert_chain = nssdb.import_cert_chain( -+ nickname=external_ca_cert_chain_nickname, -+ cert_chain_file=external_ca_cert_chain_file, -+ trust_attributes='CT,C,C') -+ subsystem.config['ca.external_ca_chain.cert'] = cert_chain -+ -+ # If specified, import externally-signed CA cert into NSS database. -+ signing_nickname = deployer.mdict['pki_ca_signing_nickname'] -+ signing_cert_file = deployer.mdict['pki_external_ca_cert_path'] -+ if signing_cert_file: -+ nssdb.add_cert( -+ nickname=signing_nickname, -+ cert_file=signing_cert_file, -+ trust_attributes='CT,C,C') -+ -+ # If specified, import CA cert and key from PKCS #12 file into NSS database. -+ pkcs12_file = deployer.mdict['pki_external_pkcs12_path'] -+ if pkcs12_file: -+ pkcs12_password = deployer.mdict['pki_external_pkcs12_password'] -+ nssdb.import_pkcs12(pkcs12_file, pkcs12_password) -+ -+ # Export CA cert from NSS database and import it into CS.cfg. -+ signing_cert_data = nssdb.get_cert( -+ nickname=signing_nickname, -+ output_format='base64') -+ subsystem.config['ca.signing.nickname'] = signing_nickname -+ subsystem.config['ca.signing.tokenname'] = deployer.mdict['pki_ca_signing_token'] -+ subsystem.config['ca.signing.cert'] = signing_cert_data -+ subsystem.config['ca.signing.cacertnickname'] = signing_nickname -+ subsystem.config['ca.signing.defaultSigningAlgorithm'] = deployer.mdict['pki_ca_signing_signing_algorithm'] -+ -+ subsystem.save() -+ -+ else: # self-signed CA -+ -+ # To be implemented in ticket #1692. -+ -+ # Generate CA cert request. -+ # Self sign CA cert. -+ # Import self-signed CA cert into NSS database. -+ -+ pass -+ -+ finally: -+ nssdb.close() -+ -+ if external and step_one: -+ return self.rv -+ - # Start/Restart this Tomcat PKI Process - # Optionally prepare to enable a java debugger - # (e. g. - 'eclipse'): -diff --git a/base/server/python/pki/server/deployment/scriptlets/finalization.py b/base/server/python/pki/server/deployment/scriptlets/finalization.py -index b929659..4c98cc4 100644 ---- a/base/server/python/pki/server/deployment/scriptlets/finalization.py -+++ b/base/server/python/pki/server/deployment/scriptlets/finalization.py -@@ -65,9 +65,15 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - if len(deployer.instance.tomcat_instance_subsystems()) == 1: - # Modify contents of 'serverCertNick.conf' (if necessary) - deployer.servercertnick_conf.modify() -- # Optionally, programmatically 'restart' the configured PKI instance -- if config.str2bool(deployer.mdict['pki_restart_configured_instance']): -- deployer.systemd.restart() -+ -+ external = config.str2bool(deployer.mdict['pki_external']) -+ step_one = not config.str2bool(deployer.mdict['pki_external_step_two']) -+ -+ if not (external and step_one): -+ # Optionally, programmatically 'restart' the configured PKI instance -+ if config.str2bool(deployer.mdict['pki_restart_configured_instance']): -+ deployer.systemd.restart() -+ - # Optionally, 'purge' the entire temporary client infrastructure - # including the client NSS security databases and password files - # --- -2.5.0 - - -From 69701a70df86f933a25847e74247c509287ca4fd Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Tue, 17 Nov 2015 05:08:51 +0100 -Subject: [PATCH 4/9] Updated pki-cert and pki-server-subsystem man pages. - -The pki-cert and pki-server-subsystem man pages have been updated -to include recent changes. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit 3294f5087997427d060bce85d033652f7a8431da) ---- - base/java-tools/man/man1/pki-cert.1 | 23 ++++++++++++++++------- - base/server/man/man8/pki-server-subsystem.8 | 26 +++++++++++++++++++++++++- - 2 files changed, 41 insertions(+), 8 deletions(-) - -diff --git a/base/java-tools/man/man1/pki-cert.1 b/base/java-tools/man/man1/pki-cert.1 -index ffa1fea..7ece1ad 100644 ---- a/base/java-tools/man/man1/pki-cert.1 -+++ b/base/java-tools/man/man1/pki-cert.1 -@@ -191,23 +191,32 @@ To release a certificate that has been placed on hold: - .B pki ca-cert-release-hold - - .SS Certificate Requests --To request a certificate, first generate a certificate request in PKCS #10 or CRMF, and store this request in the XML template file, of the profile type the request relates to. - --The list of profiles can be viewed using the CLI command: -+To request a certificate, first generate a certificate signing request (CSR), -+then submit it with a certificate profile. The list of available profiles can -+be viewed using the following command: - - .B pki ca-cert-request-profile-find - --The XML template file for a profile type can be created by calling the ca-cert-request-profile-show CLI command. For example: -+To generate a CSR, use the certutil, PKCS10Client, or -+CRMFPopClient, and store it into a file. - --\fBpki ca-cert-request-profile-show \-\-output \fP -+Basic requests can be submitted using the following command: - --will store the XML template of the request in the specified output file. -+.B pki ca-cert-request-submit --profile --request-type --csr-file --subject - --Then, fill in the values in the XML file and submit the request for review. This can be done without authentication. -+To submit more advanced requests, download a template of the request file for -+a particular profile using the following command: -+ -+.B pki ca-cert-request-profile-show \-\-output -+ -+Then, edit the request file, fill in the input attributes required by the -+profile, and submit the request using the following command: - - .B pki ca-cert-request-submit - --Then, an agent needs to review the request by running the following command: -+Depending on the profile, an agent may need to review the request by running -+the following command: - - .B pki ca-cert-request-review --file - -diff --git a/base/server/man/man8/pki-server-subsystem.8 b/base/server/man/man8/pki-server-subsystem.8 -index 04d57f5..719982c 100644 ---- a/base/server/man/man8/pki-server-subsystem.8 -+++ b/base/server/man/man8/pki-server-subsystem.8 -@@ -24,6 +24,10 @@ pki-server subsystem \- Command-Line Interface for managing Certificate System s - \fBpki-server [CLI options] subsystem-show\fR -i - \fBpki-server [CLI options] subsystem-enable\fR -i - \fBpki-server [CLI options] subsystem-disable\fR -i -+\fBpki-server [CLI options] subsystem-cert-find\fR -i -+\fBpki-server [CLI options] subsystem-cert-show\fR -i -+\fBpki-server [CLI options] subsystem-cert-export\fR -i -+\fBpki-server [CLI options] subsystem-cert-update\fR -i - .fi - - .SH DESCRIPTION -@@ -53,7 +57,7 @@ This command is to list subsystems within a specific instance. - .PP - \fBpki-server [CLI options] subsystem-show\fR -i - .RS 4 --This command is to view a details about a particular subsystem. -+This command is to view the details about a particular subsystem. - .RE - .PP - \fBpki-server [CLI options] subsystem-enable\fR -i -@@ -78,6 +82,26 @@ through the web interfaces. This is useful when specific subsystems need to be - made inaccessible for maintenance as Apache Tomcat allows web applications to be - deployed/undeployed while the instance is still running (hot deployment). - .RE -+.PP -+\fBpki-server [CLI options] subsystem-cert-find\fR -i -+.RS 4 -+This command is to list system certificates in a particular subsystem. -+.RE -+.PP -+\fBpki-server [CLI options] subsystem-cert-show\fR -i -+.RS 4 -+This command is to view the details about a system certificate in a particular subsystem. -+.RE -+.PP -+\fBpki-server [CLI options] subsystem-cert-export\fR -i -+.RS 4 -+This command is to export a system certificate in a particular subsystem. -+.RE -+.PP -+\fBpki-server [CLI options] subsystem-cert-update\fR -i -+.RS 4 -+This command is to update a system certificate in a particular subsystem. -+.RE - - .SH OPTIONS - The CLI options are described in \fBpki-server\fR(8). --- -2.5.0 - - -From 59b6e69eb36e83fd10308ba0adf23a439915803c Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Sat, 12 Dec 2015 04:10:54 +0100 -Subject: [PATCH 5/9] Fixed external CA case for IPA compatibility. - -The installation code for external CA case has been fixed such -that IPA can detect step 1 completion properly. - -The code that handles certificate data conversion has been fixed -to reformat base-64 data for PEM output properly. - -The installation summary for step 1 has been updated to provide -more accurate information. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit 449e4357e733a70e8f27f65f69ca8f0f7c8b5b21) ---- - base/common/python/pki/nss.py | 8 ++++++-- - .../python/pki/server/deployment/pkihelper.py | 7 +++++-- - .../server/deployment/scriptlets/configuration.py | 10 +++++++--- - base/server/sbin/pkispawn | 23 +++++++++++++++++++++- - 4 files changed, 40 insertions(+), 8 deletions(-) - -diff --git a/base/common/python/pki/nss.py b/base/common/python/pki/nss.py -index 196fe46..67fd90b 100644 ---- a/base/common/python/pki/nss.py -+++ b/base/common/python/pki/nss.py -@@ -43,9 +43,13 @@ def convert_data(data, input_format, output_format, header=None, footer=None): - - if input_format == 'base64' and output_format == 'pem': - -- # split a single line into multiple lines -- data = data.rstrip('\r\n') -+ # join base-64 data into a single line -+ data = data.replace('\r', '').replace('\n', '') -+ -+ # re-split the line into fixed-length lines - lines = [data[i:i+64] for i in range(0, len(data), 64)] -+ -+ # add header and footer - return '%s\n%s\n%s\n' % (header, '\n'.join(lines), footer) - - if input_format == 'pem' and output_format == 'base64': -diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py -index f349b74..e859139 100644 ---- a/base/server/python/pki/server/deployment/pkihelper.py -+++ b/base/server/python/pki/server/deployment/pkihelper.py -@@ -488,15 +488,18 @@ class ConfigurationFile: - # generic extension support in CSR - for external CA - self.add_req_ext = config.str2bool( - self.mdict['pki_req_ext_add']) -+ - self.external = config.str2bool(self.mdict['pki_external']) -+ self.external_step_one = not config.str2bool(self.mdict['pki_external_step_two']) -+ self.external_step_two = not self.external_step_one -+ - if self.external: - # generic extension support in CSR - for external CA - if self.add_req_ext: - self.req_ext_oid = self.mdict['pki_req_ext_oid'] - self.req_ext_critical = self.mdict['pki_req_ext_critical'] - self.req_ext_data = self.mdict['pki_req_ext_data'] -- self.external_step_two = config.str2bool( -- self.mdict['pki_external_step_two']) -+ - self.skip_configuration = config.str2bool( - self.mdict['pki_skip_configuration']) - self.standalone = config.str2bool(self.mdict['pki_standalone']) -diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py -index 6539de8..ba8cff6 100644 ---- a/base/server/python/pki/server/deployment/scriptlets/configuration.py -+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py -@@ -93,9 +93,9 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - token = deployer.mdict['pki_token_name'] - nssdb = instance.open_nssdb(token) - -- external = config.str2bool(deployer.mdict['pki_external']) -- step_one = not config.str2bool(deployer.mdict['pki_external_step_two']) -- step_two = not step_one -+ external = deployer.configuration_file.external -+ step_one = deployer.configuration_file.external_step_one -+ step_two = deployer.configuration_file.external_step_two - - try: - if external and step_one: # external/existing CA step 1 -@@ -141,6 +141,10 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64') - subsystem.config['ca.signing.certreq'] = signing_csr - -+ # This is needed by IPA to detect step 1 completion. -+ # See is_step_one_done() in ipaserver/install/cainstance.py. -+ subsystem.config['preop.ca.type'] = 'otherca' -+ - subsystem.save() - - elif external and step_two: # external/existing CA step 2 -diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn -index fb5a61a..3b09e0f 100755 ---- a/base/server/sbin/pkispawn -+++ b/base/server/sbin/pkispawn -@@ -611,7 +611,13 @@ def main(argv): - config.pki_log.debug(pkilogging.log_format(parser.mdict), - extra=config.PKI_INDENTATION_LEVEL_0) - -- print_install_information(parser.mdict) -+ external = deployer.configuration_file.external -+ step_one = deployer.configuration_file.external_step_one -+ -+ if external and step_one: -+ print_step_one_information(parser.mdict) -+ else: -+ print_install_information(parser.mdict) - - - def set_port(parser, tag, prompt, existing_data): -@@ -621,6 +627,21 @@ def set_port(parser, tag, prompt, existing_data): - parser.read_text(prompt, config.pki_subsystem, tag) - - -+def print_step_one_information(mdict): -+ -+ print(log.PKI_SPAWN_INFORMATION_HEADER) -+ print(" The %s subsystem of the '%s' instance is still incomplete." % -+ (config.pki_subsystem, mdict['pki_instance_name'])) -+ print() -+ print(" A CSR for the CA certificate has been generated at:\n" -+ " %s" -+ % mdict['pki_external_csr_path']) -+ print() -+ print(" Submit the CSR to an external CA to generate a CA certificate\n" -+ " for this subsystem.") -+ print(log.PKI_SPAWN_INFORMATION_FOOTER) -+ -+ - def print_install_information(mdict): - - skip_configuration = config.str2bool(mdict['pki_skip_configuration']) --- -2.5.0 - - -From ad48aafdaea1a3aeec62c76e767e6e3820b68b98 Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Fri, 22 Jan 2016 00:03:39 +0100 -Subject: [PATCH 7/9] Fixed installation summary for existing CA. - -The pkispawn has been modified to display the proper summary for -external CA and existing CA cases. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit 66a4b7e635a4456a102221049c58c461d3429093) ---- - .../python/pki/server/deployment/pkihelper.py | 1 + - .../server/deployment/scriptlets/configuration.py | 13 ++++++------- - base/server/sbin/pkispawn | 22 +++++++++++++++++++--- - 3 files changed, 26 insertions(+), 10 deletions(-) - -diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py -index e859139..07a5ce4 100644 ---- a/base/server/python/pki/server/deployment/pkihelper.py -+++ b/base/server/python/pki/server/deployment/pkihelper.py -@@ -492,6 +492,7 @@ class ConfigurationFile: - self.external = config.str2bool(self.mdict['pki_external']) - self.external_step_one = not config.str2bool(self.mdict['pki_external_step_two']) - self.external_step_two = not self.external_step_one -+ self.external_csr_path = self.mdict['pki_external_csr_path'] - - if self.external: - # generic extension support in CSR - for external CA -diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py -index ba8cff6..16c6ae5 100644 ---- a/base/server/python/pki/server/deployment/scriptlets/configuration.py -+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py -@@ -96,6 +96,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - external = deployer.configuration_file.external - step_one = deployer.configuration_file.external_step_one - step_two = deployer.configuration_file.external_step_two -+ external_csr_path = deployer.configuration_file.external_csr_path - - try: - if external and step_one: # external/existing CA step 1 -@@ -127,16 +128,15 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - - # If filename specified, generate CA cert request and - # import it into CS.cfg. -- request_file = deployer.mdict['pki_external_csr_path'] -- if request_file: -+ if external_csr_path: - nssdb.create_request( - subject_dn=deployer.mdict['pki_ca_signing_subject_dn'], -- request_file=request_file, -+ request_file=external_csr_path, - key_type=key_type, - key_size=key_size, - curve=curve, - hash_alg=hash_alg) -- with open(request_file) as f: -+ with open(external_csr_path) as f: - signing_csr = f.read() - signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64') - subsystem.config['ca.signing.certreq'] = signing_csr -@@ -150,9 +150,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - elif external and step_two: # external/existing CA step 2 - - # If specified, import existing CA cert request into CS.cfg. -- request_file = deployer.mdict['pki_external_csr_path'] -- if request_file: -- with open(request_file) as f: -+ if external_csr_path: -+ with open(external_csr_path) as f: - signing_csr = f.read() - signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64') - subsystem.config['ca.signing.certreq'] = signing_csr -diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn -index 3b09e0f..967d5f5 100755 ---- a/base/server/sbin/pkispawn -+++ b/base/server/sbin/pkispawn -@@ -613,9 +613,13 @@ def main(argv): - - external = deployer.configuration_file.external - step_one = deployer.configuration_file.external_step_one -+ external_csr_path = deployer.configuration_file.external_csr_path - - if external and step_one: -- print_step_one_information(parser.mdict) -+ if external_csr_path: -+ print_external_ca_step_one_information(parser.mdict) -+ else: -+ print_existing_ca_step_one_information(parser.mdict) - else: - print_install_information(parser.mdict) - -@@ -627,7 +631,7 @@ def set_port(parser, tag, prompt, existing_data): - parser.read_text(prompt, config.pki_subsystem, tag) - - --def print_step_one_information(mdict): -+def print_external_ca_step_one_information(mdict): - - print(log.PKI_SPAWN_INFORMATION_HEADER) - print(" The %s subsystem of the '%s' instance is still incomplete." % -@@ -638,7 +642,19 @@ def print_step_one_information(mdict): - % mdict['pki_external_csr_path']) - print() - print(" Submit the CSR to an external CA to generate a CA certificate\n" -- " for this subsystem.") -+ " for this subsystem. Import the CA certificate and the certificate\n" -+ " chain, then continue the installation.") -+ print(log.PKI_SPAWN_INFORMATION_FOOTER) -+ -+ -+def print_existing_ca_step_one_information(mdict): -+ -+ print(log.PKI_SPAWN_INFORMATION_HEADER) -+ print(" The %s subsystem of the '%s' instance is still incomplete." % -+ (config.pki_subsystem, mdict['pki_instance_name'])) -+ print() -+ print(" Import an existing CA certificate with the key and the CSR, and\n" -+ " the certificate chain if available, then continue the installation.") - print(log.PKI_SPAWN_INFORMATION_FOOTER) - - --- -2.5.0 - - -From 8ace5536715238ac91ac77d5c84873ee3caaec4f Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Fri, 22 Jan 2016 17:34:19 +0100 -Subject: [PATCH 8/9] Renamed pki.nss into pki.nssdb. - -The pki.nss module has been renamed into pki.nssdb to prevent -conflicts with the nss module. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit 9609f4e6035d3cdff19a0f78caee2d08b095c8ba) ---- - base/common/python/pki/nss.py | 533 --------------------- - base/common/python/pki/nssdb.py | 533 +++++++++++++++++++++ - base/server/python/pki/server/__init__.py | 4 +- - base/server/python/pki/server/cli/subsystem.py | 6 +- - .../server/deployment/scriptlets/configuration.py | 6 +- - 5 files changed, 541 insertions(+), 541 deletions(-) - delete mode 100644 base/common/python/pki/nss.py - create mode 100644 base/common/python/pki/nssdb.py - -diff --git a/base/common/python/pki/nss.py b/base/common/python/pki/nss.py -deleted file mode 100644 -index 67fd90b..0000000 ---- a/base/common/python/pki/nss.py -+++ /dev/null -@@ -1,533 +0,0 @@ --#!/usr/bin/python --# Authors: --# Endi S. Dewata --# --# This program is free software; you can redistribute it and/or modify --# it under the terms of the GNU General Public License as published by --# the Free Software Foundation; version 2 of the License. --# --# This program is distributed in the hope that it will be useful, --# but WITHOUT ANY WARRANTY; without even the implied warranty of --# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --# GNU General Public License for more details. --# --# You should have received a copy of the GNU General Public License along --# with this program; if not, write to the Free Software Foundation, Inc., --# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --# --# Copyright (C) 2015 Red Hat, Inc. --# All rights reserved. --# -- --import base64 --import os --import shutil --import subprocess --import tempfile -- -- --CSR_HEADER = '-----BEGIN NEW CERTIFICATE REQUEST-----' --CSR_FOOTER = '-----END NEW CERTIFICATE REQUEST-----' -- --CERT_HEADER = '-----BEGIN CERTIFICATE-----' --CERT_FOOTER = '-----END CERTIFICATE-----' -- --PKCS7_HEADER = '-----BEGIN PKCS7-----' --PKCS7_FOOTER = '-----END PKCS7-----' -- -- --def convert_data(data, input_format, output_format, header=None, footer=None): -- -- if input_format == output_format: -- return data -- -- if input_format == 'base64' and output_format == 'pem': -- -- # join base-64 data into a single line -- data = data.replace('\r', '').replace('\n', '') -- -- # re-split the line into fixed-length lines -- lines = [data[i:i+64] for i in range(0, len(data), 64)] -- -- # add header and footer -- return '%s\n%s\n%s\n' % (header, '\n'.join(lines), footer) -- -- if input_format == 'pem' and output_format == 'base64': -- -- # join multiple lines into a single line -- lines = [] -- for line in data.splitlines(): -- line = line.rstrip('\r\n') -- if line == header: -- continue -- if line == footer: -- continue -- lines.append(line) -- -- return ''.join(lines) -- -- raise Exception('Unable to convert data from %s to %s' % (input_format, output_format)) -- --def convert_csr(csr_data, input_format, output_format): -- -- return convert_data(csr_data, input_format, output_format, CSR_HEADER, CSR_FOOTER) -- --def convert_cert(cert_data, input_format, output_format): -- -- return convert_data(cert_data, input_format, output_format, CERT_HEADER, CERT_FOOTER) -- --def convert_pkcs7(pkcs7_data, input_format, output_format): -- -- return convert_data(pkcs7_data, input_format, output_format, PKCS7_HEADER, PKCS7_FOOTER) -- --def get_file_type(filename): -- -- with open(filename, 'r') as f: -- data = f.read() -- -- if data.startswith(CSR_HEADER): -- return 'csr' -- -- if data.startswith(CERT_HEADER): -- return 'cert' -- -- if data.startswith(PKCS7_HEADER): -- return 'pkcs7' -- -- return None -- -- --class NSSDatabase(object): -- -- def __init__(self, directory, token='internal', password=None, password_file=None): -- self.directory = directory -- self.token = token -- -- self.tmpdir = tempfile.mkdtemp() -- -- if password: -- self.password_file = os.path.join(self.tmpdir, 'password.txt') -- with open(self.password_file, 'w') as f: -- f.write(password) -- -- elif password_file: -- self.password_file = password_file -- -- else: -- raise Exception('Missing NSS database password') -- -- def close(self): -- shutil.rmtree(self.tmpdir) -- -- def add_cert(self, -- nickname, -- cert_file, -- trust_attributes=',,'): -- -- cmd = [ -- 'certutil', -- '-A', -- '-d', self.directory, -- '-h', self.token, -- '-f', self.password_file, -- '-n', nickname, -- '-i', cert_file, -- '-t', trust_attributes -- ] -- -- subprocess.check_call(cmd) -- -- def modify_cert(self, -- nickname, -- trust_attributes): -- -- cmd = [ -- 'certutil', -- '-M', -- '-d', self.directory, -- '-h', self.token, -- '-f', self.password_file, -- '-n', nickname, -- '-t', trust_attributes -- ] -- -- subprocess.check_call(cmd) -- -- def create_noise(self, noise_file, size=2048): -- -- subprocess.check_call([ -- 'openssl', -- 'rand', -- '-out', noise_file, -- str(size) -- ]) -- -- def create_request(self, -- subject_dn, -- request_file, -- noise_file=None, -- key_type=None, -- key_size=None, -- curve=None, -- hash_alg=None): -- -- tmpdir = tempfile.mkdtemp() -- -- try: -- if not noise_file: -- noise_file = os.path.join(tmpdir, 'noise.bin') -- if key_size: -- size = key_size -- else: -- size = 2048 -- self.create_noise( -- noise_file=noise_file, -- size=size) -- -- binary_request_file = os.path.join(tmpdir, 'request.bin') -- -- cmd = [ -- 'certutil', -- '-R', -- '-d', self.directory, -- '-h', self.token, -- '-f', self.password_file, -- '-s', subject_dn, -- '-o', binary_request_file, -- '-z', noise_file -- ] -- -- if key_type: -- cmd.extend(['-k', key_type]) -- -- if key_size: -- cmd.extend(['-g', str(key_size)]) -- -- if curve: -- cmd.extend(['-q', curve]) -- -- if hash_alg: -- cmd.extend(['-Z', hash_alg]) -- -- # generate binary request -- subprocess.check_call(cmd) -- -- # encode binary request in base-64 -- b64_request_file = os.path.join(tmpdir, 'request.b64') -- subprocess.check_call([ -- 'BtoA', binary_request_file, b64_request_file]) -- -- # read base-64 request -- with open(b64_request_file, 'r') as f: -- b64_request = f.read() -- -- # add header and footer -- with open(request_file, 'w') as f: -- f.write('-----BEGIN NEW CERTIFICATE REQUEST-----\n') -- f.write(b64_request) -- f.write('-----END NEW CERTIFICATE REQUEST-----\n') -- -- finally: -- shutil.rmtree(tmpdir) -- -- def create_self_signed_ca_cert(self, -- subject_dn, -- request_file, -- cert_file, -- serial='1', -- validity=240): -- -- cmd = [ -- 'certutil', -- '-C', -- '-x', -- '-d', self.directory, -- '-h', self.token, -- '-f', self.password_file, -- '-c', subject_dn, -- '-a', -- '-i', request_file, -- '-o', cert_file, -- '-m', serial, -- '-v', str(validity), -- '--keyUsage', 'digitalSignature,nonRepudiation,certSigning,crlSigning,critical', -- '-2', -- '-3', -- '--extSKID', -- '--extAIA' -- ] -- -- p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -- -- keystroke = '' -- -- # Is this a CA certificate [y/N]? -- keystroke += 'y\n' -- -- # Enter the path length constraint, enter to skip [<0 for unlimited path]: -- keystroke += '\n' -- -- # Is this a critical extension [y/N]? -- keystroke += 'y\n' -- -- # Enter value for the authKeyID extension [y/N]? -- keystroke += 'y\n' -- -- # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId()) -- # Enter value for the key identifier fields,enter to omit: -- keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n' -- -- # Select one of the following general name type: -- keystroke += '0\n' -- -- # Enter value for the authCertSerial field, enter to omit: -- keystroke += '\n' -- -- # Is this a critical extension [y/N]? -- keystroke += '\n' -- -- # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId()) -- # Adding Subject Key ID extension. -- # Enter value for the key identifier fields,enter to omit: -- keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n' -- -- # Is this a critical extension [y/N]? -- keystroke += '\n' -- -- # Enter access method type for Authority Information Access extension: -- keystroke += '2\n' -- -- # Select one of the following general name type: -- keystroke += '7\n' -- -- # TODO: replace with actual hostname name and port number -- # Enter data: -- keystroke += 'http://server.example.com:8080/ca/ocsp\n' -- -- # Select one of the following general name type: -- keystroke += '0\n' -- -- # Add another location to the Authority Information Access extension [y/N] -- keystroke += '\n' -- -- # Is this a critical extension [y/N]? -- keystroke += '\n' -- -- p.communicate(keystroke) -- -- rc = p.wait() -- -- if rc: -- raise Exception('Failed to generate self-signed CA certificate. RC: %d' % rc) -- -- def get_cert(self, nickname, output_format='pem'): -- -- if output_format == 'pem': -- output_format_option = '-a' -- -- elif output_format == 'base64': -- output_format_option = '-r' -- -- else: -- raise Exception('Unsupported output format: %s' % output_format) -- -- cmd = [ -- 'certutil', -- '-L', -- '-d', self.directory, -- '-h', self.token, -- '-f', self.password_file, -- '-n', nickname, -- output_format_option -- ] -- -- cert_data = subprocess.check_output(cmd) -- -- if output_format == 'base64': -- cert_data = base64.b64encode(cert_data) -- -- return cert_data -- -- def remove_cert(self, nickname): -- -- cmd = [ -- 'certutil', -- '-D', -- '-d', self.directory, -- '-h', self.token, -- '-f', self.password_file, -- '-n', nickname -- ] -- -- subprocess.check_call(cmd) -- -- def import_cert_chain(self, nickname, cert_chain_file, trust_attributes=None): -- -- tmpdir = tempfile.mkdtemp() -- -- try: -- file_type = get_file_type(cert_chain_file) -- -- if file_type == 'cert': # import single PEM cert -- self.add_cert( -- nickname=nickname, -- cert_file=cert_chain_file, -- trust_attributes=trust_attributes) -- return self.get_cert( -- nickname=nickname, -- output_format='base64') -- -- elif file_type == 'pkcs7': # import PKCS #7 cert chain -- return self.import_pkcs7( -- pkcs7_file=cert_chain_file, -- nickname=nickname, -- trust_attributes=trust_attributes, -- output_format='base64') -- -- else: # import PKCS #7 data without header/footer -- with open(cert_chain_file, 'r') as f: -- base64_data = f.read() -- pkcs7_data = convert_pkcs7(base64_data, 'base64', 'pem') -- -- tmp_cert_chain_file = os.path.join(tmpdir, 'cert_chain.p7b') -- with open(tmp_cert_chain_file, 'w') as f: -- f.write(pkcs7_data) -- -- self.import_pkcs7( -- pkcs7_file=tmp_cert_chain_file, -- nickname=nickname, -- trust_attributes=trust_attributes) -- -- return base64_data -- -- finally: -- shutil.rmtree(tmpdir) -- -- def import_pkcs7(self, pkcs7_file, nickname, trust_attributes=None, output_format='pem'): -- -- tmpdir = tempfile.mkdtemp() -- -- try: -- # export certs from PKCS #7 into PEM output -- output = subprocess.check_output([ -- 'openssl', -- 'pkcs7', -- '-print_certs', -- '-in', pkcs7_file -- ]) -- -- # parse PEM output into separate PEM certificates -- certs = [] -- lines = [] -- state = 'header' -- -- for line in output.splitlines(): -- -- if state == 'header': -- if line != CERT_HEADER: -- # ignore header lines -- pass -- else: -- # save cert header -- lines.append(line) -- state = 'body' -- -- elif state == 'body': -- if line != CERT_FOOTER: -- # save cert body -- lines.append(line) -- else: -- # save cert footer -- lines.append(line) -- -- # construct PEM cert -- cert = '\n'.join(lines) -- certs.append(cert) -- lines = [] -- state = 'header' -- -- # import PEM certs into NSS database -- counter = 1 -- for cert in certs: -- -- cert_file = os.path.join(tmpdir, 'cert%d.pem' % counter) -- with open(cert_file, 'w') as f: -- f.write(cert) -- -- if counter == 1: -- n = nickname -- else: -- n = '%s #%d' % (nickname, counter) -- -- self.add_cert(n, cert_file, trust_attributes) -- -- counter += 1 -- -- # convert PKCS #7 data to the requested format -- with open(pkcs7_file, 'r') as f: -- data = f.read() -- -- return convert_pkcs7(data, 'pem', output_format) -- -- finally: -- shutil.rmtree(tmpdir) -- -- def import_pkcs12(self, pkcs12_file, pkcs12_password=None, pkcs12_password_file=None): -- -- tmpdir = tempfile.mkdtemp() -- -- try: -- if pkcs12_password: -- password_file = os.path.join(tmpdir, 'password.txt') -- with open(password_file, 'w') as f: -- f.write(pkcs12_password) -- -- elif pkcs12_password_file: -- password_file = pkcs12_password_file -- -- else: -- raise Exception('Missing PKCS #12 password') -- -- cmd = [ -- 'pk12util', -- '-d', self.directory, -- '-h', self.token, -- '-k', self.password_file, -- '-i', pkcs12_file, -- '-w', password_file -- ] -- -- subprocess.check_call(cmd) -- -- finally: -- shutil.rmtree(tmpdir) -- -- def export_pkcs12(self, pkcs12_file, nickname, pkcs12_password=None, pkcs12_password_file=None): -- -- tmpdir = tempfile.mkdtemp() -- -- try: -- if pkcs12_password: -- password_file = os.path.join(tmpdir, 'password.txt') -- with open(password_file, 'w') as f: -- f.write(pkcs12_password) -- -- elif pkcs12_password_file: -- password_file = pkcs12_password_file -- -- else: -- raise Exception('Missing PKCS #12 password') -- -- cmd = [ -- 'pk12util', -- '-d', self.directory, -- '-k', self.password_file, -- '-o', pkcs12_file, -- '-w', password_file, -- '-n', nickname -- ] -- -- subprocess.check_call(cmd) -- -- finally: -- shutil.rmtree(tmpdir) -diff --git a/base/common/python/pki/nssdb.py b/base/common/python/pki/nssdb.py -new file mode 100644 -index 0000000..67fd90b ---- /dev/null -+++ b/base/common/python/pki/nssdb.py -@@ -0,0 +1,533 @@ -+#!/usr/bin/python -+# Authors: -+# Endi S. Dewata -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; version 2 of the License. -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License along -+# with this program; if not, write to the Free Software Foundation, Inc., -+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+# -+# Copyright (C) 2015 Red Hat, Inc. -+# All rights reserved. -+# -+ -+import base64 -+import os -+import shutil -+import subprocess -+import tempfile -+ -+ -+CSR_HEADER = '-----BEGIN NEW CERTIFICATE REQUEST-----' -+CSR_FOOTER = '-----END NEW CERTIFICATE REQUEST-----' -+ -+CERT_HEADER = '-----BEGIN CERTIFICATE-----' -+CERT_FOOTER = '-----END CERTIFICATE-----' -+ -+PKCS7_HEADER = '-----BEGIN PKCS7-----' -+PKCS7_FOOTER = '-----END PKCS7-----' -+ -+ -+def convert_data(data, input_format, output_format, header=None, footer=None): -+ -+ if input_format == output_format: -+ return data -+ -+ if input_format == 'base64' and output_format == 'pem': -+ -+ # join base-64 data into a single line -+ data = data.replace('\r', '').replace('\n', '') -+ -+ # re-split the line into fixed-length lines -+ lines = [data[i:i+64] for i in range(0, len(data), 64)] -+ -+ # add header and footer -+ return '%s\n%s\n%s\n' % (header, '\n'.join(lines), footer) -+ -+ if input_format == 'pem' and output_format == 'base64': -+ -+ # join multiple lines into a single line -+ lines = [] -+ for line in data.splitlines(): -+ line = line.rstrip('\r\n') -+ if line == header: -+ continue -+ if line == footer: -+ continue -+ lines.append(line) -+ -+ return ''.join(lines) -+ -+ raise Exception('Unable to convert data from %s to %s' % (input_format, output_format)) -+ -+def convert_csr(csr_data, input_format, output_format): -+ -+ return convert_data(csr_data, input_format, output_format, CSR_HEADER, CSR_FOOTER) -+ -+def convert_cert(cert_data, input_format, output_format): -+ -+ return convert_data(cert_data, input_format, output_format, CERT_HEADER, CERT_FOOTER) -+ -+def convert_pkcs7(pkcs7_data, input_format, output_format): -+ -+ return convert_data(pkcs7_data, input_format, output_format, PKCS7_HEADER, PKCS7_FOOTER) -+ -+def get_file_type(filename): -+ -+ with open(filename, 'r') as f: -+ data = f.read() -+ -+ if data.startswith(CSR_HEADER): -+ return 'csr' -+ -+ if data.startswith(CERT_HEADER): -+ return 'cert' -+ -+ if data.startswith(PKCS7_HEADER): -+ return 'pkcs7' -+ -+ return None -+ -+ -+class NSSDatabase(object): -+ -+ def __init__(self, directory, token='internal', password=None, password_file=None): -+ self.directory = directory -+ self.token = token -+ -+ self.tmpdir = tempfile.mkdtemp() -+ -+ if password: -+ self.password_file = os.path.join(self.tmpdir, 'password.txt') -+ with open(self.password_file, 'w') as f: -+ f.write(password) -+ -+ elif password_file: -+ self.password_file = password_file -+ -+ else: -+ raise Exception('Missing NSS database password') -+ -+ def close(self): -+ shutil.rmtree(self.tmpdir) -+ -+ def add_cert(self, -+ nickname, -+ cert_file, -+ trust_attributes=',,'): -+ -+ cmd = [ -+ 'certutil', -+ '-A', -+ '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, -+ '-n', nickname, -+ '-i', cert_file, -+ '-t', trust_attributes -+ ] -+ -+ subprocess.check_call(cmd) -+ -+ def modify_cert(self, -+ nickname, -+ trust_attributes): -+ -+ cmd = [ -+ 'certutil', -+ '-M', -+ '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, -+ '-n', nickname, -+ '-t', trust_attributes -+ ] -+ -+ subprocess.check_call(cmd) -+ -+ def create_noise(self, noise_file, size=2048): -+ -+ subprocess.check_call([ -+ 'openssl', -+ 'rand', -+ '-out', noise_file, -+ str(size) -+ ]) -+ -+ def create_request(self, -+ subject_dn, -+ request_file, -+ noise_file=None, -+ key_type=None, -+ key_size=None, -+ curve=None, -+ hash_alg=None): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ if not noise_file: -+ noise_file = os.path.join(tmpdir, 'noise.bin') -+ if key_size: -+ size = key_size -+ else: -+ size = 2048 -+ self.create_noise( -+ noise_file=noise_file, -+ size=size) -+ -+ binary_request_file = os.path.join(tmpdir, 'request.bin') -+ -+ cmd = [ -+ 'certutil', -+ '-R', -+ '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, -+ '-s', subject_dn, -+ '-o', binary_request_file, -+ '-z', noise_file -+ ] -+ -+ if key_type: -+ cmd.extend(['-k', key_type]) -+ -+ if key_size: -+ cmd.extend(['-g', str(key_size)]) -+ -+ if curve: -+ cmd.extend(['-q', curve]) -+ -+ if hash_alg: -+ cmd.extend(['-Z', hash_alg]) -+ -+ # generate binary request -+ subprocess.check_call(cmd) -+ -+ # encode binary request in base-64 -+ b64_request_file = os.path.join(tmpdir, 'request.b64') -+ subprocess.check_call([ -+ 'BtoA', binary_request_file, b64_request_file]) -+ -+ # read base-64 request -+ with open(b64_request_file, 'r') as f: -+ b64_request = f.read() -+ -+ # add header and footer -+ with open(request_file, 'w') as f: -+ f.write('-----BEGIN NEW CERTIFICATE REQUEST-----\n') -+ f.write(b64_request) -+ f.write('-----END NEW CERTIFICATE REQUEST-----\n') -+ -+ finally: -+ shutil.rmtree(tmpdir) -+ -+ def create_self_signed_ca_cert(self, -+ subject_dn, -+ request_file, -+ cert_file, -+ serial='1', -+ validity=240): -+ -+ cmd = [ -+ 'certutil', -+ '-C', -+ '-x', -+ '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, -+ '-c', subject_dn, -+ '-a', -+ '-i', request_file, -+ '-o', cert_file, -+ '-m', serial, -+ '-v', str(validity), -+ '--keyUsage', 'digitalSignature,nonRepudiation,certSigning,crlSigning,critical', -+ '-2', -+ '-3', -+ '--extSKID', -+ '--extAIA' -+ ] -+ -+ p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) -+ -+ keystroke = '' -+ -+ # Is this a CA certificate [y/N]? -+ keystroke += 'y\n' -+ -+ # Enter the path length constraint, enter to skip [<0 for unlimited path]: -+ keystroke += '\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += 'y\n' -+ -+ # Enter value for the authKeyID extension [y/N]? -+ keystroke += 'y\n' -+ -+ # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId()) -+ # Enter value for the key identifier fields,enter to omit: -+ keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n' -+ -+ # Select one of the following general name type: -+ keystroke += '0\n' -+ -+ # Enter value for the authCertSerial field, enter to omit: -+ keystroke += '\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += '\n' -+ -+ # TODO: generate SHA1 ID (see APolicyRule.formSHA1KeyId()) -+ # Adding Subject Key ID extension. -+ # Enter value for the key identifier fields,enter to omit: -+ keystroke += '2d:7e:83:37:75:5a:fd:0e:8d:52:a3:70:16:93:36:b8:4a:d6:84:9f\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += '\n' -+ -+ # Enter access method type for Authority Information Access extension: -+ keystroke += '2\n' -+ -+ # Select one of the following general name type: -+ keystroke += '7\n' -+ -+ # TODO: replace with actual hostname name and port number -+ # Enter data: -+ keystroke += 'http://server.example.com:8080/ca/ocsp\n' -+ -+ # Select one of the following general name type: -+ keystroke += '0\n' -+ -+ # Add another location to the Authority Information Access extension [y/N] -+ keystroke += '\n' -+ -+ # Is this a critical extension [y/N]? -+ keystroke += '\n' -+ -+ p.communicate(keystroke) -+ -+ rc = p.wait() -+ -+ if rc: -+ raise Exception('Failed to generate self-signed CA certificate. RC: %d' % rc) -+ -+ def get_cert(self, nickname, output_format='pem'): -+ -+ if output_format == 'pem': -+ output_format_option = '-a' -+ -+ elif output_format == 'base64': -+ output_format_option = '-r' -+ -+ else: -+ raise Exception('Unsupported output format: %s' % output_format) -+ -+ cmd = [ -+ 'certutil', -+ '-L', -+ '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, -+ '-n', nickname, -+ output_format_option -+ ] -+ -+ cert_data = subprocess.check_output(cmd) -+ -+ if output_format == 'base64': -+ cert_data = base64.b64encode(cert_data) -+ -+ return cert_data -+ -+ def remove_cert(self, nickname): -+ -+ cmd = [ -+ 'certutil', -+ '-D', -+ '-d', self.directory, -+ '-h', self.token, -+ '-f', self.password_file, -+ '-n', nickname -+ ] -+ -+ subprocess.check_call(cmd) -+ -+ def import_cert_chain(self, nickname, cert_chain_file, trust_attributes=None): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ file_type = get_file_type(cert_chain_file) -+ -+ if file_type == 'cert': # import single PEM cert -+ self.add_cert( -+ nickname=nickname, -+ cert_file=cert_chain_file, -+ trust_attributes=trust_attributes) -+ return self.get_cert( -+ nickname=nickname, -+ output_format='base64') -+ -+ elif file_type == 'pkcs7': # import PKCS #7 cert chain -+ return self.import_pkcs7( -+ pkcs7_file=cert_chain_file, -+ nickname=nickname, -+ trust_attributes=trust_attributes, -+ output_format='base64') -+ -+ else: # import PKCS #7 data without header/footer -+ with open(cert_chain_file, 'r') as f: -+ base64_data = f.read() -+ pkcs7_data = convert_pkcs7(base64_data, 'base64', 'pem') -+ -+ tmp_cert_chain_file = os.path.join(tmpdir, 'cert_chain.p7b') -+ with open(tmp_cert_chain_file, 'w') as f: -+ f.write(pkcs7_data) -+ -+ self.import_pkcs7( -+ pkcs7_file=tmp_cert_chain_file, -+ nickname=nickname, -+ trust_attributes=trust_attributes) -+ -+ return base64_data -+ -+ finally: -+ shutil.rmtree(tmpdir) -+ -+ def import_pkcs7(self, pkcs7_file, nickname, trust_attributes=None, output_format='pem'): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ # export certs from PKCS #7 into PEM output -+ output = subprocess.check_output([ -+ 'openssl', -+ 'pkcs7', -+ '-print_certs', -+ '-in', pkcs7_file -+ ]) -+ -+ # parse PEM output into separate PEM certificates -+ certs = [] -+ lines = [] -+ state = 'header' -+ -+ for line in output.splitlines(): -+ -+ if state == 'header': -+ if line != CERT_HEADER: -+ # ignore header lines -+ pass -+ else: -+ # save cert header -+ lines.append(line) -+ state = 'body' -+ -+ elif state == 'body': -+ if line != CERT_FOOTER: -+ # save cert body -+ lines.append(line) -+ else: -+ # save cert footer -+ lines.append(line) -+ -+ # construct PEM cert -+ cert = '\n'.join(lines) -+ certs.append(cert) -+ lines = [] -+ state = 'header' -+ -+ # import PEM certs into NSS database -+ counter = 1 -+ for cert in certs: -+ -+ cert_file = os.path.join(tmpdir, 'cert%d.pem' % counter) -+ with open(cert_file, 'w') as f: -+ f.write(cert) -+ -+ if counter == 1: -+ n = nickname -+ else: -+ n = '%s #%d' % (nickname, counter) -+ -+ self.add_cert(n, cert_file, trust_attributes) -+ -+ counter += 1 -+ -+ # convert PKCS #7 data to the requested format -+ with open(pkcs7_file, 'r') as f: -+ data = f.read() -+ -+ return convert_pkcs7(data, 'pem', output_format) -+ -+ finally: -+ shutil.rmtree(tmpdir) -+ -+ def import_pkcs12(self, pkcs12_file, pkcs12_password=None, pkcs12_password_file=None): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ if pkcs12_password: -+ password_file = os.path.join(tmpdir, 'password.txt') -+ with open(password_file, 'w') as f: -+ f.write(pkcs12_password) -+ -+ elif pkcs12_password_file: -+ password_file = pkcs12_password_file -+ -+ else: -+ raise Exception('Missing PKCS #12 password') -+ -+ cmd = [ -+ 'pk12util', -+ '-d', self.directory, -+ '-h', self.token, -+ '-k', self.password_file, -+ '-i', pkcs12_file, -+ '-w', password_file -+ ] -+ -+ subprocess.check_call(cmd) -+ -+ finally: -+ shutil.rmtree(tmpdir) -+ -+ def export_pkcs12(self, pkcs12_file, nickname, pkcs12_password=None, pkcs12_password_file=None): -+ -+ tmpdir = tempfile.mkdtemp() -+ -+ try: -+ if pkcs12_password: -+ password_file = os.path.join(tmpdir, 'password.txt') -+ with open(password_file, 'w') as f: -+ f.write(pkcs12_password) -+ -+ elif pkcs12_password_file: -+ password_file = pkcs12_password_file -+ -+ else: -+ raise Exception('Missing PKCS #12 password') -+ -+ cmd = [ -+ 'pk12util', -+ '-d', self.directory, -+ '-k', self.password_file, -+ '-o', pkcs12_file, -+ '-w', password_file, -+ '-n', nickname -+ ] -+ -+ subprocess.check_call(cmd) -+ -+ finally: -+ shutil.rmtree(tmpdir) -diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py -index 5942115..b2fffd5 100644 ---- a/base/server/python/pki/server/__init__.py -+++ b/base/server/python/pki/server/__init__.py -@@ -33,7 +33,7 @@ import subprocess - import tempfile - - import pki --import pki.nss -+import pki.nssdb - - INSTANCE_BASE_DIR = '/var/lib/pki' - REGISTRY_DIR = '/etc/sysconfig/pki' -@@ -305,7 +305,7 @@ class PKIInstance(object): - return password - - def open_nssdb(self, token='internal'): -- return pki.nss.NSSDatabase( -+ return pki.nssdb.NSSDatabase( - directory=self.nssdb_dir, - token=token, - password=self.get_password(token)) -diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py -index cb27adc..3af1926 100644 ---- a/base/server/python/pki/server/cli/subsystem.py -+++ b/base/server/python/pki/server/cli/subsystem.py -@@ -29,7 +29,7 @@ import string - import sys - - import pki.cli --import pki.nss -+import pki.nssdb - import pki.server - - -@@ -536,13 +536,13 @@ class SubsystemCertExportCLI(pki.cli.CLI): - - if cert_file: - -- cert_data = pki.nss.convert_cert(subsystem_cert['data'], 'base64', 'pem') -+ cert_data = pki.nssdb.convert_cert(subsystem_cert['data'], 'base64', 'pem') - with open(cert_file, 'w') as f: - f.write(cert_data) - - if csr_file: - -- csr_data = pki.nss.convert_csr(subsystem_cert['request'], 'base64', 'pem') -+ csr_data = pki.nssdb.convert_csr(subsystem_cert['request'], 'base64', 'pem') - with open(csr_file, 'w') as f: - f.write(csr_data) - -diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py -index 16c6ae5..54f1c6e 100644 ---- a/base/server/python/pki/server/deployment/scriptlets/configuration.py -+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py -@@ -28,7 +28,7 @@ from .. import pkimessages as log - from .. import pkiscriptlet - - import pki.encoder --import pki.nss -+import pki.nssdb - import pki.server - import pki.system - import pki.util -@@ -138,7 +138,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - hash_alg=hash_alg) - with open(external_csr_path) as f: - signing_csr = f.read() -- signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64') -+ signing_csr = pki.nssdb.convert_csr(signing_csr, 'pem', 'base64') - subsystem.config['ca.signing.certreq'] = signing_csr - - # This is needed by IPA to detect step 1 completion. -@@ -153,7 +153,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - if external_csr_path: - with open(external_csr_path) as f: - signing_csr = f.read() -- signing_csr = pki.nss.convert_csr(signing_csr, 'pem', 'base64') -+ signing_csr = pki.nssdb.convert_csr(signing_csr, 'pem', 'base64') - subsystem.config['ca.signing.certreq'] = signing_csr - - # If specified, import external CA cert into NSS database. --- -2.5.0 - - -From 7f2e9f9d2619bf1b57642abc23d84a745617c499 Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Tue, 2 Feb 2016 03:32:50 +0100 -Subject: [PATCH 9/9] Fixed KRA installation. - -Due to a recent change the KRA installation failed because the -installer was trying to read the pki_external_csr_path parameter -which is not available for KRA installation. The installer has -been fixed to read the parameter in external CA case only. - -https://fedorahosted.org/pki/ticket/456 -(cherry picked from commit d42f39334ce4b4f5fa89707bfb6145039ff04579) ---- - base/server/python/pki/server/deployment/pkihelper.py | 1 - - base/server/python/pki/server/deployment/scriptlets/configuration.py | 3 ++- - base/server/sbin/pkispawn | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py -index 07a5ce4..e859139 100644 ---- a/base/server/python/pki/server/deployment/pkihelper.py -+++ b/base/server/python/pki/server/deployment/pkihelper.py -@@ -492,7 +492,6 @@ class ConfigurationFile: - self.external = config.str2bool(self.mdict['pki_external']) - self.external_step_one = not config.str2bool(self.mdict['pki_external_step_two']) - self.external_step_two = not self.external_step_one -- self.external_csr_path = self.mdict['pki_external_csr_path'] - - if self.external: - # generic extension support in CSR - for external CA -diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py -index 54f1c6e..e7b257f 100644 ---- a/base/server/python/pki/server/deployment/scriptlets/configuration.py -+++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py -@@ -96,7 +96,6 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - external = deployer.configuration_file.external - step_one = deployer.configuration_file.external_step_one - step_two = deployer.configuration_file.external_step_two -- external_csr_path = deployer.configuration_file.external_csr_path - - try: - if external and step_one: # external/existing CA step 1 -@@ -128,6 +127,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - - # If filename specified, generate CA cert request and - # import it into CS.cfg. -+ external_csr_path = deployer.mdict['pki_external_csr_path'] - if external_csr_path: - nssdb.create_request( - subject_dn=deployer.mdict['pki_ca_signing_subject_dn'], -@@ -150,6 +150,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet): - elif external and step_two: # external/existing CA step 2 - - # If specified, import existing CA cert request into CS.cfg. -+ external_csr_path = deployer.mdict['pki_external_csr_path'] - if external_csr_path: - with open(external_csr_path) as f: - signing_csr = f.read() -diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn -index 967d5f5..7ab11a5 100755 ---- a/base/server/sbin/pkispawn -+++ b/base/server/sbin/pkispawn -@@ -613,9 +613,9 @@ def main(argv): - - external = deployer.configuration_file.external - step_one = deployer.configuration_file.external_step_one -- external_csr_path = deployer.configuration_file.external_csr_path - - if external and step_one: -+ external_csr_path = deployer.mdict['pki_external_csr_path'] - if external_csr_path: - print_external_ca_step_one_information(parser.mdict) - else: --- -2.5.0 - diff --git a/pki-core-Added-support-for-secure-database-connection-in-CLI.patch b/pki-core-Added-support-for-secure-database-connection-in-CLI.patch deleted file mode 100644 index 5ea18b7..0000000 --- a/pki-core-Added-support-for-secure-database-connection-in-CLI.patch +++ /dev/null @@ -1,440 +0,0 @@ -commit 256c33a5ff5cfae6921ad70af55d969901c61760 -Author: Endi S. Dewata -Date: Fri Sep 4 06:30:27 2015 +0200 - - Added support for secure database connection in CLI. - - The pki-server subsystem-cert-update has been modified to support - secure database connection with client certificate authentication. - The certificate and the private key will be exported temporarily - into PEM files so python-ldap can use them. - - The pki client-cert-show has been modified to provide an option - to export client certificate's private key. - - https://fedorahosted.org/pki/ticket/1551 - (cherry picked from commit f153bd8a455953698e8af5085cd3cd7b368b1247) - - Conflicts: - base/server/upgrade/10.2.0/01-AddTLSRangeSupport - -diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java -index f79501c..e44fae7 100644 ---- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java -+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertShowCLI.java -@@ -29,10 +29,8 @@ import org.apache.commons.lang.RandomStringUtils; - import org.apache.commons.lang.StringUtils; - import org.mozilla.jss.crypto.X509Certificate; - --import com.netscape.certsrv.cert.CertData; - import com.netscape.cmstools.cli.CLI; - import com.netscape.cmstools.cli.MainCLI; --import com.netscape.cmsutil.util.Utils; - - /** - * @author Endi S. Dewata -@@ -57,6 +55,10 @@ public class ClientCertShowCLI extends CLI { - option.setArgName("path"); - options.addOption(option); - -+ option = new Option(null, "private-key", true, "PEM file to store the private key."); -+ option.setArgName("path"); -+ options.addOption(option); -+ - option = new Option(null, "client-cert", true, "PEM file to store the certificate and the private key."); - option.setArgName("path"); - options.addOption(option); -@@ -107,90 +109,82 @@ public class ClientCertShowCLI extends CLI { - - String nickname = cmdArgs[0]; - String certPath = cmd.getOptionValue("cert"); -+ String privateKeyPath = cmd.getOptionValue("private-key"); -+ String clientCertPath = cmd.getOptionValue("client-cert"); - String pkcs12Path = cmd.getOptionValue("pkcs12"); - String pkcs12Password = cmd.getOptionValue("pkcs12-password"); -- String clientCertPath = cmd.getOptionValue("client-cert"); -- -- if (certPath != null) { -- -- if (verbose) System.out.println("Exporting certificate to " + clientCertPath + "."); -- -- // late initialization -- mainCLI.init(); - -- client = mainCLI.getClient(); -- X509Certificate cert = client.getCert(nickname); -+ File pkcs12File; - -- try (PrintWriter out = new PrintWriter(new FileWriter(certPath))) { -- out.println(CertData.HEADER); -- out.println(Utils.base64encode(cert.getEncoded())); -- out.println(CertData.FOOTER); -- } -+ if (pkcs12Path != null) { -+ // exporting certificate to PKCS #12 file - -- } else if (pkcs12Path != null) { -- -- if (verbose) System.out.println("Exporting certificate chain and private key to " + pkcs12Path + "."); -+ pkcs12File = new File(pkcs12Path); - - if (pkcs12Password == null) { - throw new Exception("Missing PKCS #12 password"); - } - -- // store password into a temporary file -- File pkcs12PasswordFile = File.createTempFile("pki-client-cert-show-", ".pwd"); -- pkcs12PasswordFile.deleteOnExit(); -+ } else if (certPath != null || clientCertPath != null || privateKeyPath != null) { -+ // exporting certificate and/or private key to PEM files using temporary PKCS #12 file - -- try (PrintWriter out = new PrintWriter(new FileWriter(pkcs12PasswordFile))) { -- out.print(pkcs12Password); -- } -+ // prepare temporary PKCS #12 file -+ pkcs12File = File.createTempFile("pki-client-cert-show-", ".p12"); -+ pkcs12File.deleteOnExit(); - -- // export certificate chain and private key into PKCS #12 file -- exportPKCS12( -- mainCLI.certDatabase.getAbsolutePath(), -- mainCLI.config.getCertPassword(), -- pkcs12Path, -- pkcs12PasswordFile.getAbsolutePath(), -- nickname); -+ // generate random password -+ pkcs12Password = RandomStringUtils.randomAlphanumeric(16); - -- } else if (clientCertPath != null) { -+ } else { -+ // displaying certificate info - -- if (verbose) System.out.println("Exporting client certificate and private key to " + clientCertPath + "."); -+ mainCLI.init(); - -- // generate random PKCS #12 password -- pkcs12Password = RandomStringUtils.randomAlphanumeric(16); -+ client = mainCLI.getClient(); -+ X509Certificate cert = client.getCert(nickname); -+ -+ ClientCLI.printCertInfo(cert); -+ return; -+ } - -- // store password into a temporary file -- File pkcs12PasswordFile = File.createTempFile("pki-client-cert-show-", ".pwd"); -- pkcs12PasswordFile.deleteOnExit(); -+ // store password into a temporary file -+ File pkcs12PasswordFile = File.createTempFile("pki-client-cert-show-", ".pwd"); -+ pkcs12PasswordFile.deleteOnExit(); - -- try (PrintWriter out = new PrintWriter(new FileWriter(pkcs12PasswordFile))) { -- out.print(pkcs12Password); -- } -+ try (PrintWriter out = new PrintWriter(new FileWriter(pkcs12PasswordFile))) { -+ out.print(pkcs12Password); -+ } - -- // export certificate chain and private key into a temporary PKCS #12 file -- File pkcs12File = File.createTempFile("pki-client-cert-show-", ".p12"); -- pkcs12File.deleteOnExit(); -+ if (verbose) System.out.println("Exporting certificate chain and private key to " + pkcs12File + "."); -+ exportPKCS12( -+ mainCLI.certDatabase.getAbsolutePath(), -+ mainCLI.config.getCertPassword(), -+ pkcs12File.getAbsolutePath(), -+ pkcs12PasswordFile.getAbsolutePath(), -+ nickname); - -- exportPKCS12( -- mainCLI.certDatabase.getAbsolutePath(), -- mainCLI.config.getCertPassword(), -+ if (certPath != null) { -+ if (verbose) System.out.println("Exporting certificate to " + certPath + "."); -+ exportCertificate( - pkcs12File.getAbsolutePath(), - pkcs12PasswordFile.getAbsolutePath(), -- nickname); -+ certPath); -+ } - -- // export client certificate and private key into a PEM file -- exportClientCertificate( -+ if (privateKeyPath != null) { -+ if (verbose) System.out.println("Exporting private key to " + privateKeyPath + "."); -+ exportPrivateKey( - pkcs12File.getAbsolutePath(), - pkcs12PasswordFile.getAbsolutePath(), -- clientCertPath); -- -- } else { -- // late initialization -- mainCLI.init(); -- -- client = mainCLI.getClient(); -- X509Certificate cert = client.getCert(nickname); -+ privateKeyPath); -+ } - -- ClientCLI.printCertInfo(cert); -+ if (clientCertPath != null) { -+ if (verbose) System.out.println("Exporting client certificate and private key to " + clientCertPath + "."); -+ exportClientCertificateAndPrivateKey( -+ pkcs12File.getAbsolutePath(), -+ pkcs12PasswordFile.getAbsolutePath(), -+ clientCertPath); - } - } - -@@ -218,7 +212,53 @@ public class ClientCertShowCLI extends CLI { - } - } - -- public void exportClientCertificate( -+ public void exportCertificate( -+ String pkcs12Path, -+ String pkcs12PasswordPath, -+ String certPath) throws Exception { -+ -+ String[] command = { -+ "/bin/openssl", -+ "pkcs12", -+ "-clcerts", // certificate only -+ "-nokeys", -+ "-in", pkcs12Path, -+ "-passin", "file:" + pkcs12PasswordPath, -+ "-out", certPath -+ }; -+ -+ try { -+ run(command); -+ -+ } catch (Exception e) { -+ throw new Exception("Unable to export certificate", e); -+ } -+ } -+ -+ public void exportPrivateKey( -+ String pkcs12Path, -+ String pkcs12PasswordPath, -+ String privateKeyPath) throws Exception { -+ -+ String[] command = { -+ "/bin/openssl", -+ "pkcs12", -+ "-nocerts", // private key only -+ "-nodes", // no encryption -+ "-in", pkcs12Path, -+ "-passin", "file:" + pkcs12PasswordPath, -+ "-out", privateKeyPath -+ }; -+ -+ try { -+ run(command); -+ -+ } catch (Exception e) { -+ throw new Exception("Unable to export private key", e); -+ } -+ } -+ -+ public void exportClientCertificateAndPrivateKey( - String pkcs12Path, - String pkcs12PasswordPath, - String clientCertPath) throws Exception { -@@ -226,7 +266,7 @@ public class ClientCertShowCLI extends CLI { - String[] command = { - "/bin/openssl", - "pkcs12", -- "-clcerts", // client certificate only -+ "-clcerts", // client certificate and private key - "-nodes", // no encryption - "-in", pkcs12Path, - "-passin", "file:" + pkcs12PasswordPath, -@@ -237,7 +277,7 @@ public class ClientCertShowCLI extends CLI { - run(command); - - } catch (Exception e) { -- throw new Exception("Unable to export client certificate", e); -+ throw new Exception("Unable to export client certificate and private key", e); - } - } - -diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py -index d004465..89d4acf 100644 ---- a/base/server/python/pki/server/__init__.py -+++ b/base/server/python/pki/server/__init__.py -@@ -28,7 +28,9 @@ import operator - import os - import pwd - import re -+import shutil - import subprocess -+import tempfile - - import pki - -@@ -162,18 +164,43 @@ class PKISubsystem(object): - - def open_database(self, name='internaldb'): - -+ # TODO: add LDAPI support - hostname = self.config['%s.ldapconn.host' % name] - port = self.config['%s.ldapconn.port' % name] -- bind_dn = self.config['%s.ldapauth.bindDN' % name] -+ secure = self.config['%s.ldapconn.secureConn' % name] - -- # TODO: add support for other authentication -- # mechanisms (e.g. client cert authentication, LDAPI) -- bind_password = self.instance.get_password(name) -+ if secure == 'true': -+ url = 'ldaps://%s:%s' % (hostname, port) - -- con = ldap.initialize('ldap://%s:%s' % (hostname, port)) -- con.simple_bind_s(bind_dn, bind_password) -+ elif secure == 'false': -+ url = 'ldap://%s:%s' % (hostname, port) - -- return con -+ else: -+ raise Exception('Invalid parameter value in %s.ldapconn.secureConn: %s' % (name, secure)) -+ -+ connection = PKIDatabaseConnection(url) -+ -+ connection.set_security_database(self.instance.nssdb_dir) -+ -+ auth_type = self.config['%s.ldapauth.authtype' % name] -+ if auth_type == 'BasicAuth': -+ connection.set_credentials( -+ bind_dn=self.config['%s.ldapauth.bindDN' % name], -+ bind_password=self.instance.get_password(name) -+ ) -+ -+ elif auth_type == 'SslClientAuth': -+ connection.set_credentials( -+ client_cert_nickname=self.config['%s.ldapauth.clientCertNickname' % name], -+ nssdb_password=self.instance.get_password('internal') -+ ) -+ -+ else: -+ raise Exception('Invalid parameter value in %s.ldapauth.authtype: %s' % (name, auth_type)) -+ -+ connection.open() -+ -+ return connection - - def __repr__(self): - return str(self.instance) + '/' + self.name -@@ -337,6 +364,64 @@ class PKIInstance(object): - return self.name - - -+class PKIDatabaseConnection(object): -+ -+ def __init__(self, url='ldap://localhost:389'): -+ -+ self.url = url -+ -+ self.nssdb_dir = None -+ -+ self.bind_dn = None -+ self.bind_password = None -+ -+ self.client_cert_nickname = None -+ self.nssdb_password = None -+ -+ self.temp_dir = None -+ self.ldap = None -+ -+ def set_security_database(self, nssdb_dir=None): -+ self.nssdb_dir = nssdb_dir -+ -+ def set_credentials(self, bind_dn=None, bind_password=None, -+ client_cert_nickname=None, nssdb_password=None): -+ self.bind_dn = bind_dn -+ self.bind_password = bind_password -+ self.client_cert_nickname = client_cert_nickname -+ self.nssdb_password = nssdb_password -+ -+ def open(self): -+ -+ self.temp_dir = tempfile.mkdtemp() -+ -+ if self.nssdb_dir: -+ -+ ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, self.nssdb_dir) -+ -+ if self.client_cert_nickname: -+ -+ password_file = os.path.join(self.temp_dir, 'password.txt') -+ with open(password_file, 'w') as f: -+ f.write(self.nssdb_password) -+ -+ ldap.set_option(ldap.OPT_X_TLS_CERTFILE, self.client_cert_nickname) -+ ldap.set_option(ldap.OPT_X_TLS_KEYFILE, password_file) -+ -+ self.ldap = ldap.initialize(self.url) -+ -+ if self.bind_dn and self.bind_password: -+ self.ldap.simple_bind_s(self.bind_dn, self.bind_password) -+ -+ def close(self): -+ -+ if self.ldap: -+ self.ldap.unbind_s() -+ -+ if self.temp_dir: -+ shutil.rmtree(self.temp_dir) -+ -+ - class PKIServerException(pki.PKIException): - - def __init__(self, message, exception=None, -diff --git a/base/server/python/pki/server/ca.py b/base/server/python/pki/server/ca.py -index 70ebf4d..31e373a 100644 ---- a/base/server/python/pki/server/ca.py -+++ b/base/server/python/pki/server/ca.py -@@ -45,13 +45,13 @@ class CASubsystem(pki.server.PKISubsystem): - - con = self.open_database() - -- entries = con.search_s( -+ entries = con.ldap.search_s( - 'ou=ca,ou=requests,%s' % base_dn, - ldap.SCOPE_ONELEVEL, - search_filter, - None) - -- con.unbind_s() -+ con.close() - - requests = [] - for entry in entries: -@@ -65,13 +65,13 @@ class CASubsystem(pki.server.PKISubsystem): - - con = self.open_database() - -- entries = con.search_s( -+ entries = con.ldap.search_s( - 'cn=%s,ou=ca,ou=requests,%s' % (request_id, base_dn), - ldap.SCOPE_BASE, - '(objectClass=*)', - None) - -- con.unbind_s() -+ con.close() - - entry = entries[0] - return self.create_request_object(entry) -diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py -index fc89c27..19db203 100644 ---- a/base/server/python/pki/server/cli/subsystem.py -+++ b/base/server/python/pki/server/cli/subsystem.py -@@ -104,7 +104,7 @@ class SubsystemFindCLI(pki.cli.CLI): - if first: - first = False - else: -- print -+ print() - - SubsystemCLI.print_subsystem(subsystem) - diff --git a/pki-core-Block-startup-until-initial-profile-load-completed.patch b/pki-core-Block-startup-until-initial-profile-load-completed.patch deleted file mode 100644 index 26a713c..0000000 --- a/pki-core-Block-startup-until-initial-profile-load-completed.patch +++ /dev/null @@ -1,110 +0,0 @@ -From b16968402bb414042b3a529097ca934f165d62b9 Mon Sep 17 00:00:00 2001 -From: Fraser Tweedale -Date: Tue, 1 Dec 2015 16:49:03 +1100 -Subject: [PATCH] Block startup until initial profile load completed - -It is possible for the CMS getStatus resource to indicate that CMS -is ready when the initial loading of profiles (which is performed by -another thread) is not complete. During startup, wait for the -initial loading of profiles to complete before continuing. - -Fixes: https://fedorahosted.org/pki/ticket/1702 -(cherry picked from commit e8a1d9cbbefb2988092e96b13d0b13254c92d1b2) ---- - .../cmscore/profile/LDAPProfileSubsystem.java | 37 ++++++++++++++++++++-- - 1 file changed, 35 insertions(+), 2 deletions(-) - -diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java -index f48aea3..28b34cd 100644 ---- a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java -+++ b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java -@@ -19,10 +19,12 @@ package com.netscape.cmscore.profile; - - import java.io.ByteArrayInputStream; - import java.io.InputStream; -+import java.util.Arrays; - import java.util.Hashtable; - import java.util.LinkedHashMap; - import java.util.TreeMap; - import java.util.TreeSet; -+import java.util.concurrent.CountDownLatch; - - import netscape.ldap.LDAPAttribute; - import netscape.ldap.LDAPConnection; -@@ -68,6 +70,11 @@ public class LDAPProfileSubsystem - /* Set of nsUniqueIds of deleted entries */ - private TreeSet deletedNsUniqueIds; - -+ /* Variables to track initial loading of profiles */ -+ private Integer initialNumProfiles = null; -+ private int numProfilesLoaded = 0; -+ private CountDownLatch initialLoadDone = new CountDownLatch(1); -+ - /** - * Initializes this subsystem with the given configuration - * store. -@@ -109,6 +116,13 @@ public class LDAPProfileSubsystem - - monitor = new Thread(this, "profileChangeMonitor"); - monitor.start(); -+ try { -+ initialLoadDone.await(); -+ } catch (InterruptedException e) { -+ CMS.debug("LDAPProfileSubsystem: caught InterruptedException " -+ + "while waiting for initial load of profiles."); -+ } -+ CMS.debug("LDAPProfileSubsystem: finished init"); - } - - /** -@@ -380,6 +394,12 @@ public class LDAPProfileSubsystem - return "cn=" + id + "," + dn; - } - -+ private void checkInitialLoadDone() { -+ if (initialNumProfiles != null -+ && numProfilesLoaded >= initialNumProfiles) -+ initialLoadDone.countDown(); -+ } -+ - public void run() { - int op = LDAPPersistSearchControl.ADD - | LDAPPersistSearchControl.MODIFY -@@ -400,12 +420,23 @@ public class LDAPProfileSubsystem - cons.setServerControls(persistCtrl); - cons.setBatchSize(1); - cons.setServerTimeLimit(0 /* seconds */); -- String[] attrs = {"*", "entryUSN", "nsUniqueId"}; -+ String[] attrs = {"*", "entryUSN", "nsUniqueId", "numSubordinates"}; - LDAPSearchResults results = conn.search( -- dn, LDAPConnection.SCOPE_ONE, "(objectclass=*)", -+ dn, LDAPConnection.SCOPE_SUB, "(objectclass=*)", - attrs, false, cons); - while (!stopped && results.hasMoreElements()) { - LDAPEntry entry = results.next(); -+ -+ String[] objectClasses = -+ entry.getAttribute("objectClass").getStringValueArray(); -+ if (Arrays.asList(objectClasses).contains("organizationalUnit")) { -+ initialNumProfiles = new Integer( -+ entry.getAttribute("numSubordinates") -+ .getStringValueArray()[0]); -+ checkInitialLoadDone(); -+ continue; -+ } -+ - LDAPEntryChangeControl changeControl = (LDAPEntryChangeControl) - LDAPUtil.getControl( - LDAPEntryChangeControl.class, results.getResponseControls()); -@@ -436,6 +467,8 @@ public class LDAPProfileSubsystem - } else { - CMS.debug("Profile change monitor: immediate result"); - readProfile(entry); -+ numProfilesLoaded += 1; -+ checkInitialLoadDone(); - } - } - } catch (ELdapException e) { --- -2.5.0 - diff --git a/pki-core-Do-Not-Create-Replication-Agreements.patch b/pki-core-Do-Not-Create-Replication-Agreements.patch deleted file mode 100644 index 4d03341..0000000 --- a/pki-core-Do-Not-Create-Replication-Agreements.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit ffa4a81a214335440a17e15a0ffa4d0e702761d7 -Author: Ade Lee -Date: Fri Jul 24 15:07:02 2015 -0400 - - Fix code to add replicationdb password unless already present - - The replicationdb password is an instance parameter and should - be created by the first subsystem in the instance. This should - happen independantly of whether replication is being set up - in case it is needed to set up replication (as a master) later. - - Related to Ticket 1414 - - (cherry picked from commit 8a002e091841ceb52346f121d75db80e78735af2) - -diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -index e7a9960..31891ca 100644 ---- a/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -+++ b/base/server/cms/src/org/dogtagpki/server/rest/SystemConfigService.java -@@ -713,7 +713,7 @@ public class SystemConfigService extends PKIService implements SystemConfigResou - passwordFile = cs.getString("passwordFile"); - psStore = CMS.createFileConfigStore(passwordFile); - psStore.putString("internaldb", data.getBindpwd()); -- if (data.getSetupReplication()) { -+ if (StringUtils.isEmpty(psStore.getString("replicationdb", null))) { - psStore.putString("replicationdb", replicationPassword); - } - psStore.commit(false); diff --git a/pki-core-Externalreg-Support-Multiple-KeySets.patch b/pki-core-Externalreg-Support-Multiple-KeySets.patch deleted file mode 100644 index eca32b2..0000000 --- a/pki-core-Externalreg-Support-Multiple-KeySets.patch +++ /dev/null @@ -1,84 +0,0 @@ -commit f97b417d964fd163f6231de5a12e26ef4215aa7a -Author: Christina Fu -Date: Tue Jul 28 11:47:27 2015 -0700 - - Ticket 1307 issue: FilterMappingResolver always returns target - - (cherry picked from commit b68fc753775cf49dcd3bafe046c71dda08ca6b9a) - -diff --git a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java -index 95cf26c..598e99a 100644 ---- a/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java -+++ b/base/tps/src/org/dogtagpki/server/tps/channel/SecureChannel.java -@@ -393,7 +393,7 @@ public class SecureChannel { - - if (!response.checkResult()) { - throw new TPSException( -- "SecureChannel.eternalAuthenticate SCP01. Failed to external authenticate to token.", -+ "SecureChannel.externalAuthenticate SCP01. Failed to external authenticate to token.", - TPSStatus.STATUS_ERROR_SECURE_CHANNEL); - } - -diff --git a/base/tps/src/org/dogtagpki/server/tps/mapping/FilterMappingResolver.java b/base/tps/src/org/dogtagpki/server/tps/mapping/FilterMappingResolver.java -index 38ea29c..45cd203 100644 ---- a/base/tps/src/org/dogtagpki/server/tps/mapping/FilterMappingResolver.java -+++ b/base/tps/src/org/dogtagpki/server/tps/mapping/FilterMappingResolver.java -@@ -42,6 +42,7 @@ public class FilterMappingResolver extends BaseMappingResolver { - String extKeySet = null; - - String targetMappedName = null; -+ String selectedMappedName = null; - - CMS.debug(method + " starts"); - -@@ -52,6 +53,7 @@ public class FilterMappingResolver extends BaseMappingResolver { - CMS.debug(method + " param minor_version =" + minor_version); - - cuid = mappingParams.getString(FilterMappingParams.FILTER_PARAM_CUID); -+ CMS.debug(method + " param cuid =" + cuid); - // msn = (String) mappingParams.get(FilterMappingParams.FILTER_PARAM_MSN); - - // they don't necessarily have extension -@@ -225,7 +227,8 @@ public class FilterMappingResolver extends BaseMappingResolver { - continue; - } - -- if (cuid.compareTo(tokenCUIDStart) < 0) { -+ if (cuid.compareToIgnoreCase(tokenCUIDStart) < 0) { -+ CMS.debug(method + " cuid < tokenCUIDStart ... out of range"); - continue; - } - -@@ -255,7 +258,8 @@ public class FilterMappingResolver extends BaseMappingResolver { - continue; - } - -- if (cuid.compareTo(tokenCUIDEnd) > 0) { -+ if (cuid.compareToIgnoreCase(tokenCUIDEnd) > 0) { -+ CMS.debug(method + " cuid > tokenCUIDEnd ... out of range"); - continue; - } - -@@ -309,17 +313,18 @@ public class FilterMappingResolver extends BaseMappingResolver { - } - - //if we make it this far, we have a mapped name -- CMS.debug(method + " Selected Token type: " + targetMappedName); -+ selectedMappedName = targetMappedName; -+ CMS.debug(method + " Selected mapped name: " + selectedMappedName); - break; - } - -- if (targetMappedName == null) { -- CMS.debug(method + " ends, found: " + targetMappedName); -+ if (selectedMappedName == null) { -+ CMS.debug(method + " ends, found: " + selectedMappedName); - throw new TPSException(method + " Can't map to target name!", - TPSStatus.STATUS_ERROR_MAPPING_RESOLVER_FAILED); - } - -- return targetMappedName; -+ return selectedMappedName; - - } - diff --git a/pki-core-Fix-Base-64-Encoded-Cert-Displays.patch b/pki-core-Fix-Base-64-Encoded-Cert-Displays.patch deleted file mode 100644 index 080855b..0000000 --- a/pki-core-Fix-Base-64-Encoded-Cert-Displays.patch +++ /dev/null @@ -1,153 +0,0 @@ -commit 6999197b067af920b53c75e17dc20181ba49e997 -Author: Matthew Harmsen -Date: Fri Jul 31 17:28:57 2015 -0600 - - remove extra space from Base 64 encoded cert displays - - - PKI TRAC Ticket #1522 - CA UI adds extra space in Base 64 encoded - certificate display - -diff --git a/base/ca/shared/webapps/ca/agent/ca/displayBySerial.template b/base/ca/shared/webapps/ca/agent/ca/displayBySerial.template -index 2bb2bfa..3b58a47 100644 ---- a/base/ca/shared/webapps/ca/agent/ca/displayBySerial.template -+++ b/base/ca/shared/webapps/ca/agent/ca/displayBySerial.template -@@ -179,11 +179,11 @@ The following format can be used to install this certificate into a server. - Base 64 encoded certificate - -

-------BEGIN CERTIFICATE-----
- 
-------END CERTIFICATE-----
- 
- - -@@ -191,11 +191,11 @@ document.write(result.header.certChainBase64); - Base 64 encoded certificate with CA certificate chain in pkcs7 format - -

-------BEGIN CERTIFICATE CHAIN-----
- 
-------END CERTIFICATE CHAIN-----
- 
- -

-diff --git a/base/ca/shared/webapps/ca/agent/ca/displayBySerial2.template b/base/ca/shared/webapps/ca/agent/ca/displayBySerial2.template -index 4a193e3..7923f41 100644 ---- a/base/ca/shared/webapps/ca/agent/ca/displayBySerial2.template -+++ b/base/ca/shared/webapps/ca/agent/ca/displayBySerial2.template -@@ -97,11 +97,11 @@ The following format can be used to install this certificate into a server. - Base 64 encoded certificate - -

-------BEGIN CERTIFICATE CHAIN-----
- 
-------END CERTIFICATE CHAIN-----
- 
- -

-diff --git a/base/ca/shared/webapps/ca/ee/ca/displayBySerial.template b/base/ca/shared/webapps/ca/ee/ca/displayBySerial.template -index e9b4d72..d1e65fa 100644 ---- a/base/ca/shared/webapps/ca/ee/ca/displayBySerial.template -+++ b/base/ca/shared/webapps/ca/ee/ca/displayBySerial.template -@@ -104,11 +104,11 @@ The following format can be used to install this certificate into a server. - Base 64 encoded certificate - -

-------BEGIN CERTIFICATE-----
- 
-------END CERTIFICATE-----
- 
- - -@@ -116,11 +116,11 @@ document.write(result.header.certChainBase64); - Base 64 encoded certificate with CA certificate chain in pkcs7 format - -

-------BEGIN CERTIFICATE-----
- 
-------END CERTIFICATE-----
- 
- -

-diff --git a/base/ca/shared/webapps/ca/ee/ca/displayBySerial2.template b/base/ca/shared/webapps/ca/ee/ca/displayBySerial2.template -index f8f3064..7e6678f 100644 ---- a/base/ca/shared/webapps/ca/ee/ca/displayBySerial2.template -+++ b/base/ca/shared/webapps/ca/ee/ca/displayBySerial2.template -@@ -97,11 +97,11 @@ The following format can be used to install this certificate into a server. - Base 64 encoded certificate - -

-------BEGIN CERTIFICATE-----
- 
-------END CERTIFICATE-----
- 
- -

-diff --git a/base/ca/shared/webapps/ca/ee/ca/displayCaCert.template b/base/ca/shared/webapps/ca/ee/ca/displayCaCert.template -index 4e93919..49a91af 100644 ---- a/base/ca/shared/webapps/ca/ee/ca/displayCaCert.template -+++ b/base/ca/shared/webapps/ca/ee/ca/displayCaCert.template -@@ -43,9 +43,9 @@ if (result.header.displayFormat == "chain") { - document.writeln('

' + result.header.subjectdn); - document.writeln('


'); - document.writeln('

');
--    document.writeln('-----BEGIN CERTIFICATE-----');
--    document.writeln(result.header.chainBase64);
--    document.writeln('-----END CERTIFICATE-----');
-+    document.writeln('-----BEGIN CERTIFICATE CHAIN-----');
-+    document.write(result.header.chainBase64);
-+    document.writeln('-----END CERTIFICATE CHAIN-----');
-     document.writeln('
'); - } else if (result.header.displayFormat == "individual") { - if (result.recordSet.length == 0) { -@@ -86,7 +86,7 @@ function displayCertificate(cert,i) - document.writeln(''); - document.writeln('
');
-     document.writeln('-----BEGIN CERTIFICATE-----');
--    document.writeln(cert.base64);
-+    document.write(cert.base64);
-     document.writeln('-----END CERTIFICATE-----');
-     document.writeln('
'); - document.writeln(''); -diff --git a/base/kra/shared/webapps/kra/agent/kra/displayBySerial2.template b/base/kra/shared/webapps/kra/agent/kra/displayBySerial2.template -index 30af980..06bef2f 100644 ---- a/base/kra/shared/webapps/kra/agent/kra/displayBySerial2.template -+++ b/base/kra/shared/webapps/kra/agent/kra/displayBySerial2.template -@@ -92,11 +92,11 @@ The following format can be used to install this certificate into a server. - Base 64 encoded certificate - -

-------BEGIN CERTIFICATE-----
- 
-------END CERTIFICATE-----
- 
- -

diff --git a/pki-core-Fix-ECC-Admin-Cert-Creation.patch b/pki-core-Fix-ECC-Admin-Cert-Creation.patch deleted file mode 100644 index c342729..0000000 --- a/pki-core-Fix-ECC-Admin-Cert-Creation.patch +++ /dev/null @@ -1,134 +0,0 @@ -commit 5823d43d06c263076159d5606154776e24b4f111 -Author: Matthew Harmsen -Date: Tue Jul 28 19:56:26 2015 -0600 - - Add certutil options for ECC - - - PKI TRAC Ticket #1524 - pkispawn: certutil options incorrect for creating - ecc admin certificate - - (cherry picked from commit f9102b8df60d50e00d2a45915d06837510cfd1aa) - -diff --git a/base/server/etc/default.cfg b/base/server/etc/default.cfg -index 58f3386..26ffd0d 100644 ---- a/base/server/etc/default.cfg -+++ b/base/server/etc/default.cfg -@@ -66,6 +66,7 @@ pki_admin_cert_file=%(pki_client_dir)s/ca_admin.cert - pki_admin_cert_request_type=pkcs10 - pki_admin_dualkey=False - pki_admin_keysize=2048 -+pki_admin_key_type=rsa - pki_admin_password= - pki_audit_group=pkiaudit - pki_audit_signing_key_algorithm=SHA256withRSA -diff --git a/base/server/man/man5/pki_default.cfg.5 b/base/server/man/man5/pki_default.cfg.5 -index df4f944..17130ae 100644 ---- a/base/server/man/man5/pki_default.cfg.5 -+++ b/base/server/man/man5/pki_default.cfg.5 -@@ -125,7 +125,7 @@ Password for the admin user. This password is used to log into the pki-console - .IP - Email address for the admin user. - .TP --.B pki_admin_dualkey, pki_admin_keysize, pki_admin_keytype -+.B pki_admin_dualkey, pki_admin_keysize, pki_admin_key_type - .IP - Settings for the administrator certificate and keys. - .TP -diff --git a/base/server/man/man8/pkispawn.8 b/base/server/man/man8/pkispawn.8 -index 8d8a4ff..411d93f 100644 ---- a/base/server/man/man8/pkispawn.8 -+++ b/base/server/man/man8/pkispawn.8 -@@ -265,6 +265,8 @@ where \fImyconfig.txt\fP contains the following text: - .nf - [DEFAULT] - pki_admin_password=\fISecret123\fP -+pki_admin_keysize=nistp256 -+pki_admin_key_type=ecc - pki_client_pkcs12_password=\fISecret123\fP - pki_ds_password=\fISecret123\fP - pki_ssl_server_key_algorithm=SHA256withEC -@@ -286,7 +288,7 @@ pki_ocsp_signing_signing_algorithm=SHA256withEC - .fi - - .PP --In order to utilize ECC, the SSL Server and Subsystem key algorithm, key size, and key type should be changed from SHA256withRSA --> SHA256withEC, 2048 --> nistp256, and rsa --> ecc, respectively. -+In order to utilize ECC, the SSL Server and Subsystem key algorithm, key size, and key type should be changed from SHA256withRSA --> SHA256withEC, 2048 --> nistp256, and rsa --> ecc, respectively. To use an ECC admin key size and key type, the values should also be changed from 2048 --> nistp256, and rsa --> ecc. - - .PP - Additionally, for a CA subsystem, both the CA and OCSP Signing key algorithm, key size, key type, and signing algorithm should be changed from SHA256withRSA --> SHA256withEC, 2048 --> nistp256, rsa --> ecc, and SHA256withRSA --> SHA256withEC,respectively. -diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py -index b02333d..93fa384 100644 ---- a/base/server/python/pki/server/deployment/pkihelper.py -+++ b/base/server/python/pki/server/deployment/pkihelper.py -@@ -2539,7 +2539,7 @@ class Certutil: - raise - return - -- def generate_certificate_request(self, subject, key_size, -+ def generate_certificate_request(self, subject, key_type, key_size, - password_file, noise_file, - output_file=None, path=None, - ascii_format=None, token=None, -@@ -2562,8 +2562,33 @@ class Certutil: - extra=config.PKI_INDENTATION_LEVEL_2) - raise Exception(log.PKIHELPER_CERTUTIL_MISSING_SUBJECT) - -+ if key_type: -+ if key_type == "ecc": -+ command.extend(["-k", "ec"]) -+ if not key_size: -+ # supply a default curve for an 'ecc' key type -+ command.extend(["-q", "nistp256"]) -+ elif key_type == "rsa": -+ command.extend(["-k", str(key_type)]) -+ else: -+ config.pki_log.error( -+ log.PKIHELPER_CERTUTIL_INVALID_KEY_TYPE_1, -+ key_type, -+ extra=config.PKI_INDENTATION_LEVEL_2) -+ raise Exception( -+ log.PKIHELPER_CERTUTIL_INVALID_KEY_TYPE_1 % key_type) -+ else: -+ config.pki_log.error( -+ log.PKIHELPER_CERTUTIL_MISSING_KEY_TYPE, -+ extra=config.PKI_INDENTATION_LEVEL_2) -+ raise Exception(log.PKIHELPER_CERTUTIL_MISSING_KEY_TYPE) -+ - if key_size: -- command.extend(["-g", str(key_size)]) -+ if key_type == "ecc": -+ # For ECC, the key_size will actually contain the key curve -+ command.extend(["-q", str(key_size)]) -+ else: -+ command.extend(["-g", str(key_size)]) - - if noise_file: - command.extend(["-z", noise_file]) -@@ -4369,6 +4394,7 @@ class ConfigClient: - - self.deployer.certutil.generate_certificate_request( - self.mdict['pki_admin_subject_dn'], -+ self.mdict['pki_admin_key_type'], - self.mdict['pki_admin_keysize'], - self.mdict['pki_client_password_conf'], - noise_file, -diff --git a/base/server/python/pki/server/deployment/pkimessages.py b/base/server/python/pki/server/deployment/pkimessages.py -index ff3d370..cc91021 100644 ---- a/base/server/python/pki/server/deployment/pkimessages.py -+++ b/base/server/python/pki/server/deployment/pkimessages.py -@@ -171,10 +171,14 @@ IMPORTANT: - PKIHELPER_APPLY_SLOT_SUBSTITUTION_1 = \ - "applying in-place slot substitutions on '%s'" - PKIHELPER_CERTUTIL_GENERATE_CSR_1 = "executing '%s'" -+PKIHELPER_CERTUTIL_INVALID_KEY_TYPE_1 = \ -+ "certutil: Invalid key type '%s'; valid types are 'ecc' or 'rsa'!" - PKIHELPER_CERTUTIL_MISSING_INPUT_FILE = \ -- "certutil: Missing '-i input-file' option!" -+ "certutil: Missing '-i input-file' option!" - PKIHELPER_CERTUTIL_MISSING_ISSUER_NAME = \ - "certutil: Missing '-c issuer-name' option!" -+PKIHELPER_CERTUTIL_MISSING_KEY_TYPE = \ -+ "certutil: Missing '-k key-type-or-id' option (must be 'ecc' or 'rsa')!" - PKIHELPER_CERTUTIL_MISSING_NICKNAME = \ - "certutil: Missing '-n nickname' option!" - PKIHELPER_CERTUTIL_MISSING_NOISE_FILE = \ diff --git a/pki-core-Fix-Firefox-Warning.patch b/pki-core-Fix-Firefox-Warning.patch deleted file mode 100644 index 442a81b..0000000 --- a/pki-core-Fix-Firefox-Warning.patch +++ /dev/null @@ -1,81 +0,0 @@ -commit e1eb261b467f6e19c7e6604fc7ecb03e8b1f8166 -Author: Jack Magne -Date: Fri Jul 31 13:55:07 2015 -0700 - - Firefox warning - - Ticket #1523 - - Move the dire warning about the crypto object to sections where it applies. - - Also slightly changed the message due to context. - -diff --git a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template -index 5075962..2c01b9a 100644 ---- a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template -+++ b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template -@@ -56,6 +56,11 @@ function getKeyStrengthTableForKeyGen() { - - } - -+function getNoCryptoWarning() { -+ document.write('

Warning: This version of Firefox no longer supports the crypto web object used to generate and archive keys from the browser. As a result expect limited functionality in this area.

'); -+ document.write('
'); -+} -+ - function getKeyTypesOptionsForKeyGen() { - var keyTypesDef = "RSA"; - var keyTypes = null; -@@ -748,6 +753,7 @@ for (var m = 0; m < inputPluginListSet.length; m++) { - document.writeln(''); - } else { - -+ getNoCryptoWarning(); - getKeyStrengthTableForKeyGen(); - - var keyTypesOptions = getKeyTypesOptionsForKeyGen(); -@@ -770,6 +776,7 @@ for (var m = 0; m < inputPluginListSet.length; m++) { - } else if (typeof(crypto) != "undefined" && typeof(crypto.version) != "undefined") { - document.writeln('crmf'); - } else { -+ getNoCryptoWarning(); - document.writeln('Not Supported'); - } - } else if ((inputListSet[n].inputSyntax == 'keygen_request_type') || -diff --git a/base/ca/shared/webapps/ca/services.template b/base/ca/shared/webapps/ca/services.template -index 0ccbd1c..0e314b2 100644 ---- a/base/ca/shared/webapps/ca/services.template -+++ b/base/ca/shared/webapps/ca/services.template -@@ -101,12 +101,6 @@ Certificate System CA Services Page - - -- -- -
- -
diff --git a/pki-core-Fix-Missing-Cert-Request-Hostname-Address.patch b/pki-core-Fix-Missing-Cert-Request-Hostname-Address.patch deleted file mode 100644 index 670f17b..0000000 --- a/pki-core-Fix-Missing-Cert-Request-Hostname-Address.patch +++ /dev/null @@ -1,329 +0,0 @@ -commit fec55e3cfa8c0917ef63f3d6289fe3788f80bf33 -Author: Endi S. Dewata -Date: Wed Aug 5 19:10:19 2015 +0200 - - Fixed missing cert request hostname and address. - - The CA services have been modified to inject request hostname and - address into the certificate request object such that they will be - stored in the database. This fixes the problem with requests - submitted either via the UI or the CLI. - - An unused method in CertRequestResource has been removed. Some - debug messages have been cleaned as well. - - https://fedorahosted.org/pki/ticket/1535 - -diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java -index a11cb47..95f1f4c 100644 ---- a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java -+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java -@@ -27,7 +27,6 @@ import javax.servlet.http.HttpServletRequest; - import javax.ws.rs.PathParam; - import javax.ws.rs.core.Context; - import javax.ws.rs.core.HttpHeaders; --import javax.ws.rs.core.MultivaluedMap; - import javax.ws.rs.core.Request; - import javax.ws.rs.core.Response; - import javax.ws.rs.core.UriInfo; -@@ -113,13 +112,6 @@ public class CertRequestService extends PKIService implements CertRequestResourc - return createOKResponse(info); - } - -- // Enrollment - used to test integration with a browser -- @Override -- public Response enrollCert(MultivaluedMap form) { -- CertEnrollmentRequest data = new CertEnrollmentRequest(form); -- return enrollCert(data); -- } -- - @Override - public Response enrollCert(CertEnrollmentRequest data) { - -@@ -128,6 +120,9 @@ public class CertRequestService extends PKIService implements CertRequestResourc - throw new BadRequestException("Unable to create enrollment reequest: Invalid input data"); - } - -+ data.setRemoteHost(servletRequest.getRemoteHost()); -+ data.setRemoteAddr(servletRequest.getRemoteAddr()); -+ - CertRequestDAO dao = new CertRequestDAO(); - - CertRequestInfos infos; -@@ -143,10 +138,10 @@ public class CertRequestService extends PKIService implements CertRequestResourc - CMS.debug("enrollCert: bad request data: " + e); - throw new BadRequestException(e.toString()); - } catch (EBaseException e) { -- throw new PKIException(e.toString()); -+ throw new PKIException(e); - } catch (Exception e) { - CMS.debug(e); -- throw new PKIException(e.toString()); -+ throw new PKIException(e); - } - - // this will return an error code of 200, instead of 201 -diff --git a/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java b/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java -index 72aad33..d55b5b4 100644 ---- a/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java -+++ b/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java -@@ -275,6 +275,14 @@ public class CertEnrollmentRequest { - return sw.toString(); - } - -+ public String toString() { -+ try { -+ return toXML(); -+ } catch (JAXBException e) { -+ throw new RuntimeException(e); -+ } -+ } -+ - @Override - public int hashCode() { - final int prime = 31; -diff --git a/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java b/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java -index b9ae1f1..7f08b4a 100644 ---- a/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java -+++ b/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java -@@ -17,14 +17,11 @@ - // --- END COPYRIGHT BLOCK --- - package com.netscape.certsrv.cert; - --import javax.ws.rs.Consumes; - import javax.ws.rs.GET; - import javax.ws.rs.POST; - import javax.ws.rs.Path; - import javax.ws.rs.PathParam; - import javax.ws.rs.QueryParam; --import javax.ws.rs.core.MediaType; --import javax.ws.rs.core.MultivaluedMap; - import javax.ws.rs.core.Response; - - import org.jboss.resteasy.annotations.ClientResponseType; -@@ -37,13 +34,6 @@ import com.netscape.certsrv.request.RequestId; - @Path("") - public interface CertRequestResource { - -- // Enrollment - used to test integration with a browser -- @POST -- @Path("certrequests") -- @ClientResponseType(entityType=CertRequestInfos.class) -- @Consumes({ MediaType.APPLICATION_FORM_URLENCODED }) -- public Response enrollCert(MultivaluedMap form); -- - @POST - @Path("certrequests") - @ClientResponseType(entityType=CertRequestInfos.class) -diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java -index 7a26e8e..d74a285 100644 ---- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java -+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertEnrollmentRequestFactory.java -@@ -20,6 +20,8 @@ package com.netscape.cms.servlet.cert; - import java.util.Enumeration; - import java.util.Locale; - -+import javax.servlet.http.HttpServletRequest; -+ - import com.netscape.certsrv.base.IArgBlock; - import com.netscape.certsrv.cert.CertEnrollmentRequest; - import com.netscape.certsrv.profile.EProfileException; -@@ -35,18 +37,22 @@ public class CertEnrollmentRequestFactory { - throws EProfileException { - IArgBlock params = cmsReq.getHttpParams(); - -- CertEnrollmentRequest ret = new CertEnrollmentRequest(); -- ret.setProfileId(profile.getId()); -+ CertEnrollmentRequest request = new CertEnrollmentRequest(); -+ request.setProfileId(profile.getId()); - - // populate profile inputs - Enumeration inputIds = profile.getProfileInputIds(); - while (inputIds.hasMoreElements()) { - IProfileInput input = profile.getProfileInput(inputIds.nextElement()); - ProfileInput addInput = ProfileInputFactory.create(input, params, locale); -- ret.addInput(addInput); -+ request.addInput(addInput); - } - -- return ret; -+ HttpServletRequest httpRequest = cmsReq.getHttpReq(); -+ request.setRemoteHost(httpRequest.getRemoteHost()); -+ request.setRemoteAddr(httpRequest.getRemoteAddr()); -+ -+ return request; - } - - } -diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java -index 4cd54a2..f1a147e 100644 ---- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java -+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java -@@ -172,13 +172,14 @@ public class CertProcessor extends CAProcessor { - auditRequesterID = auditRequesterID(req); - - // print request debug -+ CMS.debug("CertProcessor: Request:"); - if (req != null) { - Enumeration reqKeys = req.getExtDataKeys(); - while (reqKeys.hasMoreElements()) { - String reqKey = reqKeys.nextElement(); - String reqVal = req.getExtDataInString(reqKey); - if (reqVal != null) { -- CMS.debug("CertRequestSubmitter: key=$request." + reqKey + "$ value=" + reqVal); -+ CMS.debug("CertProcessor: - " + reqKey + ": " + reqVal); - } - } - } -@@ -213,7 +214,7 @@ public class CertProcessor extends CAProcessor { - notify.notify(req); - } - -- CMS.debug("CertRequestSubmitter: submit " + e.toString()); -+ CMS.debug("CertProcessor: submit " + e); - errorCode = "2"; - errorReason = CMS.getUserMessage(locale, "CMS_PROFILE_DEFERRED", e.toString()); - -@@ -223,7 +224,7 @@ public class CertProcessor extends CAProcessor { - } catch (ERejectException e) { - // return error to the user - req.setRequestStatus(RequestStatus.REJECTED); -- CMS.debug("CertRequestSubmitter: submit " + e.toString()); -+ CMS.debug("CertProcessor: submit " + e); - errorCode = "3"; - errorReason = CMS.getUserMessage(locale, "CMS_PROFILE_REJECTED", e.toString()); - -@@ -239,8 +240,8 @@ public class CertProcessor extends CAProcessor { - audit(auditMessage); - } catch (Throwable e) { - // return error to the user -- e.printStackTrace(); -- CMS.debug("CertRequestSubmitter: submit " + e.toString()); -+ CMS.debug(e); -+ CMS.debug("CertProcessor: submit " + e); - errorCode = "1"; - errorReason = CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"); - auditMessage = CMS.getLogMessage( -@@ -261,8 +262,8 @@ public class CertProcessor extends CAProcessor { - profile.getRequestQueue().updateRequest(req); - } - } catch (EBaseException e) { -- e.printStackTrace(); -- CMS.debug("CertRequestSubmitter: updateRequest " + e.toString()); -+ CMS.debug(e); -+ CMS.debug("CertProcessor: updateRequest " + e); - } - } - return errorCode; -@@ -312,7 +313,7 @@ public class CertProcessor extends CAProcessor { - } - - if (fromRA) { -- CMS.debug("CertRequestSubmitter: request from RA: " + uid); -+ CMS.debug("CertProcessor: request from RA: " + uid); - req.setExtData(ARG_REQUEST_OWNER, uid); - } - -@@ -326,18 +327,18 @@ public class CertProcessor extends CAProcessor { - - if (setId == null) { - // no profile set found -- CMS.debug("CertRequestSubmitter: no profile policy set found"); -+ CMS.debug("CertProcessor: no profile policy set found"); - throw new EBaseException(CMS.getUserMessage(locale, "CMS_PROFILE_NO_POLICY_SET_FOUND")); - } - -- CMS.debug("CertRequestSubmitter profileSetid=" + setId); -+ CMS.debug("CertProcessor: profileSetid=" + setId); - req.setExtData(ARG_PROFILE_SET_ID, setId); - req.setExtData(ARG_PROFILE_REMOTE_HOST, data.getRemoteHost()); - req.setExtData(ARG_PROFILE_REMOTE_ADDR, data.getRemoteAddr()); - -- CMS.debug("CertRequestSubmitter: request " + req.getRequestId().toString()); -+ CMS.debug("CertProcessor: request " + req.getRequestId()); - -- CMS.debug("CertRequestSubmitter: populating request inputs"); -+ CMS.debug("CertProcessor: populating request inputs"); - // give authenticator a chance to populate the request - if (authenticator != null) { - authenticator.populate(authToken, req); -diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java -index 8d9d05c..960f997 100644 ---- a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java -+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java -@@ -127,13 +127,13 @@ public class EnrollmentProcessor extends CertProcessor { - printParameterValues(params); - } - -- CMS.debug("EnrollmentSubmitter: isRenewal false"); -+ CMS.debug("EnrollmentProcessor: isRenewal false"); - startTiming("enrollment"); - - // if we did not configure profileId in xml file, - // then accept the user-provided one - String profileId = (this.profileID == null) ? data.getProfileId() : this.profileID; -- CMS.debug("EnrollmentSubmitter: profileId " + profileId); -+ CMS.debug("EnrollmentProcessor: profileId " + profileId); - - IProfile profile = ps.getProfile(profileId); - if (profile == null) { -@@ -141,17 +141,17 @@ public class EnrollmentProcessor extends CertProcessor { - throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", CMSTemplate.escapeJavaScriptStringHTML(profileId))); - } - if (!ps.isProfileEnable(profileId)) { -- CMS.debug("EnrollmentSubmitter: Profile " + profileId + " not enabled"); -+ CMS.debug("EnrollmentProcessor: Profile " + profileId + " not enabled"); - throw new BadRequestDataException("Profile " + profileId + " not enabled"); - } - - IProfileContext ctx = profile.createContext(); -- CMS.debug("EnrollmentSubmitter: set Inputs into profile Context"); -+ CMS.debug("EnrollmentProcessor: set Inputs into profile Context"); - setInputsIntoContext(data, profile, ctx); - - IProfileAuthenticator authenticator = profile.getAuthenticator(); - if (authenticator != null) { -- CMS.debug("EnrollmentSubmitter: authenticator " + authenticator.getName() + " found"); -+ CMS.debug("EnrollmentProcessor: authenticator " + authenticator.getName() + " found"); - setCredentialsIntoContext(request, authenticator, ctx); - } - -@@ -160,7 +160,7 @@ public class EnrollmentProcessor extends CertProcessor { - SessionContext context = SessionContext.getContext(); - context.put("profileContext", ctx); - context.put("sslClientCertProvider", new SSLClientCertProvider(request)); -- CMS.debug("EnrollmentSubmitter: set sslClientCertProvider"); -+ CMS.debug("EnrollmentProcessor: set sslClientCertProvider"); - - // before creating the request, authenticate the request - IAuthToken authToken = authenticate(request, null, authenticator, context, false); -diff --git a/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java -index 28b1b51..b9af84b 100644 ---- a/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java -+++ b/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java -@@ -257,7 +257,8 @@ public class CAProcessor extends Processor { - } - - protected void printParameterValues(HashMap data) { -- CMS.debug("Start of CertProcessor Input Parameters"); -+ -+ CMS.debug("CAProcessor: Input Parameters:"); - - for (Entry entry : data.entrySet()) { - String paramName = entry.getKey(); -@@ -280,13 +281,11 @@ public class CAProcessor extends Processor { - paramName.equalsIgnoreCase("pwd") || - paramName.equalsIgnoreCase("pwdagain") || - paramName.equalsIgnoreCase("uPasswd")) { -- CMS.debug("CertProcessor Input Parameter " + paramName + "='(sensitive)'"); -+ CMS.debug("CAProcessor: - " + paramName + ": (sensitive)"); - } else { -- CMS.debug("CertProcessor Input Parameter " + paramName + "='" + entry.getValue() + "'"); -+ CMS.debug("CAProcessor: - " + paramName + ": " + entry.getValue()); - } - } -- -- CMS.debug("End of CertProcessor Input Parameters"); - } - - /** diff --git a/pki-core-Fix-Pin-Reset-Operation.patch b/pki-core-Fix-Pin-Reset-Operation.patch deleted file mode 100644 index 215dd10..0000000 --- a/pki-core-Fix-Pin-Reset-Operation.patch +++ /dev/null @@ -1,39 +0,0 @@ -commit a8c1bd3da0dc6b14b29b69f7bfde4b74408a0e5a -Author: Jack Magne -Date: Tue Jul 28 15:29:35 2015 -0700 - - TPS UI: After successful key upgrade during pin reset operation the token db still shows old key - - Simple matter of not updating the token record at the end of the pin reset operation. - Also, make sure the activity log is correct. - - (cherry picked from commit e50a3d55017da97abb5296218422b4144c8ca990) - -diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSPinResetProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSPinResetProcessor.java -index 3494ca6..3a6c0df 100644 ---- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSPinResetProcessor.java -+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSPinResetProcessor.java -@@ -144,8 +144,23 @@ public class TPSPinResetProcessor extends TPSProcessor { - - checkAndHandlePinReset(channel); - -+ try { -+ tps.tdb.tdbUpdateTokenEntry(tokenRecord); -+ CMS.debug(method + ": token record updated!"); -+ } catch (Exception e) { -+ String failMsg = "update token failure"; -+ auditMsg = failMsg + ":" + e.toString(); -+ tps.tdb.tdbActivity(ActivityDatabase.OP_PIN_RESET, tokenRecord, session.getIpAddress(), auditMsg, -+ "failure"); -+ throw new TPSException(auditMsg); -+ } -+ - statusUpdate(100, "PROGRESS_PIN_RESET_COMPLETE"); - -+ auditMsg = "pin reset operation completed successfully"; -+ tps.tdb.tdbActivity(ActivityDatabase.OP_PIN_RESET, tokenRecord, session.getIpAddress(), auditMsg, -+ "success"); -+ - CMS.debug(method + ": Token Pin successfully reset!"); - - } diff --git a/pki-core-Fix-SC650-Token-Format-Enroll.patch b/pki-core-Fix-SC650-Token-Format-Enroll.patch deleted file mode 100644 index f26f874..0000000 --- a/pki-core-Fix-SC650-Token-Format-Enroll.patch +++ /dev/null @@ -1,36 +0,0 @@ -commit d4534d2326526bab910e7bd1babe0f91d11bcad9 -Author: Jack Magne -Date: Mon Aug 24 11:23:04 2015 -0700 - - SC650 format/enroll fails - - Simple fix to correctly identify scp01/gp201 sc650 card. - - (cherry picked from commit 3158e1279b210d9f409918b24180bf20b0774614) - -diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java -index 14e8ead..637cfa3 100644 ---- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java -+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java -@@ -3402,10 +3402,20 @@ public class TPSProcessor { - byte protocol = oidSecureChannelProtocol.at(length - 2); - byte implementation = oidSecureChannelProtocol.at(length - 1); - -+ if (protocol == SecureChannel.SECURE_PROTO_03) { -+ throw new TPSException("TPSProcessor.gp211GetSecureChannelProtocolDetails: No support for SCP03 as of yet, bailing.", -+ TPSStatus.STATUS_ERROR_SECURE_CHANNEL); -+ } -+ - platProtInfo.setProtocol(protocol); - platProtInfo.setImplementation(implementation); - platProtInfo.setKeysetInfoData(keyData); -- platProtInfo.setPlatform(SecureChannel.GP211); -+ -+ if (protocol == SecureChannel.SECURE_PROTO_02) -+ platProtInfo.setPlatform(SecureChannel.GP211); -+ else -+ platProtInfo.setPlatform(SecureChannel.GP201); -+ - - CMS.debug("TPSProcessor.gp211GetSecureChannelProtocolDetails: protocol: " + protocol + " implementation: " - + implementation + " keyInfoData: " + keyData.toHexString()); diff --git a/pki-core-Fix-SerialNumberUpdateTask-conditional.patch b/pki-core-Fix-SerialNumberUpdateTask-conditional.patch deleted file mode 100644 index 8025932..0000000 --- a/pki-core-Fix-SerialNumberUpdateTask-conditional.patch +++ /dev/null @@ -1,21 +0,0 @@ -commit de2c76f989adcf79b083c7f324c1b9b68571f83a -Author: Ade Lee -Date: Wed Aug 12 14:13:37 2015 -0400 - - One-liner fix to conditional for new SerialNumberUpdateTask - -diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java -index 96ae43e..f22beeb 100644 ---- a/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java -+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java -@@ -630,8 +630,8 @@ public class CertificateRepository extends Repository - serialNumberUpdateTask.stop(); - } - -- if (interval == 0) { -- CMS.debug("In setSerialNumberUpdateInterval interval = 0"); -+ if (interval <= 0) { -+ CMS.debug("In setSerialNumberUpdateInterval interval <= 0"); - return; - } - diff --git a/pki-core-Fix-TLS-ciphers-on-non-CA-HSMs.patch b/pki-core-Fix-TLS-ciphers-on-non-CA-HSMs.patch deleted file mode 100644 index 08e144e..0000000 --- a/pki-core-Fix-TLS-ciphers-on-non-CA-HSMs.patch +++ /dev/null @@ -1,116 +0,0 @@ -commit 89211b9915e9c3e034d311ac0fa7091e9e08bde8 -Author: Christina Fu -Date: Wed Aug 19 13:52:53 2015 +0200 - - Ticket 1566 on HSM, non-CA subystem installations failing while trying to join security domain Investigation shows that this issue occurs when the non-CA subsystem's SSL server and client keys are also on the HSM. While browsers (on soft token) have no issue connecting to any of the subsystems on HSM, subsystem to subsystem communication has issues when the TLS_ECDHE_RSA_* ciphers are turned on. We have decided to turn off the TLS_ECDHE_RSA_* ciphers by default (can be manually turned on if desired) based on the fact that: 1. The tested HSM seems to have issue with them (will still continue to investigate) 2. While the Perfect Forward Secrecy provides added security by the TLS_ECDHE_RSA_* ciphers, each SSL session takes 3 times longer to estabish. 3. The TLS_RSA_* ciphers are adequate at this time for the CS system operations - -diff --git a/base/server/python/pki/server/deployment/pkiparser.py b/base/server/python/pki/server/deployment/pkiparser.py -index 259e248..09619d5 100644 ---- a/base/server/python/pki/server/deployment/pkiparser.py -+++ b/base/server/python/pki/server/deployment/pkiparser.py -@@ -947,7 +947,7 @@ class PKIConfigParser: - "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_RSA_WITH_AES_128_CBC_SHA," + \ -- "-TLS_RSA_WITH_AES_256_CBC_SHA," + \ -+ "+TLS_RSA_WITH_AES_256_CBC_SHA," + \ - "+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \ - "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \ - "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -@@ -963,13 +963,13 @@ class PKIConfigParser: - "-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + \ - "-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \ - "-TLS_RSA_WITH_AES_128_CBC_SHA256," + \ -- "-TLS_RSA_WITH_AES_256_CBC_SHA256," + \ -+ "+TLS_RSA_WITH_AES_256_CBC_SHA256," + \ - "-TLS_RSA_WITH_AES_128_GCM_SHA256," + \ - "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + \ - "+TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + \ -- "+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" -+ "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ -+ "-TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" - else: - self.mdict['TOMCAT_SSL_RANGE_CIPHERS_SLOT'] = \ - "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \ -@@ -983,9 +983,9 @@ class PKIConfigParser: - "-TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -+ "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \ -+ "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_AES_256_CBC_SHA," + \ -@@ -997,9 +997,9 @@ class PKIConfigParser: - "-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \ - "-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + \ - "-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ -+ "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ - "-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \ -+ "-TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \ - "-TLS_RSA_WITH_AES_128_CBC_SHA256," + \ - "-TLS_RSA_WITH_AES_256_CBC_SHA256," + \ - "-TLS_RSA_WITH_AES_128_GCM_SHA256," + \ -diff --git a/base/server/share/conf/ciphers.info b/base/server/share/conf/ciphers.info -index 998c51e..69aaeaa 100644 ---- a/base/server/share/conf/ciphers.info -+++ b/base/server/share/conf/ciphers.info -@@ -27,10 +27,20 @@ - # TLS_RSA_WITH_AES_128_CBC_SHA256, - # TLS_RSA_WITH_AES_256_CBC_SHA256, - # TLS_RSA_WITH_AES_128_GCM_SHA256, --# TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - # TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, --# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - # TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -+# The TLS_ECDHE_RSA_* ciphers provide Perfect Forward Secrecy, -+# which, while provide added security to the already secure and adequate -+# TLS_RSA_* ciphers, requries 3 times longer to establish SSL sessions. -+# In our testing environment, some HSM might also have issues providing -+# subsystem->subsystem SSL handshake. We are therefore turning them -+# off by default. One can enable them manually by turning the "-" to -+# "+" under sslRangeCiphers and restart the subsystem. -+# TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, -+# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, -+# TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, -+# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, -+# TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - # The following ciphers are supported in rhel7.2 or greater, and they - # are off by default, and can be turned on by sites running rhel7.2 or - # greater: -@@ -45,22 +55,20 @@ - # TLS_RSA_WITH_3DES_EDE_CBC_SHA, - # TLS_RSA_WITH_AES_128_CBC_SHA, - # TLS_RSA_WITH_AES_256_CBC_SHA, --# TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - # Note: In an EC CS server setup, you will see by default that the - # following RSA ciphers are left on. Those are used for installation - # where the actual systems certs have not yet been crated, and a - # temporary RSA ssl server cert is at play. - # Those can be turned off manually by sites. --# TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, --# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, --# TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -+# TLS_RSA_WITH_AES_256_CBC_SHA256, -+# TLS_RSA_WITH_AES_128_GCM_SHA256 - # These ciphers might be removed by the installation script in some - # future release. - # - ## - # For RSA servers: -- sslRangeCiphers="-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,+TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_RSA_WITH_AES_128_CBC_SHA256,-TLS_RSA_WITH_AES_256_CBC_SHA256,-TLS_RSA_WITH_AES_128_GCM_SHA256,+TLS_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_RSA_WITH_AES_128_CBC_SHA,+TLS_RSA_WITH_AES_256_CBC_SHA" -+ sslRangeCiphers="-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_RSA_WITH_AES_128_CBC_SHA256,-TLS_RSA_WITH_AES_256_CBC_SHA256,-TLS_RSA_WITH_AES_128_GCM_SHA256,+TLS_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_RSA_WITH_AES_128_CBC_SHA,+TLS_RSA_WITH_AES_256_CBC_SHA" - # - # - # For ECC servers: -- sslRangeCiphers="-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_RSA_WITH_AES_128_CBC_SHA,-TLS_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_AES_256_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_RSA_WITH_AES_128_CBC_SHA256,-TLS_RSA_WITH_AES_256_CBC_SHA256,-TLS_RSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" -+ sslRangeCiphers="-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_RSA_WITH_AES_128_CBC_SHA,+TLS_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_AES_256_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_RSA_WITH_AES_128_CBC_SHA256,+TLS_RSA_WITH_AES_256_CBC_SHA256,-TLS_RSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" diff --git a/pki-core-Fix-admin-profiles-for-ECC-cert-reqs.patch b/pki-core-Fix-admin-profiles-for-ECC-cert-reqs.patch deleted file mode 100644 index 4336ae3..0000000 --- a/pki-core-Fix-admin-profiles-for-ECC-cert-reqs.patch +++ /dev/null @@ -1,39 +0,0 @@ -commit 017f4f9d4b3c6051f082b8c2b49d5143fd8450e9 -Author: Christina Fu -Date: Mon Aug 10 15:38:06 2015 -0700 - - Ticket 1539 Unable to create ECC KRA Instance when kra admin key type is ECC - This patch changes the relevant CA enrollment admin profiles so that they accept - requests for EC certs. The issue actually not just affected KRA, it also affected - other non-CA subsystems. - -diff --git a/base/ca/shared/profiles/ca/AdminCert.cfg b/base/ca/shared/profiles/ca/AdminCert.cfg -index a54a1b7..526d05d 100644 ---- a/base/ca/shared/profiles/ca/AdminCert.cfg -+++ b/base/ca/shared/profiles/ca/AdminCert.cfg -@@ -30,8 +30,8 @@ policyset.adminCertSet.2.default.params.range=365 - policyset.adminCertSet.2.default.params.startTime=0 - policyset.adminCertSet.3.constraint.class_id=keyConstraintImpl - policyset.adminCertSet.3.constraint.name=Key Constraint --policyset.adminCertSet.3.constraint.params.keyType=RSA --policyset.adminCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096 -+policyset.adminCertSet.3.constraint.params.keyType=- -+policyset.adminCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp384,nistp521 - policyset.adminCertSet.3.default.class_id=userKeyDefaultImpl - policyset.adminCertSet.3.default.name=Key Default - policyset.adminCertSet.4.constraint.class_id=noConstraintImpl -diff --git a/base/ca/shared/profiles/ca/caAdminCert.cfg b/base/ca/shared/profiles/ca/caAdminCert.cfg -index cd29703..f779edb 100644 ---- a/base/ca/shared/profiles/ca/caAdminCert.cfg -+++ b/base/ca/shared/profiles/ca/caAdminCert.cfg -@@ -31,8 +31,8 @@ policyset.adminCertSet.2.default.params.range=365 - policyset.adminCertSet.2.default.params.startTime=0 - policyset.adminCertSet.3.constraint.class_id=keyConstraintImpl - policyset.adminCertSet.3.constraint.name=Key Constraint --policyset.adminCertSet.3.constraint.params.keyType=RSA --policyset.adminCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096 -+policyset.adminCertSet.3.constraint.params.keyType=- -+policyset.adminCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp384,nistp521 - policyset.adminCertSet.3.default.class_id=userKeyDefaultImpl - policyset.adminCertSet.3.default.name=Key Default - policyset.adminCertSet.4.constraint.class_id=noConstraintImpl diff --git a/pki-core-Fix-missing-query-parms-in-ListCerts-page.patch b/pki-core-Fix-missing-query-parms-in-ListCerts-page.patch deleted file mode 100644 index 7aafa30..0000000 --- a/pki-core-Fix-missing-query-parms-in-ListCerts-page.patch +++ /dev/null @@ -1,204 +0,0 @@ -commit 24d7d88bd0d8b79fe5b8b6dfd84238399bc1433c -Author: Endi S. Dewata -Date: Wed Aug 12 18:59:57 2015 +0200 - - Fixed missing query parameters in ListCerts page. - - The ListCerts servlet and the templates have been fixed to pass - the skipRevoked and skipNonValid parameters to the subsequent page. - - Some debugging messages have been cleaned up as well. - - https://fedorahosted.org/pki/ticket/1538 - -diff --git a/base/ca/shared/webapps/ca/agent/ca/queryCert.template b/base/ca/shared/webapps/ca/agent/ca/queryCert.template -index 40ee64b..0a42382 100644 ---- a/base/ca/shared/webapps/ca/agent/ca/queryCert.template -+++ b/base/ca/shared/webapps/ca/agent/ca/queryCert.template -@@ -474,6 +474,10 @@ document.write( - result.header.totalRecordCount+ "'>\n"+ - "\n"+ -+"\n"+ -+"\n"+ - "\n"+ - "\n"+ - "\n"+ -+"\n"+ -+"\n"+ - "\n"+ - " mMaxReturns) { -- com.netscape.certsrv.apps.CMS.debug("Resetting page size from " + maxCount + " to " + mMaxReturns); -+ CMS.debug("ListCerts: Resetting page size from " + maxCount + " to " + mMaxReturns); - maxCount = mMaxReturns; - } - -@@ -303,7 +295,7 @@ public class ListCerts extends CMSServlet { - return; - } - -- com.netscape.certsrv.apps.CMS.debug("queryCertFilter=" + queryCertFilter); -+ CMS.debug("ListCerts: queryCertFilter: " + queryCertFilter); - - int totalRecordCount = -1; - -@@ -311,18 +303,18 @@ public class ListCerts extends CMSServlet { - totalRecordCount = Integer.parseInt(req.getParameter("totalRecordCount")); - } catch (Exception e) { - } -+ - processCertFilter(argSet, header, maxCount, - sentinel, - totalRecordCount, - req.getParameter("serialTo"), - queryCertFilter, - req, resp, revokeAll, locale[0]); -- } catch (NumberFormatException e) { -- log(ILogger.LL_FAILURE, com.netscape.certsrv.apps.CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT")); - -- error = -- new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage(getLocale(req), -- "CMS_BASE_INVALID_NUMBER_FORMAT")); -+ } catch (NumberFormatException e) { -+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_NUMBER_FORMAT")); -+ error = new EBaseException(CMS.getUserMessage(getLocale(req), -+ "CMS_BASE_INVALID_NUMBER_FORMAT"), e); - } catch (EBaseException e) { - error = e; - } -@@ -347,9 +339,9 @@ public class ListCerts extends CMSServlet { - } - } catch (IOException e) { - log(ILogger.LL_FAILURE, -- com.netscape.certsrv.apps.CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString())); -+ CMS.getLogMessage("CMSGW_ERR_OUT_STREAM_TEMPLATE", e.toString())); - throw new ECMSGWException( -- com.netscape.certsrv.apps.CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR")); -+ CMS.getUserMessage("CMS_GW_DISPLAY_TEMPLATE_ERROR"), e); - } - } - -@@ -488,9 +480,8 @@ public class ListCerts extends CMSServlet { - // even though the filter is not matched. - /*cfu - is this necessary? it breaks when paging up - if (curSerial.compareTo(sentinel) == -1) { -- com.netscape.certsrv.apps.CMS.debug("curSerial compare sentinel -1 break..."); -- -- break; -+ CMS.debug("curSerial compare sentinel -1 break..."); -+ break; - } - */ - if (!serialToVal.equals(MINUS_ONE)) { -@@ -524,8 +515,8 @@ public class ListCerts extends CMSServlet { - for (int ii = rcount - 1; ii >= 0; ii--) { - if (recs[ii] != null) { - CMS.debug("ListCerts: processing recs[" + ii + "]"); -- IArgBlock rarg = com.netscape.certsrv.apps.CMS.createArgBlock(); -- //com.netscape.certsrv.apps.CMS.debug("item "+ii+" is serial # "+ recs[ii].getSerialNumber()); -+ IArgBlock rarg = CMS.createArgBlock(); -+ // CMS.debug("item " + ii + " is serial #" + recs[ii].getSerialNumber()); - fillRecordIntoArg(recs[ii], rarg); - argSet.addRepeatRecord(rarg); - } -@@ -555,6 +546,13 @@ public class ListCerts extends CMSServlet { - - header.addStringValue("serviceURL", req.getRequestURI()); - header.addStringValue("queryCertFilter", filter); -+ -+ String skipRevoked = req.getParameter("skipRevoked"); -+ header.addStringValue("skipRevoked", skipRevoked == null ? "" : skipRevoked); -+ -+ String skipNonValid = req.getParameter("skipNonValid"); -+ header.addStringValue("skipNonValid", skipNonValid == null ? "" : skipNonValid); -+ - header.addStringValue("templateName", "queryCert"); - header.addStringValue("queryFilter", filter); - header.addIntegerValue("maxCount", maxCount); diff --git a/pki-core-Fix-pylint-errors-on-F24.patch b/pki-core-Fix-pylint-errors-on-F24.patch deleted file mode 100644 index 834cc83..0000000 --- a/pki-core-Fix-pylint-errors-on-F24.patch +++ /dev/null @@ -1,69 +0,0 @@ -From b18e9c1aec5860dd4cf10986e250e47ec6cb7b5b Mon Sep 17 00:00:00 2001 -From: Matthew Harmsen -Date: Wed, 16 Dec 2015 12:24:55 -0700 -Subject: [PATCH] Fix pylint errors on F24. - ---- - base/common/python/pki/cert.py | 3 ++- - base/common/python/pki/systemcert.py | 6 ++++-- - base/server/python/pki/server/deployment/pkihelper.py | 5 +++-- - 3 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/base/common/python/pki/cert.py b/base/common/python/pki/cert.py -index 01d2a61..23179af 100644 ---- a/base/common/python/pki/cert.py -+++ b/base/common/python/pki/cert.py -@@ -585,6 +585,7 @@ class CertReviewResponse(CertEnrollmentRequest): - else: - self.policy_sets = policy_sets - -+ # pylint: disable=E1101 - @classmethod - def from_json(cls, attr_list): - -@@ -1202,4 +1203,4 @@ def main(): - - - if __name__ == "__main__": -- main() -\ No newline at end of file -+ main() -diff --git a/base/common/python/pki/systemcert.py b/base/common/python/pki/systemcert.py -index d59e07b..6ca9097 100644 ---- a/base/common/python/pki/systemcert.py -+++ b/base/common/python/pki/systemcert.py -@@ -52,8 +52,10 @@ class SystemCertClient(object): - response = self.connection.get(url, self.headers) - cert_data = CertData.from_json(response.json()) - -+ # pylint: disable=E1136 - pem = cert_data.encoded -- b64 = pem[len(pki.CERT_HEADER):len(pem) - len(pki.CERT_FOOTER)] -- cert_data.binary = base64.decodestring(b64) -+ if pem is not None: -+ b64 = pem[len(pki.CERT_HEADER):len(pem) - len(pki.CERT_FOOTER)] -+ cert_data.binary = base64.decodestring(b64) - - return cert_data -diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py -index b6ee61b..2b2aabf 100644 ---- a/base/server/python/pki/server/deployment/pkihelper.py -+++ b/base/server/python/pki/server/deployment/pkihelper.py -@@ -3868,11 +3868,12 @@ class ConfigClient: - extra=config.PKI_INDENTATION_LEVEL_2) - - if hasattr(e, 'response'): -+ text = e.response.text # pylint: disable=E1101 - try: -- root = ET.fromstring(e.response.text) -+ root = ET.fromstring(text) - except ET.ParseError, pe: - config.pki_log.error( -- "ParseError: %s: %s " % (pe, e.response.text), -+ "ParseError: %s: %s " % (pe, text), - extra=config.PKI_INDENTATION_LEVEL_2) - raise - --- -2.5.0 - diff --git a/pki-core-Fix-setpin-utility.patch b/pki-core-Fix-setpin-utility.patch deleted file mode 100644 index 7126f28..0000000 --- a/pki-core-Fix-setpin-utility.patch +++ /dev/null @@ -1,229 +0,0 @@ -commit f60846e025ff5492e8c05ccf525fe8df1b59bba6 -Author: Jack Magne -Date: Tue Aug 11 18:26:04 2015 -0700 - - setpin utility doesn't set the pin for users. - - There were some things wrong with the setpin utility. - - 1. There were some syntax violations that had to be dealt with or a DS with syntax checking - would not be pleased. - - 2. The back end is expecting a byte of hash data at the beginning of the pin. - In our case we are sending NO hash so we want this code at the beginning '-' - - 3. We also need to prepend the dn in front of the pin so the back end can verify the set pin. - - Tested to work during both steps of the setpin process: 1) Creating the schema, 2) creating the pin. - Tested to work with actual PinBased Enrollment. - - 4. Fix also now supports the SHA256 hashing method only, with the sha256 being the default hash. - The no hash option is supported but puts the pin in the clear. - -diff --git a/base/native-tools/src/setpin/setpin.c b/base/native-tools/src/setpin/setpin.c -index f1bf6a8..a164719 100644 ---- a/base/native-tools/src/setpin/setpin.c -+++ b/base/native-tools/src/setpin/setpin.c -@@ -87,7 +87,7 @@ void testpingen(); - void do_setup(); - - --char *sha1_pw_enc( char *pwd ); -+char *sha256_pw_enc( char *pwd ); - - int errcode=0; - -@@ -375,7 +375,7 @@ void do_setup() { - doLDAPBind(); - - if (o_schemachange) { -- sprintf(x_values[0],"( %s-oid NAME '%s' DESC 'User Defined Attribute' SYNTAX '1.3.6.1.4.1.1466.115.121.1.5' SINGLE-VALUE )", -+ sprintf(x_values[0],"( %s-oid NAME '%s' DESC 'User Defined Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE X-ORIGIN 'custom for setpin' )", - o_attribute, - o_attribute); - -@@ -398,8 +398,8 @@ void do_setup() { - } - } - -- sprintf(x_values[0],"( %s-oid NAME '%s' DESC 'User Defined ObjectClass' SUP 'top' MUST ( objectclass ) MAY ( aci $ %s )", -- o_objectclass,o_objectclass, -+ sprintf(x_values[0],"( 2.16.840.1.117370.999.1.2.10 NAME '%s' DESC 'User Defined ObjectClass' SUP top MAY ( aci $ %s ) )", -+ o_objectclass, - o_attribute); - - fprintf(stderr,"Adding objectclass: %s\n",x_values[0]); -@@ -433,7 +433,7 @@ void do_setup() { - exitError("missing basedn argument"); - } - -- password = sha1_pw_enc( o_pinmanagerpwd ); -+ password = sha256_pw_enc( o_pinmanagerpwd ); - - fprintf(stderr,"Adding user: %s\n",o_pinmanager); - -@@ -533,23 +533,23 @@ int ldif_base64_encode( - /* - * Number of bytes each hash algorithm produces - */ --#define SHA1_LENGTH 20 -- -+#define SHA256_LENGTH 32 - - char * --sha1_pw_enc( char *pwd ) -+sha256_pw_enc( char *pwd ) - { -- unsigned char hash[ SHA1_LENGTH ]; -+ -+ unsigned char hash[ SHA256_LENGTH ]; - char *enc; - -- /* SHA1 hash the user's key */ -- PK11_HashBuf(SEC_OID_SHA1,hash,pwd,strlen(pwd)); -+ /* SHA246 hash the user's key */ -+ PK11_HashBuf(SEC_OID_SHA256,hash,pwd,strlen(pwd)); - enc = malloc(256); - -- sprintf( enc, "{SHA}"); -+ sprintf( enc, "{SHA256}"); - - (void)ldif_base64_encode( hash, enc + 5, -- SHA1_LENGTH, -1 ); -+ SHA256_LENGTH, -1 ); - - return( enc ); - } -@@ -871,24 +871,17 @@ void processSearchResults(LDAPMessage *r) { - - #define SENTINEL_SHA1 0 - #define SENTINEL_MD5 1 -+#define SENTINEL_SHA256 2 - #define SENTINEL_NONE '-' - -- if ((!strcmp(o_hash,"SHA1")) || (!strcmp(o_hash,"sha1")) ) { -- status = PK11_HashBuf(SEC_OID_SHA1, -- (unsigned char *)hashbuf_dest+1, -- (unsigned char *)hashbuf_source, -- strlen(hashbuf_source) -- ); -- hashbuf_dest[0] = SENTINEL_SHA1; -- pindatasize = SHA1_LENGTH + 1; -- } else if ((!strcmp(o_hash,"MD5")) || (!strcmp(o_hash,"md5")) ) { -- status = PK11_HashBuf(SEC_OID_MD5, -+ if ((!strcmp(o_hash,"SHA256")) || (!strcmp(o_hash,"sha256")) ) { -+ status = PK11_HashBuf(SEC_OID_SHA256, - (unsigned char *)hashbuf_dest+1, - (unsigned char *)hashbuf_source, - strlen(hashbuf_source) - ); -- hashbuf_dest[0] = SENTINEL_MD5; -- pindatasize = MD5_LENGTH + 1; -+ hashbuf_dest[0] = SENTINEL_SHA256; -+ pindatasize = SHA256_LENGTH + 1; - } else if ((!strcmp(o_hash,"NONE")) || (!strcmp(o_hash,"none")) ) { - hashbuf_dest[0] = SENTINEL_NONE; - status = SECSuccess; -@@ -897,7 +890,7 @@ void processSearchResults(LDAPMessage *r) { - strlen(hashbuf_source) - ); - } else { -- sprintf(errbuf,"Unsupported hash type '%s'. Must be one of 'sha1', 'md5' or 'none",o_hash); -+ sprintf(errbuf,"Unsupported hash type '%s'. Must be one of 'sha256', or 'none",o_hash); - errcode = 7; - exitError(errbuf); - } -@@ -907,16 +900,20 @@ void processSearchResults(LDAPMessage *r) { - errcode = 9; - exitError(errbuf); - } -- -- pindata = hashbuf_dest; -+ pindata = hashbuf_dest; - - if (hashbuf_source != NULL) { - free(hashbuf_source); - hashbuf_source = NULL; - } - } else { -- pindata = generatedPassword; -- pindatasize = strlen(generatedPassword); -+ /* Do last resort no hash version */ -+ hashbuf_dest[0] = SENTINEL_NONE; -+ memcpy(hashbuf_dest + 1, dn, strlen(dn)); -+ memcpy(hashbuf_dest + 1 + strlen(dn) ,generatedPassword, strlen(generatedPassword)); -+ -+ pindata = hashbuf_dest; -+ pindatasize = strlen(generatedPassword) + 1 + strlen(dn); - } - - bval.bv_len = pindatasize; -diff --git a/base/native-tools/src/setpin/setpin_options.c b/base/native-tools/src/setpin/setpin_options.c -index d8ee83a..d2fb54d 100644 ---- a/base/native-tools/src/setpin/setpin_options.c -+++ b/base/native-tools/src/setpin/setpin_options.c -@@ -51,7 +51,7 @@ char *valid_args[] = { - "case", "Restrict case of pins 'case=upperonly'", - "objectclass", "Objectclass of LDAP entry to operate on (default pinPerson)", - "attribute","Which LDAP attribute to write to (default pin)", -- "hash", "Hash algorithm used to store pin: 'none', 'md5' or 'sha1' (default)", -+ "hash", "Hash algorithm used to store pin: 'none', or 'sha256' (default) warning: 'none' is in the clear", - "saltattribute", "Which attribute to use for salt (default: dn)", - "input", "File to use for restricting DN's, or providing your own pins", - "output", "Redirect stdout to a file", -@@ -96,7 +96,7 @@ void setDefaultOptions() { - o_gen= "RNG-alphanum"; - o_case= NULL; - o_attribute="pin"; -- o_hash= "sha1"; -+ o_hash= "sha256"; - o_objectclass="pinPerson"; - o_output= NULL; - o_retry= "5"; -@@ -270,8 +270,7 @@ void validateOptions() { - } - - if (! -- (equals(o_hash,"sha1") || -- equals(o_hash,"md5") || -+ (equals(o_hash,"sha256") || - equals(o_hash,"none")) - ) { - snprintf(errbuf, ERR_BUF_LENGTH, "invalid hash: %s",o_hash); -diff --git a/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java b/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java -index 82331da..6caa9a1 100644 ---- a/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java -+++ b/base/server/cms/src/com/netscape/cms/authentication/UidPwdPinDirAuthentication.java -@@ -75,6 +75,7 @@ public class UidPwdPinDirAuthentication extends DirBasedAuthentication - - protected static final byte SENTINEL_SHA = 0; - protected static final byte SENTINEL_MD5 = 1; -+ protected static final byte SENTINEL_SHA256 = 2; - protected static final byte SENTINEL_NONE = 0x2d; - - /* Holds configuration parameters accepted by this implementation. -@@ -132,6 +133,7 @@ public class UidPwdPinDirAuthentication extends DirBasedAuthentication - protected String mPinAttr = DEF_PIN_ATTR; - protected MessageDigest mSHADigest = null; - protected MessageDigest mMD5Digest = null; -+ protected MessageDigest mSHA256Digest = null; - - private ILdapConnFactory removePinLdapFactory = null; - private LDAPConnection removePinLdapConnection = null; -@@ -165,6 +167,7 @@ public class UidPwdPinDirAuthentication extends DirBasedAuthentication - try { - mSHADigest = MessageDigest.getInstance("SHA1"); - mMD5Digest = MessageDigest.getInstance("MD5"); -+ mSHA256Digest = MessageDigest.getInstance("SHA256"); - } catch (NoSuchAlgorithmException e) { - throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.getMessage())); - } -@@ -336,6 +339,8 @@ public class UidPwdPinDirAuthentication extends DirBasedAuthentication - pinDigest = mSHADigest.digest(toBeDigested.getBytes()); - } else if (hashtype == SENTINEL_MD5) { - pinDigest = mMD5Digest.digest(toBeDigested.getBytes()); -+ } else if (hashtype == SENTINEL_SHA256) { -+ pinDigest = mSHA256Digest.digest(toBeDigested.getBytes()); - } else if (hashtype == SENTINEL_NONE) { - pinDigest = toBeDigested.getBytes(); - } else { diff --git a/pki-core-Fix-to-determine-supported-javadoc-options.patch b/pki-core-Fix-to-determine-supported-javadoc-options.patch deleted file mode 100644 index 309bf53..0000000 --- a/pki-core-Fix-to-determine-supported-javadoc-options.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 5763b6d5da785c6c5dbf696fc927cf90140a0613 Mon Sep 17 00:00:00 2001 -From: Matthew Harmsen -Date: Thu, 18 Feb 2016 17:53:26 -0700 -Subject: [PATCH] Fix to determine supported javadoc options - -- PKI TRAC Ticket #2040 - Determine supported javadoc options - -(cherry picked from commit c32dd90ef638e9653136eeb901426c56b511fda4) ---- - base/javadoc/CMakeLists.txt | 61 +++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 59 insertions(+), 2 deletions(-) - -diff --git a/base/javadoc/CMakeLists.txt b/base/javadoc/CMakeLists.txt -index fa524be..09aa410 100644 ---- a/base/javadoc/CMakeLists.txt -+++ b/base/javadoc/CMakeLists.txt -@@ -1,9 +1,66 @@ - project(pki-javadoc) - -+# It is important to identify the version of 'javadoc' being utilized since -+# different versions support different options. -+# -+# While 'cmake' contains numerous built-in references to the 'java' version, -+# it contains no built-in references to either the 'javac' or 'javadoc' -+# versions, and unfortunately, the specified version of 'java' may be -+# different from the specified versions of 'javac' and 'javadoc'. -+# -+# Additionally, although 'javadoc' contains no command-line option to identify -+# its version, it is important to note that 'javadoc' is supplied by the same -+# package that supplies 'javac', and although multiple versions of these -+# executables could co-exist on the same system, it is relatively safe to -+# assert that the currently specified 'javac' and 'javadoc' will be the same -+# version. -+# -+# As an example in support of this assertion, on systems which utilize -+# '/usr/sbin/alternatives', setting the 'javac' version will also -+# automatically set the 'javadoc' version to match the 'javac' version, and -+# 'usr/sbin/alternatives' cannot be used to set a specific 'javadoc' version. -+# -+# Therefore, regardless of the 'java' version, this 'CMakeLists.txt' file will -+# programmatically utilize the invoked 'javac' version information (output is -+# to stderr) in order to correctly identify the supported 'javadoc' options: -+# -+# # javac -version 2>&1 | awk -F \. '{printf $2}' -+# -+# NOTE: Used 'cut' instead of 'awk' due to 'cmake' parsing limitations: -+# -+# # javac -version 2>&1 | cut -f2 -d. -+# -+message( STATUS "Java_VERSION_STRING = '${Java_VERSION_STRING}'" ) -+execute_process( -+ COMMAND -+ javac -version -+ ERROR_VARIABLE -+ Javac_VERSION_OUTPUT -+ OUTPUT_VARIABLE -+ Javac_VERSION_OUTPUT -+ ERROR_STRIP_TRAILING_WHITESPACE -+ OUTPUT_STRIP_TRAILING_WHITESPACE -+) -+message( STATUS "Javac_VERSION_OUTPUT = '${Javac_VERSION_OUTPUT}'" ) -+execute_process( -+ COMMAND -+ echo ${Javac_VERSION_OUTPUT} -+ COMMAND -+ cut -f2 -d. -+ OUTPUT_VARIABLE -+ Javadoc_VERSION_MINOR -+ OUTPUT_STRIP_TRAILING_WHITESPACE -+) -+message( STATUS "Javadoc_VERSION_MINOR = '${Javadoc_VERSION_MINOR}'" ) -+ -+# REMINDER: Eventually, it would almost certainly be safer to obtain the -+# 'Javadoc_VERSION_MAJOR' number as well and perform the check -+# on "'Javadoc_VERSION_MAJOR'.'Javadoc_VERSION_MINOR'". -+# - set(doclintstr "") --if(${Java_VERSION_MINOR} VERSION_EQUAL 8 OR ${Java_VERSION_MINOR} VERSION_GREATER 8) -+if(NOT (${Javadoc_VERSION_MINOR} LESS 8)) - set(doclintstr "-Xdoclint:none") --endif(${Java_VERSION_MINOR} VERSION_EQUAL 8 OR ${Java_VERSION_MINOR} VERSION_GREATER 8) -+endif(NOT (${Javadoc_VERSION_MINOR} LESS 8)) - - javadoc(pki-javadoc - SOURCEPATH --- -2.5.0 - diff --git a/pki-core-Fix-weak-HTTPS-TLS-ciphers.patch b/pki-core-Fix-weak-HTTPS-TLS-ciphers.patch deleted file mode 100644 index f7cbfd4..0000000 --- a/pki-core-Fix-weak-HTTPS-TLS-ciphers.patch +++ /dev/null @@ -1,234 +0,0 @@ -commit 67c895851781d69343979cbcff138184803880ea -Author: Christina Fu -Date: Fri Aug 14 19:57:15 2015 +0200 - - Ticket #1556 Weak HTTPS TLS ciphers - - This patch fixes the RSA ciphers that were mistakenly turned on under ECC - section, and off under RSA section. A few adjustments have also been made - based on Bob Relyea's feedback. A new file, /conf/ciphers.info - was also created to - 1. provide info on the ciphers - 2. provide default rsa and ecc ciphers for admins to incorporate into earlier - instances (as migration script might not be ideal due to possible customization) - -diff --git a/base/server/python/pki/server/deployment/pkiparser.py b/base/server/python/pki/server/deployment/pkiparser.py -index c1b6be3..425b710 100644 ---- a/base/server/python/pki/server/deployment/pkiparser.py -+++ b/base/server/python/pki/server/deployment/pkiparser.py -@@ -921,42 +921,46 @@ class PKIConfigParser: - "tls1_0:tls1_2" - self.mdict['TOMCAT_SSL_VERSION_RANGE_DATAGRAM_SLOT'] = \ - "tls1_1:tls1_2" -+ ## -+ # Reminder: if the following cipher lists are updated, be sure -+ # to remember to update pki/base/server/share/conf/ciphers.info -+ # accordingly -+ # - if self.mdict['pki_ssl_server_key_type'] == "ecc": - self.mdict['TOMCAT_SSL_RANGE_CIPHERS_SLOT'] = \ -- "+TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA," + \ -- "+TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA," + \ -- "+TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA," + \ -- "+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \ -+ "-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA," + \ -+ "-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA," + \ -+ "-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + \ -+ "-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256," + \ - "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_RSA_WITH_AES_128_CBC_SHA," + \ - "-TLS_RSA_WITH_AES_256_CBC_SHA," + \ - "+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \ - "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -+ "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + \ - "-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + \ - "-TLS_DHE_RSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256," + \ - "-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + \ -+ "-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \ - "-TLS_RSA_WITH_AES_128_CBC_SHA256," + \ - "-TLS_RSA_WITH_AES_256_CBC_SHA256," + \ - "-TLS_RSA_WITH_AES_128_GCM_SHA256," + \ -- "-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \ -- "-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + \ - "+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ - "+TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + \ -- "+TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256," + \ -- "+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \ -- "+TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256" -+ "+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ -+ "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ -+ "+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" - else: - self.mdict['TOMCAT_SSL_RANGE_CIPHERS_SLOT'] = \ - "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + \ -@@ -965,34 +969,34 @@ class PKIConfigParser: - "-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA," + \ - "-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256," + \ -+ "-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256," +\ - "-TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + \ -- "+TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \ -- "+TLS_RSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_RSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + \ -- "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -- "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \ -- "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ -+ "+TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -+ "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA," + \ -+ "+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + \ - "-TLS_DHE_DSS_WITH_AES_256_CBC_SHA," + \ -- "+TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -- "+TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + \ -- "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA," + \ -- "+TLS_DHE_RSA_WITH_AES_128_CBC_SHA256," + \ -- "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + \ -- "+TLS_RSA_WITH_AES_128_CBC_SHA256," + \ -- "+TLS_RSA_WITH_AES_256_CBC_SHA256," + \ -- "+TLS_RSA_WITH_AES_128_GCM_SHA256," + \ -- "+TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \ -+ "-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA," + \ -+ "-TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + \ -+ "-TLS_DHE_RSA_WITH_AES_256_CBC_SHA," + \ -+ "-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256," + \ -+ "-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + \ -+ "-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256," + \ - "-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + \ - "-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + \ -- "-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ -+ "+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256," + \ - "-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + \ -- "-TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256," + \ -- "-TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \ -- "-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256" -+ "+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256," + \ -+ "-TLS_RSA_WITH_AES_128_CBC_SHA256," + \ -+ "-TLS_RSA_WITH_AES_256_CBC_SHA256," + \ -+ "-TLS_RSA_WITH_AES_128_GCM_SHA256," + \ -+ "+TLS_RSA_WITH_3DES_EDE_CBC_SHA," + \ -+ "+TLS_RSA_WITH_AES_128_CBC_SHA," + \ -+ "+TLS_RSA_WITH_AES_256_CBC_SHA" - self.mdict['TOMCAT_SSL2_CIPHERS_SLOT'] = \ - "-SSL2_RC4_128_WITH_MD5," + \ - "-SSL2_RC4_128_EXPORT40_WITH_MD5," + \ -diff --git a/base/server/share/conf/ciphers.info b/base/server/share/conf/ciphers.info -new file mode 100644 -index 0000000..998c51e ---- /dev/null -+++ b/base/server/share/conf/ciphers.info -@@ -0,0 +1,66 @@ -+## -+# BEGIN COPYRIGHT BLOCK -+# Copyright (C) 2015 Red Hat, Inc. -+# All rights reserved. -+# END COPYRIGHT BLOCK -+# -+# This file contains the default sslRangeCiphers that come with this version of -+# the PKI software in its /conf/server.xml file. -+# Depending on which kind of SSL server you have, you want to reference the -+# corresponding cipher suite for making adjustments to your instance server.xml. -+# -+# -+# About the TLS range related parameters: -+# 'sslVersionRangeStream' -+# 'sslVersionRangeDatagram' -+# 'sslRangeCiphers' -+# The sslVersionRangeStream and sslVersionRangeDatagram by default -+# contains values that are supported by the native NSS. Changes can -+# be made to restrict or relax the support. -+# The sslRangeCiphers by default conatins a list of ciphers best -+# for the type of the server installed. Changes can be made to suit -+# each site's needs. -+# Although TLS1.2 ciphers (SHA256) are preferred, many older clients -+# do not support them. For example, -+# the following "preferred modern" ciphers are on by default, and by -+# simply limiting the sslVersionRange* parameters, they can be turned off. -+# TLS_RSA_WITH_AES_128_CBC_SHA256, -+# TLS_RSA_WITH_AES_256_CBC_SHA256, -+# TLS_RSA_WITH_AES_128_GCM_SHA256, -+# TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, -+# TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, -+# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, -+# TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -+# The following ciphers are supported in rhel7.2 or greater, and they -+# are off by default, and can be turned on by sites running rhel7.2 or -+# greater: -+# TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, -+# TLS_DHE_RSA_WITH_AES_128_CBC_SHA, -+# TLS_DHE_RSA_WITH_AES_256_CBC_SHA, -+# TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, -+# TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, -+# TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 -+# Although the following (somewhat weaker ciphers, in CBC mode), though -+# adaquate for the CS operations, they can be turned off if needed: -+# TLS_RSA_WITH_3DES_EDE_CBC_SHA, -+# TLS_RSA_WITH_AES_128_CBC_SHA, -+# TLS_RSA_WITH_AES_256_CBC_SHA, -+# TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA -+# Note: In an EC CS server setup, you will see by default that the -+# following RSA ciphers are left on. Those are used for installation -+# where the actual systems certs have not yet been crated, and a -+# temporary RSA ssl server cert is at play. -+# Those can be turned off manually by sites. -+# TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, -+# TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, -+# TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -+# These ciphers might be removed by the installation script in some -+# future release. -+# -+## -+# For RSA servers: -+ sslRangeCiphers="-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,+TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_RSA_WITH_AES_128_CBC_SHA256,-TLS_RSA_WITH_AES_256_CBC_SHA256,-TLS_RSA_WITH_AES_128_GCM_SHA256,+TLS_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_RSA_WITH_AES_128_CBC_SHA,+TLS_RSA_WITH_AES_256_CBC_SHA" -+# -+# -+# For ECC servers: -+ sslRangeCiphers="-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_RSA_WITH_AES_128_CBC_SHA,-TLS_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_CBC_SHA,-TLS_DHE_DSS_WITH_AES_256_CBC_SHA,-TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,-TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA,-TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,-TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,-TLS_RSA_WITH_AES_128_CBC_SHA256,-TLS_RSA_WITH_AES_256_CBC_SHA256,-TLS_RSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,+TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,+TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,+TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,+TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" -diff --git a/base/server/tomcat7/conf/server.xml b/base/server/tomcat7/conf/server.xml -index d944d32..7deb8a2 100644 ---- a/base/server/tomcat7/conf/server.xml -+++ b/base/server/tomcat7/conf/server.xml -@@ -179,6 +179,9 @@ Tomcat Port = [TOMCAT_SERVER_PORT] (for shutdown) - ocspMinCacheEntryDuration - sets minimum seconds to next fetch attempt - ocspMaxCacheEntryDuration - sets maximum seconds to next fetch attempt - ocspTimeout -sets OCSP timeout in seconds -+ -+ See /conf/ciphers.info -+ About the TLS range related parameters - --> - /conf/ciphers.info -+ About the TLS range related parameters - --> - -Date: Mon, 20 Jul 2015 22:03:17 +0200 -Subject: [PATCH] Fixed ObjectNotFoundException in PKCS12Export. - -The PKCS12Export has been fixed to handle ObjectNotFoundException -when exporting certificates without private keys. - -https://fedorahosted.org/pki/ticket/1506 ---- - base/java-tools/src/com/netscape/cmstools/PKCS12Export.java | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java b/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java -index 77e6b7c..b8999fe 100644 ---- a/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java -+++ b/base/java-tools/src/com/netscape/cmstools/PKCS12Export.java -@@ -224,17 +224,17 @@ public class PKCS12Export { - for (int i = 0; i < certs.length; i++) { - String nickname = certs[i].getNickname(); - debug(" * Certificate: " + nickname); -- org.mozilla.jss.crypto.PrivateKey prikey = cm.findPrivKeyByCert(certs[i]); -+ try { -+ org.mozilla.jss.crypto.PrivateKey prikey = cm.findPrivKeyByCert(certs[i]); - -- if (prikey == null) { -- debug(" Private key does not exist"); -- addCertBag(certs[i], null, safeContents); -- -- } else { - debug(" Private key exists"); - byte localKeyId[] = - addCertBag(certs[i], nickname, safeContents); - addKeyBag(prikey, certs[i], password, localKeyId, encSafeContents); -+ -+ } catch (org.mozilla.jss.crypto.ObjectNotFoundException e) { -+ debug(" Private key does not exist"); -+ addCertBag(certs[i], null, safeContents); - } - } - --- -1.8.3.1 - diff --git a/pki-core-Fixed-mismatching-certificate-validity-calculation.patch b/pki-core-Fixed-mismatching-certificate-validity-calculation.patch deleted file mode 100644 index 73c693b..0000000 --- a/pki-core-Fixed-mismatching-certificate-validity-calculation.patch +++ /dev/null @@ -1,181 +0,0 @@ -From de3d8ac7b6a77b69231bf771d853e3b6a7791d01 Mon Sep 17 00:00:00 2001 -From: "Endi S. Dewata" -Date: Sun, 20 Dec 2015 21:46:56 +0100 -Subject: [PATCH 6/9] Fixed mismatching certificate validity calculation. - -The CAValidityDefault has been modified to use Calendar API to -calculate the certificate validity range to be consistent with -the ValidityConstraint and ValidityDefault. - -https://fedorahosted.org/pki/ticket/1682 -(cherry picked from commit 9193fe5191d1bd857b7e1f5a398c6a279b42ec84) ---- - .../cms/profile/def/CAValidityDefault.java | 79 ++++++++++++++++++---- - base/server/cmsbundle/src/UserMessages.properties | 2 +- - 2 files changed, 67 insertions(+), 14 deletions(-) - -diff --git a/base/server/cms/src/com/netscape/cms/profile/def/CAValidityDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/CAValidityDefault.java -index 44ffd47..a98b2c2 100644 ---- a/base/server/cms/src/com/netscape/cms/profile/def/CAValidityDefault.java -+++ b/base/server/cms/src/com/netscape/cms/profile/def/CAValidityDefault.java -@@ -20,14 +20,10 @@ package com.netscape.cms.profile.def; - import java.io.IOException; - import java.text.ParsePosition; - import java.text.SimpleDateFormat; -+import java.util.Calendar; - import java.util.Date; - import java.util.Locale; - --import netscape.security.x509.BasicConstraintsExtension; --import netscape.security.x509.CertificateValidity; --import netscape.security.x509.PKIXExtensions; --import netscape.security.x509.X509CertInfo; -- - import com.netscape.certsrv.apps.CMS; - import com.netscape.certsrv.base.IConfigStore; - import com.netscape.certsrv.ca.ICertificateAuthority; -@@ -38,6 +34,11 @@ import com.netscape.certsrv.property.EPropertyException; - import com.netscape.certsrv.property.IDescriptor; - import com.netscape.certsrv.request.IRequest; - -+import netscape.security.x509.BasicConstraintsExtension; -+import netscape.security.x509.CertificateValidity; -+import netscape.security.x509.PKIXExtensions; -+import netscape.security.x509.X509CertInfo; -+ - /** - * This class implements a CA signing cert enrollment default policy - * that populates a server-side configurable validity -@@ -46,6 +47,7 @@ import com.netscape.certsrv.request.IRequest; - */ - public class CAValidityDefault extends EnrollDefault { - public static final String CONFIG_RANGE = "range"; -+ public static final String CONFIG_RANGE_UNIT = "rangeUnit"; - public static final String CONFIG_START_TIME = "startTime"; - public static final String CONFIG_BYPASS_CA_NOTAFTER = "bypassCAnotafter"; - -@@ -61,6 +63,7 @@ public class CAValidityDefault extends EnrollDefault { - public CAValidityDefault() { - super(); - addConfigName(CONFIG_RANGE); -+ addConfigName(CONFIG_RANGE_UNIT); - addConfigName(CONFIG_START_TIME); - addConfigName(CONFIG_BYPASS_CA_NOTAFTER); - -@@ -103,6 +106,12 @@ public class CAValidityDefault extends EnrollDefault { - "7305", /* 20 years */ - CMS.getUserMessage(locale, - "CMS_PROFILE_VALIDITY_RANGE")); -+ } else if (name.equals(CONFIG_RANGE_UNIT)) { -+ return new Descriptor(IDescriptor.STRING, -+ null, -+ "day", -+ CMS.getUserMessage(locale, -+ "CMS_PROFILE_VALIDITY_RANGE_UNIT")); - } else if (name.equals(CONFIG_START_TIME)) { - return new Descriptor(IDescriptor.STRING, - null, -@@ -299,6 +308,28 @@ public class CAValidityDefault extends EnrollDefault { - return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_VALIDITY", params); - } - -+ public int convertRangeUnit(String unit) throws Exception { -+ -+ if (unit.equals("year")) { -+ return Calendar.YEAR; -+ -+ } else if (unit.equals("month")) { -+ return Calendar.MONTH; -+ -+ } else if (unit.equals("day")) { -+ return Calendar.DAY_OF_YEAR; -+ -+ } else if (unit.equals("hour")) { -+ return Calendar.HOUR_OF_DAY; -+ -+ } else if (unit.equals("minute")) { -+ return Calendar.MINUTE; -+ -+ } else { -+ throw new Exception("Invalid range unit: " + unit); -+ } -+ } -+ - /** - * Populates the request with this policy default. - */ -@@ -307,6 +338,7 @@ public class CAValidityDefault extends EnrollDefault { - - // always + 60 seconds - String startTimeStr = getConfig(CONFIG_START_TIME); -+ CMS.debug("CAValidityDefault: start time: " + startTimeStr); - try { - startTimeStr = mapPattern(request, startTimeStr); - } catch (IOException e) { -@@ -317,21 +349,42 @@ public class CAValidityDefault extends EnrollDefault { - startTimeStr = "60"; - } - int startTime = Integer.parseInt(startTimeStr); -+ - Date notBefore = new Date(CMS.getCurrentDate().getTime() + (1000 * startTime)); -- long notAfterVal = 0; -+ CMS.debug("CAValidityDefault: not before: " + notBefore); -+ -+ String rangeStr = getConfig(CONFIG_RANGE, "7305"); -+ CMS.debug("CAValidityDefault: range: " + rangeStr); - -+ int range; - try { -- String rangeStr = getConfig(CONFIG_RANGE); - rangeStr = mapPattern(request, rangeStr); -- notAfterVal = notBefore.getTime() + -- (mDefault * Integer.parseInt(rangeStr)); -- } catch (Exception e) { -- // configured value is not correct -- CMS.debug("CAValidityDefault: populate " + e.toString()); -+ range = Integer.parseInt(rangeStr); -+ } catch (IOException e) { -+ CMS.debug(e); - throw new EProfileException(CMS.getUserMessage( - getLocale(request), "CMS_INVALID_PROPERTY", CONFIG_RANGE)); - } -- Date notAfter = new Date(notAfterVal); -+ -+ String rangeUnitStr = getConfig(CONFIG_RANGE_UNIT, "day"); -+ CMS.debug("CAValidityDefault: range unit: " + rangeUnitStr); -+ -+ int rangeUnit; -+ try { -+ rangeUnit = convertRangeUnit(rangeUnitStr); -+ } catch (Exception e) { -+ CMS.debug(e); -+ throw new EProfileException(CMS.getUserMessage( -+ getLocale(request), "CMS_INVALID_PROPERTY", CONFIG_RANGE_UNIT)); -+ } -+ -+ // calculate the end of validity range -+ Calendar date = Calendar.getInstance(); -+ date.setTime(notBefore); -+ date.add(rangeUnit, range); -+ -+ Date notAfter = date.getTime(); -+ CMS.debug("CAValidityDefault: not after: " + notAfter); - - CertificateValidity validity = - new CertificateValidity(notBefore, notAfter); -diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties -index 6b4dc69..7c5c77d 100644 ---- a/base/server/cmsbundle/src/UserMessages.properties -+++ b/base/server/cmsbundle/src/UserMessages.properties -@@ -835,7 +835,7 @@ CMS_PROFILE_VALIDITY_CHECK_NOT_BEFORE=Check Not Before against current time - CMS_PROFILE_VALIDITY_CHECK_NOT_AFTER=Check Not After against Not Before - CMS_PROFILE_VALIDITY_NOT_BEFORE_GRACE_PERIOD=Grace period for Not Before being set in the future (in seconds). - CMS_PROFILE_VALIDITY_RANGE=Validity Range --CMS_PROFILE_VALIDITY_RANGE_UNIT=Validity Range Unit (default: day) -+CMS_PROFILE_VALIDITY_RANGE_UNIT=Validity Range Unit: year, month, day (default), hour, minute - CMS_PROFILE_VALIDITY_START_TIME=Relative Start Time (in seconds) - CMS_PROFILE_NOT_BEFORE_RANDOM_BITS=Not Before Random Bits - CMS_PROFILE_NOT_AFTER_RANDOM_BITS=Not After Random Bits --- -2.5.0 - diff --git a/pki-core-Fixed-pkidbuser-group-memberships.patch b/pki-core-Fixed-pkidbuser-group-memberships.patch deleted file mode 100644 index 0a0d46f..0000000 --- a/pki-core-Fixed-pkidbuser-group-memberships.patch +++ /dev/null @@ -1,155 +0,0 @@ -commit bf2a61299ab83098ab2b579af2a7e0f35e7f07a3 -Author: Matthew Harmsen -Date: Tue Sep 15 12:29:08 2015 -0600 - - Fixed pkidbuser group memberships. - - Due to a certificate mapping issue the subsystem certificate can - be mapped into either the subsystem user or pkidbuser, which may - cause problems since the users don't belong to the same groups. - As a temporary solution the pkidbuser is now added into the same - groups. This way the client subsystem can always access the - services regardless of which user the certificate is actually - mapped to. - - Bugzilla Bug #1258634 - CA fails to authenticate to KRA for archival - - https://fedorahosted.org/pki/ticket/1595 - (cherry picked from commit e6f8b52e97926e7b6c30a6ce958a7e590c2e6b76) - - Conflicts: - base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java - -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 -index a417be4..7b5bef5 100644 ---- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java -+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java -@@ -50,6 +50,7 @@ import java.security.cert.CertificateNotYetValidException; - import java.security.interfaces.RSAPublicKey; - import java.util.ArrayList; - import java.util.Arrays; -+import java.util.Collection; - import java.util.Enumeration; - import java.util.List; - import java.util.StringTokenizer; -@@ -62,32 +63,6 @@ import javax.ws.rs.core.MultivaluedMap; - import javax.ws.rs.core.Response; - import javax.xml.parsers.ParserConfigurationException; - --import netscape.ldap.LDAPAttribute; --import netscape.ldap.LDAPAttributeSet; --import netscape.ldap.LDAPConnection; --import netscape.ldap.LDAPDN; --import netscape.ldap.LDAPEntry; --import netscape.ldap.LDAPException; --import netscape.ldap.LDAPModification; --import netscape.ldap.LDAPSearchConstraints; --import netscape.ldap.LDAPSearchResults; --import netscape.ldap.LDAPv3; --import netscape.security.pkcs.ContentInfo; --import netscape.security.pkcs.PKCS10; --import netscape.security.pkcs.PKCS7; --import netscape.security.pkcs.SignerInfo; --import netscape.security.util.DerOutputStream; --import netscape.security.util.ObjectIdentifier; --import netscape.security.x509.AlgorithmId; --import netscape.security.x509.BasicConstraintsExtension; --import netscape.security.x509.CertificateChain; --import netscape.security.x509.Extension; --import netscape.security.x509.Extensions; --import netscape.security.x509.KeyUsageExtension; --import netscape.security.x509.X500Name; --import netscape.security.x509.X509CertImpl; --import netscape.security.x509.X509Key; -- - import org.apache.commons.lang.StringUtils; - import org.apache.velocity.context.Context; - import org.mozilla.jss.CryptoManager; -@@ -181,6 +156,32 @@ import com.netscape.cmsutil.http.JssSSLSocketFactory; - import com.netscape.cmsutil.ldap.LDAPUtil; - import com.netscape.cmsutil.xml.XMLObject; - -+import netscape.ldap.LDAPAttribute; -+import netscape.ldap.LDAPAttributeSet; -+import netscape.ldap.LDAPConnection; -+import netscape.ldap.LDAPDN; -+import netscape.ldap.LDAPEntry; -+import netscape.ldap.LDAPException; -+import netscape.ldap.LDAPModification; -+import netscape.ldap.LDAPSearchConstraints; -+import netscape.ldap.LDAPSearchResults; -+import netscape.ldap.LDAPv3; -+import netscape.security.pkcs.ContentInfo; -+import netscape.security.pkcs.PKCS10; -+import netscape.security.pkcs.PKCS7; -+import netscape.security.pkcs.SignerInfo; -+import netscape.security.util.DerOutputStream; -+import netscape.security.util.ObjectIdentifier; -+import netscape.security.x509.AlgorithmId; -+import netscape.security.x509.BasicConstraintsExtension; -+import netscape.security.x509.CertificateChain; -+import netscape.security.x509.Extension; -+import netscape.security.x509.Extensions; -+import netscape.security.x509.KeyUsageExtension; -+import netscape.security.x509.X500Name; -+import netscape.security.x509.X509CertImpl; -+import netscape.security.x509.X509Key; -+ - /** - * Utility class for functions to be used both by the RESTful installer - * and the UI Panels. -@@ -3930,7 +3931,7 @@ public class ConfigurationUtils { - String groupName = "Trusted Managers"; - IGroup group = system.getGroupFromName(groupName); - if (!group.isMember(id)) { -- CMS.debug("setupClientAuthUser: adding user to the trusted managers group."); -+ CMS.debug("setupClientAuthUser: adding user to the " + groupName + " group."); - group.addMemberName(id); - system.modifyGroup(group); - } -@@ -4156,7 +4157,7 @@ public class ConfigurationUtils { - user.setX509Certificates(certs); - - system.addUser(user); -- CMS.debug("setupDBUser(): successfully added the user"); -+ CMS.debug("setupDBUser(): successfully added " + DBUSER); - - system.addUserCert(user); - CMS.debug("setupDBUser(): successfully add the user certificate"); -@@ -4167,6 +4168,36 @@ public class ConfigurationUtils { - // remove old db users - CMS.debug("setupDBUser(): removing seeAlso from old dbusers"); - removeOldDBUsers(certs[0].getSubjectDN().toString()); -+ -+ // workaround for ticket #1595 -+ IConfigStore cs = CMS.getConfigStore(); -+ String csType = cs.getString("cs.type").toUpperCase(); -+ -+ Collection groupNames = new ArrayList(); -+ -+ if ("CA".equals(csType)) { -+ groupNames.add("Subsystem Group"); -+ groupNames.add("Certificate Manager Agents"); -+ -+ } else if ("KRA".equals(csType)) { -+ groupNames.add("Data Recovery Manager Agents"); -+ groupNames.add("Trusted Managers"); -+ -+ } else if ("OCSP".equals(csType)) { -+ groupNames.add("Trusted Managers"); -+ -+ } else if ("TKS".equals(csType)) { -+ groupNames.add("Token Key Service Manager Agents"); -+ } -+ -+ for (String groupName : groupNames) { -+ IGroup group = system.getGroupFromName(groupName); -+ if (!group.isMember(DBUSER)) { -+ CMS.debug("setupDBUser(): adding " + DBUSER + " to the " + groupName + " group."); -+ group.addMemberName(DBUSER); -+ system.modifyGroup(group); -+ } -+ } - } - - public static void addProfilesToTPSUser(String adminID) throws EUsrGrpException, LDAPException { diff --git a/pki-core-Fixed-user-search-in-PasswdUserDBAuthentication.patch b/pki-core-Fixed-user-search-in-PasswdUserDBAuthentication.patch deleted file mode 100644 index 5a95610..0000000 --- a/pki-core-Fixed-user-search-in-PasswdUserDBAuthentication.patch +++ /dev/null @@ -1,321 +0,0 @@ -commit dda808a071e2e7efd02dbbd0e182f94ebb3f8ffe -Author: Endi S. Dewata -Date: Fri Oct 2 00:09:36 2015 +0200 - - Fixed user search in PasswdUserDBAuthentication. - - The PasswdUserDBAuthentication.authenticate() has been modified - such that it uses the UGSubsystem to find the user in the proper - LDAP subtree to avoid matching other LDAP entries that contain - a uid attribute. - - https://fedorahosted.org/pki/ticket/1580 - (cherry picked from commit 017d582ba50fe4ffc4bedf40a5229fb6aa381b37) - -diff --git a/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java b/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java -index 73fae47..1933601 100644 ---- a/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java -+++ b/base/server/cms/src/com/netscape/cms/realm/PKIRealm.java -@@ -6,8 +6,6 @@ import java.util.ArrayList; - import java.util.Enumeration; - import java.util.List; - --import netscape.security.x509.X509CertImpl; -- - import org.apache.catalina.realm.RealmBase; - import org.apache.commons.lang.StringUtils; - -@@ -25,6 +23,8 @@ import com.netscape.certsrv.usrgrp.IUGSubsystem; - import com.netscape.certsrv.usrgrp.IUser; - import com.netscape.cms.servlet.common.AuthCredentials; - -+import netscape.security.x509.X509CertImpl; -+ - /** - * PKI Realm - * -@@ -47,7 +47,7 @@ public class PKIRealm extends RealmBase { - - @Override - public Principal authenticate(String username, String password) { -- logDebug("Authenticating username "+username+" with password."); -+ CMS.debug("PKIRealm: Authenticating user " + username + " with password."); - String auditMessage = null; - String auditSubjectID = ILogger.UNIDENTIFIED; - String attemptedAuditUID = username; -@@ -61,7 +61,7 @@ public class PKIRealm extends RealmBase { - creds.set(IPasswdUserDBAuthentication.CRED_PWD, password); - - IAuthToken authToken = authMgr.authenticate(creds); // throws exception if authentication fails -- authToken.set(SessionContext.AUTH_MANAGER_ID,IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID); -+ authToken.set(SessionContext.AUTH_MANAGER_ID, IAuthSubsystem.PASSWDUSERDB_AUTHMGR_ID); - auditSubjectID = authToken.getInString(IAuthToken.USER_ID); - - // store a message in the signed audit log file -@@ -91,7 +91,7 @@ public class PKIRealm extends RealmBase { - - @Override - public Principal authenticate(final X509Certificate certs[]) { -- logDebug("Authenticating certificate chain:"); -+ CMS.debug("PKIRealm: Authenticating certificate chain:"); - - String auditMessage = null; - // get the cert from the ssl client auth -@@ -105,7 +105,7 @@ public class PKIRealm extends RealmBase { - X509CertImpl certImpls[] = new X509CertImpl[certs.length]; - for (int i=0; i groups = ugSub.findGroupsByUser(user.getUserDN(), null); - -- logDebug("Roles:"); -+ CMS.debug("PKIRealm: Roles:"); - while (groups.hasMoreElements()) { - IGroup group = groups.nextElement(); - - String name = group.getName(); -- logDebug(" "+name); -+ CMS.debug("PKIRealm: " + name); - roles.add(name); - } - -@@ -209,19 +209,6 @@ public class PKIRealm extends RealmBase { - return null; - } - -- /* -- * TODO: Figure out how to do real logging -- */ -- public void logErr(String msg) { -- System.err.println(msg); -- CMS.debug("PKIRealm.logErr: " + msg); -- } -- -- public void logDebug(String msg) { -- System.out.println("PKIRealm: "+msg); -- CMS.debug("PKIRealm.logDebug: " + msg); -- } -- - /** - * Signed Audit Log - * -diff --git a/base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java b/base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java -index bae25b6..b6461ab 100644 ---- a/base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java -+++ b/base/server/cms/src/org/dogtagpki/server/rest/SessionContextInterceptor.java -@@ -18,6 +18,7 @@ - package org.dogtagpki.server.rest; - - import java.io.IOException; -+import java.lang.reflect.Method; - import java.security.Principal; - import java.util.Locale; - -@@ -28,6 +29,8 @@ import javax.ws.rs.core.Context; - import javax.ws.rs.core.SecurityContext; - import javax.ws.rs.ext.Provider; - -+import org.jboss.resteasy.core.ResourceMethodInvoker; -+ - import com.netscape.certsrv.apps.CMS; - import com.netscape.certsrv.authentication.IAuthToken; - import com.netscape.certsrv.base.ForbiddenException; -@@ -59,6 +62,13 @@ public class SessionContextInterceptor implements ContainerRequestFilter { - @Override - public void filter(ContainerRequestContext requestContext) throws IOException { - -+ ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) requestContext -+ .getProperty("org.jboss.resteasy.core.ResourceMethodInvoker"); -+ Method method = methodInvoker.getMethod(); -+ Class clazz = methodInvoker.getResourceClass(); -+ -+ CMS.debug("SessionContextInterceptor: " + clazz.getSimpleName() + "." + method.getName() + "()"); -+ - Principal principal = securityContext.getUserPrincipal(); - - // If unauthenticated, ignore. -diff --git a/base/server/cmscore/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java b/base/server/cmscore/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java -index 692dc49..07092aa 100644 ---- a/base/server/cmscore/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java -+++ b/base/server/cmscore/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java -@@ -17,12 +17,6 @@ - // --- END COPYRIGHT BLOCK --- - package com.netscape.cmscore.authentication; - --import netscape.ldap.LDAPConnection; --import netscape.ldap.LDAPEntry; --import netscape.ldap.LDAPException; --import netscape.ldap.LDAPSearchResults; --import netscape.ldap.LDAPv2; -- - import com.netscape.certsrv.apps.CMS; - import com.netscape.certsrv.authentication.AuthToken; - import com.netscape.certsrv.authentication.EInvalidCredentials; -@@ -38,10 +32,11 @@ import com.netscape.certsrv.logging.ILogger; - import com.netscape.certsrv.usrgrp.IUser; - import com.netscape.cmscore.dbs.DBSubsystem; - import com.netscape.cmscore.ldapconn.LdapAnonConnFactory; --import com.netscape.cmscore.ldapconn.LdapBoundConnFactory; - import com.netscape.cmscore.ldapconn.LdapConnInfo; - import com.netscape.cmscore.usrgrp.UGSubsystem; --import com.netscape.cmscore.util.Debug; -+ -+import netscape.ldap.LDAPConnection; -+import netscape.ldap.LDAPException; - - /** - * Certificate Server admin authentication. -@@ -64,8 +59,6 @@ public class PasswdUserDBAuthentication implements IAuthManager, IPasswdUserDBAu - private String mName = null; - private String mImplName = null; - private IConfigStore mConfig; -- private String mBaseDN = null; -- private LdapBoundConnFactory mConnFactory = null; - private LdapAnonConnFactory mAnonConnFactory = null; - private ILogger mLogger = CMS.getLogger(); - -@@ -94,8 +87,6 @@ public class PasswdUserDBAuthentication implements IAuthManager, IPasswdUserDBAu - if (ldapinfo == null && CMS.isPreOpMode()) - return; - -- mBaseDN = dbs.getBaseDN(); -- mConnFactory = new LdapBoundConnFactory("PasswdUserDBAuthentication", 3, 20, ldapinfo, dbs.getLdapAuthInfo()); - mAnonConnFactory = new LdapAnonConnFactory("PasswdUserDBAuthentication", 3, 20, ldapinfo); - - log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INIT_AUTH", mName)); -@@ -124,76 +115,66 @@ public class PasswdUserDBAuthentication implements IAuthManager, IPasswdUserDBAu - - // make sure the required credentials are provided - String uid = (String) authCred.get(CRED_UID); -- CMS.debug("Authentication: UID=" + uid); -+ CMS.debug("PasswdUserDBAuthentication: UID: " + uid); - if (uid == null) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_MISSING_UID")); - throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UID)); - } -- String pwd = (String) authCred.get(CRED_PWD); - -+ String pwd = (String) authCred.get(CRED_PWD); - if (pwd == null) { - log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NULL_PW", uid)); - throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PWD)); - } -+ - // don't allow anonymous binding - if (pwd == "") { - log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_EMPTY_PW", uid)); - throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); - } - -- String userdn = null; -- LDAPConnection conn = null; -+ UGSubsystem ug = UGSubsystem.getInstance(); -+ IUser user; -+ -+ try { -+ user = ug.getUser(uid); -+ } catch (EBaseException e) { -+ CMS.debug(e); -+ // not a user in our user/group database. -+ log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_UID_NOT_FOUND", uid, e.toString())); -+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + " " + e.getMessage()); -+ } -+ -+ if (user == null) { -+ CMS.debug("PasswdUserDBAuthentication: User not found: " + uid); -+ throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", -+ "Failure in User Group subsystem.")); -+ } -+ -+ String userdn = user.getUserDN(); -+ CMS.debug("PasswdUserDBAuthentication: DN: " + userdn); -+ - LDAPConnection anonConn = null; - - try { -- conn = mConnFactory.getConn(); -- // do anonymous search for the user's dn. -- LDAPSearchResults res = conn.search(mBaseDN, -- LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false); -- -- if (res.hasMoreElements()) { -- LDAPEntry entry = (LDAPEntry) res.nextElement(); -- -- userdn = entry.getDN(); -- } -- if (userdn == null) { -- log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NOT_FOUND", uid)); -- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); -- } - anonConn = mAnonConnFactory.getConn(); - anonConn.authenticate(userdn, pwd); -+ - } catch (LDAPException e) { - log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_AUTH_FAILED", uid, e.toString())); - throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); -+ - } finally { -- if (conn != null) -- mConnFactory.returnConn(conn); - if (anonConn != null) - mAnonConnFactory.returnConn(anonConn); - } - -- UGSubsystem ug = UGSubsystem.getInstance(); -- - authToken.set(TOKEN_USERDN, userdn); - authToken.set(CRED_UID, uid); // return original uid for info - -- IUser user = null; -- -- try { -- user = ug.getUser(uid); -- } catch (EBaseException e) { -- if (Debug.ON) -- e.printStackTrace(); -- // not a user in our user/group database. -- log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_UID_NOT_FOUND", uid, e.toString())); -- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL") + " " + e.getMessage()); -- } -- if (user == null) { -- throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", -- "Failure in User Group subsystem.")); -- } - authToken.set(TOKEN_USERDN, user.getUserDN()); - authToken.set(TOKEN_USERID, user.getUserID()); -+ - log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_AUTHENTICATED", uid)); - - return authToken; -@@ -241,7 +222,6 @@ public class PasswdUserDBAuthentication implements IAuthManager, IPasswdUserDBAu - public void shutdown() { - try { - // disconnect all outstanding connections in the factory -- if (mConnFactory != null) mConnFactory.reset(); - if (mAnonConnFactory != null) mAnonConnFactory.reset(); - } catch (ELdapException e) { - log(ILogger.LL_FAILURE, e.toString()); diff --git a/pki-core-HSM-failover-support.patch b/pki-core-HSM-failover-support.patch deleted file mode 100644 index df062d3..0000000 --- a/pki-core-HSM-failover-support.patch +++ /dev/null @@ -1,478 +0,0 @@ -commit 0866e353135c3db65f5f1ca721fc8f83bf7d7632 -Author: Christina Fu -Date: Wed Sep 30 13:55:05 2015 +0200 - - Ticket #1593 auto-shutdown - for HSM failover support - This is an interim solution for supporting HSM failover by automatically - shutting down the server when signing key becomes inaccessible. - At auto-shutdown, a crumb fiile will be left in the instance directory - for an external daemon to detect and restart, if necessary. - Due to limitation of the watch dog (nuxwdog) at present time, - the restart option currently only works if started with watch dog (nuxwdog), - and it will prompt for passwords on the terminals. - The restart counter is to prevent the server from going into an infinite restart - loop. Administrator will have to reset autoShutdown.restart.count to 0 when max - is reached. - - (cherry picked from commit 5a9ecad9172f76ca1b94b40aedcdd49d009aceb1) - -diff --git a/base/ca/shared/conf/CS.cfg.in b/base/ca/shared/conf/CS.cfg.in -index 564ee3a..53e65de 100644 ---- a/base/ca/shared/conf/CS.cfg.in -+++ b/base/ca/shared/conf/CS.cfg.in -@@ -1133,6 +1133,11 @@ selftests.container.order.startup=CAPresence:critical, SystemCertsVerification:c - selftests.plugin.CAPresence.CaSubId=ca - selftests.plugin.CAValidity.CaSubId=ca - selftests.plugin.SystemCertsVerification.SubId=ca -+autoShutdown.allowed=false -+autoShutdown.crumbFile=[PKI_INSTANCE_PATH]/logs/autoShutdown.crumb -+autoShutdown.restart.count=0 -+autoShutdown.restart.enable=false -+autoShutdown.restart.max=3 - smtp.host=localhost - smtp.port=25 - subsystem.0.class=com.netscape.ca.CertificateAuthority -diff --git a/base/ca/src/com/netscape/ca/SigningUnit.java b/base/ca/src/com/netscape/ca/SigningUnit.java -index 2466fb6..3946fde 100644 ---- a/base/ca/src/com/netscape/ca/SigningUnit.java -+++ b/base/ca/src/com/netscape/ca/SigningUnit.java -@@ -272,6 +272,16 @@ public final class SigningUnit implements ISigningUnit { - - signer.initSign(mPrivk); - signer.update(data); -+ -+ /* debugging -+ boolean testAutoShutdown = false; -+ testAutoShutdown = mConfig.getBoolean("autoShutdown.test", false); -+ if (testAutoShutdown) { -+ CMS.debug("SigningUnit.sign: test auto shutdown"); -+ CMS.checkForAndAutoShutdown(); -+ } -+ */ -+ - // XXX add something more descriptive. - CMS.debug("Signing Certificate"); - return signer.sign(); -@@ -289,6 +299,8 @@ public final class SigningUnit implements ISigningUnit { - throw new EBaseException(e.toString()); - } catch (SignatureException e) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString())); -+ CMS.debug("SigningUnit.sign: " + e.toString()); -+ CMS.checkForAndAutoShutdown(); - // XXX fix this exception later. - throw new EBaseException(e.toString()); - } -@@ -328,6 +340,7 @@ public final class SigningUnit implements ISigningUnit { - throw new EBaseException(e.toString()); - } catch (SignatureException e) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString())); -+ CMS.checkForAndAutoShutdown(); - // XXX fix this exception later. - throw new EBaseException(e.toString()); - } -diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java -index 3ba6d75..187b102 100644 ---- a/base/common/src/com/netscape/certsrv/apps/CMS.java -+++ b/base/common/src/com/netscape/certsrv/apps/CMS.java -@@ -237,12 +237,19 @@ public final class CMS { - * Shuts down subsystems in backwards order - * exceptions are ignored. process exists at end to force exit. - */ -- - public static void forceShutdown() { - - _engine.forceShutdown(); - } - -+ public static void autoShutdown() { -+ _engine.autoShutdown(); -+ } -+ -+ public static void checkForAndAutoShutdown() { -+ _engine.checkForAndAutoShutdown(); -+ } -+ - /** - * mode = 0 (pre-operational) - * mode = 1 (running) -diff --git a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java -index 57c2b6c..bf1d3ff 100644 ---- a/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java -+++ b/base/common/src/com/netscape/certsrv/apps/ICMSEngine.java -@@ -1131,6 +1131,13 @@ public interface ICMSEngine extends ISubsystem { - */ - public void forceShutdown(); - -+ /** -+ * graceful shutdown, same as forceShutdown, but allowing -+ * option to restart -+ */ -+ public void autoShutdown(); -+ public void checkForAndAutoShutdown(); -+ - public IPasswordStore getPasswordStore() throws EBaseException; - - public ISecurityDomainSessionTable getSecurityDomainSessionTable(); -diff --git a/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java b/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java -index 7774ca4..3146240 100644 ---- a/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java -+++ b/base/common/src/com/netscape/certsrv/kra/ProofOfArchival.java -@@ -341,6 +341,8 @@ public class ProofOfArchival implements IDBObj, IProofOfArchival, Serializable { - } catch (InvalidKeyException e) { - throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString())); - } catch (SignatureException e) { -+ CMS.debug("ProofOfArchival.encodeAndSign: " + e.toString()); -+ CMS.checkForAndAutoShutdown(); - throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString())); - } catch (IOException e) { - throw new EKRAException(CMS.getUserMessage("CMS_KRA_POA_ENCODE_FAILED_1", e.toString())); -diff --git a/base/ocsp/shared/conf/CS.cfg.in b/base/ocsp/shared/conf/CS.cfg.in -index 0cbe20b..cea8e65 100644 ---- a/base/ocsp/shared/conf/CS.cfg.in -+++ b/base/ocsp/shared/conf/CS.cfg.in -@@ -321,6 +321,11 @@ selftests.container.order.startup=OCSPPresence:critical, SystemCertsVerification - selftests.plugin.OCSPPresence.OcspSubId=ocsp - selftests.plugin.OCSPValidity.OcspSubId=ocsp - selftests.plugin.SystemCertsVerification.SubId=ocsp -+autoShutdown.allowed=false -+autoShutdown.crumbFile=[PKI_INSTANCE_PATH]/logs/autoShutdown.crumb -+autoShutdown.restart.count=0 -+autoShutdown.restart.enable=false -+autoShutdown.restart.max=3 - smtp.host=localhost - smtp.port=25 - subsystem.0.class=com.netscape.ocsp.OCSPAuthority -diff --git a/base/ocsp/src/com/netscape/ocsp/SigningUnit.java b/base/ocsp/src/com/netscape/ocsp/SigningUnit.java -index 0413f0c..5aff291 100644 ---- a/base/ocsp/src/com/netscape/ocsp/SigningUnit.java -+++ b/base/ocsp/src/com/netscape/ocsp/SigningUnit.java -@@ -275,6 +275,7 @@ public final class SigningUnit implements ISigningUnit { - throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())); - } catch (SignatureException e) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString())); -+ CMS.checkForAndAutoShutdown(); - throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())); - } - } -@@ -310,6 +311,7 @@ public final class SigningUnit implements ISigningUnit { - throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())); - } catch (SignatureException e) { - log(ILogger.LL_FAILURE, CMS.getLogMessage("OPERATION_ERROR", e.toString())); -+ CMS.checkForAndAutoShutdown(); - throw new EOCSPException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())); - } - } -diff --git a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java -index 467836b..2452a41 100644 ---- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java -+++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java -@@ -24,6 +24,8 @@ import java.io.FileReader; - import java.io.IOException; - import java.math.BigInteger; - import java.security.NoSuchAlgorithmException; -+import java.security.PublicKey; -+import java.security.SignatureException; - import java.security.cert.Certificate; - import java.security.cert.CertificateEncodingException; - import java.security.cert.X509CRL; -@@ -60,8 +62,14 @@ import netscape.security.x509.X509CertInfo; - - import org.apache.commons.lang.StringUtils; - import org.apache.xerces.parsers.DOMParser; -+import org.mozilla.jss.CryptoManager; - import org.mozilla.jss.CryptoManager.CertificateUsage; - import org.mozilla.jss.util.PasswordCallback; -+import org.mozilla.jss.crypto.PrivateKey; -+import org.mozilla.jss.crypto.Signature; -+import org.mozilla.jss.crypto.SignatureAlgorithm; -+import org.mozilla.jss.crypto.CryptoToken; -+ - import org.w3c.dom.Element; - import org.w3c.dom.NodeList; - -@@ -177,6 +185,7 @@ import com.netscape.cmsutil.net.ISocketFactory; - import com.netscape.cmsutil.password.IPasswordStore; - import com.netscape.cmsutil.password.NuxwdogPasswordStore; - import com.netscape.cmsutil.util.Utils; -+import com.netscape.cmsutil.util.Cert; - - public class CMSEngine implements ICMSEngine { - private static final String ID = "MAIN"; -@@ -187,13 +196,27 @@ public class CMSEngine implements ICMSEngine { - private static final String PROP_ENABLED = "enabled"; - private static final String SERVER_XML = "server.xml"; - -+ // used for testing HSM issues -+ public static final String PROP_SIGNED_AUDIT_CERT_NICKNAME = -+ "log.instance.SignedAudit.signedAuditCertNickname"; -+ - public static final SubsystemRegistry mSSReg = SubsystemRegistry.getInstance(); - - public String instanceDir; /* path to instance /cert- */ - private String instanceId; - private int pid; - -+ private CryptoManager mManager = null; -+ - private IConfigStore mConfig = null; -+ // AutoSD : AutoShutdown -+ private String mAutoSD_CrumbFile = null; -+ private boolean mAutoSD_Restart = false; -+ private int mAutoSD_RestartMax = 3; -+ private int mAutoSD_RestartCount = 0; -+ private String mSAuditCertNickName = null; -+ private PrivateKey mSigningKey = null; -+ private byte[] mSigningData = null; - @SuppressWarnings("unused") - private ISubsystem mOwner; - private long mStartupTime = 0; -@@ -1142,6 +1165,58 @@ public class CMSEngine implements ICMSEngine { - } - CMS.debug("CMSEngine: ready to init id=" + id); - ss.init(this, ssConfig); -+ -+ try { -+ /* -+ * autoShutdown.allowed=false -+ * autoShutdown.crumbFile=[PKI_INSTANCE_PATH]/logs/autoShutdown.crumb -+ * autoShutdown.restart.enable=false -+ * autoShutdown.restart.max=3 -+ * autoShutdown.restart.count=0 -+ */ -+ -+ mAutoSD_Restart = mConfig.getBoolean("autoShutdown.restart.enable", false); -+ CMS.debug("CMSEngine: restart at autoShutdown? " + mAutoSD_Restart); -+ if (mAutoSD_Restart) { -+ mAutoSD_RestartMax = mConfig.getInteger("autoShutdown.restart.max", 3); -+ CMS.debug("CMSEngine: restart max? " + mAutoSD_RestartMax); -+ mAutoSD_RestartCount = mConfig.getInteger("autoShutdown.restart.count", 0); -+ CMS.debug("CMSEngine: current restart count? " + mAutoSD_RestartCount); -+ } else { //!mAutoSD_Restart -+ mAutoSD_CrumbFile = mConfig.getString("autoShutdown.crumbFile", -+ instanceDir + "/logs/autoShutdown.crumb"); -+ CMS.debug("CMSEngine: autoShutdown crumb file path? " + mAutoSD_CrumbFile); -+ File crumb = new File(mAutoSD_CrumbFile); -+ try { -+ if (crumb.exists()) { -+ CMS.debug("CMSEngine: delete autoShutdown crumb file"); -+ crumb.delete(); -+ } -+ } catch (Exception e) { -+ CMS.debug("CMSEngine: delete autoShutdown crumb file failed; continue: " + e.toString()); -+ e.printStackTrace(); -+ } -+ } -+ -+ /* -+ * establish signing key reference using audit signing cert -+ * for HSM failover detection -+ */ -+ mSAuditCertNickName = mConfig.getString(PROP_SIGNED_AUDIT_CERT_NICKNAME); -+ mManager = CryptoManager.getInstance(); -+ org.mozilla.jss.crypto.X509Certificate cert = mManager.findCertByNickname(mSAuditCertNickName); -+ if (cert != null) { -+ CMS.debug("CMSEngine: found cert:" + mSAuditCertNickName); -+ } else { -+ CMS.debug("CMSEngine: cert not found:" + mSAuditCertNickName); -+ } -+ mSigningKey = mManager.findPrivKeyByCert(cert); -+ mSigningData = cert.getPublicKey().getEncoded(); -+ -+ } catch (Exception e) { -+ CMS.debug("CMSEngine: " + e.toString()); -+ } -+ - // add to id - subsystem hash table. - CMS.debug("CMSEngine: done init id=" + id); - CMS.debug("CMSEngine: initialized " + id); -@@ -1168,6 +1243,39 @@ public class CMSEngine implements ICMSEngine { - } - } - -+ /** -+ * sign some known data to determine if signing key is botched; -+ * if so, proceed to graceful shutdown -+ */ -+ public void checkForAndAutoShutdown() { -+ String method= "CMSEngine: checkForAndAutoShutdown: "; -+ CMS.debug(method + "begins"); -+ try { -+ boolean allowShutdown = mConfig.getBoolean("autoShutdown.allowed", false); -+ if ((!allowShutdown) || (mSigningKey == null) || -+ (mSigningData == null)) { -+ CMS.debug(method + "autoShutdown not allowed"); -+ return; -+ } -+ CMS.debug(method + "autoShutdown allowed"); -+ CryptoToken token = -+ ((org.mozilla.jss.pkcs11.PK11PrivKey) mSigningKey).getOwningToken(); -+ SignatureAlgorithm signAlg = Cert.mapAlgorithmToJss("SHA256withRSA"); -+ Signature signer = token.getSignatureContext(signAlg); -+ -+ signer.initSign(mSigningKey); -+ signer.update(mSigningData); -+ byte[] result = signer.sign(); -+ CMS.debug(method + " signining successful: " + new String(result)); -+ } catch (SignatureException e) { -+ CMS.debug(method + "autoShutdown for " + e.toString()); -+ CMS.autoShutdown(); -+ } catch (Exception e) { -+ CMS.debug(method + "continue for " + e.toString()); -+ } -+ CMS.debug(method + "passed; continue"); -+ } -+ - public void reinit(String id) throws EBaseException { - ISubsystem system = getSubsystem(id); - IConfigStore cs = mConfig.getSubStore(id); -@@ -1745,6 +1853,8 @@ public class CMSEngine implements ICMSEngine { - } - - public boolean areRequestsDisabled() { -+ CMS.debug("CMSEngine: in areRequestsDisabled"); -+ System.out.println("CMSEngine: in areRequestsDisabled"); - return CommandQueue.mShuttingDown; - } - -@@ -1767,23 +1877,21 @@ public class CMSEngine implements ICMSEngine { - return (File.separator.equals("\\")); - } - -- private void shutdownHttpServer() { -- -+ private void shutdownHttpServer(boolean restart) { - try { - String cmds[] = null; -- String cmd = "stop-cert"; -- if (isNT()) { -- // NT -- cmds = new String[3]; -- cmds[0] = "cmd"; -- cmds[1] = "/c"; -- cmds[2] = instanceDir + "\\" + cmd; -+ String cmd = "stop"; -+ if (restart) { -+ cmd = "restart"; -+ } -+ -+ cmds = new String[3]; -+ cmds[0] = "/usr/bin/systemctl"; -+ cmds[1] = cmd; -+ if (startedByNuxwdog()) { -+ cmds[2] = "pki-tomcatd-nuxwdog@" + instanceId + ".service"; - } else { -- // UNIX -- cmds = new String[3]; -- cmds[0] = "/bin/sh"; -- cmds[1] = "-c"; -- cmds[2] = instanceDir + "/" + cmd; -+ cmds[2] = "pki-tomcatd@" + instanceId + ".service"; - } - - Process process = Runtime.getRuntime().exec(cmds); -@@ -1848,14 +1956,52 @@ public class CMSEngine implements ICMSEngine { - * exceptions are ignored. process exists at end to force exit. - * Added extra call to shutdown the web server. - */ -- - public void forceShutdown() { -+ CMS.debug("CMSEngine.forceShutdown()...begins graceful shutdown."); -+ autoShutdown(false /*no restart*/); -+ } - -+ public void autoShutdown() { -+ autoShutdown(mAutoSD_Restart /* controlled by config */); -+ } -+ -+ public void autoShutdown(boolean restart) { -+ String method = "CMSEngine.autoShutdown(): "; - Logger.getLogger().log(ILogger.EV_SYSTEM, ILogger.S_ADMIN, - ILogger.LL_INFO, Constants.SERVER_SHUTDOWN_MESSAGE); -+ CMS.debug(method + "...with restart=" + restart); -+ -+ // update restart tracker so we don't go into infinite restart loop -+ if (restart == true) { -+ CMS.debug(method + "...checking autoShutdown.restart trackers"); -+ if (mAutoSD_RestartCount >= mAutoSD_RestartMax) { -+ mAutoSD_Restart = false; -+ mConfig.putBoolean("autoShutdown.restart.enable", mAutoSD_Restart); -+ CMS.debug(method + "...autoShutdown.restart.max reached, disabled autoShutdown.restart.enable"); -+ } else { -+ mAutoSD_RestartCount++; -+ mConfig.putInteger("autoShutdown.restart.count", mAutoSD_RestartCount); -+ CMS.debug(method + "...autoShutdown.restart.max not reached, increment autoShutdown.restart.count"); -+ } -+ try { -+ mConfig.commit(false); -+ } catch (EBaseException e) { -+ } -+ } else { -+ // leave a crumb file to be monitored by external monitor -+ File crumb = new File(mAutoSD_CrumbFile); -+ try { -+ crumb.createNewFile(); -+ } catch (IOException e) { -+ CMS.debug(method + " create autoShutdown crumb file failed on " + -+ mAutoSD_CrumbFile + "; nothing to do...keep shutting down:" + e.toString()); -+ e.printStackTrace(); -+ } -+ } - -- CMS.debug("CMSEngine.forceShutdown()"); -- -+/* cfu: not sure why it's doing a commandQueue but not registering any -+ * service to wait on... what does this do to wait on an empty queue? -+ * - CommandQueue commandQueue = new CommandQueue(); - Thread t1 = new Thread(commandQueue); - -@@ -1875,12 +2021,17 @@ public class CMSEngine implements ICMSEngine { - } - timeOut = time.getTime(); - } -- terminateRequests(); -+*/ - -+ if (areRequestsDisabled() == false) { -+ disableRequests(); -+ } -+ terminateRequests(); - shutdownSubsystems(mFinalSubsystems); - shutdownSubsystems(mDynSubsystems); - shutdownSubsystems(mStaticSubsystems); -- shutdownHttpServer(); -+ -+ shutdownHttpServer(restart); - - } - -diff --git a/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java b/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java -index b91b4cf..989be3f 100644 ---- a/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java -+++ b/base/server/cmscore/src/com/netscape/cmscore/security/KeyCertUtil.java -@@ -268,6 +268,8 @@ public class KeyCertUtil { - } catch (TokenException e) { - throw new EBaseException(CMS.getUserMessage("CMS_BASE_TOKEN_ERROR_1", e.toString())); - } catch (SignatureException e) { -+ CMS.debug("CertKeyUtil.signCert: "+ e.toString()); -+ CMS.checkForAndAutoShutdown(); - throw new EBaseException(CMS.getUserMessage("CMS_BASE_SIGNED_FAILED", e.toString())); - } catch (InvalidKeyException e) { - throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_KEY_1", e.toString())); -diff --git a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java -index 404832c..36a263e 100644 ---- a/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java -+++ b/base/server/test/com/netscape/cmscore/app/CMSEngineDefaultStub.java -@@ -545,6 +545,12 @@ public class CMSEngineDefaultStub implements ICMSEngine { - public void forceShutdown() { - } - -+ public void autoShutdown() { -+ } -+ -+ public void checkForAndAutoShutdown() { -+ } -+ - public IPasswordStore getPasswordStore() { - return null; - } diff --git a/pki-core-Issue-IE-11-warning.patch b/pki-core-Issue-IE-11-warning.patch deleted file mode 100644 index a14fb47..0000000 --- a/pki-core-Issue-IE-11-warning.patch +++ /dev/null @@ -1,153 +0,0 @@ -commit 0baf14ad496d18991a83f211b4b60d1811e21fb3 -Author: Jack Magne -Date: Thu Aug 20 12:06:32 2015 -0700 - - Internet Explorer 11 not working browser warning. - - Related to ticket #1575 Internet Explorer 11: caUserCert request submission fails using the EE page. - - This patch will only do the following: - - Detect IE when IE11 is being used. Before this IE11 was mistaken for Firefox. - Detect IE11 specifically and warn the user that there is no support. - - This ticket will live to se we can fix this properly by porting the current - VBS script to Javascript to support cert enrollment on IE 11. - -diff --git a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template -index 2c01b9a..01b94ab 100644 ---- a/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template -+++ b/base/ca/shared/webapps/ca/ee/ca/ProfileSelect.template -@@ -47,6 +47,27 @@ var key = new Object(); - key.type = "EC"; - keyList[1] = key; - -+function isIE() { -+ if ( "ActiveXObject" in window ) { -+ return true; -+ } -+ return false; -+ } -+ -+ function isIE11() { -+ -+ if ( !(window.ActiveXObject) && "ActiveXObject" in window ) { -+ return true; -+ } -+ return false; -+ } -+ -+function getIE11Warning() { -+ document.write('

Warning: Internet Explore Version 11 is not currently supported for certain enrollment operations. Please use an earlier version of the browser.

'); -+ document.write('
'); -+} -+ -+ - function getKeyStrengthTableForKeyGen() { - - document.writeln("
"); -@@ -145,7 +166,7 @@ function keyTypeOptions (keyPurpose) - if (keyFound == 0) { - keyType = "RSA"; - } -- if ((navigator.appName == "Microsoft Internet Explorer") && -+ if ((isIE()) && - ((navigator.appVersion).indexOf("NT 6.") == -1)) { - keyType = "RSA"; - } -@@ -156,7 +177,7 @@ function keyTypeOptions (keyPurpose) - function translateCurveName (name) - { - var translated = ""; -- if (navigator.appName == "Microsoft Internet Explorer") { -+ if (isIE()) { - if (name == "nistp256" || name == "ECDSA_P256") { - translated = "ECDSA_P256"; - } else if (name == "nistp384" || name == "ECDSA_P384") { -@@ -207,7 +228,7 @@ function keyLengthsCurvesOptions (keyPurpose) - } - } - } -- if ((navigator.appName == "Microsoft Internet Explorer") && -+ if ((isIE()) && - ((navigator.appVersion).indexOf("NT 6.") == -1)) { - keyType = "RSA"; - } -@@ -222,7 +243,7 @@ function keyLengthsCurvesOptions (keyPurpose) - if (keyType != "EC" && !isNumeric(value)) { - included = false; - } else if (keyType == "EC" && -- navigator.appName == "Microsoft Internet Explorer" && -+ isIE() && - value != "nistp256" && value != "nistp384" && value != "nistp521" & - value != "ECDSA_P256" && value != "ECDSA_P384" && value != "ECDSA_P521") { - included = false; -@@ -245,7 +266,7 @@ function keyLengthsCurvesOptions (keyPurpose) - if (keyType != "EC") { - options = '
KeyGen Key Strength Info
Key Type High Grade Medium Grade