summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2016-03-21 21:40:02 +0100
committerEndi S. Dewata <edewata@redhat.com>2016-03-28 18:59:10 +0200
commit93179af9333197cbdce843f16c02107b8d1db17e (patch)
treea0311796ed3c168ad0997b24af457cd79576fba3
parentc22d9a99240d2f24eb7b0ee11c3153fa475d47a1 (diff)
downloadpki-93179af9333197cbdce843f16c02107b8d1db17e.tar.gz
pki-93179af9333197cbdce843f16c02107b8d1db17e.tar.xz
pki-93179af9333197cbdce843f16c02107b8d1db17e.zip
Generating TEMP_LOST to UNINITIALIZED/ACTIVE transitions dynamically.
The TPS subsystem has been modified to generate the token state transitions from TEMP_LOST to UNINITIALIZED or ACTIVE dynamically depending on whether the token has certificates. The TEMP_LOST to ACTIVE transition has been removed from the CS.cfg. Duplicate code that loads the allowed transitions list has been merged and moved into TPSSubsystem. https://fedorahosted.org/pki/ticket/1808
-rw-r--r--base/tps-client/doc/CS.cfg.in2
-rw-r--r--base/tps/shared/conf/CS.cfg.in2
-rw-r--r--base/tps/shared/conf/token-states.properties1
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java68
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java41
-rw-r--r--base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java114
6 files changed, 98 insertions, 130 deletions
diff --git a/base/tps-client/doc/CS.cfg.in b/base/tps-client/doc/CS.cfg.in
index ddfab8824..f1a79032a 100644
--- a/base/tps-client/doc/CS.cfg.in
+++ b/base/tps-client/doc/CS.cfg.in
@@ -1545,7 +1545,7 @@ tokendb.confirmDeleteConfigTemplate=confirmDeleteConfig.template
log.instance.SignedAudit.selected.events=ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL
log.instance.SignedAudit.selectable.events=ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE,PRIVATE_KEY_ARCHIVE_PROCESSED,KEY_RECOVERY_REQUEST,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_PROCESSED,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL
log.instance.SignedAudit.nonselectable.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_PROCESSED,SERVER_SIDE_KEYGEN_REQUEST
-tokendb.allowedTransitions=0:1,0:2,0:3,0:6,3:2,3:4,3:6,4:1,4:2,4:3,4:6
+tokendb.allowedTransitions=0:1,0:2,0:3,0:6,3:2,3:6,4:1,4:2,4:3,4:6
target._000=#########################################
target._001=# entries to enable configuration of parameter sets through the TPS UI agent and admin tabs
target._002=#
diff --git a/base/tps/shared/conf/CS.cfg.in b/base/tps/shared/conf/CS.cfg.in
index 2285300ec..d7a10729d 100644
--- a/base/tps/shared/conf/CS.cfg.in
+++ b/base/tps/shared/conf/CS.cfg.in
@@ -1966,7 +1966,7 @@ tokendb.addConfigTemplate=addConfig.template
tokendb.addResultTemplate=addResults.template
tokendb.agentSelectConfigTemplate=agentSelectConfig.template
tokendb.agentViewConfigTemplate=agentViewConfig.template
-tokendb.allowedTransitions=0:1,0:2,0:3,0:6,3:2,3:4,3:6,4:1,4:2,4:3,4:6
+tokendb.allowedTransitions=0:1,0:2,0:3,0:6,3:2,3:6,4:1,4:2,4:3,4:6
tokendb.auditAdminTemplate=auditAdmin.template
tokendb.auditLog=[PKI_INSTANCE_PATH]/logs/tokendb-audit.log
tokendb.baseDN=ou=Tokens,[TOKENDB_ROOT]
diff --git a/base/tps/shared/conf/token-states.properties b/base/tps/shared/conf/token-states.properties
index f67688d4b..a64d940c6 100644
--- a/base/tps/shared/conf/token-states.properties
+++ b/base/tps/shared/conf/token-states.properties
@@ -15,6 +15,7 @@ UNINITIALIZED.TERMINATED = This token has been terminated.
TEMP_LOST.ACTIVE = This temporarily lost token has been found.
TEMP_LOST.PERM_LOST = This temporarily lost token has become permanently lost.
TEMP_LOST.TERMINATED = This temporarily lost token has been terminated.
+TEMP_LOST.UNINITIALIZED = This temporarily lost token has been found.
ACTIVE.DAMAGED = This token has been physically damaged.
ACTIVE.PERM_LOST = This token has been permanently lost.
ACTIVE.TEMP_LOST = This token has been temporarily lost.
diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java b/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java
index e8734a9b8..008f61333 100644
--- a/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java
+++ b/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java
@@ -17,6 +17,11 @@
// --- END COPYRIGHT BLOCK ---
package org.dogtagpki.server.tps;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+
import org.dogtagpki.server.tps.authentication.AuthenticationManager;
import org.dogtagpki.server.tps.cms.ConnectionManager;
import org.dogtagpki.server.tps.config.AuthenticatorDatabase;
@@ -26,7 +31,9 @@ import org.dogtagpki.server.tps.config.ProfileDatabase;
import org.dogtagpki.server.tps.config.ProfileMappingDatabase;
import org.dogtagpki.server.tps.dbs.ActivityDatabase;
import org.dogtagpki.server.tps.dbs.TPSCertDatabase;
+import org.dogtagpki.server.tps.dbs.TPSCertRecord;
import org.dogtagpki.server.tps.dbs.TokenDatabase;
+import org.dogtagpki.server.tps.dbs.TokenRecord;
import org.dogtagpki.server.tps.engine.TPSEngine;
import org.dogtagpki.server.tps.mapping.MappingResolverManager;
import org.mozilla.jss.CryptoManager;
@@ -43,6 +50,7 @@ import com.netscape.certsrv.dbs.IDBSubsystem;
import com.netscape.certsrv.logging.ILogger;
import com.netscape.certsrv.request.IRequestListener;
import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.tps.token.TokenStatus;
import com.netscape.cmscore.dbs.DBSubsystem;
/**
@@ -70,8 +78,10 @@ public class TPSSubsystem implements IAuthority, ISubsystem {
public ConnectionManager connManager;
public AuthenticationManager authManager;
public MappingResolverManager mappingResolverManager;
+
public TPSEngine engine;
public TPSTokendb tdb;
+ public Map<TokenStatus, Collection<TokenStatus>> allowedTransitions = new HashMap<TokenStatus, Collection<TokenStatus>>();
@Override
public String getId() {
@@ -105,6 +115,26 @@ public class TPSSubsystem implements IAuthority, ISubsystem {
connectorDatabase = new ConnectorDatabase();
profileDatabase = new ProfileDatabase();
profileMappingDatabase = new ProfileMappingDatabase();
+
+ CMS.debug("TokenSubsystem: allowed transitions:");
+
+ // initialize allowed token state transitions with empty containers
+ for (TokenStatus state : TokenStatus.values()) {
+ allowedTransitions.put(state, new LinkedHashSet<TokenStatus>());
+ }
+
+ // load allowed token state transitions from TPS configuration
+ for (String transition : cs.getString(TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS).split(",")) {
+ String states[] = transition.split(":");
+
+ TokenStatus fromState = TokenStatus.fromInt(Integer.valueOf(states[0]));
+ TokenStatus toState = TokenStatus.fromInt(Integer.valueOf(states[1]));
+ CMS.debug("TokenSubsystem: - " + fromState + " to " + toState);
+
+ Collection<TokenStatus> nextStates = allowedTransitions.get(fromState);
+ nextStates.add(toState);
+ }
+
tdb = new TPSTokendb(this);
engine = new TPSEngine();
@@ -112,6 +142,44 @@ public class TPSSubsystem implements IAuthority, ISubsystem {
}
+ /**
+ * Return the allowed next states for a given token based on TPS configuration.
+ *
+ * If the current state is TEMP_LOST, token will be allowed transition to either
+ * UNINITIALIZED or ACTIVE depending on whether the token has certificates.
+ *
+ * @param tokenRecord
+ * @return A non-null collection of allowed next token states.
+ */
+ public Collection<TokenStatus> getNextTokenStates(TokenRecord tokenRecord) throws Exception {
+
+ TokenStatus currentState = tokenRecord.getTokenStatus();
+ Collection<TokenStatus> nextStates = allowedTransitions.get(currentState);
+
+ if (currentState == TokenStatus.TEMP_LOST) {
+
+ Collection<TokenStatus> ns = new LinkedHashSet<TokenStatus>();
+
+ // check token certificates
+ Collection<TPSCertRecord> certRecords = tdb.tdbGetCertRecordsByCUID(tokenRecord.getId());
+
+ // if token has no certificates, allow token to become uninitialized again
+ if (certRecords.isEmpty()) {
+ ns.add(TokenStatus.UNINITIALIZED);
+
+ } else { // otherwise, allow token to become active again
+ ns.add(TokenStatus.ACTIVE);
+ }
+
+ // add the original allowed next states
+ ns.addAll(nextStates);
+
+ return ns;
+ }
+
+ return nextStates;
+ }
+
@Override
public void startup() throws EBaseException {
CMS.debug("TPSSubsystem: startup() begins");
diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
index 15e85fb32..51f496652 100644
--- a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
+++ b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
@@ -31,7 +30,6 @@ 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.server.tps.engine.TPSEngine;
import org.dogtagpki.server.tps.main.ExternalRegAttrs;
import org.dogtagpki.server.tps.main.ExternalRegCertToRecover;
import org.dogtagpki.tps.main.TPSException;
@@ -48,8 +46,8 @@ import netscape.security.x509.RevocationReason;
* TPSTokendb class offers a collection of tokendb management convenience routines
*/
public class TPSTokendb {
+
private TPSSubsystem tps;
- private Map<TokenStatus, Collection<TokenStatus>> allowedTransitions = new HashMap<TokenStatus, Collection<TokenStatus>>();
public TPSTokendb(TPSSubsystem tps) throws EBaseException {
if (tps == null) {
@@ -58,44 +56,17 @@ public class TPSTokendb {
throw new EBaseException(msg);
}
this.tps = tps;
- try {
- initAllowedTransitions();
- } catch (Exception e) {
- CMS.debug("TPSTokendb: initAllowedTransitions() failed:" + e);
- throw new EBaseException(e.toString());
- }
}
- void initAllowedTransitions()
- throws Exception {
- CMS.debug("TPSTokendb.initAllowedTransitions()");
- IConfigStore configStore = CMS.getConfigStore();
-
- // load allowed token state transitions
- CMS.debug("TPSTokendbs: allowed transitions:");
-
- for (String transition : configStore.getString(TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS).split(",")) {
- String states[] = transition.split(":");
- TokenStatus fromState = TokenStatus.fromInt(Integer.valueOf(states[0]));
- TokenStatus toState = TokenStatus.fromInt(Integer.valueOf(states[1]));
- CMS.debug("TPSTokendb: - " + fromState + " to " + toState);
-
- Collection<TokenStatus> nextStates = allowedTransitions.get(fromState);
- if (nextStates == null) {
- nextStates = new HashSet<TokenStatus>();
- allowedTransitions.put(fromState, nextStates);
- }
- nextStates.add(toState);
- }
- }
-
- public boolean isTransitionAllowed(TokenRecord tokenRecord, TokenStatus newState) {
+ public boolean isTransitionAllowed(TokenRecord tokenRecord, TokenStatus newState) throws Exception {
boolean result = false;
TokenStatus currentTokenStatus = tokenRecord.getTokenStatus();
+
CMS.debug("TokenRecord.isTransitionAllowed(): current status: " + currentTokenStatus);
- Collection<TokenStatus> nextStatuses = allowedTransitions.get(currentTokenStatus);
+ Collection<TokenStatus> nextStatuses = tps.getNextTokenStates(tokenRecord);
+
CMS.debug("TokenRecord.isTransitionAllowed(): allowed next statuses: " + nextStatuses);
- if (nextStatuses == null || !nextStatuses.contains(newState)) {
+ if (!nextStatuses.contains(newState)) {
CMS.debug("TokenRecord.isTransitionAllowed(): next status not allowed: " + newState);
result = false;
diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java
index a0ca7add3..958843e5b 100644
--- a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java
+++ b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java
@@ -24,7 +24,6 @@ import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
@@ -39,15 +38,12 @@ import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.dogtagpki.server.tps.TPSSubsystem;
import org.dogtagpki.server.tps.dbs.ActivityDatabase;
-import org.dogtagpki.server.tps.dbs.TPSCertRecord;
import org.dogtagpki.server.tps.dbs.TokenDatabase;
import org.dogtagpki.server.tps.dbs.TokenRecord;
-import org.dogtagpki.server.tps.engine.TPSEngine;
import org.jboss.resteasy.plugins.providers.atom.Link;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.BadRequestException;
-import com.netscape.certsrv.base.IConfigStore;
import com.netscape.certsrv.base.PKIException;
import com.netscape.certsrv.dbs.EDBException;
import com.netscape.certsrv.ldap.LDAPExceptionConverter;
@@ -77,58 +73,8 @@ public class TokenService extends PKIService implements TokenResource {
@Context
private HttpServletRequest servletRequest;
- public Map<TokenStatus, Collection<TokenStatus>> transitions = new HashMap<TokenStatus, Collection<TokenStatus>>();
-
public TokenService() throws Exception {
CMS.debug("TokenService.<init>()");
- IConfigStore configStore = CMS.getConfigStore();
-
- // load allowed token state transitions
- CMS.debug("TokenService: allowed transitions:");
-
- for (String transition : configStore.getString(TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS).split(",")) {
- String states[] = transition.split(":");
- TokenStatus fromState = TokenStatus.fromInt(Integer.valueOf(states[0]));
- TokenStatus toState = TokenStatus.fromInt(Integer.valueOf(states[1]));
- CMS.debug("TokenService: - " + fromState + " to " + toState);
-
- Collection<TokenStatus> nextStates = transitions.get(fromState);
- if (nextStates == null) {
- nextStates = new HashSet<TokenStatus>();
- transitions.put(fromState, nextStates);
- }
- nextStates.add(toState);
- }
-
- }
-
- public TokenStatus getTokenStatus(TokenRecord tokenRecord) {
- String status = tokenRecord.getStatus();
-
- if ("uninitialized".equals(status)) {
- return TokenStatus.UNINITIALIZED;
-
- } else if ("active".equals(status)) {
- return TokenStatus.ACTIVE;
-
- } else if ("lost".equals(status)) {
- String reason = tokenRecord.getReason();
-
- if ("keyCompromise".equals(reason)) {
- return TokenStatus.PERM_LOST;
-
- } else if ("destroyed".equals(reason)) {
- return TokenStatus.DAMAGED;
-
- } else if ("onHold".equals(reason)) {
- return TokenStatus.TEMP_LOST;
- }
-
- } else if ("terminated".equals(status)) {
- return TokenStatus.TERMINATED;
- }
-
- return TokenStatus.PERM_LOST;
}
public void setTokenStatus(TokenRecord tokenRecord, TokenStatus tokenState, String ipAddress, String remoteUser)
@@ -142,33 +88,14 @@ public class TokenService extends PKIService implements TokenResource {
break;
case ACTIVE:
- String origStatus = tokenRecord.getStatus();
- String origReason = tokenRecord.getReason();
-
- if (origStatus.equalsIgnoreCase("lost") &&
- origReason.equalsIgnoreCase("onHold")) {
-
- Collection<TPSCertRecord> certRecords = tps.tdb.tdbGetCertRecordsByCUID(tokenRecord.getId());
- if (certRecords.isEmpty()) { // token was uninitialized
- // restore to uninitialized state
- tokenRecord.setStatus("uninitialized");
- tokenRecord.setReason(null);
-
- } else { // token was active
- // unrevoke certs
- tps.tdb.unRevokeCertsByCUID(tokenRecord.getId(), ipAddress, remoteUser);
-
- // restore to active state
- tokenRecord.setStatus("active");
- tokenRecord.setReason(null);
- }
-
- } else {
- // switch to active state
- tokenRecord.setStatus("active");
- tokenRecord.setReason(null);
+ if (tokenRecord.getTokenStatus() == TokenStatus.TEMP_LOST) {
+ // unrevoke certs
+ tps.tdb.unRevokeCertsByCUID(tokenRecord.getId(), ipAddress, remoteUser);
}
+ tokenRecord.setStatus("active");
+ tokenRecord.setReason(null);
+
break;
case PERM_LOST:
@@ -221,6 +148,8 @@ public class TokenService extends PKIService implements TokenResource {
public TokenData createTokenData(TokenRecord tokenRecord) throws Exception {
+ TPSSubsystem subsystem = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID);
+
ResourceBundle labels = getResourceBundle("token-states");
TokenData tokenData = new TokenData();
@@ -229,23 +158,21 @@ public class TokenService extends PKIService implements TokenResource {
tokenData.setUserID(tokenRecord.getUserID());
tokenData.setType(tokenRecord.getType());
- TokenStatus status = getTokenStatus(tokenRecord);
+ TokenStatus status = tokenRecord.getTokenStatus();
TokenStatusData statusData = new TokenStatusData();
statusData.name = status;
statusData.label = labels.getString(status.toString());
tokenData.setStatus(statusData);
- Collection<TokenStatus> nextStates = transitions.get(status);
- if (nextStates != null) {
- Collection<TokenStatusData> nextStatesData = new ArrayList<TokenStatusData>();
- for (TokenStatus nextState : nextStates) {
- TokenStatusData nextStateData = new TokenStatusData();
- nextStateData.name = nextState;
- nextStateData.label = labels.getString(status + "." + nextState);
- nextStatesData.add(nextStateData);
- }
- tokenData.setNextStates(nextStatesData);
+ Collection<TokenStatus> nextStates = subsystem.getNextTokenStates(tokenRecord);
+ Collection<TokenStatusData> nextStatesData = new ArrayList<TokenStatusData>();
+ for (TokenStatus nextState : nextStates) {
+ TokenStatusData nextStateData = new TokenStatusData();
+ nextStateData.name = nextState;
+ nextStateData.label = labels.getString(status + "." + nextState);
+ nextStatesData.add(nextStateData);
}
+ tokenData.setNextStates(nextStatesData);
tokenData.setAppletID(tokenRecord.getAppletID());
tokenData.setKeyInfo(tokenRecord.getKeyInfo());
@@ -588,7 +515,7 @@ public class TokenService extends PKIService implements TokenResource {
TokenDatabase database = subsystem.getTokenDatabase();
tokenRecord = database.getRecord(tokenID);
- TokenStatus currentTokenStatus = getTokenStatus(tokenRecord);
+ TokenStatus currentTokenStatus = tokenRecord.getTokenStatus();
CMS.debug("TokenService.changeTokenStatus(): current status: " + currentTokenStatus);
if (currentTokenStatus == tokenStatus) {
@@ -601,9 +528,10 @@ public class TokenService extends PKIService implements TokenResource {
msg = msg + " from " + currentTokenStatus + " to " + tokenStatus;
// make sure transition is allowed
- Collection<TokenStatus> nextStatuses = transitions.get(currentTokenStatus);
+ Collection<TokenStatus> nextStatuses = subsystem.getNextTokenStates(tokenRecord);
CMS.debug("TokenService.changeTokenStatus(): allowed next statuses: " + nextStatuses);
- if (nextStatuses == null || !nextStatuses.contains(tokenStatus)) {
+
+ if (!nextStatuses.contains(tokenStatus)) {
CMS.debug("TokenService.changeTokenStatus(): next status not allowed: " + tokenStatus);
throw new BadRequestException("Invalid token status transition");
}