>From b920716a2f534104dc9b42a9b40d80b73c773c45 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Thu, 26 Sep 2013 11:53:23 -0400
Subject: [PATCH 160/160] Modify TKS self tests and execution to use new shared
 secret names

The self tests and TokenServlet are modified to use the new shared secret
names.  A parameter has been added to allow legacy systems to continue running
as-is.  With a new system, the TKS self test will not fail on startup if
no shared secret keys are configured.  It will fail, however, if the keys are
configured, but the ComputeSessionKey operation fails.
---
 .../cms/selftests/tks/TKSKnownSessionKey.java      | 44 +++++++++++++++++++---
 .../com/netscape/cms/servlet/tks/TokenServlet.java | 41 ++++++++++++++++----
 base/tks/shared/conf/CS.cfg.in                     |  1 +
 3 files changed, 73 insertions(+), 13 deletions(-)

diff --git a/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java b/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
index 985b4ef8b78f33a6de26bc0c82e064aeb60b97ad..06a6398c5626af3ecac42f2d5a26e7afe438f9fe 100644
--- a/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
+++ b/base/common/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
@@ -276,12 +276,46 @@ public class TKSKnownSessionKey
      */
     public void runSelfTest(ILogEventListener logger)
             throws ESelfTestException {
-        String logMessage = null;
+        IConfigStore cs = CMS.getConfigStore();
+        String sharedSecretName;
+        try {
+            boolean useNewNames = cs.getBoolean("tks.useNewSharedSecretNames", false);
+            if (useNewNames) {
+                String tpsList = cs.getString("tps.list", "");
+                if (tpsList.isEmpty()) {
+                    CMS.debug("TKSKnownSessionKey: no shared secrets configured, exiting");
+                    return;
+                }
+
+                for (String tpsID : tpsList.split(",")) {
+                    sharedSecretName = cs.getString("tps." + tpsID + ".nickname", "");
+                    if (!sharedSecretName.isEmpty()) {
+                        CMS.debug("TKSKnownSessionKey: testing with key " + sharedSecretName);
+                        generateSessionKey(logger, sharedSecretName);
+                    }
+                }
+            } else {
+                // legacy systems
+                sharedSecretName = cs.getString("tks.tksSharedSymKeyName", "sharedSecret");
+                generateSessionKey(logger, sharedSecretName);
+            }
+        } catch (EBaseException e) {
+            e.printStackTrace();
+            CMS.debug("TKSKnownSessionKey: failed to read config file to set up test");
+            String logMessage = CMS.getLogMessage("SELFTESTS_TKS_FAILED", getSelfTestName(), getSelfTestName());
+            mSelfTestSubsystem.log(logger, logMessage);
+            throw new ESelfTestException(logMessage);
+        }
+        return;
+    }
+
+    private void generateSessionKey(ILogEventListener logger, String sharedSecretName) throws ESelfTestException {
+        String logMessage;
         String keySet = "defKeySet";
 
-        byte[] sessionKey = SessionKey.ComputeSessionKey(mToken, mKeyName,
-                                                          mCardChallenge, mHostChallenge,
-                                                          mKeyInfo, mCUID, mMacKey, mUseSoftToken, keySet, null);
+        byte[] sessionKey = SessionKey.ComputeSessionKey(
+                mToken, mKeyName, mCardChallenge, mHostChallenge, mKeyInfo,
+                mCUID, mMacKey, mUseSoftToken, keySet, sharedSecretName);
 
         // Now we just see if we can successfully generate a session key.
         // For FIPS compliance, the routine now returns a wrapped key, which can't be extracted and compared.
@@ -296,7 +330,5 @@ public class TKSKnownSessionKey
             mSelfTestSubsystem.log(logger, logMessage);
             CMS.debug("TKSKnownSessionKey self test SUCCEEDED");
         }
-
-        return;
     }
 }
diff --git a/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java b/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
index ee6913acc20e93dc2512890e1eb121f5690e4852..766975651cd56a1c032d8ca7d9bd7255a39585dd 100644
--- a/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
+++ b/base/common/src/com/netscape/cms/servlet/tks/TokenServlet.java
@@ -284,10 +284,7 @@ public class TokenServlet extends CMSServlet {
         } catch (EBaseException eee) {
         }
 
