[Pki-devel] [pki-devel][PATCH] 0064-Port-symkey-JNI-to-Java-classes.patch
Fraser Tweedale
ftweedal at redhat.com
Sun Apr 17 23:37:45 UTC 2016
On Fri, Apr 15, 2016 at 10:03:03PM -0400, John Magne wrote:
> Subject: [PATCH] Port symkey JNI to Java classes. Ticket #801 : Merge
> pki-symkey into jss
>
> What is supported:
>
> 1. Everything that is needed to support Secure Channel Protocol 01.
> 2. Supports the nist sp800 kdf and the original kdf.
> 3. Supports key unwrapping used by TPS which was formerly in the symkey JNI.
>
> Requires:
>
> 1. A new JSS that supports more advanced symkey operations such as key derivation, more advanced key
> unwrapping , and a way to list and identify a given symmetric key by name. Version of new Jss will be forthcoming.
>
Are you going to rebase to a new version of JSS (i.e. 4.3.x) or
apply more patches on 4.2.6? There is a feature unavailable in
4.2.6 that I'd like to get into the next release of JSS as well.
> Still to do:
>
> 1. Port over the 2 or 3 SCP02 routines from Symkey to use this code.
> 2. The original symkey will remain in place until we can port over everything.
> 3. SCP03 support can be added later.
> From e4b02023290624b899192f65626f0c0f60d5638c Mon Sep 17 00:00:00 2001
> From: Jack Magne <jmagne at dhcp-16-206.sjc.redhat.com>
> Date: Tue, 29 Mar 2016 10:39:27 -0700
> Subject: [PATCH] Port symkey JNI to Java classes. Ticket #801 : Merge
> pki-symkey into jss
>
> What is supported:
>
> 1. Everything that is needed to support Secure Channel Protocol 01.
> 2. Supports the nist sp800 kdf and the original kdf.
> 3. Supports key unwrapping used by TPS which was formerly in the symkey JNI.
>
> Requires:
>
> 1. A new JSS that supports more advanced symkey operations such as key derivation, more advanced key
> unwrapping , and a way to list and identify a given symmetric key by name. Version of new Jss will be forthcoming.
>
> Still to do:
>
> 1. Port over the 2 or 3 SCP02 routines from Symkey to use this code.
> 2. The original symkey will remain in place until we can port over everything.
> 3. SCP03 support can be added later.
>
> Audit fix.
> ---
> .../cms/src/com/netscape/cms/servlet/tks/KDF.java | 67 +
> .../netscape/cms/servlet/tks/NistSP800_108KDF.java | 200 +++
> .../cms/servlet/tks/SecureChannelProtocol.java | 1412 ++++++++++++++++++++
> .../com/netscape/cms/servlet/tks/StandardKDF.java | 170 +++
> .../com/netscape/cms/servlet/tks/TokenServlet.java | 140 +-
> .../server/tps/processor/TPSProcessor.java | 83 +-
> 6 files changed, 1987 insertions(+), 85 deletions(-)
> create mode 100644 base/server/cms/src/com/netscape/cms/servlet/tks/KDF.java
> create mode 100644 base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java
> create mode 100644 base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
> create mode 100644 base/server/cms/src/com/netscape/cms/servlet/tks/StandardKDF.java
>
> diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/KDF.java b/base/server/cms/src/com/netscape/cms/servlet/tks/KDF.java
> new file mode 100644
> index 0000000..54028af
> --- /dev/null
> +++ b/base/server/cms/src/com/netscape/cms/servlet/tks/KDF.java
> @@ -0,0 +1,67 @@
> +package com.netscape.cms.servlet.tks;
> +
> +import com.netscape.certsrv.apps.CMS;
> +import com.netscape.certsrv.base.EBaseException;
> +
> +public class KDF {
> + /* DES KEY Parity conversion table. Takes each byte >> 1 as an index, returns
> + * that byte with the proper parity bit set*/
> + static final int parityTable[] =
> + {
> + /* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
> + /* E */0x01, 0x02, 0x04, 0x07, 0x08, 0x0b, 0x0d, 0x0e,
> + /* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
> + /* O */0x10, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x1f,
> + /* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */
> + /* O */0x20, 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x2f,
> + /* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */
> + /* E */0x31, 0x32, 0x34, 0x37, 0x38, 0x3b, 0x3d, 0x3e,
> + /* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */
> + /* O */0x40, 0x43, 0x45, 0x46, 0x49, 0x4a, 0x4c, 0x4f,
> + /* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */
> + /* E */0x51, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, 0x5e,
> + /* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */
> + /* E */0x61, 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x6e,
> + /* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */
> + /* O */0x70, 0x73, 0x75, 0x76, 0x79, 0x7a, 0x7c, 0x7f,
> + /* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */
> + /* O */0x80, 0x83, 0x85, 0x86, 0x89, 0x8a, 0x8c, 0x8f,
> + /* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */
> + /* E */0x91, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, 0x9e,
> + /* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */
> + /* E */0xa1, 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xae,
> + /* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */
> + /* O */0xb0, 0xb3, 0xb5, 0xb6, 0xb9, 0xba, 0xbc, 0xbf,
> + /* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */
> + /* E */0xc1, 0xc2, 0xc4, 0xc7, 0xc8, 0xcb, 0xcd, 0xce,
> + /* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */
> + /* O */0xd0, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, 0xdf,
> + /* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */
> + /* O */0xe0, 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xef,
> + /* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */
> + /* E */0xf1, 0xf2, 0xf4, 0xf7, 0xf8, 0xfb, 0xfd, 0xfe, };
> +
> + protected byte[] getDesParity(byte[] key) throws EBaseException {
> + String method = "KDF.getDesParity";
> + if (key == null
> + || (key.length != SecureChannelProtocol.DES2_LENGTH && key.length != SecureChannelProtocol.EIGHT_BYTES)) {
> + throw new EBaseException(method + " Incorrect input key !");
> + }
> +
> + byte[] desKey = new byte[key.length];
> +
> + for (int i = 0; i < key.length; i++) {
> + int index = key[i] & 0xff;
> + int finalIndex = index >> 1;
> +
> + byte val = (byte) parityTable[finalIndex];
> + desKey[i] = val;
> +
> + }
> +
> + CMS.debug("desKey: " + desKey + " len: " + desKey.length);
> +
> + return desKey;
> + }
> +
> +}
> diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java b/base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java
> new file mode 100644
> index 0000000..cb614bd
> --- /dev/null
> +++ b/base/server/cms/src/com/netscape/cms/servlet/tks/NistSP800_108KDF.java
> @@ -0,0 +1,200 @@
> +package com.netscape.cms.servlet.tks;
> +
> +import java.util.Arrays;
> +import java.util.HashMap;
> +import java.util.Map;
> +
> +import org.mozilla.jss.crypto.CryptoToken;
> +import org.mozilla.jss.crypto.HMACAlgorithm;
> +import org.mozilla.jss.crypto.JSSMessageDigest;
> +import org.mozilla.jss.crypto.SymmetricKey;
> +
> +import com.netscape.certsrv.apps.CMS;
> +import com.netscape.certsrv.base.EBaseException;
> +
> +public class NistSP800_108KDF extends KDF {
> +
> + static final int KDF_OUTPUT_SIZE_BITS = 384;
> + static final int KDF_OUTPUT_SIZE_BYTES = KDF_OUTPUT_SIZE_BITS / 8;
> + static final int KEY_DATA_SIZE_BYTES = KDF_OUTPUT_SIZE_BYTES / 3;
> +
> + static final int KDD_SIZE_BYTES = 10; // expected KDD field length in bytes
> +
> + static final byte KDF_LABEL = 0x04; // arbitra
> +
> + static final int SHA256_LENGTH = 32;
> +
> + SecureChannelProtocol protocol = null;
> +
> + NistSP800_108KDF(SecureChannelProtocol protocol) {
> + this.protocol = protocol;
> + }
> +
> + static public boolean useThisKDF(byte nistSP800_108KDFonKeyVersion, byte requestedKeyVersion) {
> + return (requestedKeyVersion >= nistSP800_108KDFonKeyVersion);
> + }
> +
> + //*******************************************************************************
> + // Generates three PK11SymKey objects using the KDF_CM_SHA256HMAC_L384() function for key data.
> + // After calling KDF_CM_SHA256HMAC_L384, the function splits up the output, sets DES parity,
> + // and imports the keys into the token.
> + //
> + // Careful: This function currently generates the key data **IN RAM** using calls to NSS sha256.
> + // The key data is then "unwrapped" (imported) to the NSS token and then erased from RAM.
> + // (This means that a malicious actor on the box could steal the key data.)
> + //
> + // Note: Returned key material from the KDF is converted into keys according to the following:
> + // * Bytes 0 - 15 : enc/auth key
> + // * Bytes 16 - 31 : mac key
> + // * Bytes 32 - 47 : kek key
> + // We chose this order to conform with the key order used by the PUT KEY command.
> + //
> + //*******************************************************************************
> +
> + public Map<String, SymmetricKey> computeCardKeys(SymmetricKey masterKey, byte[] context, CryptoToken token)
> + throws EBaseException {
> +
> + String method = "NistSP800_108KDF.computeCardKeys:";
> +
> + if (masterKey == null || context == null || token == null) {
> + throw new EBaseException(method + " Invlalid input parameters!");
> + }
> +
> + Map<String, SymmetricKey> keys = new HashMap<String, SymmetricKey>();
> +
> + byte[] kdf_output = null;
> +
> + kdf_output = kdf_CM_SHA256_HMAC_L384(masterKey, context, KDF_LABEL, KDF_OUTPUT_SIZE_BYTES, token);
> +
> + //Now create the 3 keys from only 48 of the 64 bytes...
> +
> + byte[] enc = new byte[16];
> + byte[] mac = new byte[16];
> + byte[] kek = new byte[16];
> +
> + System.arraycopy(kdf_output, 0 * SecureChannelProtocol.DES2_LENGTH, enc, 0, SecureChannelProtocol.DES2_LENGTH);
> + System.arraycopy(kdf_output, 1 * SecureChannelProtocol.DES2_LENGTH, mac, 0, SecureChannelProtocol.DES2_LENGTH);
> + System.arraycopy(kdf_output, 2 * SecureChannelProtocol.DES2_LENGTH, kek, 0, SecureChannelProtocol.DES2_LENGTH);
> +
> + byte[] encFinal = this.getDesParity(enc);
> + byte[] macFinal = this.getDesParity(mac);
> + byte[] kekFinal = this.getDesParity(kek);
> +
> + boolean showKeysOnlyForDebug = false;
> +
> + if(showKeysOnlyForDebug) {
> + SecureChannelProtocol.debugByteArray(macFinal, " Nist macFinal: ");
> + SecureChannelProtocol.debugByteArray(encFinal, " Nist encFinal: ");
> + SecureChannelProtocol.debugByteArray(kekFinal, " Nist kekFinal: ");
> + }
> +
> +
> + Arrays.fill(enc, (byte) 0);
> + Arrays.fill(mac, (byte) 0);
> + Arrays.fill(kek, (byte) 0);
> +
> + SymmetricKey macKey = protocol.unwrapSymKeyOnToken(token, macFinal, false);
> + SymmetricKey encKey = protocol.unwrapSymKeyOnToken(token, encFinal, false);
> + SymmetricKey kekKey = protocol.unwrapSymKeyOnToken(token, kekFinal, false);
> +
> + Arrays.fill(encFinal, (byte) 0);
> + Arrays.fill(macFinal, (byte) 0);
> + Arrays.fill(kekFinal, (byte) 0);
> +
> + keys.put(SecureChannelProtocol.macType, macKey);
> + keys.put(SecureChannelProtocol.encType, encKey);
> + keys.put(SecureChannelProtocol.kekType, kekKey);
> +
> + return keys;
> +
> + }
> +
> + //*******************************************************************************
> + // Key Derivation Function in Counter Mode using PRF = SHA256HMAC (NIST SP 800-108)
> + // Calculates 384 bits of diversified output from the provided master key (K_I)
> + //*******************************************************************************
> +
> + private byte[] kdf_CM_SHA256_HMAC_L384(SymmetricKey masterKey, byte[] context, byte kdfLabel,
> + int kdfOutputSizeBytes, CryptoToken token) throws EBaseException {
> +
> + String method = "NistSP800_108KDF.cm_SHA256_HMAC_L384:";
> +
> + CMS.debug(method + " entering..");
> + final byte n = 2; // ceil(384 / (SHA256LENGTH * 8)) == 2
> + int L_BYTE_array_length = 2; // 384 = 0x0180 hex; 2 byte long representation
> +
> + if (context == null) {
> + throw new EBaseException(method + " Input value context must not be null.");
> + }
> + // sanity check that output buffer is large enough to contain 384 bits
> + if (kdfOutputSizeBytes < KDF_OUTPUT_SIZE_BYTES) {
> + throw new EBaseException(method + " Array \"output\" must be at least 48 bytes in size.");
> + }
> +
> + // calculate size of temporary buffer
> + int HMAC_DATA_INPUT_SIZE = context.length + 3 + L_BYTE_array_length; // Don't change without reviewing code below.
> +
> + // prevent integer overflow
> + if (HMAC_DATA_INPUT_SIZE < context.length) {
> + throw new EBaseException(method + " Input parameter context size is too large.");
> + }
> +
> + byte L_BYTE_array[] = new byte[L_BYTE_array_length]; // Array to store L in BYTES
> + L_BYTE_array[0] = 0x01;
> + L_BYTE_array[1] = (byte) 0x80;
> +
> + // Hash Input = context + 5 BYTES
> + byte[] hmac_data_input = new byte[HMAC_DATA_INPUT_SIZE];
> +
> + byte[] K = new byte[n * SHA256_LENGTH];
> +
> + hmac_data_input[1] = kdfLabel;
> + hmac_data_input[2] = 0x0;
> + System.arraycopy(context, 0, hmac_data_input, 3, context.length);
> + System.arraycopy(L_BYTE_array, 0, hmac_data_input, context.length + 3, 2);
> +
> + byte[] outputHMAC256 = null;
> +
> + for (byte i = 1; i <= n; i++) {
> + hmac_data_input[0] = i;
> + outputHMAC256 = sha256HMAC(masterKey, hmac_data_input, HMAC_DATA_INPUT_SIZE, token);
> + CMS.debug(method + "outputHMAC256 len: " + outputHMAC256.length);
> + System.arraycopy(outputHMAC256, 0, K, (i - 1) * SHA256_LENGTH, SHA256_LENGTH);
> + }
> +
> + CMS.debug(method + " Returning: " + K.length + " bytes...");
> +
> + return K;
> + }
> +
> + private byte[] sha256HMAC(SymmetricKey masterKey, byte[] hmac_data_input, int hMAC_DATA_INPUT_SIZE,
> + CryptoToken token) throws EBaseException {
> +
> + String method = "NistSP800_108KDF.sha256HMAC:";
> +
> + CMS.debug(method + " Entering...");
> +
> + byte[] digestBytes = null;
> +
> + if (token == null) {
> + throw new EBaseException(method = " Invalid Crypto Token input!");
> + }
> +
> + try {
> + JSSMessageDigest digest = token.getDigestContext(HMACAlgorithm.SHA256);
> + digest.initHMAC(masterKey);
> +
> + digestBytes = digest.digest(hmac_data_input);
> + } catch (Exception e) {
> +
> + CMS.debug(method + " Failure to HMAC the input data: " + e);
> + throw new EBaseException(method + e);
> + }
> +
> + SecureChannelProtocol.debugByteArray(digestBytes, " output of sha256HMAC: ");
> +
> + return digestBytes;
> + }
> +
> +
> +}
> diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
> new file mode 100644
> index 0000000..5cb7b06
> --- /dev/null
> +++ b/base/server/cms/src/com/netscape/cms/servlet/tks/SecureChannelProtocol.java
> @@ -0,0 +1,1412 @@
> +package com.netscape.cms.servlet.tks;
> +
> +import java.io.ByteArrayOutputStream;
> +import java.io.CharConversionException;
> +import java.io.IOException;
> +import java.nio.ByteBuffer;
> +import java.security.InvalidAlgorithmParameterException;
> +import java.security.InvalidKeyException;
> +import java.security.NoSuchAlgorithmException;
> +import java.util.Arrays;
> +import java.util.Map;
> +
> +import org.mozilla.jss.CryptoManager;
> +import org.mozilla.jss.CryptoManager.NotInitializedException;
> +import org.mozilla.jss.NoSuchTokenException;
> +import org.mozilla.jss.crypto.BadPaddingException;
> +import org.mozilla.jss.crypto.Cipher;
> +import org.mozilla.jss.crypto.CryptoToken;
> +import org.mozilla.jss.crypto.EncryptionAlgorithm;
> +import org.mozilla.jss.crypto.IllegalBlockSizeException;
> +import org.mozilla.jss.crypto.KeyGenAlgorithm;
> +import org.mozilla.jss.crypto.KeyGenerator;
> +import org.mozilla.jss.crypto.KeyWrapAlgorithm;
> +import org.mozilla.jss.crypto.KeyWrapper;
> +import org.mozilla.jss.crypto.SymmetricKey;
> +import org.mozilla.jss.crypto.SymmetricKey.NotExtractableException;
> +import org.mozilla.jss.crypto.SymmetricKeyDeriver;
> +import org.mozilla.jss.crypto.TokenException;
> +
> +import sun.security.pkcs11.wrapper.PKCS11Constants;
> +
> +import com.netscape.certsrv.apps.CMS;
> +import com.netscape.certsrv.base.EBaseException;
> +
> +public class SecureChannelProtocol {
> +
> + static String sharedSecretKeyName = null;
> + static String masterKeyPrefix = null;
> +
> + static final int KEYLENGTH = 16;
> + static final int PREFIXLENGHT = 128;
> + static final int DES2_LENGTH = 16;
> + static final int DES3_LENGTH = 24;
> + static final int EIGHT_BYTES = 8;
> + static final int KEYNAMELENGTH = PREFIXLENGHT + 7;
> + static final String TRANSPORT_KEY_NAME = "sharedSecret";
> + static final String DEFKEYSET_NAME = "defKeySet";
> +
> + static final String encType = "enc";
> + static final String macType = "mac";
> + static final String kekType = "kek";
> + static final String authType = "auth";
> + static final String dekType = "dek";
> + static final int PROTOCOL_ONE = 1;
> + static final int PROTOCOL_TWO = 2;
> + static final int PROTOCOL_THREE = 3;
> +
> + private SymmetricKey transportKey = null;
> + CryptoManager cryptoManager = null;
> +
> + public SecureChannelProtocol() {
> + }
> +
> + public byte[] computeCryptogram_SCP01(
> + String selectedToken, String keyNickName, byte[] card_challenge,
> + byte[] host_challenge, byte[] keyInfo,
> + byte nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
> + boolean nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
> + byte[] xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
> + byte[] xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
> + int cryptogramType, byte[] authKeyArray, String useSoftToken_s, String keySet, String transportKeyName)
> + throws EBaseException {
> +
> + String method = "SecureChannelProtocol.computeCryptogram_SCP01:";
> +
> + CMS.debug(method + " Entering: Type: HOST=0 , CARD=1 : TYPE: " + cryptogramType);
> +
> + if ((card_challenge == null || card_challenge.length != EIGHT_BYTES)
> + || (host_challenge == null || host_challenge.length != EIGHT_BYTES)) {
> +
> + throw new EBaseException(method + " Invalid card challenge or host challenge!");
> +
> + }
> +
> + if( cryptogramType != 0 && cryptogramType != 1) {
> + throw new EBaseException(method + " Invalid cyrptgram type!");
> + }
> +
> + byte[] cryptogram = null;
> +
> + SymmetricKey authKey = this.computeSessionKey_SCP01(SecureChannelProtocol.encType, selectedToken, keyNickName,
> + card_challenge, host_challenge, keyInfo, nistSP800_108KdfOnKeyVersion, nistSP800_108KdfUseCuidAsKdd,
> + xCUID, xKDD, authKeyArray, useSoftToken_s, keySet, transportKeyName);
> +
> + byte[] input = new byte[DES2_LENGTH];
> + byte[] icv = new byte[EIGHT_BYTES];
> +
> + if (cryptogramType == 0) // compute host cryptogram
> + {
> + /* copy card and host challenge into input buffer */
> + for (int i = 0; i < EIGHT_BYTES; i++)
> + {
> + input[i] = card_challenge[i];
> + }
> + for (int i = 0; i < EIGHT_BYTES; i++)
> + {
> + input[EIGHT_BYTES + i] = host_challenge[i];
> + }
> + } // compute card cryptogram
> + else if (cryptogramType == 1)
> + {
> + for (int i = 0; i < EIGHT_BYTES; i++)
> + {
> + input[i] = host_challenge[i];
> + }
> + for (int i = 0; i < EIGHT_BYTES; i++)
> + {
> + input[EIGHT_BYTES + i] = card_challenge[i];
> + }
> +
> + }
> + cryptogram = computeMAC_SCP01(authKey, input, icv, selectedToken);
> +
> + SecureChannelProtocol.debugByteArray(cryptogram, " Output of computeCrytptogram type: " + cryptogramType);
> +
> + return cryptogram;
> + }
> +
> + public SymmetricKey computeSessionKey_SCP02(
> + String selectedToken, String keyNickName,
> + byte[] keyInfo,
> + byte nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
> + boolean nistSP800_108KdfUseCuidAsKdd, byte[] xCUID, byte[] xKDD, byte[] macKeyArray,
> + byte[] sequenceCounter, byte[] derivationConstant,
> + String useSoftToken_s, String keySet,
> + String transportKeyName) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.computeSessionKey_SCP01:";
> +
> + CMS.debug(method + " entering... ");
> +
> + throw new EBaseException(method + " Not yet implemented!");
> + }
> +
> + public SymmetricKey computeSessionKey_SCP01(String keyType,
> + String selectedToken, String keyNickName, byte[] card_challenge,
> + byte[] host_challenge, byte[] keyInfo,
> + byte nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
> + boolean nistSP800_108KdfUseCuidAsKdd, // AC: KDF SPEC CHANGE - pass in configuration file value
> + byte[] xCUID, // AC: KDF SPEC CHANGE - removed duplicative 'CUID' variable and replaced with 'xCUID'
> + byte[] xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
> + byte[] devKeyArray, String useSoftToken_s, String keySet, String transportKeyName) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.computeSessionKey_SCP01:";
> +
> + CMS.debug(method + " entering... requested type: " + keyType);
> +
> + // This gets set if there is no input card challenge and host challenge
> + // Allows this routine to be used for the "encryptData" routine built on top.
> +
> + boolean noDerive = false;
> +
> + if (keyType == null || devKeyArray == null || keyInfo == null
> + || keySet == null || transportKeyName == null || (keyInfo == null || keyInfo.length < 2)) {
> + throw new EBaseException(method + "Invalid input!");
> + }
> +
> + if (xCUID == null || xCUID.length <= 0) {
> + throw new EBaseException(method + "CUID invalid size!");
> + }
> +
> + if (xKDD == null || xKDD.length != NistSP800_108KDF.KDD_SIZE_BYTES) {
> + throw new EBaseException(method + "KDD invalid size!");
> + }
> +
> + if (card_challenge == null && host_challenge == null) {
> + noDerive = true;
> + CMS.debug(method + " NoDerive mode: true");
> + } else {
> + if (card_challenge == null || host_challenge == null) {
> + throw new EBaseException(method + " Invalid input!");
> + }
> +
> + CMS.debug(method + " NoDerive mode: false");
> + }
> +
> + CMS.debug(method + " entering. nickname: " + keyNickName + " selectedToken: " + selectedToken);
> + CMS.debug(method + " nistSP800_108kdfOnKeyVersion: " + nistSP800_108KdfOnKeyVersion);
> +
> + CryptoManager cm = null;
> + CryptoToken token = null;
> + try {
> + cm = CryptoManager.getInstance();
> + token = returnTokenByName(selectedToken, cm);
> + } catch (NotInitializedException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> +
> + } catch (NoSuchTokenException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + sharedSecretKeyName = SecureChannelProtocol.getSharedSecretKeyName(transportKeyName);
> + transportKey = getSharedSecretKey(token);
> +
> + String keyNameStr = null;
> +
> + SymmetricKey sessionKey = null;
> + SymmetricKey masterKey = null;
> +
> + if (keyNickName == null) {
> + keyNameStr = this.getKeyName(keyInfo);
> + } else {
> + keyNameStr = keyNickName;
> + }
> +
> + byte[] context = null;
> +
> + if (nistSP800_108KdfUseCuidAsKdd == true) {
> + context = xCUID;
> + } else {
> + context = xKDD;
> + }
> +
> + if ((keyInfo[0] == 0x1 && keyInfo[1] == 0x1 && keyNameStr.equals("#01#01")) ||
> + (keyInfo[0] == -1 && keyNameStr.indexOf("#FF") != -1))
> +
> + {
> + /* default manufacturers key */
> +
> + String finalKeyType = keyType;
> +
> + SymmetricKey devSymKey = returnDeveloperSymKey(token, finalKeyType, keySet, devKeyArray);
> +
> + // Create the auth with is the same as enc, might need it later.
> + if (keyType.equals(encType)) {
> + returnDeveloperSymKey(token, authType, keySet, devKeyArray);
> + }
> +
> + if (noDerive == true) {
> + sessionKey = devSymKey;
> + } else {
> + sessionKey = deriveKey_SCP01(token, devSymKey, host_challenge, card_challenge);
> + }
> +
> + } else {
> +
> + SymmetricKey devKey = null;
> + CMS.debug(method + "In master key mode.");
> +
> + masterKey = getSymKeyByName(token, keyNameStr);
> +
> + if (NistSP800_108KDF.useThisKDF(nistSP800_108KdfOnKeyVersion, keyInfo[1])) {
> + CMS.debug(method + " ComputeSessionKey NistSP800_108KDF code: Using NIST SP800-108 KDF.");
> +
> + NistSP800_108KDF nistKDF = new NistSP800_108KDF(this);
> +
> + Map<String, SymmetricKey> keys = null;
> + try {
> + keys = nistKDF.computeCardKeys(masterKey, context, token);
> + } catch (EBaseException e) {
> + CMS.debug(method + "Can't compute card keys! " + e);
> + throw e;
> + }
> +
> + devKey = keys.get(keyType);
> +
> + } else {
> + StandardKDF standardKDF = new StandardKDF(this);
> + CMS.debug(method + " ComputeSessionKey NistSP800_108KDF code: Using original KDF.");
> + byte[] data = standardKDF.getDiversificationData(context, keyType);
> + devKey = standardKDF.computeCardKey(masterKey, data, token, PROTOCOL_ONE);
> + }
> +
> + if (noDerive == true) {
> + sessionKey = devKey;
> + } else {
> + sessionKey = deriveKey_SCP01(token, devKey, host_challenge, card_challenge);
> + }
> + }
> +
> + return sessionKey;
> + }
> +
> + private SymmetricKey deriveKey_SCP01(CryptoToken token, SymmetricKey cardKey, byte[] host_challenge,
> + byte[] card_challenge)
> + throws EBaseException {
> + String method = "SecureChannelProtocol.deriveKey_SCP01:";
> + CMS.debug(method + "entering..");
> +
> + if (cardKey == null || token == null) {
> + throw new EBaseException(method + " Invalid input data!");
> + }
> +
> + byte[] derivationData = new byte[KEYLENGTH];
> +
> + SymmetricKey derivedKey = null;
> +
> + for (int i = 0; i < 4; i++)
> + {
> + derivationData[i] = card_challenge[i + 4];
> + derivationData[i + 4] = host_challenge[i];
> + derivationData[i + 8] = card_challenge[i];
> + derivationData[i + 12] = host_challenge[i + 4];
> + }
> +
> + SymmetricKeyDeriver encryptDes3;
> + try {
> + encryptDes3 = token.getSymmetricKeyDeriver();
> +
> + encryptDes3.initDerive(
> + cardKey, /* PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA */4354L, derivationData, null,
> + PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16);
> +
> + derivedKey = encryptDes3.derive();
> +
> + } catch (TokenException | InvalidKeyException e) {
> + CMS.debug(method + "Unable to derive the key with the proper mechanism!");
> + throw new EBaseException(e);
> + }
> +
> + return derivedKey;
> + }
> +
> + public SymmetricKey getSharedSecretKey(CryptoToken token) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.getSharedSecretKey:";
> +
> + if (transportKey == null) {
> + transportKey = getSymKeyByName(token, sharedSecretKeyName);
> + }
> +
> + if (transportKey == null) {
> + throw new EBaseException(method + "Can't locate shared secret key in token db.");
> + }
> +
> + return transportKey;
> + }
> +
> + private String getKeyName(byte[] keyVersion) {
> + String keyName = null;
> +
> + if (keyVersion == null || keyVersion.length != 2) {
> + return null;
> + }
> +
> + keyName = "#" + keyVersion[0] + "#" + keyVersion[1];
> +
> + return keyName;
> + }
> +
> + public static String getSharedSecretKeyName(String name) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.getSharedSecretKeyName:";
> + CMS.debug(method + " Entering...");
> +
> + if (name != null && SecureChannelProtocol.sharedSecretKeyName == null) {
> + SecureChannelProtocol.sharedSecretKeyName = name;
> + }
> +
> + if (SecureChannelProtocol.sharedSecretKeyName == null) {
> + throw new EBaseException(method + " Can not find shared secret key name!");
> + }
> +
> + return SecureChannelProtocol.sharedSecretKeyName;
> + }
> +
> + public static String setSharedSecretKeyName(String name) throws EBaseException {
> + return SecureChannelProtocol.getSharedSecretKeyName(name);
> + }
> +
> + private SymmetricKey returnDeveloperSymKey(CryptoToken token, String keyType, String keySet, byte[] inputKeyArray)
> + throws EBaseException {
> +
> + SymmetricKey devKey = null;
> +
> + String method = "SecureChannelProtocol.returnDeveloperSymKey:";
> +
> + String devKeyName = keySet + "-" + keyType + "Key";
> + CMS.debug(method + " entering.. searching for key: " + devKeyName);
> +
> + if (token == null || keyType == null || keySet == null) {
> + throw new EBaseException(method + "Invalid input data!");
> + }
> +
> + devKey = getSymKeyByName(token, devKeyName);
> +
> + if (devKey == null) {
> + //Put the key there and leave it
> +
> + byte[] des3InputKey = null;
> +
> + if (inputKeyArray == null) {
> + throw new EBaseException(method + "Input key is null and has to be non null when importing...");
> + }
> + int inputLen = inputKeyArray.length;
> +
> + CMS.debug(method + " inputKeyArray.length: " + inputLen);
> +
> + if (inputLen != DES3_LENGTH && inputLen != DES2_LENGTH) {
> + throw new EBaseException(method + "invalid input key length!");
> + }
> +
> + if (inputLen == DES2_LENGTH) {
> + des3InputKey = new byte[DES3_LENGTH];
> + System.arraycopy(inputKeyArray, 0, des3InputKey, 0, DES2_LENGTH);
> + System.arraycopy(inputKeyArray, 0, des3InputKey, DES2_LENGTH, EIGHT_BYTES);
> +
> + } else {
> + System.arraycopy(inputKeyArray, 0, des3InputKey, 0, DES3_LENGTH);
> + }
> +
> + SecureChannelProtocol.debugByteArray(des3InputKey, "Developer key to import: " + keyType + ": ");
> +
> + devKey = unwrapSymKeyOnToken(token, des3InputKey, true);
> + devKey.setNickName(devKeyName);
> + } else {
> + CMS.debug(method + " Found sym key: " + devKeyName);
> + }
> + return devKey;
> + }
> +
> + public SymmetricKey unwrapSymKeyOnToken(CryptoToken token, SymmetricKey unwrappingKey, byte[] inputKeyArray,
> + boolean isPerm)
> + throws EBaseException {
> +
> + String method = "SecureChannelProtocol.unwrapSymKeyOnToken:";
> + CMS.debug(method + "Entering...");
> + SymmetricKey unwrapped = null;
> +
> + if (token == null || unwrappingKey == null) {
> + throw new EBaseException(method + "Invalid input!");
> + }
> +
> + if (inputKeyArray == null || (inputKeyArray.length != DES3_LENGTH && inputKeyArray.length != DES2_LENGTH)) {
> + throw new EBaseException(method + "No raw array to use to create key!");
> + }
> +
> + byte[] finalKeyArray = null;
> +
> + if (inputKeyArray.length == DES2_LENGTH) {
> + finalKeyArray = SecureChannelProtocol.makeDes3FromDes2(inputKeyArray);
> + }
> +
> + Cipher encryptor = null;
> + byte[] wrappedKey = null;
> +
> + try {
> + encryptor = token.getCipherContext(EncryptionAlgorithm.DES3_ECB);
> +
> + encryptor.initEncrypt(unwrappingKey);
> +
> + if (finalKeyArray != null) {
> + wrappedKey = encryptor.doFinal(finalKeyArray);
> + } else {
> + wrappedKey = encryptor.doFinal(inputKeyArray);
> + }
> +
> + CMS.debug(method + " done enrypting data");
> +
> + KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.DES3_ECB);
> + keyWrap.initUnwrap(unwrappingKey, null);
> +
> + if (isPerm == true) {
> + unwrapped = keyWrap.unwrapSymmetricPerm(wrappedKey,
> + SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP, 0);
> + } else {
> + unwrapped = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP, 0);
> + }
> +
> + } catch (Exception e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + } finally {
> + if (finalKeyArray != null) {
> + Arrays.fill(finalKeyArray, (byte) 0);
> + }
> + }
> +
> + CMS.debug(method + "Returning symkey: " + unwrapped);
> +
> + return unwrapped;
> + }
> +
> + public SymmetricKey unwrapWrappedSymKeyOnToken(CryptoToken token, SymmetricKey unwrappingKey, byte[] inputKeyArray,
> + boolean isPerm)
> + throws EBaseException {
> +
> + String method = "SecureChannelProtocol.unwrapWrappedSymKeyOnToken:";
> + CMS.debug(method + "Entering...");
> + SymmetricKey unwrapped = null;
> + SymmetricKey finalUnwrapped = null;
> +
> + if (token == null || unwrappingKey == null) {
> + throw new EBaseException(method + "Invalid input!");
> + }
> +
> + if (inputKeyArray == null || (inputKeyArray.length != DES3_LENGTH && inputKeyArray.length != DES2_LENGTH)) {
> + throw new EBaseException(method + "No raw array to use to create key!");
> + }
> +
> + try {
> + KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.DES3_ECB);
> + keyWrap.initUnwrap(unwrappingKey, null);
> +
> + if (isPerm) {
> + unwrapped = keyWrap.unwrapSymmetricPerm(inputKeyArray,
> + SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP, inputKeyArray.length);
> + } else {
> + unwrapped = keyWrap.unwrapSymmetric(inputKeyArray, SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP,
> + inputKeyArray.length);
> + }
> +
> + finalUnwrapped = makeDes3KeyDerivedFromDes2(unwrapped, token.getName());
> +
> + } catch (Exception e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + CMS.debug(method + "Returning symkey: " + unwrapped);
> +
> + return finalUnwrapped;
> + }
> +
> + public SymmetricKey unwrapSymKeyOnToken(CryptoToken token, byte[] inputKeyArray, boolean isPerm)
> + throws EBaseException {
> +
> + String method = "SecureChannelProtocol.unwrapSymKeyOnToken:";
> + CMS.debug(method + "Entering...");
> + SymmetricKey unwrapped = null;
> +
> + if (token == null) {
> + throw new EBaseException(method + "Invalide crypto token!");
> + }
> +
> + if (inputKeyArray == null || (inputKeyArray.length != DES3_LENGTH && inputKeyArray.length != DES2_LENGTH)) {
> + throw new EBaseException(method + "No raw array to use to create key!");
> + }
> +
> + SymmetricKey transport = getSharedSecretKey(token);
> + unwrapped = this.unwrapSymKeyOnToken(token, transport, inputKeyArray, isPerm);
> +
> + CMS.debug(method + "Returning symkey: " + unwrapped);
> +
> + return unwrapped;
> + }
> +
> + public SymmetricKey unwrapWrappedSymKeyOnToken(CryptoToken token, byte[] wrappedKeyArray, boolean isPerm)
> + throws EBaseException {
> +
> + String method = "SecureChannelProtocol.unwrapWrappedSymKeyOnToken:";
> + CMS.debug(method + "Entering...");
> + SymmetricKey unwrapped = null;
> +
> + if (token == null) {
> + throw new EBaseException(method + "Invalide crypto token!");
> + }
> +
> + if (wrappedKeyArray == null || (wrappedKeyArray.length != DES3_LENGTH && wrappedKeyArray.length != DES2_LENGTH)) {
> + throw new EBaseException(method + "No raw array to use to create key!");
> + }
> +
> + SymmetricKey transport = getSharedSecretKey(token);
> + unwrapped = this.unwrapSymKeyOnToken(token, transport, wrappedKeyArray, isPerm);
> +
> + CMS.debug(method + "Returning symkey: " + unwrapped);
> +
> + return unwrapped;
> + }
> +
> + public static SymmetricKey getSymKeyByName(CryptoToken token, String name) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.getSymKeyByName:";
> + if (token == null || name == null) {
> + throw new EBaseException(method + "Invalid input data!");
> + }
> + SymmetricKey[] keys;
> +
> + CMS.debug(method + "Searching for sym key: " + name);
> + try {
> + keys = token.getCryptoStore().getSymmetricKeys();
> + } catch (TokenException e) {
> + throw new EBaseException(method + "Can't get the list of symmetric keys!");
> + }
> + int len = keys.length;
> + for (int i = 0; i < len; i++) {
> + SymmetricKey cur = keys[i];
> + if (cur != null) {
> + if (name.equals(cur.getNickName())) {
> + CMS.debug(method + "Found key: " + name);
> + return cur;
> + }
> + }
> + }
> +
> + CMS.debug(method + " Sym Key not found.");
> + return null;
> + }
> +
> + public CryptoToken returnTokenByName(String name, CryptoManager manager) throws NoSuchTokenException {
> +
> + if (name == null || manager == null)
> + throw new NoSuchTokenException();
> +
> + if (name.equals("internal") || name.equals("Internal KeyStorage Token")) {
> + return manager.getInternalKeyStorageToken();
> + } else {
> + return manager.getTokenByName(name);
> + }
> +
> + }
> +
> + public static byte[] makeDes3FromDes2(byte[] des2) {
> +
> + if (des2 == null || des2.length != SecureChannelProtocol.DES2_LENGTH) {
> + return null;
> + }
> +
> + byte[] des3 = new byte[SecureChannelProtocol.DES3_LENGTH];
> +
> + System.arraycopy(des2, 0, des3, 0, SecureChannelProtocol.DES2_LENGTH);
> + System.arraycopy(des2, 0, des3, DES2_LENGTH, EIGHT_BYTES);
> +
> + return des3;
> + }
> +
> + public static void debugByteArray(byte[] array, String message) {
> +
> + CMS.debug("About to dump array: " + message);
> +
> + if (array == null) {
> + CMS.debug("Array to dump is empty!");
> + return;
> + }
> +
> + CMS.debug("################### ");
> +
> + String result = getHexString(array);
> + CMS.debug(result);
> + }
> +
> + final protected static char[] hex = "0123456789abcdef".toCharArray();
> +
> + public static String getHexString(byte[] bytes) {
> +
> + char[] hexChars = new char[bytes.length * 3];
> + for (int j = 0; j < bytes.length; j++) {
> + int v = bytes[j] & 0xFF;
> + hexChars[j * 3] = hex[v >>> 4];
> + hexChars[j * 3 + 1] = hex[v & 0x0F];
> + hexChars[j * 3 + 2] = ':';
> + }
> + return new String(hexChars);
> + }
> +
> + public CryptoManager getCryptoManger() throws EBaseException {
> + String method = "SecureChannelProtocol.getCryptoManager";
> + CryptoManager cm = null;
> +
> + if (cryptoManager != null)
> + return cryptoManager;
> +
> + try {
> + cm = CryptoManager.getInstance();
> + } catch (NotInitializedException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> +
> + }
> +
> + cryptoManager = cm;
> +
> + return cryptoManager;
> +
> + }
> +
> + public static byte[] longToBytes(long x) {
> + ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
> + buffer.putLong(x);
> + return buffer.array();
> + }
> +
> + // Generate 24 key, but with a DES2 key converted to DES3
> + // This needed to appease the server side keygen and the coollkey applet.
> + public SymmetricKey generateSymKey(String selectedToken) throws EBaseException {
> + String method = "SecureChannelProtocol.generateSymKey:";
> +
> + CMS.debug(method + " entering , token: " + selectedToken);
> + SymmetricKey symKey = null;
> + SymmetricKey symKeyFinal = null;
> +
> + if (selectedToken == null) {
> + throw new EBaseException(method + " Invalid input data!");
> + }
> +
> + try {
> + CryptoManager cm = this.getCryptoManger();
> + CryptoToken token = returnTokenByName(selectedToken, cm);
> +
> + KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES3);
> +
> + symKey = kg.generate();
> +
> + symKeyFinal = this.makeDes3KeyDerivedFromDes2(symKey, selectedToken);
> +
> + } catch (NoSuchAlgorithmException | TokenException | NoSuchTokenException | IllegalStateException
> + | CharConversionException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + return symKeyFinal;
> +
> + }
> +
> + public byte[] ecbEncrypt(SymmetricKey devKey, SymmetricKey symKey, String selectedToken) throws EBaseException {
> + byte[] result = null;
> + String method = "SecureChannelProtocol.ecbEncrypt:";
> + CMS.debug(method + " Entering...");
> +
> + if (devKey == null || symKey == null || selectedToken == null) {
> + throw new EBaseException(method + " Invalid input parameters.");
> + }
> +
> + SymmetricKey des2 = this.extractDes2FromDes3(symKey, selectedToken);
> +
> + result = this.wrapSessionKey(selectedToken, des2, devKey);
> +
> + SecureChannelProtocol.debugByteArray(result, " Wrapped des2 key");
> +
> + return result;
> + }
> +
> + public SymmetricKey makeDes3KeyDerivedFromDes2(SymmetricKey des3Key, String selectedToken) throws EBaseException {
> + SymmetricKey des3 = null;
> +
> + String method = "SecureChannelProtocol.makeDes3KeyDerivedFromDes2:";
> +
> + CMS.debug(method + " Entering ...");
> +
> + if (des3Key == null || selectedToken == null) {
> + throw new EBaseException(method + " Invalid input data!");
> + }
> +
> + try {
> + CryptoManager cm = this.getCryptoManger();
> + CryptoToken token = returnTokenByName(selectedToken, cm);
> +
> + long bitPosition = 0;
> +
> + byte[] param = SecureChannelProtocol.longToBytes(bitPosition);
> +
> + SymmetricKey extracted16 = this.extractDes2FromDes3(des3Key, selectedToken);
> +
> + SymmetricKeyDeriver extract8 = token.getSymmetricKeyDeriver();
> +
> + extract8.initDerive(
> + extracted16, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY, param, null,
> + PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE, 8);
> +
> + SymmetricKey extracted8 = extract8.derive();
> +
> + CMS.debug(method + " extracted8 key: " + extracted8);
> +
> + SymmetricKeyDeriver concat = token.getSymmetricKeyDeriver();
> + concat.initDerive(
> + extracted16, extracted8, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY, null, null,
> + PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 0);
> +
> + des3 = concat.derive();
> +
> + } catch (NoSuchTokenException | IllegalStateException | TokenException | InvalidKeyException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + return des3;
> + }
> +
> + public SymmetricKey extractDes2FromDes3(SymmetricKey baseKey, String selectedToken) throws EBaseException {
> + String method = "SecureChannelProtocol.extractDes2FromDes3:";
> + CMS.debug(method + " Entering: ");
> +
> + SymmetricKey extracted16 = null;
> +
> + if (baseKey == null || selectedToken == null) {
> + throw new EBaseException(method + " Invalid input data.");
> + }
> +
> + try {
> + CryptoManager cm = this.getCryptoManger();
> + CryptoToken token = returnTokenByName(selectedToken, cm);
> +
> + long bitPosition = 0;
> +
> + byte[] param = SecureChannelProtocol.longToBytes(bitPosition);
> +
> + SymmetricKeyDeriver extract16 = token.getSymmetricKeyDeriver();
> + extract16.initDerive(
> + baseKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY, param, null,
> + PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE, 16);
> +
> + extracted16 = extract16.derive();
> +
> + } catch (NoSuchTokenException | IllegalStateException | TokenException | InvalidKeyException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + return extracted16;
> + }
> +
> + public byte[] wrapSessionKey(String tokenName, SymmetricKey sessionKey, SymmetricKey wrappingKey)
> + throws EBaseException {
> + //Now wrap the key for the trip back to TPS with shared secret transport key
> +
> + String method = "SecureChannelProtocol.wrapSessionKey";
> +
> + KeyWrapper keyWrap = null;
> + byte[] wrappedSessKeyData = null;
> +
> + if (tokenName == null || sessionKey == null) {
> + throw new EBaseException(method + " Invalid input data.");
> + }
> +
> + SymmetricKey wrapper = null;
> +
> + if (wrappingKey == null) {
> + wrapper = transportKey;
> + } else {
> + wrapper = wrappingKey;
> + }
> +
> + try {
> + CryptoManager cm = this.getCryptoManger();
> + CryptoToken token = returnTokenByName(tokenName, cm);
> +
> + keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.DES3_ECB);
> + keyWrap.initWrap(wrapper, null);
> + wrappedSessKeyData = keyWrap.wrap(sessionKey);
> + } catch (NoSuchAlgorithmException | TokenException | InvalidKeyException | InvalidAlgorithmParameterException
> + | NoSuchTokenException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + CMS.debug(method + " About to return session key: " + wrappedSessKeyData);
> +
> + return wrappedSessKeyData;
> +
> + }
> +
> + public byte[] computeDes3EcbEncryption(SymmetricKey desKey, String selectedToken, byte[] input)
> + throws EBaseException {
> +
> + String method = "SecureChannelProtocol.computeDes3EcbEncryption";
> + byte[] output = null;
> +
> + if (desKey == null || selectedToken == null) {
> + throw new EBaseException(method + " Invalid input data.");
> + }
> +
> + try {
> + CryptoManager cm = this.getCryptoManger();
> + CryptoToken token = returnTokenByName(selectedToken, cm);
> + Cipher encryptor = token.getCipherContext(EncryptionAlgorithm.DES3_ECB);
> + encryptor.initEncrypt(desKey);
> + output = encryptor.doFinal(input);
> +
> + } catch (EBaseException | NoSuchTokenException | NoSuchAlgorithmException | TokenException
> + | InvalidKeyException | InvalidAlgorithmParameterException |
> + IllegalStateException | IllegalBlockSizeException | BadPaddingException e) {
> +
> + CMS.debug(method + e);
> + throw new EBaseException(method + e);
> + }
> + return output;
> + }
> +
> + public byte[] computeKeyCheck(SymmetricKey desKey, String selectedToken) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.computeKeyCheck:";
> +
> + CMS.debug(method + " Entering...");
> +
> + byte[] input = new byte[EIGHT_BYTES];
> + byte[] finalOutput = new byte[3];
> +
> + if (desKey == null || selectedToken == null) {
> + throw new EBaseException(method + " Invalid input data.");
> + }
> +
> + byte[] output = null;
> +
> + try {
> + output = computeDes3EcbEncryption(desKey, selectedToken, input);
> + } catch (EBaseException e) {
> + CMS.debug(method + e);
> + throw e;
> +
> + }
> +
> + //Get the 3 bytes needed
> + System.arraycopy(output, 0, finalOutput, 0, 3);
> +
> + SecureChannelProtocol.debugByteArray(finalOutput, "Calculated KeyCheck Value:");
> +
> + return finalOutput;
> + }
> +
> + public byte[] computeMAC_SCP01(SymmetricKey symKey, byte[] input, byte[] icv, String selectedToken)
> + throws EBaseException {
> + byte[] output = null;
> + byte[] result = null;
> +
> + String method = "SecureChannelProtocol.computeMAC_SCP01:";
> +
> + CMS.debug(method + " Entering...");
> +
> + if (symKey == null || input == null || icv == null || icv.length != EIGHT_BYTES) {
> + throw new EBaseException(method + " invalid input data!");
> + }
> + int inputLen = input.length;
> +
> + byte[] macPad = new byte[8];
> + macPad[0] = (byte) 0x80;
> +
> + CryptoToken token = null;
> +
> + try {
> +
> + CryptoManager cm = this.getCryptoManger();
> + token = returnTokenByName(selectedToken, cm);
> +
> + Cipher cipher = token.getCipherContext(EncryptionAlgorithm.DES3_ECB);
> +
> + result = new byte[EIGHT_BYTES];
> + System.arraycopy(icv, 0, result, 0, EIGHT_BYTES);
> +
> + /* Process whole blocks */
> + int inputOffset = 0;
> + while (inputLen >= 8)
> + {
> + for (int i = 0; i < 8; i++)
> + {
> + //Xor implicitly converts bytes to ints, we convert answer back to byte.
> + byte a = (byte) (result[i] ^ input[inputOffset + i]);
> + result[i] = a;
> + }
> + cipher.initEncrypt(symKey);
> + byte[] ciphResult = cipher.doFinal(result);
> +
> + if (ciphResult.length != result.length) {
> + throw new EBaseException(method + " Invalid cipher!");
> + }
> +
> + System.arraycopy(ciphResult, 0, result, 0, EIGHT_BYTES);
> +
> + inputLen -= 8;
> + inputOffset += 8;
> + }
> +
> + /*
> + * Fold in remaining data (if any)
> + * Set i to number of bytes processed
> + */
> + int i = 0;
> + for (i = 0; i < inputLen; i++)
> + {
> + byte a = (byte) (result[i] ^ input[inputOffset + i]);
> + result[i] = a;
> + }
> +
> + /*
> + * Fill remainder of last block. There
> + * will be at least one byte handled here.
> + */
> +
> + //Start at the beginning of macPad
> + // Keep going with i in result where we left off.
> + int padOffset = 0;
> + while (i < 8)
> + {
> + byte a = (byte) (result[i] ^ macPad[padOffset++]);
> + result[i] = a;
> + i++;
> + }
> +
> + cipher.initEncrypt(symKey);
> + output = cipher.doFinal(result);
> +
> + if (output.length != result.length) {
> + throw new EBaseException(method + " Invalid cipher!");
> + }
> +
> + } catch (Exception e) {
> + throw new EBaseException(method + " Cryptographic problem encountered! " + e.toString());
> + }
> +
> + SecureChannelProtocol.debugByteArray(output, method + " output: ");
> +
> + return output;
> + }
> +
> + public byte[] diversifyKey(String tokenName,
> + String newTokenName,
> + String oldMasterKeyName,
> + String newMasterKeyName,
> + byte[] oldKeyInfo,
> + byte[] newKeyInfo,
> + byte nistSP800_108KdfOnKeyVersion,
> + boolean nistSP800_108KdfUseCuidAsKdd,
> + byte[] CUIDValue,
> + byte[] KDD,
> + byte[] kekKeyArray,
> + String useSoftToken, String keySet, byte protocol) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.diversifyKey:";
> +
> + CMS.debug(method + " Entering ... newTokenName: " + newTokenName);
> +
> + SymmetricKey masterKey = null;
> + SymmetricKey oldMasterKey = null;
> +
> + byte[] KDCenc = null;
> + byte[] KDCmac = null;
> + byte[] KDCkek = null;
> +
> + SymmetricKey old_mac_sym_key = null;
> + SymmetricKey old_enc_sym_key = null;
> + SymmetricKey old_kek_sym_key = null;
> +
> + SymmetricKey encKey = null;
> + SymmetricKey macKey = null;
> + SymmetricKey kekKey = null;
> +
> + // The final answer
> + byte[] output = null;
> +
> + if (oldMasterKeyName == null || oldKeyInfo == null || newKeyInfo == null
> + || keySet == null) {
> + throw new EBaseException(method + "Invalid input!");
> + }
> +
> + if (oldKeyInfo.length < 2 || newKeyInfo.length < 2) {
> + throw new EBaseException(method + " Invalid input length for keyinfo versions.");
> + }
> +
> + String fullNewMasterKeyName = getFullMasterKeyName(newMasterKeyName);
> + String fullOldMasterKeyName = getFullMasterKeyName(oldMasterKeyName);
> +
> + CryptoManager cm = null;
> + CryptoToken token = null;
> + CryptoToken newToken = null;
> + try {
> + cm = CryptoManager.getInstance();
> + token = returnTokenByName(tokenName, cm);
> + if (newTokenName != null) {
> + newToken = returnTokenByName(newTokenName, cm);
> + }
> + } catch (NotInitializedException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> +
> + } catch (NoSuchTokenException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + try {
> + if (newToken != null) {
> + masterKey = getSymKeyByName(newToken, fullNewMasterKeyName);
> + }
> + oldMasterKey = getSymKeyByName(token, fullOldMasterKeyName);
> + } catch (EBaseException e) {
> + masterKey = null;
> + CMS.debug(method + " Master key is null, possibly ok in moving from keyset 2 to 1");
> +
> + if (oldMasterKey == null) {
> + throw new EBaseException(method + " Can't retrieve old master key!");
> + }
> + }
> +
> + SecureChannelProtocol.debugByteArray(oldKeyInfo, " oldKeyInfo: ");
> + SecureChannelProtocol.debugByteArray(newKeyInfo, " newKeyInfo: ");
> +
> + byte oldKeyVersion = oldKeyInfo[0];
> + byte newKeyVersion = newKeyInfo[0];
> +
> + byte[] context = null;
> +
> + if (nistSP800_108KdfUseCuidAsKdd == true) {
> + context = CUIDValue;
> + } else {
> + context = KDD;
> + }
> +
> + // We may need either or both of these
> +
> + StandardKDF standardKDF = new StandardKDF(this);
> + NistSP800_108KDF nistKDF = new NistSP800_108KDF(this);
> +
> + KDCenc = standardKDF.getDiversificationData(KDD, SecureChannelProtocol.encType);
> + KDCmac = standardKDF.getDiversificationData(KDD, SecureChannelProtocol.macType);
> + KDCkek = standardKDF.getDiversificationData(KDD, SecureChannelProtocol.kekType);
> +
> + if (protocol == PROTOCOL_ONE) {
> + if (checkForDeveloperKeySet(oldMasterKeyName) == true) {
> + CMS.debug(method + " Developer key set case: ");
> + } else {
> + CMS.debug(method + " Not Developer key set case: ");
> +
> + if (NistSP800_108KDF.useThisKDF(nistSP800_108KdfOnKeyVersion, oldKeyVersion)) {
> + CMS.debug(method + " NistSP800_108KDF code: Using NIST SP800-108 KDF.");
> +
> + Map<String, SymmetricKey> keys = null;
> + try {
> + keys = nistKDF.computeCardKeys(oldMasterKey, context, token);
> + } catch (EBaseException e) {
> + CMS.debug(method + "Can't compute card keys! " + e);
> + throw e;
> + }
> +
> + old_enc_sym_key = keys.get(SecureChannelProtocol.encType);
> + old_mac_sym_key = keys.get(SecureChannelProtocol.macType);
> + old_kek_sym_key = keys.get(SecureChannelProtocol.kekType);
> +
> + if (old_enc_sym_key == null || old_mac_sym_key == null || old_kek_sym_key == null) {
> + throw new EBaseException(method + " Can't derive session keys with Nist KDF.");
> + }
> +
> + } else {
> + CMS.debug(method + " ComputeSessionKey NistSP800_108KDF code: Using original KDF.");
> +
> + old_kek_sym_key = standardKDF.computeCardKey(masterKey, KDCkek, token, PROTOCOL_ONE);
> + }
> +
> + }
> +
> + /* special case #01#01 */
> + if (fullNewMasterKeyName != null && fullNewMasterKeyName.equals("#01#01"))
> + {
> + CMS.debug(method + " Special case dev key set for DiversifyKey!");
> +
> + encKey = returnDeveloperSymKey(token, SecureChannelProtocol.encType, keySet, null);
> + macKey = returnDeveloperSymKey(token, SecureChannelProtocol.macType, keySet, null);
> + kekKey = returnDeveloperSymKey(token, SecureChannelProtocol.kekType, keySet, null);
> + } else {
> + CMS.debug(method + " Compute card key on token case ! For new key version");
> +
> + if (NistSP800_108KDF.useThisKDF(nistSP800_108KdfOnKeyVersion, newKeyVersion)) {
> + CMS.debug(method + " NistSP800_108KDF code: Using NIST SP800-108 KDF. For new key version.");
> +
> + Map<String, SymmetricKey> keys = null;
> + try {
> + keys = nistKDF.computeCardKeys(masterKey, context, token);
> + } catch (EBaseException e) {
> + CMS.debug(method + "Can't compute card keys! For new key version. " + e);
> + throw e;
> + }
> +
> + encKey = keys.get(SecureChannelProtocol.encType);
> + macKey = keys.get(SecureChannelProtocol.macType);
> + kekKey = keys.get(SecureChannelProtocol.kekType);
> +
> + } else {
> + CMS.debug(method
> + + " ComputeSessionKey NistSP800_108KDF code: Using original KDF. For new key version.");
> +
> + encKey = standardKDF.computeCardKeyOnSoftToken(masterKey, KDCenc, protocol);
> + macKey = standardKDF.computeCardKeyOnSoftToken(masterKey, KDCmac, protocol);
> + kekKey = standardKDF.computeCardKeyOnSoftToken(masterKey, KDCkek, protocol);
> + }
> +
> + if (encKey == null || macKey == null || kekKey == null) {
> + throw new EBaseException(method
> + + " Can't derive session keys with selected KDF. For new key version.");
> + }
> +
> + }
> +
> + } else if (protocol == PROTOCOL_TWO) {
> + throw new EBaseException(method + " SCP 02 not yet supported here.");
> + } else {
> + throw new EBaseException(method + " Unsupported protocol verison.");
> + }
> +
> + boolean showKeysForDebug = false;
> +
> + if (showKeysForDebug == true) {
> + try {
> + SecureChannelProtocol.debugByteArray(encKey.getKeyData(), "DiversifyKey: new encKey: ");
> + SecureChannelProtocol.debugByteArray(macKey.getKeyData(), "DiversifyKey: new macKey:");
> + SecureChannelProtocol.debugByteArray(kekKey.getKeyData(), "DiversifyKey: new kekKey");
> + } catch (NotExtractableException e) {
> + CMS.debug(method + " Can not display debugging info for key");
> + }
> + }
> +
> + if (old_kek_sym_key != null) {
> +
> + CMS.debug(method + " old kek sym key is not null");
> + output = createKeySetDataWithSymKeys(newKeyVersion, (byte[]) null,
> + old_kek_sym_key,
> + encKey,
> + macKey,
> + kekKey,
> + protocol, tokenName);
> +
> + } else {
> +
> + CMS.debug(method + " old kek sym key is null");
> + old_kek_sym_key = returnDeveloperSymKey(token, SecureChannelProtocol.kekType, keySet, kekKeyArray);
> + output = createKeySetDataWithSymKeys(newKeyVersion, (byte[]) null,
> + old_kek_sym_key,
> + encKey,
> + macKey,
> + kekKey,
> + protocol, tokenName);
> +
> + }
> +
> + return output;
> + }
> +
> + private byte[] createKeySetDataWithSymKeys(byte newKeyVersion, byte[] old_kek_key_array,
> + SymmetricKey old_kek_sym_key,
> + SymmetricKey encKey, SymmetricKey macKey, SymmetricKey kekKey, byte protocol, String tokenName)
> + throws EBaseException {
> +
> + SymmetricKey wrappingKey = null;
> +
> + String method = "SecureChannelProtocol.createKeySetDataWithSymKeys:";
> +
> + byte alg = (byte) 0x81;
> +
> + byte[] output = null;
> +
> + if (encKey == null || macKey == null || kekKey == null || tokenName == null) {
> + throw new EBaseException(method + " Invalid input data!");
> + }
> +
> + CryptoManager cm = null;
> + CryptoToken token = null;
> + try {
> + cm = CryptoManager.getInstance();
> + token = returnTokenByName(tokenName, cm);
> + } catch (NotInitializedException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> +
> + } catch (NoSuchTokenException e) {
> + CMS.debug(method + " " + e);
> + throw new EBaseException(e);
> + }
> +
> + SymmetricKey encKey16 = null;
> + SymmetricKey macKey16 = null;
> + SymmetricKey kekKey16 = null;
> +
> + byte[] encrypted_enc_key = null;
> + byte[] encrypted_mac_key = null;
> + byte[] encrypted_kek_key = null;
> +
> + byte[] keycheck_enc_key = null;
> + byte[] keycheck_mac_key = null;
> + byte[] keycheck_kek_key = null;
> +
> + if (protocol == PROTOCOL_ONE) {
> + if (old_kek_sym_key == null) {
> + CMS.debug(method + " Using old kek key array.");
> + wrappingKey = unwrapSymKeyOnToken(token, old_kek_key_array, false);
> + } else {
> + CMS.debug(method + " Using input old key key sym key.");
> + wrappingKey = old_kek_sym_key;
> + }
> +
> + alg = (byte) 0x81;
> + encKey16 = extractDes2FromDes3(encKey, tokenName);
> + macKey16 = extractDes2FromDes3(macKey, tokenName);
> + kekKey16 = extractDes2FromDes3(kekKey, tokenName);
> +
> + encrypted_enc_key = this.wrapSessionKey(tokenName, encKey16, wrappingKey);
> + encrypted_mac_key = this.wrapSessionKey(tokenName, macKey16, wrappingKey);
> + encrypted_kek_key = this.wrapSessionKey(tokenName, kekKey16, wrappingKey);
> +
> + keycheck_enc_key = this.computeKeyCheck(encKey, tokenName);
> + keycheck_mac_key = this.computeKeyCheck(macKey, tokenName);
> + keycheck_kek_key = this.computeKeyCheck(kekKey, tokenName);
> +
> + debugByteArray(keycheck_enc_key, " Keycheck enc key: ");
> + debugByteArray(keycheck_mac_key, " Keycheck mac key: ");
> + debugByteArray(keycheck_kek_key, " KeyCheck kek key: ");
> +
> + } else if (protocol == PROTOCOL_TWO) {
> + alg = (byte) 0x80;
> + throw new EBaseException(method + " SCP 02 not yet implemented!");
> + } else {
> + throw new EBaseException(method + " Invalid SCP version requested!");
> + }
> +
> + // Compose the final key set data byte array
> +
> + byte[] b1 = new byte[] { alg, 0x10 };
> + byte[] b2 = new byte[] { 0x3 };
> +
> + ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
> +
> + try {
> + outputStream.write(newKeyVersion);
> + outputStream.write(b1);
> + outputStream.write(encrypted_enc_key);
> + outputStream.write(b2);
> + outputStream.write(keycheck_enc_key);
> +
> + outputStream.write(b1);
> + outputStream.write(encrypted_mac_key);
> + outputStream.write(b2);
> + outputStream.write(keycheck_mac_key);
> +
> + outputStream.write(b1);
> + outputStream.write(encrypted_kek_key);
> + outputStream.write(b2);
> + outputStream.write(keycheck_kek_key);
> +
> + output = outputStream.toByteArray();
> +
> + } catch (IOException e) {
> + throw new EBaseException(method + " Can't compose final output byte array!");
> + }
> +
> + SecureChannelProtocol.debugByteArray(output, " Final output to createKeySetData: ");
> +
> + return output;
> + }
> +
> + private String getFullMasterKeyName(String masterKeyName)
> + {
> + if (masterKeyName == null)
> + {
> + return null;
> + }
> +
> + String fullMasterKeyName = null;
> +
> + fullMasterKeyName = "";
> +
> + if (masterKeyName.length() > 0) {
> + fullMasterKeyName += masterKeyName;
> + }
> +
> + return fullMasterKeyName;
> + }
> +
> + private boolean checkForDeveloperKeySet(String keyInfo)
> + {
> + if (keyInfo == null)
> + return true;
> +
> + //SCP01 or SCP02
> + if (keyInfo.equals("#01#01") || keyInfo.equals("#FF#01"))
> + return true;
> +
> + //SCP02
> + if (keyInfo.equals("#01#02") || keyInfo.equals("#FF#02"))
> + return true;
> +
> + return false;
> + }
> +
> + public static void setDefaultPrefix(String masterkeyPrefix) {
> + if (SecureChannelProtocol.masterKeyPrefix == null) {
> + SecureChannelProtocol.masterKeyPrefix = masterkeyPrefix;
> + }
> + }
> +
> + public byte[] encryptData(String selectedToken, String keyNickName, byte[] data, byte[] keyInfo,
> + byte nistSP800_108KdfOnKeyVersion, boolean nistSP800_108KdfUseCuidAsKdd, byte[] xCUID, byte[] xKDD,
> + byte[] kekKeyArray, String useSoftToken_s, String keySet) throws EBaseException {
> +
> + String method = "SecureChannelProtocol.encryptData:";
> +
> + CMS.debug(method + " Entering ....");
> +
> + String transportKeyName = SecureChannelProtocol.getSharedSecretKeyName(null);
> +
> + if (keyInfo == null || keySet == null || (keyInfo == null || keyInfo.length < 2)) {
> + throw new EBaseException(method + "Invalid input!");
> + }
> +
> + if (xCUID == null || xCUID.length <= 0) {
> + throw new EBaseException(method + "CUID invalid size!");
> + }
> +
> + if (xKDD == null || xKDD.length != NistSP800_108KDF.KDD_SIZE_BYTES) {
> + throw new EBaseException(method + "KDD invalid size!");
> + }
> +
> + SymmetricKey kekKey = computeSessionKey_SCP01(kekType, selectedToken, keyNickName, null,
> + null, keyInfo, nistSP800_108KdfOnKeyVersion, nistSP800_108KdfUseCuidAsKdd, xCUID, xKDD,
> + kekKeyArray, useSoftToken_s, keySet, transportKeyName);
> +
> + byte[] output = computeDes3EcbEncryption(kekKey, selectedToken, data);
> +
> + debugByteArray(output, " encryptData: Output: ");
> +
> + return output;
> + }
> +
> +}
> \ No newline at end of file
> diff --git a/base/server/cms/src/com/netscape/cms/servlet/tks/StandardKDF.java b/base/server/cms/src/com/netscape/cms/servlet/tks/StandardKDF.java
> new file mode 100644
> index 0000000..2dd145d
> --- /dev/null
> +++ b/base/server/cms/src/com/netscape/cms/servlet/tks/StandardKDF.java
> @@ -0,0 +1,170 @@
> +package com.netscape.cms.servlet.tks;
> +
> +import java.security.InvalidKeyException;
> +
> +import org.mozilla.jss.crypto.CryptoToken;
> +import org.mozilla.jss.crypto.SymmetricKey;
> +import org.mozilla.jss.crypto.SymmetricKeyDeriver;
> +import org.mozilla.jss.crypto.TokenException;
> +
> +import sun.security.pkcs11.wrapper.PKCS11Constants;
> +
> +import com.netscape.certsrv.apps.CMS;
> +import com.netscape.certsrv.base.EBaseException;
> +
> +public class StandardKDF extends KDF {
> + SecureChannelProtocol protocol = null;
> +
> + StandardKDF(SecureChannelProtocol protocol) {
> + this.protocol = protocol;
> + }
> +
> + public SymmetricKey computeCardKey(SymmetricKey masterKey, byte[] derivationData, CryptoToken token, int protocol)
> + throws EBaseException {
> +
> + String method = "StandardKDF.computeCardKeys:";
> +
> + SymmetricKey result = null;
> +
> + CMS.debug(method + " entering ...");
> +
> + if (masterKey == null || derivationData == null
> + || derivationData.length != SecureChannelProtocol.DES2_LENGTH || token == null) {
> +
> + throw new EBaseException(method + " Invlalid input parameters!");
> + }
> +
> + SymmetricKeyDeriver encryptDes3;
> + try {
> + encryptDes3 = token.getSymmetricKeyDeriver();
> +
> + encryptDes3.initDerive(
> + masterKey, /* PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA */4354L, derivationData, null,
> + PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16);
> +
> + SymmetricKey derivedKey = encryptDes3.derive();
> +
> +
> + CMS.debug(method + " derived card key first 16 :" + derivedKey);
> +
> + byte[] extracted = derivedKey.getEncoded();
> + SecureChannelProtocol.debugByteArray(extracted, " Derived key 16.");
> +
> + long bitPosition = 0;
> +
> + byte[] param = SecureChannelProtocol.longToBytes(bitPosition);
> +
> + SymmetricKeyDeriver extract8 = token.getSymmetricKeyDeriver();
> + extract8.initDerive(
> + derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null,
> + PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8);
> +
> +
> + SymmetricKey extracted8 = extract8.derive();
> + CMS.debug(method + " extracted8 key: " + extracted8);
> + byte [] extracted8Bytes = extracted8.getEncoded();
> + SecureChannelProtocol.debugByteArray(extracted8Bytes, " Derived key 8.");
> +
> +
> + SymmetricKeyDeriver concat = token.getSymmetricKeyDeriver();
> + concat.initDerive(
> + derivedKey,extracted8, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null,
> + PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0);
> +
> + result = concat.derive();
> + CMS.debug(method + " final 24 byte key: " + result);
> + byte [] extracted24Bytes = result.getEncoded();
> + SecureChannelProtocol.debugByteArray(extracted24Bytes, " Derived key 24.");
> +
> + } catch (TokenException | InvalidKeyException e) {
> + CMS.debug(method + "Unable to derive the key with the proper mechanism!");
> + throw new EBaseException(e);
> + }
> +
> + return result;
> +
> + }
> +
> + public SymmetricKey computeCardKeyOnSoftToken(SymmetricKey masterKey, byte[] data, int protocol)
> + throws EBaseException {
> + String method = "StandardKDF.computeCardKeys:";
> +
> + CMS.debug(method + " entering...");
> +
> + if (masterKey == null || data == null) {
> + throw new EBaseException(method + " Invlalid input parameters!");
> + }
> +
> + CryptoToken token = this.protocol.getCryptoManger().getInternalKeyStorageToken();
> +
> + return this.computeCardKey(masterKey, data, token, protocol);
> + }
> +
> + public SymmetricKey computeCardKeyOnToken(SymmetricKey masterKey, byte[] data, int protocol) throws EBaseException {
> + String method = "StandardKDF.computeCardKeys:";
> +
> + if (masterKey == null || data == null) {
> + throw new EBaseException(method + " Invlalid input parameters!");
> + }
> +
> + CryptoToken token = masterKey.getOwningToken();
> +
> + return this.computeCardKey(masterKey, data, token, protocol);
> + }
> +
> + public byte[] getDiversificationData(byte[] context, String type) throws EBaseException {
> +
> + String method = "StandardKDF.getDiversificationData:";
> +
> + CMS.debug(method + " entering ...");
> +
> + if (context == null || type == null) {
> + throw new EBaseException(method + "Invalid input parameters!");
> + }
> +
> + byte[] KDC = new byte[SecureChannelProtocol.DES2_LENGTH];
> +
> + // BYTE *lastTwoBytesOfAID = (BYTE *)cuidValue;
> + // BYTE *ICFabricationDate = (BYTE *)cuidValue + 2;
> + // BYTE *ICSerialNumber = (BYTE *)cuidValue + 4
> + // BYTE *ICBatchIdentifier = (BYTE *)cuidValue + 8;
> +
> + // Last 2 bytes of AID
> + KDC[0] = context[0];
> + KDC[1] = context[1];
> + KDC[2] = context[4 + 0];
> + KDC[3] = context[4 + 1];
> + KDC[4] = context[4 + 2];
> + KDC[5] = context[4 + 3];
> + KDC[6] = (byte) 0xF0;
> + KDC[7] = 0x01;
> + KDC[8] = context[0];
> + KDC[9] = context[1];
> + KDC[10] = context[4 + 0];
> + KDC[11] = context[4 + 1];
> + KDC[12] = context[4 + 2];
> + KDC[13] = context[4 + 3];
> + KDC[14] = 0x0F;
> + KDC[15] = 0x01;
> +
> + if (type.equals(SecureChannelProtocol.encType))
> + return KDC;
> +
> + KDC[6] = (byte) 0xF0;
> + KDC[7] = 0x02;
> + KDC[14] = 0x0F;
> + KDC[15] = 0x02;
> + if (type.equals(SecureChannelProtocol.macType))
> + return KDC;
> +
> + KDC[6] = (byte) 0xF0;
> + KDC[7] = 0x03;
> + KDC[14] = 0x0F;
> + KDC[15] = 0x03;
> + if (type.equals(SecureChannelProtocol.kekType))
> + return KDC;
> +
> + return KDC;
> +
> + }
> +}
> 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 83b8bef..db4cd55 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
> @@ -35,6 +35,7 @@ import org.mozilla.jss.CryptoManager.NotInitializedException;
> import org.mozilla.jss.crypto.CryptoToken;
> import org.mozilla.jss.crypto.KeyWrapAlgorithm;
> import org.mozilla.jss.crypto.KeyWrapper;
> +import org.mozilla.jss.crypto.SymmetricKey;
> import org.mozilla.jss.crypto.X509Certificate;
> import org.mozilla.jss.pkcs11.PK11SymKey;
>
> @@ -213,7 +214,10 @@ public class TokenServlet extends CMSServlet {
> }
> }
>
> - SessionKey.SetDefaultPrefix(masterKeyPrefix);
> + CMS.debug("Setting masteter keky prefix to: " + masterKeyPrefix);
> +
> + SecureChannelProtocol.setDefaultPrefix(masterKeyPrefix);
> + /*SessionKey.SetDefaultPrefix(masterKeyPrefix);*/
>
> } catch (Exception e) {
> e.printStackTrace();
> @@ -354,7 +358,6 @@ public class TokenServlet extends CMSServlet {
>
> String rKDD = req.getParameter(IRemoteRequest.TOKEN_KDD);
>
> -
> String rKeyInfo = req.getParameter(IRemoteRequest.TOKEN_KEYINFO);
>
> if ((rKeyInfo == null) || (rKeyInfo.equals(""))) {
> @@ -561,7 +564,8 @@ public class TokenServlet extends CMSServlet {
> selectedToken, keyNickName,
> keyInfo,
> nistSP800_108KdfOnKeyVersion, // AC: KDF SPEC CHANGE - pass in configuration file value
> - nistSP800_108KdfUseCuidAsKdd,xCUID,xKDD, macKeyArray, sequenceCounter, derivationConstant, useSoftToken_s, keySet,
> + nistSP800_108KdfUseCuidAsKdd, xCUID, xKDD, macKeyArray, sequenceCounter, derivationConstant,
> + useSoftToken_s, keySet,
> transportKeyName);
>
> if (session_key == null) {
> @@ -889,9 +893,9 @@ public class TokenServlet extends CMSServlet {
>
> boolean serversideKeygen = false;
> byte[] drm_trans_wrapped_desKey = null;
> - PK11SymKey desKey = null;
> + SymmetricKey desKey = null;
> // PK11SymKey kek_session_key;
> - PK11SymKey kek_key;
> + SymmetricKey kek_key;
>
> IConfigStore sconfig = CMS.getConfigStore();
> boolean isCryptoValidate = true;
> @@ -1092,14 +1096,15 @@ public class TokenServlet extends CMSServlet {
> + keySet + ".mac_key"));
> CMS.debug("TokenServlet about to try ComputeSessionKey selectedToken="
> + selectedToken + " keyNickName=" + keyNickName);
> - session_key = SessionKey.ComputeSessionKey(
> - selectedToken, keyNickName, card_challenge,
> - 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);
> +
> + SecureChannelProtocol protocol = new SecureChannelProtocol();
> + SymmetricKey macKey = protocol.computeSessionKey_SCP01(SecureChannelProtocol.macType,
> + selectedToken,
> + keyNickName, card_challenge,
> + host_challenge, keyInfo, nistSP800_108KdfOnKeyVersion, nistSP800_108KdfUseCuidAsKdd, xCUID,
> + xKDD, macKeyArray, useSoftToken_s, keySet, transportKeyName);
> +
> + session_key = protocol.wrapSessionKey(selectedToken, macKey, null);
>
> if (session_key == null) {
> CMS.debug("TokenServlet:Tried ComputeSessionKey, got NULL ");
> @@ -1110,14 +1115,13 @@ public class TokenServlet extends CMSServlet {
> byte encKeyArray[] =
> com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks."
> + keySet + ".auth_key"));
> - enc_session_key = SessionKey.ComputeEncSessionKey(
> - selectedToken, keyNickName, card_challenge,
> - 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);
> + SymmetricKey encKey = protocol.computeSessionKey_SCP01(SecureChannelProtocol.encType,
> + selectedToken,
> + keyNickName, card_challenge, host_challenge, keyInfo, nistSP800_108KdfOnKeyVersion,
> + nistSP800_108KdfUseCuidAsKdd, xCUID, xKDD, encKeyArray, useSoftToken_s, keySet,
> + transportKeyName);
> +
> + enc_session_key = protocol.wrapSessionKey(selectedToken, encKey, null);
>
> if (enc_session_key == null) {
> CMS.debug("TokenServlet:Tried ComputeEncSessionKey, got NULL ");
> @@ -1140,14 +1144,11 @@ public class TokenServlet extends CMSServlet {
> com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks."
> + keySet + ".kek_key"));
>
> - kek_key = SessionKey.ComputeKekKey(
> - selectedToken, keyNickName, card_challenge,
> - 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);
> + kek_key = protocol.computeSessionKey_SCP01(SecureChannelProtocol.kekType, selectedToken,
> + keyNickName, card_challenge,
> + host_challenge, keyInfo, nistSP800_108KdfOnKeyVersion, nistSP800_108KdfUseCuidAsKdd,
> + xCUID,
> + xKDD, kekKeyArray, useSoftToken_s, keySet, transportKeyName);
>
> CMS.debug("TokenServlet: called ComputeKekKey");
>
> @@ -1177,11 +1178,12 @@ public class TokenServlet extends CMSServlet {
> if (useSoftToken_s.equals("true")) {
> CMS.debug("TokenServlet: key encryption key generated on internal");
> //cfu audit here? sym key gen
> - desKey = SessionKey.GenerateSymkey("internal");
> +
> + desKey = protocol.generateSymKey("internal");
> //cfu audit here? sym key gen done
> } else {
> CMS.debug("TokenServlet: key encryption key generated on " + selectedToken);
> - desKey = SessionKey.GenerateSymkey(selectedToken);
> + desKey = protocol.generateSymKey(selectedToken);
> }
> if (desKey != null) {
> // AC: KDF SPEC CHANGE - Output using CUID and KDD
> @@ -1204,9 +1206,9 @@ public class TokenServlet extends CMSServlet {
> * and discard the last 8 bytes before it encrypts.
> * This is done so that the applet can digest it
> */
> - byte[] encDesKey =
> - SessionKey.ECBencrypt(kek_key,
> - desKey);
> +
> + byte[] encDesKey = protocol.ecbEncrypt(kek_key, desKey, selectedToken);
> +
> /*
> CMS.debug("computeSessionKey:encrypted desKey size = "+encDesKey.length);
> CMS.debug(encDesKey);
> @@ -1216,8 +1218,8 @@ public class TokenServlet extends CMSServlet {
> com.netscape.cmsutil.util.Utils.SpecialEncode(encDesKey);
>
> // get keycheck
> - byte[] keycheck =
> - SessionKey.ComputeKeyCheck(desKey);
> +
> + byte[] keycheck = protocol.computeKeyCheck(desKey, selectedToken);
> /*
> CMS.debug("computeSessionKey:keycheck size = "+keycheck.length);
> CMS.debug(keycheck);
> @@ -1266,28 +1268,21 @@ public class TokenServlet extends CMSServlet {
> byte authKeyArray[] =
> com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks."
> + keySet + ".auth_key"));
> - host_cryptogram = SessionKey.ComputeCryptogram(
> - selectedToken, keyNickName, card_challenge,
> - 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);
> +
> + host_cryptogram = protocol.computeCryptogram_SCP01(selectedToken, keyNickName, card_challenge,
> + host_challenge,
> + xkeyInfo, nistSP800_108KdfOnKeyVersion, nistSP800_108KdfUseCuidAsKdd, xCUID, xKDD, 0,
> + authKeyArray, useSoftToken_s, keySet, transportKeyName);
>
> if (host_cryptogram == null) {
> CMS.debug("TokenServlet:Tried ComputeCryptogram, got NULL ");
> throw new Exception("Can't compute host cryptogram!");
>
> }
> - card_crypto = SessionKey.ComputeCryptogram(
> - selectedToken, keyNickName, card_challenge,
> - 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);
> +
> + card_crypto = protocol.computeCryptogram_SCP01(selectedToken, keyNickName, card_challenge,
> + host_challenge, xkeyInfo, nistSP800_108KdfOnKeyVersion, nistSP800_108KdfUseCuidAsKdd,
> + xCUID, xKDD, 1, authKeyArray, useSoftToken_s, keySet, transportKeyName);
>
> if (card_crypto == null) {
> CMS.debug("TokenServlet:Tried ComputeCryptogram, got NULL ");
> @@ -1302,6 +1297,10 @@ public class TokenServlet extends CMSServlet {
> }
> input_card_crypto =
> com.netscape.cmsutil.util.Utils.SpecialDecode(rcard_cryptogram);
> +
> + SecureChannelProtocol.debugByteArray(input_card_crypto, "input_card_crypto");
> + SecureChannelProtocol.debugByteArray(card_crypto, "card_crypto");
> +
> if (card_crypto.length == input_card_crypto.length) {
> for (int i = 0; i < card_crypto.length; i++) {
> if (card_crypto[i] != input_card_crypto[i]) {
> @@ -1782,18 +1781,28 @@ public class TokenServlet extends CMSServlet {
> byte kekKeyArray[] =
> com.netscape.cmsutil.util.Utils.SpecialDecode(sconfig.getString("tks." + keySet + ".kek_key"));
>
> + SecureChannelProtocol secProtocol = new SecureChannelProtocol();
> // AC: KDF SPEC CHANGE - check for error reading settings
> if (missingSetting_exception == null) {
> - KeySetData = SessionKey.DiversifyKey(oldSelectedToken,
> - newSelectedToken, oldKeyNickName,
> - 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
> - (protocol == 2) ? xWrappedDekKey : kekKeyArray, useSoftToken_s, keySet, (byte) protocol);
> + if (protocol == 1) {
> + KeySetData = secProtocol.diversifyKey(oldSelectedToken,
> + newSelectedToken, oldKeyNickName,
> + 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
> + (protocol == 2) ? xWrappedDekKey : kekKeyArray, useSoftToken_s, keySet, (byte) protocol);
> +
> + } else if (protocol == 2) {
> + KeySetData = SessionKey.DiversifyKey(oldSelectedToken, newSelectedToken, oldKeyNickName,
> + newKeyNickName, xkeyInfo,
> + xnewkeyInfo, nistSP800_108KdfOnKeyVersion, nistSP800_108KdfUseCuidAsKdd, xCUID, xKDD,
> + (protocol == 2) ? xWrappedDekKey : kekKeyArray, useSoftToken_s, keySet, (byte) protocol);
> + }
> + SecureChannelProtocol.debugByteArray(KeySetData, " New keyset data: ");
>
> if (KeySetData == null || KeySetData.length <= 1) {
> CMS.getLogger().log(ILogger.EV_AUDIT,
> @@ -1817,7 +1826,6 @@ public class TokenServlet extends CMSServlet {
>
> } // ! missingParam
>
> -
> String value = "";
> String status = "0";
>
> @@ -2092,7 +2100,9 @@ public class TokenServlet extends CMSServlet {
> // AC: KDF SPEC CHANGE - check for error reading settings
> if (missingSetting_exception == null) {
>
> - encryptedData = SessionKey.EncryptData(
> + SecureChannelProtocol protocol = new SecureChannelProtocol();
> +
> + encryptedData = protocol.encryptData(
> 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
> @@ -2100,6 +2110,8 @@ public class TokenServlet extends CMSServlet {
> xKDD, // AC: KDF SPEC CHANGE - pass in KDD so symkey can make decision about which value (KDD,CUID) to use
> kekKeyArray, useSoftToken_s, keySet);
>
> + SecureChannelProtocol.debugByteArray(encryptedData, "New Encrypt Data: ");
> +
> // AC: KDF SPEC CHANGE - Log both CUID and KDD
>
> CMS.getLogger().log(ILogger.EV_AUDIT,
> diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
> index 01cde76..ed762c8 100644
> --- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
> +++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java
> @@ -33,6 +33,8 @@ import java.util.List;
> import java.util.Map;
> import java.util.Set;
>
> +import netscape.security.x509.RevocationReason;
> +
> import org.dogtagpki.server.tps.TPSSession;
> import org.dogtagpki.server.tps.TPSSubsystem;
> import org.dogtagpki.server.tps.authentication.AuthUIParameter;
> @@ -77,7 +79,10 @@ import org.dogtagpki.tps.msg.StatusUpdateRequestMsg;
> import org.dogtagpki.tps.msg.TPSMessage;
> import org.dogtagpki.tps.msg.TokenPDURequestMsg;
> import org.dogtagpki.tps.msg.TokenPDUResponseMsg;
> +import org.mozilla.jss.CryptoManager;
> import org.mozilla.jss.CryptoManager.NotInitializedException;
> +import org.mozilla.jss.crypto.CryptoToken;
> +import org.mozilla.jss.crypto.SymmetricKey;
> import org.mozilla.jss.pkcs11.PK11SymKey;
>
> import com.netscape.certsrv.apps.CMS;
> @@ -90,10 +95,9 @@ import com.netscape.certsrv.base.IConfigStore;
> import com.netscape.certsrv.common.Constants;
> import com.netscape.certsrv.logging.ILogger;
> import com.netscape.certsrv.tps.token.TokenStatus;
> +import com.netscape.cms.servlet.tks.SecureChannelProtocol;
> import com.netscape.symkey.SessionKey;
>
> -import netscape.security.x509.RevocationReason;
> -
> public class TPSProcessor {
>
> public static final int RESULT_NO_ERROR = 0;
> @@ -598,7 +602,7 @@ public class TPSProcessor {
> PK11SymKey cmacSessionKeySCP02 = null;
> PK11SymKey rmacSessionKeySCP02 = null;
>
> - PK11SymKey sharedSecret = null;
> + SymmetricKey sharedSecret = null;
>
> //Sanity checking
>
> @@ -624,16 +628,30 @@ public class TPSProcessor {
> TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
> }
>
> + SecureChannelProtocol protocol = new SecureChannelProtocol();
> +
> + String tokenName = "Internal Key Storage Token";
> +
> + CryptoManager cm = null;
> + CryptoToken token = null;
> +
> + String sharedSecretName = null;
> try {
> - sharedSecret = getSharedSecretTransportKey(connId);
> + sharedSecretName = getSharedSecretTransportKeyName(connId);
> + SecureChannelProtocol.setSharedSecretKeyName(sharedSecretName);
> +
> + cm = protocol.getCryptoManger();
> + token = protocol.returnTokenByName(tokenName, cm);
> +
> + sharedSecret = SecureChannelProtocol.getSymKeyByName(token, sharedSecretName);
> +
> + // sharedSecret = getSharedSecretTransportKey(connId);
> } catch (Exception e) {
> CMS.debug(e);
> throw new TPSException("TPSProcessor.generateSecureChannel: Can't get shared secret key!: " + e,
> TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
> }
>
> - String tokenName = "Internal Key Storage Token";
> -
> if (platProtInfo.isGP201() || platProtInfo.isSCP01()) {
>
> resp = engine.computeSessionKey(keyDiversificationData, appletInfo.getCUID(), keyInfoData,
> @@ -652,18 +670,28 @@ public class TPSProcessor {
> TPSBuffer sessionKeyWrapped = resp.getSessionKey();
> TPSBuffer encSessionKeyWrapped = resp.getEncSessionKey();
>
> - sessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
> - sessionKeyWrapped.toBytesArray());
> + /* sessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, (PK11SymKey) sharedSecret,
> + sessionKeyWrapped.toBytesArray()); */
> +
> +
> + sessionKey = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret, sessionKeyWrapped.toBytesArray(), false);
> +
> +
> +
> +
>
> if (sessionKey == null) {
> CMS.debug("TPSProcessor.generateSecureChannel: Can't extract session key!");
> throw new TPSException("TPSProcessor.generateSecureChannel: Can't extract session key!",
> TPSStatus.STATUS_ERROR_SECURE_CHANNEL);
> }
> +
> CMS.debug("TPSProcessor.generateSecureChannel: retrieved session key: " + sessionKey);
>
> - encSessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
> - encSessionKeyWrapped.toBytesArray());
> + /* encSessionKey = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName,(PK11SymKey) sharedSecret,
> + encSessionKeyWrapped.toBytesArray()); */
> +
> + encSessionKey = (PK11SymKey) protocol.unwrapWrappedSymKeyOnToken(token, sharedSecret,encSessionKeyWrapped.toBytesArray(),false);
>
> if (encSessionKey == null) {
> CMS.debug("TPSProcessor.generateSecureChannel: Can't extract enc session key!");
> @@ -716,7 +744,7 @@ public class TPSProcessor {
> connId, getSelectedTokenType(), getSelectedKeySet());
>
> TPSBuffer encSessionKeyWrappedSCP02 = respEnc02.getSessionKey();
> - encSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
> + encSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, (PK11SymKey) sharedSecret,
> encSessionKeyWrappedSCP02.toBytesArray());
>
> if (encSessionKeySCP02 == null) {
> @@ -731,7 +759,7 @@ public class TPSProcessor {
>
> TPSBuffer cmacSessionKeyWrappedSCP02 = respCMac02.getSessionKey();
>
> - cmacSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
> + cmacSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName,(PK11SymKey) sharedSecret,
> cmacSessionKeyWrappedSCP02.toBytesArray());
>
> if (cmacSessionKeySCP02 == null) {
> @@ -746,7 +774,7 @@ public class TPSProcessor {
>
> TPSBuffer rmacSessionKeyWrappedSCP02 = respRMac02.getSessionKey();
>
> - rmacSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
> + rmacSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName,(PK11SymKey) sharedSecret,
> rmacSessionKeyWrappedSCP02.toBytesArray());
>
> if (rmacSessionKeySCP02 == null) {
> @@ -763,7 +791,7 @@ public class TPSProcessor {
>
> TPSBuffer dekSessionKeyWrappedSCP02 = respDek02.getSessionKey();
>
> - dekSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName, sharedSecret,
> + dekSessionKeySCP02 = SessionKey.UnwrapSessionKeyWithSharedSecret(tokenName,(PK11SymKey) sharedSecret,
> dekSessionKeyWrappedSCP02.toBytesArray());
>
> if (dekSessionKeySCP02 == null) {
> @@ -2714,7 +2742,7 @@ public class TPSProcessor {
>
> }
>
> - protected PK11SymKey getSharedSecretTransportKey(String connId) throws TPSException, NotInitializedException {
> + protected String getSharedSecretTransportKeyName(String connId) throws TPSException {
>
> IConfigStore configStore = CMS.getConfigStore();
> String sharedSecretName = null;
> @@ -2729,10 +2757,21 @@ public class TPSProcessor {
>
> }
>
> + CMS.debug("TPSProcessor.getSharedSecretTransportKeyName: calculated key name: " + sharedSecretName);
> +
> + return sharedSecretName;
> +
> + }
> + protected PK11SymKey getSharedSecretTransportKey(String connId) throws TPSException, NotInitializedException {
> +
> +
> + String sharedSecretName = getSharedSecretTransportKeyName(connId);
> +
> CMS.debug("TPSProcessor.getSharedSecretTransportKey: calculated key name: " + sharedSecretName);
>
> String symmKeys = null;
> boolean keyPresent = false;
> +
> try {
> symmKeys = SessionKey.ListSymmetricKeys("internal");
> CMS.debug("TPSProcessor.getSharedSecretTransportKey: symmKeys List: " + symmKeys);
> @@ -2878,7 +2917,7 @@ public class TPSProcessor {
> result.setFreeMem(free_mem);
>
> CMS.debug("TPSProcessor.getAppletInfo: cuid: " + result.getCUIDhexString() + " msn: " + result.getMSNString()
> - + " major version: " + result.getMinorVersion() + " minor version: " + result.getMinorVersion()
> + + " major version: " + result.getMajorVersion() + " minor version: " + result.getMinorVersion()
> + " App major version: " + result.getAppMajorVersion() + " App minor version: "
> + result.getAppMinorVersion());
>
> @@ -3269,14 +3308,15 @@ public class TPSProcessor {
> * In the mean time, resolution is to save up the result the first
> * time it is called
> */
> - if (aInfo.getFinalAppletVersion() != null) {
> - return aInfo.getFinalAppletVersion();
> - }
>
> if (aInfo == null) {
> throw new TPSException("TPSProcessor.formatCurrentAppletVersion: ", TPSStatus.STATUS_ERROR_CONTACT_ADMIN);
> }
>
> + if (aInfo.getFinalAppletVersion() != null) {
> + return aInfo.getFinalAppletVersion();
> + }
> +
> TPSBuffer build_id = getAppletVersion();
> if (build_id == null) {
> CMS.debug(method + " getAppletVersion returning null");
> @@ -3284,7 +3324,7 @@ public class TPSProcessor {
> }
> String build_idStr = build_id.toHexStringPlain();
>
> - String finalVersion = aInfo.getAppMajorVersion() + "." + aInfo.getAppMinorVersion() + "." + build_idStr;
> + String finalVersion = aInfo.getMajorVersion() + "." + aInfo.getMinorVersion() + "." + build_idStr;
>
> finalVersion = finalVersion.toLowerCase();
>
> @@ -3852,6 +3892,7 @@ public class TPSProcessor {
> String status,
> String info) {
> String auditType = "LOGGING_SIGNED_AUDIT_TOKEN_OP_REQUEST_6";
> +
> String auditMessage = CMS.getLogMessage(
> auditType,
> session.getIpAddress(),
> @@ -3952,7 +3993,7 @@ public class TPSProcessor {
> String auditType = "";
> switch (status) {
> case "success":
> - auditType = "LOGGING_SIGNED_AUDIT_TOKEN_KEY_CHANGEOVER_SUCCESS_9";
> + auditType = "LOGGING_SIGNED_AUDIT_TOKEN_KEY_CHANGEOVER_SUCCESS_10";
> break;
> default:
> auditType = "LOGGING_SIGNED_AUDIT_TOKEN_KEY_CHANGEOVER_FAILURE_10";
> --
> 2.5.0
>
> _______________________________________________
> Pki-devel mailing list
> Pki-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/pki-devel
More information about the Pki-devel
mailing list