Beispiel #1
0
ERR_STATE *ERR_get_state(void)
{
    ERR_STATE *state = NULL;

    CRYPTO_THREAD_run_once(&err_init, err_do_init);

    state = CRYPTO_THREAD_get_local(&err_thread_local);

    if (state == NULL) {
        state = OPENSSL_zalloc(sizeof(*state));
        if (state == NULL)
            return NULL;

        if (!CRYPTO_THREAD_set_local(&err_thread_local, state)) {
            ERR_STATE_free(state);
            return NULL;
        }

        /* Ignore failures from these */
        OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
        ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE);
    }

    return state;
}
Beispiel #2
0
void err_free_strings_int(void)
{
    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);

    CRYPTO_THREAD_write_lock(err_string_lock);
    lh_ERR_STRING_DATA_free(int_error_hash);
    int_error_hash = NULL;
    CRYPTO_THREAD_unlock(err_string_lock);
}
Beispiel #3
0
int ERR_get_next_error_library(void)
{
    int ret;

    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);

    CRYPTO_THREAD_write_lock(err_string_lock);
    ret = int_err_library_number++;
    CRYPTO_THREAD_unlock(err_string_lock);
    return ret;
}
Beispiel #4
0
const char *ERR_lib_error_string(unsigned long e)
{
    ERR_STRING_DATA d, *p;
    unsigned long l;

    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);

    l = ERR_GET_LIB(e);
    d.error = ERR_PACK(l, 0, 0);
    p = int_err_get_item(&d);
    return ((p == NULL) ? NULL : p->string);
}
Beispiel #5
0
void ERR_load_ERR_strings(void)
{
#ifndef OPENSSL_NO_ERR
    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);

    err_load_strings(0, ERR_str_libraries);
    err_load_strings(0, ERR_str_reasons);
    err_load_strings(ERR_LIB_SYS, ERR_str_functs);
    build_SYS_str_reasons();
    err_load_strings(ERR_LIB_SYS, SYS_str_reasons);
