/*
- * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2020 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
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
-#include "internal/cryptlib_int.h"
+#include "crypto/cryptlib.h"
#include "internal/err.h"
-#include "internal/err_int.h"
+#include "crypto/err.h"
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
#include <openssl/bio.h>
#include <openssl/opensslconf.h>
#include "internal/thread_once.h"
-#include "internal/ctype.h"
-#include "internal/constant_time_locl.h"
+#include "crypto/ctype.h"
+#include "internal/constant_time.h"
#include "e_os.h"
-#include "err_locl.h"
+#include "err_local.h"
/* Forward declaration in case it's not published because of configuration */
ERR_STATE *ERR_get_state(void);
{ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"},
{ERR_PACK(ERR_LIB_CT, 0, 0), "CT routines"},
{ERR_PACK(ERR_LIB_ASYNC, 0, 0), "ASYNC routines"},
+ {ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, 0), "STORE routines"},
{ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"},
{ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"},
{ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"},
+ {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"},
+ {ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"},
{0, NULL},
};
{ERR_R_DISABLED, "called a function that was disabled at compile-time"},
{ERR_R_INIT_FAIL, "init fail"},
{ERR_R_OPERATION_FAIL, "operation fail"},
+ {ERR_R_INVALID_PROVIDER_FUNCTIONS, "invalid provider functions"},
+ {ERR_R_INTERRUPTED_OR_CANCELLED, "interrupted or cancelled"},
{0, NULL},
};
static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
static int int_err_library_number = ERR_LIB_USER;
-static unsigned long get_error_values(int inc, int top, const char **file,
- int *line, const char **func,
- const char **data, int *flags);
+typedef enum ERR_GET_ACTION_e {
+ EV_POP, EV_PEEK, EV_PEEK_LAST
+} ERR_GET_ACTION;
+
+static unsigned long get_error_values(ERR_GET_ACTION g,
+ const char **file, int *line,
+ const char **func, const char **data,
+ int *flags);
static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
{
int i;
ERR_STATE *es;
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return;
unsigned long ERR_get_error(void)
{
- return get_error_values(1, 0, NULL, NULL, NULL, NULL, NULL);
+ return get_error_values(EV_POP, NULL, NULL, NULL, NULL, NULL);
}
unsigned long ERR_get_error_line(const char **file, int *line)
{
- return get_error_values(1, 0, file, line, NULL, NULL, NULL);
+ return get_error_values(EV_POP, file, line, NULL, NULL, NULL);
}
unsigned long ERR_get_error_func(const char **func)
{
- return get_error_values(1, 0, NULL, NULL, func, NULL, NULL);
+ return get_error_values(EV_POP, NULL, NULL, func, NULL, NULL);
}
unsigned long ERR_get_error_data(const char **data, int *flags)
{
- return get_error_values(1, 0, NULL, NULL, NULL, data, flags);
+ return get_error_values(EV_POP, NULL, NULL, NULL, data, flags);
}
unsigned long ERR_get_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags)
{
- return get_error_values(1, 0, file, line, func, data, flags);
+ return get_error_values(EV_POP, file, line, func, data, flags);
}
-#if !OPENSSL_API_3
+#ifndef OPENSSL_NO_DEPRECATED_3_0
unsigned long ERR_get_error_line_data(const char **file, int *line,
const char **data, int *flags)
{
- return get_error_values(1, 0, file, line, NULL, data, flags);
+ return get_error_values(EV_POP, file, line, NULL, data, flags);
}
#endif
unsigned long ERR_peek_error(void)
{
- return get_error_values(0, 0, NULL, NULL, NULL, NULL, NULL);
+ return get_error_values(EV_PEEK, NULL, NULL, NULL, NULL, NULL);
}
unsigned long ERR_peek_error_line(const char **file, int *line)
{
- return get_error_values(0, 0, file, line, NULL, NULL, NULL);
+ return get_error_values(EV_PEEK, file, line, NULL, NULL, NULL);
}
unsigned long ERR_peek_error_func(const char **func)
{
- return get_error_values(0, 0, NULL, NULL, func, NULL, NULL);
+ return get_error_values(EV_PEEK, NULL, NULL, func, NULL, NULL);
}
unsigned long ERR_peek_error_data(const char **data, int *flags)
{
- return get_error_values(0, 0, NULL, NULL, NULL, data, flags);
+ return get_error_values(EV_PEEK, NULL, NULL, NULL, data, flags);
}
unsigned long ERR_peek_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags)
{
- return get_error_values(0, 0, file, line, func, data, flags);
+ return get_error_values(EV_PEEK, file, line, func, data, flags);
}
-#if !OPENSSL_API_3
+#ifndef OPENSSL_NO_DEPRECATED_3_0
unsigned long ERR_peek_error_line_data(const char **file, int *line,
const char **data, int *flags)
{
- return get_error_values(0, 0, file, line, NULL, data, flags);
+ return get_error_values(EV_PEEK, file, line, NULL, data, flags);
}
#endif
unsigned long ERR_peek_last_error(void)
{
- return get_error_values(0, 1, NULL, NULL, NULL, NULL, NULL);
+ return get_error_values(EV_PEEK_LAST, NULL, NULL, NULL, NULL, NULL);
}
unsigned long ERR_peek_last_error_line(const char **file, int *line)
{
- return get_error_values(0, 1, file, line, NULL, NULL, NULL);
+ return get_error_values(EV_PEEK_LAST, file, line, NULL, NULL, NULL);
}
unsigned long ERR_peek_last_error_func(const char **func)
{
- return get_error_values(0, 1, NULL, NULL, func, NULL, NULL);
+ return get_error_values(EV_PEEK_LAST, NULL, NULL, func, NULL, NULL);
}
unsigned long ERR_peek_last_error_data(const char **data, int *flags)
{
- return get_error_values(0, 1, NULL, NULL, NULL, data, flags);
+ return get_error_values(EV_PEEK_LAST, NULL, NULL, NULL, data, flags);
}
unsigned long ERR_peek_last_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags)
{
- return get_error_values(0, 1, file, line, func, data, flags);
+ return get_error_values(EV_PEEK_LAST, file, line, func, data, flags);
}
-#if !OPENSSL_API_3
+#ifndef OPENSSL_NO_DEPRECATED_3_0
unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
const char **data, int *flags)
{
- return get_error_values(0, 1, file, line, NULL, data, flags);
+ return get_error_values(EV_PEEK_LAST, file, line, NULL, data, flags);
}
#endif
-static unsigned long get_error_values(int inc, int top, const char **file,
- int *line, const char **func,
+static unsigned long get_error_values(ERR_GET_ACTION g,
+ const char **file, int *line,
+ const char **func,
const char **data, int *flags)
{
int i = 0;
ERR_STATE *es;
unsigned long ret;
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return 0;
- if (inc && top) {
- if (file != NULL)
- *file = "";
- if (line != NULL)
- *line = 0;
- if (func != NULL)
- *func = "";
- if (data != NULL)
- *data = "";
- if (flags != NULL)
- *flags = 0;
-
- return ERR_R_INTERNAL_ERROR;
- }
-
+ /*
+ * Clear anything that should have been cleared earlier. We do this
+ * here because this doesn't have constant-time issues.
+ */
while (es->bottom != es->top) {
if (es->err_flags[es->top] & ERR_FLAG_CLEAR) {
err_clear(es, es->top, 0);
break;
}
+ /* If everything has been cleared, the stack is empty. */
if (es->bottom == es->top)
return 0;
- if (top)
- i = es->top; /* last error */
+ /* Which error, the top of stack (latest one) or the first one? */
+ if (g == EV_PEEK_LAST)
+ i = es->top;
else
- i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */
+ i = (es->bottom + 1) % ERR_NUM_ERRORS;
ret = es->err_buffer[i];
- if (inc) {
+ if (g == EV_POP) {
es->bottom = i;
es->err_buffer[i] = 0;
}
- if (file != NULL && line != NULL) {
- if (es->err_file[i] == NULL) {
- *file = "NA";
- *line = 0;
- } else {
- *file = es->err_file[i];
- *line = es->err_line[i];
- }
+ if (file != NULL) {
+ *file = es->err_file[i];
+ if (*file == NULL)
+ *file = "";
}
-
+ if (line != NULL)
+ *line = es->err_line[i];
if (func != NULL) {
*func = es->err_func[i];
if (*func == NULL)
- *func = "N/A";
+ *func = "";
}
-
+ if (flags != NULL)
+ *flags = es->err_data_flags[i];
if (data == NULL) {
- if (inc) {
+ if (g == EV_POP) {
err_clear_data(es, i, 0);
}
} else {
- if (es->err_data[i] == NULL) {
+ *data = es->err_data[i];
+ if (*data == NULL) {
*data = "";
if (flags != NULL)
*flags = 0;
- } else {
- *data = es->err_data[i];
- if (flags != NULL)
- *flags = es->err_data_flags[i];
}
}
return ret;
return ((p == NULL) ? NULL : p->string);
}
-#if !OPENSSL_API_3
+#ifndef OPENSSL_NO_DEPRECATED_3_0
const char *ERR_func_error_string(unsigned long e)
{
return NULL;
r = ERR_GET_REASON(e);
d.error = ERR_PACK(l, 0, r);
p = int_err_get_item(&d);
- if (!p) {
+ if (p == NULL) {
d.error = ERR_PACK(0, 0, r);
p = int_err_get_item(&d);
}
ERR_STATE_free(state);
}
-#if !OPENSSL_API_1_1_0
+#ifndef OPENSSL_NO_DEPRECATED_1_1_0
void ERR_remove_thread_state(void *dummy)
{
}
#endif
-#if !OPENSSL_API_1_0_0
+#ifndef OPENSSL_NO_DEPRECATED_1_0_0
void ERR_remove_state(unsigned long pid)
{
}
return CRYPTO_THREAD_init_local(&err_thread_local, NULL);
}
-ERR_STATE *ERR_get_state(void)
+ERR_STATE *err_get_state_int(void)
{
ERR_STATE *state;
int saveerrno = get_last_sys_error();
return state;
}
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+ERR_STATE *ERR_get_state(void)
+{
+ return err_get_state_int();
+}
+#endif
+
+
/*
* err_shelve_state returns the current thread local error state
* and freezes the error module until err_unshelve_state is called.
{
ERR_STATE *es;
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return 0;
ERR_STATE *es;
/* Get the current error data; if an allocated string get it. */
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return;
i = es->top;
{
ERR_STATE *es;
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return 0;
{
ERR_STATE *es;
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return 0;
ERR_STATE *es;
int top;
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return 0;
ERR_STATE *es;
int top;
- es = ERR_get_state();
+ es = err_get_state_int();
if (es == NULL)
return;