Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
platform
active.directory
adsi
adsi.iis-admin
base
com_ole
complus_mts
component_svcs
database
directx
gdi
graphics_mm
internet.client
internet.server
internet.server.isapi-dev
localization
mapi
messaging
msi
mslayerforunicode
multimedia
networking
networking.ipv6
sdk_install
security
shell
telephony.tapi_2
telephony.tapi_3
telephony.tsp
telephony.wte
tools
ui
ui_shell
win_base_svcs
win16
  
 
date: Wed, 10 Sep 2008 02:57:01 -0700,    group: microsoft.public.platformsdk.security        back       


How to import certificate and PrK from PFX file to smart card   
I'm struggling with this problem already a few hours.

The task is as follows:
- I've got a PFX (PKCS#12) blob in memory.
- I need to import the certificate and private key to smart card


I can import PFX blob into a certstore using PFXImportCertStore(...)

That returns a HCERTSTORE and I don't know what to do with it further...


I'd be grateful even if you could point me in the right direction - what to 
look for, or the principle of importing it to the smart card.

Thanks in advance
date: Wed, 10 Sep 2008 02:57:01 -0700   author:   Ondrej P. Ondrej

RE: How to import certificate and PrK from PFX file to smart card   
Hi,

Once you have the HCERTSTORE returned by PFXImportCertStore, you must 
enumerate all the certificates on this store using 
CertEnumCertificatesInStore. For each certificate found, do the following : 

 - Retrieve its CERT_KEY_PROV_INFO_PROP_ID property using 
CertGetCertificateContextProperty. If it doesn't exists, then this is 
certainly a standalone certificate with no associated key ( a root 
certificate for example)
 - Using the information from the property mentioned above, call the 
function CryptAcquireCertificatePrivateKey to get a handle on the CSP context 
of the key associated with this certificate.
 - Call CryptGetUserKey to get a handle on the private key.
 - Call CryptExportKey to export the private key as a PRIVATEKEYBLOB blob.
 - Here you have all the needed information to import the certificate and 
its private key into the smart card. You can for example create a new 
container on the card using CryptAcquireContext , then import the private key 
using CryptImportKey and finally put the certificate in the card by setting 
the KP_CERTIFICATE property on the key you have just created.

I hope the above steps are clear enough to help you in what you intend to do.

Cheers,
-- 
Mounir IDRASSI
IDRIX
http://www.idrix.fr

To reach me: mounir_idrix_fr (replace the underscores with the at and dot 
characters respectively)


"Ondrej P." wrote:

> I'm struggling with this problem already a few hours.
> 
> The task is as follows:
> - I've got a PFX (PKCS#12) blob in memory.
> - I need to import the certificate and private key to smart card
> 
> 
> I can import PFX blob into a certstore using PFXImportCertStore(...)
> 
> That returns a HCERTSTORE and I don't know what to do with it further...
> 
> 
> I'd be grateful even if you could point me in the right direction - what to 
> look for, or the principle of importing it to the smart card.
> 
> Thanks in advance
date: Wed, 17 Sep 2008 09:18:01 -0700   author:   Mounir IDRASSI am

RE: How to import certificate and PrK from PFX file to smart card   
Thank you for your advice.

It really did help and I've moved a fair bit, but I've still got some 
problems...

Even though my code runs without errors, it doesn't write the certificate 
and key to the smart card.



Here is the source code:

