Coverage Report

Created: 2026-11-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math/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
        /* Two bounded strings, plus 64 for the fixed text and two ints. */
153
        char buf[WOLFSSL_MAX_ERROR_SZ * 2 + 64];
154
155
        WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
156
157
        if (bio == NULL) {
158
            WOLFSSL_MSG("BIO passed in was null");
159
            return;
160
        }
161
162
        do {
163
        ret = wc_PeekErrorNode(0, &file, &reason, &line);
164
        if (ret >= 0) {
165
            const char* r = wolfSSL_ERR_reason_error_string(
166
                (unsigned long)(0 - ret));
167
            if (XSNPRINTF(buf, sizeof(buf),
168
                          "error:%d:wolfSSL library:%.*s:%.*s:%d\n",
169
                          ret, WOLFSSL_MAX_ERROR_SZ - 1, r,
170
                          WOLFSSL_MAX_ERROR_SZ - 1, file, line)
171
                >= (int)sizeof(buf))
172
            {
173
                WOLFSSL_MSG("Buffer overrun formatting error message");
174
            }
175
            wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
176
            wc_RemoveErrorNode(0);
177
        }
178
        } while (ret >= 0);
179
        if (wolfSSL_BIO_write(bio, "", 1) != 1) {
180
            WOLFSSL_MSG("Issue writing final string terminator");
181
        }
182
    }
183
#endif
184
#endif
185
#endif
186
187
#ifdef OPENSSL_EXTRA
188
    /* Free the error strings.
189
     *
190
     * Error strings are handled internally. For OpenSSL compatibility only.
191
     */
192
    void wolfSSL_ERR_free_strings(void)
193
    {
194
        /* handled internally */
195
    }
196
#endif
197
198
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) || \
199
    defined(HAVE_CURL)
200
    /* Remove all entries from the error queue.
201
     */
202
    void wolfSSL_ERR_clear_error(void)
203
    {
204
        WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
205
    #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
206
        wc_ClearErrorNodes();
207
    #endif
208
    }
209
#endif
210
211
#ifdef OPENSSL_EXTRA
212
    /* Get the last error value from the error queue with its file and line.
213
     *
214
     * Entry is removed from the queue.
215
     *
216
     * @param [out] file  Name of file error occurred in.
217
     * @param [out] line  Line number error occurred on.
218
     * @return  Error value on success.
219
     * @return  0 when there are no entries in the queue or there is no error
220
     *          queue.
221
     */
222
    unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
223
    {
224
    #ifdef WOLFSSL_HAVE_ERROR_QUEUE
225
        int ret = wc_PullErrorNode(file, NULL, line);
226
        if (ret < 0) {
227
            if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
228
                return 0; /* no errors in queue */
229
            WOLFSSL_MSG("Issue getting error node");
230
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
231
            ret = 0 - ret; /* return absolute value of error */
232
233
            /* panic and try to clear out nodes */
234
            wc_ClearErrorNodes();
235
        }
236
        return (unsigned long)ret;
237
    #else
238
        (void)file;
239
        (void)line;
240
241
        return 0;
242
    #endif
243
    }
244
245
#if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
246
    (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
247
    static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
248
    static const char WOLFSSL_SYS_BIND_T[]    = "bind";
249
    static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
250
    static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
251
    static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
252
    static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
253
    static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
254
    static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
255
    static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
256
    static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
257
    static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
258
    static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
259
    static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
260
    static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
261
    static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
262
    static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
263
264
    /* Get the name of a system function.
265
     *
266
     * Maps the int identifier to a function name for compatibility.
267
     *
268
     * @param [in] fun  System function identifier. WOLFSSL_SYS_*.
269
     * @return  Name of function on success.
270
     * @return  "NULL" when the identifier is not known.
271
     */
272
    static const char* wolfSSL_ERR_sys_func(int fun)
273
    {
274
        switch (fun) {
275
            case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
276
            case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
277
            case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
278
            case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
279
            case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
280
            case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
281
            case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
282
            case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
283
            case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
284
            case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
285
            case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
286
            case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
287
            case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
288
            case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
289
            case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
290
            case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
291
            default:
292
                return "NULL";
293
        }
294
    }
295
#endif
296
297
    /* Add an error to the error queue.
298
     *
299
     * @param [in] lib   Library the error occurred in. Not used.
300
     * @param [in] fun   System function the error occurred in. WOLFSSL_SYS_*.
301
     * @param [in] err   Error value.
302
     * @param [in] file  Name of file the error occurred in.
303
     * @param [in] line  Line number the error occurred on.
304
     */
305
    void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
306
            int line)
