【问题标题】:Certificate pinning using cpprestsdk & boost使用 cpprestsdk 和 boost 固定证书
【发布时间】:2017-11-14 03:30:13
【问题描述】:

我正在尝试在 [cpprestsdk][1] 上实施证书固定,到目前为止没有成功。

我在 http_client_config 对象中看到我们可以调用方法 set_ssl_context_callback 并在该方法中,将其链接到自定义证书验证方法 - set_verify_callback .

当我调试我的代码时,方法 * set_verify_callback* 在请求发送后被调用,但我的自定义验证方法从未被调用。

我在下面添加了一个示例代码,用于演示上述行为。

bool verify_certificate(bool preverified, boost::asio::ssl::verify_context& ctx)
{
    // this code is never invoked
    char subject_name[256];
    X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
    X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
    std::cout << "Verifying:\n" << subject_name << std::endl;

    return preverified;
}


pplx::task<void> sendRequest()
{
    http_client_config config;
    config.set_validate_certificates(true);
    config.set_ssl_context_callback([](boost::asio::ssl::context& ctx)
                                    {
                                        // this code is invoked right after calling client.request
                                        ctx.set_verify_mode(boost::asio::ssl::context::verify_peer);
                                        ctx.set_verify_callback(&verify_certificate);

                                    });


    http_client client("https://google.com", config);

    http_request request(methods::GET);


    return client.request(request).then([](http_response response)
                                        {
                                            if (response.status_code() == status_codes::OK)
                                            {
                                                return response.extract_json();
                                            }

                                            return pplx::create_task([] { return json::value(); });

                                        }).then([](json::value jsonValue)
                                                {

                                                });

}


int main(int argc, const char * argv[])
{
    try
    {
        sendRequest().wait();
    }
    catch (std::exception& e)
    {
        std::wostringstream ss;
        ss << e.what() << std::endl;
        std::wcout << ss.str();

        // Return an empty task.
    }
    return 0;
}

【问题讨论】:

  • OWASP 在Certificate and Public Key Pinning 有一个用于OpenSSL 的复制/粘贴示例。它真正的固定;不是来自RFC 7469 的网络和浏览器的再现。
  • @jww - 谢谢,但这不相关,因为我面临的问题是未调用验证回调。此外,当我尝试使用 native_handle 访问 SSL* 对象时,使用 SSL_get_peer_certificate(ssl) 的证书为空; (我正在使用google.com 对其进行测试)
  • 顺便说一句,通过在没有 cpprest 的情况下使用 boost 调用回调。
  • " native_handle 到 SSL 对象,证书为空..."* - 是的,有些东西是弯曲的。握手完成后唯一一次获得 NULL 服务器证书是在使用匿名 Diffie-Hellman (ADH) 或匿名椭圆曲线 Diffie-Hellman 或 (AECDH) 时。 如果你的密码套件列表有!aNULL,那么你没有使用它们并且证书不应该为NULL。
  • 感谢您的回复,但是您知道为什么没有调用verify_certificate的回调吗?根据 boost 中的规范,验证应该在那个方法中完成。

标签: c++ boost openssl cpprest-sdk certificate-pinning


【解决方案1】:

我找到了一种解决方法,可以将此库与证书固定一起使用。

此解决方法需要覆盖库中的方法

在文件https://github.com/Microsoft/cpprestsdk/blob/master/Release/src/http/client/http_client_asio.cpp

重写方法

bool handle_cert_verification(bool preverified, boost::asio::ssl::verify_context &verifyCtx)

然后重新编译库并在您的项目中替换它。

我已向所有者提交了他们主分支的解决方案,即调用 set_verify_callback 而不是使用他们自己的实现。

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 2018-04-07
    • 1970-01-01
    • 2017-12-17
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    • 1970-01-01
    相关资源
    最近更新 更多