Quyen Nguyen
Quyen Nguyen

Reputation: 1

Ignore time validity constraints OCSP stapling response while TLS handshake

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.

  1. About server certificate: I used X509_V_FLAG_NO_CHECK_TIME to disable time validity constraints. => OK
  2. OCSP stapling response: I cannot disable like checking server certificate.

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

Answers (0)

Related Questions