Coverage Report

Created: 2026-08-15 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-heapmath/src/ssl_err.c
Line
Count
Source
1
/* ssl_err.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if !defined(WOLFSSL_SSL_ERR_INCLUDED)
25
    #ifndef WOLFSSL_IGNORE_FILE_WARN
26
        #warning ssl_err.c does not need to be compiled separately from ssl.c
27
    #endif
28
#else
29
30
#ifndef WOLFCRYPT_ONLY
31
32
/* Get the string describing an error value.
33
 *
34
 * When data is NULL, a static buffer is used and the string is overwritten by
35
 * the next call that passes NULL.
36
 *
37
 * @param [in]      errNumber  Error value.
38
 * @param [in, out] data       Buffer to hold string. Must be at least
39
 *                             WOLFSSL_MAX_ERROR_SZ bytes. May be NULL.
40
 * @return  Buffer holding string.
41
 */
42
char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
43
0
{
44
0
    WOLFSSL_ENTER("wolfSSL_ERR_error_string");
45
0
    if (data) {
46
0
        SetErrorString((int)errNumber, data);
47
0
        return data;
48
0
    }
49
0
    else {
50
0
        static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
51
0
        SetErrorString((int)errNumber, tmp);
52
0
        return tmp;
53
0
    }
54
0
}
55
56
/* Get the string describing an error value into a buffer of limited size.
57
 *
58
 * String is truncated to fit, including the NUL terminator.
59
 *
60
 * @param [in]      e    Error value.
61
 * @param [in, out] buf  Buffer to hold string.
62
 * @param [in]      len  Length of buffer in bytes.
63
 */
64
void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
65
0
{
66
0
    WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
67
0
    if (len >= WOLFSSL_MAX_ERROR_SZ)
68
0
        wolfSSL_ERR_error_string(e, buf);
69
0
    else {
70
0
        WOLFSSL_MSG("Error buffer too short, truncating");
71
0
        if (len) {
72
0
            char tmp[WOLFSSL_MAX_ERROR_SZ];
73
0
            wolfSSL_ERR_error_string(e, tmp);
74
0
            XMEMCPY(buf, tmp, len-1);
75
0
            buf[len-1] = '\0';
76
0
        }
77
0
    }
78
0
}
79
80
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) \
81
    && defined(XFPRINTF)
82
/* Print the string describing an error value to a file.
83
 *
84
 * @param [in] fp   File to print to.
85
 * @param [in] err  Error value.
86
 */
87
void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
88
0
{
89
0
    char data[WOLFSSL_MAX_ERROR_SZ + 1];
90
91
0
    WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
92
0
    SetErrorString(err, data);
93
0
    if (XFPRINTF(fp, "%s", data) < 0)
94
0
        WOLFSSL_MSG("fprintf failed in wolfSSL_ERR_print_errors_fp");
95
0
}
96
97
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
98
/* Print the entries of the error queue to a file.
99
 *
100
 * @param [in] fp  File to print to.
101
 */
102
void wolfSSL_ERR_dump_errors_fp(XFILE fp)
103
{
104
    wc_ERR_print_errors_fp(fp);
105
}
106
107
/* Pass the entries of the error queue to a callback.
108
 *
109
 * @param [in] cb  Callback to pass each error string to.
110
 * @param [in] u   Context to pass to the callback.
111
 */
112
void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
113
                                            void *u), void *u)
114
{
115
    wc_ERR_print_errors_cb(cb, u);
116
}
117
#endif
118
#endif
119
120
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
121
    /* Get the last error value from the error queue and remove it.
122
     *
123
     * @return  Error value on success.
124
     * @return  0 when there is no error queue.
125
     */
126
    unsigned long wolfSSL_ERR_get_error(void)
127
    {
128
        WOLFSSL_ENTER("wolfSSL_ERR_get_error");
129
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
130
        return (unsigned long)wc_GetErrorNodeErr();
131
#else
132
        return 0;
133
#endif
134
    }
135
#endif
136
137
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
138
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
139
#ifndef NO_BIO
140
    /* Print the entries of the error queue to a BIO.
141
     *
142
     * Entries are removed from the queue as they are printed.
143
     *
144
     * @param [in, out] bio  BIO to print to.
145
     */
146
    void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
