/*
 *   stunnel       TLS offloading and load-balancing proxy
 *   Copyright (C) 1998-2015 Michal Trojnara <Michal.Trojnara@mirt.net>
 *
 *   This program is free software; you can redistribute it and/or modify it
 *   under the terms of the GNU General Public License as published by the
 *   Free Software Foundation; either version 2 of the License, or (at your
 *   option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *   See the GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License along
 *   with this program; if not, see <http://www.gnu.org/licenses>.
 *
 *   Linking stunnel statically or dynamically with other modules is making
 *   a combined work based on stunnel. Thus, the terms and conditions of
 *   the GNU General Public License cover the whole combination.
 *
 *   In addition, as a special exception, the copyright holder of stunnel
 *   gives you permission to combine stunnel with free software programs or
 *   libraries that are released under the GNU LGPL and with code included
 *   in the standard release of OpenSSL under the OpenSSL License (or
 *   modified versions of such code, with unchanged license). You may copy
 *   and distribute such a system following the terms of the GNU GPL for
 *   stunnel and the licenses of the other code concerned.
 *
 *   Note that people who make modified versions of stunnel are not obligated
 *   to grant this special exception for their modified versions; it is their
 *   choice whether to do so. The GNU General Public License gives permission
 *   to release a modified version without this exception; this exception
 *   also makes it possible to release a modified version which carries
 *   forward this exception.
 */

#include "common.h"
#include "prototypes.h"

/**************************************** prototypes */

/* verify initialization */
NOEXPORT void set_client_CA_list(SERVICE_OPTIONS *section);
NOEXPORT void auth_warnings(SERVICE_OPTIONS *);
NOEXPORT int load_file_lookup(X509_STORE *, char *);
NOEXPORT int add_dir_lookup(X509_STORE *, char *);

/* verify callback */
NOEXPORT int verify_callback(int, X509_STORE_CTX *);
NOEXPORT int verify_checks(CLI *, int, X509_STORE_CTX *);
NOEXPORT int cert_check(CLI *, X509_STORE_CTX *, int);
#if OPENSSL_VERSION_NUMBER>=0x10002000L
NOEXPORT int cert_check_subject(CLI *, X509_STORE_CTX *);
#endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */
NOEXPORT int cert_check_local(X509_STORE_CTX *);
NOEXPORT int compare_pubkeys(X509 *, X509 *);
NOEXPORT int crl_check(CLI *, X509_STORE_CTX *);
#ifndef OPENSSL_NO_OCSP
NOEXPORT int ocsp_check(CLI *, X509_STORE_CTX *);
NOEXPORT int ocsp_request(CLI *, X509_STORE_CTX *, OCSP_CERTID *, char *);
NOEXPORT OCSP_RESPONSE *ocsp_get_response(CLI *, OCSP_REQUEST *, char *);
#endif

/* utility functions */
#ifndef OPENSSL_NO_OCSP
NOEXPORT X509 *get_current_issuer(X509_STORE_CTX *);
#endif
NOEXPORT void log_time(const int, const char *, ASN1_TIME *);

/**************************************** verify initialization */

int verify_init(SERVICE_OPTIONS *section) {
    int verify_mode=0;

    /* revocation store initialization */
    section->revocation_store=X509_STORE_new();
    if(!section->revocation_store) {
        sslerror("X509_STORE_new");
        return 1; /* FAILED */
    }

    /* CA initialization */
    if(section->ca_file) {
        if(!SSL_CTX_load_verify_locations(section->ctx,
                section->ca_file, NULL)) {
            s_log(LOG_ERR, "Error loading verify certificates from %s",
                section->ca_file);
            sslerror("SSL_CTX_load_verify_locations");
            return 1; /* FAILED */
        }
        /* revocation store needs CA certificates for CRL validation */
        if(load_file_lookup(section->revocation_store, section->ca_file))
            return 1; /* FAILED */
        if(!section->option.client) /* only performed on server */
            set_client_CA_list(section);
    }
    if(section->ca_dir) {
        if(!SSL_CTX_load_verify_locations(section->ctx,
                NULL, section->ca_dir)) {
            s_log(LOG_ERR, "Error setting verify directory to %s",
                section->ca_dir);
            sslerror("SSL_CTX_load_verify_locations");
            return 1; /* FAILED */
        }
        s_log(LOG_INFO, "Verify directory set to %s", section->ca_dir);
        /* revocation store needs CA certificates for CRL validation */
        add_dir_lookup(section->revocation_store, section->ca_dir);
    }

    /* CRL initialization */
    if(section->crl_file)
        if(load_file_lookup(section->revocation_store, section->crl_file))
            return 1; /* FAILED */
    if(section->crl_dir) {
        section->revocation_store->cache=0; /* don't cache CRLs */
        add_dir_lookup(section->revocation_store, section->crl_dir);
    }

    /* verify callback setup */
    if(section->verify_level>=0)
        verify_mode|=SSL_VERIFY_PEER;
    if(section->verify_level>=2 && !section->redirect_addr.names)
        verify_mode|=SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
    SSL_CTX_set_verify(section->ctx, verify_mode, verify_callback);
    auth_warnings(section);

    return 0; /* OK */
}

