Может ли OpenSSL в Windows использовать хранилище сертификатов системы?
Некоторый рабочий код С++, который я переношу из Linux в Windows, терпит неудачу в Windows, потому что SSL_get_verify_result()
возвращает X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
.
Этот код использовал SSL_CTX_set_default_verify_paths()
в Linux, чтобы сказать, что SSL просто просматривает стандартные местоположения по умолчанию для хранилища сертификатов.
Можно ли использовать OpenSSL для использования хранилища системных сертификатов?
Ответы
Ответ 1
Я сделал это раньше.
Надеюсь, это поможет, если это именно то, что вы ищете.
- Загрузите сертификат (в структуру
PCCERT_CONTEXT
) из хранилища Windows Cert, используя Crypto API.
- Получить зашифрованное содержимое в двоичном формате. [
PCCERT_CONTEXT->pbCertEncoded
].
- Разберите этот двоичный буфер в сертификат X509. Объект использует метод OpenSSL
d2i_X509()
.
- Получить дескриптор хранилища доверия OpenSSL с помощью метода
SSL_CTX_get_cert_store()
.
- Загрузите выше обработанный сертификат X509 в это хранилище доверия с помощью метода
X509_STORE_add_cert()
.
- Все готово!
Ответ 2
Для тех из вас, кто по-прежнему борется с этим, как я был, вот пример кода, чтобы вы начали:
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#include <cryptuiapi.h>
#include <iostream>
#include <tchar.h>
#include "openssl\x509.h"
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "cryptui.lib")
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
int main(void)
{
HCERTSTORE hStore;
PCCERT_CONTEXT pContext = NULL;
X509 *x509;
X509_STORE *store = X509_STORE_new();
hStore = CertOpenSystemStore(NULL, L"ROOT");
if (!hStore)
return 1;
while (pContext = CertEnumCertificatesInStore(hStore, pContext))
{
//uncomment the line below if you want to see the certificates as pop ups
//CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, pContext, NULL, NULL, 0, NULL);
x509 = NULL;
x509 = d2i_X509(NULL, (const unsigned char **)&pContext->pbCertEncoded, pContext->cbCertEncoded);
if (x509)
{
int i = X509_STORE_add_cert(store, x509);
if (i == 1)
std::cout << "certificate added" << std::endl;
X509_free(x509);
}
}
CertFreeCertificateContext(pContext);
CertCloseStore(hStore, 0);
system("pause");
return 0;
}
Ответ 3
Нет. Не из коробки.
Нет невозможно из коробки. Это потребует дополнительного программирования. В OpenSSL у вас есть два (из коробки) вариантов:
- Используйте собственное хранилище сертификатов OpenSSL (это иерархия каталогов, созданных perl script с OpenSSL)
- Используйте только созданный вами файл цепочки сертификатов (это текстовый файл со всеми PEM-закодированными сертификатами в цепочке доверия). Создание такого файла легко (просто добавьте его)
Ответ 4
Да
Можно использовать OpenSSL
для работы как обычно, и использовать CryptoAPI
только для процесса проверки сертификата. Я вижу несколько тем вокруг этой темы, и большинство из них на цыпочках вокруг/через.
С CryptoAPI
вам нужно:
- декодировать
PEM
до DER
с помощью CryptStringToBinary()
,
- создать объект
CERT_CONTEXT
с помощью CertCreateCertificateContext()
-
и проверьте сертификат в этой форме с помощью хорошо известной/документированной процедуры. (Например здесь, в ETutorials.)
Для последнего шага работы вам также нужно инициализировать HCERTSTORE
для одного из системных хранилищ MY
, ROOT
, CA
или перебрать их... в зависимости от поведения, которое вы хотите.