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.