The branch master has been updated via c3612970465d0a13f2fc5b47bc28ca18516a699d (commit) via 036913b1076da41f257c640a5e6230476c647eff (commit) via 49c6434673ca5e9413062851979cf6ed126c9f1c (commit) via add8c8e9647a71cc755dea22490e2075e342624b (commit) via ed57f7f93508776b898e4c23b65d67f3479edaf1 (commit) via 7c0e20dc6f11aa506abc99ccc90b3a39c48c3052 (commit) via 8a4dc425cc73040c55bc01d89c5541e37dab939a (commit) via e039ca38c8d77f1e2f182123727c884aaf2d683d (commit) from 35f6fe7ac4fbde98d4fd6af968dfe320011bbe1e (commit)
- Log ----------------------------------------------------------------- commit c3612970465d0a13f2fc5b47bc28ca18516a699d Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 16:55:32 2019 +0200 Avoid using ERR_put_error() directly in OpenSSL code If compiled with 'no-deprecated', ERR_put_error() is undefined. We had one spot where we were using it directly, because the file and line information was passed from elsewhere. Fortunately, it's possible to use ERR_raise() for that situation, and call ERR_set_debug() immediately after and thereby override the information that ERR_raise() stored in the error record. util/mkerr.pl needed a small adjustment to not generate code that won't compile in a 'no-deprecated' configuration. Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) commit 036913b1076da41f257c640a5e6230476c647eff Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 14:00:39 2019 +0200 Adapt the FIPS provider to use the new core error functions Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) commit 49c6434673ca5e9413062851979cf6ed126c9f1c Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 13:37:42 2019 +0200 Refactor provider support for reporting errors The core now supplies its own versions of ERR_new(), ERR_set_debug() and ERR_vset_error(). This should suffice for a provider to have any OpenSSL compatible functionlity it desires. The main difference between the ERR functions and the core counterparts is that the core counterparts take an OSSL_PROVIDER parameter instead of the library number. That way, providers do not need to know what number they have been assigned, that information stays in the core. Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) commit add8c8e9647a71cc755dea22490e2075e342624b Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 13:25:56 2019 +0200 ERR: Remove ERR_put_func_error() and reimplement ERR_put_error() as a macro Also, deprecate ERR_put_error() Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) commit ed57f7f93508776b898e4c23b65d67f3479edaf1 Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 13:13:52 2019 +0200 ERR: Implement the macros ERR_raise() and ERR_raise_data() and use them The ERR_raise() macro uses a trick in C. The following is permitted: #include <stdio.h> void first(void) { printf("Hello! "); } void foo(const char *bar) { printf("%s", bar); } int main() { /* This */ (first(),foo)("cookie"); } ERR_raise_data() can be used to implement FUNCerr() as well, which takes away the need for the special function ERR_put_func_error(). Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) commit 7c0e20dc6f11aa506abc99ccc90b3a39c48c3052 Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 13:03:32 2019 +0200 ERR: Add new building blocks for reporting errors The new building block are ERR_new(), ERR_set_debug(), ERR_set_error(), ERR_vset_error(), which allocate a new error record and set the diverse data in them. They are designed in such a way that it's reasonably easy to create macros that use all of them but then rely completely on the function signature of ERR_set_error() or ERR_vset_error(). Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) commit 8a4dc425cc73040c55bc01d89c5541e37dab939a Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 12:56:58 2019 +0200 ERR: refactor useful inner macros to err_locl.h. Add function name field The useful inner macros are now static inline functions. That will make them easier to debug in the future. Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) commit e039ca38c8d77f1e2f182123727c884aaf2d683d Author: Richard Levitte <levi...@openssl.org> Date: Wed Jul 24 12:53:36 2019 +0200 Move some macros from include/openssl/opensslconf.h.in, add OPENSSL_FUNC New header file, include/openssl/macros.h, which contains diverse useful macros that we use elsewhere. We also add the new macro OPENSSL_FUNC, which is an alias for __FUNC__, __FUNCTION__, __FUNCSIG or __func__, depending on what the compiler supports. In the worst case, it's an alias for the string "(unknown function)". Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/9452) ----------------------------------------------------------------------- Summary of changes: crypto/err/build.info | 2 +- crypto/err/err.c | 83 +----------------- crypto/err/err_blocks.c | 113 ++++++++++++++++++++++++ crypto/err/err_locl.h | 68 ++++++++++++++ crypto/property/property_parse.c | 53 +++++------ crypto/provider_core.c | 72 +++++++++------ doc/man3/ERR_new.pod | 78 +++++++++++++++++ doc/man3/ERR_put_error.pod | 40 ++++++--- doc/man7/provider-base.pod | 58 ++++++++---- engines/e_afalg_err.c | 3 +- engines/e_capi_err.c | 3 +- engines/e_dasync_err.c | 3 +- engines/e_ossltest_err.c | 3 +- include/openssl/core_numbers.h | 20 +++-- include/openssl/err.h | 114 ++++++++++++++---------- include/openssl/{opensslconf.h.in => macros.h} | 74 ++++------------ include/openssl/opensslconf.h.in | 117 +------------------------ providers/fips/fipsprov.c | 41 +++++---- ssl/statem/statem.c | 3 +- test/errtest.c | 8 +- util/libcrypto.num | 8 +- util/mkerr.pl | 3 +- util/private.num | 3 + 23 files changed, 543 insertions(+), 427 deletions(-) create mode 100644 crypto/err/err_blocks.c create mode 100644 crypto/err/err_locl.h create mode 100644 doc/man3/ERR_new.pod copy include/openssl/{opensslconf.h.in => macros.h} (70%) diff --git a/crypto/err/build.info b/crypto/err/build.info index 6163d95b74..c010ea4cb9 100644 --- a/crypto/err/build.info +++ b/crypto/err/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - err.c err_all.c err_prn.c + err_blocks.c err.c err_all.c err_prn.c diff --git a/crypto/err/err.c b/crypto/err/err.c index 7a35512f87..f129c1c7d6 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -22,6 +22,7 @@ #include "internal/ctype.h" #include "internal/constant_time_locl.h" #include "e_os.h" +#include "err_locl.h" static int err_load_strings(const ERR_STRING_DATA *str); @@ -235,40 +236,6 @@ static void build_SYS_str_reasons(void) } #endif -#define err_get_slot(p) \ - do { \ - (p)->top = ((p)->top + 1) % ERR_NUM_ERRORS; \ - if ((p)->top == (p)->bottom) \ - (p)->bottom = ((p)->bottom + 1) % ERR_NUM_ERRORS; \ - } while (0) - -#define err_clear_data(p, i, deall) \ - do { \ - if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) { \ - if (deall) { \ - OPENSSL_free((p)->err_data[i]); \ - (p)->err_data[i] = NULL; \ - (p)->err_data_size[i] = 0; \ - (p)->err_data_flags[i] = 0; \ - } else if ((p)->err_data[i] != NULL) { \ - (p)->err_data[i][0] = '\0'; \ - } \ - } else { \ - (p)->err_data[i] = NULL; \ - (p)->err_data_size[i] = 0; \ - (p)->err_data_flags[i] = 0; \ - } \ - } while (0) - -#define err_clear(p, i, deall) \ - do { \ - err_clear_data((p), (i), (deall)); \ - (p)->err_flags[i] = 0; \ - (p)->err_buffer[i] = 0; \ - (p)->err_file[i] = NULL; \ - (p)->err_line[i] = -1; \ - } while (0) - static void ERR_STATE_free(ERR_STATE *s) { int i; @@ -388,47 +355,6 @@ void err_free_strings_int(void) /********************************************************/ -void ERR_put_func_error(int lib, const char *func, int reason, - const char *file, int line) -{ - ERR_put_error(lib, 0, reason, file, line); - ERR_add_error_data(2, "calling function ", func); -} - -void ERR_put_error(int lib, int func, int reason, const char *file, int line) -{ - ERR_STATE *es; - -#ifdef _OSD_POSIX - /* - * In the BS2000-OSD POSIX subsystem, the compiler generates path names - * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to - * something sensible. @@@ We shouldn't modify a const string, though. - */ - if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) { - char *end; - - /* Skip the "*POSIX(" prefix */ - file += sizeof("*POSIX(") - 1; - end = &file[strlen(file) - 1]; - if (*end == ')') - *end = '\0'; - /* Optional: use the basename of the path only. */ - if ((end = strrchr(file, '/')) != NULL) - file = &end[1]; - } -#endif - es = ERR_get_state(); - if (es == NULL) - return; - - err_get_slot(es); - err_clear(es, es->top, 0); - es->err_buffer[es->top] = ERR_PACK(lib, func, reason); - es->err_file[es->top] = file; - es->err_line[es->top] = line; -} - void ERR_clear_error(void) { int i; @@ -789,18 +715,13 @@ static int err_set_error_data_int(char *data, size_t size, int flags, int deallocate) { ERR_STATE *es; - int i; es = ERR_get_state(); if (es == NULL) return 0; - i = es->top; - err_clear_data(es, es->top, deallocate); - es->err_data[i] = data; - es->err_data_size[i] = size; - es->err_data_flags[i] = flags; + err_set_data(es, es->top, data, size, flags); return 1; } diff --git a/crypto/err/err_blocks.c b/crypto/err/err_blocks.c new file mode 100644 index 0000000000..49086bd0c2 --- /dev/null +++ b/crypto/err/err_blocks.c @@ -0,0 +1,113 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> +#include <openssl/err.h> +#include "err_locl.h" + +void ERR_new(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + if (es == NULL) + return; + + /* Allocate a slot */ + err_get_slot(es); + err_clear(es, es->top, 0); +} + +void ERR_set_debug(const char *file, int line, const char *func) +{ + ERR_STATE *es; + + es = ERR_get_state(); + if (es == NULL) + return; + + err_set_debug(es, es->top, file, line, func); +} + +void ERR_set_error(int lib, int reason, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ERR_vset_error(lib, reason, fmt, args); + va_end(args); +} + +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) +{ + ERR_STATE *es; + char *buf = NULL; + size_t buf_size = 0; + unsigned long flags = 0; + size_t i; + + es = ERR_get_state(); + if (es == NULL) + return; + i = es->top; + + if (fmt != NULL) { + int printed_len = 0; + char *rbuf = NULL; + + buf = es->err_data[i]; + buf_size = es->err_data_size[i]; + + /* + * To protect the string we just grabbed from tampering by other + * functions we may call, or to protect them from freeing a pointer + * that may no longer be valid at that point, we clear away the + * data pointer and the flags. We will set them again at the end + * of this function. + */ + es->err_data[i] = NULL; + es->err_data_flags[i] = 0; + + /* + * Try to maximize the space available. If that fails, we use what + * we have. + */ + if (buf_size < ERR_MAX_DATA_SIZE + && (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) { + buf = rbuf; + buf_size = ERR_MAX_DATA_SIZE; + } + + if (buf != NULL) { + printed_len = BIO_vsnprintf(buf, ERR_MAX_DATA_SIZE, fmt, args); + } + if (printed_len < 0) + printed_len = 0; + buf[printed_len] = '\0'; + + /* + * Try to reduce the size, but only if we maximized above. If that + * fails, we keep what we have. + * (According to documentation, realloc leaves the old buffer untouched + * if it fails) + */ + if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) { + buf = rbuf; + buf_size = printed_len + 1; + } + + if (buf != NULL) + flags = ERR_TXT_MALLOCED | ERR_TXT_STRING; + } + + err_clear_data(es, es->top, 0); + err_set_error(es, es->top, lib, reason); + if (fmt != NULL) + err_set_data(es, es->top, buf, buf_size, flags); +} diff --git a/crypto/err/err_locl.h b/crypto/err/err_locl.h new file mode 100644 index 0000000000..d45a00e746 --- /dev/null +++ b/crypto/err/err_locl.h @@ -0,0 +1,68 @@ +/* + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/err.h> +#include <openssl/e_os2.h> + +static ossl_inline void err_get_slot(ERR_STATE *es) +{ + es->top = (es->top + 1) % ERR_NUM_ERRORS; + if (es->top == es->bottom) + es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; +} + +static ossl_inline void err_clear_data(ERR_STATE *es, size_t i, int deall) +{ + if (es->err_data_flags[i] & ERR_TXT_MALLOCED) { + if (deall) { + OPENSSL_free(es->err_data[i]); + es->err_data[i] = NULL; + es->err_data_size[i] = 0; + es->err_data_flags[i] = 0; + } else if (es->err_data[i] != NULL) { + es->err_data[i][0] = '\0'; + } + } else { + es->err_data[i] = NULL; + es->err_data_size[i] = 0; + es->err_data_flags[i] = 0; + } +} + +static ossl_inline void err_set_error(ERR_STATE *es, size_t i, + int lib, int reason) +{ + es->err_buffer[i] = ERR_PACK(lib, 0, reason); +} + +static ossl_inline void err_set_debug(ERR_STATE *es, size_t i, + const char *file, int line, + const char *fn) +{ + es->err_file[i] = file; + es->err_line[i] = line; + es->err_func[i] = fn; +} + +static ossl_inline void err_set_data(ERR_STATE *es, size_t i, + void *data, size_t datasz, int flags) +{ + es->err_data[i] = data; + es->err_data_size[i] = datasz; + es->err_data_flags[i] = flags; +} + +static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall) +{ + err_clear_data(es, i, (deall)); + es->err_flags[i] = 0; + es->err_buffer[i] = 0; + es->err_file[i] = NULL; + es->err_line[i] = -1; +} diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index 0b4dcfc8aa..c17b0ddefc 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -91,8 +91,8 @@ static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create, for (;;) { if (!ossl_isalpha(*s)) { - PROPerr(PROP_F_PARSE_NAME, PROP_R_NOT_AN_IDENTIFIER); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_IDENTIFIER, + "HERE-->%s", *t); return 0; } do { @@ -112,8 +112,7 @@ static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create, } name[i] = '\0'; if (err) { - PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NAME_TOO_LONG, "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -132,8 +131,8 @@ static int parse_number(const char *t[], PROPERTY_DEFINITION *res) v = v * 10 + (*s++ - '0'); } while (ossl_isdigit(*s)); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_NUMBER, PROP_R_NOT_A_DECIMAL_DIGIT); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT, + "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -157,8 +156,8 @@ static int parse_hex(const char *t[], PROPERTY_DEFINITION *res) v += ossl_tolower(*s) - 'a'; } while (ossl_isxdigit(*++s)); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_HEX, PROP_R_NOT_AN_HEXADECIMAL_DIGIT); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT, + "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -178,8 +177,8 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res) v = (v << 3) + (*s - '0'); } while (ossl_isdigit(*++s) && *s != '9' && *s != '8'); if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_OCT, PROP_R_NOT_AN_OCTAL_DIGIT); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT, + "HERE-->%s", *t); return 0; } *t = skip_space(s); @@ -204,18 +203,13 @@ static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim, s++; } if (*s == '\0') { - char buf[2] = { 0, 0 }; - - PROPerr(PROP_F_PARSE_STRING, - PROP_R_NO_MATCHING_STRING_DELIMETER); - buf[0] = delim; - ERR_add_error_data(3, "HERE-->", buf, *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMETER, + "HERE-->%c%s", delim, *t); return 0; } v[i] = '\0'; if (err) { - PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t); } else { res->v.str_val = ossl_property_value(ctx, v, create); } @@ -242,14 +236,13 @@ static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[], s++; } if (!ossl_isspace(*s) && *s != '\0' && *s != ',') { - PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_NOT_AN_ASCII_CHARACTER); - ERR_add_error_data(2, "HERE-->", s); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_ASCII_CHARACTER, + "HERE-->%s", s); return 0; } v[i] = 0; if (err) { - PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG); - ERR_add_error_data(2, "HERE-->", *t); + ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t); } else { res->v.str_val = ossl_property_value(ctx, v, create); } @@ -358,14 +351,14 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn) goto err; prop->oper = PROPERTY_OPER_EQ; if (prop->name_idx == 0) { - PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_PARSE_FAILED); - ERR_add_error_data(2, "Unknown name HERE-->", start); + ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED, + "Unknown name HERE-->%s", start); goto err; } if (match_ch(&s, '=')) { if (!parse_value(ctx, &s, prop, 1)) { - PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE); - ERR_add_error_data(2, "HERE-->", start); + ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_VALUE, + "HERE-->%s", start); goto err; } } else { @@ -380,8 +373,8 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn) done = !match_ch(&s, ','); } if (*s != '\0') { - PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_TRAILING_CHARACTERS); - ERR_add_error_data(2, "HERE-->", s); + ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS, + "HERE-->%s", s); goto err; } res = stack_to_property_list(sk); @@ -442,8 +435,8 @@ skip_value: done = !match_ch(&s, ','); } if (*s != '\0') { - PROPerr(PROP_F_OSSL_PARSE_QUERY, PROP_R_TRAILING_CHARACTERS); - ERR_add_error_data(2, "HERE-->", s); + ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS, + "HERE-->%s", s); goto err; } res = stack_to_property_list(sk); diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 385a632653..803406d7f7 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -225,9 +225,8 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name, if ((prov = ossl_provider_find(libctx, name)) != NULL) { /* refcount +1 */ ossl_provider_free(prov); /* refcount -1 */ - CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_NEW, - CRYPTO_R_PROVIDER_ALREADY_EXISTS); - ERR_add_error_data(2, "name=", name); + ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_ALREADY_EXISTS, NULL, + "name=%s", name); return NULL; } @@ -438,8 +437,8 @@ static int provider_activate(OSSL_PROVIDER *prov) if (prov->init_function == NULL || !prov->init_function(prov, core_dispatch, &provider_dispatch, &prov->provctx)) { - CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL); - ERR_add_error_data(2, "name=", prov->name); + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL, NULL, + "name=%s", prov->name); #ifndef FIPS_MODE DSO_free(prov->module); prov->module = NULL; @@ -730,6 +729,21 @@ static const OSSL_PARAM param_types[] = { OSSL_PARAM_END }; +/* + * Forward declare all the functions that are provided aa dispatch. + * This ensures that the compiler will complain if they aren't defined + * with the correct signature. + */ +static OSSL_core_get_param_types_fn core_get_param_types; +static OSSL_core_get_params_fn core_get_params; +static OSSL_core_thread_start_fn core_thread_start; +static OSSL_core_get_library_context_fn core_get_libctx; +#ifndef FIPS_MODE +static OSSL_core_new_error_fn core_new_error; +static OSSL_core_set_error_debug_fn core_set_error_debug; +static OSSL_core_vset_error_fn core_vset_error; +#endif + static const OSSL_PARAM *core_get_param_types(const OSSL_PROVIDER *prov) { return param_types; @@ -758,7 +772,6 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) return 1; } -static OSSL_core_get_library_context_fn core_get_libctx; /* Check */ static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov) { return prov->libctx; @@ -776,8 +789,26 @@ static int core_thread_start(const OSSL_PROVIDER *prov, * ones. */ #ifndef FIPS_MODE -static void core_put_error(const OSSL_PROVIDER *prov, - uint32_t reason, const char *file, int line) +/* + * TODO(3.0) These error functions should use |prov| to select the proper + * library context to report in the correct error stack, at least if error + * stacks become tied to the library context. + * We cannot currently do that since there's no support for it in the + * ERR subsystem. + */ +static void core_new_error(const OSSL_PROVIDER *prov) +{ + ERR_new(); +} + +static void core_set_error_debug(const OSSL_PROVIDER *prov, + const char *file, int line, const char *func) +{ + ERR_set_debug(file, line, func); +} + +static void core_vset_error(const OSSL_PROVIDER *prov, + uint32_t reason, const char *fmt, va_list args) { /* * If the uppermost 8 bits are non-zero, it's an OpenSSL library @@ -785,27 +816,11 @@ static void core_put_error(const OSSL_PROVIDER *prov, * provider error and will be treated as such. */ if (ERR_GET_LIB(reason) != 0) { - ERR_PUT_error(ERR_GET_LIB(reason), - ERR_GET_FUNC(reason), - ERR_GET_REASON(reason), - file, line); + ERR_vset_error(ERR_GET_LIB(reason), ERR_GET_REASON(reason), fmt, args); } else { - ERR_PUT_error(prov->error_lib, 0, (int)reason, file, line); + ERR_vset_error(prov->error_lib, (int)reason, fmt, args); } } - -/* - * TODO(3.0) This, as well as core_put_error above, should use |prov| - * to select the proper library context to report in the correct error - * stack, at least if error stacks become tied to the library context. - * We cannot currently do that since there's no support for it in the - * ERR subsystem. - */ -static void core_add_error_vdata(const OSSL_PROVIDER *prov, - int num, va_list args) -{ - ERR_add_error_vdata(num, args); -} #endif /* @@ -818,8 +833,9 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT, (void (*)(void))core_get_libctx }, { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start }, #ifndef FIPS_MODE - { OSSL_FUNC_CORE_PUT_ERROR, (void (*)(void))core_put_error }, - { OSSL_FUNC_CORE_ADD_ERROR_VDATA, (void (*)(void))core_add_error_vdata }, + { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error }, + { OSSL_FUNC_CORE_SET_ERROR_DEBUG, (void (*)(void))core_set_error_debug }, + { OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error }, #endif { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, diff --git a/doc/man3/ERR_new.pod b/doc/man3/ERR_new.pod new file mode 100644 index 0000000000..80419da2c4 --- /dev/null +++ b/doc/man3/ERR_new.pod @@ -0,0 +1,78 @@ +=pod + +=head1 NAME + +ERR_new, ERR_set_debug, ERR_set_error, ERR_vset_error +- Error recording building blocks + +=head1 SYNOPSIS + + #include <openssl/err.h> + + void ERR_new(void); + void ERR_set_debug(const char *file, int line, const char *func); + void ERR_set_error(int lib, int reason, const char *fmt, ...); + void ERR_vset_error(int lib, int reason, const char *fmt, va_list args); + +=head1 DESCRIPTION + +The functions described here are generally not used directly, but +rather through macros such as L<ERR_raise(3)>. +They can still be useful for anyone that wants to make their own +macros. + +ERR_new() allocates a new slot in the thread's error queue. + +ERR_set_debug() sets the debug information related to the current +error in the thread's error queue. +The values that can be given are the file name I<file>, line in the +file I<line> and the name of the function I<func> where the error +occured. +The names must be constant, this function will only save away the +pointers, not copy the strings. + +ERR_set_error() sets the error information, which are the library +number I<lib> and the reason code I<reason>, and additional data as a +format string I<fmt> and an arbitrary number of arguments. +The additional data is processed with L<BIO_snprintf(3)> to form the +additional data string, which is allocated and store in the error +record. + +ERR_vset_error() works like ERR_set_error(), but takes a B<va_list> +argument instead of a variable number of arguments. + +=head1 RETURN VALUES + +ERR_new, ERR_set_debug, ERR_set_error and ERR_vset_error +do not return any values. + +=head1 NOTES + +The library number is unique to each unit that records errors. +OpenSSL has a number of pre-allocated ones for its own uses, but +others may allocate their own library number dynamically with +L<ERR_get_next_error_library(3)>. + +Reason codes are unique within each library, and may have an +associated set of strings as a short description of the reason. +For dynamically allocated library numbers, reason strings are recorded +with L<ERR_load_strings(3)>. + +Provider authors are supplied with core versions of these functions, +see L<provider-base(7)>. + +=head1 SEE ALSO + +L<ERR_raise(3)>, L<ERR_get_next_error_library(3)>, +L<ERR_load_strings(3)>, L<BIO_snprintf(3)>, L<provider-base(7)> + +=head1 COPYRIGHT + +Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L<https://www.openssl.org/source/license.html>. + +=cut diff --git a/doc/man3/ERR_put_error.pod b/doc/man3/ERR_put_error.pod index c2913d5af4..729eb574ce 100644 --- a/doc/man3/ERR_put_error.pod +++ b/doc/man3/ERR_put_error.pod @@ -2,31 +2,41 @@ =head1 NAME -ERR_put_error, ERR_put_func_error, -ERR_add_error_data, ERR_add_error_vdata - record an error +ERR_raise, ERR_raise_data, +ERR_put_error, ERR_add_error_data, ERR_add_error_vdata +- record an error =head1 SYNOPSIS #include <openssl/err.h> - void ERR_put_error(int lib, int func, int reason, const char *file, int line); - void ERR_put_func_error(int lib, const char *func, int reason, - const char *file, int line); + void ERR_raise(int lib, int reason); + void ERR_raise_data(int lib, int reason, const char *fmt, ...); void ERR_add_error_data(int num, ...); void ERR_add_error_vdata(int num, va_list arg); +Deprecated since OpenSSL 3.0: + + void ERR_put_error(int lib, int func, int reason, const char *file, int line); + =head1 DESCRIPTION +ERR_raise() adds a new error to the thread's error queue. The +error occured in the library B<lib> for the reason given by the +B<reason> code. Furthermore, the name of the file, the line, and name +of the function where the error occured is saved with the error +record. + +ERR_raise_data() does the same thing as ERR_raise(), but also lets the +caller specify additional information as a format string B<fmt> and an +arbitrary number of values, which are processed with L<BIO_snprintf(3)>. + ERR_put_error() adds an error code to the thread's error queue. It signals that the error of reason code B<reason> occurred in function B<func> of library B<lib>, in line number B<line> of B<file>. This function is usually called by a macro. -ERR_put_func_err() is similar except that the B<func> is a string naming -a function external to OpenSSL, usually provided by the platform on which -OpenSSL and the application is running. - ERR_add_error_data() associates the concatenation of its B<num> string arguments with the error code added last. ERR_add_error_vdata() is similar except the argument is a B<va_list>. @@ -38,6 +48,8 @@ error messages for the error code. =head2 Reporting errors +=for comment TODO(3.0) should this be internal documentation? + Each sub-library has a specific macro XXXerr() that is used to report errors. Its first argument is a function code B<XXX_F_...>, the second argument is a reason code B<XXX_R_...>. Function codes are derived @@ -64,8 +76,12 @@ the ASN1err() macro. =head1 RETURN VALUES -ERR_put_error() and ERR_add_error_data() return -no values. +ERR_raise(), ERR_put_error(), ERR_add_error_data() and +ERR_add_error_vdata() return no values. + +=head1 NOTES + +ERR_raise() and ERR_put_error() are implemented as macros. =head1 SEE ALSO @@ -73,7 +89,7 @@ L<ERR_load_strings(3)> =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/provider-base.pod b/doc/man7/provider-base.pod index e8e5d28560..aa1a3d634b 100644 --- a/doc/man7/provider-base.pod +++ b/doc/man7/provider-base.pod @@ -20,11 +20,12 @@ provider-base int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); int core_thread_start(const OSSL_PROVIDER *prov, OSSL_thread_stop_handler_fn handfn); - void core_put_error(const OSSL_PROVIDER *prov, - uint32_t reason, const char *file, int line); - void core_add_error_vdata(const OSSL_PROVIDER *prov, - int num, va_list args); OPENSSL_CTX *core_get_library_context(const OSSL_PROVIDER *prov); + void core_new_error(const OSSL_PROVIDER *prov); + void core_set_error_debug(const OSSL_PROVIDER *prov, + const char *file, int line, const char *func); + void core_vset_error(const OSSL_PROVIDER *prov, + uint32_t reason, const char *fmt, va_list args); /* * Some OpenSSL functionality is directly offered to providers via @@ -89,9 +90,10 @@ provider): core_get_param_types OSSL_FUNC_CORE_GET_PARAM_TYPES core_get_params OSSL_FUNC_CORE_GET_PARAMS core_thread_start OSSL_FUNC_CORE_THREAD_START - core_put_error OSSL_FUNC_CORE_PUT_ERROR - core_add_error_vdata OSSL_FUNC_CORE_ADD_ERROR_VDATA core_get_library_context OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT + core_new_error OSSL_FUNC_CORE_NEW_ERROR + core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG + core_set_error OSSL_FUNC_CORE_SET_ERROR CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC CRYPTO_zalloc OSSL_FUNC_CRYPTO_ZALLOC CRYPTO_memdup OSSL_FUNC_CRYPTO_MEMDUP @@ -129,25 +131,47 @@ parameters. =for comment core_thread_start() TBA -core_put_error() is used to report an error back to the core, with +core_get_library_context() retrieves the library context in which the +B<OSSL_PROVIDER> object I<prov> is stored. +This may sometimes be useful if the provider wishes to store a +reference to its context in the same library context. + +core_new_error(), core_set_error_debug() and core_set_error() are +building blocks for reporting an error back to the core, with reference to the provider object I<prov>. + +=over 4 + +=item core_new_error() + +allocates a new thread specific error record. + +This corresponds to the OpenSSL function L<ERR_new(3)>. + +=item core_set_error_debug() + +sets debugging information in the current thread specific error +record. +The debugging information includes the name of the file I<file>, the +line I<line> and the function name I<func> where the error occured. + +This corresponds to the OpenSSL function L<ERR_set_debug(3)>. + +=item core_set_error() + +sets the I<reason> for the error, along with any addition data. The I<reason> is a number defined by the provider and used to index the reason strings table that's returned by provider_get_reason_strings(). +The additional data is given as a format string I<fmt> and a set of +arguments I<args>, which are treated in the same manner as with +BIO_vsnprintf(). I<file> and I<line> may also be passed to indicate exactly where the error occured or was reported. -This corresponds to the OpenSSL function L<ERR_put_error(3)>. -core_add_error_vdata() is used to add additional text data to an -error already reported with core_put_error(). -It takes I<num> strings in a B<va_list> and concatenates them. -Provider authors will have to write the corresponding variadic -argument function. +This corresponds to the OpenSSL function L<ERR_vset_error(3)>. -core_get_library_context() retrieves the library context in which the -B<OSSL_PROVIDER> object I<prov> is stored. -This may sometimes be useful if the provider wishes to store a -reference to its context in the same library context. +=back CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_memdup(), CRYPTO_strdup(), CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(), diff --git a/engines/e_afalg_err.c b/engines/e_afalg_err.c index c436f10a41..4db6d660c9 100644 --- a/engines/e_afalg_err.c +++ b/engines/e_afalg_err.c @@ -66,5 +66,6 @@ static void ERR_AFALG_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/engines/e_capi_err.c b/engines/e_capi_err.c index acbec41d08..e2b1f7561f 100644 --- a/engines/e_capi_err.c +++ b/engines/e_capi_err.c @@ -89,5 +89,6 @@ static void ERR_CAPI_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/engines/e_dasync_err.c b/engines/e_dasync_err.c index 0920690af6..a2e6c0dc86 100644 --- a/engines/e_dasync_err.c +++ b/engines/e_dasync_err.c @@ -51,5 +51,6 @@ static void ERR_DASYNC_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/engines/e_ossltest_err.c b/engines/e_ossltest_err.c index b81e00b43c..d9ee80cb83 100644 --- a/engines/e_ossltest_err.c +++ b/engines/e_ossltest_err.c @@ -51,5 +51,6 @@ static void ERR_OSSLTEST_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 3428ab59d9..0bbe92709c 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -66,17 +66,19 @@ OSSL_CORE_MAKE_FUNC(int,core_get_params,(const OSSL_PROVIDER *prov, # define OSSL_FUNC_CORE_THREAD_START 3 OSSL_CORE_MAKE_FUNC(int,core_thread_start,(const OSSL_PROVIDER *prov, OSSL_thread_stop_handler_fn handfn)) -# define OSSL_FUNC_CORE_PUT_ERROR 4 -OSSL_CORE_MAKE_FUNC(void,core_put_error, - (const OSSL_PROVIDER *prov, - uint32_t reason, const char *file, int line)) -# define OSSL_FUNC_CORE_ADD_ERROR_VDATA 5 -OSSL_CORE_MAKE_FUNC(void,core_add_error_vdata,(const OSSL_PROVIDER *prov, - int num, va_list args)) -# define OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT 6 +# define OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT 4 OSSL_CORE_MAKE_FUNC(OPENSSL_CTX *,core_get_library_context, (const OSSL_PROVIDER *prov)) - +# define OSSL_FUNC_CORE_NEW_ERROR 5 +OSSL_CORE_MAKE_FUNC(void,core_new_error,(const OSSL_PROVIDER *prov)) +# define OSSL_FUNC_CORE_SET_ERROR_DEBUG 6 +OSSL_CORE_MAKE_FUNC(void,core_set_error_debug, + (const OSSL_PROVIDER *prov, + const char *file, int line, const char *func)) +# define OSSL_FUNC_CORE_VSET_ERROR 7 +OSSL_CORE_MAKE_FUNC(void,core_vset_error, + (const OSSL_PROVIDER *prov, + uint32_t reason, const char *fmt, va_list args)) /* Memory allocation, freeing, clearing. */ #define OSSL_FUNC_CRYPTO_MALLOC 10 diff --git a/include/openssl/err.h b/include/openssl/err.h index e84bc68a4e..142321d2c8 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -50,6 +50,7 @@ typedef struct err_state_st { int err_data_flags[ERR_NUM_ERRORS]; const char *err_file[ERR_NUM_ERRORS]; int err_line[ERR_NUM_ERRORS]; + const char *err_func[ERR_NUM_ERRORS]; int top, bottom; } ERR_STATE; @@ -107,49 +108,49 @@ typedef struct err_state_st { # define ERR_LIB_USER 128 # if ! OPENSSL_API_3 -# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,0,(r),OPENSSL_FILE,OPENSSL_LINE) -#endif -# define FUNCerr(f,r) ERR_PUT_func_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE) -# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define OSSL_STOREerr(f,r) ERR_PUT_error(ERR_LIB_OSSL_STORE,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define CRMFerr(f,r) ERR_PUT_error(ERR_LIB_CRMF,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define CMPerr(f,r) ERR_PUT_error(ERR_LIB_CMP,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define CTerr(f,r) ERR_PUT_error(ERR_LIB_CT,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define ESSerr(f,r) ERR_PUT_error(ERR_LIB_ESS,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define PROPerr(f,r) ERR_PUT_error(ERR_LIB_PROP,0,(r),OPENSSL_FILE,OPENSSL_LINE) -# define PROVerr(f,r) ERR_PUT_error(ERR_LIB_PROV,0,(r),OPENSSL_FILE,OPENSSL_LINE) +# define SYSerr(f,r) ERR_raise(ERR_LIB_SYS,(r)) +# endif +# define FUNCerr(f,r) ERR_raise_data(ERR_LIB_SYS,(r),"calling function %s",(f)) +# define BNerr(f,r) ERR_raise(ERR_LIB_RSA,(r)) +# define RSAerr(f,r) ERR_raise(ERR_LIB_RSA,(r)) +# define DHerr(f,r) ERR_raise(ERR_LIB_DH,(r)) +# define EVPerr(f,r) ERR_raise(ERR_LIB_EVP,(r)) +# define BUFerr(f,r) ERR_raise(ERR_LIB_BUF,(r)) +# define OBJerr(f,r) ERR_raise(ERR_LIB_OBJ,(r)) +# define PEMerr(f,r) ERR_raise(ERR_LIB_PEM,(r)) +# define DSAerr(f,r) ERR_raise(ERR_LIB_DSA,(r)) +# define X509err(f,r) ERR_raise(ERR_LIB_X509,(r)) +# define ASN1err(f,r) ERR_raise(ERR_LIB_ASN1,(r)) +# define CONFerr(f,r) ERR_raise(ERR_LIB_CONF,(r)) +# define CRYPTOerr(f,r) ERR_raise(ERR_LIB_CRYPTO,(r)) +# define ECerr(f,r) ERR_raise(ERR_LIB_EC,(r)) +# define SSLerr(f,r) ERR_raise(ERR_LIB_SSL,(r)) +# define BIOerr(f,r) ERR_raise(ERR_LIB_BIO,(r)) +# define PKCS7err(f,r) ERR_raise(ERR_LIB_PKCS7,(r)) +# define X509V3err(f,r) ERR_raise(ERR_LIB_X509V3,(r)) +# define PKCS12err(f,r) ERR_raise(ERR_LIB_PKCS12,(r)) +# define RANDerr(f,r) ERR_raise(ERR_LIB_RAND,(r)) +# define DSOerr(f,r) ERR_raise(ERR_LIB_DSO,(r)) +# define ENGINEerr(f,r) ERR_raise(ERR_LIB_ENGINE,(r)) +# define OCSPerr(f,r) ERR_raise(ERR_LIB_OCSP,(r)) +# define UIerr(f,r) ERR_raise(ERR_LIB_UI,(r)) +# define COMPerr(f,r) ERR_raise(ERR_LIB_COMP,(r)) +# define ECDSAerr(f,r) ERR_raise(ERR_LIB_ECDSA,(r)) +# define ECDHerr(f,r) ERR_raise(ERR_LIB_ECDH,(r)) +# define OSSL_STOREerr(f,r) ERR_raise(ERR_LIB_OSSL_STORE,(r)) +# define FIPSerr(f,r) ERR_raise(ERR_LIB_FIPS,(r)) +# define CMSerr(f,r) ERR_raise(ERR_LIB_CMS,(r)) +# define CRMFerr(f,r) ERR_raise(ERR_LIB_CRMF,(r)) +# define CMPerr(f,r) ERR_raise(ERR_LIB_CMP,(r)) +# define TSerr(f,r) ERR_raise(ERR_LIB_TS,(r)) +# define HMACerr(f,r) ERR_raise(ERR_LIB_HMAC,(r)) +# define CTerr(f,r) ERR_raise(ERR_LIB_CT,(r)) +# define ASYNCerr(f,r) ERR_raise(ERR_LIB_ASYNC,(r)) +# define KDFerr(f,r) ERR_raise(ERR_LIB_KDF,(r)) +# define SM2err(f,r) ERR_raise(ERR_LIB_SM2,(r)) +# define ESSerr(f,r) ERR_raise(ERR_LIB_ESS,(r)) +# define PROPerr(f,r) ERR_raise(ERR_LIB_PROP,(r)) +# define PROVerr(f,r) ERR_raise(ERR_LIB_PROV,(r)) # define ERR_PACK(l,f,r) ( \ (((unsigned int)(l) & 0x0FF) << 24L) | \ @@ -235,9 +236,30 @@ typedef struct ERR_string_data_st { DEFINE_LHASH_OF(ERR_STRING_DATA); -void ERR_put_error(int lib, int func, int reason, const char *file, int line); -void ERR_put_func_error(int lib, const char *func, int reason, - const char *file, int line); +/* 12 lines and some on an 80 column terminal */ +#define ERR_MAX_DATA_SIZE 1024 + +/* Building blocks */ +void ERR_new(void); +void ERR_set_debug(const char *file, int line, const char *func); +void ERR_set_error(int lib, int reason, const char *fmt, ...); +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args); + +/* Main error raising functions */ +#define ERR_raise(lib, reason) ERR_raise_data((lib),(reason),NULL) +#define ERR_raise_data \ + (ERR_new(), \ + ERR_set_debug(OPENSSL_FILE,OPENSSL_LINE,OPENSSL_FUNC), \ + ERR_set_error) + +#if !OPENSSL_API_3 +/* Backward compatibility */ +#define ERR_put_error(lib, func, reason, file, line) \ + (ERR_new(), \ + ERR_set_debug((file), (line), NULL), \ + ERR_set_error((lib), (reason), NULL)) +#endif + void ERR_set_error_data(char *data, int flags); unsigned long ERR_get_error(void); diff --git a/include/openssl/opensslconf.h.in b/include/openssl/macros.h similarity index 70% copy from include/openssl/opensslconf.h.in copy to include/openssl/macros.h index b0d339ac9a..6b735b6b0b 100644 --- a/include/openssl/opensslconf.h.in +++ b/include/openssl/macros.h @@ -1,7 +1,5 @@ /* - * {- join("\n * ", @autowarntext) -} - * - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,43 +7,8 @@ * https://www.openssl.org/source/license.html */ -#include <openssl/opensslv.h> - -#ifndef HEADER_OPENSSLCONF_H -# define HEADER_OPENSSLCONF_H - -# ifdef __cplusplus -extern "C" { -# endif - -# ifdef OPENSSL_ALGORITHM_DEFINES -# error OPENSSL_ALGORITHM_DEFINES no longer supported -# endif - -/* - * OpenSSL was configured with the following options: - */ - -{- if (@{$config{openssl_sys_defines}}) { - foreach (@{$config{openssl_sys_defines}}) { - $OUT .= "# ifndef $_\n"; - $OUT .= "# define $_ 1\n"; - $OUT .= "# endif\n"; - } - } - foreach (@{$config{openssl_api_defines}}) { - (my $macro, my $value) = $_ =~ /^(.*?)=(.*?)$/; - $OUT .= "# define $macro $value\n"; - } - if (@{$config{openssl_feature_defines}}) { - foreach (@{$config{openssl_feature_defines}}) { - $OUT .= "# ifndef $_\n"; - $OUT .= "# define $_\n"; - $OUT .= "# endif\n"; - } - } - ""; --} +#ifndef OPENSSL_MACROS_H +# define OPENSSL_MACROS_H /* * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers @@ -162,23 +125,18 @@ extern "C" { # endif # endif -/* Generate 80386 code? */ -{- $config{processor} eq "386" ? "# define" : "# undef" -} I386_ONLY - -/* - * The following are cipher-specific, but are part of the public API. - */ -# if !defined(OPENSSL_SYS_UEFI) -{- $config{bn_ll} ? "# define" : "# undef" -} BN_LLONG -/* Only one for the following should be defined */ -{- $config{b64l} ? "# define" : "# undef" -} SIXTY_FOUR_BIT_LONG -{- $config{b64} ? "# define" : "# undef" -} SIXTY_FOUR_BIT -{- $config{b32} ? "# define" : "# undef" -} THIRTY_TWO_BIT +# ifndef OPENSSL_FUNC +# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +# define OPENSSL_FUNC __func__ +# elif defined(__STDC__) && defined(PEDANTIC) +# define OPENSSL_FUNC "(PEDANTIC disallows function name)" +# elif defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ >= 2) +# define OPENSSL_FUNC __FUNCTION__ +# elif defined(__FUNCSIG__) +# define OPENSSL_FUNC __FUNCSIG__ +# else +# define OPENSSL_FUNC "(unknown function)" +# endif # endif -# define RC4_INT {- $config{rc4_int} -} - -# ifdef __cplusplus -} -# endif -#endif /* HEADER_OPENSSLCONF_H */ +#endif /* OPENSSL_MACROS_H */ diff --git a/include/openssl/opensslconf.h.in b/include/openssl/opensslconf.h.in index b0d339ac9a..5673b5b963 100644 --- a/include/openssl/opensslconf.h.in +++ b/include/openssl/opensslconf.h.in @@ -47,121 +47,6 @@ extern "C" { ""; -} -/* - * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers - * don't like that. This will hopefully silence them. - */ -# define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy; - -/* - * Applications should use -DOPENSSL_API_COMPAT=<version> to suppress the - * declarations of functions deprecated in or before <version>. If this is - * undefined, the value of the macro OPENSSL_API_MIN above is the default. - * - * For any version number up until version 1.1.x, <version> is expected to be - * the calculated version number 0xMNNFFPPSL. For version numbers 3.0.0 and - * on, <version> is expected to be only the major version number (i.e. 3 for - * version 3.0.0). - */ -# ifndef DECLARE_DEPRECATED -# define DECLARE_DEPRECATED(f) f; -# ifdef __GNUC__ -# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) -# undef DECLARE_DEPRECATED -# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated)); -# endif -# endif -# endif - -/* - * We convert the OPENSSL_API_COMPAT value to an API level. The API level - * is the major version number for 3.0.0 and on. For earlier versions, it - * uses this scheme, which is close enough for our purposes: - * - * 0.x.y 0 (0.9.8 was the last release in this series) - * 1.0.x 1 (1.0.2 was the last release in this series) - * 1.1.x 2 (1.1.1 was the last release in this series) - */ - -/* In case someone defined both */ -# if defined(OPENSSL_API_COMPAT) && defined(OPENSSL_API_LEVEL) -# error "Disallowed to define both OPENSSL_API_COMPAT and OPENSSL_API_LEVEL" -# endif - -# ifndef OPENSSL_API_COMPAT -# define OPENSSL_API_LEVEL OPENSSL_MIN_API -# else -# if (OPENSSL_API_COMPAT < 0x1000L) /* Major version numbers up to 16777215 */ -# define OPENSSL_API_LEVEL OPENSSL_API_COMPAT -# elif (OPENSSL_API_COMPAT & 0xF0000000L) == 0x00000000L -# define OPENSSL_API_LEVEL 0 -# elif (OPENSSL_API_COMPAT & 0xFFF00000L) == 0x10000000L -# define OPENSSL_API_LEVEL 1 -# elif (OPENSSL_API_COMPAT & 0xFFF00000L) == 0x10100000L -# define OPENSSL_API_LEVEL 2 -# else - /* Major number 3 to 15 */ -# define OPENSSL_API_LEVEL ((OPENSSL_API_COMPAT >> 28) & 0xF) -# endif -# endif - -/* - * Do not deprecate things to be deprecated in version 4.0 before the - * OpenSSL version number matches. - */ -# if OPENSSL_VERSION_MAJOR < 4 -# define DEPRECATEDIN_4(f) f; -# define OPENSSL_API_4 0 -# elif OPENSSL_API_LEVEL < 4 -# define DEPRECATEDIN_4(f) DECLARE_DEPRECATED(f) -# define OPENSSL_API_4 0 -# else -# define DEPRECATEDIN_4(f) -# define OPENSSL_API_4 1 -# endif - -# if OPENSSL_API_LEVEL < 3 -# define DEPRECATEDIN_3(f) DECLARE_DEPRECATED(f) -# define OPENSSL_API_3 0 -# else -# define DEPRECATEDIN_3(f) -# define OPENSSL_API_3 1 -# endif - -# if OPENSSL_API_LEVEL < 2 -# define DEPRECATEDIN_1_1_0(f) DECLARE_DEPRECATED(f) -# define OPENSSL_API_1_1_0 0 -# else -# define DEPRECATEDIN_1_1_0(f) -# define OPENSSL_API_1_1_0 1 -# endif - -# if OPENSSL_API_LEVEL < 1 -# define DEPRECATEDIN_1_0_0(f) DECLARE_DEPRECATED(f) -# define OPENSSL_API_1_0_0 0 -# else -# define DEPRECATEDIN_1_0_0(f) -# define OPENSSL_API_1_0_0 1 -# endif - -# if OPENSSL_API_LEVEL < 0 -# define DEPRECATEDIN_0_9_8(f) DECLARE_DEPRECATED(f) -# define OPENSSL_API_0_9_8 0 -# else -# define DEPRECATEDIN_0_9_8(f) -# define OPENSSL_API_0_9_8 1 -# endif - -# ifndef OPENSSL_FILE -# ifdef OPENSSL_NO_FILENAMES -# define OPENSSL_FILE "" -# define OPENSSL_LINE 0 -# else -# define OPENSSL_FILE __FILE__ -# define OPENSSL_LINE __LINE__ -# endif -# endif - /* Generate 80386 code? */ {- $config{processor} eq "386" ? "# define" : "# undef" -} I386_ONLY @@ -178,6 +63,8 @@ extern "C" { # define RC4_INT {- $config{rc4_int} -} +#include <openssl/macros.h> + # ifdef __cplusplus } # endif diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 4c010c895e..b62bfeec39 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -39,8 +39,9 @@ extern OSSL_core_thread_start_fn *c_thread_start; static OSSL_core_get_param_types_fn *c_get_param_types; static OSSL_core_get_params_fn *c_get_params; OSSL_core_thread_start_fn *c_thread_start; -static OSSL_core_put_error_fn *c_put_error; -static OSSL_core_add_error_vdata_fn *c_add_error_vdata; +static OSSL_core_new_error_fn *c_new_error; +static OSSL_core_set_error_debug_fn *c_set_error_debug; +static OSSL_core_vset_error_fn *c_vset_error; static OSSL_CRYPTO_malloc_fn *c_CRYPTO_malloc; static OSSL_CRYPTO_zalloc_fn *c_CRYPTO_zalloc; static OSSL_CRYPTO_free_fn *c_CRYPTO_free; @@ -305,11 +306,14 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider, case OSSL_FUNC_CORE_THREAD_START: c_thread_start = OSSL_get_core_thread_start(in); break; - case OSSL_FUNC_CORE_PUT_ERROR: - c_put_error = OSSL_get_core_put_error(in); + case OSSL_FUNC_CORE_NEW_ERROR: + c_new_error = OSSL_get_core_new_error(in); break; - case OSSL_FUNC_CORE_ADD_ERROR_VDATA: - c_add_error_vdata = OSSL_get_core_add_error_vdata(in); + case OSSL_FUNC_CORE_SET_ERROR_DEBUG: + c_set_error_debug = OSSL_get_core_set_error_debug(in); + break; + case OSSL_FUNC_CORE_VSET_ERROR: + c_vset_error = OSSL_get_core_vset_error(in); break; case OSSL_FUNC_CRYPTO_MALLOC: c_CRYPTO_malloc = OSSL_get_CRYPTO_malloc(in); @@ -416,29 +420,28 @@ int fips_intern_provider_init(const OSSL_PROVIDER *provider, return 1; } -void ERR_put_error(int lib, int func, int reason, const char *file, int line) +void ERR_new(void) { - /* - * TODO(3.0) the first argument is currently NULL but is expected to - * be passed something else in the future, either an OSSL_PROVIDER or - * a OPENSSL_CTX pointer. - */ - c_put_error(NULL, ERR_PACK(lib, func, reason), file, line); - ERR_add_error_data(1, "(in the FIPS module)"); + c_new_error(NULL); +} + +void ERR_set_debug(const char *file, int line, const char *func) +{ + c_set_error_debug(NULL, file, line, func); } -void ERR_add_error_data(int num, ...) +void ERR_set_error(int lib, int reason, const char *fmt, ...) { va_list args; - va_start(args, num); - ERR_add_error_vdata(num, args); + va_start(args, fmt); + c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args); va_end(args); } -void ERR_add_error_vdata(int num, va_list args) +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) { - c_add_error_vdata(NULL, num, args); + c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args); } const OSSL_PROVIDER *FIPS_get_provider(OPENSSL_CTX *ctx) diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index a35573c935..bd9277b71e 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -118,7 +118,8 @@ void ossl_statem_set_renegotiate(SSL *s) void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file, int line) { - ERR_put_error(ERR_LIB_SSL, func, reason, file, line); + ERR_raise(ERR_LIB_SSL, reason); + ERR_set_debug(file, line, NULL); /* Override what ERR_raise set */ /* We shouldn't call SSLfatal() twice. Once is enough */ if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR) return; diff --git a/test/errtest.c b/test/errtest.c index 88ff860092..1a18335b6e 100644 --- a/test/errtest.c +++ b/test/errtest.c @@ -47,12 +47,14 @@ static int vdata_appends(void) /* Test that setting a platform error sets the right values. */ static int platform_error(void) { - const char *file = __FILE__, *f, *data; - const int line = __LINE__; + const char *file, *f, *data; + int line; int l; unsigned long e; - ERR_put_func_error(ERR_LIB_SYS, "exit", ERR_R_INTERNAL_ERROR, file, line); + file = __FILE__; + line = __LINE__ + 1; /* The error is generated on the next line */ + FUNCerr("exit", ERR_R_INTERNAL_ERROR); if (!TEST_ulong_ne(e = ERR_get_error_line_data(&f, &l, &data, NULL), 0) || !TEST_int_eq(ERR_GET_REASON(e), ERR_R_INTERNAL_ERROR) || !TEST_int_eq(l, line) diff --git a/util/libcrypto.num b/util/libcrypto.num index 81462480ca..a6c5097e1c 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -998,7 +998,7 @@ OPENSSL_LH_get_down_load 1023 3_0_0 EXIST::FUNCTION: EVP_md4 1024 3_0_0 EXIST::FUNCTION:MD4 X509_set_subject_name 1025 3_0_0 EXIST::FUNCTION: i2d_PKCS8PrivateKey_nid_bio 1026 3_0_0 EXIST::FUNCTION: -ERR_put_error 1027 3_0_0 EXIST::FUNCTION: +ERR_put_error 1027 3_0_0 NOEXIST::FUNCTION: ERR_add_error_data 1028 3_0_0 EXIST::FUNCTION: X509_ALGORS_it 1029 3_0_0 EXIST::FUNCTION: MD5_Update 1030 3_0_0 EXIST::FUNCTION:MD5 @@ -4690,7 +4690,7 @@ EVP_KEYMGMT_up_ref 4795 3_0_0 EXIST::FUNCTION: EVP_KEYMGMT_free 4796 3_0_0 EXIST::FUNCTION: EVP_KEYMGMT_provider 4797 3_0_0 EXIST::FUNCTION: X509_PUBKEY_dup 4798 3_0_0 EXIST::FUNCTION: -ERR_put_func_error 4799 3_0_0 EXIST::FUNCTION: +ERR_put_func_error 4799 3_0_0 NOEXIST::FUNCTION: EVP_MD_name 4800 3_0_0 EXIST::FUNCTION: EVP_CIPHER_name 4801 3_0_0 EXIST::FUNCTION: EVP_MD_provider 4802 3_0_0 EXIST::FUNCTION: @@ -4700,3 +4700,7 @@ EVP_CIPHER_do_all_ex 4805 3_0_0 EXIST::FUNCTION: EVP_MD_do_all_ex 4806 3_0_0 EXIST::FUNCTION: EVP_KEYEXCH_provider 4807 3_0_0 EXIST::FUNCTION: OSSL_PROVIDER_available 4808 3_0_0 EXIST::FUNCTION: +ERR_new 4809 3_0_0 EXIST::FUNCTION: +ERR_set_debug 4810 3_0_0 EXIST::FUNCTION: +ERR_set_error 4811 3_0_0 EXIST::FUNCTION: +ERR_vset_error 4812 3_0_0 EXIST::FUNCTION: diff --git a/util/mkerr.pl b/util/mkerr.pl index 956b66179a..51e034703d 100755 --- a/util/mkerr.pl +++ b/util/mkerr.pl @@ -650,7 +650,8 @@ ${st}void ERR_${lib}_error(int function, int reason, char *file, int line) { if (lib_code == 0) lib_code = ERR_get_next_error_library(); - ERR_PUT_error(lib_code, function, reason, file, line); + ERR_raise(lib_code, reason); + ERR_set_debug(file, line, NULL); } EOF diff --git a/util/private.num b/util/private.num index 1e76dfb43c..82cb72e606 100644 --- a/util/private.num +++ b/util/private.num @@ -195,7 +195,10 @@ ERR_GET_LIB define ERR_GET_REASON define ERR_PACK define ERR_free_strings define deprecated 1.1.0 +ERR_put_error define deprecated 3.0 ERR_load_crypto_strings define deprecated 1.1.0 +ERR_raise define +ERR_raise_data define EVP_DigestSignUpdate define EVP_DigestVerifyUpdate define EVP_KDF_name define