147
    {
148
        const char* file = NULL;
149
        const char* reason = NULL;
150
        int ret;
151
        int line = 0;
152
        char buf[WOLFSSL_MAX_ERROR_SZ * 2];
153
154
        WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
155
156
        if (bio == NULL) {
157
            WOLFSSL_MSG("BIO passed in was null");
158
            return;
159
        }
160
161
        do {
162
        ret = wc_PeekErrorNode(0, &file, &reason, &line);
163
        if (ret >= 0) {
164
            const char* r = wolfSSL_ERR_reason_error_string(
165
                (unsigned long)(0 - ret));
166
            if (XSNPRINTF(buf, sizeof(buf),
167
                          "error:%d:wolfSSL library:%s:%s:%d\n",
168
                          ret, r, file, line)
169
                >= (int)sizeof(buf))
170
            {
171
                WOLFSSL_MSG("Buffer overrun formatting error message");
172
            }
173
            wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
174
            wc_RemoveErrorNode(0);
175
        }
176
        } while (ret >= 0);
177
        if (wolfSSL_BIO_write(bio, "", 1) != 1) {
178
            WOLFSSL_MSG("Issue writing final string terminator");
179
        }
180
    }
181
#endif
182
#endif
183
#endif
184
185
#ifdef OPENSSL_EXTRA
186
    /* Free the error strings.
187
     *
188
     * Error strings are handled internally. For OpenSSL compatibility only.
189
     */
190
    void wolfSSL_ERR_free_strings(void)
191
    {
192
        /* handled internally */
193
    }
194
#endif
195
196
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) || \
197
    defined(HAVE_CURL)
198
    /* Remove all entries from the error queue.
199
     */
200
    void wolfSSL_ERR_clear_error(void)
201
    {
202
        WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
203
    #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
204
        wc_ClearErrorNodes();
205
    #endif
206
    }
207
#endif
208
209
#ifdef OPENSSL_EXTRA
210
    /* Get the last error value from the error queue with its file and line.
211
     *
212
     * Entry is removed from the queue.
213
     *
214
     * @param [out] file  Name of file error occurred in.
215
     * @param [out] line  Line number error occurred on.
216
     * @return  Error value on success.
217
     * @return  0 when there are no entries in the queue or there is no error
218
     *          queue.
219
     */
220
    unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
221
    {
222
    #ifdef WOLFSSL_HAVE_ERROR_QUEUE
223
        int ret = wc_PullErrorNode(file, NULL, line);
224
        if (ret < 0) {
225
            if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
226
                return 0; /* no errors in queue */
227
            WOLFSSL_MSG("Issue getting error node");
228
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
229
            ret = 0 - ret; /* return absolute value of error */
230
231
            /* panic and try to clear out nodes */
232
            wc_ClearErrorNodes();
233
        }
234
        return (unsigned long)ret;
235
    #else
236
        (void)file;
237
        (void)line;
238
239
        return 0;
240
    #endif
241
    }
242
243
#if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
244
    (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
245
    static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
246
    static const char WOLFSSL_SYS_BIND_T[]    = "bind";
247
    static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
248
    static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
249
    static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
250
    static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
251
    static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
252
    static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
253
    static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
254
    static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
255
    static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
256
    static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
257
    static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
258
    static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
259
    static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
260
    static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
261
262
    /* Get the name of a system function.
263
     *
264
     * Maps the int identifier to a function name for compatibility.
265
     *
266
     * @param [in] fun  System function identifier. WOLFSSL_SYS_*.
267
     * @return  Name of function on success.
268
     * @return  "NULL" when the identifier is not known.
269
     */
270
    static const char* wolfSSL_ERR_sys_func(int fun)
271
    {
272
        switch (fun) {
273
            case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
274
            case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
275
            case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
276
            case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
277
            case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
278
            case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
279
            case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
280
            case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
281
            case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
282
            case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
283
            case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
284
            case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
285
            case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
286
            case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
287
            case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
288
            case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
289
            default:
290
                return "NULL";
291
        }
292
    }
293
#endif
294
295
    /* Add an error to the error queue.
296
     *
297
     * @param [in] lib   Library the error occurred in. Not used.
298
     * @param [in] fun   System function the error occurred in. WOLFSSL_SYS_*.
299
     * @param [in] err   Error value.
300
     * @param [in] file  Name of file the error occurred in.
301
     * @param [in] line  Line number the error occurred on.
302
     */
303
    void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
304
            int line)