#endif
}
Beispiel #6
0
/* The API (locked) version of "init" */
int ENGINE_init(ENGINE *e)
{
    int ret;
    if (e == NULL) {
        ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    CRYPTO_THREAD_run_once(&engine_lock_init, do_engine_lock_init);
    CRYPTO_THREAD_write_lock(global_engine_lock);
    ret = engine_unlocked_init(e);
    CRYPTO_THREAD_unlock(global_engine_lock);
    return ret;
}
Beispiel #7
0
ENGINE *ENGINE_new(void)
{
    ENGINE *ret;

    CRYPTO_THREAD_run_once(&engine_lock_init, do_engine_lock_init);

    ret = OPENSSL_zalloc(sizeof(*ret));
    if (ret == NULL) {
        ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    ret->struct_ref = 1;
    engine_ref_debug(ret, 0, 1);
    CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data);
    return ret;
}
Beispiel #8
0
const char *ERR_reason_error_string(unsigned long e)
{
    ERR_STRING_DATA d, *p = NULL;
    unsigned long l, r;

    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);

    l = ERR_GET_LIB(e);
    r = ERR_GET_REASON(e);
    d.error = ERR_PACK(l, 0, r);
    p = int_err_get_item(&d);
    if (!p) {
        d.error = ERR_PACK(0, 0, r);
        p = int_err_get_item(&d);
    }
    return ((p == NULL) ? NULL : p->string);
}
Beispiel #9
0
void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
{
    LHASH_OF(ERR_STRING_DATA) *hash;

    CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init);

    CRYPTO_THREAD_write_lock(err_string_lock);
    hash = get_hash(0, 0);
    if (hash) {
        for (; str->error; str++) {
            if (lib)
                str->error |= ERR_PACK(lib, 0, 0);
            (void)lh_ERR_STRING_DATA_delete(hash, str);
        }
    }
    CRYPTO_THREAD_unlock(err_string_lock);
}
Beispiel #10
0
/******************************************************************************
* function:
*         bind_qat(ENGINE *e,
*                  const char *id)
*
* @param e  [IN] - OpenSSL engine pointer
* @param id [IN] - engine id
*
* description:
*    Connect Qat engine to OpenSSL engine library
******************************************************************************/
static int bind_qat(ENGINE *e, const char *id)
{
    int ret = 0;

    WARN("QAT Warnings enabled.\n");
    DEBUG("QAT Debug enabled.\n");
    DEBUG("[%s] id=%s\n", __func__, id);

    if (id && (strcmp(id, engine_qat_id) != 0)) {
        WARN("ENGINE_id defined already!\n");
        goto end;
    }

    if (!ENGINE_set_id(e, engine_qat_id)) {
        WARN("ENGINE_set_id failed\n");
        goto end;
    }

    if (!ENGINE_set_name(e, engine_qat_name)) {
        WARN("ENGINE_set_name failed\n");
        goto end;
    }

    /* Ensure the QAT error handling is set up */
    ERR_load_QAT_strings();

    /*
     * Create static structures for ciphers now
     * as this function will be called by a single thread.
     */
    qat_create_ciphers();
#ifndef OPENSSL_ENABLE_QAT_SMALL_PACKET_CIPHER_OFFLOADS
    CRYPTO_THREAD_run_once(&qat_pkt_threshold_table_once,qat_pkt_threshold_table_make_key);
#endif
    DEBUG("%s: About to set mem functions\n", __func__);

    if (!ENGINE_set_RSA(e, qat_get_RSA_methods())) {
        WARN("ENGINE_set_RSA failed\n");
        goto end;
    }

    if (!ENGINE_set_DSA(e, qat_get_DSA_methods())) {
        WARN("ENGINE_set_DSA failed\n");
        goto end;
    }

    if (!ENGINE_set_DH(e, qat_get_DH_methods())) {
        WARN("ENGINE_set_DH failed\n");
        goto end;
    }

    if (!ENGINE_set_EC(e, qat_get_EC_methods())) {
        WARN("ENGINE_set_EC failed\n");
        goto end;
    }

    if (!ENGINE_set_ciphers(e, qat_ciphers)) {
        WARN("ENGINE_set_ciphers failed\n");
        goto end;
    }

    if (!ENGINE_set_pkey_meths(e, qat_PRF_pkey_methods)) {
        WARN("ENGINE_set_pkey_meths failed\n");
        goto end;
    }

    pthread_atfork(engine_fork_handler, NULL, NULL);

    if (!ENGINE_set_destroy_function(e, qat_engine_destroy)
        || !ENGINE_set_init_function(e, qat_engine_init)
        || !ENGINE_set_finish_function(e, qat_engine_finish)
        || !ENGINE_set_ctrl_function(e, qat_engine_ctrl)
        || !ENGINE_set_cmd_defns(e, qat_cmd_defns)) {
        WARN("[%s] failed reg destroy, init or finish\n", __func__);

        goto end;
    }

    ret = 1;

 end:
    return ret;

}
Beispiel #11
0
/*-
 * BIO_lookup - look up the node and service you want to connect to.
 * @node: the node you want to connect to.
 * @service: the service you want to connect to.
 * @lookup_type: declare intent with the result, client or server.
 * @family: the address family you want to use.  Use AF_UNSPEC for any, or
 *  AF_INET, AF_INET6 or AF_UNIX.
 * @socktype: The socket type you want to use.  Can be SOCK_STREAM, SOCK_DGRAM
 *  or 0 for all.
 * @res: Storage place for the resulting list of returned addresses
 *
 * This will do a lookup of the node and service that you want to connect to.
 * It returns a linked list of different addresses you can try to connect to.
 *
 * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
 *
 * The return value is 1 on success or 0 in case of error.
 */