/* trusted CA names sent to clients for client cert selection */
NOEXPORT void set_client_CA_list(SERVICE_OPTIONS *section) {
    STACK_OF(X509_NAME) *ca_dn;
    char *ca_name;
    int i;

    s_log(LOG_DEBUG, "Client CA list: %s", section->ca_file);
    ca_dn=SSL_load_client_CA_file(section->ca_file);
    for(i=0; i<sk_X509_NAME_num(ca_dn); ++i) {
        ca_name=X509_NAME2text(sk_X509_NAME_value(ca_dn, i));
        s_log(LOG_INFO, "Client CA: %s", ca_name);
        str_free(ca_name);
    }
    SSL_CTX_set_client_CA_list(section->ctx, ca_dn);
}

/* issue warnings on insecure/missing authentication */
NOEXPORT void auth_warnings(SERVICE_OPTIONS *section) {
#ifndef OPENSSL_NO_PSK
    if(section->psk_keys)
        return;
#endif /* !defined(OPENSSL_NO_PSK) */
    /* for servers it is usually okay to accept all client
       certificates signed by a specified certificate authority */
    if(!section->option.client)
        return;
    if(section->verify_level<2) {
        s_log(LOG_WARNING,
            "Service [%s] needs authentication to prevent MITM attacks",
            section->servname);
        return;
    }
    if(section->verify_level>=3) /* levels>=3 don't rely on PKI */
        return;
#if OPENSSL_VERSION_NUMBER>=0x10002000L
    if(section->check_email || section->check_host || section->check_ip)
        return;
#endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */
    s_log(LOG_WARNING,
        "Service [%s] uses \"verify = 2\" without subject checks",
        section->servname);
#if OPENSSL_VERSION_NUMBER<0x10002000L
    s_log(LOG_WARNING,
        "Rebuild your stunnel against OpenSSL version 1.0.2 or higher");
#endif /* OPENSSL_VERSION_NUMBER<0x10002000L */
    s_log(LOG_WARNING,
        "Use \"checkHost\" or \"checkIP\" to restrict trusted certificates");
}

NOEXPORT int load_file_lookup(X509_STORE *store, char *name) {
    X509_LOOKUP *lookup;

    lookup=X509_STORE_add_lookup(store, X509_LOOKUP_file());
    if(!lookup) {
        sslerror("X509_STORE_add_lookup");
        return 1; /* FAILED */
    }
    if(!X509_LOOKUP_load_file(lookup, name, X509_FILETYPE_PEM)) {
        s_log(LOG_ERR, "Failed to load %s revocation lookup file", name);
        sslerror("X509_LOOKUP_load_file");
        return 1; /* FAILED */
    }
    s_log(LOG_DEBUG, "Loaded %s revocation lookup file", name);
    return 0; /* OK */
}

NOEXPORT int add_dir_lookup(X509_STORE *store, char *name) {
    X509_LOOKUP *lookup;

    lookup=X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
    if(!lookup) {
        sslerror("X509_STORE_add_lookup");
        return 1; /* FAILED */
    }
    if(!X509_LOOKUP_add_dir(lookup, name, X509_FILETYPE_PEM)) {
        s_log(LOG_ERR, "Failed to add %s revocation lookup directory", name);
        sslerror("X509_LOOKUP_add_dir");
        return 1; /* FAILED */
    }
    s_log(LOG_DEBUG, "Added %s revocation lookup directory", name);
    return 0; /* OK */
}

/**************************************** verify callback */

