summaryrefslogtreecommitdiffstats
path: root/base/server/cms/src/com/netscape
diff options
context:
space:
mode:
authorChristina Fu <cfu@redhat.com>2014-12-02 14:38:08 -0800
committerChristina Fu <cfu@redhat.com>2014-12-19 11:17:34 -0800
commit4c910296a6c6c8bf74fbdace740680db2f1fecab (patch)
tree1d0d53e8f72c7f219830d387f228003074faf98a /base/server/cms/src/com/netscape
parent00b1c33272900613687448ccab7809ba794679f6 (diff)
downloadpki-4c910296a6c6c8bf74fbdace740680db2f1fecab.tar.gz
pki-4c910296a6c6c8bf74fbdace740680db2f1fecab.tar.xz
pki-4c910296a6c6c8bf74fbdace740680db2f1fecab.zip
Ticket #864 866 (part 1 symkey, common) NIST SP800-108 KDF
- this patch does not include TPS side of changes: (#865 needs to be rewritten in Java)
Diffstat (limited to 'base/server/cms/src/com/netscape')
-rw-r--r--base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java59
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java3
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java665
3 files changed, 624 insertions, 103 deletions
diff --git a/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java b/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
index 06a6398c5..d5e7c11ad 100644
--- a/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
+++ b/base/server/cms/src/com/netscape/cms/selftests/tks/TKSKnownSessionKey.java
@@ -67,6 +67,9 @@ public class TKSKnownSessionKey
private byte[] mCUID = null;
private byte[] mMacKey = null;
private byte[] mSessionKey = null;
+ private byte mNistSP800_108KdfOnKeyVersion = 0; // AC: KDF SPEC CHANGE
+ private boolean mNistSP800_108KdfUseCuidAsKdd = false; // AC: KDF SPEC CHANGE
+ private byte[] mKDD = null; // AC: KDF SPEC CHANGE
/**
* Initializes this subsystem with the configuration store
@@ -101,6 +104,46 @@ public class TKSKnownSessionKey
mMacKey = getConfigByteArray("macKey", 16);
mUseSoftToken = getConfigString("useSoftToken");
+ // AC: KDF SPEC CHANGE
+ // read CUID for the KDD field
+ mKDD = getConfigByteArray("CUID", 10);
+ //
+ //
+ // read self-test configuration item for nistSP800-108KdfOnKeyVersion
+ //
+ // read setting as string
+ String nistSP800_108KdfOnKeyVersion_str = getConfigString("nistSP800-108KdfOnKeyVersion");
+ short nistSP800_108KdfOnKeyVersion_short;
+ // convert setting value (in ASCII-hex) to short
+ try{
+ nistSP800_108KdfOnKeyVersion_short = Short.parseShort(nistSP800_108KdfOnKeyVersion_str,16);
+ if ((nistSP800_108KdfOnKeyVersion_short < 0) || (nistSP800_108KdfOnKeyVersion_short > (short)0x00FF)){
+ throw new Exception("Out of range.");
+ }
+ }catch(Throwable t){
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_MISSING_VALUES",
+ getSelfTestName(), mPrefix + ".nistSP800-108KdfOnKeyVersion"));
+ throw new EMissingSelfTestException("nistSP800-108KdfOnKeyVersion");
+ }
+ // convert to byte (anything higher than 0x7F is represented as negative)
+ mNistSP800_108KdfOnKeyVersion = (byte)nistSP800_108KdfOnKeyVersion_short;
+ //
+ //
+ // read self-test configuration item for nistSP800-108KdfUseCuidAsKdd
+ //
+ // read setting as string
+ String nistSP800_108KdfUseCuidAsKdd_str = getConfigString("nistSP800-108KdfUseCuidAsKdd");
+ // convert setting value to boolean
+ try{
+ mNistSP800_108KdfUseCuidAsKdd = Boolean.parseBoolean(nistSP800_108KdfUseCuidAsKdd_str);
+ }catch(Throwable t){
+ mSelfTestSubsystem.log (mSelfTestSubsystem.getSelfTestLogger(),
+ CMS.getLogMessage("SELFTESTS_MISSING_VALUES",
+ getSelfTestName(), mPrefix + ".nistSP800-108KdfUseCuidAsKdd"));
+ throw new EMissingSelfTestException("nistSP800-108KdfUseCuidAsKdd");
+ }
+
String defKeySetMacKey = null;
tks = CMS.getSubsystem(mTksSubId);
if (tks != null) {
@@ -132,7 +175,12 @@ public class TKSKnownSessionKey
if (mSessionKey == null) {
mSessionKey = SessionKey.ComputeSessionKey(mToken, mKeyName,
mCardChallenge, mHostChallenge,
- mKeyInfo, mCUID, mMacKey, mUseSoftToken, null, null);
+ mKeyInfo,
+ mNistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration self-test value
+ mNistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration self-test value
+ mCUID,
+ mKDD, // AC: KDF SPEC CHANGE - pass in KDD
+ mMacKey, mUseSoftToken, null, null);
if (mSessionKey == null || mSessionKey.length != 16) {
mSelfTestSubsystem.log(mSelfTestSubsystem.getSelfTestLogger(),
CMS.getLogMessage("SELFTESTS_MISSING_VALUES",
@@ -314,8 +362,13 @@ public class TKSKnownSessionKey
String keySet = "defKeySet";
byte[] sessionKey = SessionKey.ComputeSessionKey(
- mToken, mKeyName, mCardChallenge, mHostChallenge, mKeyInfo,
- mCUID, mMacKey, mUseSoftToken, keySet, sharedSecretName);
+ mToken, mKeyName, mCardChallenge, mHostChallenge,
+ mKeyInfo,
+ mNistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration self-test value
+ mNistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration self-test value
+ mCUID,
+ mKDD, // AC: KDF SPEC CHANGE - pass in KDD
+ 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.
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 4a6503897..0b1c6f6e2 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -275,6 +275,8 @@ public class ConfigurationUtils {
HttpResponse httpresponse = httpclient.send(httprequest);
c = httpresponse.getContent();
+ //cfu
+
} catch (ConnectException e) {
CMS.debug("getHttpResponse: " + e.toString());
throw new IOException("The server you tried to contact is not running.");
@@ -4104,6 +4106,7 @@ public class ConfigurationUtils {
CMS.debug("registerUser: response is empty or null.");
throw new IOException("The server " + targetURI + "is not available");
} else {
+ CMS.debug("registerUser: response: " + response);
ByteArrayInputStream bis = new ByteArrayInputStream(response.getBytes());
XMLObject parser = new XMLObject(bis);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java b/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java
index 9b0c2bcf2..2cca81bcf 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/tks/TokenServlet.java
@@ -72,25 +72,25 @@ public class TokenServlet extends CMSServlet {
IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
private final static String LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST =
- "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_3";
+ "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_4"; // AC: KDF SPEC CHANGE: Need to log both KDD and CUID.
private final static String LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS =
- "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS_8";
+ "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS_13"; // AC: KDF SPEC CHANGE: Need to log both KDD and CUID. Also added TKSKeyset, KeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd.
private final static String LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE =
- "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE_9";
+ "LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE_14"; // AC: KDF SPEC CHANGE: Need to log both KDD and CUID. Also added TKSKeyset, KeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd.
private final static String LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST =
- "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_5";
+ "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_6"; // AC: KDF SPEC CHANGE: Need to log both KDD and CUID.
private final static String LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS =
- "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS_6";
+ "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS_12"; // AC: KDF SPEC CHANGE: Need to log both KDD and CUID. Also added TKSKeyset, OldKeyInfo_KeyVersion, NewKeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd.
private final static String LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE =
- "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE_7";
+ "LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE_13"; // AC: KDF SPEC CHANGE: Need to log both KDD and CUID. Also added TKSKeyset, OldKeyInfo_KeyVersion, NewKeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd.
private final static String LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST =
- "LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_4";
+ "LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_5"; // AC: KDF SPEC CHANGE: Need to log both KDD and CUID.
private final static String LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS =
"LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS_7";
@@ -216,9 +216,110 @@ public class TokenServlet extends CMSServlet {
}
+ // AC: KDF SPEC CHANGE - read new setting value from config file
+ // (This value allows configuration of which master keys use the NIST SP800-108 KDF and which use the original KDF for backwards compatibility)
+ // CAREFUL: Result returned may be negative due to java's lack of unsigned types.
+ // Negative values need to be treated as higher key numbers than positive key numbers.
+ private static byte read_setting_nistSP800_108KdfOnKeyVersion(String keySet) throws Exception{
+ String nistSP800_108KdfOnKeyVersion_map = "tks." + keySet + ".nistSP800-108KdfOnKeyVersion";
+ // KDF phase1: default to 00
+ String nistSP800_108KdfOnKeyVersion_value =
+ CMS.getConfigStore().getString(nistSP800_108KdfOnKeyVersion_map, "00" /*null*/);
+ short nistSP800_108KdfOnKeyVersion_short = 0;
+ // if value does not exist in file
+ if (nistSP800_108KdfOnKeyVersion_value == null){
+ // throw
+ // (we want admins to pay attention to this configuration item rather than guessing for them)
+ throw new Exception("Required configuration value \"" + nistSP800_108KdfOnKeyVersion_map + "\" missing from configuration file.");
+ }
+ // convert setting value (in ASCII-hex) to short
+ try{
+ nistSP800_108KdfOnKeyVersion_short = Short.parseShort(nistSP800_108KdfOnKeyVersion_value, 16);
+ if ((nistSP800_108KdfOnKeyVersion_short < 0) || (nistSP800_108KdfOnKeyVersion_short > (short)0x00FF)){
+ throw new Exception("Out of range.");
+ }
+ } catch(Throwable t){
+ throw new Exception("Configuration value \"" + nistSP800_108KdfOnKeyVersion_map + "\" is in incorrect format. " +
+ "Correct format is \"" + nistSP800_108KdfOnKeyVersion_map + "=xx\" where xx is key version specified in ASCII-HEX format.", t);
+ }
+ // convert to byte (anything higher than 0x7F is represented as a negative)
+ byte nistSP800_108KdfOnKeyVersion_byte = (byte)nistSP800_108KdfOnKeyVersion_short;
+ return nistSP800_108KdfOnKeyVersion_byte;
+ }
+
+ // AC: KDF SPEC CHANGE - read new setting value from config file
+ // (This value allows configuration of the NIST SP800-108 KDF:
+ // If "true" we use the CUID parameter within the NIST SP800-108 KDF.
+ // If "false" we use the KDD parameter within the NIST SP800-108 KDF.
+ private static boolean read_setting_nistSP800_108KdfUseCuidAsKdd(String keySet) throws Exception{
+ String setting_map = "tks." + keySet + ".nistSP800-108KdfUseCuidAsKdd";
+ // KDF phase1: default to "false"
+ String setting_str =
+ CMS.getConfigStore().getString(setting_map, "false" /*null*/);
+ boolean setting_boolean = false;
+ // if value does not exist in file
+ if (setting_str == null){
+ // throw
+ // (we want admins to pay attention to this configuration item rather than guessing for them)
+ throw new Exception("Required configuration value \"" + setting_map + "\" missing from configuration file.");
+ }
+ // convert setting value to boolean
+ try{
+ setting_boolean = Boolean.parseBoolean(setting_str);
+ }catch(Throwable t){
+ throw new Exception("Configuration value \"" + setting_map + "\" is in incorrect format. Should be either \"true\" or \"false\".", t);
+ }
+ return setting_boolean;
+ }
+
+ // AC: KDF SPEC CHANGE - Audit logging helper functions.
+ // Converts a byte array to an ASCII-hex string.
+ // We implemented this ourselves rather than using this.pp.toHexArray() because
+ // the team preferred CUID and KDD strings to be without ":" separators every byte.
+ final char[] bytesToHex_hexArray = "0123456789ABCDEF".toCharArray();
+ private String bytesToHex(byte[] bytes){
+ char[] hexChars = new char[bytes.length * 2];
+ for (int i = 0; i < bytes.length; i++){
+ int thisChar = bytes[i] & 0x000000FF;
+ hexChars[i * 2] = bytesToHex_hexArray[thisChar >>> 4]; // div 16
+ hexChars[i*2 + 1] = bytesToHex_hexArray[thisChar & 0x0F];
+ }
+ return new String(hexChars);
+ }
+
+ // AC: KDF SPEC CHANGE - Audit logging helper functions.
+ // Safely converts a keyInfo byte array to a Key version hex string in the format: 0xa
+ // Since key version is always the first byte, this function returns the unsigned hex string representation of parameter[0].
+ // Returns "null" if parameter is null.
+ // Returns "invalid" if parameter.length < 1
+ private String log_string_from_keyInfo(byte[] xkeyInfo){
+ return (xkeyInfo == null) ? "null" : (xkeyInfo.length < 1 ? "invalid" : "0x" + Integer.toHexString((int)(xkeyInfo[0]) & 0x000000FF) );
+ }
+
+ // AC: KDF SPEC CHANGE - Audit logging helper functions.
+ // Safely converts a byte array containing specialDecoded information to an ASCII-hex string.
+ // Parameters:
+ // specialDecoded - byte array containing data. May be null.
+ // Returns:
+ // if specialDecoded is blank, returns "null"
+ // if specialDecoded != null, returns <ASCII-HEX string representation of specialDecoded>
+ private String log_string_from_specialDecoded_byte_array(byte[] specialDecoded){
+ if (specialDecoded == null){
+ return "null";
+ }else{
+ return bytesToHex(specialDecoded);
+ }
+ }
+
+
private void processComputeSessionKey(HttpServletRequest req,
HttpServletResponse resp) throws EBaseException {
- byte[] card_challenge, host_challenge, keyInfo, xCUID, CUID, session_key;
+ byte[] card_challenge ,host_challenge,keyInfo, xCUID, session_key, xKDD; // AC: KDF SPEC CHANGE: removed duplicative 'CUID' variable and added xKDD
+
+ // AC: KDF SPEC CHANGE - new config file values (needed for symkey)
+ byte nistSP800_108KdfOnKeyVersion = (byte)0xff;
+ boolean nistSP800_108KdfUseCuidAsKdd = false;
+
byte[] card_crypto, host_cryptogram, input_card_crypto;
byte[] xcard_challenge, xhost_challenge;
byte[] enc_session_key, xkeyInfo;
@@ -228,6 +329,15 @@ public class TokenServlet extends CMSServlet {
String transportKeyName = "";
String rCUID = req.getParameter(IRemoteRequest.TOKEN_CUID);
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ String rKDD = req.getParameter("KDD");
+ if ((rKDD == null) || (rKDD.length() == 0)) {
+ // KDF phase1: default to rCUID if not present
+ CMS.debug("TokenServlet: KDD not supplied, set to CUID before TPS change");
+ rKDD = rCUID;
+ }
+
String keySet = req.getParameter(IRemoteRequest.TOKEN_KEYSET);
if (keySet == null || keySet.equals("")) {
keySet = "defKeySet";
@@ -243,6 +353,10 @@ public class TokenServlet extends CMSServlet {
IConfigStore sconfig = CMS.getConfigStore();
boolean isCryptoValidate = true;
boolean missingParam = false;
+
+ // AC: KDF SPEC CHANGE - flag for if there is an error reading our new setting
+ Exception missingSetting_exception = null;
+
session_key = null;
card_crypto = null;
host_cryptogram = null;
@@ -257,9 +371,11 @@ public class TokenServlet extends CMSServlet {
(String) sContext.get(SessionContext.USER_ID);
}
+ // AC: KDF SPEC CHANGE: Need to log both KDD and CUID
auditMessage = CMS.getLogMessage(
LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST,
rCUID,
+ rKDD, // AC: KDF SPEC CHANGE - Log both CUID and KDD.
ILogger.SUCCESS,
agentId);
@@ -299,6 +415,13 @@ public class TokenServlet extends CMSServlet {
badParams += " CUID,";
missingParam = true;
}
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ if ((rKDD == null) || (rKDD.length() == 0)) {
+ CMS.debug("TokenServlet: ComputeSessionKey(): missing request parameter: KDD");
+ badParams += " KDD,";
+ missingParam = true;
+ }
if ((rcard_challenge == null) || (rcard_challenge.equals(""))) {
badParams += " card_challenge,";
@@ -322,6 +445,11 @@ public class TokenServlet extends CMSServlet {
String keyNickName = null;
boolean sameCardCrypto = true;
+ // AC: KDF SPEC CHANGE
+ xCUID = null; // avoid errors about non-initialization
+ xKDD = null; // avoid errors about non-initialization
+ xkeyInfo = null; // avoid errors about non-initialization
+
if (!missingParam) {
xCUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
@@ -330,6 +458,15 @@ public class TokenServlet extends CMSServlet {
CMS.debug("TokenServlet: Invalid CUID length");
missingParam = true;
}
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ xKDD = com.netscape.cmsutil.util.Utils.SpecialDecode(rKDD);
+ if (xKDD == null || xKDD.length != 10) {
+ badParams += " KDD length,";
+ CMS.debug("TokenServlet: Invalid KDD length");
+ missingParam = true;
+ }
+
xkeyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
if (xkeyInfo == null || xkeyInfo.length != 2) {
badParams += " KeyInfo length,";
@@ -353,7 +490,9 @@ public class TokenServlet extends CMSServlet {
}
- CUID = null;
+ // AC: KDF SPEC CHANGE - Remove duplicative variable.
+ // CUID = null;
+
if (!missingParam) {
card_challenge =
com.netscape.cmsutil.util.Utils.SpecialDecode(rcard_challenge);
@@ -361,7 +500,33 @@ public class TokenServlet extends CMSServlet {
host_challenge = com.netscape.cmsutil.util.Utils.SpecialDecode(rhost_challenge);
keyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
- CUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+ // CUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+ // AC: KDF SPEC CHANGE: Removed duplicative variable/processing.
+
+ // AC: KDF SPEC CHANGE - read new config file values (needed for symkey)
+ try{
+ nistSP800_108KdfOnKeyVersion = TokenServlet.read_setting_nistSP800_108KdfOnKeyVersion(keySet);
+ nistSP800_108KdfUseCuidAsKdd = TokenServlet.read_setting_nistSP800_108KdfUseCuidAsKdd(keySet);
+
+ // log settings read in to debug log along with xkeyInfo
+ CMS.debug("TokenServlet: ComputeSessionKey(): xkeyInfo[0] = 0x"
+ + Integer.toHexString((int)(xkeyInfo[0]) & 0x0000000FF)
+ + ", xkeyInfo[1] = 0x"
+ + Integer.toHexString((int)(xkeyInfo[1]) & 0x0000000FF)
+ );
+ CMS.debug("TokenServlet: ComputeSessionKey(): Nist SP800-108 KDF will be used for key versions >= 0x"
+ + Integer.toHexString((int)(nistSP800_108KdfOnKeyVersion) & 0x0000000FF)
+ );
+ if (nistSP800_108KdfUseCuidAsKdd == true){
+ CMS.debug("TokenServlet: ComputeSessionKey(): Nist SP800-108 KDF (if used) will use CUID instead of KDD.");
+ }else{
+ CMS.debug("TokenServlet: ComputeSessionKey(): Nist SP800-108 KDF (if used) will use KDD.");
+ }
+ // conform to the set-an-error-flag mentality
+ }catch(Exception e){
+ missingSetting_exception = e;
+ CMS.debug("TokenServlet: ComputeSessionKey(): Exception reading Nist SP800-108 KDF config values: " + e.toString());
+ }
String keyInfoMap = "tks." + keySet + ".mk_mappings." + rKeyInfo; //#xx#xx
String mappingValue = CMS.getConfigStore().getString(keyInfoMap, null);
@@ -377,7 +542,9 @@ public class TokenServlet extends CMSServlet {
keyNickName = st.nextToken();
}
- if (selectedToken != null && keyNickName != null) {
+ if (selectedToken != null && keyNickName != null
+ // AC: KDF SPEC CHANGE - check for error flag
+ && missingSetting_exception == null) {
try {
@@ -388,7 +555,12 @@ public class TokenServlet extends CMSServlet {
+ selectedToken + " keyNickName=" + keyNickName);
session_key = SessionKey.ComputeSessionKey(
selectedToken, keyNickName, card_challenge,
- host_challenge, keyInfo, CUID, macKeyArray, useSoftToken_s, keySet, transportKeyName);
+ host_challenge,keyInfo,
+ nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
+ nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
+ xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
+ xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
+ macKeyArray, useSoftToken_s, keySet, transportKeyName );
if (session_key == null) {
CMS.debug("TokenServlet:Tried ComputeSessionKey, got NULL ");
@@ -401,7 +573,12 @@ public class TokenServlet extends CMSServlet {
+ keySet + ".auth_key"));
enc_session_key = SessionKey.ComputeEncSessionKey(
selectedToken, keyNickName, card_challenge,
- host_challenge, keyInfo, CUID, encKeyArray, useSoftToken_s, keySet);
+ host_challenge,keyInfo,
+ nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
+ nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
+ xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
+ xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
+ encKeyArray, useSoftToken_s, keySet);
if (enc_session_key == null) {
CMS.debug("TokenServlet:Tried ComputeEncSessionKey, got NULL ");
@@ -426,7 +603,12 @@ public class TokenServlet extends CMSServlet {
kek_key = SessionKey.ComputeKekKey(
selectedToken, keyNickName, card_challenge,
- host_challenge, keyInfo, CUID, kekKeyArray, useSoftToken_s, keySet);
+ host_challenge,keyInfo,
+ nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
+ nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
+ xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
+ xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
+ kekKeyArray, useSoftToken_s,keySet);
CMS.debug("TokenServlet: called ComputeKekKey");
@@ -462,10 +644,19 @@ public class TokenServlet extends CMSServlet {
CMS.debug("TokenServlet: key encryption key generated on " + selectedToken);
desKey = SessionKey.GenerateSymkey(selectedToken);
}
- if (desKey != null)
- CMS.debug("TokenServlet: key encryption key generated for " + rCUID);
- else {
- CMS.debug("TokenServlet: key encryption key generation failed for " + rCUID);
+ if (desKey != null) {
+ // AC: KDF SPEC CHANGE - Output using CUID and KDD
+ CMS.debug("TokenServlet: key encryption key generated for CUID=" +
+ trim(pp.toHexString(xCUID)) +
+ ", KDD=" +
+ trim(pp.toHexString(xKDD)));
+ } else {
+ // AC: KDF SPEC CHANGE - Output using CUID and KDD
+ CMS.debug("TokenServlet: key encryption key generation failed for CUID=" +
+ trim(pp.toHexString(xCUID)) +
+ ", KDD=" +
+ trim(pp.toHexString(xKDD)));
+
throw new Exception("can't generate key encryption key");
}
@@ -538,7 +729,12 @@ public class TokenServlet extends CMSServlet {
+ keySet + ".auth_key"));
host_cryptogram = SessionKey.ComputeCryptogram(
selectedToken, keyNickName, card_challenge,
- host_challenge, keyInfo, CUID, 0, authKeyArray, useSoftToken_s, keySet);
+ host_challenge,keyInfo,
+ nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
+ nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
+ xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
+ xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
+ 0, authKeyArray, useSoftToken_s, keySet);
if (host_cryptogram == null) {
CMS.debug("TokenServlet:Tried ComputeCryptogram, got NULL ");
@@ -547,7 +743,13 @@ public class TokenServlet extends CMSServlet {
}
card_crypto = SessionKey.ComputeCryptogram(
selectedToken, keyNickName, card_challenge,
- host_challenge, keyInfo, CUID, 1, authKeyArray, useSoftToken_s, keySet);
+ host_challenge,keyInfo,
+ nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
+ nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
+ xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
+ xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
+ 1, authKeyArray, useSoftToken_s, keySet);
+
if (card_crypto == null) {
CMS.debug("TokenServlet:Tried ComputeCryptogram, got NULL ");
@@ -575,10 +777,13 @@ public class TokenServlet extends CMSServlet {
}
}
+ // AC: KDF SPEC CHANGE - print both KDD and CUID
CMS.getLogger().log(ILogger.EV_AUDIT,
ILogger.S_TKS,
ILogger.LL_INFO, "processComputeSessionKey for CUID=" +
- trim(pp.toHexString(CUID)));
+ trim(pp.toHexString(xCUID)) +
+ ", KDD=" +
+ trim(pp.toHexString(xKDD)));
} catch (Exception e) {
CMS.debug(e);
CMS.debug("TokenServlet Computing Session Key: " + e.toString());
@@ -625,18 +830,35 @@ public class TokenServlet extends CMSServlet {
cryptogram =
com.netscape.cmsutil.util.Utils.SpecialEncode(host_cryptogram);
} else {
- status = "2";
+ // AC: Bugfix: Don't override status's value if an error was already flagged
+ if (status.equals("0") == true){
+ status = "2";
+ }
}
if (selectedToken == null || keyNickName == null) {
- status = "4";
+ // AC: Bugfix: Don't override status's value if an error was already flagged
+ if (status.equals("0") == true){
+ status = "4";
+ }
}
if (!sameCardCrypto) {
- status = "3";
+ // AC: Bugfix: Don't override status's value if an error was already flagged
+ if (status.equals("0") == true){
+ // AC: Bugfix: Don't mis-represent host cryptogram mismatch errors as TPS parameter issues
+ status = "5";
+ }
}
+ // AC: KDF SPEC CHANGE - check for settings file issue (flag)
+ if (missingSetting_exception != null){
+ // AC: Intentionally override previous errors if config file settings were missing.
+ status = "6";
+ }
+
if (missingParam) {
+ // AC: Intentionally override previous errors if parameters were missing.
status = "3";
}
@@ -650,10 +872,20 @@ public class TokenServlet extends CMSServlet {
errorMsg = "Problem creating host_cryptogram.";
}
+ // AC: Bugfix: Don't mis-represent card cryptogram mismatch errors as TPS parameter issues
+ if (status.equals("5")) {
+ errorMsg = "Card cryptogram mismatch. Token likely has incorrect keys.";
+ }
+
if (status.equals("4")) {
errorMsg = "Problem obtaining token information.";
}
+ // AC: KDF SPEC CHANGE - handle missing configuration item
+ if (status.equals("6")) {
+ errorMsg = "Problem reading required configuration value.";
+ }
+
if (status.equals("3")) {
if (badParams.endsWith(",")) {
badParams = badParams.substring(0, badParams.length() - 1);
@@ -706,31 +938,45 @@ public class TokenServlet extends CMSServlet {
}
if (status.equals("0")) {
-
- auditMessage = CMS.getLogMessage(
- LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS,
- rCUID,
- ILogger.SUCCESS,
- status,
- agentId,
- isCryptoValidate ? "true" : "false",
- serversideKeygen ? "true" : "false",
- selectedToken,
- keyNickName);
-
+ // AC: KDF SPEC CHANGE - Log both CUID and KDD.
+ // Also added TKSKeyset, KeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd
+ // Finally, log CUID and KDD in ASCII-HEX format, as long as special-decoded version is available.
+ String[] logParams = { log_string_from_specialDecoded_byte_array(xCUID), // CUID_decoded
+ log_string_from_specialDecoded_byte_array(xKDD), // KDD_decoded
+ ILogger.SUCCESS, // Outcome
+ status, // status
+ agentId, // AgentID
+ isCryptoValidate? "true":"false", // IsCryptoValidate
+ serversideKeygen? "true":"false", // IsServerSideKeygen
+ selectedToken, // SelectedToken
+ keyNickName, // KeyNickName
+ keySet, // TKSKeyset
+ log_string_from_keyInfo(xkeyInfo), // KeyInfo_KeyVersion
+ "0x" + Integer.toHexString((int)nistSP800_108KdfOnKeyVersion & 0x000000FF), // NistSP800_108KdfOnKeyVersion
+ Boolean.toString(nistSP800_108KdfUseCuidAsKdd) // NistSP800_108KdfUseCuidAsKdd
+ };
+ auditMessage = CMS.getLogMessage(LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_SUCCESS, logParams);
} else {
+ // AC: KDF SPEC CHANGE - Log both CUID and KDD
+ // Also added TKSKeyset, KeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd
+ // Finally, log CUID and KDD in ASCII-HEX format, as long as special-decoded version is available.
+ String[] logParams = { log_string_from_specialDecoded_byte_array(xCUID), // CUID_decoded
+ log_string_from_specialDecoded_byte_array(xKDD), // KDD_decoded
+ ILogger.FAILURE, // Outcome
+ status, // status
+ agentId, // AgentID
+ isCryptoValidate? "true":"false", // IsCryptoValidate
+ serversideKeygen? "true":"false", // IsServerSideKeygen
+ selectedToken, // SelectedToken
+ keyNickName, // KeyNickName
+ keySet, // TKSKeyset
+ log_string_from_keyInfo(xkeyInfo), // KeyInfo_KeyVersion
+ "0x" + Integer.toHexString((int)nistSP800_108KdfOnKeyVersion & 0x000000FF), // NistSP800_108KdfOnKeyVersion
+ Boolean.toString(nistSP800_108KdfUseCuidAsKdd), // NistSP800_108KdfUseCuidAsKdd
+ errorMsg // Error
+ };
+ auditMessage = CMS.getLogMessage(LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE, logParams);
- auditMessage = CMS.getLogMessage(
- LOGGING_SIGNED_AUDIT_COMPUTE_SESSION_KEY_REQUEST_PROCESSED_FAILURE,
- rCUID,
- ILogger.FAILURE,
- status,
- agentId,
- isCryptoValidate ? "true" : "false",
- serversideKeygen ? "true" : "false",
- selectedToken,
- keyNickName,
- errorMsg);
}
audit(auditMessage);
@@ -768,8 +1014,22 @@ public class TokenServlet extends CMSServlet {
private void processDiversifyKey(HttpServletRequest req,
HttpServletResponse resp) throws EBaseException {
- byte[] KeySetData, CUID, xCUID;
- byte[] xkeyInfo, xnewkeyInfo;
+ byte[] KeySetData,KeysValues,xCUID,xKDD; // AC: KDF SPEC CHANGE: removed duplicative 'CUID' variable and added xKDD
+
+ // AC: BUGFIX: Record the actual parameters to DiversifyKey in the audit log.
+ String oldKeyNickName = null;
+ String newKeyNickName = null;
+
+ // AC: KDF SPEC CHANGE - new config file values (needed for symkey)
+ byte nistSP800_108KdfOnKeyVersion = (byte)0xff;
+ boolean nistSP800_108KdfUseCuidAsKdd = false;
+
+ // AC: BUGFIX for key versions higher than 09: We need to initialize these variables in order for the compiler not to complain when we pass them to DiversifyKey.
+ byte[] xkeyInfo = null,xnewkeyInfo = null;
+
+ // AC: KDF SPEC CHANGE - flag for if there is an error reading our new setting
+ Exception missingSetting_exception = null;
+
boolean missingParam = false;
String errorMsg = "";
String badParams = "";
@@ -779,6 +1039,15 @@ public class TokenServlet extends CMSServlet {
String newMasterKeyName = req.getParameter(IRemoteRequest.TOKEN_NEW_KEYINFO);
String oldMasterKeyName = req.getParameter(IRemoteRequest.TOKEN_KEYINFO);
String rCUID = req.getParameter(IRemoteRequest.TOKEN_CUID);
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ String rKDD = req.getParameter("KDD");
+ if ((rKDD == null) || (rKDD.length() == 0)) {
+ // temporarily make it friendly before TPS change
+ CMS.debug("TokenServlet: KDD not supplied, set to CUID before TPS change");
+ rKDD = rCUID;
+ }
+
String auditMessage = "";
String keySet = req.getParameter(IRemoteRequest.TOKEN_KEYSET);
@@ -795,9 +1064,11 @@ public class TokenServlet extends CMSServlet {
(String) sContext.get(SessionContext.USER_ID);
}
+ // AC: KDF SPEC CHANGE: Need to log both KDD and CUID
auditMessage = CMS.getLogMessage(
LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST,
rCUID,
+ rKDD, // AC: KDF SPEC CHANGE - Log both CUID and KDD.
ILogger.SUCCESS,
agentId,
oldMasterKeyName,
@@ -810,6 +1081,14 @@ public class TokenServlet extends CMSServlet {
CMS.debug("TokenServlet: processDiversifyKey(): missing request parameter: CUID");
missingParam = true;
}
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ if ((rKDD == null) || (rKDD.length() == 0)) {
+ CMS.debug("TokenServlet: processDiversifyKey(): missing request parameter: KDD");
+ badParams += " KDD,";
+ missingParam = true;
+ }
+
if ((rnewKeyInfo == null) || (rnewKeyInfo.equals(""))) {
badParams += " newKeyInfo,";
CMS.debug("TokenServlet: processDiversifyKey(): missing request parameter: newKeyInfo");
@@ -821,6 +1100,12 @@ public class TokenServlet extends CMSServlet {
missingParam = true;
}
+ // AC: KDF SPEC CHANGE
+ xCUID = null; // avoid errors about non-initialization
+ xKDD = null; // avoid errors about non-initialization
+ xkeyInfo = null; // avoid errors about non-initialization
+ xnewkeyInfo = null; // avoid errors about non-initialization
+
if (!missingParam) {
xkeyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(oldMasterKeyName);
if (xkeyInfo == null || xkeyInfo.length != 2) {
@@ -847,9 +1132,46 @@ public class TokenServlet extends CMSServlet {
CMS.debug("TokenServlet: Invalid CUID length");
missingParam = true;
}
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ xKDD = com.netscape.cmsutil.util.Utils.SpecialDecode(rKDD);
+ if (xKDD == null || xKDD.length != 10) {
+ badParams += " KDD length,";
+ CMS.debug("TokenServlet: Invalid KDD length");
+ missingParam = true;
+ }
}
if (!missingParam) {
- CUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
+ // CUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID); // AC: KDF SPEC CHANGE: Removed duplicative variable/processing.
+
+ // AC: KDF SPEC CHANGE - read new config file values (needed for symkey)
+ try{
+ nistSP800_108KdfOnKeyVersion = TokenServlet.read_setting_nistSP800_108KdfOnKeyVersion(keySet);
+ nistSP800_108KdfUseCuidAsKdd = TokenServlet.read_setting_nistSP800_108KdfUseCuidAsKdd(keySet);
+
+ // log settings read in to debug log along with xkeyInfo and xnewkeyInfo
+ CMS.debug("TokenServlet: processDiversifyKey(): xkeyInfo[0] (old) = 0x"
+ + Integer.toHexString((int)(xkeyInfo[0]) & 0x0000000FF)
+ + ", xkeyInfo[1] (old) = 0x"
+ + Integer.toHexString((int)(xkeyInfo[1]) & 0x0000000FF)
+ + ", xnewkeyInfo[0] = 0x"
+ + Integer.toHexString((int)(xnewkeyInfo[0]) & 0x000000FF)
+ + ", xnewkeyInfo[1] = 0x"
+ + Integer.toHexString((int)(xnewkeyInfo[1]) & 0x000000FF)
+ );
+ CMS.debug("TokenServlet: processDiversifyKey(): Nist SP800-108 KDF will be used for key versions >= 0x"
+ + Integer.toHexString((int)(nistSP800_108KdfOnKeyVersion) & 0x0000000FF)
+ );
+ if (nistSP800_108KdfUseCuidAsKdd == true){
+ CMS.debug("TokenServlet: processDiversifyKey(): Nist SP800-108 KDF (if used) will use CUID instead of KDD.");
+ }else{
+ CMS.debug("TokenServlet: processDiversifyKey(): Nist SP800-108 KDF (if used) will use KDD.");
+ }
+ // conform to the set-an-error-flag mentality
+ }catch(Exception e){
+ missingSetting_exception = e;
+ CMS.debug("TokenServlet: processDiversifyKey(): Exception reading Nist SP800-108 KDF config values: " + e.toString());
+ }
if (mKeyNickName != null)
oldMasterKeyName = mKeyNickName;
@@ -859,7 +1181,6 @@ public class TokenServlet extends CMSServlet {
String oldKeyInfoMap = "tks." + keySet + ".mk_mappings." + req.getParameter(IRemoteRequest.TOKEN_KEYINFO); //#xx#xx
String oldMappingValue = CMS.getConfigStore().getString(oldKeyInfoMap, null);
String oldSelectedToken = null;
- String oldKeyNickName = null;
if (oldMappingValue == null) {
oldSelectedToken = CMS.getConfigStore().getString("tks.defaultSlot", "internal");
oldKeyNickName = req.getParameter(IRemoteRequest.TOKEN_KEYINFO);
@@ -872,7 +1193,6 @@ public class TokenServlet extends CMSServlet {
String newKeyInfoMap = "tks.mk_mappings." + rnewKeyInfo; //#xx#xx
String newMappingValue = CMS.getConfigStore().getString(newKeyInfoMap, null);
String newSelectedToken = null;
- String newKeyNickName = null;
if (newMappingValue == null) {
newSelectedToken = CMS.getConfigStore().getString("tks.defaultSlot", "internal");
newKeyNickName = rnewKeyInfo;
@@ -888,10 +1208,20 @@ public class TokenServlet extends CMSServlet {
newKeyNickName);
byte kekKeyArray[] =
- com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
+ com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
+
+ // AC: KDF SPEC CHANGE - check for error reading settings
+ if (missingSetting_exception == null){
KeySetData = SessionKey.DiversifyKey(oldSelectedToken,
newSelectedToken, oldKeyNickName,
- newKeyNickName, rnewKeyInfo, CUID, kekKeyArray, useSoftToken_s, keySet);
+ newKeyNickName,
+ xkeyInfo, // AC: KDF SPEC CHANGE - pass in old key info so symkey can make decision about which KDF version to use
+ xnewkeyInfo, // AC: BUGFIX for key versions higher than 09: We need to specialDecode keyInfo parameters before sending them into symkey! This means the parameters must be byte[]
+ nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
+ nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
+ xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
+ xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
+ kekKeyArray, useSoftToken_s, keySet);
if (KeySetData == null || KeySetData.length <= 1) {
CMS.getLogger().log(ILogger.EV_AUDIT,
@@ -901,11 +1231,18 @@ public class TokenServlet extends CMSServlet {
CMS.getLogger().log(ILogger.EV_AUDIT,
ILogger.S_TKS,
- ILogger.LL_INFO, "process DiversifyKey for CUID =" + trim(pp.toHexString(CUID))
+ ILogger.LL_INFO,
+ "process DiversifyKey for CUID=" +
+ trim(pp.toHexString(xCUID)) + // AC: KDF SPEC CHANGE: Log both CUID and KDD
+ ", KDD=" +
+ trim(pp.toHexString(xKDD))
+ ";from oldMasterKeyName=" + oldSelectedToken + ":" + oldKeyNickName
+ ";to newMasterKeyName=" + newSelectedToken + ":" + newKeyNickName);
resp.setContentType("text/html");
+
+ } // AC: KDF SPEC CHANGE - endif no error reading settings from settings file
+
} // ! missingParam
//CMS.debug("TokenServlet:processDiversifyKey " +outputString);
@@ -918,6 +1255,11 @@ public class TokenServlet extends CMSServlet {
value = IRemoteRequest.RESPONSE_STATUS+"=0&" + IRemoteRequest.TKS_RESPONSE_KeySetData+"=" +
com.netscape.cmsutil.util.Utils.SpecialEncode(KeySetData);
CMS.debug("TokenServlet:process DiversifyKey.encode " + value);
+ // AC: KDF SPEC CHANGE - check for settings file issue (flag)
+ } else if (missingSetting_exception != null){
+ status = "6";
+ errorMsg = "Problem reading required configuration value.";
+ value = "status=" + status;
} else if (missingParam) {
status = "3";
if (badParams.endsWith(",")) {
@@ -945,26 +1287,48 @@ public class TokenServlet extends CMSServlet {
if (status.equals("0")) {
- auditMessage = CMS.getLogMessage(
- LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS,
- rCUID,
- ILogger.SUCCESS,
- status,
- agentId,
- oldMasterKeyName,
- newMasterKeyName);
-
+ // AC: KDF SPEC CHANGE - Log both CUID and KDD
+ // Also added TKSKeyset, OldKeyInfo_KeyVersion, NewKeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd
+ // Finally, log CUID and KDD in ASCII-HEX format, as long as special-decoded version is available.
+ String[] logParams = { log_string_from_specialDecoded_byte_array(xCUID), // CUID_decoded
+ log_string_from_specialDecoded_byte_array(xKDD), // KDD_decoded
+ ILogger.SUCCESS, // Outcome
+ status, // status
+ agentId, // AgentID
+
+ // AC: BUGFIX: Record the actual parameters to DiversifyKey in the audit log.
+ oldKeyNickName, // oldMasterKeyName
+ newKeyNickName, // newMasterKeyName
+
+ keySet, // TKSKeyset
+ log_string_from_keyInfo(xkeyInfo), // OldKeyInfo_KeyVersion
+ log_string_from_keyInfo(xnewkeyInfo), // NewKeyInfo_KeyVersion
+ "0x" + Integer.toHexString((int)nistSP800_108KdfOnKeyVersion & 0x000000FF), // NistSP800_108KdfOnKeyVersion
+ Boolean.toString(nistSP800_108KdfUseCuidAsKdd) // NistSP800_108KdfUseCuidAsKdd
+ };
+ auditMessage = CMS.getLogMessage(LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_SUCCESS, logParams);
} else {
-
- auditMessage = CMS.getLogMessage(
- LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE,
- rCUID,
- ILogger.FAILURE,
- status,
- agentId,
- oldMasterKeyName,
- newMasterKeyName,
- errorMsg);
+ // AC: KDF SPEC CHANGE - Log both CUID and KDD
+ // Also added TKSKeyset, OldKeyInfo_KeyVersion, NewKeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd
+ // Finally, log CUID and KDD in ASCII-HEX format, as long as special-decoded version is available.
+ String[] logParams = { log_string_from_specialDecoded_byte_array(xCUID), // CUID_decoded
+ log_string_from_specialDecoded_byte_array(xKDD), // KDD_decoded
+ ILogger.FAILURE, // Outcome
+ status, // status
+ agentId, // AgentID
+
+ // AC: BUGFIX: Record the actual parameters to DiversifyKey in the audit log.
+ oldKeyNickName, // oldMasterKeyName
+ newKeyNickName, // newMasterKeyName
+
+ keySet, // TKSKeyset
+ log_string_from_keyInfo(xkeyInfo), // OldKeyInfo_KeyVersion
+ log_string_from_keyInfo(xnewkeyInfo), // NewKeyInfo_KeyVersion
+ "0x" + Integer.toHexString((int)nistSP800_108KdfOnKeyVersion & 0x000000FF), // NistSP800_108KdfOnKeyVersion
+ Boolean.toString(nistSP800_108KdfUseCuidAsKdd), // NistSP800_108KdfUseCuidAsKdd
+ errorMsg // Error
+ };
+ auditMessage = CMS.getLogMessage(LOGGING_SIGNED_AUDIT_DIVERSIFY_KEY_REQUEST_PROCESSED_FAILURE, logParams);
}
audit(auditMessage);
@@ -972,7 +1336,15 @@ public class TokenServlet extends CMSServlet {
private void processEncryptData(HttpServletRequest req,
HttpServletResponse resp) throws EBaseException {
- byte[] keyInfo, CUID, xCUID, encryptedData, xkeyInfo;
+ byte[] keyInfo, xCUID, encryptedData, xkeyInfo, xKDD; // AC: KDF SPEC CHANGE: removed duplicative 'CUID' variable and added xKDD
+
+ // AC: KDF SPEC CHANGE - new config file values (needed for symkey)
+ byte nistSP800_108KdfOnKeyVersion = (byte)0xff;
+ boolean nistSP800_108KdfUseCuidAsKdd = false;
+
+ // AC: KDF SPEC CHANGE - flag for if there is an error reading our new setting
+ Exception missingSetting_exception = null;
+
boolean missingParam = false;
byte[] data = null;
boolean isRandom = true; // randomly generate the data to be encrypted
@@ -984,6 +1356,15 @@ public class TokenServlet extends CMSServlet {
String rdata = req.getParameter(IRemoteRequest.TOKEN_DATA);
String rKeyInfo = req.getParameter(IRemoteRequest.TOKEN_KEYINFO);
String rCUID = req.getParameter(IRemoteRequest.TOKEN_CUID);
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ String rKDD = req.getParameter("KDD");
+ if ((rKDD == null) || (rKDD.length() == 0)) {
+ // temporarily make it friendly before TPS change
+ CMS.debug("TokenServlet: KDD not supplied, set to CUID before TPS change");
+ rKDD = rCUID;
+ }
+
String keySet = req.getParameter(IRemoteRequest.TOKEN_KEYSET);
if (keySet == null || keySet.equals("")) {
keySet = "defKeySet";
@@ -1008,9 +1389,11 @@ public class TokenServlet extends CMSServlet {
isRandom = true;
}
+ // AC: KDF SPEC CHANGE: Need to log both KDD and CUID
String auditMessage = CMS.getLogMessage(
LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST,
rCUID,
+ rKDD, // AC: KDF SPEC CHANGE - Log both CUID and KDD.
ILogger.SUCCESS,
agentId,
s_isRandom);
@@ -1044,12 +1427,24 @@ public class TokenServlet extends CMSServlet {
missingParam = true;
}
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ if ((rKDD == null) || (rKDD.length() == 0)) {
+ CMS.debug("TokenServlet: processDiversifyKey(): missing request parameter: KDD");
+ badParams += " KDD,";
+ missingParam = true;
+ }
+
if ((rKeyInfo == null) || (rKeyInfo.equals(""))) {
badParams += " KeyInfo,";
CMS.debug("TokenServlet: processEncryptData(): missing request parameter: key info");
missingParam = true;
}
+ // AC: KDF SPEC CHANGE
+ xCUID = null; // avoid errors about non-initialization
+ xKDD = null; // avoid errors about non-initialization
+ xkeyInfo = null; // avoid errors about non-initialization
+
if (!missingParam) {
xCUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
if (xCUID == null || xCUID.length != 10) {
@@ -1057,6 +1452,15 @@ public class TokenServlet extends CMSServlet {
CMS.debug("TokenServlet: Invalid CUID length");
missingParam = true;
}
+
+ // AC: KDF SPEC CHANGE - read new KDD parameter from TPS
+ xKDD = com.netscape.cmsutil.util.Utils.SpecialDecode(rKDD);
+ if (xKDD == null || xKDD.length != 10) {
+ badParams += " KDD length,";
+ CMS.debug("TokenServlet: Invalid KDD length");
+ missingParam = true;
+ }
+
xkeyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
if (xkeyInfo == null || xkeyInfo.length != 2) {
badParams += " KeyInfo length,";
@@ -1072,10 +1476,35 @@ public class TokenServlet extends CMSServlet {
String selectedToken = null;
String keyNickName = null;
if (!missingParam) {
+
+ // AC: KDF SPEC CHANGE - read new config file values (needed for symkey
+ try{
+ nistSP800_108KdfOnKeyVersion = TokenServlet.read_setting_nistSP800_108KdfOnKeyVersion(keySet);
+ nistSP800_108KdfUseCuidAsKdd = TokenServlet.read_setting_nistSP800_108KdfUseCuidAsKdd(keySet);
+
+ // log settings read in to debug log along with xkeyInfo
+ CMS.debug("TokenServlet: processEncryptData(): xkeyInfo[0] = 0x"
+ + Integer.toHexString((int)(xkeyInfo[0]) & 0x0000000FF)
+ + ", xkeyInfo[1] = 0x"
+ + Integer.toHexString((int)(xkeyInfo[1]) & 0x0000000FF)
+ );
+ CMS.debug("TokenServlet: processEncryptData(): Nist SP800-108 KDF will be used for key versions >= 0x"
+ + Integer.toHexString((int)(nistSP800_108KdfOnKeyVersion) & 0x0000000FF)
+ );
+ if (nistSP800_108KdfUseCuidAsKdd == true){
+ CMS.debug("TokenServlet: processEncryptData(): Nist SP800-108 KDF (if used) will use CUID instead of KDD.");
+ }else{
+ CMS.debug("TokenServlet: processEncryptData(): Nist SP800-108 KDF (if used) will use KDD.");
+ }
+ // conform to the set-an-error-flag mentality
+ }catch(Exception e){
+ missingSetting_exception = e;
+ CMS.debug("TokenServlet: processEncryptData(): Exception reading Nist SP800-108 KDF config values: " + e.toString());
+ }
+
if (!isRandom)
data = com.netscape.cmsutil.util.Utils.SpecialDecode(rdata);
keyInfo = com.netscape.cmsutil.util.Utils.SpecialDecode(rKeyInfo);
- CUID = com.netscape.cmsutil.util.Utils.SpecialDecode(rCUID);
String keyInfoMap = "tks." + keySet + ".mk_mappings." + rKeyInfo;
String mappingValue = CMS.getConfigStore().getString(keyInfoMap, null);
@@ -1090,12 +1519,30 @@ public class TokenServlet extends CMSServlet {
byte kekKeyArray[] =
com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
+ // AC: KDF SPEC CHANGE - check for error reading settings
+ if (missingSetting_exception == null){
+
encryptedData = SessionKey.EncryptData(
- selectedToken, keyNickName, data, keyInfo, CUID, kekKeyArray, useSoftToken_s, keySet);
+ selectedToken,keyNickName,data,keyInfo,
+ nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
+ nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
+ xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
+ xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
+ kekKeyArray, useSoftToken_s, keySet);
+
+ // AC: KDF SPEC CHANGE - Log both CUID and KDD
+
CMS.getLogger().log(ILogger.EV_AUDIT,
ILogger.S_TKS,
- ILogger.LL_INFO, "process EncryptData for CUID =" + trim(pp.toHexString(CUID)));
+ ILogger.LL_INFO,"process EncryptData for CUID="+
+ trim(pp.toHexString(xCUID)) +
+ ", KDD=" +
+ trim(pp.toHexString(xKDD)));
+
+ } // AC: KDF SPEC CHANGE - endif no error reading settings from settings file
+
+
} // !missingParam
resp.setContentType("text/html");
@@ -1109,6 +1556,11 @@ public class TokenServlet extends CMSServlet {
com.netscape.cmsutil.util.Utils.SpecialEncode(data) +
"&"+IRemoteRequest.TKS_RESPONSE_EncryptedData+"=" +
com.netscape.cmsutil.util.Utils.SpecialEncode(encryptedData);
+ // AC: KDF SPEC CHANGE - check for settings file issue (flag)
+ } else if (missingSetting_exception != null){
+ status = "6";
+ errorMsg = "Problem reading required configuration value.";
+ value = "status=" + status;
} else if (missingParam) {
if (badParams.endsWith(",")) {
badParams = badParams.substring(0, badParams.length() - 1);
@@ -1137,29 +1589,42 @@ public class TokenServlet extends CMSServlet {
}
if (status.equals("0")) {
-
- auditMessage = CMS.getLogMessage(
- LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS,
- rCUID,
- ILogger.SUCCESS,
- status,
- agentId,
- s_isRandom,
- selectedToken,
- keyNickName);
-
+ // AC: KDF SPEC CHANGE - Log both CUID and KDD
+ // Also added TKSKeyset, KeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd
+ // Finally, log CUID and KDD in ASCII-HEX format, as long as special-decoded version is available.
+ String[] logParams = { log_string_from_specialDecoded_byte_array(xCUID), // CUID_decoded
+ log_string_from_specialDecoded_byte_array(xKDD), // KDD_decoded
+ ILogger.SUCCESS, // Outcome
+ status, // status
+ agentId, // AgentID
+ s_isRandom, // isRandom
+ selectedToken, // SelectedToken
+ keyNickName, // KeyNickName
+ keySet, // TKSKeyset
+ log_string_from_keyInfo(xkeyInfo), // KeyInfo_KeyVersion
+ "0x" + Integer.toHexString((int)nistSP800_108KdfOnKeyVersion & 0x000000FF), // NistSP800_108KdfOnKeyVersion
+ Boolean.toString(nistSP800_108KdfUseCuidAsKdd) // NistSP800_108KdfUseCuidAsKdd
+ };
+ auditMessage = CMS.getLogMessage(LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_SUCCESS, logParams);
} else {
-
- auditMessage = CMS.getLogMessage(
- LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE,
- rCUID,
- ILogger.FAILURE,
- status,
- agentId,
- s_isRandom,
- selectedToken,
- keyNickName,
- errorMsg);
+ // AC: KDF SPEC CHANGE - Log both CUID and KDD
+ // Also added TKSKeyset, KeyInfo_KeyVersion, NistSP800_108KdfOnKeyVersion, NistSP800_108KdfUseCuidAsKdd
+ // Finally, log CUID and KDD in ASCII-HEX format, as long as special-decoded version is available.
+ String[] logParams = { log_string_from_specialDecoded_byte_array(xCUID), // CUID_decoded
+ log_string_from_specialDecoded_byte_array(xKDD), // KDD_decoded
+ ILogger.FAILURE, // Outcome
+ status, // status
+ agentId, // AgentID
+ s_isRandom, // isRandom
+ selectedToken, // SelectedToken
+ keyNickName, // KeyNickName
+ keySet, // TKSKeyset
+ log_string_from_keyInfo(xkeyInfo), // KeyInfo_KeyVersion
+ "0x" + Integer.toHexString((int)nistSP800_108KdfOnKeyVersion & 0x000000FF), // NistSP800_108KdfOnKeyVersion
+ Boolean.toString(nistSP800_108KdfUseCuidAsKdd), // NistSP800_108KdfUseCuidAsKdd
+ errorMsg // Error
+ };
+ auditMessage = CMS.getLogMessage(LOGGING_SIGNED_AUDIT_ENCRYPT_DATA_REQUEST_PROCESSED_FAILURE, logParams);
}
audit(auditMessage);