307
    {
308
        WOLFSSL_ENTER("wolfSSL_ERR_put_error");
309
310
        #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
311
        (void)fun;
312
        (void)err;
313
        (void)file;
314
        (void)line;
315
        WOLFSSL_MSG("Not compiled in debug mode");
316
        #elif defined(OPENSSL_EXTRA) && \
317
                (defined(_WIN32) || defined(NO_ERROR_QUEUE))
318
        (void)fun;
319
        (void)file;
320
        (void)line;
321
        WOLFSSL_ERROR(err);
322
        #else
323
        WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
324
            file, NULL);
325
        #endif
326
        (void)lib;
327
    }
328
329
    /* Get the last error value from the error queue with its data.
330
     *
331
     * Entry is removed from the queue. Similar to
332
     * wolfSSL_ERR_get_error_line() but takes a flags argument for more
333
     * flexibility.
334
     *
335
     * @param [out] file   Name of file error occurred in.
336
     * @param [out] line   Line number error occurred on.
337
     * @param [out] data   Error data. A string when the WOLFSSL_ERR_TXT_STRING
338
     *                     flag is returned.
339
     * @param [out] flags  Format of data. WOLFSSL_ERR_TXT_STRING.
340
     * @return  Error value on success.
341
     * @return  0 when there are no entries in the queue or there is no error
342
     *          queue.
343
     */
344
    unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
345
                                                  const char** data, int *flags)
346
    {
347
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
348
        int ret;
349
350
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
351
352
        if (flags != NULL)
353
            *flags = WOLFSSL_ERR_TXT_STRING; /* Clear the flags */
354
355
        ret = wc_PullErrorNode(file, data, line);
356
        if (ret < 0) {
357
            if (ret == WC_NO_ERR_TRACE(BAD_STATE_E))
358
                return 0; /* no errors in queue */
359
            WOLFSSL_MSG("Error with pulling error node!");
360
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
361
            ret = 0 - ret; /* return absolute value of error */
362
363
            /* panic and try to clear out nodes */
364
            wc_ClearErrorNodes();
365
        }
366
367
        return (unsigned long)ret;
368
#else
369
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
370
        WOLFSSL_MSG("Error queue turned off, can not get error line");
371
        (void)file;
372
        (void)line;
373
        (void)data;
374
        (void)flags;
375
        return 0;
376
#endif
377
    }
378
379
/* Get the last error value from the error queue without removing it.
380
 *
381
 * @return  Error value on success.
382
 * @return  0 when there are no entries in the queue.
383
 */
384
unsigned long wolfSSL_ERR_peek_error(void)
385
{
386
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
387
388
    return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
389
}
390
391
#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES_H
392
#include <wolfssl/debug-untrace-error-codes.h>
393
#endif
394
395
/* Get the library that an error value belongs to.
396
 *
397
 * @param [in] err  Error value.
398
 * @return  WOLFSSL_ERR_LIB_* value on success.
399
 * @return  WOLFSSL_ERR_LIB_SSL when the library is not identifiable.
400
 */
401
int wolfSSL_ERR_GET_LIB(unsigned long err)
402
{
403
    unsigned long value;
404
405
    value = (err & 0xFFFFFFL);
406
    switch (value) {
407
    case -PARSE_ERROR:
408
        return WOLFSSL_ERR_LIB_SSL;
409
    case -ASN_NO_PEM_HEADER:
410
    case -WOLFSSL_PEM_R_NO_START_LINE_E:
411
    case -WOLFSSL_PEM_R_PROBLEMS_GETTING_PASSWORD_E:
412
    case -WOLFSSL_PEM_R_BAD_PASSWORD_READ_E:
413
    case -WOLFSSL_PEM_R_BAD_DECRYPT_E:
414
        return WOLFSSL_ERR_LIB_PEM;
415
    case -WOLFSSL_EVP_R_BAD_DECRYPT_E:
416
    case -WOLFSSL_EVP_R_BN_DECODE_ERROR:
417
    case -WOLFSSL_EVP_R_DECODE_ERROR:
418
    case -WOLFSSL_EVP_R_PRIVATE_KEY_DECODE_ERROR:
419
        return WOLFSSL_ERR_LIB_EVP;
420
    case -WOLFSSL_ASN1_R_HEADER_TOO_LONG_E:
421
        return WOLFSSL_ERR_LIB_ASN1;
422
    default:
423
        return 0;
424
    }
425
}
426
427
#ifdef WOLFSSL_DEBUG_TRACE_ERROR_CODES
428
#include <wolfssl/debug-trace-error-codes.h>
429
#endif
430
431
/* This function is to find global error values that are the same through out
432
 * all library version. With wolfSSL having only one set of error codes the
433
 * return value is pretty straight forward. The only thing needed is all wolfSSL
434
 * error values are typically negative.
435
 *
436
 * Returns the error reason
437
 */