-        try {
-            transportKeyName = sconfig.getString("tks.tksSharedSymKeyName", TRANSPORT_KEY_NAME);
-        } catch (EBaseException e) {
-        }
+        transportKeyName = getSharedSecretName(sconfig);
 
         CMS.debug("TokenServlet: ComputeSessionKey(): tksSharedSymKeyName: " + transportKeyName);
 
@@ -447,7 +444,7 @@ public class TokenServlet extends CMSServlet {
                             desKey = kg.generate();*/
 
                         /*
-                         * XXX GenerateSymkey firt generates a 16 byte DES2 key.
+                         * GenerateSymkey firt generates a 16 byte DES2 key.
                          * It then pads it into a 24 byte key with last
                          * 8 bytes copied from the 1st 8 bytes.  Effectively
                          * making it a 24 byte DES2 key.  We need this for
@@ -471,7 +468,7 @@ public class TokenServlet extends CMSServlet {
                         }
 
                         /*
-                         * XXX ECBencrypt actually takes the 24 byte DES2 key
+                         * ECBencrypt actually takes the 24 byte DES2 key
                          * and discard the last 8 bytes before it encrypts.
                          * This is done so that the applet can digest it
                          */
@@ -496,7 +493,7 @@ public class TokenServlet extends CMSServlet {
                         keycheck_s =
                                 com.netscape.cmsutil.util.Utils.SpecialEncode(keycheck);
 
-                        //XXX use DRM transport cert to wrap desKey
+                        //use DRM transport cert to wrap desKey
                         String drmTransNickname = CMS.getConfigStore().getString("tks.drm_transport_cert_nickname", "");
 
                         if ((drmTransNickname == null) || (drmTransNickname == "")) {
@@ -737,6 +734,36 @@ public class TokenServlet extends CMSServlet {
         audit(auditMessage);
     }
 
+    // This method will return the shared secret name.  In new 10.1 subsystems, this
+    // name will be stored in tps.X.nickname.
+    //
+    // Until multiple TKS/TPS connections is fully supported, this method will just
+    // return the first shared secret nickname found, on the assumption that only
+    // one nickname will be configured.  This will have to be changed to return the correct
+    // key based on some parameter in the request in future.
+    //
+    // On legacy systems, this method just returns what was previously returned.
+    private String getSharedSecretName(IConfigStore cs) throws EBaseException {
+        boolean useNewNames = cs.getBoolean("tks.useNewSharedSecretNames", false);
+
+        if (useNewNames) {
+            String tpsList = cs.getString("tps.list", "");
+            if (!tpsList.isEmpty()) {
+                for (String tpsID : tpsList.split(",")) {
+                    String sharedSecretName = cs.getString("tps." + tpsID + ".nickname", "");
+                    if (!sharedSecretName.isEmpty()) {
+                        return sharedSecretName;
+                    }
+                }
+            }
+            CMS.debug("getSharedSecretName: no shared secret has been configured");
+            throw new EBaseException("No shared secret has been configured");
+        }
+
+        // legacy system - return as before
+        return cs.getString("tks.tksSharedSymKeyName", TRANSPORT_KEY_NAME);
+    }
+
     private void processDiversifyKey(HttpServletRequest req,
             HttpServletResponse resp) throws EBaseException {
         byte[] KeySetData, CUID, xCUID;
diff --git a/base/tks/shared/conf/CS.cfg.in b/base/tks/shared/conf/CS.cfg.in
index c0ee3fa0c808947e1bca98a5876fdbd78af94461..9a7ed7f05c3f0d5024198d8e63802ea4cc592952 100644
--- a/base/tks/shared/conf/CS.cfg.in
+++ b/base/tks/shared/conf/CS.cfg.in
@@ -323,6 +323,7 @@ tks.defaultSlot=Internal Key Storage Token
 tks.drm_transport_cert_nickname=
 tks.master_key_prefix=
 tks.tksSharedSymKeyName=sharedSecret
+tks.useNewSharedSecretNames=true
 tks.useDefaultSlot=true
 usrgrp._000=##
 usrgrp._001=## User/Group
-- 
1.8.3.1

