This commit is contained in:
432
c_adlib/ad_ff/native/CryptManager.cpp
Normal file
432
c_adlib/ad_ff/native/CryptManager.cpp
Normal file
@@ -0,0 +1,432 @@
|
||||
|
||||
#include "CryptManager.h"
|
||||
|
||||
|
||||
|
||||
void CryptManager::SetupFunctions(void *funList[])
|
||||
{
|
||||
|
||||
//PK11SetPasswordFunc = (PK11_SetPasswordFunc) funList[0];
|
||||
PK11GetInternalKeySlot = (PK11_GetInternalKeySlot) funList[1];
|
||||
PK11FreeSlot = (PK11_FreeSlot) funList[2];
|
||||
PK11Authenticate = (PK11_Authenticate) funList[3];
|
||||
PK11CheckUserPassword =(PK11_CheckUserPassword) funList[4];
|
||||
PK11SDRDecrypt = (PK11SDR_Decrypt) funList[5];
|
||||
PK11SDREncrypt = (PK11SDR_Encrypt) funList[6];
|
||||
PLBase64Encode = (PL_Base64Encode) funList[7];
|
||||
PLBase64Decode = (PL_Base64Decode) funList[8];
|
||||
|
||||
}
|
||||
|
||||
int CryptManager::GetEncryptionPref()
|
||||
{
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function encrypts the clear text data. First it performs TRIPLE DES encryption
|
||||
* and then performs base64 encoding on the encrypted data.
|
||||
*
|
||||
* @param(in) clearData clear text data to be encrypted
|
||||
* @param(out) finalData encrypted data ( null terminated)
|
||||
*
|
||||
* @return FPM_TRUE on success and FPM_FALSE on error.
|
||||
*
|
||||
*/
|
||||
int CryptManager::EncryptString (char *clearData, char **finalData)
|
||||
{
|
||||
int encryptDataLen = 0;
|
||||
char *encryptData = NULL;
|
||||
char *encodeData = NULL;
|
||||
int retValue;
|
||||
|
||||
|
||||
if( clearData == NULL )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n EncryptString : Text Data is NULL");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
// Do the encryption if encryption pref is set otherwise just do base64 encoding...
|
||||
if ( GetEncryptionPref() )
|
||||
{
|
||||
PrintMessage(MESG_DEBUG, "\n EncryptString : Performing PK11 Encryption...");
|
||||
|
||||
retValue = FPM_FALSE;
|
||||
if( ((retValue = CryptPK11EncryptString(clearData, strlen(clearData), &encryptData, &encryptDataLen)) != FPM_TRUE) || ( encryptData == NULL) )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n EncryptString : Failed to encrypt the string : %s ", clearData);
|
||||
return retValue;
|
||||
}
|
||||
|
||||
if( (CryptBase64Encode(encryptData, encryptDataLen, finalData) != FPM_TRUE) || (*finalData == NULL) )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n EncryptString : BASE64 encoding failed");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n EncryptString : Success ");
|
||||
|
||||
// WARNING : If you uncomment , then be ready for side effects , crashes..etc
|
||||
// Need full analysis of malloc for this data..
|
||||
// Free the allocated blocks...
|
||||
|
||||
//if( encryptData )
|
||||
// free( encryptData);
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
// otherwise do our own obscuring using Base64 encoding
|
||||
PrintMessage(MESG_DEBUG, "\n EncryptString : Performing JUST base64 encoding...");
|
||||
|
||||
if( (CryptBase64Encode(clearData, strlen(clearData), &encodeData) == FPM_FALSE) || (encodeData == NULL) )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n EncryptString : BASE64 encoding failed");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
// We need to add the CRYPT_PREFIX at the begining of encoded data...
|
||||
// This will help during decrption process to identify type of encryption
|
||||
|
||||
int prefixLen = strlen( CRYPT_PREFIX );
|
||||
int encodeLen = strlen( encodeData );
|
||||
*finalData = (char *)malloc( prefixLen + encodeLen + 1);
|
||||
|
||||
if( *finalData == NULL )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n EncryptString : Insufficient memory");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
// FinalData = CRYPT_PREFIX + Encoded Data + '\0'
|
||||
strcpy(*finalData, CRYPT_PREFIX);
|
||||
strcat(*finalData, encodeData);
|
||||
*(*finalData + prefixLen + encodeLen) = 0;
|
||||
|
||||
free(encodeData);
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function decrypts the encrypted data. First it performs base64 decoding and
|
||||
* then performs TRIPLE DES decryption.
|
||||
*
|
||||
* @param(in) cryptData encrypted data
|
||||
* @param(out) clearData clear text data ( null terminated)
|
||||
*
|
||||
* @return FPM_TRUE on success and FPM_FALSE on error.
|
||||
*
|
||||
*/
|
||||
|
||||
int CryptManager::DecryptString(char *cryptData, char **clearData)
|
||||
{
|
||||
int decodeLen = 0;
|
||||
int finalLen = 0;
|
||||
char *decodeData = NULL;
|
||||
char *finalData = NULL;
|
||||
int retValue;
|
||||
|
||||
if( cryptData == NULL )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n DecryptString: CryptData is NULL...");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
// treat zero-length crypt string as a special case
|
||||
if(cryptData[0] == '\0')
|
||||
{
|
||||
*clearData = (char*) malloc(1);
|
||||
**clearData = 0;
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
// use PK11 encryption stuff if crypt doesn't starts with prefix
|
||||
if( cryptData[0] != CRYPT_PREFIX[0] )
|
||||
{
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n Performing PK11 Decryption ");
|
||||
|
||||
// First do base64 decoding.....
|
||||
if( (CryptBase64Decode(cryptData, &decodeData, &decodeLen) != FPM_TRUE) || (decodeData == NULL) )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n DecryptString : Base64 decoding of crypt data failed ");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n DecryptString : base64data (%d) = %s ", decodeLen, decodeData);
|
||||
|
||||
// Now do actual PK11 decryption
|
||||
retValue = FPM_FALSE;
|
||||
retValue = CryptPK11DecryptString(decodeData, decodeLen, &finalData, &finalLen);
|
||||
|
||||
if( retValue != FPM_TRUE )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n DecryptString : Failed to decrypt the string ");
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
// WARNING : Decrypted string is not NULL terminated
|
||||
// So we will create new NULL terminated string here...
|
||||
|
||||
*clearData = (char*) malloc( finalLen + 1 );
|
||||
|
||||
if( *clearData == NULL )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n DecryptString :Insufficient memory... ");
|
||||
return FPM_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintMessage(MESG_DEBUG, "\n DecryptString : Copying new data ....");
|
||||
memcpy(*clearData, finalData, finalLen);
|
||||
*(*clearData + finalLen) = 0; // Null terminate the string....
|
||||
}
|
||||
|
||||
/*
|
||||
// Free the allocated memory
|
||||
// This is causing the problems currently...Later point we have to reanalyze the cause for this
|
||||
|
||||
if( decodeData )
|
||||
free(decodeData);
|
||||
|
||||
if( finalData )
|
||||
free(finalData);
|
||||
*/
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n decryptString : finalLen = %d ", finalLen);
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// otherwise do our own de-obscuring
|
||||
PrintMessage(MESG_DEBUG, "\n DecryptString : Performing simple Base64 Decoding ");
|
||||
|
||||
unsigned int PREFIX_Len = strlen(CRYPT_PREFIX);
|
||||
if( strlen(cryptData) == PREFIX_Len )
|
||||
{
|
||||
*clearData = (char *)malloc(1);
|
||||
**clearData = '\0';
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
if( CryptBase64Decode(&cryptData[PREFIX_Len], clearData, &decodeLen) == FPM_FALSE )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n DecryptString : Base64 decoding of crypt data failed ");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs base64 encoding of the encrypted data..
|
||||
*
|
||||
* @param(in) cryptData encrypted data
|
||||
* @param(in) cryptDataLen length of encrypted data
|
||||
* @param(out) encodeData base64 encoded data
|
||||
*
|
||||
* @return FPM_TRUE on success and FPM_FALSE on error.
|
||||
*
|
||||
*/
|
||||
|
||||
int CryptManager::CryptBase64Encode(char *cryptData, int cryptDataLen, char **encodeData)
|
||||
{
|
||||
|
||||
*encodeData = (*PLBase64Encode)((const char *)cryptData, cryptDataLen, NULL);
|
||||
|
||||
if ( *encodeData == NULL )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n Base64 encoding failed ...");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs base64 decoding of the encrypted data..
|
||||
*
|
||||
* @param(in) cryptData encrypted data
|
||||
* @param(out) decodeData base64 decoded data
|
||||
* @param(out) decodeLen length of base64 decoded data
|
||||
*
|
||||
* @return FPM_TRUE on success and FPM_FALSE on error.
|
||||
*
|
||||
*/
|
||||
int CryptManager::CryptBase64Decode(char *cryptData, char **decodeData, int *decodeLen)
|
||||
{
|
||||
int len = strlen( cryptData );
|
||||
int adjust = 0;
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n CryptBase64Decode : Length of crypt data = %d", len);
|
||||
|
||||
// Compute length adjustment
|
||||
if (cryptData[len-1] == '=')
|
||||
{
|
||||
adjust++;
|
||||
if (cryptData[len-2] == '=')
|
||||
adjust++;
|
||||
}
|
||||
|
||||
*decodeData = ( char *)(*PLBase64Decode)(cryptData, len, NULL);
|
||||
|
||||
if( *decodeData == NULL )
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n Base64 decoding failed ...");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
*decodeLen = (len*3)/4 - adjust;
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n CryptBase64Decode : Length of decoded data = %d", *decodeLen);
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs TRIPLE DES encryption of clear text data
|
||||
*
|
||||
* @param(in) clearData clear text data to be encrypted
|
||||
* @param(in) clearDataLen length of clear text data
|
||||
* @param(out) cryptData TRIPLE DES encrypted data
|
||||
* @param(out) cryptDataLen length of encrypted data
|
||||
*
|
||||
* @return FPM_TRUE on success and FPM_FALSE on error.
|
||||
*
|
||||
*/
|
||||
int CryptManager::CryptPK11EncryptString(char *clearData, int clearDataLen, char **cryptData, int *cryptDataLen)
|
||||
{
|
||||
PK11SlotInfo *slot = 0;
|
||||
SECItem keyid;
|
||||
SECItem request;
|
||||
SECItem reply;
|
||||
SECStatus status;
|
||||
|
||||
slot = (*PK11GetInternalKeySlot)();
|
||||
|
||||
if (!slot)
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n CryptPK11EncryptString : PK11_GetInternalKeySlot failed ...");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
// PK11 authentication
|
||||
if ( (*PK11Authenticate)(slot, PR_TRUE, NULL) != SECSuccess)
|
||||
{
|
||||
// since we have specified password callback function , we won't come here...
|
||||
PrintMessage(MESG_ERROR, "\n CryptPK11EncryptString : PK11_Authenticate failed, possibly master password is wrong");
|
||||
return FPM_MASTERPASSWORD_WRONG;
|
||||
}
|
||||
|
||||
|
||||
// Use default key id
|
||||
keyid.data = 0;
|
||||
keyid.len = 0;
|
||||
request.data = (unsigned char *)clearData;
|
||||
request.len = clearDataLen;
|
||||
reply.data = 0;
|
||||
reply.len = 0;
|
||||
|
||||
status = (*PK11SDREncrypt)(&keyid, &request, &reply, NULL);
|
||||
|
||||
if (status != SECSuccess)
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n CryptPK11EncryptString : PK11SDR_Encrypt failed ...");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
|
||||
*cryptData = (char*)reply.data;
|
||||
*cryptDataLen = reply.len;
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Performs TRIPLE DES decryption of base64 decoded data
|
||||
*
|
||||
* @param(in) decodeData base64 decoded data
|
||||
* @param(in) decodeLen length of base64 decoded data
|
||||
* @param(out) clearData decrypted data
|
||||
* @param(out) finalLen length of decrypted data
|
||||
*
|
||||
* @return FPM_TRUE on success and FPM_FALSE on error.
|
||||
*
|
||||
*/
|
||||
int CryptManager::CryptPK11DecryptString(char *decodeData, int decodeLen, char **clearData, int *finalLen)
|
||||
{
|
||||
PK11SlotInfo *slot = 0;
|
||||
SECStatus status;
|
||||
SECItem request;
|
||||
SECItem reply;
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n CryptPK11DecryptString entered ...");
|
||||
|
||||
// Find token with SDR key
|
||||
slot = (*PK11GetInternalKeySlot)();
|
||||
|
||||
if (!slot)
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n PK11_GetInternalKeySlot failed ...");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n PK11_GetInternalKeySlot SUCCESS ...");
|
||||
|
||||
// Force authentication
|
||||
if ( (*PK11Authenticate)(slot, PR_TRUE, NULL) != SECSuccess)
|
||||
{
|
||||
// since we have specified password callback function , we won't come here...
|
||||
PrintMessage(MESG_ERROR, "\n PK11_Authenticate failed, Probably master password is wrong");
|
||||
return FPM_MASTERPASSWORD_WRONG;
|
||||
}
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n PK11_Authenticate SUCCESS ...");
|
||||
|
||||
// Decrypt the string
|
||||
request.data = (unsigned char *)decodeData;
|
||||
request.len = decodeLen;
|
||||
reply.data = 0;
|
||||
reply.len = 0;
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n calling PK11SDR_Decrypt ...");
|
||||
|
||||
status = (*PK11SDRDecrypt)(&request, &reply, NULL);
|
||||
|
||||
if (status != SECSuccess)
|
||||
{
|
||||
PrintMessage(MESG_ERROR, "\n PK11SDR_Decrypt failed ...");
|
||||
return FPM_FALSE;
|
||||
}
|
||||
|
||||
PrintMessage(MESG_DEBUG, "\n PK11SDR_Decrypt SUCCESS ");
|
||||
|
||||
// WARNING : This string is not NULL terminated..
|
||||
*clearData = (char*)reply.data;
|
||||
*finalLen = reply.len;
|
||||
|
||||
// Free the slot
|
||||
(*PK11FreeSlot) (slot);
|
||||
|
||||
return FPM_TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user