diff options
Diffstat (limited to 'libdigidoc/DigiCrypt.c')
-rw-r--r-- | libdigidoc/DigiCrypt.c | 1006 |
1 files changed, 1006 insertions, 0 deletions
diff --git a/libdigidoc/DigiCrypt.c b/libdigidoc/DigiCrypt.c new file mode 100644 index 0000000..0930a31 --- /dev/null +++ b/libdigidoc/DigiCrypt.c @@ -0,0 +1,1006 @@ +//==========< HISTORY >============================= +// 29.10.2003 Changes by AA +// ReadCertFromCard adapted +// from Tarmo's example +// 09.10.2003 Changes by AA +// 02.09.2003 Changes from Tarmo Milva +//Changed functions: +//DigiCrypt_GetDataFromCert +//DigiCrypt_GetFirstAllowedCSPName +//DigiCrypt_GetDefaultKeyContainerName +//DigiCrypt_SelectFromAllKeysCerts +// +#include "DigiCrypt.h" +#include "DigiDocDefs.h" +#include "DigiDocConfig.h" +#include <stdio.h> +#include <tchar.h> + +#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) + +#define dSTRING_ITEM_LEN 255 +#define dNAME_ITEM_LEN 1024 +#define dCSPTYPE_NOTDEFINED -1 + +static char *psData_CSP_Path = "SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\"; +static char *psData_Extra_CSP_Name = "Advanced Setec SetCSP"; +static char *psData_Ignore_CSP_Name ="XXXEstEID"; +static char *psData_Est_CSP_Name = "EstEID"; + +//Global data +static HCRYPTPROV oG_hProvider = 0; +static char oG_sCSPName[dSTRING_ITEM_LEN+1]; +static char oG_sKeyContainerName[dNAME_ITEM_LEN+1]; +static BOOL oG_fDialogUserCancel; + +extern int RunDialogUnit(char *psList[], int iWinWidth, int iWinHeight); + PCCERT_CONTEXT DigiCrypt_ReadCertFromCard(void); +static BOOL DigiCrypt_AddCertToStore(PCCERT_CONTEXT pCert); + +static BOOL OpenProvider(HCRYPTPROV *phProv, char *psProvider, DWORD dwFlags); +static HCERTSTORE DigiCrypt_OpenStore(void); +static char *DigiCrypt_GetFirstAllowedCSPNameNew(void); +static char *DigiCrypt_GetFirstAllowedCSPName(void); +static void DigiCrypt_ReleaseFirstAllowedCSP(void); +static BOOL DigiCrypt_GetCSPFromCert(PCCERT_CONTEXT pCertContext, char *psResult, int iMaxResLen); +static BOOL DigiCrypt_GetContainerFromCert(PCCERT_CONTEXT pCertContext, char *psResult, int iMaxResLen); +static BOOL DigiCrypt_CertIsSig(PCCERT_CONTEXT pCertContext); + +static char *DigiCrypt_GetDefaultKeyContainerName(char *psCSPName); +static char *DigiCrypt_GetDefaultKeyContainerNameSimple(char *psCSPName); +static char *DigiCrypt_GetDefaultCSPName(void); +static BOOL DigiCrypt_GetDataFromCert(PCCERT_CONTEXT pCertContext); +static PCCERT_CONTEXT DigiCrypt_SelectFromAllCerts(void); +static PCCERT_CONTEXT DigiCrypt_SelectFromAllKeysCerts(HCRYPTPROV hProvider); +static void DigiCrypt_SelectCertsFromKeyContainer(HCRYPTPROV hProv, char *psContainerName); +static void DigiCrypt_ChangeContainerName(char *psContainerName); + +static void RunDlg_Clear(void); +static BOOL RunDlg_AddItem(PCCERT_CONTEXT pCertContext, BOOL fTimeCheck); +static PCCERT_CONTEXT RunDlg_RunDlg(void); +static BOOL RunDlg_FillItem(PCCERT_CONTEXT pCertContext, char *psRes, int len); + +static void IntLogToFile(char *psMsg, int iMsgLen); +static BOOL IsLogEnabled(void); + +PCCERT_CONTEXT DigiCrypt_FindContext(BOOL fByKeyContainer, DWORD *dwResult) +{ + PCCERT_CONTEXT hCert = NULL; + char *psCSPName; + char *psDefaultKeyContainerName; + oG_fDialogUserCancel = FALSE; + + *dwResult = dDigiCrypt_Okey; + memset(oG_sCSPName, 0, sizeof(oG_sCSPName)); + memset(oG_sKeyContainerName, 0, sizeof(oG_sKeyContainerName)); + + if (fByKeyContainer == TRUE) { + hCert = DigiCrypt_ReadCertFromCard(); + //TEST + //Test_ReadCertDataC(hCert); + //ENDTEST + if (hCert == NULL) { + psCSPName = DigiCrypt_GetFirstAllowedCSPNameNew(); + if (psCSPName == NULL) + *dwResult = dDigiCrypt_Error_NotFoundCSP; + else { + psDefaultKeyContainerName = DigiCrypt_GetDefaultKeyContainerName(oG_sCSPName); + if (psDefaultKeyContainerName == NULL) + *dwResult = dDigiCrypt_Error_NoDefaultKey; + else + hCert = DigiCrypt_SelectFromAllKeysCerts(oG_hProvider); + } + } + } else { + hCert = DigiCrypt_SelectFromAllCerts(); + if (hCert != NULL) + DigiCrypt_GetDataFromCert(hCert); + } + if (hCert == NULL) { + if (oG_fDialogUserCancel == TRUE) + *dwResult = dDigiCrypt_Error_UserCancel; + else { + if (*dwResult == dDigiCrypt_Okey) + *dwResult = dDIgiCrypt_Error_NotFoundCert; + } + } + return(hCert); +} + +PCCERT_CONTEXT DigiCrypt_ReadCertFromCard(void) +{ +HCRYPTPROV hCryptProv; +BYTE *pbData = NULL; +HCRYPTKEY hKey; +DWORD cbData = 0; +DWORD dwKeyType=0, dwKeySpec = AT_SIGNATURE; +DWORD dwErrCode=0; +DWORD cspType=0; +DWORD cspFlag=CRYPT_SILENT; +char *psCspName = NULL; +char *psKeyContainer; +BOOL fRes = FALSE; +PCCERT_CONTEXT pCertContext = NULL; +CRYPT_KEY_PROV_INFO KeyProvInfo; +LPWSTR wszContainerName=NULL; +LPWSTR wszProvName=NULL; +DWORD cchContainerName; +DWORD cchCSPName; +HCRYPTPROV hProv; + + +DigiCrypt_ReleaseFirstAllowedCSP(); + +psCspName=DigiCrypt_GetFirstAllowedCSPNameNew(); + +//very dummy thing.. i check from csp creators why i should do so... +if(!lstrcmp(psCspName,"EstEID Card CSP")) + fRes = CryptAcquireContext(&hProv,"XXX",psCspName,2, CRYPT_SILENT); +// end dummy// + +if (psCspName == NULL || strstr(psCspName,psData_Est_CSP_Name) == NULL) + return(pCertContext); + +cspType=DigiCrypt_FindContext_GetCSPType(psCspName); + +psKeyContainer=DigiCrypt_GetDefaultKeyContainerName(psCspName); + +fRes = CryptAcquireContext(&hCryptProv,psKeyContainer,psCspName,cspType, CRYPT_SILENT); +if (fRes == FALSE) + return(pCertContext); + +// VS: use alsu auth keys if KEY_USAGE_CHECK=false +dwKeySpec = ConfigItem_lookup_int("KEY_USAGE_CHECK", 1) ? AT_SIGNATURE : 0; + +fRes=CryptGetUserKey(hCryptProv, dwKeySpec, &hKey); +if (fRes == TRUE) + { + fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &cbData, 0); + if (fRes == TRUE) + { + pbData = malloc(cbData); + if (pbData == NULL) + fRes = FALSE; + } + if (fRes == TRUE) + fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, pbData, &cbData, 0); + if (fRes == TRUE) + { + pCertContext = CertCreateCertificateContext(MY_ENCODING_TYPE,pbData,cbData); + if (pCertContext != NULL) + { + wszContainerName=NULL; + wszProvName=NULL; + cchContainerName = (lstrlen(psKeyContainer) + 1) * sizeof(WCHAR); + cchCSPName = (lstrlen(psCspName) + 1) * sizeof(WCHAR); + wszContainerName = (LPWSTR) malloc(cchContainerName); + wszProvName = (LPWSTR) malloc(cchCSPName); + mbstowcs(wszContainerName, psKeyContainer,cchContainerName); + mbstowcs(wszProvName, psCspName, cchCSPName); + ZeroMemory((PVOID)&KeyProvInfo, sizeof(CRYPT_KEY_PROV_INFO)); + KeyProvInfo.pwszContainerName = (LPWSTR) wszContainerName; + KeyProvInfo.pwszProvName = (LPWSTR) wszProvName; + KeyProvInfo.dwProvType = PROV_RSA_SIG; + KeyProvInfo.dwFlags = 0; + KeyProvInfo.dwKeySpec = dwKeyType; + fRes = CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, (const void *) &KeyProvInfo); + if (wszContainerName != NULL) + free(wszContainerName); + if (wszProvName != NULL) + free(wszProvName); + + } + } + } + +//if (pCertContext != NULL) +// DigiCrypt_AddCertToStore(pCertContext); +if (fRes == FALSE && pCertContext != NULL) + { + CertFreeCertificateContext(pCertContext); + pCertContext = NULL; + } +if (pbData != NULL) + free(pbData); +if (hCryptProv != 0) + CryptReleaseContext(hCryptProv, 0); +return(pCertContext); +} + + +static BOOL DigiCrypt_AddCertToStore(PCCERT_CONTEXT pCert) +{ +BOOL fRes = FALSE; +HCERTSTORE hSystemStore = NULL; // The system store handle. +if (pCert != NULL) + { + if (hSystemStore = CertOpenStore( + CERT_STORE_PROV_SYSTEM_A, + 0, // Encoding type not needed with this PROV. + 0, // Accept the default HCRYPTPROV. + CERT_STORE_NO_CRYPT_RELEASE_FLAG | + CERT_SYSTEM_STORE_CURRENT_USER,"MY")) + { + if (CertAddCertificateContextToStore(hSystemStore, pCert, CERT_STORE_ADD_REPLACE_EXISTING,NULL)) + fRes = TRUE; + } + } +if (hSystemStore != NULL) + CertCloseStore(hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG); +return(fRes); +} + + +char *DigiCrypt_FindContext_GetKeyName() +{ + if (lstrlen(oG_sKeyContainerName) > 0) + return(oG_sKeyContainerName); + else + return(NULL); +} + +char *DigiCrypt_FindContext_GetCSPName() +{ + if (lstrlen(oG_sCSPName) > 0) + return(oG_sCSPName); + else + return(NULL); +} + +DWORD DigiCrypt_FindContext_GetCSPType(char *psCSPName) +{ + DWORD dwRes = PROV_RSA_SIG; + DWORD dwType = REG_DWORD; + DWORD dwLen = dSTRING_ITEM_LEN; + DWORD *pdwVal; + HKEY hKey; + LONG lRes; + char sKeyNameBuf[dSTRING_ITEM_LEN+1]; + char sValue[dSTRING_ITEM_LEN+1]; + + strncpy(sKeyNameBuf, psData_CSP_Path, sizeof(sKeyNameBuf)); + strncat(sKeyNameBuf, psCSPName, sizeof(sKeyNameBuf) - strlen(sKeyNameBuf)); + lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE,sKeyNameBuf, 0, KEY_READ, &hKey); + if (lRes == ERROR_SUCCESS) { + lRes = RegQueryValueEx(hKey, "Type", 0, &dwType, (LPBYTE)sValue, &dwLen); + if (lRes == ERROR_SUCCESS) { + pdwVal = (DWORD *)sValue; + dwRes = (*pdwVal); + } + RegCloseKey(hKey); + } + return(dwRes); +} + +static BOOL OpenProvider(HCRYPTPROV *phProv, char *psProvider, DWORD dwFlags) +{ + BOOL fRes; + DWORD dwType = DigiCrypt_FindContext_GetCSPType(psProvider); + fRes = CryptAcquireContext(phProv,NULL,psProvider, dwType, dwFlags); + return(fRes); +} + +static HCERTSTORE DigiCrypt_OpenStore(void) +{ +HCERTSTORE hStore; +hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM,0,(HCRYPTPROV)NULL,CERT_SYSTEM_STORE_CURRENT_USER,L"MY"); +return(hStore); +} + + +static BOOL DigiCrypt_GetCSPFromCert(PCCERT_CONTEXT pCertContext, char *psResult, int iMaxResLen) +{ +BOOL fRes = FALSE; +CRYPT_KEY_PROV_INFO *poKeyInfo; +DWORD pcbData; +DWORD dwLen; +if (pCertContext == NULL || psResult == 0) + return(fRes); +fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,NULL,&pcbData); +if (fRes == TRUE) + { + poKeyInfo = malloc(pcbData); + if (poKeyInfo != NULL) + { + fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,poKeyInfo,&pcbData); + if (fRes == TRUE) + { + if (poKeyInfo->pwszProvName != NULL) + { + dwLen = WideCharToMultiByte(CP_ACP,0,poKeyInfo->pwszProvName,-1,psResult,iMaxResLen,NULL,NULL); + } + else + fRes = FALSE; + } + free(poKeyInfo); + } + } +return(fRes); +} + +static BOOL DigiCrypt_GetContainerFromCert(PCCERT_CONTEXT pCertContext, char *psResult, int iMaxResLen) +{ +BOOL fRes = FALSE; +CRYPT_KEY_PROV_INFO *poKeyInfo; +DWORD pcbData; +DWORD dwLen; +if (pCertContext == NULL || psResult == 0) + return(fRes); +fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,NULL,&pcbData); +if (fRes == TRUE) + { + poKeyInfo = malloc(pcbData); + if (poKeyInfo != NULL) + { + fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,poKeyInfo,&pcbData); + if (fRes == TRUE) + { + if (poKeyInfo->pwszContainerName != NULL) + { + + dwLen = WideCharToMultiByte(CP_ACP,0,poKeyInfo->pwszContainerName,-1,psResult,iMaxResLen,NULL,NULL); + } + else + fRes = FALSE; + } + free(poKeyInfo); + } + } +return(fRes); +} + +static BOOL DigiCrypt_CertIsSig(PCCERT_CONTEXT pCertContext) +{ +BOOL fRes = FALSE; +CRYPT_KEY_PROV_INFO *poKeyInfo; +DWORD pcbData; +if (pCertContext == NULL) + return(fRes); +fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,NULL,&pcbData); +if (fRes == TRUE) + { + poKeyInfo = malloc(pcbData); + if (poKeyInfo != NULL) + { + fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,poKeyInfo,&pcbData); + if (fRes == TRUE) + { + if (poKeyInfo->dwProvType == PROV_RSA_SIG) + fRes = TRUE; + } + free(poKeyInfo); + } + } +return(fRes); +} + + +static BOOL DigiCrypt_GetDataFromCert(PCCERT_CONTEXT pCertContext) +{ + BOOL fRes = FALSE; + char sContainer[dNAME_ITEM_LEN+1]; + //DWORD dwLen; + if (pCertContext == NULL) + return(fRes); + fRes = DigiCrypt_GetCSPFromCert(pCertContext, oG_sCSPName,dSTRING_ITEM_LEN); + + if (fRes == TRUE) { + // DigiCrypt_GetDefaultKeyContainerNameSimple(oG_sCSPName); //this is not usable. Tarmo changed that! Instead we should use the following: + if (DigiCrypt_GetContainerFromCert(pCertContext, sContainer, dNAME_ITEM_LEN) == TRUE) { + strncpy(oG_sKeyContainerName, sContainer, sizeof(oG_sKeyContainerName)); + } + } + return(fRes); +} + +static char *DigiCrypt_GetFirstAllowedCSPNameNew(void) +{ + char *psRes = NULL; + HKEY hKey = NULL; + LONG lRet=0; + DWORD dwIndex = 0; + BOOL fRes; + char sProvName[dSTRING_ITEM_LEN+1]; + char sKeyNameBuf[dSTRING_ITEM_LEN+1]; + HCRYPTPROV hProvide = 0; + DWORD dwBufLen; + FILETIME oTime; + //char buff[200]; + BYTE pbData[dNAME_ITEM_LEN+1]; + DWORD cbData=dNAME_ITEM_LEN+1; + // + DWORD dwProvType; + + strncpy(sKeyNameBuf, psData_CSP_Path, sizeof(sKeyNameBuf)); + lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,sKeyNameBuf,0, KEY_READ, &hKey); + + while (lRet == ERROR_SUCCESS) { + dwBufLen = dSTRING_ITEM_LEN; + lRet = RegEnumKeyEx(hKey,dwIndex,sProvName,&dwBufLen,NULL,NULL,0,&oTime); + if (lRet == ERROR_SUCCESS) { + if (lstrcmp(sProvName,psData_Ignore_CSP_Name) != 0) { + dwProvType = DigiCrypt_FindContext_GetCSPType(sProvName); + LOG("CSP %s",sProvName); + //printf("%s :",sProvName); + if ((lstrcmp(sProvName,psData_Extra_CSP_Name) != 0) && (lstrcmp(sProvName,"Belgium Identity Card CSP")!=0)) { + //fRes = OpenProvider(&hProvide, sProvName, CRYPT_SILENT); + fRes = CryptAcquireContext(&hProvide,NULL,sProvName,dwProvType, CRYPT_SILENT); + fRes=CryptGetProvParam(hProvide, PP_ENUMCONTAINERS, pbData, &cbData,CRYPT_FIRST); + // printf("X\n"); + } else { + //fRes = OpenProvider(&hProvide, sProvName, CRYPT_VERIFYCONTEXT); + //fRes = CryptAcquireContext(&hProvide,"SetCARDKeyContainer",sProvName,dwProvType, CRYPT_SILENT); + fRes = CryptAcquireContext(&hProvide,NULL,sProvName,dwProvType, CRYPT_VERIFYCONTEXT); + if (fRes == TRUE) { + //the extra csp might give wrong answer. We should ask from provider, why. + //The following is the work-around -- try to lookup key container from the card. + //if the result is negative this is a not the csp what is needed. + fRes=CryptGetProvParam(hProvide, PP_ENUMCONTAINERS, pbData, &cbData,CRYPT_FIRST); + if (fRes == TRUE) + fRes=CryptAcquireContext(&hProvide,(char*)pbData,sProvName,dwProvType, CRYPT_SILENT); + } + } + //printf("fRes: %x\n",GetLastError()); + if (fRes == TRUE) { // && dwProvType == 2) + // printf("OK %d %s\n",cbData, pbData); + //set global values + LOG("CSP %s accepted",sProvName); + //is it hardware token? + cbData=dNAME_ITEM_LEN+1; + if (CryptGetProvParam(hProvide, PP_IMPTYPE, pbData, &cbData, 0)) { + //printf("implementat: %d\n",pbData[0]); + if((pbData[0] & 1)) // hardware token + { + strncpy(oG_sCSPName, sProvName, sizeof(oG_sCSPName)); + //CryptReleaseContext(hProvide, 0); + psRes = oG_sCSPName; + break; + } + } + } + } + } + //hProvide = 0; + CryptReleaseContext(hProvide, 0); + dwIndex++; + } + if (hKey != NULL) + RegCloseKey(hKey); + return(psRes); +} + + +static char *DigiCrypt_GetFirstAllowedCSPName(void) +{ + char *psRes = NULL; + HKEY hKey = NULL; + LONG lRet=0; + DWORD dwIndex = 0; + BOOL fRes; + char sProvName[dSTRING_ITEM_LEN+1]; + char sKeyNameBuf[dSTRING_ITEM_LEN+1]; + HCRYPTPROV hProvide = 0; + DWORD dwBufLen; + FILETIME oTime; + //char buff[200]; + BYTE pbData[dNAME_ITEM_LEN+1]; + DWORD cbData=dNAME_ITEM_LEN+1; + DWORD dwProvType; + + strncpy(sKeyNameBuf, psData_CSP_Path, sizeof(sKeyNameBuf)); + lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,sKeyNameBuf,0, KEY_READ, &hKey); + while (lRet == ERROR_SUCCESS) { + dwBufLen = dSTRING_ITEM_LEN; + lRet = RegEnumKeyEx(hKey,dwIndex,sProvName,&dwBufLen,NULL,NULL,0,&oTime); + if (lRet == ERROR_SUCCESS) { + if (lstrcmp(sProvName,psData_Ignore_CSP_Name) != 0) { + dwProvType = DigiCrypt_FindContext_GetCSPType(sProvName); + LOG("CSP %s",sProvName); + if (lstrcmp(sProvName,psData_Extra_CSP_Name) != 0) + fRes = OpenProvider(&hProvide, sProvName, CRYPT_SILENT); + else { + fRes = OpenProvider(&hProvide, sProvName, CRYPT_VERIFYCONTEXT); + //fRes = CryptAcquireContext(&hProvide,"SetCARDKeyContainer",sProvName,dwProvType, CRYPT_SILENT); + fRes = CryptAcquireContext(&hProvide,NULL,sProvName,dwProvType, CRYPT_VERIFYCONTEXT); + if(fRes) { + //the extra csp might give wrong answer. We should ask from provider, why. + //The following is the work-around -- try to lookup key container from the card. + //if the result is negative this is a not the csp what is needed. + fRes=CryptGetProvParam(hProvide, PP_ENUMCONTAINERS, pbData, &cbData,CRYPT_FIRST); + } + } + if (fRes == TRUE) { // && dwProvType == 2) + //set global values + LOG("CSP %s accepted",sProvName); + strncpy(oG_sCSPName, sProvName, sizeof(oG_sCSPName)); + CryptReleaseContext(hProvide, 0); + psRes = oG_sCSPName; + break; + } + } + } + //hProvide = 0; + CryptReleaseContext(hProvide, 0); + dwIndex++; + } + if (hKey != NULL) + RegCloseKey(hKey); + return(psRes); +} + + +static void DigiCrypt_ReleaseFirstAllowedCSP(void) +{ + //clear global values + if (oG_hProvider != 0) + CryptReleaseContext(oG_hProvider, 0); + oG_hProvider = 0; + oG_sCSPName[0] = 0; +} + +static char *DigiCrypt_GetDefaultKeyContainerName(char *psCSPName) +{ + char *psRes = NULL; + HCRYPTPROV hProvider; + BOOL fRes; + DWORD dwFlags = CRYPT_VERIFYCONTEXT; + BYTE pbData[dNAME_ITEM_LEN+1]; + DWORD cbData = dNAME_ITEM_LEN; + DWORD dwError; + DWORD dwProvType; + + ZeroMemory(pbData,cbData); + ZeroMemory(oG_sKeyContainerName,1000); + dwProvType = DigiCrypt_FindContext_GetCSPType(psCSPName); + //LOG("GetDefaultKeyContainerName CSP=%s",psCSPName); + if (lstrcmp(psCSPName,psData_Extra_CSP_Name) != 0) + fRes = CryptAcquireContext(&hProvider,NULL,psCSPName,dwProvType, CRYPT_SILENT); + else + fRes = CryptAcquireContext(&hProvider,NULL,psCSPName,dwProvType, CRYPT_VERIFYCONTEXT); + if (fRes == FALSE && dwFlags == CRYPT_SILENT) { + //by description must be CRYPT_VERIFYCONTEXT + fRes = CryptAcquireContext(&hProvider,NULL,psCSPName,dwProvType, CRYPT_VERIFYCONTEXT); + } + if (fRes == TRUE) { + cbData = dNAME_ITEM_LEN; + fRes = CryptGetProvParam(hProvider, PP_CONTAINER, pbData, &cbData, 0); + /*if (fRes == FALSE) + dwError = GetLastError();*/ + } + //Some cards should not have default key container + //let try to find key containers on the card. + if (fRes == FALSE) { + fRes=CryptGetProvParam(hProvider, PP_ENUMCONTAINERS, pbData, &cbData,CRYPT_FIRST); + if (fRes == FALSE) + dwError = GetLastError(); + } + if (fRes == TRUE) { + //oG_hProvider = hProvider; + strncpy(oG_sKeyContainerName, (char *) pbData, sizeof(oG_sKeyContainerName)); + //psRes = oG_sKeyContainerName; + DigiCrypt_ChangeContainerName(oG_sKeyContainerName); + } else { + + } + if (psRes != NULL) + LOG("GetDefaultKeyContainerName CSP=%s",psCSPName); + else + LOG("GetDefaultKeyContainerName Not found"); + if (hProvider != 0) + CryptReleaseContext(hProvider, 0); + return(oG_sKeyContainerName); +} + +static char *DigiCrypt_GetDefaultKeyContainerNameSimple(char *psCSPName) +{ + char *psRes = NULL; + HCRYPTPROV hProvider=0; + BOOL fRes; + DWORD dwFlags = 0; + BYTE pbData[dNAME_ITEM_LEN+1]; + DWORD cbData = dNAME_ITEM_LEN; + DWORD dwError; + + fRes = OpenProvider(&hProvider, psCSPName, dwFlags); + //fRes = CryptAcquireContext(&hProvider,NULL,psCSPName,PROV_RSA_SIG, dwFlags); + if (fRes == TRUE) { + fRes = CryptGetProvParam(hProvider, PP_CONTAINER, pbData, &cbData, 0); + if (fRes == FALSE) + dwError = GetLastError(); + } + if (fRes == TRUE) { + strncpy(oG_sKeyContainerName, pbData, sizeof(oG_sKeyContainerName)); + psRes = oG_sKeyContainerName; + DigiCrypt_ChangeContainerName(oG_sKeyContainerName); + } + if (hProvider != 0) + CryptReleaseContext(hProvider, 0); + return(psRes); +} + + +static PCCERT_CONTEXT DigiCrypt_SelectFromAllCerts(void) +{ +PCCERT_CONTEXT pCertContext = NULL; +HCERTSTORE hStore; +hStore = DigiCrypt_OpenStore(); +if (hStore != NULL) + { + while (TRUE) + { + pCertContext = CertEnumCertificatesInStore(hStore,pCertContext); + if (pCertContext == NULL) + break; + else + { + //TEST + //Test_ReadCertDataC(pCertContext); + //END TEST + RunDlg_AddItem(pCertContext,TRUE); + } + } + pCertContext = RunDlg_RunDlg(); + } +return(pCertContext); +} + +static void DigiCrypt_SelectCertsFromKeyContainer(HCRYPTPROV hProv, char *psContainerName) +{ +PCCERT_CONTEXT pCertContext = NULL; +HCERTSTORE hStore; +BOOL fRelease = FALSE; +char sContainer[dNAME_ITEM_LEN+1]; + +if (memcmp(psContainerName,"AUT",3) == 0) + { + LOG("Find1 Ignore AUT cert"); + return; + } +hStore = DigiCrypt_OpenStore(); +if (hStore != NULL) + { + while (TRUE) + { + pCertContext = CertEnumCertificatesInStore(hStore,pCertContext); + if (pCertContext == NULL) + break; + else + { + if (DigiCrypt_GetContainerFromCert(pCertContext, sContainer, dNAME_ITEM_LEN) == TRUE) + { + + LOG("Find1 Container %s %s",sContainer,psContainerName); + if (lstrcmp(sContainer+3,psContainerName+3) == 0) + { + LOG("Find1 Container %s accepted",sContainer); + RunDlg_AddItem(pCertContext,TRUE); + } + } + } + } + } +else + LOG("Find1 Can't open store"); +if (fRelease == TRUE) + CryptReleaseContext(hProv, 0); +} + +static PCCERT_CONTEXT DigiCrypt_SelectFromAllKeysCerts(HCRYPTPROV hProvider) +{ +PCCERT_CONTEXT pCertContext = NULL; +HCRYPTPROV hProv; +BYTE pbData[dNAME_ITEM_LEN+1]; +DWORD cbData = dNAME_ITEM_LEN; +DWORD dwFlag; +BOOL fRes; +BOOL fRelease = FALSE; +CRYPT_KEY_PROV_INFO* poKeyInfo = NULL; +char sContainer[dNAME_ITEM_LEN+1]; + +hProv = hProvider; + + +if (hProv == 0) + { + fRes = OpenProvider(&hProv, oG_sCSPName, CRYPT_VERIFYCONTEXT); + //fRes = CryptAcquireContext(&hProv,NULL,oG_sCSPName,PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + if (fRes == FALSE) + { + + LOG("Find1 - Can't open provider"); + return(pCertContext); + } + fRelease = TRUE; + } + dwFlag = CRYPT_FIRST; + fRes = TRUE; + while (fRes == TRUE) + { + cbData = dNAME_ITEM_LEN; + cbData = 0; + fRes = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &cbData, dwFlag); + if (fRes == TRUE) + fRes = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, pbData, &cbData, dwFlag); + dwFlag = 0; + + if (fRes == FALSE) + { + if (GetLastError() == ERROR_NO_MORE_ITEMS) + { + LOG("Find1 End"); + fRes = TRUE; + break; + } + } + else + { + LOG("Find1 select certs from %s",pbData); + DigiCrypt_SelectCertsFromKeyContainer(hProv, pbData); + } + } + pCertContext = RunDlg_RunDlg(); + //we have selected the cert, but do we know corresponding key? + //let change values of globals when these are different + if(DigiCrypt_GetContainerFromCert(pCertContext, sContainer, dNAME_ITEM_LEN) == TRUE) { + strncpy(oG_sKeyContainerName, sContainer, sizeof(oG_sKeyContainerName)); + } + if(fRelease == TRUE) + CryptReleaseContext(hProv, 0); + return(pCertContext); +} + + +static BOOL DigiCrypt_IsValidCert(PCCERT_CONTEXT pCertContext, BOOL fTimeCheck) +{ +BOOL fIsValid = FALSE; +BOOL fRes = FALSE; +BOOL fKuCheck = TRUE; +BYTE bKeyUsageBits = CERT_NON_REPUDIATION_KEY_USAGE; +DWORD dwKeyUsageBytes = 1; +// VS use auth certs if key_usage_check = 0 +fKuCheck = (BOOL)ConfigItem_lookup_int("KEY_USAGE_CHECK", 1); +bKeyUsageBits = fKuCheck ? CERT_NON_REPUDIATION_KEY_USAGE : 0; +//LOG("KEY_USAGE_CHECK: %d ku: %d", fKuCheck, bKeyUsageBits); +//Old version +//FILETIME oCurrentTime; +if (pCertContext != NULL && pCertContext->pCertInfo != NULL) + { + //not needed (info from Tarmo Milva) + //if (DigiCrypt_CertIsSig(pCertContext) == TRUE) + fRes = CertGetIntendedKeyUsage(X509_ASN_ENCODING,pCertContext->pCertInfo,&bKeyUsageBits,dwKeyUsageBytes); + //else + // fRes = FALSE; + if (fRes == TRUE) + { + //LOG("KU non-repu: %d", (bKeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE)); + if(!fKuCheck || (bKeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE)) + fIsValid = TRUE; + if(bKeyUsageBits & CERT_KEY_CERT_SIGN_KEY_USAGE) // don't display CA certs + fIsValid = FALSE; + } + if (fIsValid == TRUE && fTimeCheck == TRUE) + { + //Old version + //GetSystemTimeAsFileTime(&oCurrentTime); + //if (CompareFileTime(&oCurrentTime, &pCertContext->pCertInfo->NotBefore) < 0 || + // CompareFileTime(&oCurrentTime, &pCertContext->pCertInfo->NotAfter) > 0 ) + // fIsValid = FALSE; + //New version + //NULL, if current datetime + if (CertVerifyTimeValidity(NULL,pCertContext->pCertInfo) != 0) + fIsValid = FALSE; + } + } +return(fIsValid); +} + +static void DigiCrypt_ChangeContainerName(char *psContainerName) +{ +if (memcmp(psContainerName,"AUT",3) == 0) + memmove(psContainerName,"SIG",3); +} + +//dialog functions +#define DLGMAXIEMS 512 +static char *psListItems[DLGMAXIEMS]; +static PCCERT_CONTEXT psListItemsCert[DLGMAXIEMS]; +static int iListItems=0; + +static void RunDlg_Clear(void) +{ +int iI; +for (iI=0; iI < DLGMAXIEMS;++iI) + { + psListItems[iI] = NULL; + psListItemsCert[iI] = NULL; + } +iListItems=0; +} + +static BOOL RunDlg_AddItem(PCCERT_CONTEXT pCertContext, BOOL fTimeCheck) +{ +BOOL fRes = TRUE; +BOOL fAddToList = TRUE; +char *psData; +int iI, len; +if (iListItems == (DLGMAXIEMS-1)) + return(FALSE); +if (iListItems == 0) + { + for (iI=0; iI < DLGMAXIEMS;++iI) + { + psListItems[iI] = NULL; + psListItemsCert[iI] = NULL; + } + } +if (pCertContext != NULL) + { + fAddToList = DigiCrypt_IsValidCert(pCertContext,fTimeCheck); + if (fAddToList == TRUE) + { + len = dSTRING_ITEM_LEN*4; + psListItems[iListItems] = (char *)LocalAlloc(LMEM_ZEROINIT,(len)); + psListItemsCert[iListItems] = CertDuplicateCertificateContext(pCertContext); + //Make data buffer for list + psData = psListItems[iListItems]; + RunDlg_FillItem(pCertContext, psData, len); + ++iListItems; + } + } +return(fRes); +} + + +static PCCERT_CONTEXT RunDlg_RunDlg(void) +{ +PCCERT_CONTEXT hCert = NULL; +int iRes = -1; +int iI; +oG_fDialogUserCancel = FALSE; +if (iListItems > 1) + { + LOG("StartDialog"); + iRes = RunDialogUnit(psListItems, 450,300); + if (iRes < 0) + oG_fDialogUserCancel = TRUE; + LOG("EndDialog"); + } +else + { + if (iListItems == 1) + iRes = 0; + } +for (iI=0; iI < iListItems;++iI) + { + LocalFree(psListItems[iI]); + if (iRes != iI) + CertFreeCertificateContext(psListItemsCert[iI]); + else + hCert = psListItemsCert[iI]; + } +iListItems = 0; +return(hCert); +} + +static BOOL RunDlg_FillItem(PCCERT_CONTEXT pCertContext, char *psRes, int len) +{ + char sTemp[dSTRING_ITEM_LEN+1]; + SYSTEMTIME oT; + PCERT_INFO pCertInfo; + BOOL fRes = TRUE; + *psRes = 0; + + if (pCertContext == NULL || pCertContext->pCertInfo == NULL || psRes == NULL) + return(FALSE); + pCertInfo = pCertContext->pCertInfo; + CertGetNameString(pCertContext,CERT_NAME_SIMPLE_DISPLAY_TYPE,CERT_NAME_ISSUER_FLAG,NULL,sTemp,dSTRING_ITEM_LEN); + if (lstrlen(sTemp) > 0) { + strncat(psRes, sTemp, len - strlen(psRes)); + strncat(psRes, " \t", len - strlen(psRes)); + } + CertGetNameString(pCertContext,CERT_NAME_SIMPLE_DISPLAY_TYPE,0,NULL,sTemp,dSTRING_ITEM_LEN); + //CorrectCharacters(sTemp); + if (lstrlen(sTemp) > 0) { + strncat(psRes, sTemp, len - strlen(psRes)); + strncat(psRes, " \t", len - strlen(psRes)); + } + if (FileTimeToSystemTime(&pCertInfo->NotBefore,&oT) == TRUE) { + snprintf(sTemp, sizeof(sTemp), "%02d/%02d/%02d \t",oT.wYear,oT.wMonth,oT.wDay); + strncat(psRes, sTemp, len - strlen(psRes)); + } + else + fRes = FALSE; + if (FileTimeToSystemTime(&pCertInfo->NotAfter,&oT) == TRUE) { + snprintf(sTemp, sizeof(sTemp), "02d/%02d/%02d \t",oT.wYear,oT.wMonth,oT.wDay); + strncat(psRes,sTemp, len - strlen(psRes)); + } + else + fRes = FALSE; + if (DigiCrypt_GetCSPFromCert(pCertContext, sTemp, dSTRING_ITEM_LEN) == TRUE) + strncat(psRes,sTemp, len - strlen(psRes)); + return(fRes); +} + +static char sLogLine[4096]; +static char sLogFile[256]; +static int iLogCheck = -1; + +static BOOL IsLogEnabled(void) +{ + BOOL fRes = FALSE; + DWORD dwRes; + char cVal; + HANDLE hSearch; + WIN32_FIND_DATA oF; + + if(iLogCheck == -1) { + iLogCheck = 0; + dwRes = GetModuleFileName(NULL, sLogFile, 255); + //strcpy(sLogFile, "z:\\digicrypt.log"); dwRes=1;iLogCheck = 1; + //MessageBox(NULL,sLogFile,"LogFile=",MB_OK|MB_SYSTEMMODAL|MB_ICONERROR); + while (dwRes > 1) { + cVal = sLogFile[dwRes-1]; + if (cVal == '.') { + strncat(sLogFile, "log", sizeof(sLogFile) - strlen(sLogFile)); + hSearch = FindFirstFile(sLogFile,&oF); + if (hSearch != INVALID_HANDLE_VALUE) { + iLogCheck = 1; + FindClose(hSearch); + } + break; + } + --dwRes; + } + } + fRes = (BOOL)iLogCheck; + return(fRes); +} + +void LOG(char *psMsgFmt, ...) +{ + int iLen; + char buff[200]; + va_list ArgList; + va_start(ArgList, psMsgFmt); + iLen = wvsprintf((LPTSTR)sLogLine, (LPTSTR)psMsgFmt, ArgList); + snprintf(buff, sizeof(buff), (LPTSTR)psMsgFmt,ArgList); + //MessageBox(NULL,(LPTSTR)sLogLine,"Teade",0); + va_end(ArgList); + if (IsLogEnabled() == TRUE) + IntLogToFile(sLogLine,iLen); +} + +static void IntLogToFile(char *psMsg, int iMsgLen) +{ +char sLogFormat1[]="%02d%02d%02d %02d:%02d.%02d "; +char sTimeBuf[64]; +HANDLE hFile; +DWORD dwLen; +SYSTEMTIME oTime; +if (psMsg == NULL || iMsgLen == 0) + return; +GetLocalTime(&oTime); +wsprintf((LPTSTR)sTimeBuf,(LPTSTR)sLogFormat1, oTime.wYear-2000, oTime.wMonth, oTime.wDay, + oTime.wHour, oTime.wMinute, oTime.wSecond); +hFile = CreateFile((LPCTSTR)sLogFile, + GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + +if (hFile != INVALID_HANDLE_VALUE) + { + if (psMsg != NULL) + { + SetFilePointer(hFile,0,NULL,FILE_END); + WriteFile(hFile,sTimeBuf, strlen(sTimeBuf), &dwLen, NULL); + if (iMsgLen < 0) + iMsgLen = strlen(psMsg); + if (iMsgLen > 0) + WriteFile(hFile,psMsg, iMsgLen, &dwLen, NULL); + WriteFile(hFile,"\r\n", 2, &dwLen, NULL); + } + CloseHandle(hFile); + } +} + + + |