Reputation: 1
I'm working on TLS handshake to connect with server with curl library in C++.
The problem: When system client is wrong => Can not verify server certificate, OCSP stapling response.
Thus I need to implement fall case to solve this problem.
I think client use systime time to verify "This Update", "Next Update" in OCSP response. It seems to be verify automatically when I use "curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L)" and I had no way to ignore time validity.
I tried to use to verify OCSP response manually to ignore time validity:
int ocsp_callback(SSL *ssl, void *arg) {
const unsigned char *resp_data;
int len = SSL_get_tlsext_status_ocsp_resp(ssl, &resp_data);
if (len <= 0) {
printf("No OCSP response.\n");
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
const unsigned char *p = resp_data;
OCSP_RESPONSE *ocsp_resp = d2i_OCSP_RESPONSE(NULL, &p, len);
if (!ocsp_resp) {
printf("Invalid OCSP response.\n");
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
OCSP_BASICRESP *basic_resp = OCSP_response_get1_basic(ocsp_resp);
if (!basic_resp) {
OCSP_RESPONSE_free(ocsp_resp);
printf("Cannot parse OCSP response.\n");
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
STACK_OF(X509) *cert_chain = SSL_get_peer_cert_chain(ssl);
X509 *server_cert = SSL_get_peer_certificate(ssl);
X509 *issuer_cert = NULL;
if (cert_chain && sk_X509_num(cert_chain) > 1) {
issuer_cert = sk_X509_value(cert_chain, sk_X509_num(cert_chain) - 1);
}
if (!server_cert || !issuer_cert) {
printf("Cannot get server certificate or issuer.\n");
OCSP_BASICRESP_free(basic_resp);
OCSP_RESPONSE_free(ocsp_resp);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
OCSP_CERTID *cert_id = OCSP_cert_to_id(NULL, server_cert, issuer_cert);
if (!cert_id) {
printf("Cannot create OCSP_CERTID.\n");
OCSP_BASICRESP_free(basic_resp);
OCSP_RESPONSE_free(ocsp_resp);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
// Check OCSP response
int status, reason;
ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd;
if (!OCSP_resp_find_status(basic_resp, cert_id, &status, &reason, &revtime, &thisupd, &nextupd)) {
printf("Failed to extract OCSP certificate status.\n");
OCSP_CERTID_free(cert_id);
OCSP_BASICRESP_free(basic_resp);
OCSP_RESPONSE_free(ocsp_resp);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
if (status == V_OCSP_CERTSTATUS_REVOKED) {
printf("Certificate has been revoked!!\n");
OCSP_CERTID_free(cert_id);
OCSP_BASICRESP_free(basic_resp);
OCSP_RESPONSE_free(ocsp_resp);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
if (thisupd) ASN1_GENERALIZEDTIME_free(thisupd);
if (nextupd) ASN1_GENERALIZEDTIME_free(nextupd);
// Check OCSP response signature
if (OCSP_basic_verify(basic_resp, cert_chain, NULL, 0) <= 0) {
printf("Invalid OCSP response (incorrect signature).\n");
OCSP_CERTID_free(cert_id);
OCSP_BASICRESP_free(basic_resp);
OCSP_RESPONSE_free(ocsp_resp);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
printf("Valid OCSP response (time check omitted)\n");
OCSP_CERTID_free(cert_id);
OCSP_BASICRESP_free(basic_resp);
OCSP_RESPONSE_free(ocsp_resp);
X509_free(server_cert);
return SSL_TLSEXT_ERR_OK;
}
I always failed with "Failed to extract OCSP certificate status." I'm also not sure I can disable ssl verify automatically when I do above steps.
Could you please tell me how can I ignore time validity of OCSP response in fall case?
Upvotes: 0
Views: 11