我正在编写一个需要验证证书有效性的应用程序。为此,我想使用OCSP。我不是自己实现OCSP,而是查看OpenSSL的libcrypto
来准备必要的数据。
我提出了这个问题(为清楚起见,错误处理已删除):
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请求,这对我来说是一个阻止。 documentation对此有以下说法:
这些函数仅对响应者执行最小的HTTP查询。如果应用程序希望支持更高级的功能,则应使用其他更完整的HTTP库。
只是它没有说明怎么做,我似乎无法弄明白。 OCSP_sendreq_bio()
调用将OCSP_REQUEST
结构转换为ASN.1结构,但似乎没有任何允许我这样做的公共调用(除非我遗漏了某些内容)
我是以正确的方式来做这件事的吗?如果没有,我应该做什么呢?
答案 0 :(得分:1)
好吧,我是个白痴: - )
答案是OpenSSL有一堆宏,它们生成用于将struct
s转换为ASN.1二进制格式的通用函数。这些都具有i2d_STRUCT_NAME
形式(和d2i_STRUCT_NAME
用于反向操作)。确切的i2d_OCSP_REQUEST
和d2i_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);
:
SELECT
等