summaryrefslogtreecommitdiffstats
path: root/base/tps/src
diff options
context:
space:
mode:
authorJack Magne <jmagne@dhcp-16-206.sjc.redhat.com>2016-10-05 18:16:35 -0700
committerMatthew Harmsen <mharmsen@redhat.com>2016-10-10 16:38:07 -0600
commit1e39ab6823390e736bfa1044c8d63306a1fce226 (patch)
tree8fe443bc9f45e904a3a1beb79c2084ef606ca8ab /base/tps/src
parent35aff85b5b0c00d301a0122429b54a7ca9a90c7d (diff)
downloadpki-1e39ab6823390e736bfa1044c8d63306a1fce226.tar.gz
pki-1e39ab6823390e736bfa1044c8d63306a1fce226.tar.xz
pki-1e39ab6823390e736bfa1044c8d63306a1fce226.zip
Fix for: Add ability to disallow TPS to enroll a single user on multiple tokens. #1664
This bug was previously not completely fixed where we left a loophole to allow a user to end up with 2 active tokens. This fix closes that loophole. Also: Fix for: Unable to read an encrypted email using renewed tokens. #2483 This fix provides for a new optional renewal based token policy, that allows the user to retain or recover old encryption certs for that profile, that get overwritten by the renewal process. An example is: RENEW=YES;RENEW_KEEP_OLD_ENC_CERTS=YES The default is YESk you have to explicitly set it to NO to turn it off. The second part of the policy is new. When this is set to "YES", the system will make sure the old enc cert will remain on the token. If it's missing or "NO", no such attempt will be made. junk
Diffstat (limited to 'base/tps/src')
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java8
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/main/PKCS11Obj.java3
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java4
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java94
4 files changed, 107 insertions, 2 deletions
diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java b/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java
index 1a866f737..4d7af4875 100644
--- a/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java
+++ b/base/tps/src/org/dogtagpki/server/tps/TPSTokenPolicy.java
@@ -36,6 +36,7 @@ public class TPSTokenPolicy {
"RE_ENROLL=YES;RENEW=NO;FORCE_FORMAT=NO;PIN_RESET=NO;RESET_PIN_RESET_TO_NO=NO";
private boolean re_enroll = true;
private boolean renew = false;
+ private boolean renew_keep_old_enc_certs = true;
private boolean force_format = false;
private boolean pin_reset = true;
private boolean reset_pin_reset_to_no = false;
@@ -85,6 +86,8 @@ public class TPSTokenPolicy {
pin_reset = getBool(policy[1], false);
else if (policy[0].equalsIgnoreCase("RESET_PIN_RESET_TO_NO"))
reset_pin_reset_to_no = getBool(policy[1], false);
+ else if (policy[0].equalsIgnoreCase("RENEW_KEEP_OLD_ENC_CERTS"))
+ renew_keep_old_enc_certs = getBool(policy[1],true);
//else no change, just take the default;
}
}
@@ -150,6 +153,11 @@ public class TPSTokenPolicy {
return re_enroll;
}
+ public boolean isAllowdRenewSaveOldEncCerts(String cuid) {
+ getUpdatedPolicy(cuid);
+ return renew_keep_old_enc_certs;
+ }
+
public boolean isAllowdTokenRenew(String cuid) {
getUpdatedPolicy(cuid);
diff --git a/base/tps/src/org/dogtagpki/server/tps/main/PKCS11Obj.java b/base/tps/src/org/dogtagpki/server/tps/main/PKCS11Obj.java
index 2fc62d70d..6af39a7bd 100644
--- a/base/tps/src/org/dogtagpki/server/tps/main/PKCS11Obj.java
+++ b/base/tps/src/org/dogtagpki/server/tps/main/PKCS11Obj.java
@@ -655,6 +655,7 @@ public class PKCS11Obj {
int index = os.getObjectIndex();
if (type == 'C') { //found a certificate
+ CMS.debug("PKS11Obj: getNextFreeCertIdNumber: found cert index "+ index);
if (index >= 0 && index < 100) {
certTable[index] = 1;
}
@@ -669,7 +670,7 @@ public class PKCS11Obj {
}
}
- CMS.debug("TPSEnrollProcessor.getNextFreeCertIdNumber: returning free cert id: " + free_cert_id );
+ CMS.debug("PKCS11Obj.getNextFreeCertIdNumber: returning free cert id: " + free_cert_id );
return free_cert_id;
}
diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java b/base/tps/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java
index aac1a23f3..ae9919ddb 100644
--- a/base/tps/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java
@@ -152,6 +152,10 @@ public class EnrolledCertsInfo {
certificates.add(x509Cert);
}
+ public void removeCertificate(X509CertImpl x509Cert) {
+ certificates.remove(x509Cert);
+ }
+
public void setStartProgress(int startP) {
startProgress = startP;
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 aa23bf077..db9a230cb 100644
--- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java
+++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java
@@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
@@ -333,7 +334,7 @@ public class TPSEnrollProcessor extends TPSProcessor {
boolean allowMultiTokens = checkAllowMultiActiveTokensUser(isExternalReg);
- if (isTokenPresent == false && allowMultiTokens == false) {
+ if (allowMultiTokens == false) {
boolean alreadyHasActiveToken = checkUserAlreadyHasActiveToken(userid);
if (alreadyHasActiveToken == true) {
@@ -1049,8 +1050,10 @@ public class TPSEnrollProcessor extends TPSProcessor {
CMS.debug(method + ": There are multiple token entries for user "
+ userid);
+ if( checkUserAlreadyHasActiveToken(userid) == false) {
isRecover = true;
continue; // TODO: or break?
+ }
}
} else if (tokenRecord.getTokenStatus() == TokenStatus.ACTIVE) {
@@ -1411,10 +1414,14 @@ public class TPSEnrollProcessor extends TPSProcessor {
*/
Collection<TPSCertRecord> allCerts = tps.tdb.tdbGetCertRecordsByCUID(tokenRecord.getId());
+ Collection<TPSCertRecord> oldEncCertsToRecover = new ArrayList<TPSCertRecord>();
+
certsInfo.setNumCertsToEnroll(keyTypeNum);
CMS.debug(method + ": Number of certs to renew: " + keyTypeNum);
+ int numActuallyRenewed = 0;
+
for (int i = 0; i < keyTypeNum; i++) {
/*
* e.g. op.enroll.userKey.renewal.keyType.value.0=signing
@@ -1515,6 +1522,23 @@ public class TPSEnrollProcessor extends TPSProcessor {
generateCertificate(certsInfo, channel, aInfo, keyType, TPSEngine.ENROLL_MODES.MODE_RENEWAL,
-1, cEnrollInfo);
+ numActuallyRenewed ++;
+
+
+
+ if(keyType.equals(TPSEngine.CFG_ENCRYPTION)) {
+ CMS.debug(method + ": found old encryption cert (just renewed) to attempt to recover back to token, in order to read old emails.");
+ CMS.debug(method + " adding cert: " + cert);
+ oldEncCertsToRecover.add(cert);
+
+ }
+
+ if(numActuallyRenewed == keyTypeNum) {
+ CMS.debug(method + " We have already renewed the proper number of certs, bailing from loop.");
+ status = TPSStatus.STATUS_ERROR_RENEWAL_IS_PROCESSED;
+ break;
+ }
+
//renewCertificate(cert, certsInfo, channel, aInfo, keyType);
status = TPSStatus.STATUS_ERROR_RENEWAL_IS_PROCESSED;
} catch (TPSException e) {
@@ -1532,6 +1556,74 @@ public class TPSEnrollProcessor extends TPSProcessor {
CMS.debug(method + ":" + logMsg);
throw new TPSException(logMsg + TPSStatus.STATUS_ERROR_RENEWAL_FAILED);
}
+
+ //Handle recovery of old encryption certs
+
+ //See if policy calls for this feature
+
+ TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps);
+
+ boolean recoverOldEncCerts = tokenPolicy.isAllowdRenewSaveOldEncCerts(tokenRecord.getId());
+ 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.");
+
+ Iterator<TPSCertRecord> iterator = oldEncCertsToRecover.iterator();
+
+ // while loop
+ while (iterator.hasNext()) {
+ TPSCertRecord toBeRecovered = iterator.next();
+ String serialToRecover = toBeRecovered.getSerialNumber();
+
+ try {
+
+ CARetrieveCertResponse certResponse = tps.getEngine().recoverCertificate(toBeRecovered,
+ serialToRecover, TPSEngine.CFG_ENCRYPTION, getCAConnectorID());
+
+ String b64cert = certResponse.getCertB64();
+ CMS.debug("TPSEnrollProcessor.processRecovery: cert blob recovered");
+
+ KRARecoverKeyResponse keyResponse = tps.getEngine().recoverKey(toBeRecovered.getId(),
+ toBeRecovered.getUserID(),
+ channel.getDRMWrappedDesKey(), b64cert, getDRMConnectorID());
+
+
+ //Try to write recovered cert to token
+
+ CertEnrollInfo cEnrollInfo = new CertEnrollInfo();
+
+ cEnrollInfo.setTokenToBeRecovered(tokenRecord);
+ cEnrollInfo.setRecoveredCertData(certResponse);
+ cEnrollInfo.setRecoveredKeyData(keyResponse);
+
+
+ PKCS11Obj pkcs11obj = certsInfo.getPKCS11Obj();
+ int newCertId = pkcs11obj.getNextFreeCertIdNumber();
+
+ CMS.debug(method + " newCertId = " + newCertId);
+
+ CMS.debug(method + "before calling generateCertificate, certsInfo.getCurrentCertIndex() ="
+ + newCertId);
+ generateCertificate(certsInfo, channel, aInfo,
+ "encryption",
+ TPSEngine.ENROLL_MODES.MODE_RECOVERY,
+ newCertId, cEnrollInfo);
+
+ //We don't want this quasi old encryption cert in the official list.
+ // This cert is on the token ONLY to decrypt old emails after the real cert
+ // has been renewed. We want to keep the official cert list to contain only the
+ // legit certs, in order to not confuse other processes such as recovery.
+ CMS.debug(method + " About to remove old encryption cert recovered from official token db list: ");
+ certsInfo.removeCertificate(certResponse.getCert());
+
+
+ } catch (TPSException e) {
+ CMS.debug(method + "Failure to recoverd old encryption certs during renewal operation.");
+
+ }
+ }
+ }
+
return status;
}