305
    {
306
        WOLFSSL_ENTER("wolfSSL_ERR_put_error");
307
308
        #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
309
        (void)fun;
310
        (void)err;
311
        (void)file;
312
        (void)line;
313
        WOLFSSL_MSG("Not compiled in debug mode");
314
        #elif defined(OPENSSL_EXTRA) && \
315
                (defined(_WIN32) || defined(NO_ERROR_QUEUE))
316
        (void)fun;
317
        (void)file;
318
        (void)line;
319
        WOLFSSL_ERROR(err);
320
        #else
321
        WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
322
            file, NULL);
323
        #endif
324
        (void)lib;
325
    }
326
327
    /* Get the last error value from the error queue with its data.
328
     *
329
     * Entry is removed from the queue. Similar to
330
     * wolfSSL_ERR_get_error_line() but takes a flags argument for more
331
     * flexibility.
332
     *
333
     * @param [out] file   Name of file error occurred in.
334
     * @param [out] line   Line number error occurred on.
335
     * @param [out] data   Error data. A string when the WOLFSSL_ERR_TXT_STRING
336
     *                     flag is returned.
337
     * @param [out] flags  Format of data. WOLFSSL_ERR_TXT_STRING.
338
     * @return  Error value on success.
339
     * @return  0 when there are no entries in the queue or there is no error
340
     *          queue.
341
     */
342
    unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
343
                                                  const char** data, int *flags)
344
    {
345
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
346
        int ret;
347
348
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
349
350
        if (flags != NULL)
351
            *flags = WOLFSSL_ERR_TXT_STRING; /* Clear the flags */
352
353
        ret = wc_PullErrorNode(file, data, line);
354
        if (ret < 0) {
355
            if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
356
                return 0; /* no errors in queue */
357
            WOLFSSL_MSG("Error with pulling error node!");
358
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
359
            ret = 0 - ret; /* return absolute value of error */
360
361
            /* panic and try to clear out nodes */
362
            wc_ClearErrorNodes();
363
        }
364
365
        return (unsigned long)ret;
366
#else
367
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
368
        WOLFSSL_MSG("Error queue turned off, can not get error line");
369
        (void)file;
370
        (void)line;
371
        (void)data;
372
        (void)flags;
373
        return 0;
374
#endif
375
    }
376
377
/* Get the last error value from the error queue without removing it.
378
 *
379
 * @return  Error value on success.
380
 * @return  0 when there are no entries in the queue.
381
 */
382
unsigned long wolfSSL_ERR_peek_error(void)
383
{
384
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
385
386
    return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
387
}
388
389
#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES_H
390
#include <wolfssl/debug-untrace-error-codes.h>
391
#endif
392
393
/* Get the library that an error value belongs to.
394
 *
395
 * @param [in] err  Error value.
396
 * @return  WOLFSSL_ERR_LIB_* value on success.
397
 * @return  WOLFSSL_ERR_LIB_SSL when the library is not identifiable.
398
 */
399
int wolfSSL_ERR_GET_LIB(unsigned long err)
400
{
401
    unsigned long value;
402
403
    value = (err & 0xFFFFFFL);
404
    switch (value) {
405
    case -PARSE_ERROR:
406
        return WOLFSSL_ERR_LIB_SSL;
407
    case -ASN_NO_PEM_HEADER:
408
    case -WOLFSSL_PEM_R_NO_START_LINE_E:
409
    case -WOLFSSL_PEM_R_PROBLEMS_GETTING_PASSWORD_E:
410
    case -WOLFSSL_PEM_R_BAD_PASSWORD_READ_E:
411
    case -WOLFSSL_PEM_R_BAD_DECRYPT_E:
412
        return WOLFSSL_ERR_LIB_PEM;
413
    case -WOLFSSL_EVP_R_BAD_DECRYPT_E:
414
    case -WOLFSSL_EVP_R_BN_DECODE_ERROR:
415
    case -WOLFSSL_EVP_R_DECODE_ERROR:
416
    case -WOLFSSL_EVP_R_PRIVATE_KEY_DECODE_ERROR:
417
        return WOLFSSL_ERR_LIB_EVP;
418
    case -WOLFSSL_ASN1_R_HEADER_TOO_LONG_E:
419
        return WOLFSSL_ERR_LIB_ASN1;
420
    default:
421
        return 0;
422
    }
423
}
424
425
#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES
426
#include <wolfssl/debug-trace-error-codes.h>
427
#endif
428
429
/* This function is to find global error values that are the same through out
430
 * all library version. With wolfSSL having only one set of error codes the
431
 * return value is pretty straight forward. The only thing needed is all wolfSSL
432
 * error values are typically negative.
433
 *
434
 * Returns the error reason
435
 */