int BIO_lookup(const char *host, const char *service,
               enum BIO_lookup_type lookup_type,
               int family, int socktype, BIO_ADDRINFO **res)
{
    int ret = 0;                 /* Assume failure */

    switch(family) {
    case AF_INET:
#ifdef AF_INET6
    case AF_INET6:
#endif
#ifdef AF_UNIX
    case AF_UNIX:
#endif
#ifdef AF_UNSPEC
    case AF_UNSPEC:
#endif
        break;
    default:
        BIOerr(BIO_F_BIO_LOOKUP, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
        return 0;
    }

#ifdef AF_UNIX
    if (family == AF_UNIX) {
        if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
            return 1;
        else
            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
        return 0;
    }
#endif

    if (BIO_sock_init() != 1)
        return 0;

    if (1) {
        int gai_ret = 0;
#ifdef AI_PASSIVE
        struct addrinfo hints;
        memset(&hints, 0, sizeof hints);

# ifdef AI_ADDRCONFIG
        hints.ai_flags = AI_ADDRCONFIG;
# endif
        hints.ai_family = family;
        hints.ai_socktype = socktype;

        if (lookup_type == BIO_LOOKUP_SERVER)
            hints.ai_flags |= AI_PASSIVE;

        /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
         * macro magic in bio_lcl.h
         */
        switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
# ifdef EAI_SYSTEM
        case EAI_SYSTEM:
            SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
            break;
# endif
        case 0:
            ret = 1;             /* Success */
            break;
        default:
            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
            ERR_add_error_data(1, gai_strerror(gai_ret));
            break;
        }
    } else {
#endif
        const struct hostent *he;
/*
 * Because struct hostent is defined for 32-bit pointers only with
 * VMS C, we need to make sure that '&he_fallback_address' and
 * '&he_fallback_addresses' are 32-bit pointers
 */
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size save
# pragma pointer_size 32
#endif
        /* Windows doesn't seem to have in_addr_t */
#ifdef OPENSSL_SYS_WINDOWS
        static uint32_t he_fallback_address;
        static const uint32_t *he_fallback_addresses[] =
            { &he_fallback_address, NULL };
#else
        static in_addr_t he_fallback_address;
        static const in_addr_t *he_fallback_addresses[] =
            { &he_fallback_address, NULL };
#endif
        static const struct hostent he_fallback =
            { NULL, NULL, AF_INET, sizeof(he_fallback_address),
              (char **)&he_fallback_addresses };
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size restore
#endif

        struct servent *se;
        /* Apparently, on WIN64, s_proto and s_port have traded places... */
#ifdef _WIN64
        struct servent se_fallback = { NULL, NULL, NULL, 0 };
#else
        struct servent se_fallback = { NULL, NULL, 0, NULL };
#endif

        CRYPTO_THREAD_run_once(&bio_lookup_init, do_bio_lookup_init);

        CRYPTO_THREAD_write_lock(bio_lookup_lock);
        he_fallback_address = INADDR_ANY;
        if (host == NULL) {
            he = &he_fallback;
            switch(lookup_type) {
            case BIO_LOOKUP_CLIENT:
                he_fallback_address = INADDR_LOOPBACK;
                break;
            case BIO_LOOKUP_SERVER:
                he_fallback_address = INADDR_ANY;
                break;
            default:
                OPENSSL_assert(("We forgot to handle a lookup type!" == 0));
                break;
            }
        } else {
            he = gethostbyname(host);

            if (he == NULL) {
#ifndef OPENSSL_SYS_WINDOWS
                BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
                ERR_add_error_data(1, hstrerror(h_errno));
#else
                SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
#endif
                ret = 0;
                goto err;
            }
        }

        if (service == NULL) {
            se_fallback.s_port = 0;
            se_fallback.s_proto = NULL;
            se = &se_fallback;
        } else {
            char *endp = NULL;
            long portnum = strtol(service, &endp, 10);

/*
 * Because struct servent is defined for 32-bit pointers only with
 * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
 */
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size save
# pragma pointer_size 32
#endif
            char *proto = NULL;
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size restore
#endif

            switch (socktype) {
            case SOCK_STREAM:
                proto = "tcp";
                break;
            case SOCK_DGRAM:
                proto = "udp";
                break;
            }

            if (endp != service && *endp == '\0'
                    && portnum > 0 && portnum < 65536) {
                se_fallback.s_port = htons(portnum);
                se_fallback.s_proto = proto;
                se = &se_fallback;
            } else if (endp == service) {
                se = getservbyname(service, proto);

                if (se == NULL) {
#ifndef OPENSSL_SYS_WINDOWS
                    BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
                    ERR_add_error_data(1, hstrerror(h_errno));
#else
                    SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
#endif
                    goto err;
                }
            } else {
                BIOerr(BIO_F_BIO_LOOKUP, BIO_R_MALFORMED_HOST_OR_SERVICE);
                goto err;
            }
        }

        *res = NULL;

        {
/*
 * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
 * we must make sure our iterator designates the same element type, hence
 * the pointer size dance.
 */
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size save
# pragma pointer_size 32
#endif
            char **addrlistp;
#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
# pragma pointer_size restore
#endif
            size_t addresses;
            BIO_ADDRINFO *tmp_bai = NULL;

            /* The easiest way to create a linked list from an
               array is to start from the back */
            for(addrlistp = he->h_addr_list; *addrlistp != NULL;
                addrlistp++)
                ;

            for(addresses = addrlistp - he->h_addr_list;
                addrlistp--, addresses-- > 0; ) {
                if (!addrinfo_wrap(he->h_addrtype, socktype,
                                   *addrlistp, he->h_length,
                                   se->s_port, &tmp_bai))
                    goto addrinfo_malloc_err;
                tmp_bai->bai_next = *res;
                *res = tmp_bai;
                continue;
             addrinfo_malloc_err:
                BIO_ADDRINFO_free(*res);
                *res = NULL;
                BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
                ret = 0;
                goto err;
            }

            ret = 1;
        }
     err:
        CRYPTO_THREAD_unlock(bio_lookup_lock);
    }

    return ret;
}
Beispiel #12
0
int SSL_get_ex_data_X509_STORE_CTX_idx(void)
{

    CRYPTO_THREAD_run_once(&ssl_x509_store_ctx_once, ssl_x509_store_ctx_init);
    return ssl_x509_store_ctx_idx;
}
Beispiel #13
0
/*
 * If this function is called with a non NULL settings value then it must be
 * called prior to any threads making calls to any OpenSSL functions,
 * i.e. passing a non-null settings value is assumed to be single-threaded.
 */
