С++ добавление сертификата в хранилище Trust Root в Windows

У меня есть задача добавить сертификат (закрытый ключ и файл сертификата), сгенерированный библиотекой openssl, в Trust Root Storage в Windows из моей программы на C++. Не могли бы вы показать несколько примеров кода? Предполагаю, что надо использовать Win Api, но примеров пока не нашел. Может быть, у кого-то была такая же задача или он мог бы порекомендовать соответствующие ресурсы. Я все еще нашел только доверенные корневые сертификаты C++ для доступа, но это обратная проблема. Вместо этого мне нужно добавить сертификат в хранилище.


person Maria    schedule 31.03.2021    source источник


Ответы (1)


Я не знаю, лучший ли это способ сделать это, но, по крайней мере, это работает для меня (я предполагаю, что вы хотите импортировать в хранилище текущего пользователя, а не в хранилище сертификатов машины).

Сначала вам нужно загрузить файл PFX в CRYPT_DATA_BLOB (это структура, содержащая указатель на буфер и соответствующую длину). В основном вы читаете PFX в буфер и соответственно устанавливаете длину. Затем вы можете импортировать этот CRYPT_DATA_BLOB в хранилище сертификатов с помощью PFXImportCertStore. Это хранилище сертификатов является временным, поэтому оно еще не находится в нужном вам хранилище сертификатов. Затем вам нужно открыть хранилище сертификатов, в которое вы действительно хотите импортировать сертификат (с помощью CertOpenSystemStore), извлечь объект сертификата из временного хранилища сертификатов с помощью CertEnumCertificatesInStore и вставить его в окончательное хранилище сертификатов с помощью CertAddCertificateContextToStore.

Этот код показывает все вышеперечисленное более или менее:

#include <Windows.h>
#include <wincrypt.h>

int main(int argc, char** argv) {
    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);

    unsigned char buffer[8192];
    CRYPT_DATA_BLOB key;
    key.cbData = 0;
    key.pbData = buffer;

    HANDLE h = CreateFile(L"c:\\temp\\server.pfx", FILE_GENERIC_READ, 0, NULL,  OPEN_EXISTING, 0, NULL);
    ReadFile(h, buffer, 8192, &key.cbData, NULL);
    CloseHandle(h);

    HCERTSTORE store = PFXImportCertStore(&key, L"mypassword", 0);
    PCCERT_CONTEXT ctx = CertEnumCertificatesInStore(store, NULL);
    HCERTSTORE rootStore = CertOpenSystemStore(NULL, L"ROOT");
    CertAddCertificateContextToStore(rootStore, ctx, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
    CertCloseStore(store, 0);
    CertCloseStore(rootStore, 0);
    return 0;
}

Для краткости код не включает проверку ошибок. Также предполагается, что во временном хранилище находится только один сертификат (в противном случае следует зациклить CertEnumCertificatesInStore). В любом случае, я думаю, что вы можете строить отсюда (вы должны проверить параметры, доступные для многих методов).

Не забудьте добавить crypt32.lib в проект.

person Ion Larrañaga    schedule 31.03.2021
comment
Большое спасибо за ответ! - person Maria; 31.03.2021