NOEXPORT int ocsp_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509 *cert;
    OCSP_CERTID *cert_id;
    STACK_OF(OPENSSL_STRING) *aia;
    int i, ocsp_status=V_OCSP_CERTSTATUS_UNKNOWN, saved_error;
    char *url;

    /* the original error code is restored unless we report our own error */
    saved_error=X509_STORE_CTX_get_error(callback_ctx);

    /* get the current certificate ID */
    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    if(!cert) {
        s_log(LOG_ERR, "OCSP: Failed to get the current certificate");
        X509_STORE_CTX_set_error(callback_ctx,
            X509_V_ERR_APPLICATION_VERIFICATION);
        return 0; /* reject */
    }
    if(!X509_NAME_cmp(X509_get_subject_name(cert),
            X509_get_issuer_name(cert))) {
        s_log(LOG_DEBUG, "OCSP: Ignoring root certificate");
        return 1; /* accept */
    }
    cert_id=OCSP_cert_to_id(NULL, cert, get_current_issuer(callback_ctx));
    if(!cert_id) {
        sslerror("OCSP: OCSP_cert_to_id");
        X509_STORE_CTX_set_error(callback_ctx,
            X509_V_ERR_APPLICATION_VERIFICATION);
        return 0; /* reject */
    }

    /* use the responder specified in the configuration file */
    if(c->opt->ocsp_url) {
        s_log(LOG_NOTICE, "OCSP: Connecting the configured responder \"%s\"",
            c->opt->ocsp_url);
        if(ocsp_request(c, callback_ctx, cert_id, c->opt->ocsp_url)!=
                V_OCSP_CERTSTATUS_GOOD) {
            OCSP_CERTID_free(cert_id);
            return 0; /* reject */
        }
    }

    /* use the responder from AIA (Authority Information Access) */
    if(c->opt->option.aia && (aia=X509_get1_ocsp(cert))) {
        for(i=0; i<sk_OPENSSL_STRING_num(aia); i++) {
            url=sk_OPENSSL_STRING_value(aia, i);
            s_log(LOG_NOTICE, "OCSP: Connecting the AIA responder \"%s\"", url);
            ocsp_status=ocsp_request(c, callback_ctx, cert_id, url);
            if(ocsp_status!=V_OCSP_CERTSTATUS_UNKNOWN)
                break; /* we received a definitive response */
        }
        X509_email_free(aia);
        if(ocsp_status!=V_OCSP_CERTSTATUS_GOOD) {
            OCSP_CERTID_free(cert_id);
            return 0; /* reject */
        }
    }

    OCSP_CERTID_free(cert_id);
    X509_STORE_CTX_set_error(callback_ctx, saved_error);
    return 1; /* accept */
}
NOEXPORT int ocsp_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509 *cert;
    OCSP_CERTID *cert_id;
    STACK_OF(OPENSSL_STRING) *aia;
    int i, ocsp_status=V_OCSP_CERTSTATUS_UNKNOWN, saved_error;
    char *url;

     
    saved_error=X509_STORE_CTX_get_error(callback_ctx);

     
    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    if(!cert) {
        s_log(LOG_ERR, "OCSP: Failed to get the current certificate");
        X509_STORE_CTX_set_error(callback_ctx,
            X509_V_ERR_APPLICATION_VERIFICATION);
        return 0;  
    }
    if(!X509_NAME_cmp(X509_get_subject_name(cert),
            X509_get_issuer_name(cert))) {
        s_log(LOG_DEBUG, "OCSP: Ignoring root certificate");
        return 1;  
    }
    cert_id=OCSP_cert_to_id(NULL, cert, get_current_issuer(callback_ctx));
    if(!cert_id) {
        sslerror("OCSP: OCSP_cert_to_id");
        X509_STORE_CTX_set_error(callback_ctx,
            X509_V_ERR_APPLICATION_VERIFICATION);
        return 0;  
    }

     
    if(c->opt->ocsp_url) {
        s_log(LOG_NOTICE, "OCSP: Connecting the configured responder \"%s\"",
            c->opt->ocsp_url);
        if(ocsp_request(c, callback_ctx, cert_id, c->opt->ocsp_url)!=
                V_OCSP_CERTSTATUS_GOOD) {
            OCSP_CERTID_free(cert_id);
            return 0;  
        }
    }

     
    if(c->opt->option.aia && (aia=X509_get1_ocsp(cert))) {
        for(i=0; i<sk_OPENSSL_STRING_num(aia); i++) {
            url=sk_OPENSSL_STRING_value(aia, i);
            s_log(LOG_NOTICE, "OCSP: Connecting the AIA responder \"%s\"", url);
            ocsp_status=ocsp_request(c, callback_ctx, cert_id, url);
            if(ocsp_status!=V_OCSP_CERTSTATUS_UNKNOWN)
                break;  
        }
        X509_email_free(aia);
        if(ocsp_status!=V_OCSP_CERTSTATUS_GOOD) {
            OCSP_CERTID_free(cert_id);
            return 0;  
        }
    }

    OCSP_CERTID_free(cert_id);
    X509_STORE_CTX_set_error(callback_ctx, saved_error);
    return 1;  
}