Подтвердить что ты не робот

Может ли 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 для использования хранилища системных сертификатов?

4b9b3361

Ответ 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 или перебрать их... в зависимости от поведения, которое вы хотите.