我正在编写一个应用程序,它需要验证证书的有效性。为此,我想使用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请求,而HTTP对我来说是一个阻止程序。文档对此有以下几点看法:
这些函数只对响应程序执行最小的HTTP查询。如果应用程序希望支持更高级的特性,那么它应该使用另一个更完整的HTTP库。
只是它没有说怎么做,我似乎也想不出来。OCSP_sendreq_bio()调用将OCSP_REQUEST结构转换为ASN.1结构,但似乎没有任何公共调用允许我这样做(除非我遗漏了什么)。
我这样做对吗?如果没有,我应该做什么呢?
发布于 2015-11-03 14:59:52
好吧,我是个白痴:-)
答案是,OpenSSL有一堆宏,它们生成一些通用函数,用于将structs转换为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);等。
https://stackoverflow.com/questions/33500920
复制相似问题