NOEXPORT int verify_callback(int preverify_ok, X509_STORE_CTX *callback_ctx) {
        /* our verify callback function */
    SSL *ssl;
    CLI *c;

    /* retrieve application specific data */
    ssl=X509_STORE_CTX_get_ex_data(callback_ctx,
        SSL_get_ex_data_X509_STORE_CTX_idx());
    c=SSL_get_ex_data(ssl, index_cli);

    if(c->opt->verify_level<1) {
        s_log(LOG_INFO, "Certificate verification disabled");
        return 1; /* accept */
    }
    if(verify_checks(c, preverify_ok, callback_ctx))
        return 1; /* accept */
    if(c->opt->option.client || c->opt->protocol)
        return 0; /* reject */
    if(c->opt->redirect_addr.names) {
        c->redirect=REDIRECT_ON;
        return 1; /* accept */
    }
    return 0; /* reject */
}

NOEXPORT int verify_checks(CLI *c,
        int preverify_ok, X509_STORE_CTX *callback_ctx) {
    X509 *cert;
    int depth;
    char *subject;

    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    depth=X509_STORE_CTX_get_error_depth(callback_ctx);
    subject=X509_NAME2text(X509_get_subject_name(cert));

    s_log(LOG_DEBUG, "Verification started at depth=%d: %s", depth, subject);

    if(!cert_check(c, callback_ctx, preverify_ok)) {
        s_log(LOG_WARNING, "Rejected by CERT at depth=%d: %s", depth, subject);
        str_free(subject);
        return 0; /* reject */
    }
    if((c->opt->crl_file || c->opt->crl_dir) &&
            !crl_check(c, callback_ctx)) {
        s_log(LOG_WARNING, "Rejected by CRL at depth=%d: %s", depth, subject);
        str_free(subject);
        return 0; /* reject */
    }
#ifndef OPENSSL_NO_OCSP
    if((c->opt->ocsp_url || c->opt->option.aia) &&
            !ocsp_check(c, callback_ctx)) {
        s_log(LOG_WARNING, "Rejected by OCSP at depth=%d: %s", depth, subject);
        str_free(subject);
        return 0; /* reject */
    }
#endif /* !defined(OPENSSL_NO_OCSP) */

    s_log(depth ? LOG_INFO : LOG_NOTICE,
        "Certificate accepted at depth=%d: %s", depth, subject);
    str_free(subject);
    return 1; /* accept */
}

/**************************************** certificate checking */

NOEXPORT int cert_check(CLI *c, X509_STORE_CTX *callback_ctx,
        int preverify_ok) {
    int depth=X509_STORE_CTX_get_error_depth(callback_ctx);

    if(preverify_ok) {
        s_log(LOG_DEBUG, "CERT: Pre-verification succeeded");
    } else { /* remote site sent an invalid certificate */
        if(c->opt->verify_level>=4 && depth>0) {
            s_log(LOG_INFO, "CERT: Invalid CA certificate ignored");
            return 1; /* accept */
        }
        s_log(LOG_WARNING, "CERT: Pre-verification error: %s",
            X509_verify_cert_error_string(
                X509_STORE_CTX_get_error(callback_ctx)));
        /* retain the STORE_CTX error produced by pre-verification */
        return 0; /* reject */
    }

    if(depth==0) { /* additional peer certificate checks */
#if OPENSSL_VERSION_NUMBER>=0x10002000L
        if(!cert_check_subject(c, callback_ctx))
            return 0; /* reject */
#endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */
        if(c->opt->verify_level>=3 && !cert_check_local(callback_ctx))
            return 0; /* reject */
    }

    return 1; /* accept */
}

