diff --git a/crypto/err/err.c b/crypto/err/err.c index b78ee6b3..76d101ab 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -271,6 +271,11 @@ void ERR_clear_error(void) { state->top = state->bottom = 0; } +int ERR_get_next_error_library() { + err_fns_check(); + return ERRFN(get_next_library)(); +} + void ERR_clear_system_error(void) { errno = 0; } diff --git a/crypto/err/err.h b/crypto/err/err.h index 411bc9be..891fb3e7 100644 --- a/crypto/err/err.h +++ b/crypto/err/err.h @@ -254,6 +254,14 @@ void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx); void ERR_clear_error(void); +/* Custom errors. */ + +/* ERR_get_next_error_library returns a value suitable for passing as the + * |library| argument to |ERR_put_error|. This is intended for code that wishes + * to push its own, non-standard errors to the error queue. */ +int ERR_get_next_error_library(); + + /* Private functions. */ /* ERR_clear_system_error clears the system's error value (i.e. errno). */ @@ -467,6 +475,11 @@ struct ERR_FNS_st { /* get_state returns the ERR_STATE for the current thread. This function * never returns NULL. */ ERR_STATE *(*get_state)(void); + + /* get_next_library returns a unique value suitable for passing as the + * |library| to error calls. It will be distinct from all built-in library + * values. */ + int (*get_next_library)(void); }; /* OPENSSL_DECLARE_ERROR_REASON is used by util/make_errors.h (which generates diff --git a/crypto/err/err_impl.c b/crypto/err/err_impl.c index ff2509d4..6544c7b5 100644 --- a/crypto/err/err_impl.c +++ b/crypto/err/err_impl.c @@ -125,6 +125,9 @@ static LHASH_OF(ERR_STATE) *state_hash = NULL; * function / reason. */ static LHASH_OF(ERR_STRING_DATA) *error_hash = NULL; +/* global_next_library contains the next custom library value to return. */ +static int global_next_library = ERR_NUM_LIBS; + /* err_string_data_hash is an lhash hash function for ERR_STRING_DATA. */ static uint32_t err_string_data_hash(const ERR_STRING_DATA *a) { return OPENSSL_hash32(&a->error, sizeof(a->error)); @@ -271,10 +274,21 @@ static void err_shutdown(void) { CRYPTO_w_unlock(CRYPTO_LOCK_ERR); } +static int err_get_next_library(void) { + int ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + ret = global_next_library++; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; +} + const struct ERR_FNS_st openssl_err_default_impl = { err_shutdown, err_get_item, err_set_item, err_del_item, err_get_state, + err_get_next_library, };