NTE_BAD_DATA



Hi ,

I am trying to my hard against developing a simple encryption and
decryption module using the self signed certificate. I am getting the
error of NTE_BAD_DATA in the decryption module.
Please help to debug my problem

My encryption and decryption module are as follows. I am not using the
password in the following code.

DECRYPTION CODE
------------------------------------------------------------------------------------------------------------------------
#define KEYLENGTH 0x00800000
#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8
#define CERT_SUBJECT_NAME "abc"
LPCTSTR UserName=(LPCTSTR)"bond007";

int _tmain(int argc, _TCHAR* argv[])
{
if(argc < 3)
{
_tprintf(TEXT("Usage: <example.exe> <source file> ")
TEXT("<destination file> | <password>\n"));
_tprintf(TEXT("<password> is optional.\n"));
_tprintf(TEXT("Press any key to exit."));
_gettch();
return 1;
}

LPTSTR pszSource = argv[1];
LPTSTR pszDestination = argv[2];
if(MyDecryptFile(pszSource, pszDestination))
{
_tprintf(TEXT("Encryption of the file %s was successful. \n"),
pszSource);
_tprintf(TEXT("The encrypted data is in file %s.
\n"),pszDestination);
} else
{ MyHandleError(TEXT("Error encrypting file!\n"),
GetLastError());
}
return 0;
}

//-------------------------------------------------------------------
// Code for the function MyDecryptFile called by main.
bool MyDecryptFile(LPTSTR pszSourceFile, LPTSTR pszDestinationFile)
{
//---------------------------------------------------------------
// Declare and initialize local variables.
bool fReturn = false;
HANDLE hSourceFile = INVALID_HANDLE_VALUE;
HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
HCRYPTKEY hKey = NULL;
HCRYPTPROV hCryptProv = NULL;

DWORD dwCount;
PBYTE pbBuffer = NULL;
DWORD dwBlockLen;
DWORD dwBufferLen;

//---------------------------------------------------------------
// Open the source file.
hSourceFile = CreateFile(pszSourceFile,
FILE_READ_DATA,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE != hSourceFile)
{
_tprintf(TEXT("The source encrypted file, %s, is open. \n"),
pszSourceFile);
}
else
{
MyHandleError(TEXT("Error opening source plaintext file!\n"),
GetLastError());
goto Exit_MyDecryptFile;
}

//---------------------------------------------------------------
// Open the destination file.
hDestinationFile = CreateFile(pszDestinationFile,
FILE_WRITE_DATA,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE != hDestinationFile)
{
_tprintf(TEXT("The destination file, %s, is open. \n"),
pszDestinationFile);
}else{
MyHandleError(TEXT("Error opening destination file!\n"),
GetLastError());
goto Exit_MyDecryptFile;
}
HCERTSTORE hSystemStore; // The system store handle.
PCCERT_CONTEXT pDesiredCert = NULL; // Set to NULL for the first
// call to
// CertFindCertificateInStore.
CERT_NAME_BLOB SubjNameBlob;
DWORD cbNameEncoded;
BYTE* pbNameEncoded;
CRYPT_BIT_BLOB pubkey;

//-------------------------------------------------------------------
// Declare and initialize variables

// Declare and initialize a CERT_RDN_ATTR array.
// In this code, only one array element is used.

CERT_RDN_ATTR rgNameAttr[] = {
"2.5.4.3", // pszObjId
CERT_RDN_PRINTABLE_STRING, // dwValueType
strlen(CERT_SUBJECT_NAME), // value.cbData
(BYTE*)CERT_SUBJECT_NAME}; // value.pbData

//-------------------------------------------------------------------
// Declare and initialize a CERT_RDN array.
// In this code, only one array element is used.

CERT_RDN rgRDN[] = {
1, // rgRDN[0].cRDNAttr
&rgNameAttr[0]}; // rgRDN[0].rgRDNAttr

//-------------------------------------------------------------------
// Declare and initialize a CERT_NAME_INFO structure.

CERT_NAME_INFO Name = {
1, // Name.cRDN
rgRDN}; // Name.rgRDN


//-------------------------------------------------------------------
// Begin processing.

if(CryptEncodeObject(
X509_ASN_ENCODING, // Encoding type
X509_NAME, // Structure type
&Name, // Address of CERT_NAME_INFO structure
NULL, // pbEncoded
&cbNameEncoded)) // pbEncoded size
{
printf("The first call to CryptEncodeObject succeeded. \n");
}
else
{
printf("The first call to CryptEncodeObject failed. \n");
}
//-------------------------------------------------------------------
// Allocate memory for the encoded name.

if(!(pbNameEncoded = (BYTE*)malloc(cbNameEncoded)))
printf("pbNamencoded malloc operation failed.\n");

//-------------------------------------------------------------------
// Call CryptEncodeObject to do the actual encoding of the name.

if(CryptEncodeObject(
X509_ASN_ENCODING, // Encoding type
X509_NAME, // Structure type
&Name, // Address of CERT_NAME_INFO structure
pbNameEncoded, // pbEncoded
&cbNameEncoded)) // pbEncoded size
{
printf("The object is encoded. \n");
}
else
{
free(pbNameEncoded);
printf("Second call to CryptEncodeObject failed.\n");
}
//-------------------------------------------------------------------
// Set the subject member of CertReqInfo to point to
// a CERT_NAME_INFO structure that
// has been initialized with the data from cbNameEncoded
// and pbNameEncoded.

SubjNameBlob.cbData = cbNameEncoded;
SubjNameBlob.pbData = pbNameEncoded;
//-------------------------------------------------------------------
// Open the certificate store to be searched.

if(hSystemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
X509_ASN_ENCODING, // Encoding type
NULL, // Accept the default HCRYPTPROV.
CERT_SYSTEM_STORE_CURRENT_USER,
// Set the system store location in the
registry.
L"MY")) // system stores including Trust, CA, or
Root.
{
printf("Opened the MY system store. \n");
}
else
{
printf( "Could not open the MY system store.\n");
exit(1);
}
//-------------------------------------------------------------------
// Get a certificate that has lpszCertSubject as its
// subject.

if(pDesiredCert=CertFindCertificateInStore(
hSystemStore,
X509_ASN_ENCODING, // Use X509_ASN_ENCODING.
0, // No dwFlags needed.
CERT_FIND_SUBJECT_NAME, // Find a certificate with a
// subject that matches the string
// in the next parameter.
&SubjNameBlob, // The Unicode string to be found
// in a certificate's subject.
NULL)) // NULL for the first call to the
// function. In all subsequent
// calls, it is the last pointer
// returned by the function.
{
printf("The desired certificate was found. \n");
}
else
{
printf("Could not find the desired certificate.\n");
}
DWORD dwKeySpec;
BOOL fCallerFreeProv;
if(CryptAcquireCertificatePrivateKey(
pDesiredCert,
CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
NULL,
&hCryptProv,
&dwKeySpec,
&fCallerFreeProv
))
{
if(CryptGetUserKey(
hCryptProv,
AT_KEYEXCHANGE,
&hKey))
{
_tprintf(TEXT("got the key handle"));
}
else
{
MyHandleError(TEXT("Error during CryptGetUserKey\n"),
GetLastError());
goto Exit_MyDecryptFile;
}
}

else
{
MyHandleError(TEXT("Error during CryptAcquireCertificatePrivateKey
\n"), GetLastError());
goto Exit_MyDecryptFile;
}
//---------------------------------------------------------------
// The decryption key is now available, either having been
// imported from a BLOB read in from the source file or having
// been created by using the password. This point in the program
// is not reached if the decryption key is not available.

//---------------------------------------------------------------
// Determine the number of bytes to decrypt at a time.
// This must be a multiple of ENCRYPT_BLOCK_SIZE.

dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
dwBufferLen = dwBlockLen;

//---------------------------------------------------------------
// Allocate memory for the file read buffer.
if(!(pbBuffer = (PBYTE)malloc(dwBufferLen)))
{
MyHandleError(TEXT("Out of memory!\n"), E_OUTOFMEMORY);
goto Exit_MyDecryptFile;
}

//---------------------------------------------------------------
// Decrypt the source file, and write to the destination file.
bool fEOF = false;
do
{
//-----------------------------------------------------------
// Read up to dwBlockLen bytes from the source file.
if(!ReadFile(
hSourceFile,
pbBuffer,
dwBlockLen,
&dwCount,
NULL))
{
MyHandleError(
TEXT("Error reading from source file!\n"),
GetLastError());
goto Exit_MyDecryptFile;
}

if(dwCount < dwBlockLen)
{
fEOF = TRUE;
}

//-----------------------------------------------------------
// Decrypt the block of data.
if(!CryptDecrypt(
hKey,
0,
fEOF,
0,
pbBuffer,
&dwCount))
{
MyHandleError(
TEXT("Error during CryptDecrypt!\n"),
GetLastError());
goto Exit_MyDecryptFile;
}

//-----------------------------------------------------------
// Write the decrypted data to the destination file.
if(!WriteFile(
hDestinationFile,
pbBuffer,
dwCount,
&dwCount,
NULL))
{
MyHandleError(
TEXT("Error writing ciphertext.\n"),
GetLastError());
goto Exit_MyDecryptFile;
}

//-----------------------------------------------------------
// End the do loop when the last block of the source file
// has been read, encrypted, and written to the destination
// file.
}while(!fEOF);

Exit_MyDecryptFile:


// Release the session key.
if(hKey){if(!(CryptDestroyKey(hKey))){
MyHandleError(TEXT("Error during CryptDestroyKey!\n"),
GetLastError());
}
}
// Release the provider handle.
if(hCryptProv) { if(!(CryptReleaseContext(hCryptProv,
0)))
{
MyHandleError(TEXT("Error during CryptReleaseContext!\n"),
GetLastError());
}
}

return fReturn;
}
void MyHandleError(LPTSTR psz, int nErrorNumber)
{
_ftprintf(stderr, TEXT("An error occurred in the program. \n"));
_ftprintf(stderr, TEXT("%s\n"), psz);
_ftprintf(stderr, TEXT("Error number %x.\n"), nErrorNumber);
}
------------------------------------------------------------------------------------------------------------------------




ENCRYPTION CODE

#define KEYLENGTH 0x00800000
#define ENCRYPT_ALGORITHM CALG_RC4
#define ENCRYPT_BLOCK_SIZE 8
LPCWSTR UserName = (LPCWSTR)"bond007";
#define CERT_SUBJECT_NAME "abc"

int _tmain(int argc, _TCHAR* argv[])
{
if(argc < 3)
{
_tprintf(TEXT("Usage: <example.exe> <source file> ")
TEXT("<destination file> | <password>\n"));
_tprintf(TEXT("<password> is optional.\n"));
_tprintf(TEXT("Press any key to exit."));
_gettch();
return 1;
}

LPTSTR pszSource = argv[1];
LPTSTR pszDestination = argv[2];
if(argc >= 4)
{
// pszPassword = argv[3];
}

//---------------------------------------------------------------
// Call EncryptFile to do the actual encryption.
if(MyEncryptFile(pszSource, pszDestination))
{
_tprintf(TEXT("Encryption of the file %s was successful. \n"),
pszSource);
_tprintf( TEXT("The encrypted data is in file %s.
\n"),pszDestination); getch();
}
else { MyHandleError(TEXT("Error encrypting file!\n"),
GetLastError());
}

return 0;
}

bool MyEncryptFile(
LPTSTR pszSourceFile,
LPTSTR pszDestinationFile)
{
//---------------------------------------------------------------
// Declare and initialize local variables.
bool fReturn = false;
HANDLE hSourceFile = INVALID_HANDLE_VALUE;
HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
//---------------------------------------------------------------
// Open the source file.
hSourceFile = CreateFile(
pszSourceFile,
FILE_READ_DATA,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE != hSourceFile)
{
_tprintf(
TEXT("The source plaintext file, %s, is open. \n"),
pszSourceFile);
}
else
{
MyHandleError(
TEXT("Error opening source plaintext file!\n"),
GetLastError());
goto Exit_MyEncryptFile;
}

//---------------------------------------------------------------
// Open the destination file.
hDestinationFile = CreateFile(
pszDestinationFile,
FILE_WRITE_DATA,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(INVALID_HANDLE_VALUE != hDestinationFile)
{
_tprintf(
TEXT("The destination file, %s, is open. \n"),
pszDestinationFile);
}
else
{
MyHandleError(
TEXT("Error opening destination file!\n"),
GetLastError());
goto Exit_MyEncryptFile;
}

//-------------------------------------------------------------------
// Declare and initialize variables.
HCERTSTORE hSystemStore; // The system store handle.
PCCERT_CONTEXT pDesiredCert = NULL; // Set to NULL for the first
// call to
// CertFindCertificateInStore.
CERT_NAME_BLOB SubjNameBlob;
DWORD cbNameEncoded;
BYTE* pbNameEncoded;
CRYPT_BIT_BLOB pubkey;

//-------------------------------------------------------------------
// Declare and initialize variables

// Declare and initialize a CERT_RDN_ATTR array.
// In this code, only one array element is used.

CERT_RDN_ATTR rgNameAttr[] = {
"2.5.4.3", // pszObjId
CERT_RDN_PRINTABLE_STRING, // dwValueType
strlen(CERT_SUBJECT_NAME), // value.cbData
(BYTE*)CERT_SUBJECT_NAME}; // value.pbData

//-------------------------------------------------------------------
// Declare and initialize a CERT_RDN array.
// In this code, only one array element is used.

CERT_RDN rgRDN[] = {
1, // rgRDN[0].cRDNAttr
&rgNameAttr[0]}; // rgRDN[0].rgRDNAttr

//-------------------------------------------------------------------
// Declare and initialize a CERT_NAME_INFO structure.

CERT_NAME_INFO Name = {
1, // Name.cRDN
rgRDN}; // Name.rgRDN


//-------------------------------------------------------------------
// Begin processing.

if(CryptEncodeObject(
X509_ASN_ENCODING, // Encoding type
X509_NAME, // Structure type
&Name, // Address of CERT_NAME_INFO structure
NULL, // pbEncoded
&cbNameEncoded)) // pbEncoded size
{
printf("The first call to CryptEncodeObject succeeded. \n");
}
else
{
printf("The first call to CryptEncodeObject failed. \n");
}
//-------------------------------------------------------------------
// Allocate memory for the encoded name.

if(!(pbNameEncoded = (BYTE*)malloc(cbNameEncoded)))
printf("pbNamencoded malloc operation failed.\n");

//-------------------------------------------------------------------
// Call CryptEncodeObject to do the actual encoding of the name.

if(CryptEncodeObject(
X509_ASN_ENCODING, // Encoding type
X509_NAME, // Structure type
&Name, // Address of CERT_NAME_INFO structure
pbNameEncoded, // pbEncoded
&cbNameEncoded)) // pbEncoded size
{
printf("The object is encoded. \n");
}
else
{
free(pbNameEncoded);
printf("Second call to CryptEncodeObject failed.\n");
}
//-------------------------------------------------------------------
// Set the subject member of CertReqInfo to point to
// a CERT_NAME_INFO structure that
// has been initialized with the data from cbNameEncoded
// and pbNameEncoded.

SubjNameBlob.cbData = cbNameEncoded;
SubjNameBlob.pbData = pbNameEncoded;
//-------------------------------------------------------------------
// Open the certificate store to be searched.

if(hSystemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
X509_ASN_ENCODING, // Encoding type
NULL, // Accept the default HCRYPTPROV.
CERT_SYSTEM_STORE_CURRENT_USER,
// Set the system store location in the
registry.
L"MY")) // system stores including Trust, CA, or
Root.
{
printf("Opened the MY system store. \n");
}
else
{
printf( "Could not open the MY system store.\n");
exit(1);
}
//-------------------------------------------------------------------
// Get a certificate that has lpszCertSubject as its
// subject.

if(pDesiredCert=CertFindCertificateInStore(
hSystemStore,
X509_ASN_ENCODING, // Use X509_ASN_ENCODING.
0, // No dwFlags needed.
CERT_FIND_SUBJECT_NAME, // Find a certificate with a
// subject that matches the string
// in the next parameter.
&SubjNameBlob, // The Unicode string to be found
// in a certificate's subject.
NULL)) // NULL for the first call to the
// function. In all subsequent
// calls, it is the last pointer
// returned by the function.
{
printf("The desired certificate was found. \n");
}
else
{
printf("Could not find the desired certificate.\n");
}


//---------------------------------------------------------------
// Get the handle to the default provider.
HCRYPTPROV hCryptProv = NULL;
if(CryptAcquireContext(
&hCryptProv,
NULL,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
0))
{
_tprintf(TEXT("A cryptographic provider has been acquired.
\n"));
}
else
{
if(CryptAcquireContext(
&hCryptProv,
NULL,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
_tprintf(TEXT("A cryptographic provider has been acquired.
\n"));
}
else{_tprintf(TEXT("Error during CryptAcquireContext!\n"),
GetLastError()); }
}

HCRYPTKEY hCertPubKey ;
if(CryptImportPublicKeyInfo(
hCryptProv,
X509_ASN_ENCODING,
&pDesiredCert->pCertInfo->SubjectPublicKeyInfo,
&hCertPubKey))
{
_tprintf(TEXT("get handle"));
}

CertFreeCertificateContext(pDesiredCert);
//---------------------------------------------------------------
// The session key is now ready. If it is not a key derived from
// a password, the session key encrypted with the private key
// has been written to the destination file.

//---------------------------------------------------------------
// Determine the number of bytes to encrypt at a time.
// This must be a multiple of ENCRYPT_BLOCK_SIZE.
// ENCRYPT_BLOCK_SIZE is set by a #define statement.
DWORD dwBufferLen,dwBlockLen,dwCount;
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
PBYTE pbBuffer;
//---------------------------------------------------------------
// Determine the block size. If a block cipher is used,
// it must have room for an extra block.
if(ENCRYPT_BLOCK_SIZE > 1)
{
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
}
else { dwBufferLen = dwBlockLen; }
//---------------------------------------------------------------
// Allocate memory.
if(pbBuffer = (BYTE *)malloc(dwBufferLen)){
_tprintf(TEXT("Memory has been allocated for the buffer.
\n"));
}
else
{
MyHandleError(TEXT("Out of memory. \n"), E_OUTOFMEMORY);
goto Exit_MyEncryptFile;
}

//---------------------------------------------------------------
// In a do loop, encrypt the source file,
// and write to the source file.
bool fEOF = FALSE;
do
{
//-----------------------------------------------------------
// Read up to dwBlockLen bytes from the source file.
if(!ReadFile(
hSourceFile,
pbBuffer,
dwBlockLen,
&dwCount,
NULL))
{
MyHandleError(TEXT("Error reading plaintext!\n"),
GetLastError());
goto Exit_MyEncryptFile;
}

if(dwCount < dwBlockLen)
{
fEOF = TRUE;
}

//-----------------------------------------------------------
// Encrypt data.
if(!CryptEncrypt(
hCertPubKey,
NULL,
fEOF,
0,
pbBuffer,
&dwCount,
dwBufferLen))
{
MyHandleError(TEXT("Error during CryptEncrypt. \n"),
GetLastError());
goto Exit_MyEncryptFile;
}
//-----------------------------------------------------------
// Write the encrypted data to the destination file.
if(!WriteFile(hDestinationFile,
pbBuffer,
dwCount,
&dwCount,
NULL))
{
MyHandleError(TEXT("Error writing ciphertext.\n"),
GetLastError());
goto Exit_MyEncryptFile;
}

//-----------------------------------------------------------
// End the do loop when the last block of the source file
// has been read, encrypted, and written to the destination
// file.
} while(!fEOF);

fReturn = true;

Exit_MyEncryptFile:

return fReturn;
} // End Encryptfile.

.