From 8b90cb661c42c31fcc5ca8dba92ef9dbfee08dd8 Mon Sep 17 00:00:00 2001
From: Jack Magne <jmagne@dhcp-16-213.sjc.redhat.com>
Date: Thu, 6 Mar 2014 11:29:10 -0800
Subject: [PATCH] Further work on TPS Processor, format operation.

1. Method to calculate the token type.
2. Some added convenience methods to get various config params for the Format operation.
3. More progress for the format operation up until we attempt to upgrade the applet.
4. Added TPSException that holds a message and end op return code. Can be used to throw from anywhere and the return code makes it back to the client.

Further changes.
---
 .../src/org/dogtagpki/tps/main/TPSException.java   |  49 ++
 base/common/src/org/dogtagpki/tps/msg/BeginOp.java |   2 +-
 .../src/org/dogtagpki/tps/msg/TPSMessage.java      |   2 +-
 .../src/org/dogtagpki/server/tps/TPSSession.java   |  57 ++-
 .../org/dogtagpki/server/tps/engine/TPSEngine.java |  12 +-
 .../server/tps/processor/TPSFormatProcessor.java   |   9 +-
 .../server/tps/processor/TPSProcessor.java         | 504 ++++++++++++++++++++-
 7 files changed, 583 insertions(+), 52 deletions(-)
 create mode 100644 base/common/src/org/dogtagpki/tps/main/TPSException.java

diff --git a/base/common/src/org/dogtagpki/tps/main/TPSException.java b/base/common/src/org/dogtagpki/tps/main/TPSException.java
new file mode 100644
index 0000000..0ba7895
--- /dev/null
+++ b/base/common/src/org/dogtagpki/tps/main/TPSException.java
@@ -0,0 +1,49 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package org.dogtagpki.tps.main;
+import org.dogtagpki.tps.msg.EndOp.TPSStatus;
+
+import com.netscape.certsrv.base.EBaseException;
+
+
+public class TPSException extends EBaseException {
+
+    private static final long serialVersionUID = -678878301521643436L;
+    private TPSStatus status;
+
+    public TPSException(String msg) {
+        super(msg);
+        status = TPSStatus.STATUS_ERROR_CONTACT_ADMIN;
+    }
+    public TPSException(String msg,TPSStatus theStatus ) {
+
+        super(msg);
+        status = theStatus;
+
+    }
+
+    public TPSStatus getStatus() {
+        return status;
+    }
+
+    public static void main(String[] args) {
+        // TODO Auto-generated method stub
+
+    }
+
+}
diff --git a/base/common/src/org/dogtagpki/tps/msg/BeginOp.java b/base/common/src/org/dogtagpki/tps/msg/BeginOp.java
index 2d2586c..de12660 100644
--- a/base/common/src/org/dogtagpki/tps/msg/BeginOp.java
+++ b/base/common/src/org/dogtagpki/tps/msg/BeginOp.java
@@ -40,7 +40,7 @@ public class BeginOp extends TPSMessage {
         return intToOpType(opTypeInt);
     }
 
