Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

CryptImportKey returns Invalid Parameter

843811May 21 2010 — edited May 22 2010
Hello,

I've been trying for a while to import a ".pfx" file into an ACOS5 smart card (I need to do it by code).

I've managed to find a code online that does something to that effect but I've been having trouble making it work.

While it compiles properly, the program stops at CryptImportKey returning an error code of 87: Invalid Parameter (The program stops at the "Done 6.55" step in the code below).

Here is the source code of the program:
#include "stdafx.h"
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
	cout<<"Starting...\n";
	ifstream f1;
	f1.open("file.pfx",ios::binary);
	f1.seekg( 0, ios::end );
	size_t len = f1.tellg();
	char* charData = new char[len];
	f1.seekg(0, ios::beg);
	f1.read(charData, len);
	f1.close();
	
	cout<<"Done 1\n";
	//  convert char* to _CRYPTOAPI_BLOB
	
	byte* byteData = (BYTE*)charData;
	_CRYPTOAPI_BLOB pkcs12data = _CRYPTOAPI_BLOB();
	pkcs12data.cbData = static_cast<DWORD>(len);
	//buf = ctypes.create_string_buffer(datastr);
	pkcs12data.pbData = byteData;				//ctypes.cast(buf, ctypes.POINTER(ctypes.c_byte));
	
	// the rest also needs some editing
	cout<<"Done 2\n";
	HCERTSTORE hCS;

	hCS = PFXImportCertStore(&pkcs12data, L"1111", CRYPT_EXPORTABLE | CRYPT_USER_KEYSET );
	if(hCS == NULL)
	{
	return 1;
	}
	cout<<"Done 3\n";

	PCCERT_CONTEXT pCC(NULL);

	PBYTE pData(NULL);
	DWORD sizeOfData(0);

	BOOL success;
	BOOL callerFree;

	CRYPT_KEY_PROV_INFO* pKeyProvInfo(NULL);
	HCRYPTPROV cryptoProvider(0), cardCryptoProvider(0);

	DWORD cryptAcquireCertificatePrivateKeyFlags = AT_KEYEXCHANGE;

	HCRYPTKEY cryptKeyHandle(0);
	HCRYPTKEY sessionKeyHandle(0);
	HCRYPTKEY importedKey(0);

	BYTE* pPk(NULL);
	DWORD pkSize;

	DWORD err;

	cout<<"Done 4\n";
	// log in using PIN

	/*// PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN 
	char* pin;
	//char* cardPIN = "12345678";
	long pinBufferLength = 8+1;
	pin = new char[pinBufferLength];

	WideCharToMultiByte(GetACP(), 0, L"12345678", pinBufferLength-1, pin, pinBufferLength, 0, 0);

	pin[pinBufferLength-1] = 0;

	cout<<"Done 5\n";
	
	
	byte* pinData = (BYTE*)pin;

	success = CryptSetProvParam(cardCryptoProvider, PP_KEYEXCHANGE_PIN, (BYTE*)pinData, 0);
	if(!success){
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}
	
	cout<<"Done 6\n";

	delete [] pin;
	*/// PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN PIN 

	pCC = CertEnumCertificatesInStore(hCS, pCC);
	if(pCC == NULL)
	{
		return 1;
	}
	
	cout<<"Done 6.1\n";

	CertGetCertificateContextProperty(pCC, CERT_KEY_PROV_INFO_PROP_ID, NULL, &sizeOfData);
	pData = new BYTE[sizeOfData];

	success = CertGetCertificateContextProperty(pCC, CERT_KEY_PROV_INFO_PROP_ID, (PVOID)pData, &sizeOfData);
	if(!success) {
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}

	cout<<"Done 6.2\n";

	pKeyProvInfo = (CRYPT_KEY_PROV_INFO*) pData;

	success = CryptAcquireCertificatePrivateKey(pCC,NULL, NULL, &cryptoProvider, &cryptAcquireCertificatePrivateKeyFlags, &callerFree);
	if(!success) {
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}

	cout<<"Done 6.3\n";

	success = CryptGetUserKey(cryptoProvider, AT_KEYEXCHANGE, &cryptKeyHandle);
	if(!success){
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}

	cout<<"Done 6.4\n";

	// export key
	
	/*success = CryptGenKey(cryptoProvider, CALG_3DES, CRYPT_EXPORTABLE, &sessionKeyHandle);
	if(!success){
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}*/
	
	cout<<"Done 6.45\n";
	//cout<<pkSize <<endl;

	success = CryptExportKey(cryptKeyHandle, NULL, PRIVATEKEYBLOB, 0x00, NULL, &pkSize );
	if(!success){
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}
	pPk = new BYTE[pkSize];

	cout<<pkSize <<endl;

	success = CryptExportKey(cryptKeyHandle, NULL, PRIVATEKEYBLOB, 0x00, pPk, &pkSize );
	if(!success){
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}

	cout<<pkSize <<endl;
	cout<<"Done 6.5\n";

	if(CryptAcquireContextW(&cardCryptoProvider, L"11111111-1111-1111-1111-111111111111", L"Advanced Card Systems CSP v2.3", PROV_RSA_FULL,CRYPT_MACHINE_KEYSET))
	{
		printf("Key container has been opened.\n");
	}
	else{
		DWORD d = GetLastError();
		printf("%u\n",d);
		//return 1;*/
		if(CryptAcquireContextW(&cardCryptoProvider, L"11111111-1111-1111-1111-111111111111", L"Advanced Card Systems CSP v2.3", PROV_RSA_FULL,CRYPT_NEWKEYSET))
		{
			printf("A new key container has been created.\n");
		}
		else{
			DWORD d = GetLastError();
			printf("%u\n",d);
			return 1;
		}
	}
	
	cout<<"Done 6.55\n";

	// import key
	success = CryptImportKey(cardCryptoProvider, pPk, pkSize, 0, 0x00, &importedKey);
	//success = CryptImportKey(cardCryptoProvider, pPk, pkSize, sessionKeyHandle, 0, &importedKey);
	//success = CryptImportKey(cardCryptoProvider, pPk, pkSize, CRYPT_BLOB_VER3, CRYPT_EXPORTABLE, &importedKey);
	if(!success){
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}

	cout<<"Done 6.6\n";

	// import certificate

	success = CryptSetKeyParam(importedKey, KP_CERTIFICATE, pCC->pbCertEncoded, 0);
	if(!success){
		err = GetLastError();
		printf("%u\n",err);
		return 1;
	}

	cout<<"Done 7\n";

	if(pCC) {
		CertFreeCertificateContext(pCC);
	}

	if(pData) {
		delete [] pData;
		pData = NULL;
	}

	if(pPk) {
		memset(pPk, 0, pkSize);
		delete [] pPk;
		pPk = NULL;
	}

	if(importedKey) {
		CryptDestroyKey(importedKey);
	}

	if(cryptKeyHandle) {
		CryptDestroyKey(cryptKeyHandle);
	}

	if(callerFree && cryptoProvider) {
		CryptReleaseContext(cryptoProvider, NULL);
	}
	cout<<"end of program\n";
	return 0;
}
I'd greatly appreciate any advice concerning this problem.

Thanks in advance.
Regards,
Pascal Andraos.
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jun 19 2010
Added on May 21 2010
2 comments
1,036 views