为客户端证书添加CA证书

时间:2012-11-05 20:54:25

标签: winapi cryptography cryptoapi

我正在编写一个使用CryptoAPI和Schannel建立与客户端的安全SSL连接的服务器应用程序。服务器要求客户端提交证书以进行验证(通过在ASC_REQ_MUTUAL_AUTH中设置AcceptSecurityContext标志)。

我遇到的问题是某些客户端(即使用javax.net.ssl的客户端)未传递其客户端证书(即使已将其配置为这样做)。我怀疑这是因为用于签署客户端证书的CA证书不在握手期间传递给客户端的CA列表中。

我尝试使用以下变体将CA证书添加到此列表中:

PCERT_CONTEXT caCertContext = ...; /* Imported from a DER formatted file */

HCERTSTORE systemStore = CertOpenStore(
                CERT_STORE_PROV_SYSTEM,
                0,
                0,
                CERT_STORE_OPEN_EXISTING_FLAG |
                    CERT_SYSTEM_STORE_LOCAL_MACHINE,
                L"ROOT");

bool ok = CertAddCertificateContextToStore(
                systemStore,
                caCertContext,
                CERT_STORE_ADD_USE_EXISTING,
                NULL);

if (!ok)
{
    std::cerr << "Could not add certificate to system store!" << std::endl;
}

在上面的例子中CertAddCertificateContextToStore总是失败。如果我将CERT_SYSTEM_STORE_LOCAL_MACHINE更改为CERT_SYSTEM_STORE_CURRENT_USER,我会看到一个弹出窗口,要求我确认证书,但即使我接受CA证书也不会出现在发送给客户端的列表中。

我还尝试使用临时内存存储扩展系统存储集(我从here获取的内容),但无济于事。

有人知道解决这个问题的方法吗?理想情况下,不使用任何GUI或外部工具以编程方式?

1 个答案:

答案 0 :(得分:1)

您收到该错误是因为您无权以读写方式访问该商店,您只能以读取方式访问该商店。所以你需要做的就是添加CERT_STORE_READONLY_FLAG所以它将是:

HCERTSTORE systemStore = CertOpenStore(
            CERT_STORE_PROV_SYSTEM,
            0,
            0,
            CERT_STORE_OPEN_EXISTING_FLAG |
                CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG ,
            L"ROOT");

如果您要对商店进行更改而不将其设置为只读,这意味着在运行C ++应用程序时需要管理提升。