436
int wolfSSL_ERR_GET_REASON(unsigned long err)
437
{
438
    int ret = (int)err;
439
440
    WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
441
442
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
443
    /* Nginx looks for this error to know to stop parsing certificates.
444
     * Same for HAProxy. */
445
    if ((err == (unsigned long)((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE)) ||
446
        ((err & 0xFFFFFFL) ==
447
            (unsigned long)(-WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))) ||
448
        ((err & 0xFFFL) == (unsigned long)PEM_R_NO_START_LINE))
449
        return PEM_R_NO_START_LINE;
450
    if (err == (unsigned long)((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
451
        return SSL_R_HTTP_REQUEST;
452
#endif
453
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
454
    if (err == (unsigned long)((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
455
        return ASN1_R_HEADER_TOO_LONG;
456
#endif
457
458
    /* check if error value is in range of wolfCrypt or wolfSSL errors */
459
    ret = 0 - ret; /* setting as negative value */
460
461
    if ((ret <= WC_SPAN1_FIRST_E && ret >= WC_SPAN1_LAST_E) ||
462
        (ret <= WC_SPAN2_FIRST_E && ret >= WC_SPAN2_LAST_E) ||
463
        (ret <= WOLFSSL_FIRST_E && ret >= WOLFSSL_LAST_E))
464
    {
465
        /* Every protocol-version mismatch is reported internally as
466
         * VERSION_ERROR, while the SSL_R_* version reasons carry real
467
         * OpenSSL values so that consumers can use them as distinct
468
         * switch cases; translate so that ERR_GET_REASON() comparisons
469
         * against SSL_R_WRONG_VERSION_NUMBER keep matching. */
470
        if (ret == WC_NO_ERR_TRACE(VERSION_ERROR))
471
            return WOLFSSL_SSL_R_WRONG_VERSION_NUMBER;
472
        return ret;
473
    }
474
    else {
475
        WOLFSSL_MSG("Not in range of typical error values");
476
        ret = (int)err;
477
    }
478
479
    return ret;
480
}
481
482
#if !defined(NETOS)
483
/* Load the SSL error strings.
484
 *
485
 * Error strings are handled internally. For OpenSSL compatibility only.
486
 */
487
void wolfSSL_ERR_load_SSL_strings(void)
488
{
489
490
}
491
#endif
492
493
/* Get the last error value from the error queue with its file and line
494
 * without removing it.
495
 *
496
 * @param [out] file  Name of file error occurred in.
497
 * @param [out] line  Line number error occurred on.
498
 * @return  Error value on success.
499
 * @return  0 when there are no entries in the queue.
500
 * @return  0 when there is no error queue.
501
 */
502
unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
503
{
504
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
505
506
    (void)line;
507
    (void)file;
508
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
509
    {
510
        int ret;
511
512
        if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
513
            WOLFSSL_MSG("Issue peeking at error node in queue");
514
            return 0;
515
        }
516
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) \
517
        || defined(WOLFSSL_HAPROXY)
518
        if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
519
            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
520
    #endif
521
    #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
522
        if (ret == ASN1_R_HEADER_TOO_LONG) {
523
            return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
524
        }
525
    #endif
526
        return (unsigned long)ret;
527
    }
528
#else
529
    return 0;
530
#endif
531
}
532
#endif
533
534
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
535
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
536
     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
537
     defined(WOLFSSL_OPENSSH)))
538
/* Remove the error queue entries of a thread.
539
 *
540
 * Not implemented. For OpenSSL compatibility only.
541
 *
542
 * @param [in] pid  Thread identifier. Not used.
543
 */
544
void wolfSSL_ERR_remove_thread_state(void* pid)
545
{
546
    (void) pid;
547
    return;
548
}
549
#endif
550
551
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
552
/* Load the ERR error strings.
553
 *
554
 * Error strings are handled internally. For OpenSSL compatibility only.
555
 *
556
 * @return  WOLFSSL_SUCCESS always.
557
 */
558
int wolfSSL_ERR_load_ERR_strings(void)
559
{
560
    return WOLFSSL_SUCCESS;
561
}
562
563
/* Load the crypto error strings.
564
 *
565
 * Error strings are handled internally. For OpenSSL compatibility only.
566
 */
567
void wolfSSL_ERR_load_crypto_strings(void)
568
{
569
    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
570
    /* Do nothing */
571
    return;
572
}
573
574
#ifndef NO_BIO
575
/* Load the BIO error strings.
576
 *
577
 * Error strings are handled internally. For OpenSSL compatibility only.
578
 */
579
void wolfSSL_ERR_load_BIO_strings(void) {
580
    WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings");
581
    /* do nothing */
582
}
583
#endif
584
#endif
585
586
#if defined(OPENSSL_EXTRA)
587
/* Get the last error value from the error queue without removing it.
588
 *
589
 * Some error values are mapped to the OpenSSL equivalent.
590
 *
591
 * @return  Error value on success.
592
 * @return  0 when there are no entries in the queue.
593
 * @return  0 when there is no error queue.
594
 */
595
unsigned long wolfSSL_ERR_peek_last_error(void)
596
{
597
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
598
599
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
600
    {
601
        int ret;
602
603
        if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
604
            WOLFSSL_MSG("Issue peeking at error node in queue");
605
            return 0;
606
        }
607
        if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
608
            return (WOLFSSL_ERR_LIB_PEM << 24) |
609
                -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
610
    #if defined(WOLFSSL_PYTHON)
611
        if (ret == ASN1_R_HEADER_TOO_LONG)
612
            return (WOLFSSL_ERR_LIB_ASN1 << 24) |
613
                -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
614
    #endif
615
        return (unsigned long)ret;
616
    }
617
#else
618
    return 0;
619
#endif
620
}
621
622
/* Determine whether an error value is to be ignored when peeking.
623
 *
624
 * @param [in] err  Error value.
625
 * @return  1 when the error is to be ignored.
626
 * @return  0 otherwise.
627
 */
628
static int peek_ignore_err(int err)
629
{
630
  switch(err) {
631
    case -WC_NO_ERR_TRACE(WANT_READ):
632
    case -WC_NO_ERR_TRACE(WANT_WRITE):
633
    case -WC_NO_ERR_TRACE(ZERO_RETURN):
634
    case -WOLFSSL_ERROR_ZERO_RETURN:
635
    case -WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E):
636
    case -WC_NO_ERR_TRACE(SOCKET_ERROR_E):
637
      return 1;
638
    default:
639
      return 0;
640
  }
641
}
642
643
/* Get the last error value from the error queue with its data without
644
 * removing it.
645
 *
646
 * Errors that are not real errors, such as WANT_READ, are skipped.
647
 *
648
 * @param [out] file   Name of file error occurred in.
649
 * @param [out] line   Line number error occurred on.
650
 * @param [out] data   Error data. Always set to "" when not NULL.
651
 * @param [out] flags  Format of data. Always set to WOLFSSL_ERR_TXT_STRING
652
 *                     when not NULL.
653
 * @return  Error value on success.
654
 * @return  0 when there are no entries in the queue.
655
 */
