summaryrefslogtreecommitdiffstats
path: root/pki/base/tps/src/engine/RA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/tps/src/engine/RA.cpp')
-rw-r--r--pki/base/tps/src/engine/RA.cpp241
1 files changed, 220 insertions, 21 deletions
diff --git a/pki/base/tps/src/engine/RA.cpp b/pki/base/tps/src/engine/RA.cpp
index 0491b6db4..19c445f9d 100644
--- a/pki/base/tps/src/engine/RA.cpp
+++ b/pki/base/tps/src/engine/RA.cpp
@@ -61,6 +61,19 @@ extern "C"
#include "main/RollingLogFile.h"
#include "selftests/SelfTest.h"
+typedef struct
+{
+ enum
+ {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+
static ConfigStore *m_cfg = NULL;
static LogFile* m_debug_log = (LogFile *)NULL;
static LogFile* m_error_log = (LogFile *)NULL;
@@ -1501,6 +1514,10 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
const char *connId)
{
PK11SymKey *symKey = NULL;
+ PK11SymKey *symKey24 = NULL;
+ PK11SymKey *encSymKey24 = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *encSymKey16 = NULL;
char body[MAX_BODY_LEN];
char configname[256];
char * cardc = NULL;
@@ -1511,6 +1528,8 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
PSHttpResponse *response = NULL;
HttpConnection *tksConn = NULL;
RA_pblock *ra_pb = NULL;
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ char* transportKeyName = NULL;
RA::Debug(LL_PER_PDU, "Start ComputeSessionKey", "");
tksConn = RA::GetTKSConn(connId);
@@ -1621,6 +1640,21 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
}
}
+ // Now unwrap the session keys with shared secret transport key
+
+ PR_snprintf((char *)configname, 256, "conn.%s.tksSharedSymKeyName", connId);
+
+ transportKeyName = (char *) m_cfg->GetConfigAsString(configname, TRANSPORT_KEY_NAME);
+
+ RA::Debug(LL_PER_PDU,"RA:ComputeSessionKey","Shared Secret key name: %s.", transportKeyName);
+
+ transportKey = FindSymKeyByName( slot, transportKeyName);
+
+ if ( transportKey == NULL ) {
+ RA::Debug(LL_PER_PDU,"RA::ComputeSessionKey","fail getting transport key");
+ goto loser;
+ }
+
sessionKey_s = ra_pb->find_val_s(TKS_RESPONSE_SessionKey);
if (sessionKey_s == NULL) {
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no sessionKey_b");
@@ -1632,21 +1666,24 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "decodekey len=%d",decodeKey->size());
- BYTE masterKeyData[24];
- SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData)};
BYTE *keyData = (BYTE *)*decodeKey;
- memcpy(masterKeyData, (char*)keyData, 16);
- memcpy(masterKeyData+16, (char*)keyData, 8);
+ SECItem wrappeditem = {siBuffer , keyData, 16 };
- symKey = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
+ symKey = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( symKey ) {
+ symKey24 = CreateDesKey24Byte(slot, symKey);
+ }
if( decodeKey != NULL ) {
delete decodeKey;
decodeKey = NULL;
}
- if (symKey == NULL)
+ if (symKey24 == NULL)
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "MAC Session key is NULL");
@@ -1662,27 +1699,30 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey",
"decodeEnckey len=%d",decodeEncKey->size());
- BYTE masterEncKeyData[24];
- SECItem masterEncKeyItem =
- {siBuffer, masterEncKeyData, sizeof(masterEncKeyData)};
BYTE *EnckeyData = (BYTE *)*decodeEncKey;
- memcpy(masterEncKeyData, (char*)EnckeyData, 16);
- memcpy(masterEncKeyData+16, (char*)EnckeyData, 8);
+ wrappeditem.data = (unsigned char *) EnckeyData;
+ wrappeditem.len = 16;
+
+ encSymKey16 = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( encSymKey16 ) {
+ encSymKey24 = CreateDesKey24Byte(slot, encSymKey16);
+ }
- *encSymKey =
- PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
- PK11_OriginGenerated, CKA_ENCRYPT, &masterEncKeyItem,
- CKF_ENCRYPT, PR_FALSE, 0);
+ *encSymKey = encSymKey24;
if( decodeEncKey != NULL ) {
delete decodeEncKey;
decodeEncKey = NULL;
}
- if (encSymKey == NULL)
+ if (encSymKey24 == NULL)
RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "encSessionKey is NULL");
-
if (serverKeygen) {
char * tmp= NULL;
tmp = ra_pb->find_val_s(TKS_RESPONSE_DRM_Trans_DesKey);
@@ -1761,13 +1801,28 @@ PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
response = NULL;
}
+ if ( SecParam != NULL ) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+
if (ra_pb != NULL) {
delete ra_pb;
}
+
+ if ( symKey != NULL ) {
+ PK11_FreeSymKey( symKey );
+ symKey = NULL;
+ }
+
+ if ( encSymKey16 != NULL ) {
+ PK11_FreeSymKey( encSymKey16 );
+ encSymKey16 = NULL;
+ }
+
// in production, if TKS is unreachable, symKey will be NULL,
// and this will signal error to the caller.
- return symKey;
-
+ return symKey24;
}
Buffer *RA::ComputeHostCryptogram(Buffer &card_challenge,
@@ -3420,3 +3475,147 @@ TPS_PUBLIC bool RA::verifySystemCerts() {
return rv;
}
+
+PK11SymKey *RA::FindSymKeyByName( PK11SlotInfo *slot, char *keyname) {
+char *name = NULL;
+ PK11SymKey *foundSymKey= NULL;
+ PK11SymKey *firstSymKey= NULL;
+ PK11SymKey *sk = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ secuPWData pwdata;
+
+ pwdata.source = secuPWData::PW_NONE;
+ pwdata.data = (char *) NULL;
+ if (keyname == NULL)
+ {
+ goto cleanup;
+ }
+ if (slot== NULL)
+ {
+ goto cleanup;
+ }
+ /* Initialize the symmetric key list. */
+ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata );
+ /* scan through the symmetric key list for a key matching our nickname */
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ /* get the nickname of this symkey */
+ name = PK11_GetSymKeyNickname( sk );
+
+ /* if the name matches, make a 'copy' of it */
+ if ( name != NULL && !strcmp( keyname, name ))
+ {
+ if (foundSymKey == NULL)
+ {
+ foundSymKey = PK11_ReferenceSymKey(sk);
+ }
+ PORT_Free(name);
+ }
+
+ sk = PK11_GetNextSymKey( sk );
+ }
+
+ /* We're done with the list now, let's free all the keys in it
+ It's okay to free our key, because we made a copy of it */
+
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ nextSymKey = PK11_GetNextSymKey(sk);
+ PK11_FreeSymKey(sk);
+ sk = nextSymKey;
+ }
+
+ cleanup:
+ return foundSymKey;
+}
+
+PK11SymKey *RA::CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey)
+{
+ PK11SymKey *newKey = NULL;
+ PK11SymKey *firstEight = NULL;
+ PK11SymKey *concatKey = NULL;
+ PK11SymKey *internalOrigKey = NULL;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_OBJECT_HANDLE keyhandle = 0;
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "entering.");
+
+ PK11SlotInfo *internal = PK11_GetInternalSlot();
+ if ( slot == NULL || origKey == NULL || internal == NULL)
+ goto loser;
+
+ if( internal != slot ) { //Make sure we do this on the NSS Generic Crypto services because concatanation
+ // only works there.
+ internalOrigKey = PK11_MoveSymKey( internal, CKA_ENCRYPT, 0, PR_FALSE, origKey );
+ }
+ // 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, 8);
+ else
+ firstEight = PK11_Derive(origKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+
+ if (firstEight == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error deriving 8 byte portion of key.");
+ 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 ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "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 ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "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;
+ }
+
+ if ( internal != NULL ) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ return newKey;
+}