438
int wolfSSL_ERR_GET_REASON(unsigned long err)
439
{
440
    int ret = (int)err;
441
442
    WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
443
444
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
445
    /* Nginx looks for this error to know to stop parsing certificates.
446
     * Same for HAProxy. */
447
    if ((err == (unsigned long)((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE)) ||
448
        ((err & 0xFFFFFFL) ==
449
            (unsigned long)(-WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))) ||
450
        ((err & 0xFFFL) == (unsigned long)PEM_R_NO_START_LINE))
451
        return PEM_R_NO_START_LINE;
452
    if (err == (unsigned long)((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
453
        return SSL_R_HTTP_REQUEST;
454
#endif
455
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
456
    if (err == (unsigned long)((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
457
        return ASN1_R_HEADER_TOO_LONG;
458
#endif
459
460
    /* check if error value is in range of wolfCrypt or wolfSSL errors */
461
    ret = 0 - ret; /* setting as negative value */
462
463
    if ((ret <= WC_SPAN1_FIRST_E && ret >= WC_SPAN1_LAST_E) ||
464
        (ret <= WC_SPAN2_FIRST_E && ret >= WC_SPAN2_LAST_E) ||
465
        (ret <= WOLFSSL_FIRST_E && ret >= WOLFSSL_LAST_E))
466
    {
467
        /* Every protocol-version mismatch is reported internally as
468
         * VERSION_ERROR, while the SSL_R_* version reasons carry real
469
         * OpenSSL values so that consumers can use them as distinct
470
         * switch cases; translate so that ERR_GET_REASON() comparisons
471
         * against SSL_R_WRONG_VERSION_NUMBER keep matching. */
472
        if (ret == WC_NO_ERR_TRACE(VERSION_ERROR))
473
            return WOLFSSL_SSL_R_WRONG_VERSION_NUMBER;
474
        return ret;
475
    }
476
    else {
477
        WOLFSSL_MSG("Not in range of typical error values");
478
        ret = (int)err;
479
    }
480
481
    return ret;
482
}
483
484
#if !defined(NETOS)
485
/* Load the SSL error strings.
486
 *
487
 * Error strings are handled internally. For OpenSSL compatibility only.
488
 */
489
void wolfSSL_ERR_load_SSL_strings(void)
490
{
491
492
}
493
#endif
494
495
/* Get the last error value from the error queue with its file and line
496
 * without removing it.
497
 *
498
 * @param [out] file  Name of file error occurred in.
499
 * @param [out] line  Line number error occurred on.
500
 * @return  Error value on success.
501
 * @return  0 when there are no entries in the queue.
502
 * @return  0 when there is no error queue.
503
 */
504
unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
505
{
506
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
507
508
    (void)line;
509
    (void)file;
510
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
511
    {
512
        int ret;
513
514
        if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
515
            WOLFSSL_MSG("Issue peeking at error node in queue");
516
            return 0;
517
        }
518
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) \
519
        || defined(WOLFSSL_HAPROXY)
520
        if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
521
            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
522
    #endif
523
    #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
524
        if (ret == ASN1_R_HEADER_TOO_LONG) {
525
            return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
526
        }
527
    #endif
528
        return (unsigned long)ret;
529
    }
530
#else
531
    return 0;
532
#endif
533
}
534
#endif
535
536
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
537
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
538
     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
539
     defined(WOLFSSL_OPENSSH)))
540
/* Remove the error queue entries of a thread.
541
 *
542
 * Not implemented. For OpenSSL compatibility only.
543
 *
544
 * @param [in] pid  Thread identifier. Not used.
545
 */
546
void wolfSSL_ERR_remove_thread_state(void* pid)
547
{
548
    (void) pid;
549
    return;
550
}
551
#endif
552
553
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
554
/* Load the ERR error strings.
555
 *
556
 * Error strings are handled internally. For OpenSSL compatibility only.
557
 *
558
 * @return  WOLFSSL_SUCCESS always.
559
 */
560
int wolfSSL_ERR_load_ERR_strings(void)
561
{
562
    return WOLFSSL_SUCCESS;
563
}
564
565
/* Load the crypto error strings.
566
 *
567
 * Error strings are handled internally. For OpenSSL compatibility only.
568
 */
569
void wolfSSL_ERR_load_crypto_strings(void)
570
{
571
    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
572
    /* Do nothing */
573
    return;
574
}
575
576
#ifndef NO_BIO
577
/* Load the BIO error strings.
578
 *
579
 * Error strings are handled internally. For OpenSSL compatibility only.
580
 */
581
void wolfSSL_ERR_load_BIO_strings(void) {
582
    WOLFSSL_ENTER("wolfSSL_ERR_load_BIO_strings");
583
    /* do nothing */
584
}
585
#endif
586
#endif
587
588
#if defined(OPENSSL_EXTRA)
589
/* Get the last error value from the error queue without removing it.
590
 *
591
 * Some error values are mapped to the OpenSSL equivalent.
592
 *
593
 * @return  Error value on success.
594
 * @return  0 when there are no entries in the queue.
595
 * @return  0 when there is no error queue.
596
 */
597
unsigned long wolfSSL_ERR_peek_last_error(void)
598
{
599
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
600
601
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
602
    {
603
        int ret;
604
605
        if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
606
            WOLFSSL_MSG("Issue peeking at error node in queue");
607
            return 0;
608
        }
609
        if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
610
            return (WOLFSSL_ERR_LIB_PEM << 24) |
611
                -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
612
    #if defined(WOLFSSL_PYTHON)
613
        if (ret == ASN1_R_HEADER_TOO_LONG)
614
            return (WOLFSSL_ERR_LIB_ASN1 << 24) |
615
                -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
616
    #endif
617
        return (unsigned long)ret;
618
    }
619
#else
620
    return 0;
621
#endif
622
}
623
624
/* Determine whether an error value is to be ignored when peeking.
625
 *
626
 * @param [in] err  Error value.
627
 * @return  1 when the error is to be ignored.
628
 * @return  0 otherwise.
629
 */
630
static int peek_ignore_err(int err)
631
{
632
  switch(err) {
633
    case -WC_NO_ERR_TRACE(WANT_READ):
634
    case -WC_NO_ERR_TRACE(WANT_WRITE):
635
    case -WC_NO_ERR_TRACE(ZERO_RETURN):
636
    case -WOLFSSL_ERROR_ZERO_RETURN:
637
    case -WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E):
638
    case -WC_NO_ERR_TRACE(SOCKET_ERROR_E):
639
      return 1;
640
    default:
641
      return 0;
642
  }
643
}
644
645
/* Get the last error value from the error queue with its data without
646
 * removing it.
647
 *
648
 * Errors that are not real errors, such as WANT_READ, are skipped.
649
 *
650
 * @param [out] file   Name of file error occurred in.
651
 * @param [out] line   Line number error occurred on.
652
 * @param [out] data   Error data. Always set to "" when not NULL.
653
 * @param [out] flags  Format of data. Always set to WOLFSSL_ERR_TXT_STRING
654
 *                     when not NULL.
655
 * @return  Error value on success.
656
 * @return  0 when there are no entries in the queue.
657
 */
