2015-11-03 50 views
1

我在寫一個需要驗證證書有效性的應用程序。爲此,我想使用OCSP。我不是自己實施OCSP,而是在考慮OpenSSL的libcrypto以準備必要的數據。帶libcrypto和libcurl的OCSP

我想出了這個(爲清楚起見移除錯誤處理):

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代理對我來說是一個阻斷器。 documentation有如下說明:

這些函數只對響應者執行最小HTTP查詢。如果應用程序希望支持更高級的功能,它應該使用另一個更完整的HTTP庫。

只是它沒有說如何去做,我似乎無法弄清楚。 OCSP_sendreq_bio()調用將OCSP_REQUEST結構轉換爲ASN.1結構,但似乎沒有任何公共調用允許我這樣做(除非我錯過了某些東西)。

我對此有何看法?如果不是,我該怎麼做呢?

回答

1

好吧,我:-)

白癡的回答是,OpenSSL的有一堆產生的通用功能,用於將由struct件事情的ASN.1二進制格式的宏。這些全都具有i2d_STRUCT_NAME(和d2i_STRUCT_NAME用於反向操作)的形式。確切的i2d_OCSP_REQUESTd2i_OCSP_RESPONSE函數沒有記錄,但其他一些函數(例如,我在我的問題中使用的friggin)的其他函數(如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);