#if OPENSSL_VERSION_NUMBER>=0x10002000L
NOEXPORT int cert_check_subject(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509 *cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    NAME_LIST *ptr;
    char *peername=NULL;

    if(c->opt->check_host) {
        for(ptr=c->opt->check_host; ptr; ptr=ptr->next)
            if(X509_check_host(cert, ptr->name, 0, 0, &peername)>0)
                break;
        if(!ptr) {
            s_log(LOG_WARNING, "CERT: No matching host name found");
            return 0; /* reject */
        }
        s_log(LOG_INFO, "CERT: Host name \"%s\" matched with \"%s\"",
            ptr->name, peername);
        OPENSSL_free(peername);
    }

    if(c->opt->check_email) {
        for(ptr=c->opt->check_email; ptr; ptr=ptr->next)
            if(X509_check_email(cert, ptr->name, 0, 0)>0)
                break;
        if(!ptr) {
            s_log(LOG_WARNING, "CERT: No matching email address found");
            return 0; /* reject */
        }
        s_log(LOG_INFO, "CERT: Email address \"%s\" matched", ptr->name);
    }

    if(c->opt->check_ip) {
        for(ptr=c->opt->check_ip; ptr; ptr=ptr->next)
            if(X509_check_ip_asc(cert, ptr->name, 0)>0)
                break;
        if(!ptr) {
            s_log(LOG_WARNING, "CERT: No matching IP address found");
            return 0; /* reject */
        }
        s_log(LOG_INFO, "CERT: IP address \"%s\" matched", ptr->name);
    }

    return 1; /* accept */
}
#endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */

NOEXPORT int cert_check_local(X509_STORE_CTX *callback_ctx) {
    X509 *cert;
    X509_NAME *subject;
#if OPENSSL_VERSION_NUMBER>=0x10000000L
    STACK_OF(X509) *sk;
    int i;
#endif
    X509_OBJECT obj;
    int success;

    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    subject=X509_get_subject_name(cert);

#if OPENSSL_VERSION_NUMBER>=0x10000000L
    /* modern API allows retrieving multiple matching certificates */
    sk=X509_STORE_get1_certs(callback_ctx, subject);
    if(sk) {
        for(i=0; i<sk_X509_num(sk); i++)
            if(compare_pubkeys(cert, sk_X509_value(sk, i))) {
                sk_X509_pop_free(sk, X509_free);
                return 1; /* accept */
            }
        sk_X509_pop_free(sk, X509_free);
    }
#endif

    /* pre-1.0.0 API only returns a single matching certificate */
    memset((char *)&obj, 0, sizeof obj);
    if(X509_STORE_get_by_subject(callback_ctx, X509_LU_X509,
            subject, &obj)<=0) {
        s_log(LOG_WARNING,
            "CERT: Certificate not found in local repository");
        return 0; /* reject */
    }
    success=compare_pubkeys(cert, obj.data.x509);
    X509_OBJECT_free_contents(&obj);
    if(!success) {
        s_log(LOG_WARNING, "CERT: Public keys do not match");
        X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REJECTED);
    }
    return success;
}

NOEXPORT int compare_pubkeys(X509 *c1, X509 *c2) {
    ASN1_BIT_STRING *k1=X509_get0_pubkey_bitstr(c1);
    ASN1_BIT_STRING *k2=X509_get0_pubkey_bitstr(c2);
    if(!k1 || !k2 || k1->length!=k2->length || k1->length<0 ||
            safe_memcmp(k1->data, k2->data, (size_t)k1->length))
        return 0; /* reject */
    s_log(LOG_INFO, "CERT: Locally installed certificate matched");
    return 1; /* accept */
}

/**************************************** CRL checking */

