简体   繁体   English

将 Windows 证书存储 CRL 导入 OpenSSL

[英]Import Windows Certificate Store CRLs into OpenSSL

I'm using OpenSSL in Windows.我在 Windows 中使用 OpenSSL。 I want OpenSSL's certificate checking to validate certificates against their CRLs.我希望 OpenSSL 的证书检查能够根据其 CRL 验证证书。 In the OpenSSL documentation, it says:在 OpenSSL 文档中,它说:

If CRLs checking is enable CRLs are expected to be available in the corresponding X509_STORE structure.如果启用 CRL 检查,则预计 CRL 在相应的 X509_STORE 结构中可用。 No attempt is made to download CRLs from the CRL distribution points extension.不会尝试从 CRL 分发点扩展下载 CRL。

I populate OpenSSL's certificates store with certificates the Windows Certificate Store.我使用 Windows 证书存储中的证书填充 OpenSSL 的证书存储。 I'd like to do the same with the CRLs that exist in the Windows Certificate Store.我想对 Windows 证书存储中存在的 CRL 执行相同的操作。

Is there a way to do that?有没有办法做到这一点? Is it possible that OpenSSL has added CRL downloading to its checks but it is not yet documented? OpenSSL 是否可能已将 CRL 下载添加到其检查中,但尚未记录?

Turns out it's a lot easier than I thought - you use CertEnumCRLsInStore to get the CRLs for the relevant store, and then use d2i_X509_CRL to encode the certificates for OpenSSL.事实证明它比我想象的要容易得多 - 您使用CertEnumCRLsInStore来获取相关商店的 CRL,然后使用d2i_X509_CRL为 OpenSSL 编码证书。 The whole thing is remarkably similar to this: https://stackoverflow.com/a/40046425/1132699整个事情与此非常相似: https : //stackoverflow.com/a/40046425/1132699

I wrote the following code to enable getting CRLs from cache on demand:我编写了以下代码来启用按需从缓存中获取 CRL:

#define length_of(x) (sizeof(x) / sizeof(x[0]))
#define length_of_null_terminated_string(x) (length_of(x) - 1)

static X509_CRL * GetCRLByUrl(
    const char * url)
{
    PCCRL_CONTEXT pCrlContext = nullptr;
    BOOL res = ::CryptRetrieveObjectByUrlA(url, CONTEXT_OID_CRL, 0, 0, (LPVOID*)&pCrlContext, nullptr, nullptr, nullptr, nullptr);
    if (!res) {
        DWORD dwErr = ::GetLastError();
        return nullptr;
    }

    const unsigned char * pbCrlEncoded = pCrlContext->pbCrlEncoded;
    X509_CRL * x509_crl = d2i_X509_CRL(NULL, &pbCrlEncoded, pCrlContext->cbCrlEncoded);
    ::CertFreeCRLContext(pCrlContext);
    if (!x509_crl) {
        return nullptr;
    }

    return x509_crl;

    LOG_SCOPE_LEAVE;
}

static STACK_OF(X509_CRL) * LookupCRLsInWindowsStore(
    X509_STORE_CTX * ctx,
    X509_NAME * nm)
{
    STACK_OF(X509_CRL) * crls = sk_X509_CRL_new_null();
    if (!crls) {
        return nullptr;
    }

    X509 * x509 = X509_STORE_CTX_get_current_cert(ctx);

    static int nids[] = { NID_crl_distribution_points, NID_freshest_crl };
    for (int * it = std::begin(nids), * itEnd = std::end(nids); it != itEnd; ++it) {
        int nid = *it;
        STACK_OF(DIST_POINT) * crldp = (STACK_OF(DIST_POINT) *)X509_get_ext_d2i(x509, nid, NULL, NULL);
        for (int i = 0, iEnd = sk_DIST_POINT_num(crldp); i < iEnd; ++i) {
            DIST_POINT * dp = sk_DIST_POINT_value(crldp, i);
            if (!dp->distpoint) {
                continue;
            }
            if (dp->distpoint->type != 0) {
                continue;
            }

            GENERAL_NAMES * gens = dp->distpoint->name.fullname;
            for (int j = 0, jEnd = sk_GENERAL_NAME_num(gens); j < jEnd; ++j) {
                GENERAL_NAME * gen = sk_GENERAL_NAME_value(gens, i);
                int gtype;
                ASN1_STRING * uri = (ASN1_STRING *)GENERAL_NAME_get0_value(gen, &gtype);
                if (gtype != GEN_URI) {
                    continue;
                }
                const char * url = (const char *)ASN1_STRING_data(uri);
                if (ASN1_STRING_length(uri) < length_of_null_terminated_string("http://") || strncmp(url, "http://", length_of_null_terminated_string("http://")) != 0) {
                    continue;
                }
                X509_CRL * x509_crl = GetCRLByUrl(url);
                if (x509_crl) {
                    sk_X509_CRL_push(crls, x509_crl);
                    break;
                }
            }
        }
        sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
    }

    return crls;
}

X509_STORE * x509_store = ...;
X509_STORE_set_lookup_crls_cb(x509_store, LookupCRLsInWindowsStore);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM