summaryrefslogtreecommitdiffstats
path: root/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2015-02-11 16:28:50 -0500
committerAde Lee <alee@redhat.com>2015-02-26 23:21:46 -0500
commit705084a0021e161f1b4cea25dbaf622cfe68c47e (patch)
treebd423d083327a96423b9864e7851dffcc5b5ef99 /base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
parent3b6664da6c762a592573d5fa05043ecca20bf7a7 (diff)
downloadpki-705084a0021e161f1b4cea25dbaf622cfe68c47e.tar.gz
pki-705084a0021e161f1b4cea25dbaf622cfe68c47e.tar.xz
pki-705084a0021e161f1b4cea25dbaf622cfe68c47e.zip
Add granularity to token termination in TPS
BZ 1163987. Added revocation checks to optionally revoke expired certs, and handle cases where certs are shared on multiple tokens.
Diffstat (limited to 'base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java')
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java159
1 files changed, 141 insertions, 18 deletions
diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
index bf86b19ed..c3fd70df9 100644
--- a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
+++ b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
@@ -20,6 +20,7 @@ package org.dogtagpki.server.tps;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -29,6 +30,7 @@ import netscape.security.x509.RevocationReason;
import org.dogtagpki.server.tps.cms.CARemoteRequestHandler;
import org.dogtagpki.server.tps.cms.CARevokeCertResponse;
+import org.dogtagpki.server.tps.dbs.ActivityDatabase;
import org.dogtagpki.server.tps.dbs.TPSCertRecord;
import org.dogtagpki.server.tps.dbs.TokenRecord;
import org.dogtagpki.tps.main.TPSException;
@@ -258,7 +260,7 @@ public class TPSTokendb {
* @param cuid the cuid of the token
* @return ArrayList of the cert records
*/
- public ArrayList<TPSCertRecord> tdbGetCertificatesByCUID(String cuid)
+ public ArrayList<TPSCertRecord> tdbGetCertRecordsByCUID(String cuid)
throws TPSException {
if (cuid == null)
throw new TPSException("TPSTokendb.tdbGetCertificatesByCUID: cuid null");
@@ -281,6 +283,36 @@ public class TPSTokendb {
return certRecords;
}
+ public ArrayList<TPSCertRecord> tdbGetCertRecordsByCert(String serial, String issuer)
+ throws TPSException {
+ if (serial == null)
+ throw new TPSException("TPSTokendb.tdbGetCertificatesBySerial: serial null");
+
+ if (issuer == null) {
+ throw new TPSException("TPSTokendb.tdbGetCertificatesBySerial: issuer null");
+ }
+
+ Map<String, String> attributes = new HashMap<String, String>();
+ attributes.put("serialNumber", serial);
+ attributes.put("issuedBy", issuer);
+
+ ArrayList<TPSCertRecord> certRecords = new ArrayList<TPSCertRecord>();
+ Iterator<TPSCertRecord> records;
+ try {
+ records = tps.certDatabase.findRecords(null, attributes).iterator();
+ } catch (Exception e) {
+ CMS.debug("TPSTokendb.tdbGetCertificatesByCUID:" + e);
+ throw new TPSException(e.getMessage());
+ }
+
+ while (records.hasNext()) {
+ TPSCertRecord certRecord = records.next();
+ certRecords.add(certRecord);
+ }
+
+ return certRecords;
+ }
+
public void tdbRemoveCertificatesByCUID(String cuid)
throws Exception {
String method = "TPSTokendb.tdbRemoveCertificatesByCUID";
@@ -306,20 +338,105 @@ public class TPSTokendb {
}
}
- public void revokeCertsByCUID(String cuid, String tokenReason) throws Exception {
+ public void revokeCertsByCUID(String cuid, String tokenReason, String ipAddress, String remoteUser)
+ throws Exception {
String method = "TPStokendb.revokeCertsByCUID";
CMS.debug(method + ": called");
if (cuid == null)
throw new TPSException(method + ": cuid null");
- revokeCertsByCUID(true, cuid, tokenReason);
+ revokeCertsByCUID(true, cuid, tokenReason, ipAddress, remoteUser);
}
- public void unRevokeCertsByCUID(String cuid) throws Exception {
+ public void unRevokeCertsByCUID(String cuid, String ipAddress, String remoteUser) throws Exception {
String method = "TPStokendb.unRevokeCertsByCUID";
CMS.debug(method + ": called");
if (cuid == null)
throw new TPSException(method + ": cuid null");
- revokeCertsByCUID(false, cuid, null /* null for unrevoke*/);
+ revokeCertsByCUID(false, cuid, null /* null for unrevoke*/, ipAddress, remoteUser);
+ }
+
+ private boolean isLastActiveSharedCert(String serial, String issuer, String cuid) throws TPSException {
+ ArrayList<TPSCertRecord> certRecords = tps.getTokendb().tdbGetCertRecordsByCert(serial, issuer);
+ for (TPSCertRecord cert : certRecords) {
+ // exclude current token
+ if (cert.getTokenID().equals(cuid))
+ continue;
+
+ if (cert.getStatus().equals("active"))
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean shouldRevoke(TPSCertRecord cert, String cuid, String tokenReason,
+ String ipAddress, String remoteUser) throws Exception {
+ IConfigStore configStore = CMS.getConfigStore();
+ String method = "TPStokendb.shouldRevoke";
+ String activityMsg;
+
+ if (cert == null) {
+ throw new TPSException(method + ": cert null");
+ }
+
+ String tokenType = cert.getType();
+ String keyType = cert.getKeyType();
+
+ // check if certificate revocation is enabled
+ String config = "op.enroll." + tokenType + ".keyGen." + keyType +
+ ".recovery." + tokenReason + ".revokeCert";
+ boolean revokeCerts = configStore.getBoolean(config, true);
+ if (!revokeCerts) {
+ activityMsg = "certificate revocation (serial " + cert.getSerialNumber() +
+ ") not enabled for tokenType: " + tokenType +
+ ", keyType: " + keyType +
+ ", state: " + tokenReason;
+
+ tdbActivity(ActivityDatabase.OP_DO_TOKEN, tdbGetTokenEntry(cuid),
+ ipAddress, activityMsg, "success", remoteUser);
+
+ return false;
+ }
+
+ // check if expired certificates should be revoked.
+ config = "op.enroll." + tokenType + ".keyGen." + keyType + ".recovery." +
+ tokenReason + ".revokeExpiredCerts";
+ boolean revokeExpiredCerts = configStore.getBoolean(config, true);
+ if (!revokeExpiredCerts) {
+ Date notBefore = cert.getValidNotBefore();
+ Date notAfter = cert.getValidNotAfter();
+ Date now = new Date();
+ if (now.after(notAfter)) {
+ activityMsg = "revocation not enabled for expired cert: " + cert.getSerialNumber();
+ tdbActivity(ActivityDatabase.OP_DO_TOKEN, tdbGetTokenEntry(cuid),
+ ipAddress, activityMsg, "success", remoteUser);
+ return false;
+ }
+ if (now.before(notBefore)) {
+ activityMsg = "revocation not enabled for cert that is not yet valid: " + cert.getSerialNumber();
+ tdbActivity(ActivityDatabase.OP_DO_TOKEN, tdbGetTokenEntry(cuid),
+ ipAddress, activityMsg, "success", remoteUser);
+ return false;
+ }
+ }
+
+ // check if certs on multiple tokens should be revoked
+ config = "op.enroll." + tokenType + ".keyGen." + keyType + ".recovery." +
+ tokenReason + ".holdRevocationUntilLastCredential";
+ boolean holdRevocation = configStore.getBoolean(config, false);
+ if (holdRevocation) {
+ if (!isLastActiveSharedCert(cert.getSerialNumber(), cert.getIssuedBy(), cuid)) {
+ activityMsg = "revocation not permitted as certificate " + cert.getSerialNumber() +
+ " is shared by anothr active token";
+
+ tdbActivity(ActivityDatabase.OP_DO_TOKEN, tdbGetTokenEntry(cuid),
+ ipAddress, activityMsg, "success", remoteUser);
+
+ return false;
+ }
+ }
+
+ return true;
}
/*
@@ -328,17 +445,19 @@ public class TPSTokendb {
* @param cuid cuid of token to revoke/unrevoke
* @param onHold true if revocation is to put onHold; false if to really revoke
*/
- private void revokeCertsByCUID(boolean isRevoke, String cuid, String tokenReason) throws Exception {
+ private void revokeCertsByCUID(boolean isRevoke, String cuid, String tokenReason,
+ String ipAddress, String remoteUser) throws Exception {
String method = "TPSTokendb.revokeCertsByCUID";
if (cuid == null)
throw new TPSException(method + ": cuid null");
String auditMsg;
IConfigStore configStore = CMS.getConfigStore();
- ArrayList<TPSCertRecord> certRecords = tps.getTokendb().tdbGetCertificatesByCUID(cuid);
+ ArrayList<TPSCertRecord> certRecords = tps.getTokendb().tdbGetCertRecordsByCUID(cuid);
if (tokenReason != null) {
if (!tokenReason.equalsIgnoreCase("onHold") &&
!tokenReason.equalsIgnoreCase("destroyed") &&
- !tokenReason.equalsIgnoreCase("keyCompromise")) {
+ !tokenReason.equalsIgnoreCase("keyCompromise") &&
+ !tokenReason.equalsIgnoreCase("terminated")) {
auditMsg = "unknown tokenRecord lost reason:" + tokenReason;
CMS.debug(method + ":" + auditMsg);
throw new Exception(method + ":" + auditMsg);
@@ -355,13 +474,8 @@ public class TPSTokendb {
if (isRevoke) {
auditMsg = "called to revoke";
CMS.debug(method + ":" + auditMsg);
- boolean revokeCert = false;
+ boolean revokeCert = shouldRevoke(cert, cuid, tokenReason, ipAddress, remoteUser);
- // get revoke or not
- config = "op.enroll." + cert.getType() + ".keyGen." + cert.getKeyType() +
- ".recovery." + tokenReason + ".revokeCert";
- //TODO: temporaryToken doesn't have all params; default to false if not found for now
- revokeCert = configStore.getBoolean(config, false); // default to false
if (!revokeCert) {
auditMsg = "cert not to be revoked:" + cert.getSerialNumber();
CMS.debug(method + ":" + auditMsg);
@@ -407,20 +521,29 @@ public class TPSTokendb {
// update certificate status
if (isRevoke) {
if (revokeReason == RevocationReason.CERTIFICATE_HOLD) {
- cert.setStatus("revoked_on_hold");
+ updateCertsStatus(cert.getSerialNumber(), cert.getIssuedBy(), "revoked_on_hold");
} else {
- cert.setStatus("revoked");
+ updateCertsStatus(cert.getSerialNumber(), cert.getIssuedBy(), "revoked");
}
} else {
- cert.setStatus("active");
+ updateCertsStatus(cert.getSerialNumber(), cert.getIssuedBy(), "active");
}
- tps.certDatabase.updateRecord(cert.getId(), cert);
+
auditMsg = "cert (un)revoked:" + cert.getSerialNumber();
CMS.debug(method + ":" + auditMsg);
//TODO: tdbActivity
}
}
+ public void updateCertsStatus(String serial, String issuer, String status) throws Exception {
+ ArrayList<TPSCertRecord> certRecords = tps.getTokendb().tdbGetCertRecordsByCert(serial, issuer);
+
+ for (TPSCertRecord certRecord : certRecords) {
+ certRecord.setStatus(status);
+ tps.certDatabase.updateRecord(certRecord.getId(), certRecord);
+ }
+ }
+
public void tdbAddCertEntry(TPSCertRecord certRecord, String status)
throws Exception {
certRecord.setStatus(status);