2015-11-03 3 views
1

Я пишу приложение, которое должно проверить действительность сертификатов. Для этого я хотел бы использовать OCSP. Вместо того, чтобы внедрять OCSP самостоятельно, я искал libcrypto OpenSSL для подготовки необходимых данных.OCSP с libcrypto и libcurl

Я пришел с этим (обработка ошибок удалены для ясности):

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, но, похоже, не существует публичных вызовов, которые позволяют мне это делать (если только я не пропустил что-то).

Я собираюсь сделать это правильно? Если нет, что я должен делать вместо этого?

ответ

1

Хорошо, я идиот :-)

Ответ в том, что OpenSSL имеет кучу макросов, которые генерируют общие функции для преобразования что-то из struct с в ASN.1 двоичном формате. Все они имеют форму i2d_STRUCT_NAMEd2i_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); 

и т.д.