656
unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
657
                                               const char **data, int *flags)
658
{
659
  unsigned long err;
660
661
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
662
    err = wc_PeekErrorNodeLineData(file, line, data, flags, peek_ignore_err);
663
664
    if (err == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
665
        return (WOLFSSL_ERR_LIB_PEM << 24) |
666
            -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
667
#ifdef OPENSSL_ALL
668
    /* PARSE_ERROR is returned if an HTTP request is detected. */
669
    else if (err == -WC_NO_ERR_TRACE(PARSE_ERROR))
670
        /* SSL_R_HTTP_REQUEST */
671
        return (WOLFSSL_ERR_LIB_SSL << 24) | -WC_NO_ERR_TRACE(PARSE_ERROR);
672
#endif
673
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
674
    else if (err == ASN1_R_HEADER_TOO_LONG)
675
        return (WOLFSSL_ERR_LIB_ASN1 << 24) |
676
            -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
677
#endif
678
  return err;
679
}
680
681
/* Remove the error queue entries of a thread.
682
 *
683
 * All entries of the current thread's queue are removed, not just those of the
684
 * given thread.
685
 *
686
 * @param [in] id  Thread identifier. Not used.
687
 */
688
void wolfSSL_ERR_remove_state(unsigned long id)
689
{
690
    WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
691
    (void)id;
692
    if (wc_ERR_remove_state() != 0) {
693
        WOLFSSL_MSG("Error with removing the state");
694
    }
695
}
696
#endif
697
698
#endif /* !WOLFCRYPT_ONLY */
699
700
#endif /* !WOLFSSL_SSL_ERR_INCLUDED */