diff options
author | Christina Fu <cfu@redhat.com> | 2014-08-16 13:46:20 -0700 |
---|---|---|
committer | Christina Fu <cfu@redhat.com> | 2014-08-20 10:14:00 -0700 |
commit | f90798b725430ac2ec44d1e29ea9fbd53abc4c64 (patch) | |
tree | 1c19948a7c33e7bf8f06eca076dd36e6caf882f5 /base | |
parent | 6936dab4beffcb16dfff9332e5f18e37bf67c20a (diff) | |
download | pki-f90798b725430ac2ec44d1e29ea9fbd53abc4c64.tar.gz pki-f90798b725430ac2ec44d1e29ea9fbd53abc4c64.tar.xz pki-f90798b725430ac2ec44d1e29ea9fbd53abc4c64.zip |
ticket#882 tokendb policy handling, revocation and re-enroll
Diffstat (limited to 'base')
11 files changed, 1071 insertions, 218 deletions
diff --git a/base/common/src/org/dogtagpki/tps/main/Util.java b/base/common/src/org/dogtagpki/tps/main/Util.java index 8e6ffe614..c39b43577 100644 --- a/base/common/src/org/dogtagpki/tps/main/Util.java +++ b/base/common/src/org/dogtagpki/tps/main/Util.java @@ -20,11 +20,18 @@ */ package org.dogtagpki.tps.main; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.spec.AlgorithmParameterSpec; +import netscape.security.x509.AuthorityKeyIdentifierExtension; +import netscape.security.x509.KeyIdentifier; +import netscape.security.x509.PKIXExtensions; +import netscape.security.x509.SubjectKeyIdentifierExtension; +import netscape.security.x509.X509CertImpl; + import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.Cipher; import org.mozilla.jss.crypto.CryptoToken; @@ -32,6 +39,7 @@ import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.IVParameterSpec; import org.mozilla.jss.pkcs11.PK11SymKey; +import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; import com.netscape.cmsutil.util.Utils; @@ -288,4 +296,40 @@ public class Util { } + /* + * getCertAkiString returns the Authority Key Identifier of the certificate in Base64 encoding + * @param cert X509CertImpl of the cert to be processed + * @return Base64 encoding of the cert's AKI + */ + public static String getCertAkiString(X509CertImpl cert) + throws EBaseException, IOException { + if (cert == null) { + throw new EBaseException("CARemoteRequestHandler: getCertAkiString(): input parameter cert null."); + } + AuthorityKeyIdentifierExtension certAKI = + (AuthorityKeyIdentifierExtension) + cert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); + KeyIdentifier kid = + (KeyIdentifier) certAKI.get(AuthorityKeyIdentifierExtension.KEY_ID); + return (CMS.BtoA(kid.getIdentifier()).trim()); + } + + /* + * getCertAkiString returns the Subject Key Identifier of the certificate in Base64 encoding + * @param cert X509CertImpl of the cert to be processed + * @return Base64 encoding of the cert's SKI + */ + public static String getCertSkiString(X509CertImpl cert) + throws EBaseException, IOException { + if (cert == null) { + throw new EBaseException("CARemoteRequestHandler: getCertSkiString(): input parameter cert null."); + } + SubjectKeyIdentifierExtension certSKI = + (SubjectKeyIdentifierExtension) + cert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); + KeyIdentifier kid = + (KeyIdentifier) certSKI.get(SubjectKeyIdentifierExtension.KEY_ID); + return (CMS.BtoA(kid.getIdentifier()).trim()); + } + } diff --git a/base/tps-tomcat/shared/conf/CS.cfg.in b/base/tps-tomcat/shared/conf/CS.cfg.in index 4ae2b222f..e91b3451c 100644 --- a/base/tps-tomcat/shared/conf/CS.cfg.in +++ b/base/tps-tomcat/shared/conf/CS.cfg.in @@ -35,6 +35,7 @@ auths.impl.UidPwdPinDirAuth.class=com.netscape.cms.authentication.UidPwdPinDirAu auths.instance.AgentCertAuth.agentGroup=Certificate Manager Agents auths.instance.AgentCertAuth.pluginName=AgentCertAuth auths.instance.TokenAuth.pluginName=TokenAuth +auths.instance.ldap1.authCredName=uid auths.instance.ldap1.ui.retries=3 auths.instance.ldap1.ui.title.en=LDAP Authentication auths.instance.ldap1.ui.description.en=This authenticates user against the LDAP directory. @@ -1302,7 +1303,7 @@ tokendb.bindPassPath=[PKI_INSTANCE_PATH]/conf/password.conf tokendb.certBaseDN=ou=Certificates,[TOKENDB_ROOT] tokendb.confirmConfigChangesTemplate=confirmConfigChanges.template tokendb.confirmDeleteConfigTemplate=confirmDeleteConfig.template -tokendb.defaultPolicy=RE_ENROLL=YES +tokendb.defaultPolicy=RE_ENROLL=YES;RENEW=NO;FORCE_FORMAT=NO;PIN_RESET=NO;RESET_PIN_RESET_TO_NO=NO tokendb.deleteResultTemplate=deleteResults.template tokendb.deleteTemplate=delete.template tokendb.doTokenConfirmTemplate=doTokenConfirm.template diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java index 0d5fe4bc4..75cdddadb 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSubsystem.java @@ -105,7 +105,7 @@ public class TPSSubsystem implements IAuthority, ISubsystem { connectorDatabase = new ConnectorDatabase(); profileDatabase = new ProfileDatabase(); profileMappingDatabase = new ProfileMappingDatabase(); - tdb = new TPSTokendb(); + tdb = new TPSTokendb(this); engine = new TPSEngine(); engine.init(); diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokenPolicy.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokenPolicy.java new file mode 100644 index 000000000..1a866f737 --- /dev/null +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokenPolicy.java @@ -0,0 +1,158 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2014 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package org.dogtagpki.server.tps; + +import org.dogtagpki.server.tps.dbs.TokenRecord; +import org.dogtagpki.tps.main.TPSException; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.EPropertyNotFound; +import com.netscape.certsrv.base.IConfigStore; + +/* + * TPSTokenPolicy - handles token enrollment related policies + * + * @author cfu + */ +public class TPSTokenPolicy { + private TPSSubsystem tps; + private static final String DEFAULT_POLICY_SET_STRING = + "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 force_format = false; + private boolean pin_reset = true; + private boolean reset_pin_reset_to_no = false; + + public TPSTokenPolicy (TPSSubsystem tps) throws TPSException { + if (tps == null) { + String msg = "TPSTokenPolicy.TPSTokenPolicy: tps cannnot be null"; + CMS.debug(msg); + throw new TPSException(msg); + } + this.tps = tps; + // init from config first + String policySetString = getDefaultPolicySetString(); + parsePolicySetString(policySetString); + + } + + public String getDefaultPolicySetString() { + IConfigStore configStore = CMS.getConfigStore(); + String configName = "tokendb.defaultPolicy"; + String policySetString; + try { + policySetString = configStore.getString(configName); + } catch (EPropertyNotFound e) { + policySetString = DEFAULT_POLICY_SET_STRING; + } catch (EBaseException e) { + policySetString = DEFAULT_POLICY_SET_STRING; + } + + return policySetString; + } + + public void parsePolicySetString (String policySetString) { + if (policySetString == null) + return; // take the default + + String[] policySet = policySetString.split(";"); + for (String policyString : policySet) { + String[] policy = policyString.split("="); + if (policy[0].equalsIgnoreCase("RE_ENROLL")) + re_enroll = getBool(policy[1], true); + else if (policy[0].equalsIgnoreCase("RENEW")) + renew = getBool(policy[1], false); + else if (policy[0].equalsIgnoreCase("FORCE_FORMAT")) + force_format = getBool(policy[1], false); + else if (policy[0].equalsIgnoreCase("PIN_RESET")) + 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 no change, just take the default; + } + } + +/* + * getBool translates string to boolean: + * true: "YES", "yes", "TRUE", "true" + * false: "NO", "no", "FALSE", "false" + * + * if tring is null or Anything othrer than the above, defaultbool is returned + */ + private boolean getBool(String string, boolean defaultBool) { + if (string == null) + return defaultBool; + + if (string.equalsIgnoreCase("YES") || + string.equalsIgnoreCase("true")) { + return true; + } else if (string.equalsIgnoreCase("NO") || + string.equalsIgnoreCase("false")) { + return false; + } + + return defaultBool; + } + + private void getUpdatedPolicy(String cuid) { + // note: default policy already initialized in the constructor + TokenRecord tokenRecord = null; + String policySetString = null; + try { + tokenRecord = tps.tdb.tdbGetTokenEntry(cuid); + } catch (Exception e) { + // just take the default; + return; + } + + policySetString = tokenRecord.getPolicy(); + parsePolicySetString(policySetString); + } + + public boolean isAllowedTokenPinReset(String cuid) { + getUpdatedPolicy(cuid); + + return reset_pin_reset_to_no; + } + + public boolean isAllowedPinReset(String cuid) { + getUpdatedPolicy(cuid); + + return pin_reset; + } + + public boolean isForceTokenFormat(String cuid) { + getUpdatedPolicy(cuid); + + return force_format; + } + + public boolean isAllowdTokenReenroll(String cuid) { + getUpdatedPolicy(cuid); + + return re_enroll; + } + + public boolean isAllowdTokenRenew(String cuid) { + getUpdatedPolicy(cuid); + + return renew; + } +}
\ No newline at end of file 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 5b78c9dae..de3d443c6 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokendb.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSTokendb.java @@ -17,13 +17,16 @@ // --- END COPYRIGHT BLOCK --- package org.dogtagpki.server.tps; +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 org.dogtagpki.server.tps.dbs.TPSCertRecord; import org.dogtagpki.server.tps.dbs.TokenRecord; -import org.dogtagpki.server.tps.processor.EnrolledCertsInfo; +import org.dogtagpki.tps.main.TPSException; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; @@ -34,9 +37,16 @@ import com.netscape.certsrv.tps.token.TokenStatus; * 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() throws EBaseException { + public TPSTokendb(TPSSubsystem tps) throws EBaseException { + if (tps == null) { + String msg = "TPStokendb.TPSTokendb: tps cannot be null"; + CMS.debug(msg); + throw new EBaseException(msg); + } + this.tps = tps; try { initAllowedTransitions(); } catch (Exception e) { @@ -89,9 +99,9 @@ public class TPSTokendb { * tdbActivity logs token activities; This version is called by non-administrative functions */ public void tdbActivity( - TPSSubsystem tpsSubsystem, String op, TokenRecord tokenRecord, String ip, String msg, String result) { + String op, TokenRecord tokenRecord, String ip, String msg, String result) { try { - tpsSubsystem.activityDatabase.log( + tps.activityDatabase.log( ip, (tokenRecord != null)? tokenRecord.getId():null, op, @@ -108,9 +118,9 @@ public class TPSTokendb { * tdbActivity logs token activities; This version is called by administrative functions */ public void tdbActivity( - TPSSubsystem tpsSubsystem, String op, TokenRecord tokenRecord, String ip, String msg, String result, String uid) { + String op, TokenRecord tokenRecord, String ip, String msg, String result, String uid) { try { - tpsSubsystem.activityDatabase.log( + tps.activityDatabase.log( ip, (tokenRecord != null)? tokenRecord.getId():null, op, @@ -123,10 +133,10 @@ public class TPSTokendb { } } - public boolean isTokenPresent(TPSSubsystem tpsSubsystem, String cuid) { + public boolean isTokenPresent(String cuid) { boolean present = false; try { - tpsSubsystem.tokenDatabase.getRecord(cuid); + tps.tokenDatabase.getRecord(cuid); present = true; } catch (Exception e) { CMS.debug("TPSTokendb.isTokenPresent: token entry not found"); @@ -135,44 +145,127 @@ public class TPSTokendb { return present; } - public TokenRecord tdbGetTokenEntry(TPSSubsystem tpsSubsystem, String cuid) + public TokenRecord tdbGetTokenEntry(String cuid) + throws Exception { + return tps.tokenDatabase.getRecord(cuid); + } + + /* + * tdbFindTokenRecordsByUID finds and returns token records belong to one user + * @param uid the uid of the owner to the token + * @return ArrayList of the token records + */ + public ArrayList<TokenRecord> tdbFindTokenRecordsByUID(String uid) throws Exception { - return tpsSubsystem.tokenDatabase.getRecord(cuid); + ArrayList<TokenRecord> tokenRecords = new ArrayList<TokenRecord>(); + String filter = uid; + Iterator<TokenRecord> records = null; + records = tps.tokenDatabase.findRecords(filter).iterator(); + + while (records.hasNext()) { + TokenRecord tokenRecord = records.next(); + tokenRecords.add(tokenRecord); + } + + return tokenRecords; } - public void tdbAddTokenEntry(TPSSubsystem tpsSubsystem, TokenRecord tokenRecord, String status) + public void tdbHasActiveToken(String userid) + throws Exception { + if (userid == null) + throw new Exception("TPSTokendb.tdbhasActiveToken: uerid null"); + + ArrayList<TokenRecord> tokens = + tdbFindTokenRecordsByUID(userid); + boolean foundActive = false; + for (TokenRecord tokenRecord:tokens) { + if (tokenRecord.getStatus().equals("active")) { + foundActive = true; + } + } + if (!foundActive) { + throw new Exception("TPSTokendb.tdbhasActiveToken: active token not found"); + } + } + + public void tdbAddTokenEntry(TokenRecord tokenRecord, String status) throws Exception { tokenRecord.setStatus(status); - tpsSubsystem.tokenDatabase.addRecord(tokenRecord.getId(), tokenRecord); + tps.tokenDatabase.addRecord(tokenRecord.getId(), tokenRecord); } - public void tdbUpdateTokenEntry(TPSSubsystem tpsSubsystem, TokenRecord tokenRecord) + public void tdbUpdateTokenEntry(TokenRecord tokenRecord) throws Exception { String id = tokenRecord.getId(); TokenRecord existingTokenRecord; try { - existingTokenRecord = tpsSubsystem.tokenDatabase.getRecord(id); + existingTokenRecord = tps.tokenDatabase.getRecord(id); } catch (Exception e) { CMS.debug("TPSTokendb.tdbUpdateTokenEntry: token entry not found; Adding"); // add and exit - tdbAddTokenEntry(tpsSubsystem, tokenRecord, tokenRecord.getStatus()); + tdbAddTokenEntry(tokenRecord, "uninitialized"); return; } // token found; modify CMS.debug("TPSTokendb.tdbUpdateTokenEntry: token entry found; Modifying with status: "+ tokenRecord.getStatus()); // don't change the create time of an existing token record; put it back tokenRecord.setCreateTimestamp(existingTokenRecord.getCreateTimestamp()); - tpsSubsystem.tokenDatabase.updateRecord(id, tokenRecord); + tps.tokenDatabase.updateRecord(id, tokenRecord); } - public void tdbUpdateCertificates(TPSSubsystem tpsSubsystem, String cuid, EnrolledCertsInfo certs) - throws Exception { - boolean tokenExist = isTokenPresent(tpsSubsystem, cuid); + /* + * tdbAddCertificatesForCUID adds certificates issued for the token CUID + * @param cuid the cuid of the token + * @param certs an ArrayList of TPSCertRecord + */ + public void tdbAddCertificatesForCUID(String cuid, ArrayList<TPSCertRecord> certs) + throws TPSException { + boolean tokenExist = isTokenPresent(cuid); if (!tokenExist){ - throw new Exception("TPSTokendb:tdbUpdateCertificates: token "+ cuid + " does not exist"); + CMS.debug("TPSTokendb.tdbAddCertificatesForCUID: token not found: "+ cuid); + throw new TPSException("TPSTokendb:tdbUpdateCertificates: token "+ cuid + " does not exist"); + } + + CMS.debug("TPSTokendb.tdbAddCertificatesForCUID: found token "+ cuid); + CMS.debug("TPSTokendb.tdbAddCertificatesForCUID: number of certs to update:"+ certs.size()); + try { + for (TPSCertRecord cert: certs) { + cert.setOrigin(cuid); + tps.certDatabase.addRecord(cert.getId(), cert); + } + } catch (Exception e) { + CMS.debug("TPSTokendb.tdbAddCertificatesForCUID: "+ e); + // TODO: what if it throws in the middle of the cert list -- some cert records already updated? + throw new TPSException(e.getMessage()); } + } + /* + * tdbGetCertificatesByCUID finds and returns certificate records belong to a token cuid + * @param cuid the cuid of the token + * @return ArrayList of the cert records + */ + public ArrayList<TPSCertRecord> tdbGetCertificatesByCUID(String cuid) + throws TPSException { + if (cuid == null) + throw new TPSException("TPSTokendb.tdbGetCertificatesByCUID: cuid null"); + + ArrayList<TPSCertRecord> certRecords = new ArrayList<TPSCertRecord>(); + String filter = cuid; + Iterator<TPSCertRecord> records; + try { + records = tps.certDatabase.findRecords(filter).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; } } 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 aa5cb542b..bc92363b3 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 @@ -24,11 +24,7 @@ import java.security.cert.CertificateException; import java.util.Hashtable; import java.util.List; -import netscape.security.x509.AuthorityKeyIdentifierExtension; -import netscape.security.x509.KeyIdentifier; -import netscape.security.x509.PKIXExtensions; import netscape.security.x509.RevocationReason; -import netscape.security.x509.SubjectKeyIdentifierExtension; import netscape.security.x509.X509CertImpl; import org.dogtagpki.server.connector.IRemoteRequest; @@ -316,11 +312,11 @@ public class CARemoteRequestHandler extends RemoteRequestHandler * @returns CARevokeCertResponse */ private CARevokeCertResponse revokeCertificate( - BigInteger serialno, + String serialno, RevocationReason reason) throws EBaseException { - CMS.debug("CARemoteRequestHandler: revokeCertificate(): begins."); + CMS.debug("CARemoteRequestHandler: revokeCertificate(): begins on serial#:"+ serialno); if (serialno == null || reason == null) { throw new EBaseException("CARemoteRequestHandler: revokeCertificate(): input parameter null."); } @@ -337,7 +333,7 @@ public class CARemoteRequestHandler extends RemoteRequestHandler IRemoteRequest.CA_OP + "=" + IRemoteRequest.CA_REVOKE + "&" + IRemoteRequest.CA_REVOCATION_REASON + "=" + reason.getCode() + "&" + IRemoteRequest.CA_REVOKE_ALL + "=(" + - IRemoteRequest.CA_REVOKE_SERIAL + "=" + serialno.toString() + ")&" + + IRemoteRequest.CA_REVOKE_SERIAL + "=" + serialno + ")&" + IRemoteRequest.CA_REVOKE_COUNT + "=1"); String content = resp.getContent(); @@ -386,10 +382,10 @@ public class CARemoteRequestHandler extends RemoteRequestHandler * @returns CARevokeCertResponse */ private CARevokeCertResponse unrevokeCertificate( - BigInteger serialno) + String serialno) throws EBaseException { - CMS.debug("CARemoteRequestHandler: unrevokeCertificate(): begins."); + CMS.debug("CARemoteRequestHandler: unrevokeCertificate(): begins on serial#:"+ serialno); if (serialno == null) { throw new EBaseException("CARemoteRequestHandler: unrevokeCertificate(): input parameter null."); } @@ -401,7 +397,7 @@ public class CARemoteRequestHandler extends RemoteRequestHandler CMS.debug("CARemoteRequestHandler: unrevokeCertificate(): sending request to CA"); HttpResponse resp = conn.send("unrevoke", - IRemoteRequest.CA_UNREVOKE_SERIAL + "=" + serialno.toString()); + IRemoteRequest.CA_UNREVOKE_SERIAL + "=" + serialno); String content = resp.getContent(); CMS.debug("CARemoteRequestHandler: unrevokeCertificate(): got content = " + content); @@ -450,17 +446,36 @@ public class CARemoteRequestHandler extends RemoteRequestHandler * @param cert cert to (un)revoke * @param serialno parameter for the (Un)RevokeCertificate() functions * @param reason RevocationReason for the base revokeCertificate() function + * @throws IOException */ + @SuppressWarnings("unused") private CARevokeCertResponse revokeFromOtherCA( boolean revoke, // true==revoke; false==unrevoke X509CertImpl cert, RevocationReason reason) - throws EBaseException { - - CMS.debug("CARemoteRequestHandler: revokeFromOtherCA: begins"); + throws EBaseException, IOException { if (cert == null) { throw new EBaseException("CARemoteRequestHandler: revokeFromOtherCA(): input parameter cert null."); } + String certAkiString = null; + try { + certAkiString = Util.getCertAkiString(cert); + } catch (Exception e) { + throw new EBaseException("CARemoteRequestHandler: revokeFromOtherCA(): getCertAkiString failed:" + e); + } + return revokeFromOtherCA(revoke, cert.getSerialNumber().toString(), certAkiString, reason); + } + + + private CARevokeCertResponse revokeFromOtherCA( + boolean revoke, // true==revoke; false==unrevoke + String serialno, + String certAkiString, + RevocationReason reason) + throws EBaseException { + + + CMS.debug("CARemoteRequestHandler: revokeFromOtherCA: begins"); TPSSubsystem subsystem = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); @@ -468,12 +483,6 @@ public class CARemoteRequestHandler extends RemoteRequestHandler subsystem.getConnectionManager().getCAList(); Exception exception = null; - String certAkiString = null; - try { - certAkiString = getCertAkiString(cert); - } catch (Exception e) { - exception = e; - } for (String ca : caList) { try { @@ -481,9 +490,9 @@ public class CARemoteRequestHandler extends RemoteRequestHandler if (certAkiString.equals(caSkiString)) { CMS.debug("CARemoteRequestHandler: revokeFromOtherCA() cert AKI and caCert SKI matched"); if (revoke) { - return revokeCertificate(cert.getSerialNumber(), reason); + return revokeCertificate(serialno, reason); } else { - return unrevokeCertificate(cert.getSerialNumber()); + return unrevokeCertificate(serialno); } } else { // not a match then iterate to next ca in list CMS.debug("CARemoteRequestHandler: revokeFromOtherCA() cert AKI and caCert SKI not matched"); @@ -526,7 +535,6 @@ public class CARemoteRequestHandler extends RemoteRequestHandler * config store. If not, put it in, so we don't have to * calculate that every time. */ - String caSKI = null; try { String configName = "tps.connector." + conn + ".caSKI"; CMS.debug("CARemoteRequestHandler: getCaSki() retriving configName=" + configName); @@ -548,7 +556,7 @@ public class CARemoteRequestHandler extends RemoteRequestHandler X509Certificate c = cm.findCertByNickname(caNickname); X509CertImpl caCert = new X509CertImpl(c.getEncoded()); // now retrieve caSKI and store in config - caSkiString = getCertSkiString(caCert); + caSkiString = Util.getCertSkiString(caCert); CMS.debug("CARemoteRequestHandler: getCaSki() caSKI calculated. Saving it."); conf.putString("tps.connector." + conn + ".caSKI", caSkiString); conf.commit(false); @@ -577,31 +585,7 @@ public class CARemoteRequestHandler extends RemoteRequestHandler return caSkiString; } - private String getCertAkiString(X509CertImpl cert) - throws EBaseException, IOException { - if (cert == null) { - throw new EBaseException("CARemoteRequestHandler: getCertAkiString(): input parameter cert null."); - } - AuthorityKeyIdentifierExtension certAKI = - (AuthorityKeyIdentifierExtension) - cert.getExtension(PKIXExtensions.AuthorityKey_Id.toString()); - KeyIdentifier kid = - (KeyIdentifier) certAKI.get(AuthorityKeyIdentifierExtension.KEY_ID); - return (CMS.BtoA(kid.getIdentifier()).trim()); - } - private String getCertSkiString(X509CertImpl cert) - throws EBaseException, IOException { - if (cert == null) { - throw new EBaseException("CARemoteRequestHandler: getCertSkiString(): input parameter cert null."); - } - SubjectKeyIdentifierExtension certSKI = - (SubjectKeyIdentifierExtension) - cert.getExtension(PKIXExtensions.SubjectKey_Id.toString()); - KeyIdentifier kid = - (KeyIdentifier) certSKI.get(SubjectKeyIdentifierExtension.KEY_ID); - return (CMS.BtoA(kid.getIdentifier()).trim()); - } /** * revokeCertificate() supports revocation routing by providing @@ -624,11 +608,28 @@ public class CARemoteRequestHandler extends RemoteRequestHandler X509CertImpl cert, RevocationReason reason) throws EBaseException { - - CMS.debug("CARemoteRequestHandler: revokeCertificate() begins with CA discovery"); if (cert == null) { throw new EBaseException("CARemoteRequestHandler: revokeCertificate(): input parameter cert null."); } + String certAkiString = null; + try { + certAkiString = Util.getCertAkiString(cert); + } catch (IOException e) { + throw new EBaseException("CARemoteRequestHandler: revokeCertificate(): getCertAkiString failed:" + e); + } + + return revokeCertificate(revoke, cert.getSerialNumber().toString(), certAkiString, reason); + } + + public CARevokeCertResponse revokeCertificate( + boolean revoke, // true==revoke; false==unrevoke + String serialno, + String certAkiString, + RevocationReason reason) + throws EBaseException { + + CMS.debug("CARemoteRequestHandler: revokeCertificate() begins with CA discovery"); + if (revoke == true && reason == null) { throw new EBaseException("CARemoteRequestHandler: revokeCertificate(): input parameter reason null."); } @@ -636,11 +637,9 @@ public class CARemoteRequestHandler extends RemoteRequestHandler boolean skipMatch = false; String caSkiString = null; - String certAkiString = null; try { caSkiString = getCaSki(connid); - certAkiString = getCertAkiString(cert); } catch (Exception e) { CMS.debug("CARemoteRequestHandler: revokeCertificate() exception:" + e); skipMatch = true; @@ -654,19 +653,19 @@ public class CARemoteRequestHandler extends RemoteRequestHandler if (certAkiString.equals(caSkiString)) { CMS.debug("CARemoteRequestHandler: revokeCertificate() cert AKI and caCert SKI matched"); if (revoke) { - return revokeCertificate(cert.getSerialNumber(), reason); + return revokeCertificate(serialno, reason); } else { - return unrevokeCertificate(cert.getSerialNumber()); + return unrevokeCertificate(serialno); } } else { CMS.debug("CARemoteRequestHandler: revokeCertificate() cert AKI and caCert SKI of the designated issuing ca do not match...calling revokeFromOtherCA to search for another ca"); - return revokeFromOtherCA(revoke, cert, reason); + return revokeFromOtherCA(revoke, serialno, certAkiString, reason); } } else { if (revoke) { - return revokeCertificate(cert.getSerialNumber(), reason); + return revokeCertificate(serialno, reason); } else { - return unrevokeCertificate(cert.getSerialNumber()); + return unrevokeCertificate(serialno); } } } diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/dbs/TPSCertRecord.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/dbs/TPSCertRecord.java index 958913953..288f25f53 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/dbs/TPSCertRecord.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/dbs/TPSCertRecord.java @@ -58,6 +58,7 @@ public class TPSCertRecord extends DBRecord { this.id = id; } + // the serial number is in HEX @DBAttribute("tokenSerial") public String getSerialNumber() { return serialNumber; @@ -113,10 +114,12 @@ public class TPSCertRecord extends DBRecord { } @DBAttribute("userCertificate") + // Alternative to the actual certificate -- certificate AKI public String getCertificate() { return certificate; } + // Alternative to the actual certificate -- certificate AKI public void setCertificate(String certificate) { this.certificate = certificate; } diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java index 427e04e73..16716ab07 100644 --- a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java +++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/EnrolledCertsInfo.java @@ -17,12 +17,19 @@ // --- END COPYRIGHT BLOCK --- package org.dogtagpki.server.tps.processor; +import java.io.IOException; +import java.math.BigInteger; import java.util.ArrayList; import netscape.security.x509.X509CertImpl; +import org.dogtagpki.server.tps.dbs.TPSCertRecord; import org.dogtagpki.server.tps.main.PKCS11Obj; import org.dogtagpki.tps.main.TPSBuffer; +import org.dogtagpki.tps.main.Util; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; public class EnrolledCertsInfo { @@ -146,4 +153,108 @@ public class EnrolledCertsInfo { } + public ArrayList<TPSCertRecord> toTPSCertRecords(String cuid, String uid) { + ArrayList<TPSCertRecord> certs = new ArrayList<TPSCertRecord>(); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: starts"); + int index = 0; + for (X509CertImpl cert: certificates) { + TPSCertRecord certRecord = new TPSCertRecord(); + + //serial number + BigInteger serial_BigInt = cert.getSerialNumber(); + + String hexSerial = serial_BigInt.toString(16); + String serialNumber = "0x" + hexSerial; + certRecord.setSerialNumber(serialNumber); + + //id - TODO - calculate the real id later + String id = serialNumber+":"+uid; + + certRecord.setId(id); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: converting cert:"+ certRecord.getId()); + + //token id + certRecord.setTokenID(cuid); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: cuid =" + cuid); + + //origin + if ((!origins.isEmpty()) && index <origins.size() && origins.get(index)!= null) { + certRecord.setOrigin(origins.get(index)); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: origin =" + origins.get(index)); + } else { + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: origin not found for index:"+ index); + } + + //user id + certRecord.setUserID(uid); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: uid =" + uid); + + //KeyType + if ((!ktypes.isEmpty()) && index <ktypes.size() && ktypes.get(index)!= null) { + certRecord.setKeyType(ktypes.get(index)); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: keyType =" + ktypes.get(index)); + } else { + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: keyType not found for index:"+ index); + } + + //token type + if ((!tokenTypes.isEmpty()) && index <tokenTypes.size() && tokenTypes.get(index)!= null) { + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: tokenType=" + tokenTypes.get(index)); + certRecord.setType(tokenTypes.get(index)); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: tokenType set"); + } else { + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: tokenType not found for index:"+ index); + //certRecord.setType(""); + } + + //Issuer + String issuedBy = cert.getIssuerDN().toString(); + certRecord.setIssuedBy(issuedBy); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: issuer ="+ issuedBy); + + //Subject + String subject = cert.getSubjectDN().toString(); + certRecord.setSubject(subject); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: subject ="+ subject); + + //NotBefore + certRecord.setValidNotBefore(cert.getNotBefore()); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: notBefore ="+ cert.getNotBefore().toString()); + + //NotAfter + certRecord.setValidNotAfter(cert.getNotAfter()); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: notAfter ="+ cert.getNotAfter().toString()); + + //status + certRecord.setStatus("active"); + + /* certificate + byte[] certBytes = null; + try { + certBytes = cert.getEncoded(); + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: certBytes ="+ CMS.BtoA(certBytes)); + } catch (CertificateEncodingException e) { + CMS.debug("EnrolledCertsInfo.toTPSCertRecord: "+ e); + //TODO: throw + + } + certRecord.setCertificate(CMS.BtoA(certBytes)); + */ + // Alternative to the actual certificate -- certificate AKI + try { + String aki = Util.getCertAkiString(cert); + certRecord.setCertificate(aki); + } catch (EBaseException | IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + certs.add(certRecord); + + index++; + } + CMS.debug("EnrolledCertsInfo.toTPSCertRecords: ends"); + return certs; + } + } 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 9bc831b57..ecd86bd1a 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 @@ -3,6 +3,7 @@ package org.dogtagpki.server.tps.processor; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.Map; import java.util.Random; @@ -15,6 +16,7 @@ import netscape.security.x509.X509CertImpl; import org.dogtagpki.server.tps.TPSSession; import org.dogtagpki.server.tps.TPSSubsystem; +import org.dogtagpki.server.tps.TPSTokenPolicy; import org.dogtagpki.server.tps.authentication.TPSAuthenticator; import org.dogtagpki.server.tps.channel.SecureChannel; import org.dogtagpki.server.tps.channel.SecureChannel.TokenKeyType; @@ -22,6 +24,7 @@ import org.dogtagpki.server.tps.cms.CAEnrollCertResponse; import org.dogtagpki.server.tps.cms.CARemoteRequestHandler; import org.dogtagpki.server.tps.cms.KRAServerSideKeyGenResponse; 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.ObjectSpec; @@ -31,6 +34,7 @@ import org.dogtagpki.tps.main.TPSBuffer; import org.dogtagpki.tps.main.TPSException; import org.dogtagpki.tps.main.Util; import org.dogtagpki.tps.msg.BeginOpMsg; +import org.dogtagpki.tps.msg.EndOpMsg; import org.dogtagpki.tps.msg.EndOpMsg.TPSStatus; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.crypto.InvalidKeyFormatException; @@ -42,6 +46,7 @@ import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.authentication.IAuthCredentials; import com.netscape.certsrv.authentication.IAuthToken; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.EPropertyNotFound; import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.tps.token.TokenStatus; import com.netscape.cmsutil.util.Utils; @@ -69,8 +74,8 @@ public class TPSEnrollProcessor extends TPSProcessor { private void enroll() throws TPSException, IOException { CMS.debug("TPSEnrollProcessor enroll: entering..."); String auditMsg = null; - TPSEngine engine = getTPSEngine(); TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); + TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps); AppletInfo appletInfo = null; TokenRecord tokenRecord = null; @@ -78,14 +83,26 @@ public class TPSEnrollProcessor extends TPSProcessor { appletInfo = getAppletInfo(); } catch (TPSException e) { auditMsg = e.toString(); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw e; } appletInfo.setAid(getCardManagerAID()); + + CMS.debug("TPSEnrollProcessor.enroll: token cuid: " + appletInfo.getCUIDhexStringPlain()); boolean isTokenPresent = false; - tokenRecord = createTokenRecord(isTokenPresent, appletInfo); + try { + tokenRecord = tps.tdb.tdbGetTokenEntry(appletInfo.getCUIDhexStringPlain()); + // now the in memory tokenRecord is replaced by the actual token data + CMS.debug("TPSEnrollProcessor.enroll: found token..."); + isTokenPresent = true; + } catch (Exception e) { + CMS.debug("TPSEnrollProcessor.enroll: token does not exist in tokendb... create one in memory"); + tokenRecord = new TokenRecord(); + tokenRecord.setId(appletInfo.getCUIDhexStringPlain()); + } + fillTokenRecord(tokenRecord, appletInfo); session.setTokenRecord(tokenRecord); String resolverInstName = getResolverInstanceName(); @@ -97,10 +114,11 @@ public class TPSEnrollProcessor extends TPSProcessor { CMS.debug("TPSEnrollProcessor.enroll: resolved tokenType: " + tokenType); checkProfileStateOK(); + String cuid = appletInfo.getCUIDhexStringPlain(); boolean do_force_format = false; if (isTokenPresent) { - CMS.debug("TPSEnrollProcessor.enroll: token exists"); + CMS.debug("TPSEnrollProcessor.enroll: token exists in tokendb"); TokenStatus newState = TokenStatus.ACTIVE; // Check for transition to ACTIVE status. @@ -108,11 +126,11 @@ public class TPSEnrollProcessor extends TPSProcessor { CMS.debug("TPSEnrollProcessor.enroll: token transition disallowed " + tokenRecord.getTokenStatus() + " to " + newState); - auditMsg = "Operation for CUID " + appletInfo.getCUIDhexStringPlain() + + auditMsg = "Operation for CUID "+ cuid + " Disabled, illegal transition attempted " + tokenRecord.getTokenStatus() + " to " + newState; - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_DISABLED_TOKEN); @@ -121,7 +139,19 @@ public class TPSEnrollProcessor extends TPSProcessor { tokenRecord.getTokenStatus() + " to " + newState); } - do_force_format = engine.raForceTokenFormat(appletInfo.getCUIDhexString()); + do_force_format = tokenPolicy.isForceTokenFormat(cuid); + + if (!tokenPolicy.isAllowdTokenReenroll(cuid) && + !tokenPolicy.isAllowdTokenRenew(cuid)) { + CMS.debug("TPSEnrollProcessor.enroll: token renewal or reEnroll disallowed "); + auditMsg = "Operation renewal or reEnroll for CUID "+ cuid + + " Disabled"; + tps.tdb.tdbActivity(ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); + + throw new TPSException(auditMsg, + TPSStatus.STATUS_ERROR_DISABLED_TOKEN); + } } else { CMS.debug("TPSEnrollProcessor.enroll: token does not exist"); tokenRecord.setStatus("uninitialized"); @@ -162,27 +192,24 @@ public class TPSEnrollProcessor extends TPSProcessor { pkcs11objx = getCurrentObjectsOnToken(channel); } catch (DataFormatException e) { auditMsg = "TPSEnrollProcessor.enroll: Failed to parse original token data: " + e.toString(); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw new TPSException(auditMsg); } pkcs11objx.setCUID(appletInfo.getCUID()); - try { - tokenRecord.setStatus("active"); - String successMsg = "update token success"; - tps.tdb.tdbUpdateTokenEntry(tps, tokenRecord); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), - successMsg, "success"); - } catch (Exception e) { - String failMsg = "update token failure"; - auditMsg = failMsg + ":" + e.toString(); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), - failMsg, "failure"); - throw new TPSException(auditMsg); + if (!isTokenPresent) { + try { + tps.tdb.tdbAddTokenEntry(tokenRecord, "uninitialized"); + } catch (Exception e) { + String failMsg = "add token failure"; + auditMsg = failMsg + ":" + e.toString(); + throw new TPSException(auditMsg); + } } + statusUpdate(10, "PROGRESS_PROCESS_PROFILE"); EnrolledCertsInfo certsInfo = new EnrolledCertsInfo(); @@ -192,8 +219,41 @@ public class TPSEnrollProcessor extends TPSProcessor { certsInfo.setStartProgress(15); certsInfo.setEndProgress(90); - generateCertificates(certsInfo, channel, appletInfo); - + boolean renewed = false; + TPSStatus status = generateCertsAfterRenewalRecoveryPolicy(certsInfo, channel, appletInfo); + //anything failed would have thrown an exception + String statusString = "Unknown"; // gives some meaningful debug message + if (status == TPSStatus.STATUS_NO_ERROR) + statusString = "Enrollment to follow"; + else if (status == TPSStatus.STATUS_ERROR_RECOVERY_IS_PROCESSED) + statusString = "Recovery processed"; + else if (status == TPSStatus.STATUS_ERROR_RENEWAL_IS_PROCESSED) + statusString = "Renewal processed"; + auditMsg = "generateCertsAfterRenewalRecoveryPolicy returns status:" + + EndOpMsg.statusToInt(status) + " : " + statusString; + CMS.debug("TPSEnrollProcessor.enroll: " + auditMsg); + if (status == TPSStatus.STATUS_NO_ERROR) { + if (!generateCertificates(certsInfo, channel, appletInfo)) { + CMS.debug("TPSEnrollProcessor.enroll:generateCertificates returned false means some certs failed enrollment; clean up (format) the token"); + format(true /*skipAuth*/); + throw new TPSException("generateCertificates failed"); + } else { + CMS.debug("TPSEnrollProcessor.enroll:generateCertificates returned true means cert enrollment successful"); + } + } + // at this point, enrollment, renewal, or recovery have been processed accordingly; + if (status == TPSStatus.STATUS_ERROR_RENEWAL_IS_PROCESSED && + tokenPolicy.isAllowdTokenRenew(cuid)) { + renewed = true; + CMS.debug("TPSEnrollProcessor.enroll: renewal happened.. "); + } +/* + * TODO: + * find the point to do the following... + * when total available memory is exceeded on the token ... + * if(!renewed) //Renewal should leave what they have on the token. + * format(true); + */ String tokenLabel = buildTokenLabel(certsInfo, appletInfo); pkcs11objx.setTokenName(new TPSBuffer(tokenLabel.getBytes())); @@ -228,11 +288,27 @@ public class TPSEnrollProcessor extends TPSProcessor { statusUpdate(99, "PROGRESS_SET_LIFECYCLE"); channel.setLifeycleState((byte) 0x0f); - auditMsg = "enroll operation succeeded"; - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), auditMsg, - "success"); - //nothing to do here; log it and continue - CMS.debug(auditMsg); + try { + tokenRecord.setStatus("active"); + tps.tdb.tdbUpdateTokenEntry(tokenRecord); + } catch (Exception e){ + String failMsg = "update token failure"; + auditMsg = failMsg + ":" + e.toString(); + tps.tdb.tdbActivity(ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), failMsg, + "failure"); + throw new TPSException(auditMsg); + } + //update the tokendb with new certs + CMS.debug("TPSEnrollProcessor.enroll: updating tokendb with certs."); + ArrayList<TPSCertRecord> certRecords = certsInfo.toTPSCertRecords(tokenRecord.getId(), tokenRecord.getUserID()); + tps.tdb.tdbAddCertificatesForCUID(tokenRecord.getId(), certRecords); + + auditMsg = "appletVersion=" + lastObjVer + "; tokenType =" + selectedTokenType + "; userid =" + userid; + if (renewed) { + tps.tdb.tdbActivity(ActivityDatabase.OP_RENEWAL, tokenRecord, session.getIpAddress(), auditMsg, "success"); + } else { + tps.tdb.tdbActivity(ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), auditMsg, "success"); + } CMS.debug("TPSEnrollProcessor.enroll: leaving ..."); @@ -337,8 +413,8 @@ public class TPSEnrollProcessor extends TPSProcessor { // all exceptions are considered login failure CMS.debug("TPSEnrollProcessor.checkAndAuthenticateUser:: authentication exception thrown: " + e); String msg = "TPS error user authentication failed:" + e; - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), - msg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_ENROLLMENT, tokenRecord, session.getIpAddress(), msg, + "failure"); throw new TPSException(msg, TPSStatus.STATUS_ERROR_LOGIN); @@ -463,14 +539,14 @@ public class TPSEnrollProcessor extends TPSProcessor { protected boolean checkUpdateAppletEncryption() throws TPSException { - CMS.debug("TPSProcessor.checkUpdateAppletEncryption entering..."); + CMS.debug("TPSEnrollProcessor.checkUpdateAppletEncryption entering..."); IConfigStore configStore = CMS.getConfigStore(); String appletEncryptionConfig = "op." + currentTokenOperation + "." + selectedTokenType + "." + TPSEngine.CFG_UPDATE_APPLET_ENCRYPTION; - CMS.debug("TPSProcessor.checkUpdateAppletEncryption config to check: " + appletEncryptionConfig); + CMS.debug("TPSEnrollProcessor.checkUpdateAppletEncryption config to check: " + appletEncryptionConfig); boolean appletEncryption = false; @@ -479,10 +555,10 @@ public class TPSEnrollProcessor extends TPSProcessor { } catch (EBaseException e) { //Default TPSException will return a "contact admin" error code. throw new TPSException( - "TPSProcessor.checkUpdateAppletEncryption: internal error in getting value from config."); + "TPSEnrollProcessor.checkUpdateAppletEncryption: internal error in getting value from config."); } - CMS.debug("TPSProcessor.checkUpdateAppletEncryption returning: " + appletEncryption); + CMS.debug("TPSEnrollProcessor.checkUpdateAppletEncryption returning: " + appletEncryption); return appletEncryption; } @@ -561,11 +637,186 @@ public class TPSEnrollProcessor extends TPSProcessor { return pkcs11objx; } + /* + * generateCertsAfterRenewalRecoveryPolicy determines whether a renewal or recovery is needed; + * if recovery is needed, it determines which certificates (from which old token) + * to recover onto the new token. + * + * Note: renewal and recovery are invoked in this method; However, if a new enrollment is determined + * to be the proper course of action, it is done after this method. + */ + private TPSStatus generateCertsAfterRenewalRecoveryPolicy(EnrolledCertsInfo certsInfo, SecureChannel channel, AppletInfo aInfo) + throws TPSException { + TPSStatus status = TPSStatus.STATUS_NO_ERROR; + String auditMsg; + final String method = "TPSEnrollProcessor.generateCertsAfterRenewalRecoveryPolicy"; + CMS.debug(method + ": begins"); + TPSSubsystem tps = + (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); + TPSTokenPolicy tokenPolicy = new TPSTokenPolicy(tps); + + ArrayList<TokenRecord> tokenRecords = null; + try { + tokenRecords = tps.tdb.tdbFindTokenRecordsByUID(userid); + } catch (Exception e) { + // no existing record, means no "renewal" or "recovery" actions needed + auditMsg = "no token associated with user: " + userid; + CMS.debug(method + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_INACTIVE_TOKEN_NOT_FOUND); + } + CMS.debug(method + " found " + tokenRecords.size() + " tokens for user:" + userid); + boolean isRecover = false; + + for (TokenRecord tokenRecord:tokenRecords) { + CMS.debug(method + " token id:" + + tokenRecord.getId() + "; status=" + + tokenRecord.getStatus()); + if (isRecover == true) { // this could be set in previous iteration + TokenRecord lostToken = tokenRecord; + String reasonStr = lostToken.getReason(); + //RevocationReason reason = RevocationReason.valueOf(reasonStr); + String origTokenType = selectedTokenType; + auditMsg = "isRecover true; reasonStr =" + reasonStr; + CMS.debug(method + auditMsg); + + if (reasonStr.equals("keyCompromise")) { + return processRecovery(); + } else if (reasonStr.equals("onHold")) { + /* + * the inactive one becomes the temp token + * No recovery scheme, basically we are going to + * do the brand new enrollment + */ + IConfigStore configStore = CMS.getConfigStore(); + String configName = TPSEngine.OP_ENROLL_PREFIX + "." + getSelectedTokenType() + "temporaryToken.tokenType"; + try { + String tmpTokenType = configStore.getString(configName); + } catch (EPropertyNotFound e) { + auditMsg = "configuration " + configName + " not found"; + CMS.debug(method + auditMsg); + throw new TPSException(method + auditMsg); + } catch (EBaseException e) { + auditMsg = "configuration " + configName + " not found"; + CMS.debug(method + auditMsg); + throw new TPSException(method + auditMsg); + } + return processRecovery(); + + } else if (reasonStr.equals("destroyed")) { + return processRecovery(); + } else { + auditMsg = "No such lost reason: " + reasonStr + " for this cuid: " + aInfo.getCUIDhexStringPlain(); + CMS.debug(method + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_NO_SUCH_LOST_REASON); + } + + } + + //Is this the same token? + if (tokenRecord.getId().equals(aInfo.getCUIDhexStringPlain())) { + //same token + if (tokenRecord.getStatus().equals("uninitialized")) { + if (tokenRecords.size() == 1) { + CMS.debug(method + ": need to do enrollment"); + // need to do enrollment outside + break; + } else { + CMS.debug(method + ": There are multiple token entries for user " + + userid); + try { + tps.tdb.tdbHasActiveToken(userid); + auditMsg = method + ": user already has an active token"; + CMS.debug(auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN); + } catch (Exception e1) {// user has no active token + /* + * current token is in active state + * there are no other active tokens for this user + * that means the previous one is the lost one + * + * get the most recent previous token: + */ + isRecover = true; + } + } + } else if (tokenRecord.getStatus().equals("active")) { + if (tokenPolicy.isAllowdTokenRenew(aInfo.getCUIDhexStringPlain())) { + return processRenewal(); } + break; + } else if (tokenRecord.getStatus().equals("terminated")) { + auditMsg = method + ": terminated token cuid=" + + aInfo.getCUIDhexStringPlain(); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_CONTACT_ADMIN); + } else if (tokenRecord.getStatus().equals("lost")) { + String reasonStr = tokenRecord.getReason(); + if (reasonStr.equals("keyCompromise")) { + auditMsg = "This token cannot be reused because it has been reported lost"; + CMS.debug(method + ": " + + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_UNUSABLE_TOKEN_KEYCOMPROMISE); + } else if (reasonStr.equals("onHold")) { + try { + tps.tdb.tdbHasActiveToken(userid); + auditMsg = "user already has an active token"; + CMS.debug(method + ": " + + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN); + } catch (Exception e2) { + auditMsg = "User needs to contact administrator to report lost token (it should be put on Hold)."; + CMS.debug(method + ": " + + auditMsg); + break; + } + } else if (reasonStr.equals("destroyed")) { + auditMsg = "This destroyed lost case should not be executed because the token is so damaged. It should not get here"; + CMS.debug(method + ": " + + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_TOKEN_DISABLED); + } else { + auditMsg = "No such lost reason: " + reasonStr + " for this cuid: " + aInfo.getCUIDhexStringPlain(); + CMS.debug(method + ":" + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_NO_SUCH_LOST_REASON); + } + + } else { + auditMsg = "No such token status for this cuid=" + aInfo.getCUIDhexStringPlain(); + CMS.debug(method + ":" + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_NO_SUCH_TOKEN_STATE); + } + } else { //cuid != current token + continue; + } + } + + CMS.debug(method + ": ends"); + return status; + } + + private TPSStatus processRenewal() { + TPSStatus status = TPSStatus.STATUS_ERROR_RENEWAL_IS_PROCESSED; + + // TODO Auto-generated method stub + CMS.debug("TPSEnrollProcess.processRenewal: reached"); + + return status; + } + + private TPSStatus processRecovery() { + TPSStatus status = TPSStatus.STATUS_ERROR_RECOVERY_IS_PROCESSED; + + // TODO Auto-generated method stub + CMS.debug("TPSEnrollProcess.processRecovery: reached"); + + return status; + } + //Stub to generate a certificate, more to come - private void generateCertificates(EnrolledCertsInfo certsInfo, SecureChannel channel, AppletInfo aInfo) + private boolean generateCertificates(EnrolledCertsInfo certsInfo, SecureChannel channel, AppletInfo aInfo) throws TPSException, IOException { - CMS.debug("TPSProcess.generateCertificates: begins "); + CMS.debug("TPSEnrollProcess.generateCertificates: begins "); + boolean noFailedCerts = true; + if (certsInfo == null || aInfo == null || channel == null) { throw new TPSException("TPSEnrollProcessor.generateCertificates: Bad Input data!", TPSStatus.STATUS_ERROR_MAC_ENROLL_PDU); @@ -580,10 +831,27 @@ public class TPSEnrollProcessor extends TPSProcessor { for (int i = 0; i < keyTypeNum; i++) { String keyType = getConfiguredKeyType(i); certsInfo.setCurrentCertIndex(i); - generateCertificate(certsInfo, channel, aInfo, keyType); + try { + generateCertificate(certsInfo, channel, aInfo, keyType); + } catch (TPSException e) { + CMS.debug("TPSEnrollProcessor.generateCertificate: exception:" + e); + noFailedCerts = false; + break; //need to clean up half-done token later + } + } + + /* + * In this special case of RE_ENROLL, Revoke current certs for this token + * if so configured + */ + /*TODO: format that follows should do this already based on the returned noFailedCerts value + if (noFailedCerts == true) { + revokeCertificates(aInfo.getCUIDhexStringPlain()); } + */ - CMS.debug("TPSProcess.generateCertificates: ends "); + CMS.debug("TPSEnrollProcessor.generateCertificates: ends "); + return noFailedCerts; } private String buildTokenLabel(EnrolledCertsInfo certsInfo, AppletInfo ainfo) throws TPSException { @@ -1498,11 +1766,11 @@ public class TPSEnrollProcessor extends TPSProcessor { try { id = configStore.getString(config, "kra1"); } catch (EBaseException e) { - throw new TPSException("TPSProcessor.getDRMConnectorID: Internal error finding config value."); + throw new TPSException("TPSEnrollProcessor.getDRMConnectorID: Internal error finding config value."); } - CMS.debug("TPSProcessor.getDRMConectorID: returning: " + id); + CMS.debug("TPSEnrollProcessor.getDRMConectorID: returning: " + id); return id; } @@ -1533,24 +1801,6 @@ public class TPSEnrollProcessor extends TPSProcessor { return keyTypeNum; } - protected String getCAConnectorID() throws TPSException { - IConfigStore configStore = CMS.getConfigStore(); - String id = null; - - String config = "op." + currentTokenOperation + "." + selectedTokenType + ".ca.conn"; - - try { - id = configStore.getString(config, "ca1"); - } catch (EBaseException e) { - throw new TPSException("TPSEnrollProcessor.getCAConnectorID: Internal error finding config value."); - - } - - CMS.debug("TPSEnrollProcessor.getCAConectorID: returning: " + id); - - return id; - } - private TPSBuffer makeKeyIDFromPublicKeyInfo(byte[] publicKeyInfo) throws TPSException { final String alg = "SHA1"; 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 94cab4a29..85ad5ff85 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 @@ -19,25 +19,32 @@ package org.dogtagpki.server.tps.processor; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import netscape.security.x509.RevocationReason; + import org.dogtagpki.server.tps.TPSSession; import org.dogtagpki.server.tps.TPSSubsystem; import org.dogtagpki.server.tps.authentication.AuthUIParameter; import org.dogtagpki.server.tps.authentication.TPSAuthenticator; import org.dogtagpki.server.tps.channel.SecureChannel; +import org.dogtagpki.server.tps.cms.CARemoteRequestHandler; +import org.dogtagpki.server.tps.cms.CARevokeCertResponse; import org.dogtagpki.server.tps.cms.TKSComputeRandomDataResponse; import org.dogtagpki.server.tps.cms.TKSComputeSessionKeyResponse; import org.dogtagpki.server.tps.cms.TKSEncryptDataResponse; import org.dogtagpki.server.tps.cms.TKSRemoteRequestHandler; 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.profile.BaseTokenProfileResolver; @@ -904,33 +911,19 @@ public class TPSProcessor { } /* - * createTokenRecord - + * fillTokenRecord - * - retrieves token record from tokendb if it exists, or * - creates a new token record - * - sets the isTokenPresent to true if token found in tokendb * this in-memory copy of tokenRecord is to be set in the TPSSession */ - protected TokenRecord createTokenRecord(boolean isTokenPresent, AppletInfo appletInfo) + protected void fillTokenRecord(TokenRecord tokenRecord, AppletInfo appletInfo) throws TPSException { - CMS.debug("TPSProcessor.createTokenRecord: begins"); - if (appletInfo == null) { - CMS.debug("TPSProcessor.createTokenRecord: param appletInfo cannot be null"); + String method = "TPSProcessor.fillTokenRecord"; + CMS.debug(method + ": begins"); + if (tokenRecord == null || appletInfo == null) { + CMS.debug(method + ": params tokenRecord and appletInfo cannot be null"); throw new TPSException( - "TPSProcessor.requestExtendedLogin: missing parameter(s): parameter appletInfo"); - } - TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); - TokenRecord tokenRecord = null; - - try { - TokenRecord gotToken = tps.tdb.tdbGetTokenEntry(tps, appletInfo.getCUIDhexStringPlain()); - // now the in memory tokenRecord is replaced by the actual token data - tokenRecord = gotToken; - CMS.debug("TPSProcessor.createTokenRecord: found token..."); - isTokenPresent = true; - } catch (Exception e) { - CMS.debug("TPSProcessor.createTokenRecord: token does not exist..."); - tokenRecord = new TokenRecord(); - tokenRecord.setId(appletInfo.getCUIDhexStringPlain()); + method + ": missing parameter(s): parameter appletInfo"); } byte app_major_version = appletInfo.getAppMajorVersion(); @@ -939,7 +932,7 @@ public class TPSProcessor { try { build_id = getAppletVersion(); } catch (IOException e) { - CMS.debug("TPSProcessor.createTokenRecord: failed getting applet version:" + e + " ... continue"); + CMS.debug(method + ": failed getting applet version:" + e + " ... continue"); } if (build_id != null) { tokenRecord.setAppletID(Integer.toHexString(app_major_version) + "." @@ -947,11 +940,209 @@ public class TPSProcessor { build_id.toHexStringPlain()); } - CMS.debug("TPSProcessor.createTokenRecord: ends"); + CMS.debug(method + ": ends"); + + } + + protected String getCAConnectorID() throws TPSException { + IConfigStore configStore = CMS.getConfigStore(); + String id = null; + + String config = "op." + currentTokenOperation + "." + selectedTokenType + ".ca.conn"; + + try { + id = configStore.getString(config, "ca1"); + } catch (EBaseException e) { + throw new TPSException("TPSProcessor.getCAConnectorID: Internal error finding config value."); + + } + + CMS.debug("TPSProcessor.getCAConectorID: returning: " + id); - return tokenRecord; + return id; } + /* + * 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 + */ + protected void revokeCertificates(String cuid) throws TPSException { + String auditMsg = ""; + final String method = "TPSProcessor.revokeCertificates"; + + //bail out if not configured to revoke cert + IConfigStore configStore = CMS.getConfigStore(); + String configName = TPSEngine.OP_FORMAT_PREFIX + "." + selectedTokenType + ".revokeCert"; + boolean revokeCert = false; + try { + revokeCert = configStore.getBoolean(configName, false); + } catch (EBaseException e) { + auditMsg = method + ": config not found: "+ configName + + "; default to false"; + CMS.debug(auditMsg); + return; + } + if (!revokeCert) { + auditMsg = method + ": revokeCert = false"; + CMS.debug(auditMsg); + return; + } + + if (cuid == null) { + auditMsg = "cuid null"; + CMS.debug(method + ":" + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + CMS.debug(method + ": begins for cuid:" + cuid); + TPSSubsystem tps = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); + boolean isTokenPresent = tps.tdb.isTokenPresent(cuid); + if (!isTokenPresent) { + auditMsg = method + ": token not found: "+ cuid; + CMS.debug(auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + + String caConnId = getCAConnectorID(); + CARemoteRequestHandler caRH = null; + try { + caRH = new CARemoteRequestHandler(caConnId); + } catch (EBaseException e) { + auditMsg = method + ": getting CARemoteRequestHandler failure"; + CMS.debug(auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + //find all certs belonging to the token + ArrayList<TPSCertRecord> certRecords = tps.tdb.tdbGetCertificatesByCUID(cuid); + + CMS.debug(method + ": found " + certRecords.size() + " certs"); + + for (TPSCertRecord cert:certRecords) { + if (cert.getStatus().equals("revoked")) { + // already revoked cert should not be on token any more + CMS.debug(method + ": cert " + cert.getSerialNumber() + + " already revoked; remove from tokendb and move on"); + try { + tps.certDatabase.removeRecord(cert.getId()); + } catch (Exception e) { + auditMsg = method + ": removeRecord failed"; + CMS.debug(auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + continue; + } + + String origin = cert.getOrigin(); + if (origin!= null && !origin.equals(cuid)) { + /* + * Raidzilla Bug #57803: + * If the certificate is not originally created for this + * token, we should not revoke the certificate here. + * To figure out if this certificate is originally created + * for this token, we check the tokenOrigin attribute. + */ + CMS.debug(method + ": cert " + cert.getSerialNumber() + + " originally created for this token: "+ origin + + " while current token: " + cuid + + "; Remove from tokendb and skip the revoke"); + try { + tps.certDatabase.removeRecord(cert.getId()); + } catch (Exception e) { + auditMsg = method + ": removeRecord failed"; + CMS.debug(auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + continue; + } + if (origin == null) { + // no tokenOrigin, then don't care, keep going + CMS.debug(method + ": tokenOrigin is not present in tokendb cert record"); + } + + // revoke the cert + /* + * if the certificates are revoked_on_hold, don't do anything because the certificates may + * be referenced by more than one token. + */ + if (cert.getStatus().equals("revoked_on_hold")) { + CMS.debug(method + ": cert " + cert.getSerialNumber() + + " has status revoked_on_hold; remove from tokendb and move on"); + try { + tps.certDatabase.removeRecord(cert.getId()); + } catch (Exception e) { + auditMsg = method + ": removeRecord failed"; + CMS.debug(auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + 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' + BigInteger bInt = new BigInteger(serial, 16); + String serialStr = bInt.toString(); + CMS.debug(method + ": found cert hex serial: " + serial + + " dec serial:" + serialStr); + try { + CARevokeCertResponse response = + caRH.revokeCertificate(true, serialStr, cert.getCertificate(), + revokeReason); + CMS.debug(method + ": response status =" + response.getStatus()); + } catch (EBaseException e) { + auditMsg = method + ": revokeCertificate from CA failed:" + e; + CMS.debug(auditMsg); + + if (revokeReason == RevocationReason.CERTIFICATE_HOLD) { + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, session.getTokenRecord(), + session.getIpAddress(), auditMsg, + "failure"); + } else { + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, session.getTokenRecord(), + session.getIpAddress(), auditMsg, + "failure"); + } + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + } else { + auditMsg = "mulformed hex serial number :" + hexSerial; + CMS.debug(method + ": " + auditMsg); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, session.getTokenRecord(), session.getIpAddress(), + auditMsg, + "failure"); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_REVOKE_CERTIFICATES_FAILED); + } + auditMsg = "Certificate " + hexSerial + " revoked"; + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, session.getTokenRecord(), session.getIpAddress(), auditMsg, + "success"); + + // delete cert from tokendb + CMS.debug(method + ": cert " + cert.getSerialNumber() + + ": remove from tokendb"); + try { + tps.certDatabase.removeRecord(cert.getId()); + } catch (Exception e) { + auditMsg = "removeRecord failed:" + e; + CMS.debug(method + ": " + auditMsg); + throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_UPDATE_TOKENDB_FAILED); + } + continue; + } + CMS.debug(method + ": done for cuid:" + cuid); + } + + protected void format(boolean skipAuth) throws TPSException, IOException { String auditMsg = null; @@ -966,14 +1157,14 @@ public class TPSProcessor { appletInfo = getAppletInfo(); } catch (TPSException e) { auditMsg = e.toString(); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw e; } appletInfo.setAid(getCardManagerAID()); boolean isTokenPresent = false; - tokenRecord = createTokenRecord(isTokenPresent, appletInfo); + fillTokenRecord(tokenRecord, appletInfo); session.setTokenRecord(tokenRecord); String cuid = appletInfo.getCUIDhexString(); @@ -1008,8 +1199,8 @@ public class TPSProcessor { tokenType = resolveTokenProfile(resolverInstName, cuid, msn, major_version, minor_version); } catch (TPSException e) { auditMsg = e.toString(); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_MISCONFIGURATION); } @@ -1028,8 +1219,8 @@ public class TPSProcessor { } catch (EBaseException e) { CMS.debug("TPSProcessor.format: Internal Error obtaining mandatory config values. Error: " + e); auditMsg = "TPS error getting config values from config store." + e.toString(); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_MISCONFIGURATION); } @@ -1053,8 +1244,8 @@ public class TPSProcessor { CMS.debug("TPSProcessor.format:: authentication exception thrown: " + e); auditMsg = "authentication failed, status = STATUS_ERROR_LOGIN"; - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_LOGIN); @@ -1083,8 +1274,8 @@ public class TPSProcessor { " Disabled, illegal transition attempted " + tokenRecord.getTokenStatus() + " to " + newState; - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), - auditMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), auditMsg, + "failure"); throw new TPSException(auditMsg, TPSStatus.STATUS_ERROR_DISABLED_TOKEN); @@ -1137,25 +1328,34 @@ public class TPSProcessor { channel.externalAuthenticate(); tokenRecord.setKeyInfo(channel.getKeyInfoData().toHexStringPlain()); + if (isTokenPresent) { + // Revoke certificates on token, if so configured + try { + revokeCertificates(tokenRecord.getId()); + } catch (TPSException te) { + // failed revocation; capture message and continue + auditMsg = te.getMessage(); + } + } + // Update Token DB try { - tps.tdb.tdbUpdateTokenEntry(tps, tokenRecord); + tps.tdb.tdbUpdateTokenEntry(tokenRecord); String successMsg = "update token success"; - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), - successMsg, "success"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), successMsg, + "success"); } catch (Exception e) { String failMsg = "update token failure"; auditMsg = failMsg + ":" + e.toString(); - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), - failMsg, "failure"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), failMsg, + "failure"); throw new TPSException(auditMsg); } - // ToDo: Revoke certificates auditMsg = "format operation succeeded"; - tps.tdb.tdbActivity(tps, ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), auditMsg, "success"); + tps.tdb.tdbActivity(ActivityDatabase.OP_FORMAT, tokenRecord, session.getIpAddress(), auditMsg, "success"); CMS.debug("TPSProcessor.format:: ends"); @@ -1229,7 +1429,6 @@ public class TPSProcessor { CMS.debug("TPSProcessor.getResolverInstanceName: returning: " + resolverInstName); - // TODO Auto-generated method stub return resolverInstName; } @@ -2106,10 +2305,10 @@ public class TPSProcessor { String key = entry.getKey(); String value = entry.getValue(); - CMS.debug("TPSEnrollProcessor.mapPattern: Exposed: key: " + key + " Param: " + value); + CMS.debug("TPSProcessor.mapPattern: Exposed: key: " + key + " Param: " + value); if (key.equals(patternToMap)) { - CMS.debug("TPSEnrollProcessor.mapPattern: found match: key: " + key + " mapped to: " + value); + CMS.debug("TPSProcessor.mapPattern: found match: key: " + key + " mapped to: " + value); patternMapped = value; break; } @@ -2118,7 +2317,7 @@ public class TPSProcessor { result = piece1 + patternMapped + piece2; - CMS.debug("TPSEnrollProcessor.mapPattern: returning: " + result); + CMS.debug("TPSProcessor.mapPattern: returning: " + result); return result; } 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 84046a964..898091d20 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 @@ -292,18 +292,16 @@ public class TokenService extends PKIService implements TokenResource { tokenRecord = createTokenRecord(tokenData); tokenRecord.setId(tokenID); database.addRecord(tokenID, tokenRecord); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_ADD, - tokenRecord, ipAddress, msg, "success", - remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_ADD, tokenRecord, + ipAddress, msg, "success", remoteUser); tokenData = createTokenData(database.getRecord(tokenID)); return createCreatedResponse(tokenData, tokenData.getLink().getHref()); } catch (Exception e) { e.printStackTrace(); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_ADD, - tokenRecord, ipAddress, msg, "failure", - remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_ADD, tokenRecord, + ipAddress, msg, "failure", remoteUser); msg = msg + ":" + e; throw new PKIException(msg); @@ -334,9 +332,8 @@ public class TokenService extends PKIService implements TokenResource { tokenRecord.setKeyInfo(tokenData.getKeyInfo()); tokenRecord.setPolicy(tokenData.getPolicy()); database.updateRecord(tokenID, tokenRecord); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DO_TOKEN, - tokenRecord, ipAddress, msg, "success", - remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DO_TOKEN, tokenRecord, + ipAddress, msg, "success", remoteUser); tokenData = createTokenData(database.getRecord(tokenID)); @@ -344,9 +341,9 @@ public class TokenService extends PKIService implements TokenResource { } catch (Exception e) { e.printStackTrace(); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DO_TOKEN, - tokenRecord, ipAddress, msg, - "failure", remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DO_TOKEN, tokenRecord, + ipAddress, msg, "failure", + remoteUser); msg = msg + ":" + e; throw new PKIException(msg); @@ -403,9 +400,8 @@ public class TokenService extends PKIService implements TokenResource { } database.updateRecord(tokenID, tokenRecord); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DO_TOKEN, - tokenRecord, ipAddress, msg, "success", - remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DO_TOKEN, tokenRecord, + ipAddress, msg, "success", remoteUser); tokenData = createTokenData(database.getRecord(tokenID)); @@ -413,9 +409,9 @@ public class TokenService extends PKIService implements TokenResource { } catch (Exception e) { e.printStackTrace(); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DO_TOKEN, - tokenRecord, ipAddress, msg, - "failure", remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DO_TOKEN, tokenRecord, + ipAddress, msg, "failure", + remoteUser); msg = msg + ":" + e; throw new PKIException(msg); @@ -450,19 +446,19 @@ public class TokenService extends PKIService implements TokenResource { if (nextStatuses == null || !nextStatuses.contains(tokenStatus)) { CMS.debug("TokenService.changeTokenStatus(): next status not allowed: " + tokenStatus); msg = msg + ": Invalid token status transition"; - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DO_TOKEN, - tokenRecord, ipAddress, - msg, - "failure", remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DO_TOKEN, tokenRecord, + ipAddress, msg, + "failure", + remoteUser); throw new BadRequestException(msg); } CMS.debug("TokenService.changeTokenStatus(): next status allowed: " + tokenStatus); setTokenStatus(tokenRecord, tokenStatus); database.updateRecord(tokenID, tokenRecord); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DO_TOKEN, - tokenRecord, ipAddress, msg, - "success", remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DO_TOKEN, tokenRecord, + ipAddress, msg, "success", + remoteUser); TokenData tokenData = createTokenData(database.getRecord(tokenID)); @@ -471,9 +467,9 @@ public class TokenService extends PKIService implements TokenResource { } catch (Exception e) { e.printStackTrace(); msg = msg + e; - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DO_TOKEN, - tokenRecord, ipAddress, msg, - "failure", remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DO_TOKEN, tokenRecord, + ipAddress, msg, "failure", + remoteUser); throw new PKIException(msg); } @@ -496,17 +492,16 @@ public class TokenService extends PKIService implements TokenResource { TokenDatabase database = subsystem.getTokenDatabase(); tokenRecord = database.getRecord(tokenID); database.removeRecord(tokenID); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DELETE, - tokenRecord, ipAddress, msg, "success", - remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DELETE, tokenRecord, + ipAddress, msg, "success", remoteUser); return createNoContentResponse(); } catch (Exception e) { e.printStackTrace(); - subsystem.tdb.tdbActivity(subsystem, ActivityDatabase.OP_DELETE, - tokenRecord, ipAddress, msg, - "failure", remoteUser); + subsystem.tdb.tdbActivity(ActivityDatabase.OP_DELETE, tokenRecord, + ipAddress, msg, "failure", + remoteUser); msg = msg + ":" + e; throw new PKIException(msg); |