----------------------------------
void MyClassDlg::importCertKeyToSmartCard(CString cardPIN, _CRYPTOAPI_BLOB 
&pkcs12data, CString password)
{
	HCERTSTORE hCS;

	hCS = PFXImportCertStore(&pkcs12data, (LPCWSTR) password, CRYPT_EXPORTABLE 
| CRYPT_USER_KEYSET );
	if(hCS == NULL) 
	{
		return;
	}

	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;
	
	CString readerName = m_readers[m_cbReaders.GetCurSel()]->description;
	if(readerName.GetLength() > 0) 	{
		readerName.SetAt(readerName.GetLength()-1, ' ' );
		readerName.TrimRight();
	} 

	CString containerName(L"MyContainer");
	CString containerNameFull;
	containerNameFull.Format(L"\\\\.\\%s\\%s", readerName, containerName);

	success = CryptAcquireContextW(&cardCryptoProvider, 
(LPCTSTR)containerNameFull, L"Siemens Card API 
CSP",			PROV_RSA_FULL,CRYPT_NEWKEYSET// | CRYPT_SILENT	);
	if(!success) {
		return;
	}


	// log in using PIN

	char* pin;
	long pinBufferLength = cardPIN.GetLength()+1;
	pin = new char[pinBufferLength];
	
	WideCharToMultiByte(GetACP(), 0, cardPIN, pinBufferLength-1, pin, 
pinBufferLength, 0, 0);
	
	pin[pinBufferLength-1] = 0;


	success = CryptSetProvParam(cardCryptoProvider, PP_KEYEXCHANGE_PIN, 
(BYTE*)pin, 0);
	if(!success){
		err = GetLastError();
		return;
	}

	delete [] pin;

	do
	{
		pCC = CertEnumCertificatesInStore(hCS, pCC);
		if(pCC == NULL) 
		{
			break;
		}

		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();
			break;
		}

		pKeyProvInfo = (CRYPT_KEY_PROV_INFO*) pData;

		success = CryptAcquireCertificatePrivateKey(pCC,CRYPT_ACQUIRE_SILENT_FLAG, 
NULL, &cryptoProvider, &cryptAcquireCertificatePrivateKeyFlags, &callerFree);
		if(!success) {
			err = GetLastError();
			break;
		}

		success = CryptGetUserKey(cryptoProvider, AT_KEYEXCHANGE, &cryptKeyHandle);
		if(!success){
			err = GetLastError();
			break;
		}


		// export key

		success = CryptGenKey(cryptoProvider, CALG_3DES, CRYPT_EXPORTABLE, 
&sessionKeyHandle);
		if(!success){
			err = GetLastError();
			break;
		}

		CryptExportKey(cryptKeyHandle, sessionKeyHandle, PRIVATEKEYBLOB, 0, NULL, 
&pkSize );
		pPk = new BYTE[pkSize];

		success = CryptExportKey(cryptKeyHandle, NULL, PRIVATEKEYBLOB, 0, pPk, 
&pkSize );
		if(!success){
			err = GetLastError();
			break;
		}


		// import key

		success = CryptImportKey(cardCryptoProvider, pPk, pkSize, 
sessionKeyHandle, 0, &importedKey);
		if(!success){
			err = GetLastError();
			break;
		}

		// import certificate

		success = CryptSetKeyParam(importedKey, KP_CERTIFICATE, 
pCC->pbCertEncoded, 0);
		if(!success){
			err = GetLastError();
			break;
		}
		
	}
	while(false);

	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);
	}

}

----------------------------------



"Mounir IDRASSI" wrote:

> Hi,
> 
> Once you have the HCERTSTORE returned by PFXImportCertStore, you must 
> enumerate all the certificates on this store using 
> CertEnumCertificatesInStore. For each certificate found, do the following : 
> 
>  - Retrieve its CERT_KEY_PROV_INFO_PROP_ID property using 
> CertGetCertificateContextProperty. If it doesn't exists, then this is 
> certainly a standalone certificate with no associated key ( a root 
> certificate for example)
>  - Using the information from the property mentioned above, call the 
> function CryptAcquireCertificatePrivateKey to get a handle on the CSP context 
> of the key associated with this certificate.
>  - Call CryptGetUserKey to get a handle on the private key.
>  - Call CryptExportKey to export the private key as a PRIVATEKEYBLOB blob.
>  - Here you have all the needed information to import the certificate and 
> its private key into the smart card. You can for example create a new 
> container on the card using CryptAcquireContext , then import the private key 
> using CryptImportKey and finally put the certificate in the card by setting 
> the KP_CERTIFICATE property on the key you have just created.
> 
> I hope the above steps are clear enough to help you in what you intend to do.
> 
> Cheers,
> -- 
> Mounir IDRASSI
> IDRIX
> http://www.idrix.fr
date: Tue, 23 Sep 2008 06:50:08 -0700   author:   Ondrej P.

RE: How to import certificate and PrK from PFX file to smart card   
Just for reference I will write here how I solved the problem:

The CryptImportKey implemented in Siemens card API needs 4th parameter to be 
zero (found in API doc), so I removed CryptGenKey and replaced 
sessionKeyHandle with zeros.
date: Thu, 25 Sep 2008 02:07:01 -0700   author:   Ondrej P.

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us