- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 C++
向 ocsp
服务器发送一个 ocsp
请求,但是我找不到任何准备请求的东西.在文档中我发现了以下函数
long SSL_get_tlsext_status_ocsp_resp(ssl, unsigned char **resp);
long SSL_set_tlsext_status_ocsp_resp(ssl, unsigned char *resp, int len);
如何添加证书并为请求设置随机数?
最佳答案
您要做的是为 openssl OCSP 生成 C++ 代码命令:
openssl ocsp -issuer issuer.pem -cert alice.pem -cert bob.pem -reqout ocspreq.der
您需要的主要 OPENSSL API 是:
使用的 API 可能因您希望读入和写出的证书格式而异。
将上述 openssl 命令转换为简单 C++ 代码的示例是:
template<typename T, typename D>
std::unique_ptr<T, D> make_handle(T* handle, D deleter)
{
return std::unique_ptr<T, D>{handle, deleter};
}
bool generate_ocsp_request()
{
// load issuer certificate
auto file = make_handle(BIO_new_file("issuer.pem", "r"), BIO_free);
if(!file) return false;
auto const issuer = make_handle(PEM_read_bio_X509(file.get(), nullptr, nullptr, nullptr), X509_free);
if(!issuer) return false;
// setup OCSP request
auto const request = make_handle(OCSP_REQUEST_new(), OCSP_REQUEST_free);
if(!request) return false;
auto const cert_id_md = EVP_sha1();
// add alice certificate to OCSP request
file = make_handle(BIO_new_file("alice.pem", "r"), BIO_free);
if(!file) return false;
auto cert = PEM_read_bio_X509(file.get(), nullptr, nullptr, nullptr);
auto id = OCSP_cert_to_id(cert_id_md, cert, issuer.get());
if (id == nullptr) return false;
if (!OCSP_request_add0_id(request.get(), id)) return false;
// add bob certificate to OCSP request
file = make_handle(BIO_new_file("bob.pem", "r"), BIO_free);
if(!file) return false;
cert = PEM_read_bio_X509(file.get(), nullptr, nullptr, nullptr);
id = OCSP_cert_to_id(cert_id_md, cert, issuer.get());
if (id == nullptr) return false;
if (!OCSP_request_add0_id(request.get(), id)) return false;
// write the request out in DER format
file = make_handle(BIO_new_file("ocspreq.der", "wb"), BIO_free);
if(!file) return false;
// the below doesn't compile in C++ :(
// return i2d_OCSP_REQUEST_bio(file.get(), request.get()) != 0;
// go around the macro's that cause the problem in C++ because it will not automatically convert void* to unsigned char* like in C
return ASN1_i2d_bio(reinterpret_cast<i2d_of_void *>(i2d_OCSP_REQUEST), file.get(), reinterpret_cast<unsigned char*>(request.get())) != 0;
}
更新:
阅读回复有点复杂。
用于处理响应的主要 API 是:
没有可以提取的“文本”,您需要从响应中具体提取您想要的内容。
下面的代码基本上是这个命令的一个例子
openssl ocsp -respin ocspresp.der -reqin ocspreq.der -issuer issuer.pem -cert alice.pem -cert bob.pem
bool read_ocsp_response()
{
// load ocsp request (der format)
auto file = make_handle(BIO_new_file("ocspreq.der", "rb"), BIO_free);
if(!file) return false;
auto const request = make_handle(d2i_OCSP_REQUEST_bio(file.get(), nullptr), OCSP_REQUEST_free);
if(!request) return false;
// load ocsp response (der format)
file = make_handle(BIO_new_file("ocspresp.der", "rb"), BIO_free);
if(!file) return false;
auto const response = make_handle(d2i_OCSP_RESPONSE_bio(file.get(), nullptr), OCSP_RESPONSE_free);
if(!response) return false;
file.reset();
// was the server response ok?
if(OCSP_response_status(response.get()) != OCSP_RESPONSE_STATUS_SUCCESSFUL) return false;
// verify response
auto const basic_response = make_handle(OCSP_response_get1_basic(response.get()), OCSP_BASICRESP_free);
if(!basic_response) return false;
// check that the response is for the expected request
auto const nonce_check_result = OCSP_check_nonce(request.get(), basic_response.get());
if(nonce_check_result <= 0)
{
if(nonce_check_result == -1)
{
puts("WARNING: no nonce in response");
}
else
{
return false;
}
}
// verify the response against the issuer certificate
auto const issuers_certificate_stack = make_handle(sk_X509_new_null(), [](auto handle){ sk_X509_pop_free(handle, X509_free); });
if(!issuers_certificate_stack) return false;
file = make_handle(BIO_new_file("issuer.pem", "r"), BIO_free);
if(!file) return false;
auto const issuer = PEM_read_bio_X509(file.get(), nullptr, nullptr, nullptr);
if(!issuer) return false;
file.reset();
sk_X509_push(issuers_certificate_stack.get(), issuer);
// load default certificate store
auto const store = make_handle(X509_STORE_new(), X509_STORE_free);
if(!store) return false;
auto const lookup = X509_STORE_add_lookup(store.get(), X509_LOOKUP_file());
if(lookup == nullptr) return false;
if(OCSP_basic_verify(basic_response.get(), issuers_certificate_stack.get(), store.get(), OCSP_TRUSTOTHER) != 1) return false;
// check that all the certificates have a status ok results
if(OCSP_resp_count(basic_response.get() == 0) return false;
for (auto i = 0; i < OCSP_resp_count(basic_response.get()); i++)
{
auto const single_response = OCSP_resp_get0(basic_response.get(), i);
if(single_response == nullptr) return false;
if(OCSP_single_get0_status(single_response, nullptr, nullptr, nullptr, nullptr) != V_OCSP_CERTSTATUS_GOOD) return false;
}
return true;
}
如果您想查找特定证书(如 alice.pem)的状态,则可以使用从 OCSP_cert_to_id 返回的 OCSP_CERTID (参见生成请求)并将其与 OCSP_resp_find_status 一起使用用于查找该证书状态的 API,而不是像我在上面的代码中那样枚举所有证书。
如果您打算定期查询证书,您可能希望使用状态返回的下一次更新时间戳来安排下一次检查调用的时间。
关于c++ - 如何在 C++ 中使用 openssl 创建 ocsp 请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56253312/
我是一名优秀的程序员,十分优秀!