diff --git a/SOURCES/pki-core-rhel-7-9-rhcs-9-7-bu-6.0.patch b/SOURCES/pki-core-rhel-7-9-rhcs-9-7-bu-6.0.patch new file mode 100644 index 0000000..c25cb79 --- /dev/null +++ b/SOURCES/pki-core-rhel-7-9-rhcs-9-7-bu-6.0.patch @@ -0,0 +1,119 @@ +From 54a1664ddd7b6b2a8b2a0c7f0eec403507c246c1 Mon Sep 17 00:00:00 2001 +From: Jack Magne +Date: Thu, 15 Apr 2021 18:42:31 -0400 +Subject: [PATCH 1/2] pkispawn fails against 389-ds 1.4.3.19 #3458 (#3465) + + Add suggested patch from stanislavlevin to solve this issue. + Also add f34 to the ipa tests,this time really add the tests. + Upon further review, back out of f34 tests until the infractructure + supports it. + + Also hardcode tomcat app setting in spec file for the moment to + avoid possible glitches on certain platform. + + Co-authored-by: Jack Magne + +(cherry picked from commit 9e1ef2557403d1a5117858322af0ae7fc1f4fd44) +--- + .../src/com/netscape/cmscore/apps/CMSEngine.java | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +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 08e6f8d..db341d5 100644 +--- a/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java ++++ b/base/server/cmscore/src/com/netscape/cmscore/apps/CMSEngine.java +@@ -287,9 +287,8 @@ public class CMSEngine implements ICMSEngine { + + private static final int PW_OK =0; + private static final int PW_BAD_SETUP = 1; +- private static final int PW_INVALID_PASSWORD = 2; ++ private static final int PW_INVALID_CREDENTIALS = 2; + private static final int PW_CANNOT_CONNECT = 3; +- private static final int PW_NO_USER = 4; + private static final int PW_MAX_ATTEMPTS = 3; + + +@@ -365,7 +364,7 @@ public class CMSEngine implements ICMSEngine { + + for (String tag : tags) { + int iteration = 0; +- int result = PW_INVALID_PASSWORD; ++ int result = PW_INVALID_CREDENTIALS; + String binddn; + String authType; + LdapConnInfo connInfo = null; +@@ -450,10 +449,10 @@ public class CMSEngine implements ICMSEngine { + String passwd = mPasswordStore.getPassword(tag, iteration); + result = testLDAPConnection(tag, connInfo, binddn, passwd); + iteration++; +- } while ((result == PW_INVALID_PASSWORD) && (iteration < PW_MAX_ATTEMPTS)); ++ } while ((result == PW_INVALID_CREDENTIALS) && (iteration < PW_MAX_ATTEMPTS)); + + if (result != PW_OK) { +- if ((result == PW_NO_USER) && (tag.equals("replicationdb"))) { ++ if ((result == PW_INVALID_CREDENTIALS) && (tag.equals("replicationdb"))) { + System.out.println( + "CMSEngine: init(): password test execution failed for replicationdb" + + "with NO_SUCH_USER. This may not be a latest instance. Ignoring .."); +@@ -473,8 +472,10 @@ public class CMSEngine implements ICMSEngine { + public int testLDAPConnection(String name, LdapConnInfo info, String binddn, String pwd) { + int ret = PW_OK; + +- if (StringUtils.isEmpty(pwd)) +- return PW_INVALID_PASSWORD; ++ if (StringUtils.isEmpty(pwd)) { ++ return PW_INVALID_CREDENTIALS; ++ } ++ + + String host = info.getHost(); + int port = info.getPort(); +@@ -488,12 +489,9 @@ public class CMSEngine implements ICMSEngine { + } catch (LDAPException e) { + switch (e.getLDAPResultCode()) { + case LDAPException.NO_SUCH_OBJECT: +- System.out.println("testLDAPConnection: The specified user " + binddn + " does not exist"); +- ret = PW_NO_USER; +- break; + case LDAPException.INVALID_CREDENTIALS: + System.out.println("testLDAPConnection: Invalid Password"); +- ret = PW_INVALID_PASSWORD; ++ ret = PW_INVALID_CREDENTIALS; + break; + default: + System.out.println("testLDAPConnection: Unable to connect to " + name + ": " + e); +-- +1.8.3.1 + + +From d511e7f255350881333b14ba9b68a879335abddc Mon Sep 17 00:00:00 2001 +From: Christina Fu +Date: Wed, 21 Apr 2021 17:32:42 -0700 +Subject: [PATCH 2/2] bug1949656 CRMF requests with non-SKID extensions + +This patch address the issue where if a CRMF request bears any extension +other than SKID then it fails to process. + +fixes https://bugzilla.redhat.com/show_bug.cgi?id=1949656 + +(cherry picked from commit fe133f9affcde7b56fe69bf0c7daef6930749e74) +--- + base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java +index f9903c6..b7fdb9e 100644 +--- a/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java ++++ b/base/server/cms/src/com/netscape/cms/profile/common/EnrollProfile.java +@@ -2286,7 +2286,7 @@ public abstract class EnrollProfile extends BasicProfile + ext = new SubjectKeyIdentifierExtension(false, + jssext.getExtnValue().toByteArray()); + } else { +- new Extension(oid, isCritical, extValue); ++ ext = new Extension(oid, isCritical, extValue); + } + + extensions.parseExtension(ext); +-- +1.8.3.1 + diff --git a/SOURCES/pki-core-rhel-7-9-rhcs-9-7-bu-6.1.patch b/SOURCES/pki-core-rhel-7-9-rhcs-9-7-bu-6.1.patch new file mode 100644 index 0000000..5ec95bd --- /dev/null +++ b/SOURCES/pki-core-rhel-7-9-rhcs-9-7-bu-6.1.patch @@ -0,0 +1,760 @@ +From 6b5c8073187a69c09000e88394465228f08d64be Mon Sep 17 00:00:00 2001 +From: Christina Fu +Date: Wed, 28 Apr 2021 16:26:46 -0700 +Subject: [PATCH 1/4] Bug1911472 Revoke via REST API not working when Agent + certificate not issued by CA + +This patch resolves the issue that when a client cert is issued by an +external CA, the revocation check inside the CA REST service handler +(ca/src/org/dogtagpki/server/ca/rest/CertService.java) +assumes that all client certs are issued by this CA. +The fix is to check the issuer, and add an option, allowExtCASignedAgentCerts +to allow for external CA signed agent certs. +If the issuer is external, and ca.allowExtCASignedAgentCerts is true, then the +internal cert status check is bypassed and to rely on OCSP enablement +(enableOCSP) in server.xml. +The ca.allowExtCASignedAgentCerts config param currently is only used in +the rest revocation case. It is not used anywhere else (not even unrevocation). + +fixes https://bugzilla.redhat.com/show_bug.cgi?id=1911472 + +(cherry picked from commit 62f680f98e5bf9a3e6d44279fcc735e65c6d8d91) +--- + .../src/com/netscape/ca/CertificateAuthority.java | 6 ++++ + .../org/dogtagpki/server/ca/rest/CertService.java | 38 +++++++++++++++++++--- + .../netscape/certsrv/ca/ICertificateAuthority.java | 2 ++ + 3 files changed, 41 insertions(+), 5 deletions(-) + +diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java +index bd99344..c519a5a 100644 +--- a/base/ca/src/com/netscape/ca/CertificateAuthority.java ++++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java +@@ -333,6 +333,7 @@ public class CertificateAuthority + + private boolean mByName = true; + ++ private boolean mAllowExtCASignedAgentCerts = false; + private boolean mUseNonces = true; + private int mMaxNonces = 100; + +@@ -454,6 +455,10 @@ public class CertificateAuthority + return mPolicy.getPolicyProcessor(); + } + ++ public boolean allowExtCASignedAgentCerts() { ++ return mAllowExtCASignedAgentCerts; ++ } ++ + public boolean noncesEnabled() { + return mUseNonces; + } +@@ -574,6 +579,7 @@ public class CertificateAuthority + if (initSigUnitSucceeded) + checkForNewerCert(); + ++ mAllowExtCASignedAgentCerts = mConfig.getBoolean("allowExtCASignedAgentCerts", false); + mUseNonces = mConfig.getBoolean("enableNonces", true); + mMaxNonces = mConfig.getInteger("maxNumberOfNonces", 100); + +diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java +index 000ce32..74d3a5d 100644 +--- a/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java ++++ b/base/ca/src/org/dogtagpki/server/ca/rest/CertService.java +@@ -44,6 +44,7 @@ import netscape.security.x509.AlgorithmId; + import netscape.security.x509.CRLExtensions; + import netscape.security.x509.CRLReasonExtension; + import netscape.security.x509.RevocationReason; ++import netscape.security.x509.X500Name; + import netscape.security.x509.X509CertImpl; + import netscape.security.x509.X509ExtensionException; + import netscape.security.x509.X509Key; +@@ -172,6 +173,8 @@ public class CertService extends PKIService implements CertResource { + return unrevokeCert(id); + } + ++ String caIssuerDN = null; ++ X500Name caX500DN = null; + RevocationProcessor processor; + try { + processor = new RevocationProcessor("caDoRevoke-agent", getLocale(headers)); +@@ -190,6 +193,8 @@ public class CertService extends PKIService implements CertResource { + + processor.setAuthority(authority); + ++ caX500DN = (X500Name) authority.getCACert().getIssuerDN(); ++ + } catch (EBaseException e) { + throw new PKIException(e.getMessage()); + } +@@ -209,12 +214,35 @@ public class CertService extends PKIService implements CertResource { + if (clientCert != null) { + clientSerialNumber = clientCert.getSerialNumber(); + clientSubjectDN = clientCert.getSubjectDN().toString(); +- clientRecord = processor.getCertificateRecord(clientSerialNumber); + +- // Verify client cert is not revoked. +- // TODO: This should be checked during authentication. +- if (clientRecord.getStatus().equals(ICertRecord.STATUS_REVOKED)) { +- throw new UnauthorizedException(CMS.getLogMessage("CMSGW_UNAUTHORIZED")); ++ X500Name x500issuerDN = (X500Name) clientCert.getIssuerDN(); ++ /* ++ * internal revocation check only to be conducted for certs ++ * issued by this CA ++ * For client certs issued by external CAs, TLS mutual auth ++ * would have completed the authenticaton/verification if ++ * OCSP was enabled; ++ * Furthermore, prior to the actual revocation, client cert ++ * is mapped against the agent group database for proper ++ * privilege regardless of the issuer. ++ */ ++ if (x500issuerDN.equals(caX500DN)) { ++ CMS.debug("CertService.revokeCert: client cert issued by this CA"); ++ clientRecord = processor.getCertificateRecord(clientSerialNumber); ++ ++ // Verify client cert is not revoked. ++ // TODO: This should be checked during authentication. ++ if (clientRecord.getStatus().equals(ICertRecord.STATUS_REVOKED)) { ++ throw new UnauthorizedException(CMS.getLogMessage("CMSGW_UNAUTHORIZED")); ++ } ++ } else { ++ CMS.debug("CertService.revokeCert: client cert not issued by this CA"); ++ if (!authority.allowExtCASignedAgentCerts()) { ++ CMS.debug("CertService.revokeCert: allowExtCASignedAgentCerts false;"); ++ throw new UnauthorizedException(CMS.getLogMessage("CMSGW_UNAUTHORIZED")); ++ } else { ++ CMS.debug("CertService.revokeCert: allowExtCASignedAgentCerts true;"); ++ } + } + } + +diff --git a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java +index d941624..c5604e3 100644 +--- a/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java ++++ b/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java +@@ -136,6 +136,8 @@ public interface ICertificateAuthority extends ISubsystem { + */ + public IPolicyProcessor getPolicyProcessor(); + ++ public boolean allowExtCASignedAgentCerts(); ++ + public boolean noncesEnabled(); + + public Map getNonces(HttpServletRequest request, String name); +-- +1.8.3.1 + + +From a2599f832ed3036f84d507dce36548e0ca1351d0 Mon Sep 17 00:00:00 2001 +From: Jack Magne +Date: Fri, 30 Apr 2021 20:10:58 -0400 +Subject: [PATCH 2/4] Fix Bug #1955633 - Recovery of Keys migrated to latest + version of KRA fail to recover and result in Null Point Exception + [rhel-7.9.z] + +This is a very simple fix to prevent the reported null pointer exception. +Checking in directly using the trivial checkin policy. + +(cherry picked from commit c792a8545aecdb4ec17b1a18a401fcff288f877e) +--- + base/server/cmscore/src/com/netscape/cmscore/dbs/KeyRecord.java | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/KeyRecord.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/KeyRecord.java +index 556c4a7..fd8fff9 100644 +--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/KeyRecord.java ++++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/KeyRecord.java +@@ -506,6 +506,10 @@ public class KeyRecord implements IDBObj, IKeyRecord { + } + + public Boolean isEncrypted() throws EBaseException { ++ if(mMetaInfo == null) { ++ return null; ++ } ++ + String encrypted = (String) mMetaInfo.get(KeyRecordParser.OUT_PL_ENCRYPTED); + if (encrypted == null) + return null; +-- +1.8.3.1 + + +From 201cef17ad2a6fcc84277b9a62c7e986212c0622 Mon Sep 17 00:00:00 2001 +From: jmagne +Date: Thu, 6 May 2021 17:17:37 -0700 +Subject: [PATCH 3/4] Fix: Bug 1942687 - TPS not populating Token Policy, or + switching PIN_RESET=YES to NO . (#3510) + +Now the behavior will be the following: + + When a new token entry gets created in the token db, due to a token operation such + as format or enrollment, the db entry will get populated with the contents of the + CS.cfg value: + ex: + tokendb.defaultPolicy=RE_ENROLL=YES;RENEW=NO;FORCE_FORMAT=NO;PIN_RESET=NO;RESET_PIN_RESET_TO_NO=NO + + Now the value of RESET_PIN_RESET_TO_NO is actually observed. + If this value is set to YES and pin reset is allowed, after a successful pin reset, + the value of PIN_RESET will be set to NO, thus not allowing further pin resets on this + token, until the value is manually changed in the token db entry. + + Also, the class itself has been simplified to allow the cuid token number at constructor + time. Now if another token is desired , we must instantiate a new TPSTokenPolicy object for + that additional token. + +Co-authored-by: Jack Magne +(cherry picked from commit 5f25323a9098af496196dbff0e7f0e89ee7621de) +--- + .../org/dogtagpki/server/tps/TPSTokenPolicy.java | 133 ++++++++++++++++++--- + .../src/org/dogtagpki/server/tps/TPSTokendb.java | 4 + + .../server/tps/processor/TPSEnrollProcessor.java | 23 ++-- + .../server/tps/processor/TPSPinResetProcessor.java | 14 ++- + .../server/tps/processor/TPSProcessor.java | 21 ++++ + 5 files changed, 165 insertions(+), 30 deletions(-) + +diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java b/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java +index 4d7af48..685319e 100644 +--- a/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java ++++ b/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java +@@ -40,18 +40,31 @@ public class TPSTokenPolicy { + private boolean force_format = false; + private boolean pin_reset = true; + private boolean reset_pin_reset_to_no = false; ++ private String cuid = null; + +- public TPSTokenPolicy (TPSSubsystem tps) throws TPSException { ++ //Construct with a single token in mind. Load the token's config from ++ //the db after the default. All operations will then be on this token. ++ // ++ public TPSTokenPolicy (TPSSubsystem tps,String cuid) throws TPSException { + if (tps == null) { + String msg = "TPSTokenPolicy.TPSTokenPolicy: tps cannnot be null"; + CMS.debug(msg); + throw new TPSException(msg); + } ++ if (cuid == null) { ++ String msg = "TPSTokenPolicy.TPSTokenPolicy: cuid cannnot be null"; ++ CMS.debug(msg); ++ throw new TPSException(msg); ++ } ++ + this.tps = tps; +- // init from config first ++ // Get the CS.cfg defaults first + String policySetString = getDefaultPolicySetString(); + parsePolicySetString(policySetString); + ++ this.cuid = cuid; ++ //Read from the token db once and write at the end if needed ++ getUpdatedPolicy(); + } + + public String getDefaultPolicySetString() { +@@ -92,6 +105,41 @@ public class TPSTokenPolicy { + } + } + ++ /* Take the current state of the policyt variables, create a new policy string, ++ * and write the new value for the provided token cuid. ++ */ ++ public void updatePolicySet() throws TPSException { ++ ++ String method = "TPSTokenPolicy.updatePolicySet: "; ++ String msg = method + "Can't update token policy string to database."; ++ ++ TokenRecord tokenRecord = null; ++ String policySetString = null; ++ try { ++ tokenRecord = tps.tdb.tdbGetTokenEntry(this.cuid); ++ } catch (Exception e) { ++ throw new TPSException(e.toString() + " " + msg); ++ } ++ ++ String newPolicy = ""; ++ ++ newPolicy += "RE_ENROLL=" + getFromBool(re_enroll); ++ newPolicy += ";RENEW=" + getFromBool(renew); ++ newPolicy += ";FORCE_FORMAT=" + getFromBool(force_format); ++ newPolicy += ";PIN_RESET=" + getFromBool(pin_reset); ++ newPolicy += ";RESET_PIN_RESET_TO_NO=" + getFromBool(reset_pin_reset_to_no); ++ newPolicy += ";RENEW_KEEP_OLD_ENC_CERTS=" + getFromBool(renew_keep_old_enc_certs); ++ ++ CMS.debug(method + "newPolicy: " + newPolicy); ++ tokenRecord.setPolicy(newPolicy); ++ try { ++ tps.tdb.tdbUpdateTokenEntry(tokenRecord); ++ } catch(Exception e) { ++ throw new TPSException(e.toString() + " " + msg); ++ } ++ ++ } ++ + /* + * getBool translates string to boolean: + * true: "YES", "yes", "TRUE", "true" +@@ -114,12 +162,19 @@ public class TPSTokenPolicy { + return defaultBool; + } + +- private void getUpdatedPolicy(String cuid) { ++ private String getFromBool(boolean value) { ++ if(value == true) ++ return "YES"; ++ ++ return "NO"; ++ } ++ ++ private void getUpdatedPolicy() { + // note: default policy already initialized in the constructor + TokenRecord tokenRecord = null; + String policySetString = null; + try { +- tokenRecord = tps.tdb.tdbGetTokenEntry(cuid); ++ tokenRecord = tps.tdb.tdbGetTokenEntry(this.cuid); + } catch (Exception e) { + // just take the default; + return; +@@ -129,38 +184,82 @@ public class TPSTokenPolicy { + parsePolicySetString(policySetString); + } + +- public boolean isAllowedTokenPinReset(String cuid) { +- getUpdatedPolicy(cuid); ++ // Note we only want to allow one cuid to be operated upon ++ // by this class, since we are going to allow values to be changed ++ // as well as written. ++ ++ public boolean isAllowedTokenPinReset() { ++ ++ return reset_pin_reset_to_no; ++ } ++ ++ // Add better named version to get the value ++ // reset_pin_reset_to_no ++ ++ public boolean isAllowedResetPinResetToNo() { + + return reset_pin_reset_to_no; ++ + } + +- public boolean isAllowedPinReset(String cuid) { +- getUpdatedPolicy(cuid); ++ public boolean isAllowedPinReset() { + + return pin_reset; + } + +- public boolean isForceTokenFormat(String cuid) { +- getUpdatedPolicy(cuid); ++ public boolean isForceTokenFormat() { + + return force_format; + } + +- public boolean isAllowdTokenReenroll(String cuid) { +- getUpdatedPolicy(cuid); ++ public boolean isAllowdTokenReenroll() { + + return re_enroll; + } + +- public boolean isAllowdRenewSaveOldEncCerts(String cuid) { +- getUpdatedPolicy(cuid); ++ public boolean isAllowdRenewSaveOldEncCerts() { ++ + return renew_keep_old_enc_certs; + } + +- public boolean isAllowdTokenRenew(String cuid) { +- getUpdatedPolicy(cuid); ++ public boolean isAllowdTokenRenew() { + + return renew; + } +-} +\ No newline at end of file ++ ++ public void setAllowedTokenPinReset(boolean value) { ++ ++ reset_pin_reset_to_no = value; ++ } ++ ++ public void setAllowedResetPinResetToNo(boolean value) { ++ ++ reset_pin_reset_to_no = value; ++ } ++ ++ public void setAllowedPinReset(boolean value) { ++ ++ pin_reset = value; ++ } ++ ++ public void setForceTokenFormat(boolean value) { ++ ++ force_format = value; ++ } ++ ++ public void setAllowdTokenReenroll(boolean value) { ++ ++ re_enroll = value; ++ } ++ ++ public void setAllowdRenewSaveOldEncCerts(boolean value) { ++ ++ renew_keep_old_enc_certs = value; ++ } ++ ++ public void setAllowdTokenRenew(boolean value) { ++ ++ renew = value; ++ } ++ ++} +diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java +index 7434502..b58c24f 100644 +--- a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java ++++ b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java +@@ -200,9 +200,13 @@ public class TPSTokendb { + + public void tdbAddTokenEntry(TokenRecord tokenRecord, TokenStatus status) + throws Exception { ++ ++ String method = "TPSTokendb.tdbAddTokenEntry: "; + tokenRecord.setTokenStatus(status); + + tps.tokenDatabase.addRecord(tokenRecord.getId(), tokenRecord); ++ ++ CMS.debug(method + "Added tokenRecord."); + } + + public void tdbUpdateTokenEntry(TokenRecord tokenRecord) +diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java +index 5175344..2d8c89f 100644 +--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java ++++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java +@@ -95,7 +95,7 @@ public class TPSEnrollProcessor extends TPSProcessor { + String logMsg = null; + String auditInfo = null; + TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); +- TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps); ++ TPSTokenPolicy tokenPolicy = null; + IConfigStore configStore = CMS.getConfigStore(); + String configName; + +@@ -128,12 +128,13 @@ public class TPSEnrollProcessor extends TPSProcessor { + tokenRecord = isTokenRecordPresent(appletInfo); + + if (tokenRecord != null) { +- CMS.debug(method + " found token..."); ++ CMS.debug(method + " found token... policy: " + tokenRecord.getPolicy()); + isTokenPresent = true; + } else { + CMS.debug(method + " token does not exist in tokendb... create one in memory"); + tokenRecord = new TokenRecord(); + tokenRecord.setId(appletInfo.getCUIDhexStringPlain()); ++ fillTokenRecordDefaultPolicy(tokenRecord); + } + + fillTokenRecord(tokenRecord, appletInfo); +@@ -332,13 +333,14 @@ public class TPSEnrollProcessor extends TPSProcessor { + " to " + newState); + } + +- do_force_format = tokenPolicy.isForceTokenFormat(cuid); ++ tokenPolicy = new TPSTokenPolicy(tps,cuid); ++ do_force_format = tokenPolicy.isForceTokenFormat(); + if (do_force_format) + CMS.debug(method + " Will force format first due to policy."); + + if (!isExternalReg && +- !tokenPolicy.isAllowdTokenReenroll(cuid) && +- !tokenPolicy.isAllowdTokenRenew(cuid)) { ++ !tokenPolicy.isAllowdTokenReenroll() && ++ !tokenPolicy.isAllowdTokenRenew()) { + CMS.debug(method + " token renewal or reEnroll disallowed "); + logMsg = "Operation renewal or reEnroll for CUID " + cuid + + " Disabled"; +@@ -524,7 +526,7 @@ public class TPSEnrollProcessor extends TPSProcessor { + // at this point, enrollment, renewal, or recovery have been processed accordingly; + if (!isExternalReg && + status == TPSStatus.STATUS_RENEWAL_IS_PROCESSED && +- tokenPolicy.isAllowdTokenRenew(cuid)) { ++ tokenPolicy.isAllowdTokenRenew()) { + renewed = true; + CMS.debug(method + " renewal happened.. "); + } +@@ -1110,7 +1112,7 @@ public class TPSEnrollProcessor extends TPSProcessor { + IConfigStore configStore = CMS.getConfigStore(); + String configName; + TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); +- TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps); ++ TPSTokenPolicy tokenPolicy = null; + + ArrayList tokenRecords = null; + try { +@@ -1157,7 +1159,8 @@ public class TPSEnrollProcessor extends TPSProcessor { + + } else if (tokenRecord.getTokenStatus() == TokenStatus.ACTIVE) { + // current token is already active; renew if allowed +- if (tokenPolicy.isAllowdTokenRenew(aInfo.getCUIDhexStringPlain())) { ++ tokenPolicy = new TPSTokenPolicy(tps,aInfo.getCUIDhexStringPlain()); ++ if (tokenPolicy.isAllowdTokenRenew()) { + return processRenewal(certsInfo, channel, aInfo, tokenRecord); + } else { + logMsg = "token is already active; can't renew because renewal is not allowed; will re-enroll if allowed"; +@@ -1658,9 +1661,9 @@ public class TPSEnrollProcessor extends TPSProcessor { + + //See if policy calls for this feature + +- TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps); ++ TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps,tokenRecord.getId()); + +- boolean recoverOldEncCerts = tokenPolicy.isAllowdRenewSaveOldEncCerts(tokenRecord.getId()); ++ boolean recoverOldEncCerts = tokenPolicy.isAllowdRenewSaveOldEncCerts(); + CMS.debug(method + " Recover Old Encryption Certs for Renewed Certs: " + recoverOldEncCerts); + if (oldEncCertsToRecover.size() > 0 && recoverOldEncCerts == true) { + CMS.debug("About to attempt to recover old encryption certs just renewed."); +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 805af20..2ee9186 100644 +--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSPinResetProcessor.java ++++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSPinResetProcessor.java +@@ -121,14 +121,14 @@ public class TPSPinResetProcessor extends TPSProcessor { + TPSStatus.STATUS_ERROR_UNKNOWN_TOKEN); + } + +- TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps); +- + fillTokenRecord(tokenRecord, appletInfo); + session.setTokenRecord(tokenRecord); + + String cuid = appletInfo.getCUIDhexStringPlain(); + String tokenType = null; + ++ TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps,cuid); ++ + if(isExternalReg) { + CMS.debug(method + " isExternalReg: ON"); + +@@ -309,7 +309,7 @@ public class TPSPinResetProcessor extends TPSProcessor { + + } + +- boolean pinResetAllowed = tokenPolicy.isAllowedPinReset(tokenRecord.getId()); ++ boolean pinResetAllowed = tokenPolicy.isAllowedPinReset(); + + CMS.debug(method + ": PinResetPolicy: Pin Reset Allowed: " + pinResetAllowed); + logMsg = method + " PinReset Policy forbids pin reset operation."; +@@ -362,6 +362,14 @@ public class TPSPinResetProcessor extends TPSProcessor { + throw new TPSException(logMsg, TPSStatus.STATUS_ERROR_UPDATE_TOKENDB_FAILED); + } + ++ //If policy tells us to disallow pin reset after ++ //a successfull pin reset, do so. ++ // ++ if(tokenPolicy.isAllowedResetPinResetToNo()) { ++ tokenPolicy.setAllowedPinReset(false); ++ tokenPolicy.updatePolicySet(); ++ CMS.debug(method + ": Updating pin reset policy to NO."); ++ } + CMS.debug(method + ": Token Pin successfully reset!"); + + } +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 baf0671..cadab1d 100644 +--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java ++++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java +@@ -1531,6 +1531,26 @@ public class TPSProcessor { + + } + ++ protected void fillTokenRecordDefaultPolicy(TokenRecord tokenRecord) throws TPSException { ++ ++ String method = "TPSProcessor.fillTokenRecordDefaultPolicy: "; ++ ++ try { ++ IConfigStore configStore = CMS.getConfigStore(); ++ ++ String config = "tokendb.defaultPolicy"; ++ String defaultPolicy = configStore.getString(config); ++ ++ CMS.debug(method + " default token policy: " + defaultPolicy); ++ ++ tokenRecord.setPolicy(defaultPolicy); ++ } catch (Exception e) { ++ CMS.debug(method + "Problem with adding the default policy to the token."); ++ throw new TPSException(e.toString(),TPSStatus.STATUS_ERROR_MISCONFIGURATION); ++ } ++ ++ } ++ + protected TokenRecord isTokenRecordPresent(AppletInfo appletInfo) throws TPSException { + + if (appletInfo == null) { +@@ -2353,6 +2373,7 @@ public class TPSProcessor { + try { + tps.tdb.tdbAddTokenEntry(tokenRecord, TokenStatus.UNFORMATTED); + tps.tdb.tdbActivity(ActivityDatabase.OP_ADD, tokenRecord, session.getIpAddress(), logMsg, "success"); ++ fillTokenRecordDefaultPolicy(tokenRecord); + CMS.debug("TPSProcessor.format: token added"); + } catch (Exception e) { + logMsg = logMsg + ":" + e.toString(); +-- +1.8.3.1 + +From e83bcc4f045bd6ad43798ff38306ab3c4bc4a52d Mon Sep 17 00:00:00 2001 +From: Chris Kelley +Date: Fri, 7 May 2021 14:05:18 +0100 +Subject: [PATCH 4/4] Prevent debug exception when product version not found + +Resolves: #1914587 +(cherry picked from commit d86eefb661766342a4473c699dc6687986420161) +--- + base/common/src/com/netscape/certsrv/apps/CMS.java | 18 ++++++++ + .../netscape/cms/servlet/csadmin/GetStatus.java | 51 +++------------------- + 2 files changed, 23 insertions(+), 46 deletions(-) + +diff --git a/base/common/src/com/netscape/certsrv/apps/CMS.java b/base/common/src/com/netscape/certsrv/apps/CMS.java +index 1dace42..e852043 100644 +--- a/base/common/src/com/netscape/certsrv/apps/CMS.java ++++ b/base/common/src/com/netscape/certsrv/apps/CMS.java +@@ -17,7 +17,9 @@ + // --- END COPYRIGHT BLOCK --- + package com.netscape.certsrv.apps; + ++import java.io.File; + import java.math.BigInteger; ++import java.nio.file.Files; + import java.security.NoSuchAlgorithmException; + import java.security.cert.Certificate; + import java.security.cert.CertificateEncodingException; +@@ -135,6 +137,7 @@ public final class CMS { + public static final String SUBSYSTEM_SELFTESTS = ISelfTestSubsystem.ID; + public static final int PRE_OP_MODE = 0; + public static final int RUNNING_MODE = 1; ++ private static final String PRODUCT_NAME_FILE = "/usr/share/pki/CS_SERVER_VERSION"; + + /** + * Private constructor. +@@ -1519,6 +1522,21 @@ public final class CMS { + _engine.sleepOneMinute(); + } + ++ /** ++ * Return the product name from /usr/share/pki/CS_SERVER_VERSION ++ * which is provided by the server theme package. ++ */ ++ public static String getProductName() throws Exception { ++ ++ File file = new File(PRODUCT_NAME_FILE); ++ ++ if (!file.exists()) { ++ return null; ++ } ++ ++ return new String(Files.readAllBytes(file.toPath())).trim(); ++ } ++ + public static boolean isExcludedLdapAttrsEnabled() { + return _engine.isExcludedLdapAttrsEnabled(); + } +diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/GetStatus.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/GetStatus.java +index 1cb8a4c..8f6d340 100644 +--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/GetStatus.java ++++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/GetStatus.java +@@ -18,7 +18,6 @@ + package com.netscape.cms.servlet.csadmin; + + import java.io.IOException; +-import java.io.FileInputStream; + import java.util.Locale; + + import javax.servlet.ServletConfig; +@@ -26,6 +25,7 @@ import javax.servlet.ServletException; + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; + ++import org.apache.commons.lang.StringUtils; + import org.w3c.dom.Node; + + import com.netscape.certsrv.apps.CMS; +@@ -35,8 +35,6 @@ import com.netscape.cms.servlet.base.CMSServlet; + import com.netscape.cms.servlet.base.UserInfo; + import com.netscape.cms.servlet.common.CMSRequest; + import com.netscape.cmsutil.xml.XMLObject; +-import org.apache.commons.io.IOUtils; +-import org.apache.commons.lang.StringUtils; + + public class GetStatus extends CMSServlet { + +@@ -44,8 +42,6 @@ public class GetStatus extends CMSServlet { + * + */ + private static final long serialVersionUID = -2852842030221659847L; +- // File below will be a member of a pki theme package. +- private static final String productVersionFILE = "/usr/share/pki/CS_SERVER_VERSION"; + + public GetStatus() { + super(); +@@ -85,13 +81,13 @@ public class GetStatus extends CMSServlet { + xmlObj.addItemToContainer(root, "Type", type); + xmlObj.addItemToContainer(root, "Status", status); + xmlObj.addItemToContainer(root, "Version", version); ++ + // File below will be a member of a pki theme package. +- String productVersion = getProductVersion(productVersionFILE); ++ String productName = CMS.getProductName(); + +- if(!StringUtils.isEmpty(productVersion)) { +- xmlObj.addItemToContainer(root,"ProductVersion", productVersion); ++ if (!StringUtils.isEmpty(productName)) { ++ xmlObj.addItemToContainer(root, "ProductVersion", productName); + } +- + byte[] cb = xmlObj.toByteArray(); + + outputResult(httpResp, "application/xml", cb); +@@ -119,41 +115,4 @@ public class GetStatus extends CMSServlet { + } + return locale; + } +- +- /** +- * Return the product version if the file: /usr/share/pki/CS_SERVER_VERSION +- * exists. +- * +- * Caller only cares if there is a string or not, exceptions handled here. +- */ +- private String getProductVersion(String versionFilePathName) { +- String version = null; +- FileInputStream inputStream = null; +- +- if(StringUtils.isEmpty(versionFilePathName)) { +- CMS.debug("Missing product version file path!"); +- return null; +- } +- +- try { +- inputStream = new FileInputStream(versionFilePathName); +- String contents = IOUtils.toString(inputStream); +- +- if(contents != null) { +- CMS.debug("Returning product version: " + version); +- version = contents.trim(); +- } +- } catch (Exception e) { +- CMS.debug("Failed to read product version String. " + e); +- } +- finally { +- if(inputStream != null) { +- try { +- inputStream.close(); +- } catch (IOException e) { +- } +- } +- } +- return version; +- } + } +-- +1.8.3.1 + diff --git a/SPECS/pki-core.spec b/SPECS/pki-core.spec index afc93e3..452f790 100644 --- a/SPECS/pki-core.spec +++ b/SPECS/pki-core.spec @@ -65,13 +65,13 @@ Name: pki-core %if 0%{?rhel} Version: 10.5.18 -%define redhat_release 12 +%define redhat_release 14 %define redhat_stage 0 #%define default_release %{redhat_release}.%{redhat_stage} %define default_release %{redhat_release} %else Version: 10.5.18 -%define fedora_release 12 +%define fedora_release 14 %define fedora_stage 0 #%define default_release %{fedora_release}.%{fedora_stage} %define default_release %{fedora_release} @@ -217,6 +217,8 @@ Patch7: pki-core-Fix-auditProfileUpgrade.patch Patch8: pki-core-Fix-AddProfileCaAuditSigningCert.patch Patch9: pki-core-rhel-7-9-rhcs-9-7-bu-4.patch Patch10: pki-core-Change-var-TPS-to-tps.patch +Patch11: pki-core-rhel-7-9-rhcs-9-7-bu-6.0.patch +Patch12: pki-core-rhel-7-9-rhcs-9-7-bu-6.1.patch # Obtain version phase number (e. g. - used by "alpha", "beta", etc.) # @@ -828,6 +830,8 @@ This package is a part of the PKI Core used by the Certificate System. %patch8 -p1 %patch9 -p1 %patch10 -p1 +%patch11 -p1 +%patch12 -p1 %clean %{__rm} -rf %{buildroot} @@ -1365,6 +1369,38 @@ fi %endif # %{with server} %changelog +* Thu May 13 2021 Dogtag Team 10.5.18-14 +- ########################################################################## +- # RHEL 7.9: +- ########################################################################## +- Bugzilla Bug 1911472 - Revoke via REST API not working when Agent + certificate not issued by CA [rhel-7.9.z] (cfu) +- Bugzilla Bug 1914587 - RHEL IPA PKI - Failed to read product version + String.java.io.FileNotFoundException (ckelley) +- Bugzilla Bug 1942687 - TPS not populating Token Policy, or switching + PIN_RESET=YES to NO [rhel-7.9.z] (jmagne) +- Bugzilla Bug 1955633 - Recovery of Keys migrated to latest version of KRA + fail to recover and result in Null Point Exception [rhel-7.9.z] (jmagne) +- ########################################################################## +- # RHCS 9.7: +- ########################################################################## +- Bugzilla Bug #1774177 - Rebase redhat-pki, redhat-pki-theme, pki-core, and + pki-console to 10.5.18 in RHCS 9.7 (Batch Update 6) + +* Thu Apr 22 2021 Dogtag Team 10.5.18-13 +- ########################################################################## +- # RHEL 7.9: +- ########################################################################## +- Bugzilla Bug 1949136 - PKI instance creation failed with new 389-ds-base + build (jmagne) +- Bugzilla Bug 1949656 - CRMF requests with extensions other than SKID cannot + be processed (cfu) +- ########################################################################## +- # RHCS 9.7: +- ########################################################################## +- Bugzilla Bug #1774177 - Rebase redhat-pki, redhat-pki-theme, pki-core, and + pki-console to 10.5.18 in RHCS 9.7 (Batch Update 6) + * Wed Feb 24 2021 Dogtag Team 10.5.18-12 - Change variable 'TPS' to 'tps' - ########################################################################## @@ -1651,7 +1687,7 @@ fi - ########################################################################## - # RHEL 7.7: - ########################################################################## -- Bugzilla Bug #1633422 - Rebase pki-core from 10.5.1 to 10.5.16 (RHEL) +- Bugzilla Bug #1633422 - Rebase pki-core from 10.5.1 to 10.5.16 (RHEL) - ########################################################################## - # RHCS 9.5: - ##########################################################################