int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
{
    static int stoperrset = 0;

    if (stopped) {
        if (!stoperrset) {
            /*
             * We only ever set this once to avoid getting into an infinite
             * loop where the error system keeps trying to init and fails so
             * sets an error etc
             */
            stoperrset = 1;
            CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
        }
        return 0;
    }

    if (!CRYPTO_THREAD_run_once(&base, ossl_init_base))
        return 0;

    if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
            && !CRYPTO_THREAD_run_once(&load_crypto_strings,
                                       ossl_init_no_load_crypto_strings))
        return 0;

    if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
            && !CRYPTO_THREAD_run_once(&load_crypto_strings,
                                       ossl_init_load_crypto_strings))
        return 0;

    if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
            && !CRYPTO_THREAD_run_once(&add_all_ciphers, ossl_init_no_add_algs))
        return 0;

    if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
            && !CRYPTO_THREAD_run_once(&add_all_ciphers,
                                       ossl_init_add_all_ciphers))
        return 0;

    if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
            && !CRYPTO_THREAD_run_once(&add_all_digests, ossl_init_no_add_algs))
        return 0;

    if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
            && !CRYPTO_THREAD_run_once(&add_all_digests,
                                       ossl_init_add_all_digests))
        return 0;

    if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
            && !CRYPTO_THREAD_run_once(&config, ossl_init_no_config))
        return 0;

    if (opts & OPENSSL_INIT_LOAD_CONFIG) {
        int ret;
        CRYPTO_THREAD_write_lock(init_lock);
        config_filename = (settings == NULL) ? NULL : settings->config_name;
        ret = CRYPTO_THREAD_run_once(&config, ossl_init_config);
        CRYPTO_THREAD_unlock(init_lock);
        if (!ret)
            return 0;
    }

#ifndef OPENSSL_NO_ASYNC
    if ((opts & OPENSSL_INIT_ASYNC)
            && !CRYPTO_THREAD_run_once(&async, ossl_init_async))
        return 0;
#endif
#ifndef OPENSSL_NO_ENGINE
    if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
            && !CRYPTO_THREAD_run_once(&engine_openssl,
                                       ossl_init_engine_openssl))
        return 0;
# if !defined(OPENSSL_NO_HW) && \
    (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
    if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
            && !CRYPTO_THREAD_run_once(&engine_cryptodev,
                                       ossl_init_engine_cryptodev))
        return 0;
# endif
# ifndef OPENSSL_NO_RDRAND
    if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
            && !CRYPTO_THREAD_run_once(&engine_rdrand, ossl_init_engine_rdrand))
        return 0;
# endif
    if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
            && !CRYPTO_THREAD_run_once(&engine_dynamic,
                                       ossl_init_engine_dynamic))
        return 0;
# ifndef OPENSSL_NO_STATIC_ENGINE
#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
    if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
            && CRYPTO_THREAD_run_once(&engine_padlock,
                                      ossl_init_engine_padlock))
        return 0;
#  endif
#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
    if ((opts & OPENSSL_INIT_ENGINE_CAPI)
            && CRYPTO_THREAD_run_once(&engine_capi, ossl_init_engine_capi))
        return 0;
#  endif
    if ((opts & OPENSSL_INIT_ENGINE_DASYNC)
            && !CRYPTO_THREAD_run_once(&engine_dasync, ossl_init_engine_dasync))
        return 0;
#  if !defined(OPENSSL_NO_AFALGENG)
    if ((opts & OPENSSL_INIT_ENGINE_AFALG)
            && !CRYPTO_THREAD_run_once(&engine_afalg, ossl_init_engine_afalg))
        return 0;
#  endif
# endif
    if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
                | OPENSSL_INIT_ENGINE_DASYNC | OPENSSL_INIT_ENGINE_OPENSSL
                | OPENSSL_INIT_ENGINE_AFALG)) {
        ENGINE_register_all_complete();
    }
#endif

    if ((opts & OPENSSL_INIT_ZLIB)
            && CRYPTO_THREAD_run_once(&zlib, ossl_init_zlib))
        return 0;

    return 1;
}