-    public Map<String, String> GetExtensions() {
+    public Map<String, String> getExtensions() {
         return extensions;
     }
 
diff --git a/base/common/src/org/dogtagpki/tps/msg/TPSMessage.java b/base/common/src/org/dogtagpki/tps/msg/TPSMessage.java
index f6939d3..f6d238b 100644
--- a/base/common/src/org/dogtagpki/tps/msg/TPSMessage.java
+++ b/base/common/src/org/dogtagpki/tps/msg/TPSMessage.java
@@ -516,7 +516,7 @@ public class TPSMessage {
         String encoded = "s=204&msg_type=2&operation=5&extensions=tokenType%3DuserKey%26clientVersion%3DESC+1%2E0%2E1%26tokenATR%3D3BFF1400FF8131FE458025A00000005657534336353003003B%26statusUpdate%3Dtrue%26extendedLoginRequest%3Dtrue%26";
         BeginOp testMessage = (BeginOp) TPSMessage.createMessage(encoded);
         System.out.println("Encoded msg: " + testMessage.encode());
-        System.out.println("msg Extensions: " + testMessage.GetExtensions());
+        System.out.println("msg Extensions: " + testMessage.getExtensions());
 
     }
 
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSession.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSession.java
index afc1f60..4e338d1 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSession.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/TPSSession.java
@@ -21,12 +21,12 @@ import java.io.IOException;
 
 import org.dogtagpki.server.tps.processor.TPSFormatProcessor;
 import org.dogtagpki.tps.TPSConnection;
+import org.dogtagpki.tps.main.TPSException;
 import org.dogtagpki.tps.msg.BeginOp;
 import org.dogtagpki.tps.msg.EndOp;
 import org.dogtagpki.tps.msg.TPSMessage;
 
 import com.netscape.certsrv.apps.CMS;
-import com.netscape.certsrv.base.EBaseException;
 
 public class TPSSession {
 
@@ -81,7 +81,7 @@ public class TPSSession {
         }
     }
 
-    public void process() throws IOException, EBaseException {
+    public void process() throws IOException {
         EndOp.TPSStatus status = EndOp.TPSStatus.STATUS_ERROR_BAD_STATUS;
         CMS.debug("In TPSSession.process()");
 
@@ -98,29 +98,40 @@ public class TPSSession {
             throw new IOException("Wong first message type read in TPSSession.process!");
         }
 
-        switch (op_type) {
-        case OP_FORMAT:
-
-            TPSFormatProcessor processor = new TPSFormatProcessor();
-            BeginOp beginOp = (BeginOp) firstMsg;
-            status = processor.process(this, beginOp);
-
-        case OP_ENROLL:
-            break;
-        case OP_RENEW:
-            break;
-        case OP_RESET_PIN:
-            break;
-        case OP_UNBLOCK:
-            break;
-        case OP_UNDEFINED:
-            break;
-        default:
-            break;
+        int result = EndOp.RESULT_ERROR;
+        try {
+
+            switch (op_type) {
+            case OP_FORMAT:
+
+                TPSFormatProcessor processor = new TPSFormatProcessor();
+                BeginOp beginOp = (BeginOp) firstMsg;
+                status = processor.process(this, beginOp);
+
+            case OP_ENROLL:
+                break;
+            case OP_RENEW:
+                break;
+            case OP_RESET_PIN:
+                break;
+            case OP_UNBLOCK:
+                break;
+            case OP_UNDEFINED:
+                break;
+            default:
+                break;
 
-        }
+            }
+        } catch (TPSException e) {
+            //Get the status from the exception and return it to the client.
+            CMS.debug("TPSSession.process: Message processing failed: " + e);
+            status = e.getStatus();
+        } catch (IOException e) {
+            CMS.debug("TPSSession.process: IO error happened during processing: " + e);
+           // We get here we are done.
+            throw new IOException(e);
 
-        int result = EndOp.RESULT_ERROR;
+        }
 
         if (status == EndOp.TPSStatus.STATUS_NO_ERROR) {
             result = EndOp.RESULT_GOOD;
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java
index d3bf546..0b22a9d 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/engine/TPSEngine.java
@@ -70,6 +70,10 @@ public class TPSEngine {
     public static final String CFG_RECV_BUF_SIZE = "tps.recvBufSize";
     public static final String CFG_AUTHS_ENABLE="auth.enable";
     public static final String CFG_PROFILE_MAPPING_ORDER="mapping.order";
+    public static final String CFG_ALLOW_UNKNOWN_TOKEN="allowUnkonwnToken";
+    public static final String CFG_ALLOW_NO_APPLET="update.applet.emptyToken.enable";
+    public static final String CFG_APPLET_UPDATE_REQUIRED_VERSION="update.applet.requiredVersion";
+    public static final String CFG_APPLET_DIRECTORY="update.applet.directory";
 
     /* default values */
     public static final String CFG_DEF_CARDMGR_INSTANCE_AID = "A0000000030000";
@@ -85,7 +89,7 @@ public class TPSEngine {
 
     /* misc values */
 
-    public static final String OP_FORMAT_PREFEX = "op.format";
+    public static final String OP_FORMAT_PREFIX = "op.format";
 
 
 
@@ -99,6 +103,12 @@ public class TPSEngine {
         return rc;
     }
 
+    public static boolean isTokenPresent(String cuid) {
+        boolean present = false;
+
+        return present;
+    }
+
     public static void main(String[] args) {
 
     }
diff --git a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSFormatProcessor.java b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSFormatProcessor.java
index 11688a4..5615513 100644
--- a/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSFormatProcessor.java
+++ b/base/tps-tomcat/src/org/dogtagpki/server/tps/processor/TPSFormatProcessor.java
@@ -17,12 +17,14 @@
 // --- END COPYRIGHT BLOCK ---
 package org.dogtagpki.server.tps.processor;
 
+import java.io.IOException;
+
 import org.dogtagpki.server.tps.TPSSession;
+import org.dogtagpki.tps.main.TPSException;
 import org.dogtagpki.tps.msg.BeginOp;
 import org.dogtagpki.tps.msg.EndOp.TPSStatus;
 
 import com.netscape.certsrv.apps.CMS;
-import com.netscape.certsrv.base.EBaseException;
 
 public class TPSFormatProcessor extends TPSProcessor {
 
@@ -30,9 +32,10 @@ public class TPSFormatProcessor extends TPSProcessor {
     }
 
 
-    public TPSStatus process(TPSSession session, BeginOp beginMsg) throws EBaseException {
+    public TPSStatus process(TPSSession theSession, BeginOp beginMsg) throws TPSException, IOException {
         CMS.debug("In TPS_Format_Processor.Process.");
-        return super.format(session,beginMsg);
+        setSession(theSession);
+        return super.format(beginMsg);
     }
 
     public static void main(String[] args) {
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 634cae0..f1569b6 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
@@ -17,14 +17,20 @@
 // --- END COPYRIGHT BLOCK ---
 package org.dogtagpki.server.tps.processor;
 
+import java.io.IOException;
+import java.util.Map;
+
 import org.dogtagpki.server.tps.TPSSession;
+import org.dogtagpki.server.tps.channel.SecureChannel.SecurityLevel;
 import org.dogtagpki.server.tps.engine.TPSEngine;
 import org.dogtagpki.tps.apdu.APDU;
 import org.dogtagpki.tps.apdu.APDUResponse;
 import org.dogtagpki.tps.apdu.GetData;
 import org.dogtagpki.tps.apdu.GetStatus;
+import org.dogtagpki.tps.apdu.GetVersion;
 import org.dogtagpki.tps.apdu.Select;
 import org.dogtagpki.tps.main.TPSBuffer;
+import org.dogtagpki.tps.main.TPSException;
 import org.dogtagpki.tps.main.Util;
 import org.dogtagpki.tps.msg.BeginOp;
 import org.dogtagpki.tps.msg.EndOp.TPSStatus;
@@ -46,9 +52,19 @@ public abstract class TPSProcessor {
 
     private boolean isExternalReg = false;
 
+    private TPSSession session = null;
+
     public TPSProcessor() {
     }
 
+    protected void setSession(TPSSession session) {
+        this.session = session;
+    }
+
+    protected TPSSession getSession() {
+        return session;
+    }
+
     protected TPSBuffer extractTokenNSM(TPSBuffer cplc_data) {
         if (cplc_data == null || cplc_data.size() < CPLC_DATA_SIZE) {
             CMS.debug("TPS_Processor.extractTokenMSN: cplc_data: invalid length.");
@@ -82,7 +98,7 @@ public abstract class TPSProcessor {
 
     }
 
-    protected int selectCardManager(TPSSession session, String prefix, String tokenType) {
+    protected int selectCardManager(String prefix, String tokenType) {
         //ToDo
         return 0;
     }
@@ -104,9 +120,11 @@ public abstract class TPSProcessor {
      * 00 A4 04 00 07
      * 53 4C 42 47 49 4E 41
      *
+     * @throws IOException
+     *
      */
 
-    protected int selectApplet(TPSSession session, byte p1, byte p2, TPSBuffer aid) {
+    protected int selectApplet(byte p1, byte p2, TPSBuffer aid) throws IOException {
 
         CMS.debug("In TPS_Processor.SelectApplet.");
         int rc = RESULT_ERROR;
@@ -119,7 +137,7 @@ public abstract class TPSProcessor {
 
         Select select_apdu = new Select(p1, p2, aid);
 
-        APDUResponse respApdu = handleAPDURequest(session, select_apdu);
+        APDUResponse respApdu = handleAPDURequest(select_apdu);
 
         if (checkTokenPDUResponse(respApdu) == true) {
             rc = RESULT_NO_ERROR;
@@ -129,7 +147,7 @@ public abstract class TPSProcessor {
 
     }
 
-    protected TPSBuffer getStatus(TPSSession session) {
+    protected TPSBuffer getStatus() throws IOException {
 
         CMS.debug("In TPS_Processor.GetStatus.");
 
@@ -137,7 +155,7 @@ public abstract class TPSProcessor {
 
         GetStatus get_status_apdu = new GetStatus();
 
-        APDUResponse respApdu = handleAPDURequest(session, get_status_apdu);
+        APDUResponse respApdu = handleAPDURequest(get_status_apdu);
 
         if (respApdu != null) {
             result = respApdu.getData();
@@ -146,7 +164,7 @@ public abstract class TPSProcessor {
         return result;
     }
 
-    protected APDUResponse handleAPDURequest(TPSSession session, APDU apdu) {
+    protected APDUResponse handleAPDURequest(APDU apdu) throws IOException {
         APDUResponse response = null;
 
         if (session == null || apdu == null) {
@@ -159,7 +177,7 @@ public abstract class TPSProcessor {
             session.write(request_msg);
         } catch (Exception e) {
             CMS.debug("TPS_Processor.HandleAPDURequest failed WriteMsg: " + e.toString());
-            return response;
+            throw new IOException(e);
 
         }
 
@@ -169,7 +187,7 @@ public abstract class TPSProcessor {
             response_msg = (TokenPDUResponse) session.read();
         } catch (Exception e) {
             CMS.debug("TPS_Processor.HandleAPDURequest failed ReadMsg: " + e.toString());
-            return response;
+            throw new IOException(e);
 
         }
 
@@ -185,13 +203,13 @@ public abstract class TPSProcessor {
 
     }
 
-    protected TPSBuffer getCplcData(TPSSession session) {
+    protected TPSBuffer getCplcData() throws IOException {
         CMS.debug("In TPS_Processor.GetData");
         TPSBuffer result = null;
 
         GetData get_data_apdu = new GetData();
 
-        APDUResponse respApdu = handleAPDURequest(session, get_data_apdu);
+        APDUResponse respApdu = handleAPDURequest(get_data_apdu);
 
         result = respApdu.getData();
 
@@ -199,12 +217,65 @@ public abstract class TPSProcessor {
 
     }
 
-    protected TPSStatus format(TPSSession session, BeginOp message) throws EBaseException {
+    protected TPSBuffer getAppletVersion() throws IOException {
+
+        CMS.debug("In TPSProcessor.getAppletVersion");
+        TPSBuffer build_id = null;
+
+        GetVersion get_version_apdu = new GetVersion();
+
+        APDUResponse respApdu = handleAPDURequest(get_version_apdu);
+
+        if (checkTokenPDUResponse(respApdu) != true) {
+            CMS.debug("TPSProcessor.getAppletVersion: Error in getAppletVersion!");
+            return null;
+        }
+
+        TPSBuffer apdu_data = respApdu.getData();
+
+        if (apdu_data.size() != 6) {
+            CMS.debug("TPSProcessor.getAppletVersion: incorrect return data size!");
+            return null;
+        }
+
+        build_id = apdu_data.substr(0, 4);
+
+        CMS.debug("TPSProcessor.getAppletVersion: returning: " + build_id.toHexString());
+
+        return build_id;
+
+    }
+
+    protected String upgradeApplet(String operation, String tokenType, String new_version, SecurityLevel securityLevel,
+            Map<String, String> extensions, int startProgress, int endProgress) throws TPSException {
+
+        String newVersion = null;
+        boolean appletUpgraded = false;
+
+        String directory = getAppletDirectory(operation, tokenType);
+
+        CMS.debug("TPSProcessor.upgradeApplet: applet target directory: " + directory);
+
+        //ToDo actually finish this later.
+        if (appletUpgraded == false) {
+            throw new TPSException("TPSProcessor.upgradeApplet: Error upgrading applet",
+                    TPSStatus.STATUS_ERROR_UPGRADE_APPLET);
+        }
+
+        return newVersion;
+    }
+
+    protected TPSStatus format(BeginOp message) throws TPSException, IOException {
+
+        if (session == null) {
+            throw new TPSException("TPSProcessor.format, no TPSSession object specified!");
+        }
 
         IConfigStore configStore = CMS.getConfigStore();
 
         String CardManagerAID = null;
         String NetKeyAID = null;
+        String appletVersion = null;
 
         String External_Reg_Cfg = TPSEngine.CFG_EXTERNAL_REG + "." + "enable";
         boolean isExternalReg = false;
@@ -218,9 +289,9 @@ public abstract class TPSProcessor {
             this.isExternalReg = configStore.getBoolean(External_Reg_Cfg, false);
             CMS.debug("In TPS_Processor.Format isExternalReg: " + isExternalReg);
         } catch (EBaseException e1) {
-            CMS.debug("In TPS_Processor.Format: Error obtaining config values.");
-            e1.printStackTrace();
-            throw new EBaseException("TPS error getting config values from config store.");
+            CMS.debug("TPS_Processor.Format: Error obtaining mandatory config values.");
+            throw new TPSException("TPS error getting config values from config store.",
+                    TPSStatus.STATUS_ERROR_UPGRADE_APPLET);
         }
 
         TPSStatus ret = TPSStatus.STATUS_NO_ERROR;
@@ -229,14 +300,14 @@ public abstract class TPSProcessor {
 
         int select_rc = RESULT_NO_ERROR;
 
-        select_rc = selectApplet(session, (byte) 0x04, (byte) 0x00, aidBuf);
+        select_rc = selectApplet((byte) 0x04, (byte) 0x00, aidBuf);
 
         if (select_rc == RESULT_ERROR) {
             ret = TPSStatus.STATUS_ERROR_SECURE_CHANNEL;
             return ret;
         }
 
-        TPSBuffer cplc_data = getCplcData(session);
+        TPSBuffer cplc_data = getCplcData();
 
         if (cplc_data == null) {
             ret = TPSStatus.STATUS_ERROR_SECURE_CHANNEL;
@@ -251,7 +322,7 @@ public abstract class TPSProcessor {
 
         if (token_cuid != null) {
             cuid = token_cuid.toHexString();
-            CMS.debug("TPS_Processor.Format: token_cuid str: " + cuid);
+            CMS.debug("TPS_Processor.format: token_cuid str: " + cuid);
         } else {
             ret = TPSStatus.STATUS_ERROR_SECURE_CHANNEL;
             return ret;
@@ -263,7 +334,7 @@ public abstract class TPSProcessor {
 
         if (token_msn != null) {
             msn = token_msn.toHexString();
-            CMS.debug("TPS_Processor.Format: token_msn str: " + msn);
+            CMS.debug("TPS_Processor.format: token_msn str: " + msn);
         }
 
         /**
@@ -274,14 +345,14 @@ public abstract class TPSProcessor {
 
         select_rc = RESULT_NO_ERROR;
 
-        select_rc = selectApplet(session, (byte) 0x04, (byte) 0x00, netkeyAid);
+        select_rc = selectApplet((byte) 0x04, (byte) 0x00, netkeyAid);
 
         if (select_rc == RESULT_ERROR) {
             ret = TPSStatus.STATUS_ERROR_SECURE_CHANNEL;
             return ret;
         }
 
-        TPSBuffer status = getStatus(session);
+        TPSBuffer status = getStatus();
 
         byte major_version = 0x0;
         byte minor_version = 0x0;
@@ -289,16 +360,17 @@ public abstract class TPSProcessor {
         byte app_minor_version = 0x0;
 
         if (status != null) {
-            CMS.debug("TPS_Processor.Format: status: " + status.toHexString());
+            CMS.debug("TPS_Processor.format: status: " + status.toHexString());
             major_version = status.at(0);
             minor_version = status.at(1);
             app_major_version = status.at(2);
             app_minor_version = status.at(3);
-            CMS.debug("TPS_Processor.Format: major_version " + major_version + " minor_version: " + minor_version
+            CMS.debug("TPS_Processor.format: major_version " + major_version + " minor_version: " + minor_version
                     + " app_major_version: " + app_major_version + " app_minor_version: " + app_minor_version);
 
         } else {
             ret = TPSStatus.STATUS_ERROR_SECURE_CHANNEL;
+            return ret;
         }
 
         if (isExternalReg) {
@@ -307,9 +379,166 @@ public abstract class TPSProcessor {
             //ToDo, Do some authentication
         }
 
+        String tokenType = null;
+
+        tokenType = this.getTokenType(TPSEngine.OP_FORMAT_PREFIX, major_version, minor_version, cuid, msn,
+                message.getExtensions());
+
+        CMS.debug("TPS_Processor.format: calculated tokenType: " + tokenType);
+
+        //Now check provided profile
+
+        boolean profileStatusOK = checkProfileStateOK(tokenType);
+
+        if (profileStatusOK == false) {
+            CMS.debug("TPSProcessor.format: profile is disabled for profile: " + tokenType + " cuid: " + cuid);
+            ret = TPSStatus.STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+            return ret;
+        }
+
+        if (TPSEngine.isTokenPresent(cuid)) {
+            //ToDo
+
+        } else {
+
+            boolean allowUnknown = checkAllowUnknownToken(TPSEngine.OP_FORMAT_PREFIX);
+
+            if (allowUnknown == false) {
+                CMS.debug("TPSProcessor.format: Can not allow an unknown token.");
+                ret = TPSStatus.STATUS_ERROR_DISABLED_TOKEN;
+            }
+
+        }
+
+        TPSBuffer build_id = getAppletVersion();
+
+        if (build_id == null) {
+
+            boolean allowNoApplet = checkAllowNoAppletToken(TPSEngine.OP_FORMAT_PREFIX, tokenType);
+
+            if (allowNoApplet == false) {
+                CMS.debug("TPSProcessor.format: tokenw with no applet not allowed, exiting.");
+                ret = TPSStatus.STATUS_ERROR_SECURE_CHANNEL;
+                return ret;
+            }
+
+        } else {
+            appletVersion = Integer.toHexString(app_major_version) + "." + Integer.toHexString(app_minor_version) + "."
+                    + build_id.toHexString();
+        }
+
+        String appletRequiredVersion = checkForAppletUpgrade(TPSEngine.OP_FORMAT_PREFIX, tokenType);
+
+        CMS.debug("TPSProcessor.format: appletVersion found: " + appletVersion + "requiredVersion: "
+                + appletRequiredVersion);
+
+        SecurityLevel secLevel = SecurityLevel.SECURE_MSG_MAC_ENC;
+
+        String newKeyVersion = upgradeApplet(TPSEngine.OP_FORMAT_PREFIX, tokenType, appletRequiredVersion, secLevel,
+                message.getExtensions(),
+                10, 90);
+
+        CMS.debug("TPSProcessor.format: upgraded aplet version: " + newKeyVersion);
         return ret;
     }
 
+    boolean checkProfileStateOK(String tokenType) {
+
+        boolean result = true;
+        IConfigStore configStore = CMS.getConfigStore();
+
+        String profileConfig = "config.Profiles." + tokenType + ".state";
+        String profileState = null;
+
+        try {
+            profileState = configStore.getString(profileConfig);
+        } catch (EBaseException e) {
+
+            CMS.debug("TPSProcessor.checkProfileStateOK:  getting profileState, assuming entry does not exist, continuing! "
+                    + e);
+        }
+
+        if (profileState != null && !profileState.equals("Enabled")) {
+            CMS.debug("TPSProcessor.checkProfileStateOK: profile specifically disabled.");
+            result = false;
+        }
+
+        return result;
+
+    }
+
+    boolean checkAllowNoAppletToken(String operation, String tokenType) {
+        boolean allow = true;
+        IConfigStore configStore = CMS.getConfigStore();
+
+        String noAppletConfig = operation + "." + tokenType + "." + TPSEngine.CFG_ALLOW_NO_APPLET;
+
+        try {
+            allow = configStore.getBoolean(noAppletConfig, false);
+        } catch (EBaseException e) {
+        }
+        CMS.debug("TPSProcessor.checkAllowNoAppletToken: returning: " + allow);
+
+        return allow;
+    }
+
+    protected String checkForAppletUpgrade(String operation, String tokenType) throws TPSException {
+        String requiredVersion = null;
+        IConfigStore configStore = CMS.getConfigStore();
+
+        String appletRequiredConfig = operation + "." + tokenType + "." + TPSEngine.CFG_APPLET_UPDATE_REQUIRED_VERSION;
+
+        try {
+            requiredVersion = configStore.getString(appletRequiredConfig, null);
+        } catch (EBaseException e) {
+        }
+        CMS.debug("TPSProcessor.checkForAppletUpgrade: returning: " + requiredVersion);
+
+        if (requiredVersion == null) {
+            throw new TPSException("TPSProcessor.checkForAppletUpgrade: Can't find applet required Version.",
+                    TPSStatus.STATUS_ERROR_UPGRADE_APPLET);
+        }
+
+        return requiredVersion;
+    }
+
+    protected boolean checkAllowUnknownToken(String operation) {
+        boolean allow = true;
+
+        IConfigStore configStore = CMS.getConfigStore();
+
+        String unknownConfig = operation + "." + TPSEngine.CFG_ALLOW_UNKNOWN_TOKEN;
+
+        try {
+            allow = configStore.getBoolean(unknownConfig, true);
+        } catch (EBaseException e) {
+        }
+
+        CMS.debug("checkAllowUnknownToken: returning: " + allow);
+        return allow;
+
+    }
+
+    protected String getAppletDirectory(String operation, String tokenType) throws TPSException {
+        String directory = null;
+
+        IConfigStore configStore = CMS.getConfigStore();
+
+        String directoryConfig = operation + "." + tokenType + "." + TPSEngine.CFG_APPLET_DIRECTORY;
+
+        try {
+            directory = configStore.getString(directoryConfig, null);
+        } catch (EBaseException e) {
+        }
+
+        if (directory == null) {
+            throw new TPSException("TPSProcessor.getAppletDirectory", TPSStatus.STATUS_ERROR_UPGRADE_APPLET);
+        }
+
+        CMS.debug("getAppletDirectory: returning: " + directory);
+        return directory;
+    }
+
     protected boolean checkTokenPDUResponse(APDUResponse response) {
 
         boolean result = false;
@@ -335,10 +564,239 @@ public abstract class TPSProcessor {
         return isExternalReg;
     }
 
-    public TPSStatus process(TPSSession session, BeginOp beginMsg) throws EBaseException {
+    public TPSStatus process(TPSSession session, BeginOp beginMsg) throws TPSException, IOException {
         return TPSStatus.STATUS_NO_ERROR;
     }
 
+    /* Return calculated token profile type.
+    *
+    */
+    public String getTokenType(String prefix, int major_version, int minor_version, String cuid, String msn,
+            Map<String, String> extensions) throws TPSException {
+        String tokenType = null;
+        String mappingOrder = null;
+
+        IConfigStore configStore = CMS.getConfigStore();
+        String cuid_x = cuid;
+
+        String configName = prefix + "." + TPSEngine.CFG_PROFILE_MAPPING_ORDER;
+
+        try {
+            mappingOrder = configStore.getString(configName, null);
+        } catch (EBaseException e1) {
+            //The whole feature won't work if this is wrong.
+            throw new TPSException(
+                    "TPSProcessor.getTokenType: Token Type configuration incorrect! Mising mapping order!",
+                    TPSStatus.STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND);
+        }
+
+        String[] mappings = mappingOrder.split(",");
+
+        String targetTokenType = null;
+
+        for (int i = 0; i < mappings.length; i++) {
+
+            String mappingId = mappings[i];
+            CMS.debug("TPS_Processor::GetTokenType:  mapping: " + mappingId);
+
+            String mappingConfigName = prefix + ".mapping." + mappingId + ".target.tokenType";
+
+            CMS.debug("TPS_Processor::GetTokenType:  mappingConfigName: " + mappingConfigName);
+
+            try {
+                targetTokenType = configStore.getString(mappingConfigName, null);
+            } catch (EBaseException e) {
+                throw new TPSException(
+                        "TPSProcessor.getTokenType: Token Type configuration incorrect! Invalid or no targetTokenType.",
+                        TPSStatus.STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND);
+            }
+
+            mappingConfigName = prefix + ".mapping." + mappingId + ".filter.tokenType";
+
+            CMS.debug("TPS_Processor::GetTokenType:  mappingConfigName: " + mappingConfigName);
+
+            //For this and remaining cases, it is not automatically an error if we don't get anything back
+            // from the config.
+            try {
+                tokenType = configStore.getString(mappingConfigName, null);
+            } catch (EBaseException e) {
+                tokenType = null;
+            }
+
+            CMS.debug("TPS_Processor::GetTokenType:  targetTokenType: " + targetTokenType);
+
+            if (tokenType != null && tokenType.length() > 0) {
+
+                if (extensions == null) {
+                    continue;
+                }
+
+                String eTokenType = extensions.get("tokenType");
+                if (eTokenType == null) {
+                    continue;
+                }
+
+                if (!eTokenType.equals(tokenType)) {
+                    continue;
+                }
+            }
+
+            mappingConfigName = prefix + ".mapping." + mappingId + ".filter.tokenATR";
+
+            CMS.debug("TPS_Processor::GetTokenType:  mappingConfigName: " + mappingConfigName);
+
+            String tokenATR = null;
+
+            try {
+                tokenATR = configStore.getString(mappingConfigName, null);
+            } catch (EBaseException e) {
+                tokenATR = null;
+            }
+
+            CMS.debug("TPS_Processor::GetTokenType:  tokenATR: " + tokenATR);
+
+            if (tokenATR != null && tokenATR.length() > 0) {
+                if (extensions == null) {
+                    continue;
+                }
+
+                String eTokenATR = extensions.get("tokenATR");
+
+                if (eTokenATR == null) {
+                    continue;
+                }
+
+                if (!eTokenATR.equals(tokenATR)) {
+                    continue;
+                }
+
+            }
+
+            mappingConfigName = prefix + ".mapping." + mappingId + ".filter.tokenCUID.start";
+
+            CMS.debug("TPS_Processor::GetTokenType:  mappingConfigName: " + mappingConfigName);
+
+            String tokenCUIDStart = null;
+
+            try {
+                tokenCUIDStart = configStore.getString(mappingConfigName, null);
+            } catch (EBaseException e) {
+                tokenCUIDStart = null;
+            }
+
+            CMS.debug("TPS_Processor::GetTokenType:  tokenCUIDStart: " + tokenCUIDStart);
+
+            if (tokenCUIDStart != null && tokenCUIDStart.length() > 0) {
+                if (cuid_x == null) {
+                    continue;
+                }
+
+                if (tokenCUIDStart.length() != 20) {
+                    continue;
+                }
+
+                if (cuid_x.compareTo(tokenCUIDStart) < 0) {
+                    continue;
+                }
+
+            }
+
+            mappingConfigName = prefix + ".mapping." + mappingId + ".filter.tokenCUID.end";
+
+            CMS.debug("TPS_Processor::GetTokenType:  mappingConfigName: " + mappingConfigName);
+
+            String tokenCUIDEnd = null;
+            try {
+                tokenCUIDEnd = configStore.getString(mappingConfigName, null);
+            } catch (EBaseException e) {
+                targetTokenType = null;
+            }
+
+            CMS.debug("TPS_Processor::GetTokenType:  tokenCUIDEnd: " + tokenCUIDEnd);
+
+            if (tokenCUIDEnd != null && tokenCUIDEnd.length() > 0) {
+                if (cuid_x == null) {
+                    continue;
+                }
+
+                if (tokenCUIDEnd.length() != 20) {
+                    continue;
+                }
+
+                if (cuid_x.compareTo(tokenCUIDEnd) > 0) {
+                    continue;
+                }
+
+            }
+
+            mappingConfigName = prefix + ".mapping." + mappingId + ".filter.appletMajorVersion";
+
+            CMS.debug("TPS_Processor::GetTokenType:  mappingConfigName: " + mappingConfigName);
+
+            String majorVersion = null;
+            String minorVersion = null;
+
+            try {
+                majorVersion = configStore.getString(mappingConfigName, null);
+            } catch (EBaseException e) {
+                majorVersion = null;
+            }
+
+            CMS.debug("TPS_Processor::GetTokenType:  majorVersion: " + majorVersion);
+            if (majorVersion != null && majorVersion.length() > 0) {
+
+                int major = 0;
+
+                try {
+                    Integer.parseInt(majorVersion);
+                } catch (NumberFormatException e) {
+                }
+
+                if (major != major_version) {
+                    continue;
+                }
+            }
+
+            mappingConfigName = prefix + ".mapping." + mappingId + ".filter.appletMinorVersion";
+
+            CMS.debug("TPS_Processor::GetTokenType:  mappingConfigName: " + mappingConfigName);
+
+            try {
+                minorVersion = configStore.getString(mappingConfigName, null);
+            } catch (EBaseException e) {
+                minorVersion = null;
+            }
+            CMS.debug("TPS_Processor::GetTokenType:  minorVersion " + minorVersion);
+
+            if (minorVersion != null && minorVersion.length() > 0) {
+
+                int minor = 0;
+
+                try {
+                    minor = Integer.parseInt(minorVersion);
+                } catch (NumberFormatException e) {
+                }
+
+                if (minor != minor_version) {
+                    continue;
+                }
+            }
+
+            //if we make it this far, we have a token type
+            CMS.debug("TPS_Processor::GetTokenType: Selected Token type: " + targetTokenType);
+            break;
+        }
+
+        if (targetTokenType == null) {
+            CMS.debug("TPSProcessor.getTokenType: end found: " + targetTokenType);
+            throw new TPSException("TPSProcessor.getTokenType: Can't find token type!",
+                    TPSStatus.STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND);
+        }
+
+        return targetTokenType;
+
+    }
+
     public static void main(String[] args) {
     }
 
-- 
1.8.3.1