/* based on the BSD-style licensed code of mod_ssl */
NOEXPORT int crl_check(CLI *c, X509_STORE_CTX *callback_ctx) {
    X509_STORE_CTX store_ctx;
    X509_OBJECT obj;
    X509_NAME *subject;
    X509_NAME *issuer;
    X509 *cert;
    X509_CRL *crl;
    X509_REVOKED *revoked;
    EVP_PKEY *pubkey;
    long serial;
    int i, n, rc;
    char *cp;
    ASN1_TIME *last_update=NULL, *next_update=NULL;

    cert=X509_STORE_CTX_get_current_cert(callback_ctx);
    subject=X509_get_subject_name(cert);
    issuer=X509_get_issuer_name(cert);

    /* try to retrieve a CRL corresponding to the _subject_ of
     * the current certificate in order to verify it's integrity */
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    memset((char *)&obj, 0, sizeof obj);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        cp=X509_NAME2text(subject);
        s_log(LOG_INFO, "CRL: issuer: %s", cp);
        str_free(cp);
        last_update=X509_CRL_get_lastUpdate(crl);
        next_update=X509_CRL_get_nextUpdate(crl);
        log_time(LOG_INFO, "CRL: last update", last_update);
        log_time(LOG_INFO, "CRL: next update", next_update);

        /* verify the signature on this CRL */
        pubkey=X509_get_pubkey(cert);
        if(X509_CRL_verify(crl, pubkey)<=0) {
            s_log(LOG_WARNING, "CRL: Invalid signature");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_CRL_SIGNATURE_FAILURE);
            X509_OBJECT_free_contents(&obj);
            if(pubkey)
                EVP_PKEY_free(pubkey);
            return 0; /* reject */
        }
        if(pubkey)
            EVP_PKEY_free(pubkey);

        /* check date of CRL to make sure it's not expired */
        if(!next_update) {
            s_log(LOG_WARNING, "CRL: Invalid nextUpdate field");
            X509_STORE_CTX_set_error(callback_ctx,
                X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject */
        }
        if(X509_cmp_current_time(next_update)<0) {
            s_log(LOG_WARNING, "CRL: CRL Expired - revoking all certificates");
            X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CRL_HAS_EXPIRED);
            X509_OBJECT_free_contents(&obj);
            return 0; /* reject */
        }
        X509_OBJECT_free_contents(&obj);
    }

    /* try to retrieve a CRL corresponding to the _issuer_ of
     * the current certificate in order to check for revocation */
    memset((char *)&obj, 0, sizeof obj);
    X509_STORE_CTX_init(&store_ctx, c->opt->revocation_store, NULL, NULL);
    rc=X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj);
    X509_STORE_CTX_cleanup(&store_ctx);
    crl=obj.data.crl;
    if(rc>0 && crl) {
        /* check if the current certificate is revoked by this CRL */
        n=sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
        for(i=0; i<n; i++) {
            revoked=sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
            if(ASN1_INTEGER_cmp(revoked->serialNumber,
                    X509_get_serialNumber(cert))==0) {
                serial=ASN1_INTEGER_get(revoked->serialNumber);
                cp=X509_NAME2text(issuer);
                s_log(LOG_WARNING, "CRL: Certificate with serial %ld (0x%lX) "
                    "revoked per CRL from issuer %s", serial, serial, cp);
                str_free(cp);
                X509_STORE_CTX_set_error(callback_ctx, X509_V_ERR_CERT_REVOKED);
                X509_OBJECT_free_contents(&obj);
                return 0; /* reject */
            }
        }
        X509_OBJECT_free_contents(&obj);
    }
    return 1; /* accept */
}

#ifndef OPENSSL_NO_OCSP

/**************************************** OCSP checking */

/* type checks not available -- use generic functions */
#ifndef sk_OPENSSL_STRING_num
#define sk_OPENSSL_STRING_num(st) sk_num(st)
#endif
#ifndef sk_OPENSSL_STRING_value
#define sk_OPENSSL_STRING_value(st, i) sk_value((st),(i))
#endif

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;

    /* 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 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++) {
            s_log(LOG_NOTICE, "OCSP: Connecting AIA responder \"%s\"",
                sk_OPENSSL_STRING_value(aia, i));
            ocsp_status=ocsp_request(c, callback_ctx, cert_id,
                sk_OPENSSL_STRING_value(aia, i));
            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 */
}

/* returns one of:
 * V_OCSP_CERTSTATUS_GOOD
 * V_OCSP_CERTSTATUS_REVOKED
 * V_OCSP_CERTSTATUS_UNKNOWN */
