Newsgroup: it.comp.programmare.win32
Titolo: Ma le CryptoAPI sbroccano ?

Un ciao a tutto il newsgroup,
ho un problema saltato fuori come un fulmine a ciel sereno in 
un controllo OCX che utilizza le cryptoAPI.
Il componente, in un suo metodo,  non fà altro che prendere i
certificati installati in una smart card
Orga Micardo 2.1 e installarli nel sistema. ( quello che riporto sotto
è un frammento di codice, dove viene generato l'errore e non tutta la
funzione. ).
L'errore che mi viene restituito è "si è verificato un errore interno"
e mi viene dato all'altezza della funzione
sts = CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &dwDataLen, 0); 
Come mi devo comportare di fronte ad un errore così generico,
considerando che con altre smart card funziona ?
Grazie mille a chiunque mi risponderà...
Leonardo
/*************************************/
/*** INSTALLAZIONE DEI CERTIFICATI ***/
/*** UTENTE DALLA SMART-CARD *********/
/*************************************/
{
	BOOL sts = FALSE;
	HCERTSTORE hCertStore = NULL;
	HCRYPTPROV hProv = 0;
	HCRYPTKEY hKey = 0;
	DWORD dwProvType = PROV_RSA_FULL;
	DWORD dwFlags = CRYPT_MACHINE_KEYSET;
	DWORD dwDataLen=255;
	WCHAR* wszProvider = NULL;
	WCHAR* wszContainer = NULL;
	PCCERT_CONTEXT pCert = NULL;
	BYTE* pbCert = NULL;
	PCRYPT_KEY_PROV_INFO keyProvInfo = NULL;
	BOOL bContinue=TRUE;
	int numero_certificato=0,i=0;
	/*************************************/
	/*** IMPOSTAZIONE DEL NOME DEL CSP ***/
	/*************************************/
	CONST CHAR* pszProvider = "Orga Micardo Card CSP v1.0";
 
	/**************************************************/
	/*** ACQUISIZIONE DEL NOME DEL LETTORE E **********/
	/*** IMPOSTAZIONE DELLA STRINGA PER CONNETTERSI ***/
	/*** AL LETTORE/CARTA/CONTAINER *******************/
	/**************************************************/
	char* szReaderName = malloc(ATSIGN_SCARD_MAX_READER_NAME_LEN);
	char* pszReader;
	char  pszContainer[255];
	char* pszData;
	/*****************************/
	/*** ACQ. NOME DEL LETTORE ***/
	/*****************************/
	atsignSCardGetReaderName( szReaderName );
	/*********************************************************/
	/*** COSTRUZIONE DELLA STRINGA DI ACQUIS. DEL CONTESTO ***/
	/*********************************************************/
	pszReader=malloc(strlen(szReaderName)+10);
	strcpy(pszReader,"\\\\.\\");;
	strcat(pszReader,szReaderName);
	strcat(pszReader,"\\");
	/*******************************/
	/*** SCRITTURA FILE DI DEBUG ***/
	/*******************************/
	ScriviDebug_stringa("Lettore : ");
	ScriviDebug_stringa(pszReader);
	ScriviDebug_stringa("\n");
 
	while (bContinue==TRUE)
	{
 
		sts = CryptAcquireContext(&hProv,(LPCSTR)pszReader,pszProvider,dwProvType,dwFlags);
		if (!sts) 
		{	
			dwLastError=GetLastError();	
			bContinue=FALSE;
			break;
		}
 
		//Prendo il nome del container successivo
		for	(i=0;i<=numero_certificato;i++)
		{
			sts = CryptGetProvParam(hProv,	PP_ENUMCONTAINERS, 
			(BYTE*)pszContainer,&dwDataLen,CRYPT_NEXT);
			if (!sts) 
			{
				dwLastError=ERROR_SUCCESS;
				bContinue=FALSE;
				break;
			}
		}
 
		// Rilascio il provider
		CryptReleaseContext(hProv,0);
 
		pszData = (char*) malloc(sizeof(char)*(25 + dwDataLen));
		memcpy((void*)pszData, pszReader, 25);
		memcpy(pszData+25, pszContainer, dwDataLen);
		// Apro il container corrente
		sts = CryptAcquireContext(&hProv,(LPCSTR)pszData,pszProvider,
				dwProvType,CRYPT_MACHINE_KEYSET);
 
 
		if (!sts) 
		{
			dwLastError=GetLastError();
			bContinue=FALSE;
			break;
		}
		// Prendo le informazioni sulla key
		sts = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey);
		if (!sts) 
		{
			dwLastError=GetLastError();
			bContinue=FALSE;
			break;
		}
		// Prendo la dim in bytes del certificato
		sts = CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &dwDataLen, 0);
		if (!sts) 
		{
			dwLastError=GetLastError();
			bContinue=FALSE;
			break;
		}
		// Dimensiona mem per accogliere il Certificato
		pbCert = (BYTE*)malloc(dwDataLen);
		if (!pbCert) 
		{
			dwLastError=GetLastError();
			bContinue=FALSE;
			break;
		}
		// Carica il certificato associato alla chiave
		sts = CryptGetKeyParam(hKey, KP_CERTIFICATE, pbCert, &dwDataLen, 0);
		if (!sts) 
		{
			dwLastError=GetLastError();
			bContinue=FALSE;
			break;
		}
		// Crea il contesto per il certificato
		pCert = CertCreateCertificateContext(X509_ASN_ENCODING |
PKCS_7_ASN_ENCODING, pbCert, dwDataLen);
		if (pCert == NULL) 
		{
			dwLastError=GetLastError();
			bContinue=FALSE;
			break;
		}
		// Dimensiona mem per accogliere le informazioni sul provider
		keyProvInfo = (PCRYPT_KEY_PROV_INFO)malloc(dwDataLen);
		keyProvInfo->dwFlags = 0;
		keyProvInfo->cProvParam = 0;
		keyProvInfo->rgProvParam = 0;
		keyProvInfo->dwKeySpec = AT_KEYEXCHANGE;
		keyProvInfo->dwProvType = PROV_RSA_FULL;
		dwDataLen = strlen(pszProvider)+1;
		wszProvider = (WCHAR *) malloc(dwDataLen * sizeof(WCHAR));
		MultiByteToWideChar( CP_ACP, 0, pszProvider, dwDataLen, wszProvider,
dwDataLen);
		keyProvInfo->pwszProvName = wszProvider;
		dwDataLen = strlen(pszContainer)+1;
		wszContainer = (WCHAR *) malloc(dwDataLen * sizeof(WCHAR));
		MultiByteToWideChar( CP_ACP, 0, pszContainer,dwDataLen,
wszContainer, dwDataLen);
		keyProvInfo->pwszContainerName = wszContainer;
		// Imposta i dati del PROVIDER nel certificato
		sts = CertSetCertificateContextProperty(pCert,
CERT_KEY_PROV_INFO_PROP_ID,	0, keyProvInfo);
		if (!sts) {dwLastError=GetLastError();bContinue=FALSE;break;}
		// Apro lo USER STORE
		hCertStore = CertOpenStore(	CERT_STORE_PROV_SYSTEM_W, 0, 
							hProv,CERT_SYSTEM_STORE_CURRENT_USER,L"MY");
		if (!hCertStore) 
		{
			dwLastError=GetLastError();
			bContinue=FALSE;
			break;
		}
		// Aggiungo o rimpiazzo il certificato nello USER STORE
		if (hCertStore)
		{
			sts = CertAddCertificateContextToStore(	hCertStore,	
				pCert,
				CERT_STORE_ADD_REPLACE_EXISTING,
				NULL);
		}
		if (hKey) 
		{
			CryptDestroyKey(hKey);
		}
		if (hProv) 
		{
			CryptReleaseContext(hProv, 0);
		}
 
		numero_certificato=numero_certificato+1;
	}
	if (hCertStore) CertCloseStore(hCertStore,
CERT_CLOSE_STORE_FORCE_FLAG);
	if (pbCert) free(pbCert);
	if (pCert) CertFreeCertificateContext(pCert);
	if (keyProvInfo) free(keyProvInfo);
	if (wszProvider) free(wszProvider);
	if (wszContainer) free(wszContainer);
 
}

On 22 Feb 2003 10:02:59 -0800, 
prin...@principe101.net
 (principe101)
wrote:
riassumo una parte del codice:
numero_certificato=0;
while(bContinue)
{
    CryptAcquireContext();
    for(i=0;i!=numero_certificato;i++)
       CryptGetProvParam();
    CryptReleaseContext();
    .... // do ohter things
    numero_certificato++;
}
non capisco perché ad ogni loop (intendo while(bcontinue))
chiami x volte CryptGetProvParam
non č ugale scrivere:
CryptAcquireContext();
while(bContinue)
{
   CryptGetProvParam();
    .... // do ohter things
}
CryptReleaseContext();
o il context va rilasciato subito per qualche motivo a me oscuro? (
come il resto delle api in questione? =)) 
hai dei memory leak cmq.. mancano delle free... anche se non credo sia
questo il tuo problema...
ciao
 sbirish

come il resto delle api in questione? =)) 
ehrm cough.. CryptoGetProvParam non viene chiamato al primo loop
... non va chiamata con CRYPT_FIRST la prima volta? che mi sfugge?