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 <[email protected]> > 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 > [email protected] > https://www.redhat.com/mailman/listinfo/pki-devel _______________________________________________ Pki-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/pki-devel
