err.c 20.5 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (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
8
 */
9 10

#include <stdio.h>
U
Ulf Möller 已提交
11
#include <stdarg.h>
12
#include <string.h>
M
Matt Caswell 已提交
13
#include <internal/cryptlib_int.h>
14
#include <internal/err.h>
15
#include <internal/err_int.h>
16 17 18
#include <openssl/lhash.h>
#include <openssl/crypto.h>
#include <openssl/buffer.h>
B
Bodo Möller 已提交
19
#include <openssl/bio.h>
20
#include <openssl/opensslconf.h>
21
#include <internal/thread_once.h>
B
Ben Laurie 已提交
22

23 24
static void err_load_strings(int lib, ERR_STRING_DATA *str);

25
static void ERR_STATE_free(ERR_STATE *s);
26
#ifndef OPENSSL_NO_ERR
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
static ERR_STRING_DATA ERR_str_libraries[] = {
    {ERR_PACK(ERR_LIB_NONE, 0, 0), "unknown library"},
    {ERR_PACK(ERR_LIB_SYS, 0, 0), "system library"},
    {ERR_PACK(ERR_LIB_BN, 0, 0), "bignum routines"},
    {ERR_PACK(ERR_LIB_RSA, 0, 0), "rsa routines"},
    {ERR_PACK(ERR_LIB_DH, 0, 0), "Diffie-Hellman routines"},
    {ERR_PACK(ERR_LIB_EVP, 0, 0), "digital envelope routines"},
    {ERR_PACK(ERR_LIB_BUF, 0, 0), "memory buffer routines"},
    {ERR_PACK(ERR_LIB_OBJ, 0, 0), "object identifier routines"},
    {ERR_PACK(ERR_LIB_PEM, 0, 0), "PEM routines"},
    {ERR_PACK(ERR_LIB_DSA, 0, 0), "dsa routines"},
    {ERR_PACK(ERR_LIB_X509, 0, 0), "x509 certificate routines"},
    {ERR_PACK(ERR_LIB_ASN1, 0, 0), "asn1 encoding routines"},
    {ERR_PACK(ERR_LIB_CONF, 0, 0), "configuration file routines"},
    {ERR_PACK(ERR_LIB_CRYPTO, 0, 0), "common libcrypto routines"},
    {ERR_PACK(ERR_LIB_EC, 0, 0), "elliptic curve routines"},
    {ERR_PACK(ERR_LIB_ECDSA, 0, 0), "ECDSA routines"},
    {ERR_PACK(ERR_LIB_ECDH, 0, 0), "ECDH routines"},
    {ERR_PACK(ERR_LIB_SSL, 0, 0), "SSL routines"},
    {ERR_PACK(ERR_LIB_BIO, 0, 0), "BIO routines"},
    {ERR_PACK(ERR_LIB_PKCS7, 0, 0), "PKCS7 routines"},
    {ERR_PACK(ERR_LIB_X509V3, 0, 0), "X509 V3 routines"},
    {ERR_PACK(ERR_LIB_PKCS12, 0, 0), "PKCS12 routines"},
    {ERR_PACK(ERR_LIB_RAND, 0, 0), "random number generator"},
    {ERR_PACK(ERR_LIB_DSO, 0, 0), "DSO support routines"},
    {ERR_PACK(ERR_LIB_TS, 0, 0), "time stamp routines"},
    {ERR_PACK(ERR_LIB_ENGINE, 0, 0), "engine routines"},
    {ERR_PACK(ERR_LIB_OCSP, 0, 0), "OCSP routines"},
55
    {ERR_PACK(ERR_LIB_UI, 0, 0), "UI routines"},
56 57 58
    {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"},
    {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"},
    {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"},
59
    {ERR_PACK(ERR_LIB_CT, 0, 0), "CT routines"},
M
Matt Caswell 已提交
60
    {ERR_PACK(ERR_LIB_ASYNC, 0, 0), "ASYNC routines"},
D
Dr. Stephen Henson 已提交
61
    {ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"},
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
    {0, NULL},
};

static ERR_STRING_DATA ERR_str_functs[] = {
    {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"},
    {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"},
    {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"},
    {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"},
    {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"},
    {ERR_PACK(0, SYS_F_BIND, 0), "bind"},
    {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"},
    {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"},
# ifdef OPENSSL_SYS_WINDOWS
    {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"},
# endif
    {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"},
    {ERR_PACK(0, SYS_F_FREAD, 0), "fread"},
79 80
    {ERR_PACK(0, SYS_F_GETADDRINFO, 0), "getaddrinfo"},
    {ERR_PACK(0, SYS_F_GETNAMEINFO, 0), "getnameinfo"},
81 82 83
    {ERR_PACK(0, SYS_F_SETSOCKOPT, 0), "setsockopt"},
    {ERR_PACK(0, SYS_F_GETSOCKOPT, 0), "getsockopt"},
    {ERR_PACK(0, SYS_F_GETSOCKNAME, 0), "getsockname"},
K
Kurt Roeckx 已提交
84
    {ERR_PACK(0, SYS_F_GETHOSTBYNAME, 0), "gethostbyname"},
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    {0, NULL},
};

static ERR_STRING_DATA ERR_str_reasons[] = {
    {ERR_R_SYS_LIB, "system lib"},
    {ERR_R_BN_LIB, "BN lib"},
    {ERR_R_RSA_LIB, "RSA lib"},
    {ERR_R_DH_LIB, "DH lib"},
    {ERR_R_EVP_LIB, "EVP lib"},
    {ERR_R_BUF_LIB, "BUF lib"},
    {ERR_R_OBJ_LIB, "OBJ lib"},
    {ERR_R_PEM_LIB, "PEM lib"},
    {ERR_R_DSA_LIB, "DSA lib"},
    {ERR_R_X509_LIB, "X509 lib"},
    {ERR_R_ASN1_LIB, "ASN1 lib"},
    {ERR_R_EC_LIB, "EC lib"},
    {ERR_R_BIO_LIB, "BIO lib"},
    {ERR_R_PKCS7_LIB, "PKCS7 lib"},
    {ERR_R_X509V3_LIB, "X509V3 lib"},
    {ERR_R_ENGINE_LIB, "ENGINE lib"},
    {ERR_R_ECDSA_LIB, "ECDSA lib"},

    {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"},
    {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"},

    {ERR_R_FATAL, "fatal"},
    {ERR_R_MALLOC_FAILURE, "malloc failure"},
    {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
     "called a function you should not call"},
    {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"},
    {ERR_R_INTERNAL_ERROR, "internal error"},
    {ERR_R_DISABLED, "called a function that was disabled at compile-time"},
117
    {ERR_R_INIT_FAIL, "init fail"},
118 119 120

    {0, NULL},
};
121
#endif
122

123 124 125
static CRYPTO_ONCE err_init = CRYPTO_ONCE_STATIC_INIT;
static CRYPTO_THREAD_LOCAL err_thread_local;

126 127 128
static CRYPTO_ONCE err_string_init = CRYPTO_ONCE_STATIC_INIT;
static CRYPTO_RWLOCK *err_string_lock;

129 130
static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);

131
/*
R
Rich Salz 已提交
132
 * The internal state
133
 */
R
Rich Salz 已提交
134

B
Ben Laurie 已提交
135
static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
136
static int int_err_library_number = ERR_LIB_USER;
137

138 139 140
static unsigned long get_error_values(int inc, int top, const char **file,
                                      int *line, const char **data,
                                      int *flags);
141

B
Ben Laurie 已提交
142
static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
143 144 145 146 147 148 149
{
    unsigned long ret, l;

    l = a->error;
    ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l);
    return (ret ^ ret % 19 * 13);
}
B
Ben Laurie 已提交
150 151

static int err_string_data_cmp(const ERR_STRING_DATA *a,
152 153 154 155 156
                               const ERR_STRING_DATA *b)
{
    return (int)(a->error - b->error);
}

157
static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
158
{
R
Rich Salz 已提交
159
    ERR_STRING_DATA *p = NULL;
160

161
    CRYPTO_THREAD_read_lock(err_string_lock);
R
Rich Salz 已提交
162 163
    if (int_error_hash != NULL)
        p = lh_ERR_STRING_DATA_retrieve(int_error_hash, d);
164
    CRYPTO_THREAD_unlock(err_string_lock);
165

166 167
    return p;
}
168

169
#ifndef OPENSSL_NO_ERR
170 171
# define NUM_SYS_STR_REASONS 127
# define LEN_SYS_STR_REASON 32
172 173

static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
174 175 176 177 178 179 180 181 182
/*
 * SYS_str_reasons is filled with copies of strerror() results at
 * initialization. 'errno' values up to 127 should cover all usual errors,
 * others will be displayed numerically by ERR_error_string. It is crucial
 * that we have something for each reason code that occurs in
 * ERR_str_reasons, or bogus reason strings will be returned for SYSerr(),
 * which always gets an errno value and never one of those 'standard' reason
 * codes.
 */
183

184
static void build_SYS_str_reasons(void)
185 186 187 188
{
    /* OPENSSL_malloc cannot be used here, use static storage instead */
    static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
    static int init = 1;
R
Rich Salz 已提交
189
    int i;
190

191
    CRYPTO_THREAD_write_lock(err_string_lock);
192
    if (!init) {
193
        CRYPTO_THREAD_unlock(err_string_lock);
194 195 196 197 198 199 200 201 202
        return;
    }

    for (i = 1; i <= NUM_SYS_STR_REASONS; i++) {
        ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];

        str->error = (unsigned long)i;
        if (str->string == NULL) {
            char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
203
            if (openssl_strerror_r(i, *dest, sizeof(*dest)))
204 205 206 207 208 209 210 211 212 213 214 215 216
                str->string = *dest;
        }
        if (str->string == NULL)
            str->string = "unknown";
    }

    /*
     * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as
     * required by ERR_load_strings.
     */

    init = 0;

217
    CRYPTO_THREAD_unlock(err_string_lock);
218
}
219 220
#endif

221
#define err_clear_data(p,i) \
222
        do { \
R
Rich Salz 已提交
223
        if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
224 225 226 227 228 229
                {  \
                OPENSSL_free((p)->err_data[i]); \
                (p)->err_data[i]=NULL; \
                } \
        (p)->err_data_flags[i]=0; \
        } while(0)
230 231

#define err_clear(p,i) \
232 233 234 235 236 237 238
        do { \
        (p)->err_flags[i]=0; \
        (p)->err_buffer[i]=0; \
        err_clear_data(p,i); \
        (p)->err_file[i]=NULL; \
        (p)->err_line[i]= -1; \
        } while(0)
239

U
Ulf Möller 已提交
240
static void ERR_STATE_free(ERR_STATE *s)
241 242
{
    int i;
243

244 245
    if (s == NULL)
        return;
B
Ben Laurie 已提交
246

247 248 249 250 251
    for (i = 0; i < ERR_NUM_ERRORS; i++) {
        err_clear_data(s, i);
    }
    OPENSSL_free(s);
}
252

253
DEFINE_RUN_ONCE_STATIC(do_err_strings_init)
254
{
M
Matt Caswell 已提交
255
    OPENSSL_init_crypto(0, NULL);
256
    err_string_lock = CRYPTO_THREAD_lock_new();
257
    return err_string_lock != NULL;
258 259 260 261
}

void err_cleanup(void)
{
262
    CRYPTO_THREAD_cleanup_local(&err_thread_local);
263 264
    CRYPTO_THREAD_lock_free(err_string_lock);
    err_string_lock = NULL;
265 266
}

267
int ERR_load_ERR_strings(void)
268
{
269
#ifndef OPENSSL_NO_ERR
270 271
    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
        return 0;
272

273 274 275 276 277
    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);
278
#endif
279
    return 1;
280
}
281

282
static void err_load_strings(int lib, ERR_STRING_DATA *str)
283
{
284
    CRYPTO_THREAD_write_lock(err_string_lock);
R
Rich Salz 已提交
285 286 287 288
    if (int_error_hash == NULL)
        int_error_hash = lh_ERR_STRING_DATA_new(err_string_data_hash,
                                                err_string_data_cmp);
    if (int_error_hash != NULL) {
R
Rich Salz 已提交
289 290 291
        for (; str->error; str++) {
            if (lib)
                str->error |= ERR_PACK(lib, 0, 0);
R
Rich Salz 已提交
292
            (void)lh_ERR_STRING_DATA_insert(int_error_hash, str);
R
Rich Salz 已提交
293
        }
294
    }
295
    CRYPTO_THREAD_unlock(err_string_lock);
296
}
297

298
int ERR_load_strings(int lib, ERR_STRING_DATA *str)
299
{
300 301
    if (ERR_load_ERR_strings() == 0)
        return 0;
302
    err_load_strings(lib, str);
303
    return 1;
304
}
305

306
int ERR_unload_strings(int lib, ERR_STRING_DATA *str)
307
{
308 309
    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
        return 0;
310 311

    CRYPTO_THREAD_write_lock(err_string_lock);
R
Rich Salz 已提交
312
    if (int_error_hash != NULL) {
R
Rich Salz 已提交
313 314 315
        for (; str->error; str++) {
            if (lib)
                str->error |= ERR_PACK(lib, 0, 0);
R
Rich Salz 已提交
316
            (void)lh_ERR_STRING_DATA_delete(int_error_hash, str);
R
Rich Salz 已提交
317
        }
318
    }
319
    CRYPTO_THREAD_unlock(err_string_lock);
320 321

    return 1;
322
}
323

324
void err_free_strings_int(void)
325
{
326 327
    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
        return;
328 329

    CRYPTO_THREAD_write_lock(err_string_lock);
R
Rich Salz 已提交
330 331
    lh_ERR_STRING_DATA_free(int_error_hash);
    int_error_hash = NULL;
332
    CRYPTO_THREAD_unlock(err_string_lock);
333
}
334

335 336
/********************************************************/

337 338 339
void ERR_put_error(int lib, int func, int reason, const char *file, int line)
{
    ERR_STATE *es;
340

341
#ifdef _OSD_POSIX
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
    /*
     * 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];
    }
359
#endif
360 361 362 363 364 365 366 367 368 369 370
    es = ERR_get_state();

    es->top = (es->top + 1) % ERR_NUM_ERRORS;
    if (es->top == es->bottom)
        es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
    es->err_flags[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;
    err_clear_data(es, es->top);
}
371

U
Ulf Möller 已提交
372
void ERR_clear_error(void)
373 374 375
{
    int i;
    ERR_STATE *es;
376

377
    es = ERR_get_state();
378

379 380 381 382 383
    for (i = 0; i < ERR_NUM_ERRORS; i++) {
        err_clear(es, i);
    }
    es->top = es->bottom = 0;
}
384

U
Ulf Möller 已提交
385
unsigned long ERR_get_error(void)
386 387 388
{
    return (get_error_values(1, 0, NULL, NULL, NULL, NULL));
}
389

390 391 392 393
unsigned long ERR_get_error_line(const char **file, int *line)
{
    return (get_error_values(1, 0, file, line, NULL, NULL));
}
394

U
Ulf Möller 已提交
395
unsigned long ERR_get_error_line_data(const char **file, int *line,
396 397 398 399
                                      const char **data, int *flags)
{
    return (get_error_values(1, 0, file, line, data, flags));
}
B
Bodo Möller 已提交
400

U
Ulf Möller 已提交
401
unsigned long ERR_peek_error(void)
402 403 404
{
    return (get_error_values(0, 0, NULL, NULL, NULL, NULL));
}
405

B
Bodo Möller 已提交
406
unsigned long ERR_peek_error_line(const char **file, int *line)
407 408 409
{
    return (get_error_values(0, 0, file, line, NULL, NULL));
}
410

U
Ulf Möller 已提交
411
unsigned long ERR_peek_error_line_data(const char **file, int *line,
412 413 414 415
                                       const char **data, int *flags)
{
    return (get_error_values(0, 0, file, line, data, flags));
}
B
Bodo Möller 已提交
416 417

unsigned long ERR_peek_last_error(void)
418 419 420
{
    return (get_error_values(0, 1, NULL, NULL, NULL, NULL));
}
B
Bodo Möller 已提交
421 422

unsigned long ERR_peek_last_error_line(const char **file, int *line)
423 424 425
{
    return (get_error_values(0, 1, file, line, NULL, NULL));
}
B
Bodo Möller 已提交
426

B
Bodo Möller 已提交
427
unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
                                            const char **data, int *flags)
{
    return (get_error_values(0, 1, file, line, data, flags));
}

static unsigned long get_error_values(int inc, int top, const char **file,
                                      int *line, const char **data,
                                      int *flags)
{
    int i = 0;
    ERR_STATE *es;
    unsigned long ret;

    es = ERR_get_state();

    if (inc && top) {
        if (file)
            *file = "";
        if (line)
            *line = 0;
        if (data)
            *data = "";
        if (flags)
            *flags = 0;

        return ERR_R_INTERNAL_ERROR;
    }

    if (es->bottom == es->top)
        return 0;
    if (top)
        i = es->top;            /* last error */
    else
        i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */

    ret = es->err_buffer[i];
    if (inc) {
        es->bottom = i;
        es->err_buffer[i] = 0;
    }

    if ((file != NULL) && (line != NULL)) {
        if (es->err_file[i] == NULL) {
            *file = "NA";
            if (line != NULL)
                *line = 0;
        } else {
            *file = es->err_file[i];
            if (line != NULL)
                *line = es->err_line[i];
        }
    }

    if (data == NULL) {
        if (inc) {
            err_clear_data(es, i);
        }
    } else {
        if (es->err_data[i] == NULL) {
            *data = "";
            if (flags != NULL)
                *flags = 0;
        } else {
            *data = es->err_data[i];
            if (flags != NULL)
                *flags = es->err_data_flags[i];
        }
    }
    return ret;
}
498

B
Bodo Möller 已提交
499
void ERR_error_string_n(unsigned long e, char *buf, size_t len)
500 501 502 503 504
{
    char lsbuf[64], fsbuf[64], rsbuf[64];
    const char *ls, *fs, *rs;
    unsigned long l, f, r;

505 506 507
    if (len == 0)
        return;

508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
    l = ERR_GET_LIB(e);
    f = ERR_GET_FUNC(e);
    r = ERR_GET_REASON(e);

    ls = ERR_lib_error_string(e);
    fs = ERR_func_error_string(e);
    rs = ERR_reason_error_string(e);

    if (ls == NULL)
        BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
    if (fs == NULL)
        BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
    if (rs == NULL)
        BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);

    BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf,
                 fs ? fs : fsbuf, rs ? rs : rsbuf);
    if (strlen(buf) == len - 1) {
        /*
         * output may be truncated; make sure we always have 5
         * colon-separated fields, i.e. 4 colons ...
         */
B
Bodo Möller 已提交
530
#define NUM_COLONS 4
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
        if (len > NUM_COLONS) { /* ... if possible */
            int i;
            char *s = buf;

            for (i = 0; i < NUM_COLONS; i++) {
                char *colon = strchr(s, ':');
                if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) {
                    /*
                     * set colon no. i at last possible position (buf[len-1]
                     * is the terminating 0)
                     */
                    colon = &buf[len - 1] - NUM_COLONS + i;
                    *colon = ':';
                }
                s = colon + 1;
            }
        }
    }
}
B
Bodo Möller 已提交
550

551 552 553 554
/*
 * ERR_error_string_n should be used instead for ret != NULL as
 * ERR_error_string cannot know how large the buffer is
 */
B
Bodo Möller 已提交
555
char *ERR_error_string(unsigned long e, char *ret)
556 557
{
    static char buf[256];
B
Bodo Möller 已提交
558

559 560 561
    if (ret == NULL)
        ret = buf;
    ERR_error_string_n(e, ret, 256);
562

563 564
    return ret;
}
565

U
Ulf Möller 已提交
566
const char *ERR_lib_error_string(unsigned long e)
567 568 569
{
    ERR_STRING_DATA d, *p;
    unsigned long l;
570

571 572 573
    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
        return NULL;
    }
574

575 576
    l = ERR_GET_LIB(e);
    d.error = ERR_PACK(l, 0, 0);
R
Rich Salz 已提交
577
    p = int_err_get_item(&d);
578 579
    return ((p == NULL) ? NULL : p->string);
}
580

U
Ulf Möller 已提交
581
const char *ERR_func_error_string(unsigned long e)
582 583 584 585
{
    ERR_STRING_DATA d, *p;
    unsigned long l, f;

586 587 588
    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
        return NULL;
    }
589

590 591 592
    l = ERR_GET_LIB(e);
    f = ERR_GET_FUNC(e);
    d.error = ERR_PACK(l, f, 0);
R
Rich Salz 已提交
593
    p = int_err_get_item(&d);
594 595
    return ((p == NULL) ? NULL : p->string);
}
596

U
Ulf Möller 已提交
597
const char *ERR_reason_error_string(unsigned long e)
598 599 600 601
{
    ERR_STRING_DATA d, *p = NULL;
    unsigned long l, r;

602 603 604
    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
        return NULL;
    }
605

606 607 608
    l = ERR_GET_LIB(e);
    r = ERR_GET_REASON(e);
    d.error = ERR_PACK(l, 0, r);
R
Rich Salz 已提交
609
    p = int_err_get_item(&d);
610 611
    if (!p) {
        d.error = ERR_PACK(0, 0, r);
R
Rich Salz 已提交
612
        p = int_err_get_item(&d);
613 614 615
    }
    return ((p == NULL) ? NULL : p->string);
}
616

617
void err_delete_thread_state(void)
618
{
619 620 621
    ERR_STATE *state = ERR_get_state();
    if (state == NULL)
        return;
622

623 624
    CRYPTO_THREAD_set_local(&err_thread_local, NULL);
    ERR_STATE_free(state);
625
}
626

627
#if OPENSSL_API_COMPAT < 0x10100000L
628 629 630 631 632
void ERR_remove_thread_state(void *dummy)
{
}
#endif

633
#if OPENSSL_API_COMPAT < 0x10000000L
634
void ERR_remove_state(unsigned long pid)
635 636
{
}
637 638
#endif

639
DEFINE_RUN_ONCE_STATIC(err_do_init)
640
{
641
    return CRYPTO_THREAD_init_local(&err_thread_local, NULL);
642 643
}

U
Ulf Möller 已提交
644
ERR_STATE *ERR_get_state(void)
645
{
646 647
    ERR_STATE *state = NULL;

648 649
    if (!RUN_ONCE(&err_init, err_do_init))
        return NULL;
650 651 652 653 654 655 656 657 658 659 660

    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;
661
        }
662 663

        /* Ignore failures from these */
664
        OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
M
Matt Caswell 已提交
665
        ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE);
666
    }
667 668

    return state;
669
}
670

U
Ulf Möller 已提交
671
int ERR_get_next_error_library(void)
672
{
R
Rich Salz 已提交
673 674
    int ret;

675 676 677
    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
        return 0;
    }
678 679

    CRYPTO_THREAD_write_lock(err_string_lock);
R
Rich Salz 已提交
680
    ret = int_err_library_number++;
681
    CRYPTO_THREAD_unlock(err_string_lock);
R
Rich Salz 已提交
682
    return ret;
683
}
684

U
Ulf Möller 已提交
685
void ERR_set_error_data(char *data, int flags)
686 687 688
{
    ERR_STATE *es;
    int i;
689

690
    es = ERR_get_state();
691

692 693 694
    i = es->top;
    if (i == 0)
        i = ERR_NUM_ERRORS - 1;
695

696 697 698 699
    err_clear_data(es, i);
    es->err_data[i] = data;
    es->err_data_flags[i] = flags;
}
700

U
Ulf Möller 已提交
701
void ERR_add_error_data(int num, ...)
702 703 704 705 706 707
{
    va_list args;
    va_start(args, num);
    ERR_add_error_vdata(num, args);
    va_end(args);
}
708 709

void ERR_add_error_vdata(int num, va_list args)
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731
{
    int i, n, s;
    char *str, *p, *a;

    s = 80;
    str = OPENSSL_malloc(s + 1);
    if (str == NULL)
        return;
    str[0] = '\0';

    n = 0;
    for (i = 0; i < num; i++) {
        a = va_arg(args, char *);
        /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
        if (a != NULL) {
            n += strlen(a);
            if (n > s) {
                s = n + 20;
                p = OPENSSL_realloc(str, s + 1);
                if (p == NULL) {
                    OPENSSL_free(str);
                    return;
R
Rich Salz 已提交
732 733
                }
                str = p;
734
            }
R
Rich Salz 已提交
735
            OPENSSL_strlcat(str, a, (size_t)s + 1);
736 737 738 739
        }
    }
    ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING);
}
740 741

int ERR_set_mark(void)
742 743
{
    ERR_STATE *es;
744

745
    es = ERR_get_state();
746

747 748 749 750 751
    if (es->bottom == es->top)
        return 0;
    es->err_flags[es->top] |= ERR_FLAG_MARK;
    return 1;
}
752 753

int ERR_pop_to_mark(void)
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
{
    ERR_STATE *es;

    es = ERR_get_state();

    while (es->bottom != es->top
           && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
        err_clear(es, es->top);
        es->top -= 1;
        if (es->top == -1)
            es->top = ERR_NUM_ERRORS - 1;
    }

    if (es->bottom == es->top)
        return 0;
    es->err_flags[es->top] &= ~ERR_FLAG_MARK;
    return 1;
}