summaryrefslogtreecommitdiffstats
path: root/base/symkey
diff options
context:
space:
mode:
authorJack Magne <jmagne@dhcp-16-213.sjc.redhat.com>2014-04-02 19:10:51 -0700
committerJack Magne <jmagne@dhcp-16-213.sjc.redhat.com>2014-04-14 10:11:14 -0700
commit7604304b755bc8d78889322bdf825a7ed907d683 (patch)
tree7de8da75d6dfe447ab547db2b88ae3b34fb3ad88 /base/symkey
parentf0b112fa8d859056aaa729cda0761a1786987088 (diff)
downloadpki-7604304b755bc8d78889322bdf825a7ed907d683.tar.gz
pki-7604304b755bc8d78889322bdf825a7ed907d683.tar.xz
pki-7604304b755bc8d78889322bdf825a7ed907d683.zip
Further progress Format operation.
1. Read applet into memory to prepare to write to token. 2. With tpsclient create secure channel by implementing Initialize Update and ExternalAuthenticate messages. 3. Support for MAC and encryption for messages going on after secure channel has been created. 4. Implemented method to remove an aid file or instance from the token. 5. Added some symkey methods to allow TPS to manipulate session keys. 6. Performed some cfu feedback fixes such as changing al the names of APDU classes to have APDU in the name. Have not tried this with real token as of yet. The tpsclient does verify of the MAC coming from the server and decrypts encrypted messages. Decrypted messages have to be correct for the MAC verification to work. Next step will be to add the phone home servlet to the TPS and give it a try with a real token and esc.
Diffstat (limited to 'base/symkey')
-rw-r--r--base/symkey/src/com/netscape/symkey/SessionKey.cpp193
-rw-r--r--base/symkey/src/com/netscape/symkey/SessionKey.java122
-rw-r--r--base/symkey/src/com/netscape/symkey/SymKey.cpp97
-rw-r--r--base/symkey/src/com/netscape/symkey/SymKey.h1
4 files changed, 356 insertions, 57 deletions
diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.cpp b/base/symkey/src/com/netscape/symkey/SessionKey.cpp
index 0878e26dd..9f3a353a3 100644
--- a/base/symkey/src/com/netscape/symkey/SessionKey.cpp
+++ b/base/symkey/src/com/netscape/symkey/SessionKey.cpp
@@ -1843,6 +1843,199 @@ finish:
return handleBA;
}
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_UnwrapSessionKeyWithSharedSecret
+ * Method: UnwrapSessionKeyWithSharedSecret
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jobject JNICALL
+ Java_com_netscape_symkey_SessionKey_
+ (JNIEnv*, jclass, jstring, jobject,jbyteArray);
+#ifdef __cplusplus
+}
+#endif
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_netscape_symkey_SessionKey_UnwrapSessionKeyWithSharedSecret
+(JNIEnv* env, jclass this2, jstring tokenName, jobject sharedSecretKey,jbyteArray sessionKeyBA)
+{
+ jobject keyObj = NULL;
+ PK11SymKey *sessionKey = NULL;
+ PK11SymKey *sharedSecret = NULL;
+ PK11SymKey *finalKey = NULL;
+ PK11SlotInfo *slot = NULL;
+ char *tokenNameChars = NULL;
+ PRStatus r = PR_FAILURE;
+ int sessionKeyLen = 0;
+ jbyte *sessionKeyBytes = NULL;
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ SECItem wrappedItem = {siBuffer , NULL, 0 };
+
+ PR_fprintf(PR_STDOUT,"In SessionKey.UnwrapSessionKeyWithSharedSecret!\n");
+
+ if( sharedSecretKey == NULL || sessionKeyBA == NULL) {
+ goto loser;
+ }
+
+ if (tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ if ( tokenNameChars && !strcmp(tokenNameChars, "internal")) {
+ slot = PK11_GetInternalSlot();
+ } else {
+ slot = ReturnSlot(tokenNameChars);
+ }
+
+ PR_fprintf(PR_STDOUT,"SessionKey.UnwrapSessionKeyWithSharedSecret slot %p name %s tokenName %s \n",slot, PK11_GetSlotName(slot), PK11_GetTokenName(slot));
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ } else {
+ slot = PK11_GetInternalKeySlot();
+ }
+
+ if(slot == NULL) {
+ goto loser;
+ }
+
+ sessionKeyBytes = (jbyte *)(env)->GetByteArrayElements(sessionKeyBA, NULL);
+ sessionKeyLen = (env)->GetArrayLength(sessionKeyBA);
+
+ if(sessionKeyBytes == NULL) {
+ goto loser;
+ }
+
+ r = JSS_PK11_getSymKeyPtr(env, sharedSecretKey, &sharedSecret);
+
+ if (r != PR_SUCCESS) {
+ PR_fprintf(PR_STDOUT,"SessionKey: UnwrapSessionKeyWithSharedSecret Unable to get input shared secret sym key! \n");
+ goto loser;
+ }
+
+ wrappedItem.data = (unsigned char *) sessionKeyBytes;
+ wrappedItem.len = sessionKeyLen;
+
+ sessionKey = PK11_UnwrapSymKey(sharedSecret,
+ CKM_DES3_ECB,SecParam, &wrappedItem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ PR_fprintf(PR_STDOUT,"SessionKey: UnwrapSessionKeyWithSharedSecret symKey: %p \n",sessionKey);
+
+ if(sessionKey == NULL) {
+ PR_fprintf(PR_STDOUT,"SessionKey:UnwrapSessionKeyWithSharedSecret Error unwrapping a session key! \n");
+ goto loser;
+ }
+
+ // Done to be compat with current system. Current TPS does this.
+ finalKey = CreateDesKey24Byte(slot, sessionKey);
+
+ if(finalKey == NULL) {
+ PR_fprintf(PR_STDOUT,"SessionKey:UnwrapSessionKeyWithSharedSecret Error final unwrapped key! \n");
+ goto loser;
+
+ }
+
+ /* wrap the sesssion in java object. */
+ keyObj = JSS_PK11_wrapSymKey(env, &finalKey, NULL);
+
+loser:
+
+ if ( slot != NULL ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if ( sessionKeyBA != NULL) {
+ (env)->ReleaseByteArrayElements( sessionKeyBA, sessionKeyBytes, 0);
+ }
+
+ if(sessionKey) {
+ PK11_FreeSymKey(sessionKey);
+ sessionKey = NULL;
+ }
+
+ // Don't free finalKey ptr because wrapping routine takes that out of our hands.
+
+ return keyObj;
+}
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*
+ * Class: com_netscape_cms_servlet_tks_GetSymKeyByName
+ * Method: GetSymKeyByName
+ * Signature: ([B[B[B[B)[B
+ */
+ JNIEXPORT jobject JNICALL
+ Java_com_netscape_symkey_SessionKey_GetSymKeyByName
+ (JNIEnv*, jclass, jstring, jstring);
+#ifdef __cplusplus
+}
+#endif
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_netscape_symkey_SessionKey_GetSymKeyByName
+(JNIEnv* env, jclass this2, jstring tokenName, jstring keyName)
+{
+
+ jobject keyObj = NULL;
+ PK11SymKey *key = NULL;
+ char *tokenNameChars = NULL;
+ char *keyNameChars = NULL;
+ PK11SlotInfo *slot = NULL;
+ CK_OBJECT_HANDLE keyhandle = 0;
+
+ PR_fprintf(PR_STDOUT,"In SessionKey GetSymKeyByName!\n");
+
+ if (keyName) {
+ keyNameChars = (char *)(env)->GetStringUTFChars(keyName,NULL);
+ }
+
+ if (tokenName)
+ {
+ tokenNameChars = (char *)(env)->GetStringUTFChars(tokenName, NULL);
+ if ( tokenNameChars && !strcmp(tokenNameChars, "internal")) {
+ slot = PK11_GetInternalSlot();
+ } else {
+ slot = ReturnSlot(tokenNameChars);
+ }
+
+ PR_fprintf(PR_STDOUT,"SessionKey: GetSymKeyByName slot %p name %s tokenName %s keyName %s \n",slot, PK11_GetSlotName(slot), PK11_GetTokenName(slot),keyNameChars);
+ (env)->ReleaseStringUTFChars(tokenName, (const char *)tokenNameChars);
+ } else {
+ slot = PK11_GetInternalKeySlot();
+ }
+
+ if(slot == NULL)
+ goto finish;
+
+ key = ReturnSymKey( slot, keyNameChars);
+
+ PR_fprintf(PR_STDOUT,"SessionKey: GetSymKeyByName returned key %p \n",key);
+ if (key == NULL) {
+ goto finish;
+ }
+
+ /* wrap the symkey in java object. */
+ keyObj = JSS_PK11_wrapSymKey(env, &key, NULL);
+
+finish:
+
+ if (keyName) {
+ (env)->ReleaseStringUTFChars(keyName, (const char *)keyNameChars);
+ }
+
+ if(slot) {
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ }
+
+ return keyObj;
+}
#ifdef __cplusplus
extern "C"
diff --git a/base/symkey/src/com/netscape/symkey/SessionKey.java b/base/symkey/src/com/netscape/symkey/SessionKey.java
index 47f9385f7..56782aad9 100644
--- a/base/symkey/src/com/netscape/symkey/SessionKey.java
+++ b/base/symkey/src/com/netscape/symkey/SessionKey.java
@@ -75,47 +75,47 @@ public class SessionKey {
public static native byte[] ComputeKeyCheck(PK11SymKey desKey); /* byte data[] ); */
public static native byte[] ComputeSessionKey(String tokenName,
- String keyName,
- byte[] card_challenge,
- byte[] host_challenge,
- byte[] keyInfo,
- byte[] CUID,
- byte[] macKeyArray,
- String useSoftToken,
- String keySet,
- String sharedSecretKeyName);
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] macKeyArray,
+ String useSoftToken,
+ String keySet,
+ String sharedSecretKeyName);
public static native byte[] ComputeEncSessionKey(String tokenName,
- String keyName,
- byte[] card_challenge,
- byte[] host_challenge,
- byte[] keyInfo,
- byte[] CUID,
- byte[] encKeyArray,
- String useSoftToken,
- String keySet);
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] encKeyArray,
+ String useSoftToken,
+ String keySet);
public static native PK11SymKey ComputeKekSessionKey(String tokenName,
- String keyName,
- byte[] card_challenge,
- byte[] host_challenge,
- byte[] keyInfo,
- byte[] CUID,
- byte[] kekKeyArray,
- String useSoftToken,
- String keySet);
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] kekKeyArray,
+ String useSoftToken,
+ String keySet);
public static native PK11SymKey ComputeKekKey(String tokenName,
- String keyName,
- byte[] card_challenge,
- byte[] host_challenge,
- byte[] keyInfo,
- byte[] CUID,
- byte[] kekKeyArray,
- String useSoftToken, String keySet);
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] kekKeyArray,
+ String useSoftToken, String keySet);
public static native byte[] ECBencrypt(PK11SymKey key,
- PK11SymKey desKey); //byte[] data );
+ PK11SymKey desKey); //byte[] data );
public static native PK11SymKey GenerateSymkey(String tokenName);
@@ -126,42 +126,52 @@ public class SessionKey {
// public static native PK11SymKey bytes2PK11SymKey( byte[] symKeyBytes );
public static native byte[] ComputeCryptogram(String tokenName,
- String keyName,
- byte[] card_challenge,
- byte[] host_challenge,
- byte[] keyInfo,
- byte[] CUID,
- int type,
- byte[] authKeyArray,
- String useSoftToken, String keySet);
+ String keyName,
+ byte[] card_challenge,
+ byte[] host_challenge,
+ byte[] keyInfo,
+ byte[] CUID,
+ int type,
+ byte[] authKeyArray,
+ String useSoftToken, String keySet);
public static native byte[] EncryptData(String tokenName,
- String keyName,
- byte[] in,
- byte[] keyInfo,
- byte[] CUID,
- byte[] kekKeyArray,
- String useSoftToken, String keySet);
+ String keyName,
+ byte[] in,
+ byte[] keyInfo,
+ byte[] CUID,
+ byte[] kekKeyArray,
+ String useSoftToken, String keySet);
public static native byte[] DiversifyKey(String tokenName,
- String newTokenName,
- String oldMasterKeyName,
- String newMasterKeyName,
- String keyInfo,
- byte[] CUIDValue,
- byte[] kekKeyArray,
- String useSoftToken, String keySet);
+ String newTokenName,
+ String oldMasterKeyName,
+ String newMasterKeyName,
+ String keyInfo,
+ byte[] CUIDValue,
+ byte[] kekKeyArray,
+ String useSoftToken, String keySet);
// internal calls from config TKS keys tab
public static native String GenMasterKey(String token,
- String keyName);
+ String keyName);
public static native String DeleteSymmetricKey(String token,
- String keyName);
+ String keyName);
public static native String ListSymmetricKeys(String token);
// set when called from the config TKS tab to create master key
// get when called from the RA to create session key
public static native void SetDefaultPrefix(String masterPrefix);
+
+ // Functions that the TPS may use during processing to manipulate sym keys in such a way not available in JSS
+
+ // Return a names Sym Key, in this case will be the shared secret in practice.
+ public static native PK11SymKey GetSymKeyByName(String tokenName, String keyName);
+
+ // TKS sends over the session key(s) wrapped with shared secret. TPS now does this unwrapping and creates the session keys
+ // 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);
}
diff --git a/base/symkey/src/com/netscape/symkey/SymKey.cpp b/base/symkey/src/com/netscape/symkey/SymKey.cpp
index c300d1ada..758156677 100644
--- a/base/symkey/src/com/netscape/symkey/SymKey.cpp
+++ b/base/symkey/src/com/netscape/symkey/SymKey.cpp
@@ -140,7 +140,6 @@ PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname)
pwdata.source = secuPWData::PW_NONE;
pwdata.data = (char *) NULL;
- PR_fprintf(PR_STDOUT,"In ReturnSymKey name %s \n",keyname);
if (keyname == NULL)
{
goto cleanup;
@@ -186,6 +185,102 @@ PK11SymKey * ReturnSymKey( PK11SlotInfo *slot, char *keyname)
return foundSymKey;
}
+PK11SymKey *CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey) {
+
+ PK11SymKey *newKey = NULL;
+
+ CK_OBJECT_HANDLE keyhandle = 0;
+ PK11SymKey *firstEight = NULL;
+ PK11SymKey *concatKey = NULL;
+ PK11SymKey *internalOrigKey = NULL;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+
+ PK11SlotInfo *internal = PK11_GetInternalSlot();
+ if ( slot == NULL || origKey == NULL || internal == NULL )
+ goto loser;
+
+ PR_fprintf(PR_STDOUT,"In SessionKey CreateDesKey24Bit!\n");
+
+ if( internal != slot ) { //Make sure we do this on the NSS Generic Crypto services because concatanation
+ PR_fprintf(PR_STDOUT,"CreateDesKey24Bit! Input key not on internal slot!\n");
+ internalOrigKey = PK11_MoveSymKey( internal, CKA_ENCRYPT, 0, PR_FALSE, origKey );
+ if(internalOrigKey == NULL) {
+ PR_fprintf(PR_STDOUT,"CreateDesKey24Bit! Can't move input key to internal!\n");
+ goto loser;
+ }
+ }
+
+ // Extract first eight bytes from generated key into another key.
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+
+ if ( internalOrigKey)
+ firstEight = PK11_Derive(internalOrigKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, EIGHT_BYTES);
+ else
+ firstEight = PK11_Derive(origKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, EIGHT_BYTES);
+
+ if (firstEight == NULL ) {
+ PR_fprintf(PR_STDOUT,"CreateDesKey24Bit! Can't extract first 8 bits of input key!\n");
+ goto loser;
+ }
+
+ //Concatenate 8 byte key to the end of the original key, giving new 24 byte key
+ keyhandle = PK11_GetSymKeyHandle(firstEight);
+
+ paramsItem.data=(unsigned char *) &keyhandle;
+ paramsItem.len=sizeof(keyhandle);
+
+ if ( internalOrigKey ) {
+ concatKey = PK11_Derive ( internalOrigKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ } else {
+ concatKey = PK11_Derive ( origKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ }
+
+ if ( concatKey == NULL ) {
+ PR_fprintf(PR_STDOUT,"CreateDesKey24Bit: error concatenating 8 bytes on end of key.");
+ goto loser;
+ }
+
+ //Make sure we move this to the proper token, in case it got moved by NSS
+ //during the derive phase.
+
+ newKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, concatKey);
+
+ if ( newKey == NULL ) {
+ PR_fprintf(PR_STDOUT,"CreateDesKey24Bit: error moving key to original slot.");
+ }
+
+loser:
+
+
+ if ( concatKey != NULL ) {
+ PK11_FreeSymKey( concatKey );
+ concatKey = NULL;
+ }
+
+ if ( firstEight != NULL ) {
+ PK11_FreeSymKey ( firstEight );
+ firstEight = NULL;
+ }
+
+ if ( internalOrigKey != NULL ) {
+ PK11_FreeSymKey ( internalOrigKey );
+ internalOrigKey = NULL;
+ }
+
+ //Caller will free the slot input slot object
+
+ if ( internal != NULL ) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ return newKey;
+}
+
extern "C" JNIEXPORT jstring
JNICALL Java_com_netscape_symkey_SessionKey_DeleteKey(JNIEnv * env, jclass this2, jstring tokenName, jstring keyName)
diff --git a/base/symkey/src/com/netscape/symkey/SymKey.h b/base/symkey/src/com/netscape/symkey/SymKey.h
index 5a53d48c9..efe187075 100644
--- a/base/symkey/src/com/netscape/symkey/SymKey.h
+++ b/base/symkey/src/com/netscape/symkey/SymKey.h
@@ -47,6 +47,7 @@ PK11SlotInfo *ReturnSlot(char *tokenNameChars);
PK11SymKey *ComputeCardKey(PK11SymKey *masterKey, unsigned char *data, PK11SlotInfo *slot);
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);
char *GetSharedSecretKeyName(char *newKeyName);