//------------------------------------------------------------------------------------- // Данный пример демонстрирует поиск контейнера соответствующего сертификату. // Для проверки работы примера необходимо создать контейнер и положить соответствующий // ему сертификат в файл test_search.cer. Программа возвращает имя найденного контейнера. //------------------------------------------------------------------------------------- BOOL CmpCertAndContFP(LPCSTR szContainerName, LPBYTE pbFPCert, DWORD cbFPCert); static void HandleError(char *s); int main(int argc, char **argv) { //------------------------------------------------------------------------ // Объявление переменных HCERTSTORE hFileStore; // Дескриптор хранилища сертификатов PCCERT_CONTEXT pCertCtx; // Контекст сертификата HCRYPTPROV hCryptProv; // Дескриптор криптопровайдера HCRYPTKEY hPublicKey; // Дескриптор ключа из сертификата LPBYTE pbFPCert; // Параметр FP из сертификата DWORD cbFPCert; // Размер параметра FP из сертификата LPBYTE pbContainerName; // Имя контейнера DWORD cbContainerName; // Размер имени контейнера DWORD dwFlags; if (2 != argc) { HandleError("Wrong arguments!"); } //------------------------------------------------------------------------ // Создание хранилища сертификатов из файла if ((hFileStore = CertOpenStore( CERT_STORE_PROV_FILENAME_A, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG, argv[1] // Файл с сертификатом ))) { printf("The file store was created successfully.\n"); } else { HandleError("An error occurred during creation of the file store!"); } //------------------------------------------------------------------------ // Получение контекста сертификата из хранилища if ((pCertCtx = CertEnumCertificatesInStore(hFileStore, NULL))) { printf("Certificate context was loaded from store.\n"); } else { HandleError("Error during CertEnumCertificatesInStore!"); } //------------------------------------------------------------------------ // Получение дескриптора криптопровайдера if (CryptAcquireContext( &hCryptProv, NULL, NULL, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT)) { printf("CryptAcquireContext succeeded. \n"); } else { HandleError("Error during CryptAcquireContext!"); } //------------------------------------------------------------------------ // Получение дескриптора открытого ключа из сертификата if (CryptImportPublicKeyInfo( hCryptProv, pCertCtx->dwCertEncodingType, &pCertCtx->pCertInfo->SubjectPublicKeyInfo, &hPublicKey)) { printf("CryptImportPublicKeyInfo succeeded. \n"); } else { HandleError("Error during CryptImportPublicKeyInfo!"); } //------------------------------------------------------------------------ // Получение параметра KP_FP открытого ключа из сертификата // Получение размера параметра if (CryptGetKeyParam(hPublicKey, KP_FP, NULL, &cbFPCert, 0)) { printf("CryptGetKeyParam KP_FP succeeded. \n"); } else { HandleError("Error during CryptGetKeyParam!"); } // Выделение памяти pbFPCert = (LPBYTE)malloc(cbFPCert); if (!pbFPCert) { HandleError("Fail to allocate memory!"); } // Получение параметра if (CryptGetKeyParam(hPublicKey, KP_FP, pbFPCert, &cbFPCert, 0)) { printf("CryptGetKeyParam KP_FP succeeded. \n"); } else { HandleError("Error during CryptGetKeyParam!"); } //------------------------------------------------------------------------ // Получение имени первого контейнера // Получение размера параметра if (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, NULL, &cbContainerName, CRYPT_FIRST)) { printf("CryptGetProvParam PP_ENUMCONTAINERS succeeded. \n"); } else { HandleError("Error during CryptGetProvParam!"); } // Выделение памяти pbContainerName = (LPBYTE)malloc(cbContainerName); if (!pbContainerName) { HandleError("Fail to allocate memory!"); } //------------------------------------------------------------------------ // Перебор всех контейнеров dwFlags = CRYPT_FIRST; while (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, pbContainerName, &cbContainerName, dwFlags | CRYPT_FQCN)) { if (CmpCertAndContFP((LPCSTR)pbContainerName, pbFPCert, cbFPCert)) { printf("Container found! Name: '%s'\n", pbContainerName); break; } dwFlags = CRYPT_NEXT; } //------------------------------------------------------------------------ // Освобождение памяти if (pbContainerName) free(pbContainerName); if (pbFPCert) free(pbFPCert); if (hFileStore) { if (!CertCloseStore(hFileStore, CERT_CLOSE_STORE_FORCE_FLAG)) { HandleError("Error during CertCloseStore!"); } } if (hPublicKey) { if (!CryptDestroyKey(hPublicKey)) { HandleError("Error during CryptDestroyKey!"); } } if (hCryptProv) { if (!CryptReleaseContext(hCryptProv, 0)) { HandleError("Error during CryptReleaseContext!"); } } return 0; } BOOL CmpCertAndContFP(LPCSTR szContainerName, LPBYTE pbFPCert, DWORD cbFPCert) { HCRYPTPROV hProvCont; LPBYTE pbFPCont; DWORD cbFPCont; BOOL result = FALSE; //------------------------------------------------------------------------ // Получение дескриптора контейнера if (CryptAcquireContext( &hProvCont, szContainerName, NULL, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT)) { printf("CryptAcquireContext for '%s' succeeded. \n", szContainerName); } else { HandleError("Error during CryptAcquireContext!\n"); } //------------------------------------------------------------------------ // Получение параметра PP_SIGNATURE_KEY_FP для ключа в контейнере cbFPCont = cbFPCert; // Размер FP из контейнера равен размеру FP из сертификата pbFPCont = (LPBYTE)malloc(cbFPCont); if (CryptGetProvParam(hProvCont, PP_SIGNATURE_KEY_FP, pbFPCont, &cbFPCont, 0)) { printf("CryptGetProvParam PP_SIGNATURE_KEY_FP for '%s' succeeded. \n", szContainerName); // Сравнение FP из сертификата с FP из контейнера if (!memcmp(pbFPCont, pbFPCert, cbFPCert)) { result = TRUE; goto Done; } } //------------------------------------------------------------------------ // Получение параметра PP_EXCHANGE_KEY_FP для ключа в контейнере if (CryptGetProvParam(hProvCont, PP_EXCHANGE_KEY_FP, pbFPCont, &cbFPCont, 0)) { printf("CryptGetProvParam PP_EXCHANGE_KEY_FP for '%s' succeeded. \n", szContainerName); // Сравнение FP из сертификата с FP из контейнера if (!memcmp(pbFPCont, pbFPCert, cbFPCert)) { result = TRUE; goto Done; } } Done: if (pbFPCont) free(pbFPCont); if (hProvCont) { if (!CryptReleaseContext(hProvCont, 0)) { HandleError("Error during CryptReleaseContext!"); } } return result; } // Конец примера
AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Ядро Windows NT: не поддерживает.