summaryrefslogtreecommitdiffstats
path: root/base/symkey
diff options
context:
space:
mode:
Diffstat (limited to 'base/symkey')
-rw-r--r--base/symkey/src/com/netscape/symkey/Buffer.cpp6
-rw-r--r--base/symkey/src/com/netscape/symkey/EncryptData.cpp5
-rw-r--r--base/symkey/src/com/netscape/symkey/SessionKey.cpp604
-rw-r--r--base/symkey/src/com/netscape/symkey/SessionKey.java17
-rw-r--r--base/symkey/src/com/netscape/symkey/SymKey.cpp446
-rw-r--r--base/symkey/src/com/netscape/symkey/SymKey.h5
6 files changed, 937 insertions, 146 deletions
diff --git a/base/symkey/src/com/netscape/symkey/Buffer.cpp b/base/symkey/src/com/netscape/symkey/Buffer.cpp
index 5c687c5f5..6241534a5 100644
--- a/base/symkey/src/com/netscape/symkey/Buffer.cpp
+++ b/base/symkey/src/com/netscape/symkey/Buffer.cpp
@@ -171,10 +171,10 @@ Buffer::dump() const
unsigned int i;
for( i=0; i < len; ++i ) {
- printf("%02x ", buf[i]);
- if( i % 16 == 15 ) printf("\n");
+ PR_fprintf(PR_STDOUT,"%02x ", buf[i]);
+ if( i % 16 == 15 ) PR_fprintf(PR_STDOUT,"\n");
}
- printf("\n");
+ PR_fprintf(PR_STDOUT,"\n");
}
static const char hextbl[] = {
diff --git a/base/symkey/src/com/netscape/symkey/EncryptData.cpp b/base/symkey/src/com/netscape/symkey/EncryptData.cpp
index 3963b5026..cebc0bb25 100644
--- a/base/symkey/src/com/netscape/symkey/EncryptData.cpp
+++ b/base/symkey/src/com/netscape/symkey/EncryptData.cpp
@@ -219,7 +219,6 @@ Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstr
if (masterKey != NULL)
{
-
// ---------------------------------
// AC KDF SPEC CHANGE: Determine which KDF to use.
//
@@ -279,11 +278,9 @@ Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstr
GetDiversificationData(kddValue,kekData,kek);
// AC: Derives the Kek key for the token.
- kekKey = ComputeCardKeyOnToken(masterKey,kekData);
+ kekKey = ComputeCardKeyOnToken(masterKey,kekData,1);
} // endif use original KDF
- // ---------------------------------
-
if (kekKey != NULL)
{
diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.cpp b/base/symkey/src/com/netscape/symkey/SessionKey.cpp
index 2c146730f..610928099 100644
--- a/base/symkey/src/com/netscape/symkey/SessionKey.cpp
+++ b/base/symkey/src/com/netscape/symkey/SessionKey.cpp
@@ -349,6 +349,101 @@ JSS_PK11_getSymKeyPtr(JNIEnv *env, jobject symKeyObject, PK11SymKey **ptr)
SYM_KEY_PROXY_SIG, (void**)ptr);
}
#endif //STEAL_JSS
+
+
+/* ToDo: fully support nistSP800 in next ticket
+*/
+PK11SymKey *DeriveKeySCP02(PK11SymKey *cardKey, const Buffer& sequenceCounter, const Buffer& derivationConstant)
+{
+
+ PK11SymKey *key = NULL;
+ PK11SymKey *master = NULL;
+ unsigned char message[KEYLENGTH] = {0};
+ unsigned char derivationData[DES3_LENGTH] = {0};
+
+ PRBool invalid_mechanism = PR_TRUE;
+ SECStatus s = SECFailure;
+ int len = 0;
+ int i = 0;
+
+ SECItem *secParam = NULL;
+
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ SECItem param = { siBuffer, NULL, 0 };
+
+ unsigned char icv[EIGHT_BYTES] = { 0 };
+
+ if( sequenceCounter == NULL || derivationConstant == NULL ||
+ sequenceCounter.size() != 2 || derivationConstant.size() != 2 ||
+ cardKey == NULL) {
+ PR_fprintf(PR_STDERR,"In DeriveKeySCP02! Error invalid input data!\n");
+ goto done;
+ }
+
+ PR_fprintf(PR_STDOUT,"In DeriveKeySCP02! \n");
+ PR_fprintf(PR_STDOUT,"In DeriveKeySCP02! seqCounter[0] : %d sequenceCounter [1] : %d \n", sequenceCounter[0], sequenceCounter[1]);
+ PR_fprintf(PR_STDOUT,"In DeriveKeySCP02! derivationConstant[0] : %x derivationConstant[1] : %x \n", derivationConstant[0], derivationConstant[1]);
+
+ master = cardKey;
+
+ message[0] = (unsigned char) derivationConstant[0];
+ message[1] = (unsigned char) derivationConstant[1];
+ message[2] = (unsigned char) sequenceCounter[0];
+ message[3] = (unsigned char) sequenceCounter[1];
+
+
+ //ToDo use the new NSS provided derive mechanisms for this operation
+ if(invalid_mechanism == PR_FALSE) {
+ // Use derive mechanisms
+ } else {
+
+ //Use encryption method
+ param.data = (unsigned char *) &icv;
+ param.len = 8;
+ secParam = PK11_ParamFromIV(CKM_DES3_CBC_PAD, &param);
+ context = PK11_CreateContextBySymKey(CKM_DES3_CBC_PAD, CKA_ENCRYPT, master, secParam);
+ if(context == NULL) {
+ goto done;
+ }
+ s = PK11_CipherOp(context,&derivationData[0] , &len, EIGHT_BYTES, &message[0], EIGHT_BYTES);
+
+ if (s != SECSuccess) { goto done; }
+
+ s = PK11_CipherOp(context, &derivationData[EIGHT_BYTES], &len, EIGHT_BYTES, &message[EIGHT_BYTES], EIGHT_BYTES);
+ if (s != SECSuccess) { goto done; }
+
+ for(i = 0;i < EIGHT_BYTES ;i++)
+ {
+ derivationData[i+KEYLENGTH] = derivationData[i];
+ }
+
+ key = CreateUnWrappedSymKeyOnToken( slot, master, &derivationData[0] , DES3_LENGTH, PR_FALSE );
+
+ PR_fprintf(PR_STDOUT,"In DeriveKeySCP02! calculated key: %p \n", key);
+ }
+
+ done:
+
+ memset(derivationData, 0, sizeof derivationData);
+ if ( context != NULL) {
+ PK11_DestroyContext(context, PR_TRUE);
+ context = NULL;
+ }
+
+ if (slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if (secParam) {
+ SECITEM_FreeItem(secParam, PR_TRUE);
+ secParam = NULL;
+ }
+
+ return key;
+}
+
// Function takes wither a symkey OR a keybuffer (for the default keyset case)
// To derive a new key.
PK11SymKey *DeriveKey(PK11SymKey *cardKey, const Buffer& hostChallenge, const Buffer& cardChallenge)
@@ -567,6 +662,369 @@ finish:
}
+//ToDo: Fix this to conform the nistSP800
+//=================================================================================
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_RASessionKey
+ * Method: ComputeSessionKeySCP02
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKeySCP02
+ (JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring, jstring);
+#ifdef __cplusplus
+}
+#endif
+#define KEYLENGTH 16
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_ComputeSessionKeySCP02(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName, jbyteArray keyInfo, jbyteArray CUID, jbyteArray devKeyArray, jbyteArray sequenceCounter, jbyteArray derivationConstant, jstring useSoftToken_s, jstring keySet, jstring sharedSecretKeyName)
+{
+ /* hardcode permanent dev key */
+ jbyte *dev_key = NULL;
+ if (devKeyArray != NULL) {
+ dev_key = (jbyte*)(env)->GetByteArrayElements(devKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ SECItem wrappedKeyItem = { siBuffer, NULL , 0};
+ SECItem noParams = { siBuffer, NULL, 0 };
+ SECStatus wrapStatus = SECFailure;
+
+
+ char *keyNameChars=NULL;
+ char *tokenNameChars=NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ PK11SymKey *symkey = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *masterKey = NULL;
+
+ PK11SymKey *devSymKey = NULL;
+ PK11SymKey *symkey16 = NULL;
+ PK11SymKey *devKey = NULL;
+
+
+ BYTE devData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+ const char *devKeyName = NULL;
+
+ const char *macName = "mac";
+ const char *encName = "enc";
+ const char *kekName = "kek";
+
+ keyType kType = mac;
+
+ /* Derive vars */
+
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+
+ /* Java object return vars */
+
+ jbyteArray handleBA=NULL;
+ jbyte *handleBytes=NULL;
+
+ jbyte * cuidValue = NULL;
+
+ jbyte *sc = NULL;
+ int sc_len = 0;
+
+ int dc_len = 0;
+ jbyte *dc = NULL;
+
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+
+ Buffer devBuff( ( BYTE *) dev_key , KEYLENGTH );
+
+ char *keySetStringChars = NULL;
+ if( keySet != NULL ) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ char *sharedSecretKeyNameChars = NULL;
+
+ if( sharedSecretKeyName != NULL ) {
+ sharedSecretKeyNameChars = (char *) (env)->GetStringUTFChars( sharedSecretKeyName, NULL);
+ }
+
+ char *sharedSecretKeyNameString = sharedSecretKeyNameChars;
+
+ if ( sharedSecretKeyNameString == NULL ) {
+ sharedSecretKeyNameString = (char *) TRANSPORT_KEY_NAME;
+ }
+
+ GetSharedSecretKeyName(sharedSecretKeyNameString);
+
+ if( sequenceCounter != NULL) {
+ sc = (jbyte*)(env)->GetByteArrayElements( sequenceCounter, NULL);
+ sc_len = (env)->GetArrayLength(sequenceCounter);
+ }
+
+ if( sc == NULL || sc_len != 2) {
+ goto done;
+ }
+
+ if( derivationConstant != NULL) {
+ dc = (jbyte*)(env)->GetByteArrayElements( derivationConstant, NULL);
+ dc_len = (env)->GetArrayLength( derivationConstant);
+ }
+
+ if( dc == NULL || dc_len != 2) {
+ goto done;
+ }
+
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ){
+ goto done;
+ }
+
+ if ( CUID != NULL ) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ if(tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ }
+
+ if(keyName)
+ {
+ keyNameChars = (char *)(env)->GetStringUTFChars(keyName, NULL);
+ strncpy(keyname,keyNameChars,KEYNAMELENGTH);
+ (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
+ }else
+ GetKeyName(keyVersion,keyname);
+
+ //Get key type from derivation constant
+ switch((unsigned char) dc[1]) {
+ case 0x1 :
+ kType = mac;
+ devKeyName = macName;
+ break;
+
+ case 0x82:
+ kType = enc;
+ devKeyName = encName;
+ break;
+
+ case 0x81:
+ kType = kek;
+ devKeyName = kekName;
+ break;
+
+ default:
+ kType = mac;
+ devKeyName = macName;
+ break;
+ }
+
+ GetDiversificationData(cuidValue,devData,kType);
+
+ PR_fprintf(PR_STDOUT,"In SessionKey.ComputeSessionKeySCP02! keyName %s keyVersion[0] %d keyVersion[1] %d \n",keyname,(int) keyVersion[0],(int) keyVersion[1]);
+
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 ) ||
+ (keyVersion[0] == -1 && keyVersion[1] == 0x1))
+
+ {
+ /* default manufacturers key */
+
+ devSymKey = ReturnDeveloperSymKey(slot, (char *) devKeyName , keySetString, devBuff);
+
+ if( devSymKey == NULL ) {
+ goto done;
+ }
+
+ PR_fprintf(PR_STDOUT,"SessionKey.ComputeSessionKeySCP02! sc[0] : %d sc[1] : %d \n", sc[0], sc[1]);
+ symkey = DeriveKeySCP02( //Util::DeriveKey(
+ devSymKey, Buffer((BYTE*)sc, sc_len), Buffer((BYTE*)dc, dc_len));
+
+ if(symkey == NULL)
+ {
+ goto done;
+ }
+
+ //In the enc key case create the auth as well, we may need it later.
+
+ if(kType == enc) {
+
+ PK11SymKey *authKey = NULL;
+
+ authKey = ReturnDeveloperSymKey(slot, (char *) "auth" , keySetString, devBuff);
+
+ if(authKey == NULL)
+ {
+ goto done;
+ }
+
+ PK11_FreeSymKey(authKey);
+ authKey = NULL;
+
+ }
+
+ }else
+ {
+ PR_fprintf(PR_STDOUT,"SessionKey.ComputeSessionKeySCP02! Attempting with master key. \n");
+ masterKey = ReturnSymKey( slot,keyname);
+ if(masterKey == NULL)
+ {
+ goto done;
+ }
+
+ devKey =ComputeCardKeyOnToken(masterKey,devData,2);
+ if(devKey == NULL)
+ {
+ goto done;
+ }
+
+ symkey = DeriveKeySCP02(devKey, Buffer((BYTE*)sc, sc_len), Buffer((BYTE*)dc, dc_len));
+
+ if(symkey == NULL)
+ {
+ goto done;
+ }
+ }
+ //Now wrap the key for the trip back to TPS with shared secret transport key
+
+ symkey16 = NULL;
+ transportKey = ReturnSymKey( internal, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ PR_fprintf(PR_STDERR, "Can't find shared secret transport key! \n");
+ goto done;
+ }
+
+ handleBA = (env)->NewByteArray( KEYLENGTH);
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ symkey16 = PK11_Derive(symkey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
+ CKA_DERIVE, 16);
+ if ( !symkey16 ) {
+ PR_fprintf(PR_STDERR,"Can't derive 16 byte key from 24 byte symkey! \n");
+ goto done;
+ }
+
+ wrappedKeyItem.data = (unsigned char *) handleBytes;
+ wrappedKeyItem.len = KEYLENGTH;
+ wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, transportKey, symkey16, &wrappedKeyItem);
+
+ if(wrapStatus == SECFailure )
+ {
+ PR_fprintf(PR_STDERR, "Can't wrap session key! Error: %d \n", PR_GetError());
+ }
+
+done:
+
+ if( slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ if( internal ) {
+ PK11_FreeSlot(internal);
+ internal = NULL;
+ }
+
+ if ( symkey ) {
+ PK11_FreeSymKey( symkey);
+ symkey = NULL;
+ }
+
+ if ( transportKey ) {
+ PK11_FreeSymKey( transportKey );
+ transportKey = NULL;
+ }
+
+ if ( symkey16 ) {
+ PK11_FreeSymKey( symkey16 );
+ symkey16 = NULL;
+ }
+
+ if( masterKey ) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if( devKey ) {
+ PK11_FreeSymKey( devKey);
+ devKey = NULL;
+ }
+
+ if( devSymKey ) {
+ PK11_FreeSymKey( devSymKey );
+ devSymKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ if( sharedSecretKeyNameChars ) {
+ (env)->ReleaseStringUTFChars(sharedSecretKeyName, (const char *)sharedSecretKeyNameChars);
+ sharedSecretKeyNameChars = NULL;
+ }
+
+ if ( handleBytes != NULL) {
+ (env)->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ }
+
+ if ( sc != NULL) {
+ (env)->ReleaseByteArrayElements(sequenceCounter, sc, JNI_ABORT);
+ }
+
+ if ( dc != NULL) {
+ (env)->ReleaseByteArrayElements(derivationConstant, dc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL) {
+ (env)->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if ( cuidValue != NULL) {
+ (env)->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ if( dev_key != NULL) {
+ (env)->ReleaseByteArrayElements(devKeyArray, dev_key, JNI_ABORT);
+ }
+
+ if (wrapStatus != SECFailure ){
+ return handleBA;
+ }else{
+ return NULL;
+ }
+
+}
+
+
+
//=================================================================================
#ifdef __cplusplus
extern "C"
@@ -595,7 +1053,7 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
return NULL;
}
- char input[KEYLENGTH];
+ unsigned char input[KEYLENGTH] = {0};
int i = 0;
SECItem wrappedKeyItem = { siBuffer, NULL , 0};
@@ -762,7 +1220,7 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
}else
GetKeyName(keyVersion,keyname);
- PR_fprintf(PR_STDOUT,"In SessionKey.ComputeSessionKey! \n");
+ PR_fprintf(PR_STDOUT,"In SessionKey.ComputeSessionKey! keyName %s keyVersion[0] %d keyVersion[1] %d \n",keyname,(int) keyVersion[0],(int) keyVersion[1]);
if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 && strcmp( keyname, "#01#01") == 0) ||
(keyVersion[0] == -1 && strstr(keyname, "#FF")))
@@ -781,13 +1239,13 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
}else
{
+ PR_fprintf(PR_STDOUT,"In SessionKey.ComputeSessionKey! Upgraded keyset mode. \n");
masterKey = ReturnSymKey( slot,keyname);
if(masterKey == NULL)
{
goto done;
}
-
// ---------------------------------
// AC KDF SPEC CHANGE: Determine which KDF to use.
//
@@ -847,17 +1305,12 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
GetDiversificationData(kddValue,macData,mac);//keytype is mac
// AC: Derives the mac key for the token.
- macKey =ComputeCardKeyOnToken(masterKey,macData);
+ macKey =ComputeCardKeyOnToken(masterKey,macData,1);
} // endif use original KDF
// ---------------------------------
- if(macKey == NULL)
- {
- goto done;
- }
-
// AC: This computes the GP session key using the card-specific MAC key we previously derived.
symkey = DeriveKey(macKey, Buffer((BYTE*)hc, hc_len), Buffer((BYTE*)cc, cc_len));
@@ -1030,7 +1483,7 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
return NULL;
}
- char input[KEYLENGTH];
+ unsigned char input[KEYLENGTH] = {0};
int i = 0;
SECItem wrappedKeyItem = { siBuffer, NULL , 0};
@@ -1205,7 +1658,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
goto done;
}
-
// ---------------------------------
// AC KDF SPEC CHANGE: Determine which KDF to use.
//
@@ -1265,12 +1717,11 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
GetDiversificationData(kddValue,encData,enc);
// AC: Derives the enc key for the token.
- encKey =ComputeCardKeyOnToken(masterKey,encData);
+ encKey =ComputeCardKeyOnToken(masterKey,encData,1);
} // endif use original KDF
// ---------------------------------
-
if(encKey == NULL) {
goto done;
}
@@ -1446,7 +1897,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute
keySetString = (char *) DEFKEYSET_NAME;
}
- char input[KEYLENGTH];
+ unsigned char input[KEYLENGTH] = {0};
int i;
jobject keyObj = NULL;
@@ -1575,7 +2026,6 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute
goto done;
}
-
// ---------------------------------
// AC KDF SPEC CHANGE: Determine which KDF to use.
//
@@ -1635,12 +2085,11 @@ extern "C" JNIEXPORT jobject JNICALL Java_com_netscape_symkey_SessionKey_Compute
GetDiversificationData(kddValue,kekData,kek);//keytype is kek
// AC: Derives the mac key for the token.
- kekKey =ComputeCardKeyOnToken(masterKey,kekData);
+ kekKey =ComputeCardKeyOnToken(masterKey,kekData,1);
} // endif use original KDF
// ---------------------------------
-
}
if(kekKey == NULL) {
@@ -2049,7 +2498,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
goto done;
}
-
// ---------------------------------
// AC KDF SPEC CHANGE: Determine which KDF to use.
//
@@ -2109,12 +2557,11 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Comp
GetDiversificationData(kddValue,authData,enc);
// AC: Derives the mac key for the token.
- authKey = ComputeCardKeyOnToken(masterKey,authData);
+ authKey = ComputeCardKeyOnToken(masterKey,authData,1);
} // endif use original KDF
// ---------------------------------
-
if (authKey == NULL)
{
goto done;
@@ -2297,14 +2744,24 @@ Java_com_netscape_symkey_SessionKey_ECBencrypt
goto finish;
}
+ PR_fprintf(PR_STDOUT,"In SessionKey: ECBencrypt! 16 byte key derived.... \n");
+
//Wrap the new 16 bit key with the input symkey.
wrappedKeyItem.data = (unsigned char *) handleBytes;
wrappedKeyItem.len = dlen;
+
+ PR_fprintf(PR_STDOUT,"In SessionKey: ECBencrypt! About to wrap des key with sym key.\n");
wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, symkey, newdeskey, &wrappedKeyItem);
if( wrapStatus == SECSuccess) {
PR_fprintf(PR_STDERR, "ECBencrypt wrapStatus %d wrappedKeySize %d \n", wrapStatus, wrappedKeyItem.len);
+
+ PR_fprintf(PR_STDOUT," ECBencrypt wrapped data: \n");
+ Buffer wrappedDataBuf(wrappedKeyItem.data,wrappedKeyItem.len);
+ wrappedDataBuf.dump();
+
+
} else {
PR_fprintf(PR_STDERR, "ECBecrypt wrap failed! Error %d \n", PR_GetError());
}
@@ -2328,6 +2785,105 @@ extern "C"
{
#endif
/*
+ * Class: com_netscape_cms_servlet_tks_DeriveDESKeyFrom3DesKey
+ * Method: DeriveDESKeyFrom3DesKey
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jobject JNICALL
+ Java_com_netscape_symkey_SessionKey_DeriveDESKeyFrom3DesKey
+ (JNIEnv*, jclass,jstring ,jobject,jlong);
+#ifdef __cplusplus
+}
+#endif
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_netscape_symkey_SessionKey_DeriveDESKeyFrom3DesKey
+(JNIEnv* env, jclass this2, jstring tokenName, jobject des3Key,jlong alg)
+{
+ PK11SymKey * des3 = NULL;
+ PK11SymKey * des = NULL;
+ PK11SymKey * desFinal = NULL;
+ PRStatus r = PR_FAILURE;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ jobject keyObj = NULL;
+ char *tokenNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+
+ if( des3Key == NULL) {
+ goto loser;
+ }
+
+ if(alg != CKM_DES_CBC && alg != CKM_DES_ECB) {
+ PR_fprintf(PR_STDOUT,"SessionKey.DeriveDESKeyFrom3DesKey invalid alg!.. \n");
+ goto loser;
+ }
+
+ if (tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ if ( tokenNameChars && !strcmp(tokenNameChars, "internal")) {
+ slot = PK11_GetInternalSlot();
+ } else {
+ slot = ReturnSlot(tokenNameChars);
+ }
+
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ } else {
+ slot = PK11_GetInternalKeySlot();
+ }
+
+ if(slot == NULL) {
+ goto loser;
+ }
+
+ r = JSS_PK11_getSymKeyPtr(env, des3Key, &des3);
+
+ if (r != PR_SUCCESS) {
+ PR_fprintf(PR_STDOUT,"SessionKey: DeriveDESKeyFrom3DesKey Unable to get input session 3des sym key! \n");
+ goto loser;
+ }
+
+ /* Now create a DES key with the first 8 bytes of the input 3des key */
+
+ // Extract first eight bytes from generated key into another key.
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+
+ des = PK11_Derive(des3, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, alg , CKA_DERIVE, 8);
+ if (des == NULL ) {
+ goto loser;
+ }
+
+ //Make sure we move this to the orig token, in case it got moved by NSS
+ //during the derive phase.
+
+ desFinal = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, des);
+
+
+ /* wrap the sesssion in java object. */
+ keyObj = JSS_PK11_wrapSymKey(env, &desFinal, NULL);
+
+loser:
+
+ if ( slot != NULL ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if ( des != NULL) {
+ PK11_FreeSymKey(des);
+ des = NULL;
+ }
+ return keyObj;
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
* Class: com_netscape_cms_servlet_tks_UnwrapSessionKeyWithSharedSecret
* Method: UnwrapSessionKeyWithSharedSecret
* Signature: ([B[B[B[B)[B
@@ -2396,6 +2952,7 @@ Java_com_netscape_symkey_SessionKey_UnwrapSessionKeyWithSharedSecret
wrappedItem.data = (unsigned char *) sessionKeyBytes;
wrappedItem.len = sessionKeyLen;
+
sessionKey = PK11_UnwrapSymKey(sharedSecret,
CKM_DES3_ECB,SecParam, &wrappedItem,
CKM_DES3_ECB,
@@ -2437,6 +2994,12 @@ loser:
sessionKey = NULL;
}
+ if (SecParam) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+
+
// Don't free finalKey ptr because wrapping routine takes that out of our hands.
return keyObj;
@@ -2467,7 +3030,6 @@ Java_com_netscape_symkey_SessionKey_GetSymKeyByName
char *tokenNameChars = NULL;
char *keyNameChars = NULL;
PK11SlotInfo *slot = NULL;
- CK_OBJECT_HANDLE keyhandle = 0;
PR_fprintf(PR_STDOUT,"In SessionKey GetSymKeyByName!\n");
diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.java b/base/symkey/src/com/netscape/symkey/SessionKey.java
index d44cc5479..7a32de60c 100644
--- a/base/symkey/src/com/netscape/symkey/SessionKey.java
+++ b/base/symkey/src/com/netscape/symkey/SessionKey.java
@@ -74,6 +74,19 @@ public class SessionKey {
// external calls from RA
public static native byte[] ComputeKeyCheck(PK11SymKey desKey); /* byte data[] ); */
+ //SCP02/GP211 methods
+
+ public static native byte[] ComputeSessionKeySCP02(String tokenName,
+ String keyName,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] devKeyArray,
+ byte[] sequenceCounter,
+ byte[] derivationConstant,
+ String useSoftToken,
+ String keySet,
+ String sharedSecretKeyName);
+
public static native byte[] ComputeSessionKey(String tokenName,
String keyName,
byte[] card_challenge,
@@ -173,7 +186,7 @@ public class SessionKey {
byte[] CUIDValue,
byte[] KDD, // AC: KDF SPEC CHANGE
byte[] kekKeyArray,
- String useSoftToken, String keySet);
+ String useSoftToken, String keySet,byte protocol);
// internal calls from config TKS keys tab
public static native String GenMasterKey(String token,
@@ -197,4 +210,6 @@ public class SessionKey {
// with functionality only available now in NSS. This is all to preserve exact functional parity with the current TKS.
public static native PK11SymKey UnwrapSessionKeyWithSharedSecret(String tokenName, PK11SymKey sharedSecret,
byte[] sessionKeyArray);
+
+ public static native PK11SymKey DeriveDESKeyFrom3DesKey(String tokenName, PK11SymKey key3Des,long alg);
}
diff --git a/base/symkey/src/com/netscape/symkey/SymKey.cpp b/base/symkey/src/com/netscape/symkey/SymKey.cpp
index 6e206db54..8890ac3b5 100644
--- a/base/symkey/src/com/netscape/symkey/SymKey.cpp
+++ b/base/symkey/src/com/netscape/symkey/SymKey.cpp
@@ -91,6 +91,8 @@ char masterKeyNickName[KEYNAMELENGTH];
char masterNewKeyNickName[KEYNAMELENGTH];
char sharedSecretSymKeyName[KEYNAMELENGTH] = { 0 };
+static int checkForDeveloperKeySet(char * keyInfo);
+
//=================================================================================
#ifdef __cplusplus
extern "C"
@@ -509,10 +511,10 @@ static secuPWData pwdata = { secuPWData::PW_NONE, 0 };
* Internal token is required when we are doing key diversification
* where raw key material needs to be accessed
*/
-PK11SymKey *ComputeCardKeyOnSoftToken(PK11SymKey *masterKey, unsigned char *data)
+PK11SymKey *ComputeCardKeyOnSoftToken(PK11SymKey *masterKey, unsigned char *data, int protocol)
{
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
- PK11SymKey *key = ComputeCardKey(masterKey, data, slot);
+ PK11SymKey *key = ComputeCardKey(masterKey, data, slot,protocol);
if( slot != NULL) {
PK11_FreeSlot(slot);
slot = NULL;
@@ -521,7 +523,7 @@ PK11SymKey *ComputeCardKeyOnSoftToken(PK11SymKey *masterKey, unsigned char *data
return key;
}
-PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot)
+PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot,int protocol)
{
PK11SymKey *key = NULL;
PK11Context *context = NULL;
@@ -533,9 +535,12 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
static SECItem noParams = { siBuffer, NULL, 0 };
unsigned char *in = data;
PK11SymKey *tmpkey = NULL;
+ unsigned char icv[EIGHT_BYTES] = { 0 };
unsigned char wrappedkey[DES3_LENGTH];
SECItem wrappeditem = { siBuffer, NULL, 0 };
+ PR_fprintf(PR_STDOUT,"ComputeCardKey: protocol %d.\n",protocol);
+
keyData = (unsigned char*)malloc(keysize);
for (i = 0;i < keysize; i++)
@@ -550,7 +555,7 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT,
masterKey,
- &noParams);
+ &noParams);
if (context == NULL) {
PR_fprintf(PR_STDERR,"ComputeCardKey: failed to create context.\n");
@@ -591,7 +596,7 @@ PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotI
PR_fprintf(PR_STDERR,"ComputeCardKey: failed to keygen. \n");
goto done;
}
-
+
context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT,
tmpkey,
&noParams);
@@ -635,10 +640,10 @@ done:
return key;
}
-PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data)
+PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data, int protocol)
{
PK11SlotInfo *slot = PK11_GetSlotFromKey(masterKey);
- PK11SymKey *key = ComputeCardKey(masterKey, data, slot);
+ PK11SymKey *key = ComputeCardKey(masterKey, data, slot,protocol);
if( slot) {
PK11_FreeSlot(slot);
@@ -787,13 +792,14 @@ PRStatus ComputeKeyCheckWithSymKey(PK11SymKey * newKey, Buffer& output)
}
// Create key set data with the help of either a provided old_keyk_ke2_sym key or key buffer (for the Default keyset case).
-PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek_key2, PK11SymKey *old_kek_key2_sym, PK11SymKey *new_auth_key, PK11SymKey *new_mac_key, PK11SymKey *new_kek_key, Buffer &output)
+PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek_key2, PK11SymKey *old_kek_key2_sym, PK11SymKey *new_auth_key, PK11SymKey *new_mac_key, PK11SymKey *new_kek_key,int protocol, Buffer &output)
{
PRStatus rv = PR_FAILURE;
static SECItem noParams = { siBuffer, NULL, 0 };
PK11SymKey *transportKey = NULL;
PK11SymKey *wrappingKey = NULL;
BYTE masterKeyData[DES3_LENGTH];
+ BYTE alg = 0x81;
/* Wrapping vars */
SECItem wrappedKeyItem = { siBuffer, NULL , 0 };
@@ -819,34 +825,69 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek
Buffer kc_kek_key(3);
Buffer result;
- PR_fprintf(PR_STDOUT,"In CreateKeySetDataWithSymKeys!\n");
+ //Buffer *dumpBuffer = NULL;
+ //int showDerivedKeys = 0;
+
+ PR_fprintf(PR_STDOUT,"In CreateKeySetDataWithSymKeys! Protocol: %d \n",protocol);
if ( new_auth_key == NULL || new_mac_key == NULL || new_kek_key == NULL) {
return rv;
}
slot = PK11_GetSlotFromKey(new_auth_key);
- if ( old_kek_key2_sym == NULL ) { /* perm key mode */
- /* Find transport key, shared secret */
- transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
- if ( transportKey == NULL ) {
- goto done;
+
+ if(protocol == 1) {
+ if ( old_kek_key2_sym == NULL ) { /* perm key mode */
+ /* Find transport key, shared secret */
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
+ if ( transportKey == NULL ) {
+ goto done;
+ }
+
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(masterKeyData, old_kek_key2, KEYLENGTH);
+ memcpy(masterKeyData+16, old_kek_key2, EIGHT_BYTES);
+
+ wrappingKey = CreateUnWrappedSymKeyOnToken( slot, transportKey, masterKeyData, sizeof(masterKeyData), PR_FALSE);
+
+ } else { /* card key mode */
+ PR_fprintf(PR_STDOUT,"In CreateKeySetDataWithSymKeys: SCP01 card key mode.\n");
+ wrappingKey = old_kek_key2_sym;
}
- /* convert 16-byte to 24-byte triple-DES key */
- memcpy(masterKeyData, old_kek_key2, KEYLENGTH);
- memcpy(masterKeyData+16, old_kek_key2, EIGHT_BYTES);
+ } else if(protocol == 2) {
- wrappingKey = CreateUnWrappedSymKeyOnToken( slot, transportKey, masterKeyData, sizeof(masterKeyData), PR_FALSE);
+ PR_fprintf(PR_STDOUT,"In CreateKeySetDataWithSymKeys: Using dekKey from SCP02 for wrapping key.\n");
- } else { /* card key mode */
- wrappingKey = old_kek_key2_sym;
- }
+
+ // Use the unwapped SCP02 DEK sym key pointer.
+ wrappingKey = old_kek_key2_sym;
+
+ } else {
+ PR_fprintf(PR_STDERR,"Invalid protocol %d . \n",protocol);
+ goto done;
+
+ }
//Now derive 16 byte versions of the provided symkeys
authKey16 = PK11_Derive(new_auth_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT,
CKA_DERIVE, 16);
+ /*
+
+ if(showDerivedKeys == 1) {
+ SECItem *keyData = NULL;
+ PK11_ExtractKeyValue( authKey16 );
+ keyData = PK11_GetKeyData(authKey16);
+ dumpBuffer = new Buffer(keyData->data,keyData->len );
+ PR_fprintf(PR_STDERR,"Debug authKey16 data: \n");
+ dumpBuffer->dump();
+ delete dumpBuffer;
+ dumpBuffer = NULL;
+ }
+
+ */
+
if ( authKey16 == NULL ) {
PR_fprintf(PR_STDERR,"Error deriving authKey16. Error %d \n", PR_GetError());
goto done;
@@ -860,13 +901,28 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek
goto done;
}
- macKey16 = PK11_Derive(new_mac_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT, CKA_DERIVE, 16);
+ macKey16 = PK11_Derive(new_mac_key, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT, CKA_DERIVE, 16);
if ( macKey16 == NULL ) {
PR_fprintf(PR_STDERR,"Error deriving macKey16. Error %d \n", PR_GetError());
goto done;
}
+ /*
+
+ if(showDerivedKeys == 1) {
+ SECItem *keyData = NULL;
+ PK11_ExtractKeyValue( macKey16 );
+ keyData = PK11_GetKeyData(macKey16);
+ dumpBuffer = new Buffer(keyData->data,keyData->len );
+ PR_fprintf(PR_STDERR,"Debug macKey16 data: \n");
+ dumpBuffer->dump();
+ delete dumpBuffer;
+ dumpBuffer = NULL;
+ }
+
+ */
+
wrappedKeyItem.data = (unsigned char *) encrypted_mac_key;
wrappedKeyItem.len = encrypted_mac_key.size();
wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, macKey16, &wrappedKeyItem);
@@ -883,6 +939,21 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek
PR_fprintf(PR_STDERR,"Error deriving kekKey16. Error %d \n", PR_GetError());
}
+ /*
+
+ if(showDerivedKeys == 1) {
+ SECItem *keyData = NULL;
+ PK11_ExtractKeyValue( kekKey16 );
+ keyData = PK11_GetKeyData(kekKey16);
+ dumpBuffer = new Buffer(keyData->data,keyData->len );
+ PR_fprintf(PR_STDERR,"Debug kekKey16 data: \n");
+ dumpBuffer->dump();
+ delete dumpBuffer;
+ dumpBuffer = NULL;
+ }
+
+ */
+
wrappedKeyItem.data = (unsigned char *) encrypted_kek_key;
wrappedKeyItem.len = encrypted_mac_key.size();
wrapStatus = PK11_WrapSymKey(CKM_DES3_ECB,&noParams, wrappingKey, kekKey16, &wrappedKeyItem);
@@ -897,18 +968,22 @@ PRStatus CreateKeySetDataWithSymKeys( Buffer &newMasterVer,const Buffer &old_kek
ComputeKeyCheckWithSymKey(new_kek_key, kc_kek_key);
+ if(protocol == 2) {
+ alg = 0x80;
+ } //default at top is 0x81
+
result = newMasterVer +
- Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)alg) +
Buffer(1, (BYTE)0x10) +
encrypted_auth_key +
Buffer(1, (BYTE)0x03) +
kc_auth_key +
- Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)alg) +
Buffer(1, (BYTE)0x10) +
encrypted_mac_key +
Buffer(1, (BYTE)0x03) +
kc_mac_key +
- Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)alg) +
Buffer(1, (BYTE)0x10) +
encrypted_kek_key +
Buffer(1, (BYTE)0x03) +
@@ -1042,13 +1117,13 @@ void getFullName(char * fullMasterKeyName, char * masterKeyNameChars )
// AC: KDF SPEC CHANGE: function signature change - added jstring oldKeyInfo, jbyte nistSP800_108KdfOnKeyVersion, jboolean nistSP800_108KdfUseCuidAsKdd, and jbyteArray KDD
// 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 jbyteArray's
// -- Changed parameter "jstring keyInfo" to "jbyteArray newKeyInfo"
-extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey
-(JNIEnv *, jclass, jstring, jstring, jstring, jstring, jbyteArray, jbyteArray, jbyte, jboolean, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
+//extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey
+//(JNIEnv *, jclass, jstring, jstring, jstring, jstring, jbyteArray, jbyteArray, jbyte, jboolean, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
// AC: KDF SPEC CHANGE: function signature change - added jstring oldKeyInfo, jbyte nistSP800_108KdfOnKeyVersion, jboolean nistSP800_108KdfUseCuidAsKdd, and jbyteArray KDD
// 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 jbyteArray's
// -- Changed parameter "jstring keyInfo" to "jbyteArray newKeyInfo"
-extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey( JNIEnv * env, jclass this2, jstring tokenName,jstring newTokenName, jstring oldMasterKeyName, jstring newMasterKeyName, jbyteArray oldKeyInfo, jbyteArray newKeyInfo, jbyte nistSP800_108KdfOnKeyVersion, jboolean nistSP800_108KdfUseCuidAsKdd, jbyteArray CUIDValue, jbyteArray KDD, jbyteArray kekKeyArray, jstring useSoftToken_s, jstring keySet)
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_DiversifyKey( JNIEnv * env, jclass this2, jstring tokenName,jstring newTokenName, jstring oldMasterKeyName, jstring newMasterKeyName, jbyteArray oldKeyInfo, jbyteArray newKeyInfo, jbyte nistSP800_108KdfOnKeyVersion, jboolean nistSP800_108KdfUseCuidAsKdd, jbyteArray CUIDValue, jbyteArray KDD, jbyteArray kekKeyArray, jstring useSoftToken_s, jstring keySet,jbyte protocol)
{
PK11SymKey *encKey = NULL;
PK11SymKey *macKey = NULL;
@@ -1069,6 +1144,7 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
PK11SymKey* old_mac_sym_key = NULL;
PK11SymKey* old_enc_sym_key = NULL;
PK11SymKey* old_kek_sym_key = NULL;
+ BYTE scp02DekKeyData[DES3_LENGTH];
char *keySetStringChars = NULL;
if ( keySet != NULL ) {
@@ -1106,10 +1182,10 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
Buffer output;
PK11SlotInfo *newSlot =NULL;
char * newTokenNameChars = NULL;
- char *keyInfoChars = NULL;
+ //char *keyInfoChars = NULL;
// AC: KDF SPEC CHANGE: Need to retrieve old key info from JNI.
- char* oldKeyInfoChars = NULL;
+ //char* oldKeyInfoChars = NULL;
// AC: KDF SPEC CHANGE: Convert new setting value to BYTE (unsigned).
BYTE nistSP800_108KdfOnKeyVersion_byte = static_cast<BYTE>(nistSP800_108KdfOnKeyVersion);
@@ -1125,6 +1201,7 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
PK11SymKey * masterKey = NULL;
PK11SymKey * oldMasterKey = NULL;
+ PK11SymKey * transportKey = NULL;
BYTE KDCenc[KEYLENGTH];
BYTE KDCmac[KEYLENGTH];
@@ -1170,7 +1247,7 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
goto done;
}
- PR_fprintf(PR_STDOUT,"In SessionKey.DiversifyKey! \n");
+ PR_fprintf(PR_STDOUT,"In SessionKey.DiversifyKey! Protocol: %d \n", protocol);
// AC: KDF SPEC CHANGE:
// Changed from "cuidValue" to "kddValue".
@@ -1274,106 +1351,106 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
if(newSlot == NULL) {
newSlot = slot;
}
- if(strcmp( oldMasterKeyNameChars, "#01#01") == 0 || strcmp( oldMasterKeyNameChars, "#FF#01") == 0)
- {
- old_kek_key_buff = Buffer((BYTE*)old_kek_key, KEYLENGTH);
+ if(protocol == 1) {
+ if( checkForDeveloperKeySet(oldMasterKeyNameChars ))
+ {
+ old_kek_key_buff = Buffer((BYTE*)old_kek_key, KEYLENGTH);
+ }
+ else
+ {
+ oldMasterKey = ReturnSymKey(slot,fullMasterKeyName);
- // AC: BUGFIX: Remove garbage code.
- // I believe that this code is a no-op as long as the system is working correctly
- // (with the developer keyset data populated in the config file & copied to HSM).
- //
- // Notes:
- // "old_kek_key_buff" appears to only be used if unable to read/load the developer keys into HSM.
- // "old_kek_key_buff" is populated with incorrect data (not appropriate key-length)
- // "output" is overwritten when "CreateKeySetDataWithSymKeys" is called
- //
- // As a result, only when there is some failure (i.e. we execute a "goto" and skip assignment
- // to "output") do we return a keyset data that is 16 bytes in length (the default KEK).
- // This is unlikely to work and even if it does, is a horrible idea as the caller has no way
- // of knowing that we've now essentially inserted a "backdoor" on the token. So, instead of
- // this, we treat #00#00 just like any other "normal" case.
- //
- //}else if(strcmp( oldMasterKeyNameChars, "#00#00") == 0)
- //{
- // /* print Debug message - do not create real keysetdata */
- // old_kek_key_buff = Buffer((BYTE*)"#00#00", 6);
- // output = Buffer((BYTE*)old_kek_key, KEYLENGTH);
+ // AC: BUGFIX: Check for nonexistent master key instead of (potentially) crashing.
+ if (oldMasterKey == NULL){
+ goto done;
+ }
- }
- else
- {
- oldMasterKey = ReturnSymKey(slot,fullMasterKeyName);
+ // ---------------------------------
+ // AC KDF SPEC CHANGE: Determine which KDF to use.
+ //
+ // if old key version meets setting value, use NIST SP800-108 KDF for deriving old keys
+ if (NistSP800_108KDF::useNistSP800_108KDF(nistSP800_108KdfOnKeyVersion_byte, oldKeyVersion) == true){
+
+ PR_fprintf(PR_STDOUT,"DiversifyKey old key NistSP800_108KDF code: Using NIST SP800-108 KDF for old keyset.\n");
+
+ // react to "UseCUIDAsKDD" setting value
+ jbyte* context_jbyte = NULL;
+ jsize context_len_jsize = 0;
+ if (nistSP800_108KdfUseCuidAsKdd == JNI_TRUE){
+ context_jbyte = cuidValue;
+ context_len_jsize = cuidValue_len;
+ }else{
+ context_jbyte = kddValue;
+ context_len_jsize = kddValue_len;
+ }
+ // Converting this way is safe since jbyte is guaranteed to be 8 bits
+ // Of course, this assumes that "char" is 8 bits (not guaranteed, but typical),
+ // but it looks like this assumption is also made in GetDiversificationData
+ const BYTE* const context = reinterpret_cast<const BYTE*>(context_jbyte);
- // AC: BUGFIX: Check for nonexistent master key instead of (potentially) crashing.
- if (oldMasterKey == NULL){
- goto done;
- }
+ // Convert jsize to size_t
+ const size_t context_len = static_cast<size_t>(context_len_jsize);
+ if (context_len > 0x000000FF){ // sanity check (CUID should never be larger than 255 bytes)
+ PR_fprintf(PR_STDERR, "DiversifyKey old key NistSP800_108KDF code: Error; context_len larger than 255 bytes.\n");
+ goto done;
+ }
+ // call NIST SP800-108 KDF routine
+ try{
+ NistSP800_108KDF::ComputeCardKeys(oldMasterKey, context, context_len, &old_enc_sym_key, &old_mac_sym_key, &old_kek_sym_key);
+ }catch(std::runtime_error& ex){
+ PR_fprintf(PR_STDERR, "DiversifyKey old key NistSP800_108KDF code: Exception invoking NistSP800_108KDF::ComputeCardKeys: ");
+ PR_fprintf(PR_STDERR, "%s\n", ex.what() == NULL ? "null" : ex.what());
+ goto done;
+ }catch(...){
+ PR_fprintf(PR_STDERR, "DiversifyKey old key NistSP800_108KDF code: Unknown exception invoking NistSP800_108KDF::ComputeCardKeys.\n");
+ goto done;
+ }
- // ---------------------------------
- // AC KDF SPEC CHANGE: Determine which KDF to use.
- //
- // if old key version meets setting value, use NIST SP800-108 KDF for deriving old keys
- if (NistSP800_108KDF::useNistSP800_108KDF(nistSP800_108KdfOnKeyVersion_byte, oldKeyVersion) == true){
+ // if not a key version where we use the NIST SP800-108 KDF, use the original KDF
+ }else{
- PR_fprintf(PR_STDOUT,"DiversifyKey old key NistSP800_108KDF code: Using NIST SP800-108 KDF for old keyset.\n");
+ PR_fprintf(PR_STDOUT,"DiversifyKey old key NistSP800_108KDF code: Using original KDF for old keyset.\n");
- // react to "UseCUIDAsKDD" setting value
- jbyte* context_jbyte = NULL;
- jsize context_len_jsize = 0;
- if (nistSP800_108KdfUseCuidAsKdd == JNI_TRUE){
- context_jbyte = cuidValue;
- context_len_jsize = cuidValue_len;
- }else{
- context_jbyte = kddValue;
- context_len_jsize = kddValue_len;
- }
+ // AC: Derives the kek key for the token.
+ old_kek_sym_key = ComputeCardKeyOnToken(oldMasterKey,KDCkek,1);
- // Converting this way is safe since jbyte is guaranteed to be 8 bits
- // Of course, this assumes that "char" is 8 bits (not guaranteed, but typical),
- // but it looks like this assumption is also made in GetDiversificationData
- const BYTE* const context = reinterpret_cast<const BYTE*>(context_jbyte);
+ } // endif use original KDF
+ }
- // Convert jsize to size_t
- const size_t context_len = static_cast<size_t>(context_len_jsize);
- if (context_len > 0x000000FF){ // sanity check (CUID should never be larger than 255 bytes)
- PR_fprintf(PR_STDERR, "DiversifyKey old key NistSP800_108KDF code: Error; context_len larger than 255 bytes.\n");
- goto done;
- }
+ } else if(protocol == 2) {
- // call NIST SP800-108 KDF routine
- try{
- NistSP800_108KDF::ComputeCardKeys(oldMasterKey, context, context_len, &old_enc_sym_key, &old_mac_sym_key, &old_kek_sym_key);
- }catch(std::runtime_error& ex){
- PR_fprintf(PR_STDERR, "DiversifyKey old key NistSP800_108KDF code: Exception invoking NistSP800_108KDF::ComputeCardKeys: ");
- PR_fprintf(PR_STDERR, "%s\n", ex.what() == NULL ? "null" : ex.what());
- goto done;
- }catch(...){
- PR_fprintf(PR_STDERR, "DiversifyKey old key NistSP800_108KDF code: Unknown exception invoking NistSP800_108KDF::ComputeCardKeys.\n");
- goto done;
- }
+ Buffer dek_key_buf = Buffer((BYTE*)old_kek_key, 16);
- // if not a key version where we use the NIST SP800-108 KDF, use the original KDF
- }else{
+ PR_fprintf(PR_STDOUT,"DiversifyKey: protocol is 2 import wrapped dek key. \n");
+ dek_key_buf.dump();
+ transportKey = ReturnSymKey( slot, GetSharedSecretKeyName(NULL));
- PR_fprintf(PR_STDOUT,"DiversifyKey old key NistSP800_108KDF code: Using original KDF for old keyset.\n");
+ if(transportKey == NULL)
+ goto done;
- // AC: Derives the kek key for the token.
- old_kek_sym_key = ComputeCardKeyOnToken(oldMasterKey,KDCkek);
+ /* convert 16-byte to 24-byte triple-DES key */
+ memcpy(scp02DekKeyData, old_kek_key, 16);
- } // endif use original KDF
- // ---------------------------------
+ old_kek_sym_key = UnwrapWrappedSymKeyOnToken( slot, transportKey,DES2_LENGTH, scp02DekKeyData, PR_FALSE);
+ if(old_kek_sym_key == NULL) {
+ PR_fprintf(PR_STDERR,"DiversifyKey: Can't unwrap dek key for protocol 2! \n");
+ goto done;
+ }
+ } else {
+ PR_fprintf(PR_STDERR,"DiversifyKey: invalid protocol! \n");
+ goto done;
+ }
// AC KDF SPEC CHANGE: Moved this code down so we don't skip it during "goto done".
//if (oldMasterKey) {
// PK11_FreeSymKey( oldMasterKey );
// oldMasterKey = NULL;
//}
- }
// AC KDF SPEC CHANGE: Moved this code down so we don't skip it during "goto done".
//if(oldMasterKeyNameChars) {
@@ -1406,7 +1483,6 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
} else {
PR_fprintf(PR_STDOUT,"DiversifyKey: Compute card key on token case ! \n");
-
// ---------------------------------
// AC KDF SPEC CHANGE: Determine which KDF to use.
//
@@ -1457,14 +1533,13 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
// AC: Derives the kek key for the token.
/* compute card key */
- encKey = ComputeCardKeyOnSoftToken(masterKey, KDCenc);
- macKey = ComputeCardKeyOnSoftToken(masterKey, KDCmac);
- kekKey = ComputeCardKeyOnSoftToken(masterKey, KDCkek);
+ encKey = ComputeCardKeyOnSoftToken(masterKey, KDCenc,protocol);
+ macKey = ComputeCardKeyOnSoftToken(masterKey, KDCmac,protocol);
+ kekKey = ComputeCardKeyOnSoftToken(masterKey, KDCkek,protocol);
} // endif use original KDF
// ---------------------------------
-
/* Fixes Bugscape Bug #55855: TKS crashes if specified key
* is not present -- for each portion of the key, check if
* the PK11SymKey is NULL before sending it to PK11_GetKeyData()!
@@ -1487,19 +1562,23 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_Dive
}
if (old_kek_sym_key != NULL) {
+
CreateKeySetDataWithSymKeys(newMasterKeyBuffer, Buffer(),
old_kek_sym_key,
encKey,
macKey,
kekKey,
+ protocol,
output); }
else {
old_kek_sym_key = ReturnDeveloperSymKey(slot, (char *) "kek", keySetString, old_kek_key_buff);
+
CreateKeySetDataWithSymKeys(newMasterKeyBuffer, Buffer(),
old_kek_sym_key,
encKey,
macKey,
kekKey,
+ protocol,
output);
}
@@ -1638,13 +1717,14 @@ PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWra
PK11Context * EncContext = NULL;
SECItem unWrappedKeyItem = { siBuffer, NULL, 0};
PK11SymKey *unwrapper = NULL;
+ PK11SymKey *unwrapped24Key = NULL;
PR_fprintf( PR_STDOUT,
"Creating UnWrappedSymKey on token. \n");
if ( (slot == NULL) || (unWrappingKey == NULL) ||
(keyToBeUnWrapped == NULL) ||
- (sizeOfKeyToBeUnWrapped != DES3_LENGTH)
+ ((sizeOfKeyToBeUnWrapped != DES3_LENGTH) && (sizeOfKeyToBeUnWrapped != DES2_LENGTH))
) {
return NULL;
}
@@ -1675,7 +1755,11 @@ PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWra
goto done;
}
- if ( final_len != DES3_LENGTH ) {
+ PR_fprintf( PR_STDOUT,
+ "Creating UnWrappedSymKey on token. final len %d \n", final_len);
+
+
+ if ( final_len != DES3_LENGTH && final_len != DES2_LENGTH) {
goto done;
}
@@ -1689,6 +1773,22 @@ PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWra
CKM_DES3_ECB,
CKA_UNWRAP,
sizeOfKeyToBeUnWrapped, 0, isPerm );
+
+ if(sizeOfKeyToBeUnWrapped == DES2_LENGTH) {
+ unwrapped24Key = CreateDesKey24Byte(slot, unWrappedSymKey);
+ if(unwrapped24Key == NULL) {
+ PR_fprintf( PR_STDERR,
+ "UnwrapWrappedSymKeyOnToken . Unable to unwrap 24 byte key onto token!. \n");
+
+ }
+ }
+
+
+ if(unwrapped24Key != NULL) {
+ PK11_FreeSymKey( unWrappedSymKey);
+ unWrappedSymKey = unwrapped24Key;
+ }
+
done:
@@ -1710,7 +1810,7 @@ done:
if( unwrapKeySlot != NULL) {
PK11_FreeSlot( unwrapKeySlot);
unwrapKeySlot = NULL;
- }
+ }
PR_fprintf( PR_STDOUT,
"UnWrappedSymKey on token result: %p \n",unWrappedSymKey);
@@ -1735,6 +1835,8 @@ PK11SymKey *ReturnDeveloperSymKey(PK11SlotInfo *slot, char *keyType, char *keySe
snprintf(devKeyName,maxKeyNameSize,"%s-%sKey", keySet, keyType);
+ PR_fprintf(PR_STDOUT,"ReturnDeveloperSymKey! trying to find key %s. \n",devKeyName);
+
devSymKey = ReturnSymKey( slot, devKeyName );
// Try to create the key once and leave it there.
@@ -1767,7 +1869,10 @@ PK11SymKey *ReturnDeveloperSymKey(PK11SlotInfo *slot, char *keyType, char *keySe
PR_fprintf(PR_STDERR, "Can't set the nickname of just written devKey! \n");
}
}
+ } else {
+ PR_fprintf(PR_STDOUT,"ReturnDeveloperSymKey! input key size %d. \n",inputKey.size());
}
+
}
done:
@@ -1806,3 +1911,114 @@ JNICALL Java_com_netscape_symkey_SessionKey_SetDefaultPrefix(JNIEnv * env, jclas
return;
}
+
+int checkForDeveloperKeySet(char * keyInfo)
+{
+
+ if(keyInfo == NULL)
+ return 1;
+
+ //SCP01 or SCP02
+ if(strcmp( keyInfo, "#01#01") == 0 || strcmp( keyInfo, "#FF#01") == 0)
+ return 1;
+
+ //SCP02
+ if(strcmp( keyInfo, "#01#02") == 0 || strcmp( keyInfo, "#FF#02") == 0)
+ return 1;
+
+ return 0;
+}
+
+// Unwrap previously wrapped sym key. Assume the final output is 24 bytes DES3, this function assumes the key is wrapped already.
+
+PK11SymKey *UnwrapWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWrappingKey,int sizeOfWrappedKey, unsigned char * wrappedKeyData, PRBool isPerm) {
+
+ PK11SymKey * unWrappedSymKey = NULL;
+ int final_len = DES3_LENGTH;
+ SECItem unWrappedKeyItem = { siBuffer, NULL, 0};
+ PK11SymKey *unwrapper = NULL;
+ PK11SymKey *unwrapped24Key = NULL;
+
+
+ PR_fprintf( PR_STDOUT,
+ "Creating UnWrappedSymKey on token. UnwrapWrappedSymKeyOnToken. \n");
+
+ if ( (slot == NULL) || (unWrappingKey == NULL) || (wrappedKeyData == NULL))
+ {
+ return NULL;
+ }
+
+ if(sizeOfWrappedKey == DES2_LENGTH) {
+ PR_fprintf( PR_STDOUT,
+ "UnwrapWrappedSymKeyOnToken . Given 16 byte encrypted key will have to derive a 24 byte on later. \n");
+ }
+
+ PK11SlotInfo *unwrapKeySlot = PK11_GetSlotFromKey( unWrappingKey );
+
+ if ( unwrapKeySlot != slot ) {
+ unwrapper = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, unWrappingKey);
+ }
+
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ if ( SecParam == NULL) {
+ goto done;
+ }
+
+ if ( final_len != DES3_LENGTH ) {
+ goto done;
+ }
+
+ unWrappedKeyItem.data = wrappedKeyData;
+ unWrappedKeyItem.len = sizeOfWrappedKey;
+
+ /* Now try to unwrap our key into the token */
+ unWrappedSymKey = PK11_UnwrapSymKeyWithFlagsPerm(unwrapper ? unwrapper : unWrappingKey,
+ CKM_DES3_ECB,SecParam, &unWrappedKeyItem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ sizeOfWrappedKey, 0, isPerm );
+
+ if(unWrappedSymKey == NULL) {
+ PR_fprintf( PR_STDERR,
+ "UnwrapWrappedSymKeyOnToken . Unable to unwrap key onto token!. \n");
+ goto done;
+ }
+
+ if(sizeOfWrappedKey == DES2_LENGTH) {
+ unwrapped24Key = CreateDesKey24Byte(slot, unWrappedSymKey);
+ if(unwrapped24Key == NULL) {
+ PR_fprintf( PR_STDERR,
+ "UnwrapWrappedSymKeyOnToken . Unable to unwrap 24 byte key onto token!. \n");
+
+ }
+ }
+
+done:
+
+ if( SecParam != NULL ) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+
+ if( unwrapper != NULL ) {
+ PK11_FreeSymKey( unwrapper );
+ unwrapper = NULL;
+ }
+
+ if( unwrapKeySlot != NULL) {
+ PK11_FreeSlot( unwrapKeySlot);
+ unwrapKeySlot = NULL;
+ }
+
+ if( unwrapped24Key != NULL) {
+ PK11_FreeSymKey( unWrappedSymKey);
+ unWrappedSymKey = unwrapped24Key;
+ }
+
+ PR_fprintf( PR_STDOUT,
+ "UnwrapWrappedSymKey on token result: %p \n",unWrappedSymKey);
+
+
+ return unWrappedSymKey;
+
+}
diff --git a/base/symkey/src/com/netscape/symkey/SymKey.h b/base/symkey/src/com/netscape/symkey/SymKey.h
index efe187075..4f1bbe7ef 100644
--- a/base/symkey/src/com/netscape/symkey/SymKey.h
+++ b/base/symkey/src/com/netscape/symkey/SymKey.h
@@ -41,13 +41,14 @@ extern char sharedSecretSymKeyName[KEYNAMELENGTH];
void GetDiversificationData(jbyte *cuidValue,BYTE *KDC,keyType keytype);
PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname);
void GetKeyName(jbyte *keyVersion,char *keyname);
-PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data);
+PK11SymKey * ComputeCardKeyOnToken(PK11SymKey *masterKey, BYTE* data,int protocol);
PRStatus EncryptData(const Buffer &kek_key, PK11SymKey *card_key, Buffer &input, Buffer &output);
PK11SlotInfo *ReturnSlot(char *tokenNameChars);
-PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot);
+PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot,int protocol);
PK11SymKey *CreateUnWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWrappingKey, BYTE *keyToBeUnWrapped, int sizeOfKeyToBeUnWrapped, PRBool isPerm);
PK11SymKey *ReturnDeveloperSymKey(PK11SlotInfo *slot, char *keyType, char *keySet, Buffer &inputKey);
PK11SymKey *CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey);
+PK11SymKey *UnwrapWrappedSymKeyOnToken( PK11SlotInfo *slot, PK11SymKey * unWrappingKey,int sizeOfWrappedKey, unsigned char * wrappedKeyData, PRBool isPerm);
char *GetSharedSecretKeyName(char *newKeyName);