NOEXPORT int ocsp_request(CLI *c, X509_STORE_CTX *callback_ctx,
        OCSP_CERTID *cert_id, char *url) {
    int ocsp_status=V_OCSP_CERTSTATUS_UNKNOWN;
    int response_status;
    int reason;
    int ctx_err=X509_V_ERR_APPLICATION_VERIFICATION;
    OCSP_REQUEST *request=NULL;
    OCSP_RESPONSE *response=NULL;
    OCSP_BASICRESP *basic_response=NULL;
    ASN1_GENERALIZEDTIME *revoked_at=NULL,
        *this_update=NULL, *next_update=NULL;

    /* build request */
    request=OCSP_REQUEST_new();
    if(!request) {
        sslerror("OCSP: OCSP_REQUEST_new");
        goto cleanup;
    }
    if(!OCSP_request_add0_id(request, OCSP_CERTID_dup(cert_id))) {
        sslerror("OCSP: OCSP_request_add0_id");
        goto cleanup;
    }
#if 0
    OCSP_request_add1_nonce(request, NULL, -1);
#endif

    /* send the request and get a response */
    response=ocsp_get_response(c, request, url);
    if(!response)
        goto cleanup;
    response_status=OCSP_response_status(response);
    if(response_status!=OCSP_RESPONSE_STATUS_SUCCESSFUL) {
        s_log(LOG_WARNING, "OCSP: Responder error: %d: %s",
            response_status, OCSP_response_status_str(response_status));
        goto cleanup;
    }

    /* verify the response */
    basic_response=OCSP_response_get1_basic(response);
    if(!basic_response) {
        sslerror("OCSP: OCSP_response_get1_basic");
        goto cleanup;
    }
#if 0
    if(OCSP_check_nonce(request, basic_response)<=0) {
        s_log(LOG_WARNING, "OCSP: Invalid nonce");
        goto cleanup;
    }
#endif
    if(OCSP_basic_verify(basic_response, X509_STORE_CTX_get_chain(callback_ctx),
            c->opt->revocation_store, c->opt->ocsp_flags)<=0) {
        sslerror("OCSP: OCSP_basic_verify");
        goto cleanup;
    }
    if(!OCSP_resp_find_status(basic_response, cert_id, &ocsp_status, &reason,
            &revoked_at, &this_update, &next_update)) {
        sslerror("OCSP: OCSP_resp_find_status");
        goto cleanup;
    }
    s_log(LOG_INFO, "OCSP: Status: %s", OCSP_cert_status_str(ocsp_status));
    log_time(LOG_INFO, "OCSP: This update", this_update);
    log_time(LOG_INFO, "OCSP: Next update", next_update);
    /* check if the response is valid for at least one minute */
    if(!OCSP_check_validity(this_update, next_update, 60, -1)) {
        sslerror("OCSP: OCSP_check_validity");
        ocsp_status=V_OCSP_CERTSTATUS_UNKNOWN;
        goto cleanup;
    }
    switch(ocsp_status) {
    case V_OCSP_CERTSTATUS_GOOD:
        s_log(LOG_NOTICE, "OCSP: Certificate accepted");
        break;
    case V_OCSP_CERTSTATUS_REVOKED:
        if(reason==-1)
            s_log(LOG_WARNING, "OCSP: Certificate revoked");
        else
            s_log(LOG_WARNING, "OCSP: Certificate revoked: %d: %s",
                reason, OCSP_crl_reason_str(reason));
        log_time(LOG_NOTICE, "OCSP: Revoked at", revoked_at);
        ctx_err=X509_V_ERR_CERT_REVOKED;
        break;
    case V_OCSP_CERTSTATUS_UNKNOWN:
        s_log(LOG_WARNING, "OCSP: Unknown verification status");
    }
cleanup:
    if(request)
        OCSP_REQUEST_free(request);
    if(response)
        OCSP_RESPONSE_free(response);
    if(basic_response)
        OCSP_BASICRESP_free(basic_response);
    if(ocsp_status!=V_OCSP_CERTSTATUS_GOOD)
        X509_STORE_CTX_set_error(callback_ctx, ctx_err);
    return ocsp_status;
}

