{ERR_PACK(ERR_LIB_UI, 0, 0), "UI routines"},
{ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"},
{ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"},
+ {ERR_PACK(ERR_LIB_CRMF, 0, 0), "CRMF routines"},
+ {ERR_PACK(ERR_LIB_CMP, 0, 0), "CMP routines"},
{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_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"},
{0, NULL},
};
}
#ifndef OPENSSL_NO_ERR
-/* A measurement on Linux 2018-11-21 showed about 3.5kib */
-# define SPACE_SYS_STR_REASONS 4 * 1024
+/* 2019-05-21: Russian and Ukrainian locales on Linux require more than 6,5 kB */
+# define SPACE_SYS_STR_REASONS 8 * 1024
# define NUM_SYS_STR_REASONS 127
static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
str->error = ERR_PACK(ERR_LIB_SYS, 0, i);
- if (str->string == NULL) {
+ /*
+ * If we have used up all the space in strerror_pool,
+ * there's no point in calling openssl_strerror_r()
+ */
+ if (str->string == NULL && cnt < sizeof(strerror_pool)) {
if (openssl_strerror_r(i, cur, sizeof(strerror_pool) - cnt)) {
size_t l = strlen(cur);
str->string = cur;
cnt += l;
- if (cnt > sizeof(strerror_pool))
- cnt = sizeof(strerror_pool);
cur += l;
/*
* VMS has an unusual quirk of adding spaces at the end of
- * some (most? all?) messages. Lets trim them off.
+ * some (most? all?) messages. Lets trim them off.
*/
- while (ossl_isspace(cur[-1])) {
+ while (cur > strerror_pool && ossl_isspace(cur[-1])) {
cur--;
cnt--;
}
return ERR_R_INTERNAL_ERROR;
}
+ while (es->bottom != es->top) {
+ if (es->err_flags[es->top] & ERR_FLAG_CLEAR) {
+ err_clear(es, es->top);
+ es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1;
+ continue;
+ }
+ i = (es->bottom + 1) % ERR_NUM_ERRORS;
+ if (es->err_flags[i] & ERR_FLAG_CLEAR) {
+ es->bottom = i;
+ err_clear(es, es->bottom);
+ continue;
+ }
+ break;
+ }
+
if (es->bottom == es->top)
return 0;
+
if (top)
i = es->top; /* last error */
else
return ((p == NULL) ? NULL : p->string);
}
-void err_delete_thread_state(void)
+/* TODO(3.0): arg ignored for now */
+static void err_delete_thread_state(void *arg)
{
ERR_STATE *state = CRYPTO_THREAD_get_local(&err_thread_local);
if (state == NULL)
return NULL;
}
- if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE)
+ if (!ossl_init_thread_start(NULL, err_delete_thread_state)
|| !CRYPTO_THREAD_set_local(&err_thread_local, state)) {
ERR_STATE_free(state);
CRYPTO_THREAD_set_local(&err_thread_local, NULL);
return 1;
}
-#ifdef UINTPTR_T
-# undef UINTPTR_T
-#endif
-/*
- * uintptr_t is the answer, but unfortunately C89, current "least common
- * denominator" doesn't define it. Most legacy platforms typedef it anyway,
- * so that attempt to fill the gaps means that one would have to identify
- * that track these gaps, which would be undesirable. Macro it is...
- */
-#if defined(__VMS) && __INITIAL_POINTER_SIZE==64
-/*
- * But we can't use size_t on VMS, because it adheres to sizeof(size_t)==4
- * even in 64-bit builds, which means that it won't work as mask.
- */
-# define UINTPTR_T unsigned long long
-#else
-# define UINTPTR_T size_t
-#endif
-
void err_clear_last_constant_time(int clear)
{
ERR_STATE *es;
top = es->top;
- es->err_flags[top] &= ~(0 - clear);
- es->err_buffer[top] &= ~(0UL - clear);
- es->err_file[top] = (const char *)((UINTPTR_T)es->err_file[top] &
- ~((UINTPTR_T)0 - clear));
- es->err_line[top] |= 0 - clear;
-
- es->top = (top + ERR_NUM_ERRORS - clear) % ERR_NUM_ERRORS;
+ /*
+ * Flag error as cleared but remove it elsewhere to avoid two errors
+ * accessing the same error stack location, revealing timing information.
+ */
+ clear = constant_time_select_int(constant_time_eq_int(clear, 0),
+ 0, ERR_FLAG_CLEAR);
+ es->err_flags[top] |= clear;
}