owacoder
owacoder

Reputation: 4873

Boost.Asio SSL context load_verify_paths not loading certificate(s)

I have code to retrieve all root certificates in the Windows certificate store for the current user:

#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;
}

Then I write the certificates out to a file:

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

I have verified that the file is being written correctly.

A sample of the first two certificates from the file:

-----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-----

I then close the file, and call

sslContext->load_verify_file(filename);

The load_verify_file function fails with error too long. The function also fails if I only write one certificate to the file, with the same error code.

openssl verify <cert_filename> returns the following (complete) output:

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:

Is the error caused by the format that I am writing to the file in? What else could cause this error?

Upvotes: 1

Views: 1225

Answers (1)

Mine
Mine

Reputation: 4241

Use base64 -d to decode the certificate, it shows der formatted binary, but the length is not correct, e.g. the first certificate's der format indicates 0x0530 + 4 bytes. The der file shall have 1332 bytes, but actually it's only 1078 bytes.

So it indicates that the certificate is corrupted.

Google this topic, it's found that CryptBinaryToString() is a better option to convert the pbCertEncoded, instead of directly calling Base64 function to get the string.

Upvotes: 2

Related Questions