diff options
author | Christina Fu <cfu@redhat.com> | 2014-09-02 20:30:42 -0700 |
---|---|---|
committer | Christina Fu <cfu@redhat.com> | 2014-09-03 16:13:27 -0700 |
commit | 82d3ed74289857b5fa60a842979406a2a8acecda (patch) | |
tree | aa397c752fe4c1fb2edd1868442b06acd6771d7d | |
parent | 223d15539b7bcc0df025025036af2935726e52e3 (diff) | |
download | pki-82d3ed74289857b5fa60a842979406a2a8acecda.tar.gz pki-82d3ed74289857b5fa60a842979406a2a8acecda.tar.xz pki-82d3ed74289857b5fa60a842979406a2a8acecda.zip |
ticket #941 Rest interface triggered revoke/unrevoke and cert status update; recovery
6 files changed, 291 insertions, 39 deletions
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokendb.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokendb.java index e15a4de29..914706dd9 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokendb.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokendb.java @@ -17,6 +17,7 @@ // --- END COPYRIGHT BLOCK --- package org.dogtagpki.server.tps; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -24,6 +25,10 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; +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.TPSCertRecord; import org.dogtagpki.server.tps.dbs.TokenRecord; import org.dogtagpki.tps.main.TPSException; @@ -275,4 +280,146 @@ public class TPSTokendb { return certRecords; } + + public void revokeCertsByCUID(String cuid, String tokenReason) throws Exception { + String method = "TPStokendb.revokeCertsByCUID"; + CMS.debug(method + ": called"); + if (cuid == null) + throw new TPSException(method + ": cuid null"); + revokeCertsByCUID(true, cuid, tokenReason); + } + + public void unRevokeCertsByCUID(String cuid) 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 + * @param isRevoke true if to revoke; false to unrevoke + * @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 { + 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); + if (tokenReason != null) { + if (!tokenReason.equalsIgnoreCase("onHold") && + !tokenReason.equalsIgnoreCase("destroyed") && + !tokenReason.equalsIgnoreCase("keyCompromise")) { + auditMsg = "unknown tokenRecord lost reason:" + tokenReason; + CMS.debug(method + ":" + auditMsg); + throw new Exception(method + ":" + auditMsg); + } + + } + for (TPSCertRecord cert : certRecords) { + // get conn id + String config = "op.enroll." + cert.getType() + ".keyGen." + cert.getKeyType() + ".ca.conn"; + String connID = configStore.getString(config); + + RevocationReason revokeReason = RevocationReason.UNSPECIFIED; + + if (isRevoke) { + auditMsg = "called to revoke"; + CMS.debug(method + ":" + auditMsg); + boolean revokeCert = false; + + // 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); + continue; + } + auditMsg = "cert to be revoked:" + cert.getSerialNumber(); + CMS.debug(method + ":" + auditMsg); + + // get revoke reason + config = "op.enroll." + cert.getType() + ".keyGen." + cert.getKeyType() + + ".recovery." + tokenReason + ".revokeCert.reason"; + int reasonInt = configStore.getInteger(config, 0); + revokeReason = RevocationReason.fromInt(reasonInt); + } else { // is unrevoke + auditMsg = "called to unrevoke"; + CMS.debug(method + ":" + auditMsg); + if (!cert.getStatus().equalsIgnoreCase("revoked_on_hold")) { + auditMsg = "cert record current status is not revoked_on_hold; cannot unrevoke"; + CMS.debug(method + ":" + auditMsg); + continue;// TODO: continue or bail? + } + } + + CARemoteRequestHandler caRH = null; + caRH = new CARemoteRequestHandler(connID); + String hexSerial = cert.getSerialNumber(); + if (hexSerial.length() >= 3 && hexSerial.startsWith("0x")) { + String serial = hexSerial.substring(2); // skip over the '0x' + BigInteger bInt = new BigInteger(serial, 16); + String serialStr = bInt.toString(); + CMS.debug(method + ": found cert hex serial: " + serial + + " dec serial:" + serialStr); + CARevokeCertResponse response = + caRH.revokeCertificate(isRevoke, serialStr, cert.getCertificate(), + revokeReason); + CMS.debug(method + ": response status =" + response.getStatus()); + } else { + auditMsg = "mulformed hex serial number :" + hexSerial; + CMS.debug(method + ": " + auditMsg); + throw new Exception(auditMsg); + } + + // update certificate status + if (isRevoke) { + if (revokeReason == RevocationReason.CERTIFICATE_HOLD) { + cert.setStatus("revoked_on_hold"); + } else { + cert.setStatus("revoked"); + } + } else { + cert.setStatus("active"); + } + tps.certDatabase.updateRecord(cert.getId(), cert); + auditMsg = "cert (un)revoked:" + cert.getSerialNumber(); + CMS.debug(method + ":" + auditMsg); + //TODO: tdbActivity + } + } + + public void tdbAddCertEntry(TPSCertRecord certRecord, String status) + throws Exception { + certRecord.setStatus(status); + + tps.certDatabase.addRecord(certRecord.getId(), certRecord); + } + + public void tdbUpdateCertEntry(TPSCertRecord certRecord) + throws Exception { + String method = "TPSTokendb.tdbUpdateCertEntry"; + String id = certRecord.getId(); + TPSCertRecord existingCertRecord; + try { + existingCertRecord = tps.certDatabase.getRecord(id); + } catch (Exception e) { + CMS.debug(method + ": token entry not found; Adding"); + // add and exit + tdbAddCertEntry(certRecord, certRecord.getStatus()); + return; + } + // cert found; modify + CMS.debug(method + ": cert entry found; Modifying with status: "+ certRecord.getStatus()); + // don't change the create time of an existing token record; put it back + certRecord.setCreateTime(existingCertRecord.getCreateTime()); + tps.certDatabase.updateRecord(id, certRecord); + } } diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/cms/CARemoteRequestHandler.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/cms/CARemoteRequestHandler.java index d98d41a23..5851d2f69 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/cms/CARemoteRequestHandler.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/cms/CARemoteRequestHandler.java @@ -201,7 +201,7 @@ public class CARemoteRequestHandler extends RemoteRequestHandler BigInteger serialno) throws EBaseException { - CMS.debug("CARemoteRequestHandler: renewCertificate(): begins."); + CMS.debug("CARemoteRequestHandler: retrieveCertificate(): begins."); if (serialno == null) { throw new EBaseException("CARemoteRequestHandler: retrieveCertificate(): input parameter null."); } diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java index 8bb6e6bf6..c4b485c45 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java @@ -424,8 +424,18 @@ public class TPSEngine { String userid, TPSBuffer sDesKey, String b64cert, String drmConnId) throws TPSException { - + String method = "TPSEngine.recoverKey"; CMS.debug("TPSEngine.recoverKey"); + if (cuid == null) + CMS.debug(method + ": cuid null"); + else if (userid == null) + CMS.debug(method + ": userid null"); + else if (sDesKey == null) + CMS.debug(method + ": isDesKey null"); + else if (b64cert == null) + CMS.debug(method + ": b64cert null"); + else if (drmConnId == null) + CMS.debug(method + ": drmConnId null"); if (cuid == null || userid == null || sDesKey == null || b64cert == null || drmConnId == null) { throw new TPSException("TPSEngine.recoverKey: invalid input data!", TPSStatus.STATUS_ERROR_RECOVERY_FAILED); diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java index 618ed1488..cff615752 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java @@ -26,6 +26,7 @@ import org.dogtagpki.server.tps.cms.CAEnrollCertResponse; import org.dogtagpki.server.tps.cms.CARemoteRequestHandler; import org.dogtagpki.server.tps.cms.CARenewCertResponse; import org.dogtagpki.server.tps.cms.CARetrieveCertResponse; +import org.dogtagpki.server.tps.cms.CARevokeCertResponse; import org.dogtagpki.server.tps.cms.KRARecoverKeyResponse; import org.dogtagpki.server.tps.cms.KRAServerSideKeyGenResponse; import org.dogtagpki.server.tps.dbs.ActivityDatabase; @@ -818,13 +819,13 @@ public class TPSEnrollProcessor extends TPSProcessor { String tmpTokenType = configStore.getString(configName); setSelectedTokenType(tmpTokenType); } catch (EPropertyNotFound e) { - auditMsg = "configuration " + configName + " not found"; + auditMsg = " configuration " + configName + " not found"; CMS.debug(method + ":" + auditMsg); - throw new TPSException(method + auditMsg); + throw new TPSException(method + ":" + auditMsg); } catch (EBaseException e) { - auditMsg = "configuration " + configName + " not found"; - CMS.debug(method + auditMsg); - throw new TPSException(method + auditMsg); + auditMsg = " configuration " + configName + " not found"; + CMS.debug(method + ":" + auditMsg); + throw new TPSException(method + ":" + auditMsg); } return processRecovery(lostToken, certsInfo, channel, aInfo); @@ -1150,10 +1151,13 @@ public class TPSEnrollProcessor extends TPSProcessor { private TPSStatus processRecovery(TokenRecord toBeRecovered, EnrolledCertsInfo certsInfo, SecureChannel channel, AppletInfo aInfo) throws TPSException, IOException { - + String method = "TPSEnrollProcessor.processRecover"; + String auditMsg; TPSStatus status = TPSStatus.STATUS_ERROR_RECOVERY_IS_PROCESSED; TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); + IConfigStore configStore = CMS.getConfigStore(); + CMS.debug("TPSEnrollProcessor.processRecovery: entering:"); if (toBeRecovered == null || certsInfo == null || channel == null || aInfo == null) { @@ -1258,10 +1262,22 @@ public class TPSEnrollProcessor extends TPSProcessor { } String b64cert = null; if (serialToRecover != null) { + // get recovery conn id + String caConnId; + String config = "op.enroll." + certToRecover.getType() + ".keyGen." + certToRecover.getKeyType() + ".ca.conn"; + try { + caConnId = configStore.getString(config); + } catch (Exception e) { + auditMsg = "cannot find config:" + config; + CMS.debug(method + ":" + auditMsg); + throw new TPSException( + method + ":" + auditMsg, + TPSStatus.STATUS_ERROR_RECOVERY_FAILED); + } CMS.debug("TPSEnrollProcessor.processRecovery: Selecting cert to recover: " + serialToRecover); CARetrieveCertResponse certResponse = tps.getEngine().recoverCertificate(certToRecover, - serialToRecover, keyTypeValue, getCAConnectorID()); + serialToRecover, keyTypeValue, caConnId); b64cert = certResponse.getCertB64(); CMS.debug("TPSEnrollProcessor.processRecovery: recoverd cert blob: " + b64cert); @@ -1279,10 +1295,37 @@ public class TPSEnrollProcessor extends TPSProcessor { generateCertificate(certsInfo, channel, aInfo, keyTypeValue, TPSEngine.ENROLL_MODES.MODE_RECOVERY, actualCertIndex, cEnrollInfo); - //ToDo: write code to unrevoke this certificate. - // Right now we are not handling cert satus correctly in the TPS UI anyway. - //Fix that first and then do this. + // unrevoke cert if needed + if (certToRecover.getStatus().equalsIgnoreCase("revoked_on_hold")) { + auditMsg = "unrevoking cert..."; + CMS.debug(method + ":" + auditMsg); + CARemoteRequestHandler caRH = null; + try { + caRH = new CARemoteRequestHandler(caConnId); + + CARevokeCertResponse response = + caRH.revokeCertificate(false /*unrevoke*/, serialToRecover, + certToRecover.getCertificate(), + null); + CMS.debug(method + ": response status =" + response.getStatus()); + + } catch (EBaseException e) { + auditMsg = "failed getting CARemoteRequestHandler"; + CMS.debug(method + ":" + auditMsg); + throw new TPSException(method + ":" + auditMsg, TPSStatus.STATUS_ERROR_RECOVERY_FAILED); + } + } + + // set cert status to active + certToRecover.setStatus("active"); + try { + tps.tdb.tdbUpdateCertEntry(certToRecover); + } catch (Exception e) { + auditMsg = "failed tdbUpdateCertEntry"; + CMS.debug(method + ":" + auditMsg); + throw new TPSException(method + ":" + auditMsg, TPSStatus.STATUS_ERROR_RECOVERY_FAILED); + } } else { } diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSProcessor.java index 6ea180096..e23cea0ad 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSProcessor.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSProcessor.java @@ -986,16 +986,13 @@ public class TPSProcessor { } /* - * revokeCertificates revokes certificates on the token specified - * @param cuid the cuid of the token to revoke certificates - * @return auditMsg captures the audit message - * @throws TPSException in case of error + * revokeCertsAtFormat returns a boolean that tells if config wants to revoke certs on the token during format */ - protected void revokeCertificates(String cuid) throws TPSException { - String auditMsg = ""; - final String method = "TPSProcessor.revokeCertificates"; + protected boolean revokeCertsAtFormat() { + String method = "revokeCertsAtFormat"; + String auditMsg; + CMS.debug(method + ": begins"); - //bail out if not configured to revoke cert IConfigStore configStore = CMS.getConfigStore(); String configName = TPSEngine.OP_FORMAT_PREFIX + "." + selectedTokenType + ".revokeCert"; boolean revokeCert = false; @@ -1005,14 +1002,46 @@ public class TPSProcessor { auditMsg = method + ": config not found: " + configName + "; default to false"; CMS.debug(auditMsg); - return; } if (!revokeCert) { auditMsg = method + ": revokeCert = false"; CMS.debug(auditMsg); - return; + } + return revokeCert; + } + + protected RevocationReason getRevocationReasonAtFormat() { + String method = "getRevocationReasonAtFormat"; + String auditMsg; + + IConfigStore configStore = CMS.getConfigStore(); + String configName = TPSEngine.OP_FORMAT_PREFIX + "." + selectedTokenType + ".revokeCert.revokeReason"; + RevocationReason revokeReason = RevocationReason.UNSPECIFIED; + try { + int revokeReasonInt = configStore.getInteger(configName); + revokeReason = RevocationReason.fromInt(revokeReasonInt); + } catch (EBaseException e) { + auditMsg = method + ": config not found: " + configName + + "; default to unspecified"; + CMS.debug(auditMsg); + revokeReason = RevocationReason.UNSPECIFIED; } + return revokeReason; + } + + /* + * revokeCertificates revokes certificates on the token specified + * @param cuid the cuid of the token to revoke certificates + * @return auditMsg captures the audit message + * @throws TPSException in case of error + * + * TODO: maybe make this a callback function later + */ + protected void revokeCertificates(String cuid, RevocationReason revokeReason, String caConnId) throws TPSException { + String auditMsg = ""; + final String method = "TPSProcessor.revokeCertificates"; + if (cuid == null) { auditMsg = "cuid null"; CMS.debug(method + ":" + auditMsg); @@ -1027,7 +1056,6 @@ public class TPSProcessor { throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); } - String caConnId = getCAConnectorID(); CARemoteRequestHandler caRH = null; try { caRH = new CARemoteRequestHandler(caConnId); @@ -1100,17 +1128,7 @@ public class TPSProcessor { } continue; } - configName = TPSEngine.OP_FORMAT_PREFIX + "." + selectedTokenType + ".revokeCert.revokeReason"; - RevocationReason revokeReason = RevocationReason.UNSPECIFIED; - try { - int revokeReasonInt = configStore.getInteger(configName); - revokeReason = RevocationReason.fromInt(revokeReasonInt); - } catch (EBaseException e) { - auditMsg = method + ": config not found: " + configName + - "; default to unspecified"; - CMS.debug(auditMsg); - revokeReason = RevocationReason.UNSPECIFIED; - } + String hexSerial = cert.getSerialNumber(); if (hexSerial.length() >= 3 && hexSerial.startsWith("0x")) { String serial = hexSerial.substring(2); // skip over the '0x' @@ -1364,10 +1382,13 @@ public class TPSProcessor { channel.externalAuthenticate(); tokenRecord.setKeyInfo(channel.getKeyInfoData().toHexStringPlain()); - if (isTokenPresent) { + if (isTokenPresent && revokeCertsAtFormat()) { // Revoke certificates on token, if so configured + RevocationReason reason = getRevocationReasonAtFormat(); + String caConnId = getCAConnectorID(); + try { - revokeCertificates(tokenRecord.getId()); + revokeCertificates(tokenRecord.getId(), reason, caConnId); } catch (TPSException te) { // failed revocation; capture message and continue auditMsg = te.getMessage(); diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TokenService.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TokenService.java index f12c39b1f..a58447089 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TokenService.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/rest/TokenService.java @@ -121,13 +121,23 @@ public class TokenService extends PKIService implements TokenResource { return TokenStatus.PERM_LOST; } - public void setTokenStatus(TokenRecord tokenRecord, TokenStatus tokenState) { + public void setTokenStatus(TokenRecord tokenRecord, TokenStatus tokenState) throws Exception { + TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); + switch (tokenState) { case UNINITIALIZED: tokenRecord.setStatus("uninitialized"); tokenRecord.setReason(null); break; case ACTIVE: + String origStatus = tokenRecord.getStatus(); + String origReason = tokenRecord.getReason(); + if (origStatus.equalsIgnoreCase("lost") && + origReason.equalsIgnoreCase("onHold")) { + //unrevoke certs + tps.tdb.unRevokeCertsByCUID(tokenRecord.getId()); + } + tokenRecord.setStatus("active"); tokenRecord.setReason(null); break; @@ -135,18 +145,39 @@ public class TokenService extends PKIService implements TokenResource { case TEMP_LOST_PERM_LOST: tokenRecord.setStatus("lost"); tokenRecord.setReason("keyCompromise"); + + //revoke certs + tps.tdb.revokeCertsByCUID(tokenRecord.getId(), "keyCompromise"); break; case DAMAGED: tokenRecord.setStatus("lost"); tokenRecord.setReason("destroyed"); + + //revoke certs + tps.tdb.revokeCertsByCUID(tokenRecord.getId(), "destroyed"); + break; case TEMP_LOST: tokenRecord.setStatus("lost"); tokenRecord.setReason("onHold"); + + // put certs onHold + tps.tdb.revokeCertsByCUID(tokenRecord.getId(), "onHold"); break; case TERMINATED: + String reason = "keyCompromise"; + String origStatus2 = tokenRecord.getStatus(); + String origReason2 = tokenRecord.getReason(); + // temp token looks at "onHold" + if (origStatus2.equalsIgnoreCase("lost") && + origReason2.equalsIgnoreCase("onHold")) { + reason = "onHold"; + } tokenRecord.setStatus("terminated"); - tokenRecord.setReason(null); + tokenRecord.setReason(reason); + + //revoke certs + tps.tdb.revokeCertsByCUID(tokenRecord.getId(), reason) ; break; default: throw new PKIException("Unsupported token state: " + tokenState); @@ -182,7 +213,7 @@ public class TokenService extends PKIService implements TokenResource { return tokenData; } - public TokenRecord createTokenRecord(TokenData tokenData) { + public TokenRecord createTokenRecord(TokenData tokenData) throws Exception { TokenRecord tokenRecord = new TokenRecord(); tokenRecord.setId(tokenData.getID()); |