Может ли OpenSSL в Windows использовать хранилище системных сертификатов? - PullRequest
29 голосов
/ 01 марта 2012

Некоторый рабочий код C ++, который я портирую с 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 использовать хранилище системных сертификатов?

Ответы [ 4 ]

42 голосов
/ 01 августа 2012

Я сделал это раньше.Надеюсь, это поможет, если это именно то, что вы ищете.

  1. Загрузите свой сертификат (в структуре PCCERT_CONTEXT) из хранилища сертификатов Windows, используя API-интерфейсы Crypto.
  2. Получите зашифрованный контентоб этом в двоичном формате, как это.[PCCERT_CONTEXT->pbCertEncoded].
  3. Разобрать этот двоичный буфер в объект сертификата X509, используя метод d2i_X509() OpenSSL.
  4. Получить дескриптор хранилища доверия OpenSSL, используя метод SSL_CTX_get_cert_store().
  5. Загрузите выше анализируемый сертификат X509 в это доверенное хранилище, используя метод X509_STORE_add_cert().
  6. Готово!
15 голосов
/ 14 октября 2016

Для тех из вас, кто до сих пор борется с этим, как я, вот пример кода, с которого можно начать:

#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 голосов
/ 01 марта 2012

Нет.Не из коробки.

Нет, это невозможно из коробки.Это потребует дополнительного программирования.С OpenSSL у вас есть две (из коробки) опции:

  1. Использовать собственное хранилище сертификатов OpenSSL (это иерархия каталогов, созданных скриптом Perl, предоставляемым OpenSSL)
  2. Использовать толькофайл цепочки сертификатов, созданный вами (это текстовый файл со всеми сертификатами в кодировке PEM в цепочке доверия).Создать такой файл легко (просто добавив его)
1 голос
/ 16 марта 2013

Да

Можно использовать OpenSSL для обычной работы и CryptoAPI только для процесса проверки сертификата.Я вижу несколько тем вокруг этой темы, и большинство из них ходят на цыпочках вокруг / через.

С CryptoAPI вам необходимо:

  • декодировать PEM до DER сCryptStringToBinary(),
  • создайте объект CERT_CONTEXT с CertCreateCertificateContext()
  • и проверьте сертификат в этой форме с помощью хорошо известной / документированной процедуры.(Например, здесь, на ETutorials .)

    Для последнего шага, вам также нужно инициализировать HCERTSTORE для одного из MY, ROOT, CA системных хранилищили перебирайте их ... в зависимости от желаемого поведения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...