c++ - Boost.Asio SSL 上下文 load_verify_paths 未加载证书

标签 c++ windows boost openssl boost-asio

我有代码为当前用户检索 Windows 证书存储中的所有根证书:

#include <windows.h>
#include <Wincrypt.h>

inline std::vector<std::string> system_root_certificates()
{
    std::vector<std::string> certs;

    HCERTSTORE hStore;
    PCCERT_CONTEXT pCertContext = NULL;

    if (!(hStore = ::CertOpenStore(
              CERT_STORE_PROV_SYSTEM_A,
              0,
              NULL,
              CERT_SYSTEM_STORE_CURRENT_USER,
              "Root")))
        return certs;

    do
    {
        if (pCertContext = ::CertFindCertificateInStore(
                  hStore,
                  X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                  0,
                  CERT_FIND_ANY,
                  NULL,
                  pCertContext))
        {
            certs.push_back("-----BEGIN CERTIFICATE-----\n" +
                            Base64::encode_copy(std::string((char *) pCertContext->pbCertEncoded, (size_t) pCertContext->cbCertEncoded), true) +
                            "\n-----END CERTIFICATE-----\n");
        }
    } while (pCertContext);

    if (!pCertContext)
        ::CertFreeCertificateContext(pCertContext);

    ::CertCloseStore(
              hStore,
              CERT_CLOSE_STORE_FORCE_FLAG);

    return certs;
}

然后我将证书写到一个文件中:

...
for (size_t i = 0; i < certs.size(); ++i)
    certFile << certs[i];
...

我已确认文件写入正确。

文件中前两个证书的示例:

-----BEGIN CERTIFICATE-----
MIIFMIIDoAMCAgIQrRahoKWtc1j0Ey5lDQYJhkiGDQEBBQAwMRMwBgoJJomTLGQBFgNjbTEZFwYK
kiaJ8ixkGRYJaWNyc29mMS0wBgNVAxMkaWNyc29mIFJvdCBDcnRpaWNhZSBBdGhvaXR5HhcNMTA1
OTIzOTIyFw0yMDUwMjMyMTNaXzETEQYKkiaJ8ixkGRYDb20xMBcGCZImk/IsARkWbWljb3NvdDEt
KwYDBAMTTWljb3NvdCBSb3QgZXJ0ZmljdGUgdXRocml0MIICMA0GKoZI9w0BAQUAggIPMIICAoIC
APNdgGfUp6kMkCDQCDx1zbcHnInazsNgkWhalHEpdnzCyCV2Dlj6NDbmr/eA6VgLk+Wd43ci9zRk
IpEd4QmQFP78WBnhtweSrohZ2J8HA1j8KW0y0qjL/OELMk/muK1PXG8TmduVdduot5SRd1v1DI9q
fRRwfW2v9dpwR7e/L2znt+ERrHmRfMXW5OF+w37l0jwANoLe4W3zbvifyctSc5g2i6FrlZeb3sJN
/waWJQbIrOTuM5UxyDUINMp51bW+MllAwKVOTT3bBzPkv+8/ZNhCNVf9RXwkTZ7WdBGXkM5odJJv
S2+w48c2oND8wFr5YbkwcZYKsJHAle8QKGrjH7HkAz93BMcgSQ8diKTXfoitLexFxFEEKvzsnpoR
W97OiObi/ayVKEDbBJDfMznZRaUjBqVVMbsGYA5BfR8ul8sRFdUklO8Vif1L+jJb0TMAWWJwMuou
QC173SFnMJmPqiOo0bBumzbEQHScWGXBHnpbyI+7JnzUQOW2bKqGAL/ONQIDAAGjME8wBgNVDwQE
AgHGDwYDHRMB/wQFAwEBMB0GVR0OFgQUrIJgVieXJRP84QpTWeSkEAYJBgEEgjcVBAMCADANCSqG
hvcNAQUFA4ICAMURAzpgXVIRj7K7yLIFtLeoIJ1cA7Yc+gYTtshjmkdvV9JVBLEm1qlQoLzSbszD
rN8ZeKxZrGY0xBs+OEwzMBINJv5RAP+vToQNH+RtLk6FjWwzVNJkv1Cvejmg7WMD/BMGFjbUO5Ub
YjrlF9QFkponW6q9u77jiWBxVrOl0G0OfpUDaD3yY7hrtugw4cqU96KqmTCyp8JRKCABJytLt50R
cL6ygrwMaNCNJIeqKHKdX1mQ9d6TOmJaOeKIHbkGwYlr12nDEjaEyaDaL2l45Xra1wzAvWMXORM4
Nlt7hVZqZGLB4qq/ZqKUEpxmEGvyMJItKfA9FENo8Zwpy844JW18834kJAMIR+yll/UYz7vVdpbv
zttWlaBCl1jhMSLTWeY+IgDqhLYl2fMIaMBkHXzsk6Jibi7YWI/ESSbdKTWHMHFwFDxpiRJ9LqP+
f56CUgorQyvZiJ/I+4mNoYV1fmyecxNkaaUvypZt+ARNkj1uFCHJ4MP9a51K0aGdQ3c/2g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICMIICoAMCAgIBMA0GKoZI9w0BBAUAgYsxMAkGVQQGAlpBFTATA1UEEwxXc3RlbiBDcGUxMBIG
VQQHC0R1YmFuaWxsMQ8wBgNVChMGaGF3ZTEdGwYDBAsTVGhhdGUgZXJ0ZmljdGlvMR8wBgNVAxMW
aGF3ZSBUbWVzYW1wbmcgQTAeDTk3MTAxMDAwMFoXMjAxMzEyNTk1WjCBMQswBgNVBhMCQTEVEwYD
BAgTV2VzZXJuQ2FwMRQwBgNVBxMLdXJibnZpbGUxMA0GVQQKBlRod3RlHTAbA1UEExRUYXd0IENl
dGlmY2F0b24xMB0GVQQDFlRod3RlVGltc3RhcGluIENBgZ8wBgkqSIb3AQEBAAOBADCBAoGB1itY
YUWG6jR7nO2wLhgO4F+o07TJfFlODnNUwX/2Luk6JBU8RwRjnsSUWt9M89lDPBB6JduQ8FHn1kEA
nyjfvpS7thTjhdep4EyksCsa8vg7PkWskgC0QZj77fq3iviIAgMBAaMTETAPA1UdAQH/BTADAf8w
BgkqSIb3AQEEAAOBAGfbwuaHQIOGNX0fmsMMIKi6BImG9RAIv8uiitBNPvTXacZesJRvuefeiLZ7
4yflw/A1y7UnM3ncpgCe+vzNlEIW0xxov1zdqXsQMnRUMYuFhJG3ATAUryjKsVAZCayJ0w==
-----END CERTIFICATE-----