658
unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
659
                                               const char **data, int *flags)
660
{
661
  unsigned long err;
662
663
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
664
    err = wc_PeekErrorNodeLineData(file, line, data, flags, peek_ignore_err);
665
666
    if (err == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER))
667
        return (WOLFSSL_ERR_LIB_PEM << 24) |
668
            -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E);
669
#ifdef OPENSSL_ALL
670
    /* PARSE_ERROR is returned if an HTTP request is detected. */
671
    else if (err == -WC_NO_ERR_TRACE(PARSE_ERROR))
672
        /* SSL_R_HTTP_REQUEST */
673
        return (WOLFSSL_ERR_LIB_SSL << 24) | -WC_NO_ERR_TRACE(PARSE_ERROR);
674
#endif
675
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
676
    else if (err == ASN1_R_HEADER_TOO_LONG)
677
        return (WOLFSSL_ERR_LIB_ASN1 << 24) |
678
            -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E);
679
#endif
680
  return err;
681
}
682
683
/* Remove the error queue entries of a thread.
684
 *
685
 * All entries of the current thread's queue are removed, not just those of the
686
 * given thread.
687
 *
688
 * @param [in] id  Thread identifier. Not used.
689
 */
690
void wolfSSL_ERR_remove_state(unsigned long id)
691
{
692
    WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
693
    (void)id;
694
    if (wc_ERR_remove_state() != 0) {
695
        WOLFSSL_MSG("Error with removing the state");
696
    }
697
}
698
#endif
699
700
#endif /* !WOLFCRYPT_ONLY */
701
702
#endif /* !WOLFSSL_SSL_ERR_INCLUDED */