NOEXPORT OCSP_RESPONSE *ocsp_get_response(CLI *c,
        OCSP_REQUEST *req, char *url) {
    BIO *bio=NULL;
    OCSP_REQ_CTX *req_ctx=NULL;
    OCSP_RESPONSE *resp=NULL;
    int err;
    char *host=NULL, *port=NULL, *path=NULL;
    SOCKADDR_UNION addr;
    int ssl;

    /* parse the OCSP URL */
    if(!OCSP_parse_url(url, &host, &port, &path, &ssl)) {
        s_log(LOG_ERR, "OCSP: Failed to parse the OCSP URL");
        goto cleanup;
    }
    if(ssl) {
        s_log(LOG_ERR, "OCSP: SSL not supported for OCSP"
            " - additional stunnel service needs to be defined");
        goto cleanup;
    }
    memset(&addr, 0, sizeof addr);
    addr.in.sin_family=AF_INET;
    if(!hostport2addr(&addr, host, port, 0)) {
        s_log(LOG_ERR, "OCSP: Failed to resolve the OCSP server address");
        goto cleanup;
    }

    /* connect specified OCSP server (responder) */
    c->fd=s_socket(addr.sa.sa_family, SOCK_STREAM, 0, 1, "OCSP: socket");
    if(c->fd==INVALID_SOCKET)
        goto cleanup;
    if(s_connect(c, &addr, addr_len(&addr)))
        goto cleanup;
    bio=BIO_new_socket((int)c->fd, BIO_NOCLOSE);
    if(!bio)
        goto cleanup;
    s_log(LOG_DEBUG, "OCSP: Connected %s:%s", host, port);

    /* OCSP protocol communication loop */
    req_ctx=OCSP_sendreq_new(bio, path, NULL, -1);
    if(!req_ctx) {
        sslerror("OCSP: OCSP_sendreq_new");
        goto cleanup;
    }
    if(!OCSP_REQ_CTX_add1_header(req_ctx, "Host", host)) {
        sslerror("OCSP: OCSP_REQ_CTX_add1_header");
        goto cleanup;
    }
    if(!OCSP_REQ_CTX_set1_req(req_ctx, req))
        goto cleanup;
    while(OCSP_sendreq_nbio(&resp, req_ctx)==-1) {
        s_poll_init(c->fds);
        s_poll_add(c->fds, c->fd, BIO_should_read(bio), BIO_should_write(bio));
        err=s_poll_wait(c->fds, c->opt->timeout_busy, 0);
        if(err==-1)
            sockerror("OCSP: s_poll_wait");
        if(err==0)
            s_log(LOG_INFO, "OCSP: s_poll_wait: TIMEOUTbusy exceeded");
        if(err<=0)
            goto cleanup;
    }
#if 0
    s_log(LOG_DEBUG, "OCSP: context state: 0x%x", *(int *)req_ctx);
#endif
    /* http://www.mail-archive.com/openssl-users@openssl.org/msg61691.html */
    if(resp) {
        s_log(LOG_DEBUG, "OCSP: Response received");
    } else {
        if(ERR_peek_error())
            sslerror("OCSP: OCSP_sendreq_nbio");
        else /* OpenSSL error: OCSP_sendreq_nbio does not use OCSPerr */
            s_log(LOG_ERR, "OCSP: OCSP_sendreq_nbio: OpenSSL internal error");
    }

cleanup:
    if(req_ctx)
        OCSP_REQ_CTX_free(req_ctx);
    if(bio)
        BIO_free_all(bio);
    if(c->fd!=INVALID_SOCKET) {
        closesocket(c->fd);
        c->fd=INVALID_SOCKET; /* avoid double close on cleanup */
    }
    if(host)
        OPENSSL_free(host);
    if(port)
        OPENSSL_free(port);
    if(path)
        OPENSSL_free(path);
    return resp;
}

/* find the issuer certificate without lookups */
NOEXPORT X509 *get_current_issuer(X509_STORE_CTX *callback_ctx) {
    STACK_OF(X509) *chain;
    int depth;

    chain=X509_STORE_CTX_get_chain(callback_ctx);
    depth=X509_STORE_CTX_get_error_depth(callback_ctx);
    if(depth<sk_X509_num(chain)-1) /* not the root CA cert */
        ++depth; /* index of the issuer cert */
    return sk_X509_value(chain, depth);
}

#endif /* !defined(OPENSSL_NO_OCSP) */

char *X509_NAME2text(X509_NAME *name) {
    char *text;
    BIO *bio;
    int n;

    bio=BIO_new(BIO_s_mem());
    if(!bio)
        return str_dup("BIO_new() failed");
    X509_NAME_print_ex(bio, name, 0,
        XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB & ~XN_FLAG_SPC_EQ);
    n=BIO_pending(bio);
    text=str_alloc((size_t)n+1);
    n=BIO_read(bio, text, n);
    if(n<0) {
        BIO_free(bio);
        str_free(text);
        return str_dup("BIO_read() failed");
    }
    text[n]='\0';
    BIO_free(bio);
    return text;
}

NOEXPORT void log_time(const int level, const char *txt, ASN1_TIME *t) {
    char *cp;
    BIO *bio;
    int n;

    if(!t)
        return;
    bio=BIO_new(BIO_s_mem());
    if(!bio)
        return;
    ASN1_TIME_print(bio, t);
    n=BIO_pending(bio);
    cp=str_alloc((size_t)n+1);
    n=BIO_read(bio, cp, n);
    if(n<0) {
        BIO_free(bio);
        str_free(cp);
        return;
    }
    cp[n]='\0';
    BIO_free(bio);
    s_log(level, "%s: %s", txt, cp);
    str_free(cp);
}

/* end of verify.c */