然后我关闭文件,然后调用

sslContext->load_verify_file(filename);

load_verify_file函数失败并出现错误 too long .如果我只将一个证书写入文件,该函数也会失败,并出现相同的错误代码。

openssl verify <cert_filename>返回以下(完整)输出:

unable to load certificate
2404:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:.\crypto\asn1\asn1_lib.c:142:
2404:error:0D068066:asn1 encoding routines:ASN1_CHECK_TLEN:bad object header:.\crypto\asn1\tasn_dec.c:1303:
2404:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:.\crypto\asn1\tasn_dec.c:380:Type=X509
2404:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:.\crypto\pem\pem_oth.c:83:

错误是由我写入文件的格式引起的吗?还有什么可能导致此错误?

最佳答案

使用base64 -d解码证书,显示为der格式的二进制文件,但长度不正确,例如第一个证书的 der 格式表示 0x0530 + 4 字节。 der文件应该有1332字节,但实际上它只有1078字节。

所以它表明证书已损坏。

谷歌这个话题,发现CryptBinaryToString()是一个更好的选择来转换pbCertEncoded,而不是直接调用Base64函数来获取字符串。

关于c++ - Boost.Asio SSL 上下文 load_verify_paths 未加载证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40198728/

相关文章:

c++ - 关于 UDP/IP 和 sendto/recvfrom 返回值的混淆

c++ - 在哪里可以找到 C++ 中 operator new 的确切实现?

windows - 在 Windows 上的 emacs 中运行 M-x sql-postgres

C++ boost::mpl::type 前向声明

c++ - 使用 boost::hana 获取函数参数的类型

c++ - BOOST 单元测试覆盖运算符<<

java - 您会为共享软件/免费软件桌面应用程序使用什么语言/平台?

c++ - 生成 32 位随机数的问题

c++ - 获取 Windows 时区信息 (C++/MFC)

c# - 如何使用 C# 删除 StartMenu 快捷方式