1

我正在编写一个需要验证证书有效性的应用程序。为此,我想使用 OCSP。我没有自己实现 OCSP,而是查看 OpenSSLlibcrypto以准备必要的数据。

我想出了这个(为清楚起见,删除了错误处理):

int main(int argc, char** argv) {
    SSL_library_init();
    FILE *cert_f = fopen(argv[1], "r");
    FILE *cacert_f = fopen(argv[2], "r");
    X509 *cert = d2i_X509_fp(cert_f, NULL);
    X509 *cacert = d2i_X509_fp(cacert_f, NULL);
    fclose(cert_f);
    fclose(cacert_f);

    OCSP_REQUEST *req = OCSP_REQUEST_new();
    OCSP_CERTID *id = OCSP_cert_to_id(EVP_sha1(), cert, cacert);
    OCSP_request_add0_id(req, id);
    BIO *bio = BIO_new_connect("ocspserver:http");
    OCSP_RESPONSE *resp = OCSP_sendreq_bio(bio, "/2", req);
}

哪个发出请求就好了。唯一的问题是它OCSP_sendreq_bio()似乎不支持通过 HTTP 代理发送 HTTP 请求,这对我来说是一个障碍。该文档对此有以下说法:

这些函数只对响应者执行最小的 HTTP 查询。如果应用程序希望支持更高级的功能,它应该使用替代的更完整的 HTTP 库。

只是它没有说该怎么做,我似乎无法弄清楚。该OCSP_sendreq_bio()调用将OCSP_REQUEST结构转换为 ASN.1 结构,但似乎没有任何公共调用允许我这样做(除非我遗漏了什么)。

我会以正确的方式解决这个问题吗?如果没有,我应该怎么做?

4

1 回答 1

1

好吧,我是个白痴:-)

答案是 OpenSSL 有一堆宏,它们生成通用函数,用于将某些东西从structs 转换为 ASN.1 二进制格式。这些都具有形式i2d_STRUCT_NAME(并d2i_STRUCT_NAME用于反向操作)。确切的i2d_OCSP_REQUESTd2i_OCSP_RESPONSE函数没有记录,但其他一些(例如,d2i_X509我在我的问题中使用的)具有非常相似的函数签名(因为它们是使用相同的宏生成的)。

因此,答案是OCSP_sendreq_bio用这样的东西代替:

unsigned char *data = NULL;
long len = (long)i2d_OCSP_REQUEST(req, &data);
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://ocspserver/2");
curl_easy_setopt(curl, CURLOPT_POST, (long)1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_memory_append_function);
curl_easy_perform(curl);

等等

于 2015-11-03T14:59:52.923 回答