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; }
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); }
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; }
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); }
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 }
/* 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; }
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; }
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); }
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); }
/****************************************************************************** * 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; }
/*- * 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; }
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; }
/* * 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; }