Coverage Report

Created: 2026-09-27 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/src/ssl.c
Line
Count
Source
1
/* ssl.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(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(_GNU_SOURCE)
25
    /* turn on GNU extensions for XISASCII */
26
    #define _GNU_SOURCE 1
27
#endif
28
29
#if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) || \
30
    defined(OPENSSL_EXTRA_X509_SMALL)
31
32
#include <wolfssl/internal.h>
33
#include <wolfssl/error-ssl.h>
34
#include <wolfssl/wolfcrypt/error-crypt.h>
35
#include <wolfssl/wolfcrypt/coding.h>
36
#include <wolfssl/wolfcrypt/kdf.h>
37
#ifdef NO_INLINE
38
    #include <wolfssl/wolfcrypt/misc.h>
39
#else
40
    #define WOLFSSL_MISC_INCLUDED
41
    #include <wolfcrypt/src/misc.c>
42
#endif
43
44
#ifdef HAVE_ERRNO_H
45
    #include <errno.h>
46
#endif
47
48
49
#if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
50
    #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
51
                && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
52
                && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \
53
                && (!defined(WOLFSSL_TLS13) \
54
                    || !defined(WOLFSSL_HAVE_MLKEM_CLIENT_SUPPORT) \
55
                    || defined(WOLFSSL_TLS_NO_MLKEM_STANDALONE))
56
        #error "No cipher suites defined because DH disabled, ECC disabled, " \
57
               "and no static suites defined. Please see top of README"
58
    #endif
59
    #ifdef WOLFSSL_CERT_GEN
60
        /* need access to Cert struct for creating certificate */
61
        #include <wolfssl/wolfcrypt/asn_public.h>
62
    #endif
63
#endif
64
65
#if !defined(WOLFCRYPT_ONLY) && (defined(OPENSSL_EXTRA)     \
66
    || defined(OPENSSL_EXTRA_X509_SMALL)                    \
67
    || defined(HAVE_WEBSERVER) || defined(WOLFSSL_KEY_GEN))
68
    #include <wolfssl/openssl/evp.h>
69
    /* ed25519 compat helpers (wolfSSL_ED25519_new/free) are used by the X509
70
     * Ed25519 paths, which also build under OPENSSL_EXTRA_X509_SMALL. */
71
    #include <wolfssl/openssl/ed25519.h>
72
    /* openssl headers end, wolfssl internal headers next */
73
#endif
74
75
#include <wolfssl/wolfcrypt/wc_encrypt.h>
76
77
#ifndef NO_RSA
78
    #include <wolfssl/wolfcrypt/rsa.h>
79
#endif
80
81
#ifdef OPENSSL_EXTRA
82
    /* openssl headers begin */
83
    #include <wolfssl/openssl/ssl.h>
84
    #include <wolfssl/openssl/aes.h>
85
#ifndef WOLFCRYPT_ONLY
86
    #include <wolfssl/openssl/hmac.h>
87
    #include <wolfssl/openssl/cmac.h>
88
#endif
89
    #include <wolfssl/openssl/crypto.h>
90
    #include <wolfssl/openssl/des.h>
91
    #include <wolfssl/openssl/bn.h>
92
    #include <wolfssl/openssl/buffer.h>
93
    #include <wolfssl/openssl/dh.h>
94
    #include <wolfssl/openssl/rsa.h>
95
    #include <wolfssl/openssl/fips_rand.h>
96
    #include <wolfssl/openssl/pem.h>
97
    #include <wolfssl/openssl/ec.h>
98
    #include <wolfssl/openssl/ec25519.h>
99
    #include <wolfssl/openssl/ec448.h>
100
    #include <wolfssl/openssl/ed448.h>
101
    #include <wolfssl/openssl/ecdsa.h>
102
    #include <wolfssl/openssl/ecdh.h>
103
    #include <wolfssl/openssl/err.h>
104
    #include <wolfssl/openssl/modes.h>
105
    #include <wolfssl/openssl/opensslv.h>
106
    #include <wolfssl/openssl/rc4.h>
107
    #include <wolfssl/openssl/stack.h>
108
    #include <wolfssl/openssl/x509_vfy.h>
109
    /* openssl headers end, wolfssl internal headers next */
110
    #include <wolfssl/wolfcrypt/hmac.h>
111
    #include <wolfssl/wolfcrypt/random.h>
112
    #include <wolfssl/wolfcrypt/des3.h>
113
    #include <wolfssl/wolfcrypt/ecc.h>
114
    #include <wolfssl/wolfcrypt/md4.h>
115
    #include <wolfssl/wolfcrypt/md5.h>
116
    #include <wolfssl/wolfcrypt/arc4.h>
117
    #include <wolfssl/wolfcrypt/curve25519.h>
118
    #include <wolfssl/wolfcrypt/ed25519.h>
119
    #include <wolfssl/wolfcrypt/curve448.h>
120
    #if defined(HAVE_FALCON)
121
        #include <wolfssl/wolfcrypt/falcon.h>
122
    #endif /* HAVE_FALCON */
123
    #if defined(WOLFSSL_HAVE_MLDSA)
124
        #include <wolfssl/wolfcrypt/wc_mldsa.h>
125
    #endif /* WOLFSSL_HAVE_MLDSA */
126
    #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
127
        #ifdef HAVE_OCSP
128
            #include <wolfssl/openssl/ocsp.h>
129
        #endif
130
        #include <wolfssl/openssl/lhash.h>
131
        #include <wolfssl/openssl/txt_db.h>
132
    #endif /* WITH_STUNNEL */
133
    #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
134
        #include <wolfssl/wolfcrypt/sha512.h>
135
    #endif
136
    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
137
        && !defined(WC_NO_RNG)
138
        #include <wolfssl/wolfcrypt/srp.h>
139
    #endif
140
#endif
141
142
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
143
    #include <wolfssl/openssl/x509v3.h>
144
    int wolfssl_bn_get_value(WOLFSSL_BIGNUM* bn, mp_int* mpi);
145
    int wolfssl_bn_set_value(WOLFSSL_BIGNUM** bn, mp_int* mpi);
146
#endif
147
148
#if defined(WOLFSSL_QT)
149
    #include <wolfssl/wolfcrypt/sha.h>
150
#endif
151
152
#ifdef NO_ASN
153
    #include <wolfssl/wolfcrypt/dh.h>
154
#endif
155
#endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
156
157
#if !defined(WOLFCRYPT_ONLY) && defined(WOLFSSL_SYS_CRYPTO_POLICY)
158
/* The system wide crypto-policy. Configured by wolfSSL_crypto_policy_enable.
159
 * */
160
static struct SystemCryptoPolicy crypto_policy;
161
#endif /* !WOLFCRYPT_ONLY && WOLFSSL_SYS_CRYPTO_POLICY */
162
163
/*
164
 * ssl.c Build Options:
165
 *
166
 * See also: tls.c for TLS extension/protocol options, tls13.c for TLS 1.3,
167
 *           internal.c for handshake internals, wc_port.c for platform/memory.
168
 *
169
 * OpenSSL Compatibility:
170
 * OPENSSL_EXTRA:              Enable OpenSSL compatibility API        default: off
171
 * OPENSSL_ALL:                Enable all OpenSSL compat APIs          default: off
172
 * OPENSSL_EXTRA_X509_SMALL:   Minimal OpenSSL X509 compat APIs       default: off
173
 * OPENSSL_EXTRA_NO_ASN1:      OpenSSL extra without ASN1 objects      default: off
174
 * OPENSSL_COMPATIBLE_DEFAULTS:
175
 *                  Default behavior compatible with OpenSSL           default: off
176
 * NO_WOLFSSL_STUB:            Disable stubs for unimplemented funcs   default: off
177
 * WOLFSSL_DEBUG_OPENSSL:
178
 *                  Alias for WOLFSSL_VERBOSE_LOGGING                  default: off
179
 * WOLFSSL_HAVE_ERROR_QUEUE:   OpenSSL-compatible error queue          default: off
180
 * WOLFSSL_ERROR_CODE_OPENSSL: Use OpenSSL-compatible error codes      default: off
181
 * WOLFSSL_CIPHER_INTERNALNAME:
182
 *                  Use wolfSSL internal cipher suite names             default: off
183
 * NO_CIPHER_SUITE_ALIASES:    Disable cipher suite name aliases       default: off
184
 * WOLFSSL_SET_CIPHER_BYTES:   Set cipher suites by raw byte values    default: off
185
 * WOLFSSL_OLD_SET_CURVES_LIST:
186
 *                  Old-style curve list parsing for compat             default: off
187
 * WOLFSSL_NO_OPENSSL_RAND_CB: Disable OpenSSL RAND callback compat   default: off
188
 * NO_ERROR_STRINGS:           Disable human-readable error strings    default: off
189
 * WOLFSSL_PUBLIC_ASN:         Make ASN parsing functions public        default: off
190
 *
191
 * Extra Data / BIO:
192
 * HAVE_EX_DATA:               Enable ex_data on SSL/CTX/X509 objects  default: off
193
 * HAVE_EX_DATA_CLEANUP_HOOKS: Cleanup callbacks for ex_data           default: off
194
 * HAVE_EX_DATA_CRYPTO:        ex_data support for wolfCrypt objects   default: off
195
 * MAX_EX_DATA:                Max ex_data entries per object           default: 5
196
 * NO_BIO:                     Disable BIO abstraction layer           default: off
197
 *
198
 * Session & Cache:
199
 * NO_SESSION_CACHE:           Disable server session cache            default: off
200
 * NO_SESSION_CACHE_REF:       wolfSSL_get_session returns ssl->session
201
 *                             reference instead of ClientCache ref    default: off
202
 * SESSION_CACHE_DYNAMIC_MEM:  Dynamically allocate session cache      default: off
203
 * NO_CLIENT_CACHE:            Disable client-side session cache       default: off
204
 * SESSION_CERTS:              Store full cert chain in session         default: off
205
 * WOLFSSL_SESSION_ID_CTX:     Session ID context for cache sharing    default: off
206
 *
207
 * I/O & Transport:
208
 * USE_WOLFSSL_IO:             Use built-in I/O callbacks              default: on
209
 * WOLFSSL_USER_IO:            Application provides custom I/O         default: off
210
 * WOLFSSL_NO_SOCK:            Build without socket support            default: off
211
 * NO_WRITEV:                  Disable writev() scatter/gather I/O     default: off
212
 * WOLFSSL_DTLS_MTU:           Enable DTLS MTU management APIs         default: off
213
 * WOLFSSL_DTLS_DROP_STATS:    Track DTLS packet drop statistics       default: off
214
 * WOLFSSL_MULTICAST:          Enable DTLS multicast support           default: off
215
 *
216
 * Callbacks & Features:
217
 * WOLFSSL_CHECK_ALERT_ON_ERR: Check alerts on handshake error         default: off
218
 * ATOMIC_USER:                User-defined record layer callbacks      default: off
219
 * HAVE_WRITE_DUP:             Separate threads for SSL read/write     default: off
220
 * WOLFSSL_CALLBACKS:          Handshake monitoring callbacks           default: off
221
 * NO_HANDSHAKE_DONE_CB:       Disable handshake completion callback   default: off
222
 * WOLFSSL_SHUTDOWNONCE:       Send close_notify only once             default: off
223
 * WOLFSSL_COPY_CERT:          Copy certificate buffer (own copy)      default: off
224
 * WOLFSSL_COPY_KEY:           Copy private key buffer (own copy)      default: off
225
 * WOLF_PRIVATE_KEY_ID:        Reference private keys by ID            default: off
226
 * WOLFSSL_REFCNT_ERROR_RETURN:
227
 *                  Return errors on ref counting failures             default: off
228
 * WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST:
229
 *                  Allow runtime max fragment size adjustment          default: off
230
 * WOLFSSL_ALLOW_NO_SUITES:    Allow SSL objects with no cipher suites default: off
231
 *
232
 * Certificates & Keys:
233
 * KEEP_PEER_CERT:             Keep peer cert after handshake          default: off
234
 * KEEP_OUR_CERT:              Keep our cert after handshake           default: off
235
 * WOLFSSL_STATIC_RSA:         Enable static RSA key exchange          default: off
236
 * WOLFSSL_HAVE_CERT_SERVICE:  Certificate service callbacks           default: off
237
 * WOLFSSL_SYS_CA_CERTS:       Load system CA certs from OS            default: off
238
 *
239
 * Application Compatibility:
240
 * HAVE_CURL:                  APIs for libcurl compatibility          default: off
241
 * HAVE_LIGHTY:                APIs for lighttpd compatibility         default: off
242
 * HAVE_MEMCACHED:             APIs for memcached compatibility        default: off
243
 * WOLFSSL_APACHE_HTTPD:       APIs for Apache httpd compatibility     default: off
244
 * WOLFSSL_NGINX:              APIs for nginx compatibility            default: off
245
 * WOLFSSL_HAPROXY:            APIs for HAProxy compatibility          default: off
246
 * WOLFSSL_ASIO:               APIs for Boost.Asio compatibility       default: off
247
 * WOLFSSL_PYTHON:             APIs for Python module compatibility    default: off
248
 * WOLFSSL_QT:                 APIs for Qt framework compatibility     default: off
249
 * WOLFSSL_JNI:                APIs for Java JNI/JSSE compatibility    default: off
250
 *
251
 * Protocol Features:
252
 * WOLFSSL_HAVE_WOLFSCEP:      Enable wolfSCEP protocol support        default: off
253
 * WOLFCRYPT_HAVE_SRP:         Enable SRP protocol support             default: off
254
 * HAVE_LIBZ:                  Enable zlib TLS compression             default: off
255
 * WOLFSSL_EXTRA:              Extra SSL session info APIs              default: off
256
 * WOLFSSL_WPAS_SMALL:         Minimal wpa_supplicant/hostapd APIs     default: off
257
 * HAVE_FUZZER:                Fuzzing callback support                 default: off
258
 *
259
 * Memory & Threading:
260
 * WOLFSSL_STATIC_MEMORY_LEAN: Lean static memory allocation           default: off
261
 * WOLFSSL_THREADED_CRYPT:     Multi-threaded crypto operations         default: off
262
 * WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS:
263
 *                  Thread-safe cleanup via atomics                     default: off
264
 * WOLFSSL_ATOMIC_INITIALIZER: Static init for atomic variables        default: off
265
 * WOLFSSL_DEBUG_MEMORY:       Log malloc/free with file/line info     default: off
266
 * WOLFSSL_NO_REALLOC:         Disable realloc, use malloc+copy+free   default: off
267
 * WOLFSSL_HEAP_TEST:          Heap-related testing utilities           default: off
268
 *
269
 * Debugging & Build:
270
 * SHOW_SIZES:                 Display struct sizes at init             default: off
271
 * WOLFSSL_DEBUG_TRACE_ERROR_CODES:
272
 *                  Trace error code origins for debugging              default: off
273
 * HAVE_ATEXIT:                Register wolfSSL_Cleanup via atexit     default: off
274
 * WOLFSSL_SYS_CRYPTO_POLICY:  Honor system crypto policy settings     default: off
275
 *
276
 * Hardware TLS:
277
 * WOLFSSL_RENESAS_TSIP_TLS:   Renesas TSIP hardware crypto for TLS   default: off
278
 * WOLFSSL_RENESAS_FSPSM_TLS:  Renesas FSP Security Module for TLS    default: off
279
 * WOLFSSL_EGD_NBLOCK:         Non-blocking EGD entropy support        default: off
280
 */
281
282
#ifndef WOLFCRYPT_ONLY
283
284
#if !defined(NO_RSA) || !defined(NO_DH) || defined(HAVE_ECC) || \
285
    (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && !defined(NO_DSA))
286
287
#define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
288
static WC_RNG globalRNG;
289
static volatile int initGlobalRNG = 0;
290
291
#if defined(OPENSSL_EXTRA) || !defined(WOLFSSL_MUTEX_INITIALIZER)
292
static WC_MAYBE_UNUSED wolfSSL_Mutex globalRNGMutex
293
    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(globalRNGMutex);
294
#endif
295
#ifndef WOLFSSL_MUTEX_INITIALIZER
296
static int globalRNGMutex_valid = 0;
297
#endif
298
299
#if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
300
static WOLFSSL_DRBG_CTX* gDrbgDefCtx = NULL;
301
#endif
302
303
WC_RNG* wolfssl_get_global_rng(void)
304
0
{
305
0
    WC_RNG* ret = NULL;
306
307
0
    if (initGlobalRNG == 0)
308
0
        WOLFSSL_MSG("Global RNG no Init");
309
0
    else
310
0
        ret = &globalRNG;
311
312
0
    return ret;
313
0
}
314
315
/* Make a global RNG and return.
316
 *
317
 * @return  Global RNG on success.
318
 * @return  NULL on error.
319
 */
320
WC_RNG* wolfssl_make_global_rng(void)
321
0
{
322
0
    WC_RNG* ret;
323
324
0
#ifdef HAVE_GLOBAL_RNG
325
    /* Get the global random number generator instead. */
326
0
    ret = wolfssl_get_global_rng();
327
#ifdef OPENSSL_EXTRA
328
    if (ret == NULL) {
329
        /* Create a global random if possible. */
330
        (void)wolfSSL_RAND_Init();
331
        ret = wolfssl_get_global_rng();
332
    }
333
#endif
334
#else
335
    WOLFSSL_ERROR_MSG("Bad RNG Init");
336
    ret = NULL;
337
#endif
338
339
0
    return ret;
340
0
}
341
342
/* Too many defines to check explicitly - prototype it and always include
343
 * for RSA, DH, ECC and DSA for BN. */
344
WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local);
345
346
/* Make a random number generator or get global if possible.
347
 *
348
 * Global may not be available and NULL will be returned.
349
 *
350
 * @param [in, out] rng    Local random number generator.
351
 * @param [out]     local  Local random number generator returned.
352
 * @return  NULL on failure.
353
 * @return  A random number generator object.
354
 */
355
WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local)
356
0
{
357
0
    WC_RNG* ret = NULL;
358
#ifdef WOLFSSL_SMALL_STACK
359
    int freeRng = 0;
360
361
    /* Allocate RNG object . */
362
    if (rng == NULL) {
363
        rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
364
        freeRng = 1;
365
    }
366
#endif
367
368
0
    if (rng != NULL) {
369
0
        if (wc_InitRng(rng) == 0) {
370
0
            ret = rng;
371
0
            *local = 1;
372
0
        }
373
0
        else {
374
0
            WOLFSSL_MSG("Bad RNG Init");
375
#ifdef WOLFSSL_SMALL_STACK
376
            if (freeRng) {
377
                XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
378
                rng = NULL;
379
            }
380
#endif
381
0
        }
382
0
    }
383
0
    if (ret == NULL) {
384
0
#ifdef HAVE_GLOBAL_RNG
385
0
        WOLFSSL_MSG("trying global RNG");
386
0
#endif
387
0
        ret = wolfssl_make_global_rng();
388
0
    }
389
390
0
    return ret;
391
0
}
392
#endif
393
394
#ifdef OPENSSL_EXTRA
395
    /* WOLFSSL_NO_OPENSSL_RAND_CB: Allows way to reduce code size for
396
     *                OPENSSL_EXTRA where RAND callbacks are not used */
397
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
398
        static const WOLFSSL_RAND_METHOD* gRandMethods = NULL;
399
        static wolfSSL_Mutex gRandMethodMutex
400
            WOLFSSL_MUTEX_INITIALIZER_CLAUSE(gRandMethodMutex);
401
        #ifndef WOLFSSL_MUTEX_INITIALIZER
402
        static int gRandMethodsInit = 0;
403
        #endif
404
    #endif /* !WOLFSSL_NO_OPENSSL_RAND_CB */
405
#endif /* OPENSSL_EXTRA */
406
407
#endif /* !WOLFCRYPT_ONLY */
408
409
#define WOLFSSL_SSL_MISC_INCLUDED
410
#include "src/ssl_misc.c"
411
412
#define WOLFSSL_EVP_INCLUDED
413
#include "wolfcrypt/src/evp.c"
414
415
/* Crypto code uses EVP APIs. */
416
#define WOLFSSL_SSL_CRYPTO_INCLUDED
417
#include "src/ssl_crypto.c"
418
419
#ifndef WOLFCRYPT_ONLY
420
#define WOLFSSL_SSL_CERTMAN_INCLUDED
421
#include "src/ssl_certman.c"
422
423
#define WOLFSSL_SSL_SESS_INCLUDED
424
#include "src/ssl_sess.c"
425
426
/* Forward declarations for static functions that are defined in a file
427
 * included later in this amalgamation but used by one included earlier. Keep
428
 * them here, next to the includes, rather than inside the files that need
429
 * them.
430
 *
431
 * x509GetIssuerFromCM() is defined in src/x509_str.c, which also requires
432
 * NO_CERTS to be undefined. */
433
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
434
static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
435
        WOLFSSL_X509 *x);
436
#endif
437
438
#define WOLFSSL_SSL_API_CERT_INCLUDED
439
#include "src/ssl_api_cert.c"
440
441
#define WOLFSSL_SSL_API_PK_INCLUDED
442
#include "src/ssl_api_pk.c"
443
#endif
444
445
446
#ifndef WOLFCRYPT_ONLY
447
448
449
450
#define WOLFSSL_SSL_BN_INCLUDED
451
#include "src/ssl_bn.c"
452
453
#define WOLFSSL_SSL_ASN1_INCLUDED
454
#include "src/ssl_asn1.c"
455
456
#define WOLFSSL_SSL_TSP_INCLUDED
457
#include "src/ssl_tsp.c"
458
459
#define WOLFSSL_PK_INCLUDED
460
#include "src/pk.c"
461
462
#define WOLFSSL_EVP_PK_INCLUDED
463
#include "wolfcrypt/src/evp_pk.c"
464
465
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
466
/* copies over data of "in" to "out" */
467
static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out)
468
{
469
    if (in == NULL || out == NULL)
470
        return;
471
472
    *out = *in;
473
}
474
475
476
#if defined(OPENSSL_ALL)
477
static WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_dup(WOLFSSL_X509_OBJECT* obj)
478
{
479
    WOLFSSL_X509_OBJECT* ret = NULL;
480
    if (obj) {
481
        ret = wolfSSL_X509_OBJECT_new();
482
        if (ret) {
483
            ret->type = obj->type;
484
            switch (ret->type) {
485
                case WOLFSSL_X509_LU_NONE:
486
                    break;
487
                case WOLFSSL_X509_LU_X509:
488
                    ret->data.x509 = wolfSSL_X509_dup(obj->data.x509);
489
                    break;
490
                case WOLFSSL_X509_LU_CRL:
491
            #if defined(HAVE_CRL)
492
                    ret->data.crl = wolfSSL_X509_CRL_dup(obj->data.crl);
493
            #endif
494
                    break;
495
            }
496
        }
497
    }
498
    return ret;
499
}
500
#endif /* OPENSSL_ALL */
501
502
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
503
504
#define WOLFSSL_SSL_SK_INCLUDED
505
#include "src/ssl_sk.c"
506
507
508
#include <wolfssl/wolfcrypt/hpke.h>
509
510
#define WOLFSSL_SSL_ECH_INCLUDED
511
#include "src/ssl_ech.c"
512
513
#ifdef OPENSSL_EXTRA
514
static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
515
        Suites* suites, const char* list);
516
#endif
517
518
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
519
#include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
520
#endif
521
522
/* prevent multiple mutex initializations */
523
524
/* note, initRefCount is not used for thread synchronization, only for
525
 * bookkeeping while inits_count_mutex is held.
526
 */
527
static volatile WC_THREADSHARED int initRefCount = 0;
528
529
/* init ref count mutex */
530
static WC_THREADSHARED wolfSSL_Mutex inits_count_mutex
531
    WOLFSSL_MUTEX_INITIALIZER_CLAUSE(inits_count_mutex);
532
#ifndef WOLFSSL_MUTEX_INITIALIZER
533
static WC_THREADSHARED volatile int inits_count_mutex_valid = 0;
534
#endif
535
536
#ifdef NO_TLS
537
static const WOLFSSL_METHOD gNoTlsMethod;
538
#endif
539
540
/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
541
   WOLFSSL_METHOD pointer passed in is given to ctx to manage.
542
   This function frees the passed in WOLFSSL_METHOD struct on failure and on
543
   success is freed when ctx is freed.
544
 */
545
WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
546
0
{
547
0
    WOLFSSL_CTX* ctx = NULL;
548
549
0
    WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
550
551
0
    if (initRefCount == 0) {
552
        /* user no longer forced to call Init themselves */
553
0
        int ret = wolfSSL_Init();
554
0
        if (ret != WOLFSSL_SUCCESS) {
555
0
            WOLFSSL_MSG("wolfSSL_Init failed");
556
0
            WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
557
0
            XFREE(method, heap, DYNAMIC_TYPE_METHOD);
558
0
            return NULL;
559
0
        }
560
0
    }
561
562
0
#ifndef NO_TLS
563
0
    if (method == NULL)
564
0
        return ctx;
565
#else
566
    /* a blank TLS method */
567
    method = (WOLFSSL_METHOD*)&gNoTlsMethod;
568
#endif
569
570
0
    ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
571
0
    if (ctx) {
572
0
        int ret;
573
574
0
        ret = InitSSL_Ctx(ctx, method, heap);
575
    #ifdef WOLFSSL_STATIC_MEMORY
576
        if (heap != NULL) {
577
            ctx->onHeapHint = 1; /* free the memory back to heap when done */
578
        }
579
    #endif
580
0
        if (ret < 0) {
581
0
            WOLFSSL_MSG("Init CTX failed");
582
0
            wolfSSL_CTX_free(ctx);
583
0
            ctx = NULL;
584
0
        }
585
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
586
                           && !defined(NO_SHA256) && !defined(WC_NO_RNG)
587
        else {
588
            ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
589
            if (ctx->srp == NULL){
590
                WOLFSSL_MSG("Init CTX failed");
591
                wolfSSL_CTX_free(ctx);
592
                return NULL;
593
            }
594
            XMEMSET(ctx->srp, 0, sizeof(Srp));
595
        }
596
#endif
597
0
    }
598
0
    else {
599
0
        WOLFSSL_MSG("Alloc CTX failed, method freed");
600
0
        XFREE(method, heap, DYNAMIC_TYPE_METHOD);
601
0
    }
602
603
#ifdef OPENSSL_COMPATIBLE_DEFAULTS
604
    if (ctx) {
605
        wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
606
        wolfSSL_CTX_set_mode(ctx, WOLFSSL_MODE_AUTO_RETRY);
607
        if (wolfSSL_CTX_set_min_proto_version(ctx,
608
                (method->version.major == DTLS_MAJOR) ?
609
                DTLS1_VERSION : SSL3_VERSION) != WOLFSSL_SUCCESS ||
610
#ifdef HAVE_ANON
611
                wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS ||
612
#endif
613
                wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS) {
614
            WOLFSSL_MSG("Setting OpenSSL CTX defaults failed");
615
            wolfSSL_CTX_free(ctx);
616
            ctx = NULL;
617
        }
618
        else {
619
            /* a default, not a minimum the user asked for */
620
            ctx->minVersionSet = 0;
621
        }
622
    }
623
#endif
624
625
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
626
    /* Load the crypto-policy ciphers if configured. */
627
    if (ctx && wolfSSL_crypto_policy_is_enabled()) {
628
        const char * list = wolfSSL_crypto_policy_get_ciphers();
629
        int          ret = 0;
630
631
        if (list != NULL && *list != '\0') {
632
            if (AllocateCtxSuites(ctx) != 0) {
633
                WOLFSSL_MSG("allocate ctx suites failed");
634
                wolfSSL_CTX_free(ctx);
635
                ctx = NULL;
636
            }
637
            else {
638
                ret = wolfSSL_parse_cipher_list(ctx, NULL, ctx->suites, list);
639
                if (ret != WOLFSSL_SUCCESS) {
640
                    WOLFSSL_MSG("parse cipher list failed");
641
                    wolfSSL_CTX_free(ctx);
642
                    ctx = NULL;
643
                }
644
            }
645
        }
646
    }
647
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
648
649
0
    WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
650
0
    return ctx;
651
0
}
652
653
654
WOLFSSL_ABI
655
WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
656
0
{
657
#ifdef WOLFSSL_HEAP_TEST
658
    /* if testing the heap hint then set top level CTX to have test value */
659
    return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
660
#else
661
0
    return wolfSSL_CTX_new_ex(method, NULL);
662
0
#endif
663
0
}
664
665
/* increases CTX reference count to track proper time to "free" */
666
int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
667
0
{
668
0
    int ret;
669
0
    wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
670
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
671
    return ((ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
672
#else
673
0
    (void)ret;
674
0
    return WOLFSSL_SUCCESS;
675
0
#endif
676
0
}
677
678
WOLFSSL_ABI
679
void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
680
0
{
681
0
    WOLFSSL_ENTER("wolfSSL_CTX_free");
682
0
    if (ctx) {
683
0
        FreeSSL_Ctx(ctx);
684
0
    }
685
686
0
    WOLFSSL_LEAVE("wolfSSL_CTX_free", 0);
687
0
}
688
689
690
#ifdef HAVE_ENCRYPT_THEN_MAC
691
/**
692
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
693
 * The default value: enabled.
694
 *
695
 * ctx  SSL/TLS context.
696
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
697
 * returns WOLFSSL_SUCCESS
698
 */
699
int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
700
0
{
701
0
    ctx->disallowEncThenMac = !set;
702
0
    return WOLFSSL_SUCCESS;
703
0
}
704
705
/**
706
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
707
 * The default value comes from context.
708
 *
709
 * ctx  SSL/TLS context.
710
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
711
 * returns WOLFSSL_SUCCESS
712
 */
713
int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
714
0
{
715
0
    ssl->options.disallowEncThenMac = !set;
716
0
    return WOLFSSL_SUCCESS;
717
0
}
718
#endif
719
720
#ifdef SINGLE_THREADED
721
/* no locking in single threaded mode, allow a CTX level rng to be shared with
722
 * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
723
int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
724
{
725
    WC_RNG* rng;
726
    int     ret;
727
728
    if (ctx == NULL) {
729
        return BAD_FUNC_ARG;
730
    }
731
732
    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
733
    if (rng == NULL) {
734
        return MEMORY_E;
735
    }
736
737
#ifndef HAVE_FIPS
738
    ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
739
#else
740
    ret = wc_InitRng(rng);
741
#endif
742
    if (ret != 0) {
743
        XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
744
        return ret;
745
    }
746
747
    ctx->rng = rng;
748
    return WOLFSSL_SUCCESS;
749
}
750
#endif
751
752
753
WOLFSSL_ABI
754
WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
755
0
{
756
0
    WOLFSSL* ssl = NULL;
757
0
    int ret = 0;
758
759
0
    WOLFSSL_ENTER("wolfSSL_new");
760
761
0
    if (ctx == NULL) {
762
0
        WOLFSSL_MSG("wolfSSL_new ctx is null");
763
0
        return NULL;
764
0
    }
765
766
0
    ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
767
768
0
    if (ssl == NULL) {
769
0
        WOLFSSL_MSG_EX("ssl xmalloc failed to allocate %d bytes",
770
0
                        (int)sizeof(WOLFSSL));
771
0
    }
772
0
    else {
773
0
        ret = InitSSL(ssl, ctx, 0);
774
0
        if (ret < 0) {
775
0
            WOLFSSL_MSG_EX("wolfSSL_new failed during InitSSL. err = %d", ret);
776
0
            FreeSSL(ssl, ctx->heap);
777
0
            ssl = NULL;
778
0
        }
779
0
        else if (ret == 0) {
780
0
            WOLFSSL_MSG("wolfSSL_new InitSSL success");
781
0
        }
782
0
        else {
783
            /* Only success (0) or negative values should ever be seen. */
784
0
            WOLFSSL_MSG_EX("WARNING: wolfSSL_new unexpected InitSSL return"
785
0
                           " value = %d", ret);
786
0
        } /* InitSSL check */
787
0
    } /* ssl XMALLOC success */
788
789
0
    WOLFSSL_LEAVE("wolfSSL_new InitSSL =", ret);
790
0
    (void)ret;
791
792
0
    return ssl;
793
0
}
794
795
796
WOLFSSL_ABI
797
void wolfSSL_free(WOLFSSL* ssl)
798
0
{
799
0
    WOLFSSL_ENTER("wolfSSL_free");
800
801
0
    if (ssl) {
802
0
        WOLFSSL_MSG_EX("Free SSL: %p", (wc_ptr_t)ssl);
803
0
        FreeSSL(ssl, ssl->ctx->heap);
804
0
    }
805
0
    else {
806
0
        WOLFSSL_MSG("Free SSL: wolfSSL_free already null");
807
0
    }
808
0
    WOLFSSL_LEAVE("wolfSSL_free", 0);
809
0
}
810
811
812
int wolfSSL_is_server(WOLFSSL* ssl)
813
0
{
814
0
    if (ssl == NULL)
815
0
        return BAD_FUNC_ARG;
816
0
    return ssl->options.side == WOLFSSL_SERVER_END;
817
0
}
818
819
#ifdef HAVE_WRITE_DUP
820
821
/*
822
 * Release resources around WriteDup object
823
 *
824
 * ssl WOLFSSL object
825
 *
826
 * no return, destruction so make best attempt
827
*/
828
void FreeWriteDup(WOLFSSL* ssl)
829
{
830
    int doFree = 0;
831
832
    WOLFSSL_ENTER("FreeWriteDup");
833
834
    if (ssl->dupWrite) {
835
        if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
836
            ssl->dupWrite->dupCount--;
837
            if (ssl->dupWrite->dupCount == 0) {
838
                doFree = 1;
839
            } else {
840
                WOLFSSL_MSG("WriteDup count not zero, no full free");
841
            }
842
            wc_UnLockMutex(&ssl->dupWrite->dupMutex);
843
        }
844
    }
845
846
    if (doFree) {
847
#ifdef WOLFSSL_DTLS13
848
        struct Dtls13RecordNumber* rn = ssl->dupWrite->sendAckList;
849
        while (rn != NULL) {
850
            struct Dtls13RecordNumber* next = rn->next;
851
            XFREE(rn, ssl->heap, DYNAMIC_TYPE_DTLS_MSG);
852
            rn = next;
853
        }
854
#endif
855
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
856
        Free_HS_Hashes(ssl->dupWrite->postHandshakeHashState, ssl->heap);
857
        Free_HS_Hashes(ssl->dupWrite->postHandshakeSyncedHashState, ssl->heap);
858
        {
859
            CertReqCtx* ctx = ssl->dupWrite->postHandshakeCertReqCtx;
860
            while (ctx != NULL) {
861
                CertReqCtx* nxt = ctx->next;
862
                XFREE(ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
863
                ctx = nxt;
864
            }
865
        }
866
#endif /* WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
867
        wc_FreeMutex(&ssl->dupWrite->dupMutex);
868
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
869
        ssl->dupWrite = NULL;
870
        WOLFSSL_MSG("Did WriteDup full free, count to zero");
871
    }
872
}
873
874
875
/*
876
 * duplicate existing ssl members into dup needed for writing
877
 *
878
 * dup write only WOLFSSL
879
 * ssl existing WOLFSSL
880
 *
881
 * 0 on success
882
*/
883
static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
884
{
885
    word16 tmp_weOwnRng;
886
#ifdef HAVE_ONE_TIME_AUTH
887
#ifdef HAVE_POLY1305
888
    Poly1305* tmp_poly1305 = NULL;
889
#endif
890
#endif
891
892
    /* shared dupWrite setup */
893
    ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
894
                                       DYNAMIC_TYPE_WRITEDUP);
895
    if (ssl->dupWrite == NULL) {
896
        return MEMORY_E;
897
    }
898
    XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
899
900
    if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
901
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
902
        ssl->dupWrite = NULL;
903
        return BAD_MUTEX_E;
904
    }
905
906
    /* Pre-allocate any objects that can fail BEFORE performing destructive
907
     * state mutations on ssl, so an allocation failure cannot leave ssl
908
     * with a zeroed encrypt context and a poisoned dupWrite.
909
     * dup->heap == ssl->heap here because dup was initialised with ssl->ctx;
910
     * use ssl->heap consistently for cleanup symmetry. */
911
#ifdef HAVE_ONE_TIME_AUTH
912
#ifdef HAVE_POLY1305
913
    if (ssl->auth.setup && ssl->auth.poly1305 != NULL) {
914
        tmp_poly1305 = (Poly1305*)XMALLOC(sizeof(Poly1305), ssl->heap,
915
            DYNAMIC_TYPE_CIPHER);
916
        if (tmp_poly1305 == NULL) {
917
            wc_FreeMutex(&ssl->dupWrite->dupMutex);
918
            XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
919
            ssl->dupWrite = NULL;
920
            return MEMORY_E;
921
        }
922
    }
923
#endif
924
#endif
925
926
    ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
927
    dup->dupWrite = ssl->dupWrite; /* each side uses */
928
929
    tmp_weOwnRng = dup->options.weOwnRng;
930
931
    /* copy write parts over to dup writer */
932
    XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
933
    XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
934
    XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
935
    XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
936
    XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion));
937
    XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion));
938
939
    /* dup side now owns encrypt/write ciphers */
940
    XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
941
942
#ifdef HAVE_ONE_TIME_AUTH
943
#ifdef HAVE_POLY1305
944
    if (tmp_poly1305 != NULL) {
945
        dup->auth.poly1305 = tmp_poly1305;
946
        dup->auth.setup = 1;
947
    }
948
#endif
949
#endif
950
951
#ifdef WOLFSSL_TLS13
952
    if (IsAtLeastTLSv1_3(ssl->version)) {
953
        /* Copy TLS 1.3 application traffic secrets so the write side can
954
         * derive updated keys when wolfSSL_update_keys() is called. */
955
        XMEMCPY(dup->clientSecret, ssl->clientSecret, SECRET_LEN);
956
        XMEMCPY(dup->serverSecret, ssl->serverSecret, SECRET_LEN);
957
958
#ifdef WOLFSSL_DTLS13
959
        if (ssl->options.dtls) {
960
            /* Copy epoch array (contains only value types -- safe to memcpy). */
961
            XMEMCPY(dup->dtls13Epochs, ssl->dtls13Epochs,
962
                    sizeof(ssl->dtls13Epochs));
963
964
            /* Re-point dtls13EncryptEpoch into dup's own epoch array. */
965
            if (ssl->dtls13EncryptEpoch != NULL) {
966
                dup->dtls13EncryptEpoch =
967
                    &dup->dtls13Epochs[ssl->dtls13EncryptEpoch -
968
                                       ssl->dtls13Epochs];
969
            }
970
971
            /* Copy current write epoch number. */
972
            dup->dtls13Epoch = ssl->dtls13Epoch;
973
974
            /* Transfer record-number encryption cipher ownership to dup. */
975
            XMEMCPY(&dup->dtlsRecordNumberEncrypt,
976
                    &ssl->dtlsRecordNumberEncrypt, sizeof(RecordNumberCiphers));
977
            XMEMSET(&ssl->dtlsRecordNumberEncrypt,
978
                    0, sizeof(RecordNumberCiphers));
979
        }
980
#endif /* WOLFSSL_DTLS13 */
981
    }
982
#endif /* WOLFSSL_TLS13 */
983
984
985
    dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
986
    dup->CBIOSend = ssl->CBIOSend;
987
#ifdef OPENSSL_EXTRA
988
    dup->cbioFlag = ssl->cbioFlag;
989
#endif
990
    dup->wfd    = ssl->wfd;
991
    dup->wflags = ssl->wflags;
992
#ifndef WOLFSSL_AEAD_ONLY
993
    dup->hmac   = ssl->hmac;
994
#endif
995
#ifdef HAVE_TRUNCATED_HMAC
996
    dup->truncated_hmac = ssl->truncated_hmac;
997
#endif
998
999
    /* Restore rng option */
1000
    dup->options.weOwnRng = tmp_weOwnRng;
1001
1002
    /* unique side dup setup */
1003
    dup->dupSide = WRITE_DUP_SIDE;
1004
    ssl->dupSide = READ_DUP_SIDE;
1005
1006
    return 0;
1007
}
1008
1009
1010
/*
1011
 * duplicate a WOLFSSL object post handshake for writing only
1012
 * turn existing object into read only.  Allows concurrent access from two
1013
 * different threads.
1014
 *
1015
 * ssl existing WOLFSSL object
1016
 *
1017
 * return dup'd WOLFSSL object on success
1018
*/
1019
WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
1020
{
1021
    WOLFSSL* dup = NULL;
1022
    int ret = 0;
1023
1024
    (void)ret;
1025
    WOLFSSL_ENTER("wolfSSL_write_dup");
1026
1027
    if (ssl == NULL) {
1028
        return ssl;
1029
    }
1030
1031
    if (ssl->options.handShakeDone == 0) {
1032
        WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
1033
        return NULL;
1034
    }
1035
1036
    if (ssl->dupWrite) {
1037
        WOLFSSL_MSG("wolfSSL_write_dup already called once");
1038
        return NULL;
1039
    }
1040
1041
    dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
1042
    if (dup) {
1043
        if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
1044
            FreeSSL(dup, ssl->ctx->heap);
1045
            dup = NULL;
1046
        } else if ( (ret = DupSSL(dup, ssl)) < 0) {
1047
            FreeSSL(dup, ssl->ctx->heap);
1048
            dup = NULL;
1049
        }
1050
    }
1051
1052
    WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
1053
1054
    return dup;
1055
}
1056
1057
1058
/*
1059
 * Notify write dup side of fatal error or close notify
1060
 *
1061
 * ssl WOLFSSL object
1062
 * err Notify err
1063
 *
1064
 * 0 on success
1065
*/
1066
int NotifyWriteSide(WOLFSSL* ssl, int err)
1067
{
1068
    int ret;
1069
1070
    WOLFSSL_ENTER("NotifyWriteSide");
1071
1072
    ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
1073
    if (ret == 0) {
1074
        ssl->dupWrite->dupErr = err;
1075
        ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
1076
    }
1077
1078
    return ret;
1079
}
1080
1081
1082
#endif /* HAVE_WRITE_DUP */
1083
1084
1085
#ifdef HAVE_POLY1305
1086
/* set if to use old poly 1 for yes 0 to use new poly */
1087
int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
1088
0
{
1089
0
    (void)ssl;
1090
0
    (void)value;
1091
1092
0
#ifndef WOLFSSL_NO_TLS12
1093
0
    WOLFSSL_ENTER("wolfSSL_use_old_poly");
1094
0
    WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
1095
0
            "is depreciated");
1096
0
    ssl->options.oldPoly = (word16)value;
1097
0
    WOLFSSL_LEAVE("wolfSSL_use_old_poly", 0);
1098
0
#endif
1099
0
    return 0;
1100
0
}
1101
#endif
1102
1103
1104
WOLFSSL_ABI
1105
int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
1106
0
{
1107
0
    int ret;
1108
1109
0
    WOLFSSL_ENTER("wolfSSL_set_fd");
1110
1111
0
    if (ssl == NULL) {
1112
0
        return BAD_FUNC_ARG;
1113
0
    }
1114
1115
0
    ret = wolfSSL_set_read_fd(ssl, fd);
1116
0
    if (ret == WOLFSSL_SUCCESS) {
1117
0
        ret = wolfSSL_set_write_fd(ssl, fd);
1118
0
    }
1119
1120
0
    return ret;
1121
0
}
1122
1123
1124
int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
1125
0
{
1126
0
    WOLFSSL_ENTER("wolfSSL_set_read_fd");
1127
1128
0
    if (ssl == NULL) {
1129
0
        return BAD_FUNC_ARG;
1130
0
    }
1131
1132
0
    ssl->rfd = fd;      /* not used directly to allow IO callbacks */
1133
0
    ssl->IOCB_ReadCtx  = &ssl->rfd;
1134
1135
    #ifdef WOLFSSL_DTLS
1136
        ssl->buffers.dtlsCtx.connected = 0;
1137
        if (ssl->options.dtls) {
1138
            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
1139
            ssl->buffers.dtlsCtx.rfd = fd;
1140
        #ifdef USE_WOLFSSL_IO
1141
            ssl->buffers.dtlsCtx.rfdIsDGram =
1142
                (byte)(wolfIO_SockIsDGram(fd) != 0);
1143
        #endif
1144
        }
1145
    #endif
1146
1147
0
    WOLFSSL_LEAVE("wolfSSL_set_read_fd", WOLFSSL_SUCCESS);
1148
0
    return WOLFSSL_SUCCESS;
1149
0
}
1150
1151
1152
int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
1153
0
{
1154
0
    WOLFSSL_ENTER("wolfSSL_set_write_fd");
1155
1156
0
    if (ssl == NULL) {
1157
0
        return BAD_FUNC_ARG;
1158
0
    }
1159
1160
0
    ssl->wfd = fd;      /* not used directly to allow IO callbacks */
1161
0
    ssl->IOCB_WriteCtx  = &ssl->wfd;
1162
1163
    #ifdef WOLFSSL_DTLS
1164
        ssl->buffers.dtlsCtx.connected = 0;
1165
        if (ssl->options.dtls) {
1166
            ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
1167
            ssl->buffers.dtlsCtx.wfd = fd;
1168
        #ifdef USE_WOLFSSL_IO
1169
            ssl->buffers.dtlsCtx.wfdIsDGram =
1170
                (byte)(wolfIO_SockIsDGram(fd) != 0);
1171
        #endif
1172
        }
1173
    #endif
1174
1175
0
    WOLFSSL_LEAVE("wolfSSL_set_write_fd", WOLFSSL_SUCCESS);
1176
0
    return WOLFSSL_SUCCESS;
1177
0
}
1178
1179
1180
/**
1181
  * Get the name of cipher at priority level passed in.
1182
  */
1183
char* wolfSSL_get_cipher_list(int priority)
1184
0
{
1185
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1186
1187
0
    if (priority >= GetCipherNamesSize() || priority < 0) {
1188
0
        return 0;
1189
0
    }
1190
1191
0
    return (char*)ciphers[priority].name;
1192
0
}
1193
1194
1195
/**
1196
  * Get the name of cipher at priority level passed in.
1197
  */
1198
char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
1199
0
{
1200
1201
0
    if (ssl == NULL) {
1202
0
        return NULL;
1203
0
    }
1204
0
    else {
1205
0
        const char* cipher;
1206
1207
0
        if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
1208
0
            if (priority == 0) {
1209
0
                return (char*)cipher;
1210
0
            }
1211
0
            else {
1212
0
                return NULL;
1213
0
            }
1214
0
        }
1215
0
        else {
1216
0
            return wolfSSL_get_cipher_list(priority);
1217
0
        }
1218
0
    }
1219
0
}
1220
1221
1222
int wolfSSL_get_ciphers(char* buf, int len)
1223
0
{
1224
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1225
0
    int ciphersSz = GetCipherNamesSize();
1226
0
    int i;
1227
1228
0
    if (buf == NULL || len <= 0)
1229
0
        return BAD_FUNC_ARG;
1230
1231
    /* Add each member to the buffer delimited by a : */
1232
0
    for (i = 0; i < ciphersSz; i++) {
1233
0
        int cipherNameSz = (int)XSTRLEN(ciphers[i].name);
1234
0
        if (cipherNameSz + 1 < len) {
1235
0
            XSTRNCPY(buf, ciphers[i].name, (size_t)len);
1236
0
            buf += cipherNameSz;
1237
1238
0
            if (i < ciphersSz - 1)
1239
0
                *buf++ = ':';
1240
0
            *buf = 0;
1241
1242
0
            len -= cipherNameSz + 1;
1243
0
        }
1244
0
        else
1245
0
            return BUFFER_E;
1246
0
    }
1247
0
    return WOLFSSL_SUCCESS;
1248
0
}
1249
1250
1251
#ifndef NO_ERROR_STRINGS
1252
/* places a list of all supported cipher suites in TLS_* format into "buf"
1253
 * return WOLFSSL_SUCCESS on success */
1254
int wolfSSL_get_ciphers_iana(char* buf, int len)
1255
0
{
1256
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1257
0
    int ciphersSz = GetCipherNamesSize();
1258
0
    int i;
1259
0
    int cipherNameSz;
1260
1261
0
    if (buf == NULL || len <= 0)
1262
0
        return BAD_FUNC_ARG;
1263
1264
    /* Add each member to the buffer delimited by a : */
1265
0
    for (i = 0; i < ciphersSz; i++) {
1266
0
#ifndef NO_CIPHER_SUITE_ALIASES
1267
0
        if (ciphers[i].flags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS)
1268
0
            continue;
1269
0
#endif
1270
0
        cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
1271
0
        if (cipherNameSz + 1 < len) {
1272
0
            XSTRNCPY(buf, ciphers[i].name_iana, (size_t)len);
1273
0
            buf += cipherNameSz;
1274
1275
0
            if (i < ciphersSz - 1)
1276
0
                *buf++ = ':';
1277
0
            *buf = 0;
1278
1279
0
            len -= cipherNameSz + 1;
1280
0
        }
1281
0
        else
1282
0
            return BUFFER_E;
1283
0
    }
1284
0
    return WOLFSSL_SUCCESS;
1285
0
}
1286
#endif /* NO_ERROR_STRINGS */
1287
1288
1289
const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
1290
0
{
1291
0
    const char* cipher;
1292
1293
0
    if (ssl == NULL || buf == NULL || len <= 0)
1294
0
        return NULL;
1295
1296
0
    cipher = wolfSSL_get_cipher_name_iana(ssl);
1297
0
    if (cipher == NULL)
1298
0
        return NULL;
1299
0
    len = (int)min((word32)len, (word32)(XSTRLEN(cipher) + 1));
1300
0
    XMEMCPY(buf, cipher, (size_t)len);
1301
0
    return buf;
1302
0
}
1303
1304
int wolfSSL_get_fd(const WOLFSSL* ssl)
1305
0
{
1306
0
    int fd = -1;
1307
0
    WOLFSSL_ENTER("wolfSSL_get_fd");
1308
0
    if (ssl) {
1309
0
        fd = ssl->rfd;
1310
0
    }
1311
0
    WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
1312
0
    return fd;
1313
0
}
1314
1315
int wolfSSL_get_wfd(const WOLFSSL* ssl)
1316
0
{
1317
0
    int fd = -1;
1318
0
    WOLFSSL_ENTER("wolfSSL_get_fd");
1319
0
    if (ssl) {
1320
0
        fd = ssl->wfd;
1321
0
    }
1322
0
    WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
1323
0
    return fd;
1324
0
}
1325
1326
1327
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
1328
1329
int wolfSSL_CTX_set_AcceptFilter(
1330
    WOLFSSL_CTX *ctx,
1331
    NetworkFilterCallback_t AcceptFilter,
1332
    void *AcceptFilter_arg)
1333
{
1334
    if (ctx == NULL)
1335
        return BAD_FUNC_ARG;
1336
    ctx->AcceptFilter = AcceptFilter;
1337
    ctx->AcceptFilter_arg = AcceptFilter_arg;
1338
    return 0;
1339
}
1340
1341
int wolfSSL_set_AcceptFilter(
1342
    WOLFSSL *ssl,
1343
    NetworkFilterCallback_t AcceptFilter,
1344
    void *AcceptFilter_arg)
1345
{
1346
    if (ssl == NULL)
1347
        return BAD_FUNC_ARG;
1348
    ssl->AcceptFilter = AcceptFilter;
1349
    ssl->AcceptFilter_arg = AcceptFilter_arg;
1350
    return 0;
1351
}
1352
1353
int wolfSSL_CTX_set_ConnectFilter(
1354
    WOLFSSL_CTX *ctx,
1355
    NetworkFilterCallback_t ConnectFilter,
1356
    void *ConnectFilter_arg)
1357
{
1358
    if (ctx == NULL)
1359
        return BAD_FUNC_ARG;
1360
    ctx->ConnectFilter = ConnectFilter;
1361
    ctx->ConnectFilter_arg = ConnectFilter_arg;
1362
    return 0;
1363
}
1364
1365
int wolfSSL_set_ConnectFilter(
1366
    WOLFSSL *ssl,
1367
    NetworkFilterCallback_t ConnectFilter,
1368
    void *ConnectFilter_arg)
1369
{
1370
    if (ssl == NULL)
1371
        return BAD_FUNC_ARG;
1372
    ssl->ConnectFilter = ConnectFilter;
1373
    ssl->ConnectFilter_arg = ConnectFilter_arg;
1374
    return 0;
1375
}
1376
1377
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
1378
1379
1380
1381
WOLFSSL_ABI
1382
WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
1383
0
{
1384
0
    if (ssl) {
1385
0
        return ssl->rng;
1386
0
    }
1387
1388
0
    return NULL;
1389
0
}
1390
1391
1392
#ifndef WOLFSSL_LEANPSK
1393
/* object size based on build */
1394
int wolfSSL_GetObjectSize(void)
1395
0
{
1396
#ifdef SHOW_SIZES
1397
    printf("sizeof suites           = %lu\n", (unsigned long)sizeof(Suites));
1398
    printf("sizeof ciphers(2)       = %lu\n", (unsigned long)sizeof(Ciphers));
1399
#ifndef NO_RC4
1400
    printf("\tsizeof arc4         = %lu\n", (unsigned long)sizeof(Arc4));
1401
#endif
1402
    printf("\tsizeof aes          = %lu\n", (unsigned long)sizeof(Aes));
1403
#ifndef NO_DES3
1404
    printf("\tsizeof des3         = %lu\n", (unsigned long)sizeof(Des3));
1405
#endif
1406
#ifdef HAVE_CHACHA
1407
    printf("\tsizeof chacha       = %lu\n", (unsigned long)sizeof(ChaCha));
1408
#endif
1409
#ifdef WOLFSSL_SM4
1410
    printf("\tsizeof sm4          = %lu\n", (unsigned long)sizeof(Sm4));
1411
#endif
1412
    printf("sizeof cipher specs     = %lu\n", (unsigned long)
1413
        sizeof(CipherSpecs));
1414
    printf("sizeof keys             = %lu\n", (unsigned long)sizeof(Keys));
1415
    printf("sizeof Hashes(2)        = %lu\n", (unsigned long)sizeof(Hashes));
1416
#ifndef NO_MD5
1417
    printf("\tsizeof MD5          = %lu\n", (unsigned long)sizeof(wc_Md5));
1418
#endif
1419
#ifndef NO_SHA
1420
    printf("\tsizeof SHA          = %lu\n", (unsigned long)sizeof(wc_Sha));
1421
#endif
1422
#ifdef WOLFSSL_SHA224
1423
    printf("\tsizeof SHA224       = %lu\n", (unsigned long)sizeof(wc_Sha224));
1424
#endif
1425
#ifndef NO_SHA256
1426
    printf("\tsizeof SHA256       = %lu\n", (unsigned long)sizeof(wc_Sha256));
1427
#endif
1428
#ifdef WOLFSSL_SHA384
1429
    printf("\tsizeof SHA384       = %lu\n", (unsigned long)sizeof(wc_Sha384));
1430
#endif
1431
#ifdef WOLFSSL_SHA384
1432
    printf("\tsizeof SHA512       = %lu\n", (unsigned long)sizeof(wc_Sha512));
1433
#endif
1434
#ifdef WOLFSSL_SM3
1435
    printf("\tsizeof sm3          = %lu\n", (unsigned long)sizeof(Sm3));
1436
#endif
1437
    printf("sizeof Buffers          = %lu\n", (unsigned long)sizeof(Buffers));
1438
    printf("sizeof Options          = %lu\n", (unsigned long)sizeof(Options));
1439
    printf("sizeof Arrays           = %lu\n", (unsigned long)sizeof(Arrays));
1440
#ifndef NO_RSA
1441
    printf("sizeof RsaKey           = %lu\n", (unsigned long)sizeof(RsaKey));
1442
#endif
1443
#ifdef HAVE_ECC
1444
    printf("sizeof ecc_key          = %lu\n", (unsigned long)sizeof(ecc_key));
1445
#endif
1446
    printf("sizeof WOLFSSL_CIPHER    = %lu\n", (unsigned long)
1447
        sizeof(WOLFSSL_CIPHER));
1448
    printf("sizeof WOLFSSL_SESSION   = %lu\n", (unsigned long)
1449
        sizeof(WOLFSSL_SESSION));
1450
    printf("sizeof WOLFSSL           = %lu\n", (unsigned long)sizeof(WOLFSSL));
1451
    printf("sizeof WOLFSSL_CTX       = %lu\n", (unsigned long)
1452
        sizeof(WOLFSSL_CTX));
1453
#endif
1454
1455
0
    return sizeof(WOLFSSL);
1456
0
}
1457
1458
int wolfSSL_CTX_GetObjectSize(void)
1459
0
{
1460
0
    return sizeof(WOLFSSL_CTX);
1461
0
}
1462
1463
int wolfSSL_METHOD_GetObjectSize(void)
1464
0
{
1465
0
    return sizeof(WOLFSSL_METHOD);
1466
0
}
1467
#endif
1468
1469
1470
#ifdef WOLFSSL_STATIC_MEMORY
1471
1472
int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx,
1473
    wolfSSL_method_func method, unsigned char* buf, unsigned int sz, int flag,
1474
    int maxSz)
1475
{
1476
    WOLFSSL_HEAP_HINT* hint = NULL;
1477
1478
    if (ctx == NULL || buf == NULL) {
1479
        return BAD_FUNC_ARG;
1480
    }
1481
1482
    if (*ctx == NULL && method == NULL) {
1483
        return BAD_FUNC_ARG;
1484
    }
1485
1486
    /* If there is a heap already, capture it in hint. */
1487
    if (*ctx && (*ctx)->heap != NULL) {
1488
        hint = (*ctx)->heap;
1489
    }
1490
1491
    if (wc_LoadStaticMemory(&hint, buf, sz, flag, maxSz)) {
1492
        WOLFSSL_MSG("Error loading static memory");
1493
        return WOLFSSL_FAILURE;
1494
    }
1495
1496
    if (*ctx) {
1497
        if ((*ctx)->heap == NULL) {
1498
            (*ctx)->heap = (void*)hint;
1499
        }
1500
    }
1501
    else {
1502
        /* create ctx if needed */
1503
        *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
1504
        if (*ctx == NULL) {
1505
            WOLFSSL_MSG("Error creating ctx");
1506
            return WOLFSSL_FAILURE;
1507
        }
1508
    }
1509
1510
    return WOLFSSL_SUCCESS;
1511
}
1512
1513
1514
int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
1515
{
1516
    if (ssl == NULL) {
1517
        return BAD_FUNC_ARG;
1518
    }
1519
    WOLFSSL_ENTER("wolfSSL_is_static_memory");
1520
1521
#ifndef WOLFSSL_STATIC_MEMORY_LEAN
1522
    /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
1523
    if (mem_stats != NULL && ssl->heap != NULL) {
1524
        WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
1525
        WOLFSSL_HEAP* heap      = hint->memory;
1526
        if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
1527
            XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
1528
        }
1529
    }
1530
#endif
1531
1532
    (void)mem_stats;
1533
    return (ssl->heap) ? 1 : 0;
1534
}
1535
1536
1537
int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
1538
{
1539
    if (ctx == NULL) {
1540
        return BAD_FUNC_ARG;
1541
    }
1542
    WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
1543
1544
#ifndef WOLFSSL_STATIC_MEMORY_LEAN
1545
    /* fill out statistics if wanted */
1546
    if (mem_stats != NULL && ctx->heap != NULL) {
1547
        WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
1548
        if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
1549
            return MEMORY_E;
1550
        }
1551
    }
1552
#endif
1553
1554
    (void)mem_stats;
1555
    return (ctx->heap) ? 1 : 0;
1556
}
1557
1558
#endif /* WOLFSSL_STATIC_MEMORY */
1559
1560
#ifndef NO_TLS
1561
/* return max record layer size plaintext input size */
1562
int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
1563
0
{
1564
0
    WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
1565
1566
0
    if (ssl == NULL)
1567
0
        return BAD_FUNC_ARG;
1568
1569
0
    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
1570
0
        WOLFSSL_MSG("Handshake not complete yet");
1571
0
        return BAD_FUNC_ARG;
1572
0
    }
1573
1574
0
    return min(OUTPUT_RECORD_SIZE, wolfssl_local_GetMaxPlaintextSize(ssl));
1575
0
}
1576
1577
1578
/* return record layer size of plaintext input size */
1579
int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
1580
0
{
1581
0
    int maxSize;
1582
1583
0
    WOLFSSL_ENTER("wolfSSL_GetOutputSize");
1584
1585
0
    if (inSz < 0)
1586
0
        return BAD_FUNC_ARG;
1587
1588
0
    maxSize = wolfSSL_GetMaxOutputSize(ssl);
1589
0
    if (maxSize < 0)
1590
0
        return maxSize;   /* error */
1591
0
    if (inSz > maxSize)
1592
0
        return INPUT_SIZE_E;
1593
1594
#ifdef HAVE_LIBZ
1595
    /* SendData() sizes the record for deflate's worst case, so report that
1596
     * same bound: an incompressible fragment emits more than its plaintext
1597
     * length. */
1598
    if (ssl->options.usingCompression)
1599
        inSz += MAX_COMP_EXTRA;
1600
#endif
1601
1602
0
    return wolfssl_local_GetRecordSize(ssl, inSz, 1);
1603
0
}
1604
1605
1606
#endif /* !NO_TLS */
1607
1608
#define WOLFSSL_SSL_API_RW_INCLUDED
1609
#include "src/ssl_api_rw.c"
1610
1611
#define WOLFSSL_SSL_API_DTLS_INCLUDED
1612
#include "src/ssl_api_dtls.c"
1613
1614
/* helpers to set the device id, WOLFSSL_SUCCESS on ok */
1615
WOLFSSL_ABI
1616
int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
1617
0
{
1618
0
    if (ssl == NULL)
1619
0
        return BAD_FUNC_ARG;
1620
1621
0
    ssl->devId = devId;
1622
1623
0
    return WOLFSSL_SUCCESS;
1624
0
}
1625
1626
WOLFSSL_ABI
1627
int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
1628
0
{
1629
0
    if (ctx == NULL)
1630
0
        return BAD_FUNC_ARG;
1631
1632
0
    ctx->devId = devId;
1633
1634
0
    return WOLFSSL_SUCCESS;
1635
0
}
1636
1637
/* helpers to get device id and heap */
1638
WOLFSSL_ABI
1639
int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
1640
0
{
1641
0
    int devId = INVALID_DEVID;
1642
0
    if (ssl != NULL)
1643
0
        devId = ssl->devId;
1644
0
    if (ctx != NULL && devId == INVALID_DEVID)
1645
0
        devId = ctx->devId;
1646
0
    return devId;
1647
0
}
1648
void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
1649
0
{
1650
0
    void* heap = NULL;
1651
0
    if (ctx != NULL)
1652
0
        heap = ctx->heap;
1653
0
    else if (ssl != NULL)
1654
0
        heap = ssl->heap;
1655
0
    return heap;
1656
0
}
1657
1658
1659
1660
/* get current error state value */
1661
int wolfSSL_state(WOLFSSL* ssl)
1662
0
{
1663
0
    if (ssl == NULL) {
1664
0
        return BAD_FUNC_ARG;
1665
0
    }
1666
1667
0
    return ssl->error;
1668
0
}
1669
1670
1671
WOLFSSL_ABI
1672
int wolfSSL_get_error(WOLFSSL* ssl, int ret)
1673
0
{
1674
0
    WOLFSSL_ENTER("wolfSSL_get_error");
1675
1676
0
    if (ret > 0)
1677
0
        return WOLFSSL_ERROR_NONE;
1678
0
    if (ssl == NULL)
1679
0
        return BAD_FUNC_ARG;
1680
1681
0
    WOLFSSL_LEAVE("wolfSSL_get_error", ssl->error);
1682
1683
    /* make sure converted types are handled in SetErrorString() too */
1684
0
    if (ssl->error == WC_NO_ERR_TRACE(WANT_READ))
1685
0
        return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
1686
0
    else if (ssl->error == WC_NO_ERR_TRACE(WANT_WRITE))
1687
0
        return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
1688
0
    else if (ssl->error == WC_NO_ERR_TRACE(ZERO_RETURN) ||
1689
0
             ssl->options.shutdownDone)
1690
0
        return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
1691
#ifdef OPENSSL_EXTRA
1692
    else if (ssl->error == WC_NO_ERR_TRACE(MATCH_SUITE_ERROR))
1693
        return WOLFSSL_ERROR_SYSCALL;           /* convert to OpenSSL type */
1694
    else if (ssl->error == WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E))
1695
        return WOLFSSL_ERROR_SYSCALL;           /* convert to OpenSSL type */
1696
#endif
1697
#ifdef WOLFSSL_ASYNC_CRYPT
1698
    else if (ssl->error == WC_NO_ERR_TRACE(MP_WOULDBLOCK))
1699
        return WC_PENDING_E;                    /* map non-blocking crypto */
1700
#endif
1701
0
    return ssl->error;
1702
0
}
1703
1704
1705
/* retrieve alert history, WOLFSSL_SUCCESS on ok */
1706
int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
1707
0
{
1708
0
    if (ssl && h) {
1709
0
        *h = ssl->alert_history;
1710
0
    }
1711
0
    return WOLFSSL_SUCCESS;
1712
0
}
1713
1714
1715
#define WOLFSSL_SSL_ERR_INCLUDED
1716
#include "src/ssl_err.c"
1717
1718
1719
/* don't free temporary arrays at end of handshake */
1720
void wolfSSL_KeepArrays(WOLFSSL* ssl)
1721
0
{
1722
0
    if (ssl)
1723
0
        ssl->options.saveArrays = 1;
1724
0
}
1725
1726
1727
/* user doesn't need temporary arrays anymore, Free */
1728
void wolfSSL_FreeArrays(WOLFSSL* ssl)
1729
0
{
1730
0
    if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
1731
0
        ssl->options.saveArrays = 0;
1732
0
        FreeArrays(ssl, 1);
1733
0
    }
1734
0
}
1735
1736
/* Set option to indicate that the resources are not to be freed after
1737
 * handshake.
1738
 *
1739
 * ssl  The SSL/TLS object.
1740
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
1741
 */
1742
int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
1743
0
{
1744
0
    if (ssl == NULL)
1745
0
        return BAD_FUNC_ARG;
1746
1747
0
    ssl->options.keepResources = 1;
1748
1749
0
    return 0;
1750
0
}
1751
1752
/* Free the handshake resources after handshake.
1753
 *
1754
 * ssl  The SSL/TLS object.
1755
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
1756
 */
1757
int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
1758
0
{
1759
0
    if (ssl == NULL)
1760
0
        return BAD_FUNC_ARG;
1761
1762
0
    FreeHandshakeResources(ssl);
1763
1764
0
    return 0;
1765
0
}
1766
1767
/* Use the client's order of preference when matching cipher suites.
1768
 *
1769
 * ssl  The SSL/TLS context object.
1770
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
1771
 */
1772
int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
1773
0
{
1774
0
    if (ctx == NULL)
1775
0
        return BAD_FUNC_ARG;
1776
1777
0
    ctx->useClientOrder = 1;
1778
1779
0
    return 0;
1780
0
}
1781
1782
/* Use the client's order of preference when matching cipher suites.
1783
 *
1784
 * ssl  The SSL/TLS object.
1785
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
1786
 */
1787
int wolfSSL_UseClientSuites(WOLFSSL* ssl)
1788
0
{
1789
0
    if (ssl == NULL)
1790
0
        return BAD_FUNC_ARG;
1791
1792
0
    ssl->options.useClientOrder = 1;
1793
1794
0
    return 0;
1795
0
}
1796
1797
1798
const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
1799
0
{
1800
0
#ifndef WOLFSSL_AEAD_ONLY
1801
0
    if (ssl == NULL)
1802
0
        return NULL;
1803
1804
0
    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
1805
0
         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
1806
0
        return ssl->keys.client_write_MAC_secret;
1807
0
    else
1808
0
        return ssl->keys.server_write_MAC_secret;
1809
#else
1810
    (void)ssl;
1811
    (void)verify;
1812
1813
    return NULL;
1814
#endif
1815
0
}
1816
1817
int wolfSSL_GetSide(WOLFSSL* ssl)
1818
0
{
1819
0
    if (ssl)
1820
0
        return ssl->options.side;
1821
1822
0
    return BAD_FUNC_ARG;
1823
0
}
1824
1825
#ifdef ATOMIC_USER
1826
1827
void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
1828
{
1829
    if (ctx)
1830
        ctx->MacEncryptCb = cb;
1831
}
1832
1833
1834
void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
1835
{
1836
    if (ssl)
1837
        ssl->MacEncryptCtx = ctx;
1838
}
1839
1840
1841
void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
1842
{
1843
    if (ssl)
1844
        return ssl->MacEncryptCtx;
1845
1846
    return NULL;
1847
}
1848
1849
1850
void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
1851
{
1852
    if (ctx)
1853
        ctx->DecryptVerifyCb = cb;
1854
}
1855
1856
1857
void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
1858
{
1859
    if (ssl)
1860
        ssl->DecryptVerifyCtx = ctx;
1861
}
1862
1863
1864
void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
1865
{
1866
    if (ssl)
1867
        return ssl->DecryptVerifyCtx;
1868
1869
    return NULL;
1870
}
1871
1872
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
1873
/**
1874
 * Set the callback, against the context, that encrypts then MACs.
1875
 *
1876
 * ctx  SSL/TLS context.
1877
 * cb   Callback function to use with Encrypt-Then-MAC.
1878
 */
1879
void  wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
1880
{
1881
    if (ctx)
1882
        ctx->EncryptMacCb = cb;
1883
}
1884
1885
/**
1886
 * Set the context to use with callback that encrypts then MACs.
1887
 *
1888
 * ssl  SSL/TLS object.
1889
 * ctx  Callback function's context.
1890
 */
1891
void  wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
1892
{
1893
    if (ssl)
1894
        ssl->EncryptMacCtx = ctx;
1895
}
1896
1897
/**
1898
 * Get the context being used with callback that encrypts then MACs.
1899
 *
1900
 * ssl  SSL/TLS object.
1901
 * returns callback function's context or NULL if SSL/TLS object is NULL.
1902
 */
1903
void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
1904
{
1905
    if (ssl)
1906
        return ssl->EncryptMacCtx;
1907
1908
    return NULL;
1909
}
1910
1911
1912
/**
1913
 * Set the callback, against the context, that MAC verifies then decrypts.
1914
 *
1915
 * ctx  SSL/TLS context.
1916
 * cb   Callback function to use with Encrypt-Then-MAC.
1917
 */
1918
void  wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
1919
{
1920
    if (ctx)
1921
        ctx->VerifyDecryptCb = cb;
1922
}
1923
1924
/**
1925
 * Set the context to use with callback that MAC verifies then decrypts.
1926
 *
1927
 * ssl  SSL/TLS object.
1928
 * ctx  Callback function's context.
1929
 */
1930
void  wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
1931
{
1932
    if (ssl)
1933
        ssl->VerifyDecryptCtx = ctx;
1934
}
1935
1936
/**
1937
 * Get the context being used with callback that MAC verifies then decrypts.
1938
 *
1939
 * ssl  SSL/TLS object.
1940
 * returns callback function's context or NULL if SSL/TLS object is NULL.
1941
 */
1942
void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
1943
{
1944
    if (ssl)
1945
        return ssl->VerifyDecryptCtx;
1946
1947
    return NULL;
1948
}
1949
#endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
1950
1951
1952
1953
const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
1954
{
1955
    if (ssl)
1956
        return ssl->keys.client_write_key;
1957
1958
    return NULL;
1959
}
1960
1961
1962
const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
1963
{
1964
    if (ssl)
1965
        return ssl->keys.client_write_IV;
1966
1967
    return NULL;
1968
}
1969
1970
1971
const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
1972
{
1973
    if (ssl)
1974
        return ssl->keys.server_write_key;
1975
1976
    return NULL;
1977
}
1978
1979
1980
const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
1981
{
1982
    if (ssl)
1983
        return ssl->keys.server_write_IV;
1984
1985
    return NULL;
1986
}
1987
1988
int wolfSSL_GetKeySize(WOLFSSL* ssl)
1989
{
1990
    if (ssl)
1991
        return ssl->specs.key_size;
1992
1993
    return BAD_FUNC_ARG;
1994
}
1995
1996
1997
int wolfSSL_GetIVSize(WOLFSSL* ssl)
1998
{
1999
    if (ssl)
2000
        return ssl->specs.iv_size;
2001
2002
    return BAD_FUNC_ARG;
2003
}
2004
2005
2006
int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
2007
{
2008
    if (ssl)
2009
        return ssl->specs.bulk_cipher_algorithm;
2010
2011
    return BAD_FUNC_ARG;
2012
}
2013
2014
2015
int wolfSSL_GetCipherType(WOLFSSL* ssl)
2016
{
2017
    if (ssl == NULL)
2018
        return BAD_FUNC_ARG;
2019
2020
#ifndef WOLFSSL_AEAD_ONLY
2021
    if (ssl->specs.cipher_type == block)
2022
        return WOLFSSL_BLOCK_TYPE;
2023
    if (ssl->specs.cipher_type == stream)
2024
        return WOLFSSL_STREAM_TYPE;
2025
#endif
2026
    if (ssl->specs.cipher_type == aead)
2027
        return WOLFSSL_AEAD_TYPE;
2028
2029
    return WOLFSSL_FATAL_ERROR;
2030
}
2031
2032
2033
int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
2034
{
2035
    if (ssl == NULL)
2036
        return BAD_FUNC_ARG;
2037
2038
    return ssl->specs.block_size;
2039
}
2040
2041
2042
int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
2043
{
2044
    if (ssl == NULL)
2045
        return BAD_FUNC_ARG;
2046
2047
    return ssl->specs.aead_mac_size;
2048
}
2049
2050
2051
int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
2052
{
2053
    if (ssl == NULL)
2054
        return BAD_FUNC_ARG;
2055
2056
    if (ssl->options.tls1_1)
2057
        return 1;
2058
2059
    return 0;
2060
}
2061
2062
2063
2064
int wolfSSL_GetHmacSize(WOLFSSL* ssl)
2065
{
2066
    /* AEAD ciphers don't have HMAC keys */
2067
    if (ssl)
2068
        return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
2069
2070
    return BAD_FUNC_ARG;
2071
}
2072
2073
#ifdef WORD64_AVAILABLE
2074
int wolfSSL_GetPeerSequenceNumber(WOLFSSL* ssl, word64 *seq)
2075
{
2076
    if ((ssl == NULL) || (seq == NULL))
2077
        return BAD_FUNC_ARG;
2078
2079
    *seq = ((word64)ssl->keys.peer_sequence_number_hi << 32) |
2080
                    ssl->keys.peer_sequence_number_lo;
2081
    return !(*seq);
2082
}
2083
2084
int wolfSSL_GetSequenceNumber(WOLFSSL* ssl, word64 *seq)
2085
{
2086
    if ((ssl == NULL) || (seq == NULL))
2087
        return BAD_FUNC_ARG;
2088
2089
    *seq = ((word64)ssl->keys.sequence_number_hi << 32) |
2090
                    ssl->keys.sequence_number_lo;
2091
    return !(*seq);
2092
}
2093
#endif
2094
2095
#endif /* ATOMIC_USER */
2096
2097
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) \
2098
    && defined(XFPRINTF)
2099
2100
2101
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
2102
#endif
2103
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM && XFPRINTF */
2104
2105
#ifndef WOLFSSL_LEANPSK
2106
/* turn on handshake group messages for context */
2107
int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
2108
0
{
2109
0
    if (ctx == NULL)
2110
0
       return BAD_FUNC_ARG;
2111
2112
0
    ctx->groupMessages = 1;
2113
2114
0
    return WOLFSSL_SUCCESS;
2115
0
}
2116
2117
int wolfSSL_CTX_clear_group_messages(WOLFSSL_CTX* ctx)
2118
0
{
2119
0
    if (ctx == NULL)
2120
0
       return BAD_FUNC_ARG;
2121
2122
0
    ctx->groupMessages = 0;
2123
2124
0
    return WOLFSSL_SUCCESS;
2125
0
}
2126
#endif
2127
2128
2129
#ifndef WOLFSSL_LEANPSK
2130
/* turn on handshake group messages for ssl object */
2131
int wolfSSL_set_group_messages(WOLFSSL* ssl)
2132
0
{
2133
0
    if (ssl == NULL)
2134
0
       return BAD_FUNC_ARG;
2135
2136
0
    ssl->options.groupMessages = 1;
2137
2138
0
    return WOLFSSL_SUCCESS;
2139
0
}
2140
2141
int wolfSSL_clear_group_messages(WOLFSSL* ssl)
2142
0
{
2143
0
    if (ssl == NULL)
2144
0
       return BAD_FUNC_ARG;
2145
2146
0
    ssl->options.groupMessages = 0;
2147
2148
0
    return WOLFSSL_SUCCESS;
2149
0
}
2150
2151
/* make minVersion the internal equivalent SSL version */
2152
static int SetMinVersionHelper(byte* minVersion, int version)
2153
0
{
2154
0
    (void)minVersion;
2155
2156
0
    switch (version) {
2157
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
2158
        case WOLFSSL_SSLV3:
2159
            *minVersion = SSLv3_MINOR;
2160
            break;
2161
#endif
2162
2163
0
#ifndef NO_TLS
2164
    #ifndef NO_OLD_TLS
2165
        #ifdef WOLFSSL_ALLOW_TLSV10
2166
        case WOLFSSL_TLSV1:
2167
            *minVersion = TLSv1_MINOR;
2168
            break;
2169
        #endif
2170
2171
        case WOLFSSL_TLSV1_1:
2172
            *minVersion = TLSv1_1_MINOR;
2173
            break;
2174
    #endif
2175
0
    #ifndef WOLFSSL_NO_TLS12
2176
0
        case WOLFSSL_TLSV1_2:
2177
0
            *minVersion = TLSv1_2_MINOR;
2178
0
            break;
2179
0
    #endif
2180
0
#endif
2181
0
    #ifdef WOLFSSL_TLS13
2182
0
        case WOLFSSL_TLSV1_3:
2183
0
            *minVersion = TLSv1_3_MINOR;
2184
0
            break;
2185
0
    #endif
2186
2187
#ifdef WOLFSSL_DTLS
2188
        case WOLFSSL_DTLSV1:
2189
            *minVersion = DTLS_MINOR;
2190
            break;
2191
        case WOLFSSL_DTLSV1_2:
2192
            *minVersion = DTLSv1_2_MINOR;
2193
            break;
2194
#ifdef WOLFSSL_DTLS13
2195
        case WOLFSSL_DTLSV1_3:
2196
            *minVersion = DTLSv1_3_MINOR;
2197
            break;
2198
#endif /* WOLFSSL_DTLS13 */
2199
#endif /* WOLFSSL_DTLS */
2200
2201
0
        default:
2202
0
            WOLFSSL_MSG("Bad function argument");
2203
0
            return BAD_FUNC_ARG;
2204
0
    }
2205
2206
0
    return WOLFSSL_SUCCESS;
2207
0
}
2208
2209
2210
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
2211
WOLFSSL_ABI
2212
int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
2213
0
{
2214
0
    int ret;
2215
2216
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
2217
2218
0
    if (ctx == NULL) {
2219
0
        WOLFSSL_MSG("Bad function argument");
2220
0
        return BAD_FUNC_ARG;
2221
0
    }
2222
2223
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2224
    if (crypto_policy.enabled) {
2225
        return CRYPTO_POLICY_FORBIDDEN;
2226
    }
2227
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2228
2229
0
    ret = SetMinVersionHelper(&ctx->minDowngrade, version);
2230
0
    if (ret == WOLFSSL_SUCCESS)
2231
0
        ctx->minVersionSet = 1;
2232
2233
0
    return ret;
2234
0
}
2235
2236
2237
/* Work out whether the version set by wolfSSL_SetVersion() is one pinned
2238
 * version or the top of a range. */
2239
static void RestoreDowngrade(WOLFSSL* ssl)
2240
0
{
2241
0
    if (ssl->options.versionSet && ssl->ctx != NULL) {
2242
0
        if (ssl->options.failNoPSK || !ssl->options.minVersionSet) {
2243
            /* A PSK requirement is TLS 1.3 only, and with no minimum there is
2244
             * one version, so both keep the version pinned */
2245
0
            ssl->options.downgrade = 0;
2246
0
        }
2247
0
        else {
2248
            /* Set the connection's downgrade option to the context's default */
2249
0
            ssl->options.downgrade = (word16)(ssl->ctx->method->downgrade);
2250
0
        }
2251
0
    }
2252
0
}
2253
2254
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
2255
int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
2256
0
{
2257
0
    int ret;
2258
2259
0
    WOLFSSL_ENTER("wolfSSL_SetMinVersion");
2260
2261
0
    if (ssl == NULL) {
2262
0
        WOLFSSL_MSG("Bad function argument");
2263
0
        return BAD_FUNC_ARG;
2264
0
    }
2265
2266
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2267
    if (crypto_policy.enabled) {
2268
        return CRYPTO_POLICY_FORBIDDEN;
2269
    }
2270
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2271
2272
0
    ret = SetMinVersionHelper(&ssl->options.minDowngrade, version);
2273
0
    if (ret == WOLFSSL_SUCCESS) {
2274
0
        ssl->options.minVersionSet = 1;
2275
0
        RestoreDowngrade(ssl);
2276
0
    }
2277
2278
0
    return ret;
2279
0
}
2280
2281
2282
/* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
2283
int wolfSSL_GetVersion(const WOLFSSL* ssl)
2284
0
{
2285
0
    if (ssl == NULL)
2286
0
        return BAD_FUNC_ARG;
2287
2288
0
    if (ssl->version.major == SSLv3_MAJOR) {
2289
0
        switch (ssl->version.minor) {
2290
0
            case SSLv3_MINOR :
2291
0
                return WOLFSSL_SSLV3;
2292
0
            case TLSv1_MINOR :
2293
0
                return WOLFSSL_TLSV1;
2294
0
            case TLSv1_1_MINOR :
2295
0
                return WOLFSSL_TLSV1_1;
2296
0
            case TLSv1_2_MINOR :
2297
0
                return WOLFSSL_TLSV1_2;
2298
0
            case TLSv1_3_MINOR :
2299
0
                return WOLFSSL_TLSV1_3;
2300
0
            default:
2301
0
                break;
2302
0
        }
2303
0
    }
2304
#ifdef WOLFSSL_DTLS
2305
    if (ssl->version.major == DTLS_MAJOR) {
2306
        switch (ssl->version.minor) {
2307
            case DTLS_MINOR :
2308
                return WOLFSSL_DTLSV1;
2309
            case DTLSv1_2_MINOR :
2310
                return WOLFSSL_DTLSV1_2;
2311
            case DTLSv1_3_MINOR :
2312
                return WOLFSSL_DTLSV1_3;
2313
            default:
2314
                break;
2315
        }
2316
    }
2317
#endif /* WOLFSSL_DTLS */
2318
2319
0
    return VERSION_ERROR;
2320
0
}
2321
2322
int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
2323
0
{
2324
0
    word16 haveRSA = 1;
2325
0
    word16 havePSK = 0;
2326
0
    int    keySz   = 0;
2327
2328
0
    WOLFSSL_ENTER("wolfSSL_SetVersion");
2329
2330
0
    if (ssl == NULL) {
2331
0
        WOLFSSL_MSG("Bad function argument");
2332
0
        return BAD_FUNC_ARG;
2333
0
    }
2334
2335
0
    switch (version) {
2336
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
2337
        case WOLFSSL_SSLV3:
2338
            ssl->version = MakeSSLv3();
2339
            break;
2340
#endif
2341
2342
0
#ifndef NO_TLS
2343
    #ifndef NO_OLD_TLS
2344
        #ifdef WOLFSSL_ALLOW_TLSV10
2345
        case WOLFSSL_TLSV1:
2346
            ssl->version = MakeTLSv1();
2347
            break;
2348
        #endif
2349
2350
        case WOLFSSL_TLSV1_1:
2351
            ssl->version = MakeTLSv1_1();
2352
            break;
2353
    #endif
2354
0
    #ifndef WOLFSSL_NO_TLS12
2355
0
        case WOLFSSL_TLSV1_2:
2356
0
            ssl->version = MakeTLSv1_2();
2357
0
            break;
2358
0
    #endif
2359
2360
0
    #ifdef WOLFSSL_TLS13
2361
0
        case WOLFSSL_TLSV1_3:
2362
0
            ssl->version = MakeTLSv1_3();
2363
0
            break;
2364
0
    #endif /* WOLFSSL_TLS13 */
2365
0
#endif
2366
2367
0
        default:
2368
0
            WOLFSSL_MSG("Bad function argument");
2369
0
            return BAD_FUNC_ARG;
2370
0
    }
2371
2372
0
    ssl->options.versionSet = 1;
2373
0
    ssl->options.maxVersionMinor = ssl->version.minor;
2374
0
    if (!ssl->options.minVersionSet) {
2375
        /* no minimum asked for, so this version is the whole range */
2376
0
        ssl->options.downgrade = 0;
2377
0
    }
2378
2379
    #ifdef NO_RSA
2380
        haveRSA = 0;
2381
    #endif
2382
    #ifndef NO_PSK
2383
        havePSK = ssl->options.havePSK;
2384
    #endif
2385
0
    #ifndef NO_CERTS
2386
0
        keySz = ssl->buffers.keySz;
2387
0
    #endif
2388
2389
0
    if (AllocateSuites(ssl) != 0)
2390
0
        return WOLFSSL_FAILURE;
2391
0
    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
2392
0
               ssl->options.haveDH, ssl->options.haveECDSAsig,
2393
0
               ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
2394
0
               ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
2395
0
    return WOLFSSL_SUCCESS;
2396
0
}
2397
#endif /* !leanpsk */
2398
2399
/* If we don't have static mutex initializers, but we do have static atomic
2400
 * initializers, activate WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS to leverage
2401
 * the latter.
2402
 *
2403
 * See further explanation below in wolfSSL_Init().
2404
 */
2405
#ifndef WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
2406
    #if !defined(WOLFSSL_MUTEX_INITIALIZER) && !defined(SINGLE_THREADED) && \
2407
            defined(WOLFSSL_ATOMIC_OPS) && defined(WOLFSSL_ATOMIC_INITIALIZER)
2408
        #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 1
2409
    #else
2410
        #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 0
2411
    #endif
2412
#elif defined(WOLFSSL_MUTEX_INITIALIZER) || defined(SINGLE_THREADED)
2413
    #undef WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
2414
    #define WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS 0
2415
#endif
2416
2417
#if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
2418
    #ifndef WOLFSSL_ATOMIC_OPS
2419
        #error WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS requires WOLFSSL_ATOMIC_OPS
2420
    #endif
2421
    #ifndef WOLFSSL_ATOMIC_INITIALIZER
2422
        #error WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS requires WOLFSSL_ATOMIC_INITIALIZER
2423
    #endif
2424
    static wolfSSL_Atomic_Int inits_count_mutex_atomic_initing_flag =
2425
        WOLFSSL_ATOMIC_INITIALIZER(0);
2426
#endif /* WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS && !WOLFSSL_MUTEX_INITIALIZER */
2427
2428
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
2429
static void AtExitCleanup(void)
2430
{
2431
    if (initRefCount > 0) {
2432
        initRefCount = 1;
2433
        (void)wolfSSL_Cleanup();
2434
#if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
2435
        if (inits_count_mutex_valid == 1) {
2436
            (void)wc_FreeMutex(&inits_count_mutex);
2437
            inits_count_mutex_valid = 0;
2438
            inits_count_mutex_atomic_initing_flag = 0;
2439
        }
2440
#endif
2441
    }
2442
}
2443
#endif
2444
2445
WOLFSSL_ABI
2446
int wolfSSL_Init(void)
2447
0
{
2448
0
    int ret = WOLFSSL_SUCCESS;
2449
#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
2450
    int i;
2451
#endif
2452
2453
0
    WOLFSSL_ENTER("wolfSSL_Init");
2454
2455
0
#if defined(LIBWOLFSSL_CMAKE_OUTPUT)
2456
0
    WOLFSSL_MSG(LIBWOLFSSL_CMAKE_OUTPUT);
2457
#else
2458
    WOLFSSL_MSG("No extra wolfSSL cmake messages found");
2459
#endif
2460
2461
#ifndef WOLFSSL_MUTEX_INITIALIZER
2462
    if (inits_count_mutex_valid == 0) {
2463
    #if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
2464
2465
        /* Without this mitigation, if two threads enter wolfSSL_Init() at the
2466
         * same time, and both see zero inits_count_mutex_valid, then both will
2467
         * run wc_InitMutex(&inits_count_mutex), leading to process corruption
2468
         * or (best case) a resource leak.
2469
         *
2470
         * When WOLFSSL_ATOMIC_INITIALIZER() is available, we can mitigate this
2471
         * by use an atomic counting int as a mutex.
2472
         */
2473
2474
        if (wolfSSL_Atomic_Int_FetchAdd(&inits_count_mutex_atomic_initing_flag,
2475
                                        1) != 0)
2476
        {
2477
            (void)wolfSSL_Atomic_Int_FetchSub(
2478
                &inits_count_mutex_atomic_initing_flag, 1);
2479
            return DEADLOCK_AVERTED_E;
2480
        }
2481
    #endif /* WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS */
2482
        if (wc_InitMutex(&inits_count_mutex) != 0) {
2483
            WOLFSSL_MSG("Bad Init Mutex count");
2484
    #if WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
2485
            (void)wolfSSL_Atomic_Int_FetchSub(
2486
                &inits_count_mutex_atomic_initing_flag, 1);
2487
    #endif
2488
            return BAD_MUTEX_E;
2489
        }
2490
        else {
2491
            inits_count_mutex_valid = 1;
2492
        }
2493
    }
2494
#endif /* !WOLFSSL_MUTEX_INITIALIZER */
2495
2496
0
    if (wc_LockMutex(&inits_count_mutex) != 0) {
2497
0
        WOLFSSL_MSG("Bad Lock Mutex count");
2498
0
        return BAD_MUTEX_E;
2499
0
    }
2500
2501
#if FIPS_VERSION_GE(5,1)
2502
    if ((ret == WOLFSSL_SUCCESS) && (initRefCount == 0)) {
2503
        ret = wolfCrypt_SetPrivateKeyReadEnable_fips(1, WC_KEYTYPE_ALL);
2504
        if (ret == 0)
2505
            ret = WOLFSSL_SUCCESS;
2506
    }
2507
#endif
2508
2509
0
    if ((ret == WOLFSSL_SUCCESS) && (initRefCount == 0)) {
2510
        /* Initialize crypto for use with TLS connection */
2511
2512
0
        if (wolfCrypt_Init() != 0) {
2513
0
            WOLFSSL_MSG("Bad wolfCrypt Init");
2514
0
            ret = WC_INIT_E;
2515
0
        }
2516
2517
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2518
    !defined(WOLFCRYPT_ONLY)
2519
        /* Calculate the index of OID groups in wolfssl_object_info[]. */
2520
        wolfssl_object_info_slice_init();
2521
#endif
2522
2523
#if defined(HAVE_GLOBAL_RNG) && !defined(WOLFSSL_MUTEX_INITIALIZER)
2524
        if (ret == WOLFSSL_SUCCESS) {
2525
            if (wc_InitMutex(&globalRNGMutex) != 0) {
2526
                WOLFSSL_MSG("Bad Init Mutex rng");
2527
                ret = BAD_MUTEX_E;
2528
            }
2529
            else {
2530
                globalRNGMutex_valid = 1;
2531
            }
2532
        }
2533
#endif
2534
2535
    #ifdef WC_RNG_SEED_CB
2536
        wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
2537
    #endif
2538
2539
#ifdef OPENSSL_EXTRA
2540
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
2541
        if ((ret == WOLFSSL_SUCCESS) && (wolfSSL_RAND_InitMutex() != 0)) {
2542
            ret = BAD_MUTEX_E;
2543
        }
2544
    #endif
2545
        if ((ret == WOLFSSL_SUCCESS) &&
2546
            (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS)) {
2547
            WOLFSSL_MSG("wolfSSL_RAND_seed failed");
2548
            ret = WC_INIT_E;
2549
        }
2550
#endif
2551
2552
0
#ifndef NO_SESSION_CACHE
2553
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
2554
        for (i = 0; i < SESSION_ROWS; ++i) {
2555
            SessionCache[i].lock_valid = 0;
2556
        }
2557
        for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < SESSION_ROWS); ++i) {
2558
            if (wc_InitRwLock(&SessionCache[i].row_lock) != 0) {
2559
                WOLFSSL_MSG("Bad Init Mutex session");
2560
                ret = BAD_MUTEX_E;
2561
            }
2562
            else {
2563
                SessionCache[i].lock_valid = 1;
2564
            }
2565
        }
2566
    #else
2567
0
        if (ret == WOLFSSL_SUCCESS) {
2568
0
            if (wc_InitRwLock(&session_lock) != 0) {
2569
0
                WOLFSSL_MSG("Bad Init Mutex session");
2570
0
                ret = BAD_MUTEX_E;
2571
0
            }
2572
0
            else {
2573
0
                session_lock_valid = 1;
2574
0
            }
2575
0
        }
2576
0
    #endif
2577
0
    #ifndef NO_CLIENT_CACHE
2578
        #ifndef WOLFSSL_MUTEX_INITIALIZER
2579
        if (ret == WOLFSSL_SUCCESS) {
2580
            if (wc_InitMutex(&clisession_mutex) != 0) {
2581
                WOLFSSL_MSG("Bad Init Mutex session");
2582
                ret = BAD_MUTEX_E;
2583
            }
2584
            else {
2585
                clisession_mutex_valid = 1;
2586
            }
2587
        }
2588
        #endif
2589
0
    #endif
2590
0
#endif
2591
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
2592
        /* OpenSSL registers cleanup using atexit */
2593
        if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
2594
            WOLFSSL_MSG("Bad atexit registration");
2595
            ret = WC_INIT_E;
2596
        }
2597
#endif
2598
0
    }
2599
2600
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2601
    /* System wide crypto policy disabled by default. */
2602
    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
2603
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2604
2605
0
    if (ret == WOLFSSL_SUCCESS) {
2606
0
        initRefCount = initRefCount + 1;
2607
0
    }
2608
0
    else {
2609
0
        initRefCount = 1; /* Force cleanup */
2610
0
    }
2611
2612
0
    wc_UnLockMutex(&inits_count_mutex);
2613
2614
0
    if (ret != WOLFSSL_SUCCESS) {
2615
0
        (void)wolfSSL_Cleanup(); /* Ignore any error from cleanup */
2616
0
    }
2617
2618
0
    return ret;
2619
0
}
2620
2621
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
2622
/* Helper function for wolfSSL_crypto_policy_enable and
2623
 * wolfSSL_crypto_policy_enable_buffer.
2624
 *
2625
 * Parses the crypto policy string, verifies values,
2626
 * and sets in global crypto policy struct. Not thread
2627
 * safe. String length has already been verified.
2628
 *
2629
 * Returns WOLFSSL_SUCCESS on success.
2630
 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
2631
 * Returns < 0 on misc error.
2632
 * */
2633
static int crypto_policy_parse(void)
2634
{
2635
    const char * hdr = WOLFSSL_SECLEVEL_STR;
2636
    int          sec_level = 0;
2637
    size_t       i = 0;
2638
2639
    /* All policies should begin with "@SECLEVEL=<N>" (N={0..5}) followed
2640
     * by bulk cipher list. */
2641
    if (XMEMCMP(crypto_policy.str, hdr, strlen(hdr)) != 0) {
2642
        WOLFSSL_MSG("error: crypto policy: invalid header");
2643
        return WOLFSSL_BAD_FILE;
2644
    }
2645
2646
    {
2647
        /* Extract the security level. */
2648
        char *       policy_mem = crypto_policy.str;
2649
        policy_mem += strlen(hdr);
2650
        sec_level = (int) (*policy_mem - '0');
2651
    }
2652
2653
    if (sec_level < MIN_WOLFSSL_SEC_LEVEL ||
2654
        sec_level > MAX_WOLFSSL_SEC_LEVEL) {
2655
        WOLFSSL_MSG_EX("error: invalid SECLEVEL: %d", sec_level);
2656
        return WOLFSSL_BAD_FILE;
2657
    }
2658
2659
    /* Remove trailing '\r' or '\n'. */
2660
    for (i = 0; i < MAX_WOLFSSL_CRYPTO_POLICY_SIZE; ++i) {
2661
        if (crypto_policy.str[i] == '\0') {
2662
            break;
2663
        }
2664
2665
        if (crypto_policy.str[i] == '\r' || crypto_policy.str[i] == '\n') {
2666
            crypto_policy.str[i] = '\0';
2667
            break;
2668
        }
2669
    }
2670
2671
    #if defined(DEBUG_WOLFSSL_VERBOSE)
2672
    WOLFSSL_MSG_EX("info: SECLEVEL=%d", sec_level);
2673
    WOLFSSL_MSG_EX("info: using crypto-policy file: %s, %ld", policy_file, sz);
2674
    #endif /* DEBUG_WOLFSSL_VERBOSE */
2675
2676
    crypto_policy.secLevel = sec_level;
2677
    crypto_policy.enabled = 1;
2678
2679
    return WOLFSSL_SUCCESS;
2680
}
2681
2682
#ifndef NO_FILESYSTEM
2683
/* Enables wolfSSL system wide crypto-policy, using the given policy
2684
 * file arg. If NULL is passed, then the default system crypto-policy
2685
 * file that was set at configure time will be used instead.
2686
 *
2687
 * While enabled:
2688
 *   - TLS methods, min key sizes, and cipher lists are all configured
2689
 *     automatically by the policy.
2690
 *   - Attempting to use lesser strength parameters will fail with
2691
 *     error CRYPTO_POLICY_FORBIDDEN.
2692
 *
2693
 * Disable with wolfSSL_crypto_policy_disable.
2694
 *
2695
 * Note: the wolfSSL_crypto_policy_X API are not thread safe, and should
2696
 * only be called at program init time.
2697
 *
2698
 * Returns WOLFSSL_SUCCESS on success.
2699
 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
2700
 * Returns < 0 on misc error.
2701
 * */
2702
int wolfSSL_crypto_policy_enable(const char * policy_file)
2703
{
2704
    XFILE   file;
2705
    long    sz = 0;
2706
    size_t  n_read = 0;
2707
2708
    WOLFSSL_ENTER("wolfSSL_crypto_policy_enable");
2709
2710
    if (wolfSSL_crypto_policy_is_enabled()) {
2711
        WOLFSSL_MSG_EX("error: crypto policy already enabled: %s",
2712
                       policy_file);
2713
        return CRYPTO_POLICY_FORBIDDEN;
2714
    }
2715
2716
    if (policy_file == NULL) {
2717
        /* Use the configure-time default if NULL passed. */
2718
        policy_file = WC_STRINGIFY(WOLFSSL_CRYPTO_POLICY_FILE);
2719
    }
2720
2721
    if (policy_file == NULL || *policy_file == '\0') {
2722
        WOLFSSL_MSG("error: crypto policy empty file");
2723
        return BAD_FUNC_ARG;
2724
    }
2725
2726
    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
2727
2728
    file = XFOPEN(policy_file, "rb");
2729
2730
    if (file == XBADFILE) {
2731
        WOLFSSL_MSG_EX("error: crypto policy file open failed: %s",
2732
                       policy_file);
2733
        return WOLFSSL_BAD_FILE;
2734
    }
2735
2736
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
2737
        WOLFSSL_MSG_EX("error: crypto policy file seek end failed: %s",
2738
                       policy_file);
2739
        XFCLOSE(file);
2740
        return WOLFSSL_BAD_FILE;
2741
    }
2742
2743
    sz = XFTELL(file);
2744
2745
    if (XFSEEK(file, 0, XSEEK_SET) != 0) {
2746
        WOLFSSL_MSG_EX("error: crypto policy file seek failed: %s",
2747
                       policy_file);
2748
        XFCLOSE(file);
2749
        return WOLFSSL_BAD_FILE;
2750
    }
2751
2752
    if (sz <= 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) {
2753
        WOLFSSL_MSG_EX("error: crypto policy file %s, invalid size: %ld",
2754
                       policy_file, sz);
2755
        XFCLOSE(file);
2756
        return WOLFSSL_BAD_FILE;
2757
    }
2758
2759
    n_read = XFREAD(crypto_policy.str, 1, sz, file);
2760
    XFCLOSE(file);
2761
2762
    if (n_read != (size_t) sz) {
2763
        WOLFSSL_MSG_EX("error: crypto policy file %s: read %zu, "
2764
                       "expected %ld", policy_file, n_read, sz);
2765
        return WOLFSSL_BAD_FILE;
2766
    }
2767
2768
    crypto_policy.str[n_read] = '\0';
2769
2770
    return crypto_policy_parse();
2771
}
2772
#endif /* ! NO_FILESYSTEM */
2773
2774
/* Same behavior as wolfSSL_crypto_policy_enable, but loads
2775
 * via memory buf instead of file.
2776
 *
2777
 * Returns WOLFSSL_SUCCESS on success.
2778
 * Returns CRYPTO_POLICY_FORBIDDEN if already enabled.
2779
 * Returns < 0 on misc error.
2780
 * */
2781
int wolfSSL_crypto_policy_enable_buffer(const char * buf)
2782
{
2783
    size_t sz = 0;
2784
2785
    WOLFSSL_ENTER("wolfSSL_crypto_policy_enable_buffer");
2786
2787
    if (wolfSSL_crypto_policy_is_enabled()) {
2788
        WOLFSSL_MSG_EX("error: crypto policy already enabled");
2789
        return CRYPTO_POLICY_FORBIDDEN;
2790
    }
2791
2792
    if (buf == NULL || *buf == '\0') {
2793
        return BAD_FUNC_ARG;
2794
    }
2795
2796
    sz = XSTRLEN(buf);
2797
2798
    if (sz == 0 || sz > MAX_WOLFSSL_CRYPTO_POLICY_SIZE) {
2799
        return BAD_FUNC_ARG;
2800
    }
2801
2802
    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
2803
    XMEMCPY(crypto_policy.str, buf, sz);
2804
2805
    return crypto_policy_parse();
2806
}
2807
2808
/* Returns whether the system wide crypto-policy is enabled.
2809
 *
2810
 * Returns 1 if enabled.
2811
 *         0 if disabled.
2812
 * */
2813
int wolfSSL_crypto_policy_is_enabled(void)
2814
{
2815
    WOLFSSL_ENTER("wolfSSL_crypto_policy_is_enabled");
2816
2817
    return crypto_policy.enabled == 1;
2818
}
2819
2820
/* Disables the system wide crypto-policy.
2821
 * note: SSL and CTX structures already instantiated will
2822
 * keep their security policy parameters. This will only
2823
 * affect new instantiations.
2824
 * */
2825
void wolfSSL_crypto_policy_disable(void)
2826
{
2827
    WOLFSSL_ENTER("wolfSSL_crypto_policy_disable");
2828
    crypto_policy.enabled = 0;
2829
    XMEMSET(&crypto_policy, 0, sizeof(crypto_policy));
2830
    return;
2831
}
2832
2833
/* Get the crypto-policy bulk cipher list string.
2834
 * String is not owned by caller, should not be freed.
2835
 *
2836
 * Returns pointer to bulk cipher list string.
2837
 * Returns NULL if NOT enabled, or on error.
2838
 * */
2839
const char * wolfSSL_crypto_policy_get_ciphers(void)
2840
{
2841
    WOLFSSL_ENTER("wolfSSL_crypto_policy_get_ciphers");
2842
2843
    if (crypto_policy.enabled == 1) {
2844
        /* The crypto policy config will have
2845
         * this form:
2846
         *   "@SECLEVEL=2:kEECDH:kRSA..." */
2847
        return crypto_policy.str;
2848
    }
2849
2850
    return NULL;
2851
}
2852
2853
/* Get the configured crypto-policy security level.
2854
 * A security level of 0 does not impose any additional
2855
 * restrictions.
2856
 *
2857
 * Returns 1 - 5 if enabled.
2858
 * Returns 0 if NOT enabled.
2859
 * */
2860
int wolfSSL_crypto_policy_get_level(void)
2861
{
2862
    if (crypto_policy.enabled == 1) {
2863
        return crypto_policy.secLevel;
2864
    }
2865
2866
    return 0;
2867
}
2868
2869
/* Get security level from ssl structure.
2870
 * @param ssl  a pointer to WOLFSSL structure
2871
 */
2872
int wolfSSL_get_security_level(const WOLFSSL * ssl)
2873
{
2874
    if (ssl == NULL) {
2875
        return BAD_FUNC_ARG;
2876
    }
2877
2878
    return ssl->secLevel;
2879
}
2880
2881
#ifndef NO_WOLFSSL_STUB
2882
/*
2883
 * Set security level (wolfSSL doesn't support setting the security level).
2884
 *
2885
 * The security level can only be set through a system wide crypto-policy
2886
 * with wolfSSL_crypto_policy_enable().
2887
 *
2888
 * @param ssl  a pointer to WOLFSSL structure
2889
 * @param level security level
2890
 */
2891
void wolfSSL_set_security_level(WOLFSSL * ssl, int level)
2892
{
2893
    WOLFSSL_ENTER("wolfSSL_set_security_level");
2894
    (void)ssl;
2895
    (void)level;
2896
}
2897
#endif /* !NO_WOLFSSL_STUB */
2898
2899
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
2900
2901
2902
#define WOLFSSL_SSL_LOAD_INCLUDED
2903
#include <src/ssl_load.c>
2904
2905
#define WOLFSSL_SSL_API_CRL_OCSP_INCLUDED
2906
#include "src/ssl_api_crl_ocsp.c"
2907
2908
2909
void wolfSSL_load_error_strings(void)
2910
0
{
2911
    /* compatibility only */
2912
0
}
2913
2914
2915
int wolfSSL_library_init(void)
2916
0
{
2917
0
    WOLFSSL_ENTER("wolfSSL_library_init");
2918
0
    if (wolfSSL_Init() == WOLFSSL_SUCCESS)
2919
0
        return WOLFSSL_SUCCESS;
2920
0
    else
2921
0
        return WOLFSSL_FATAL_ERROR;
2922
0
}
2923
2924
2925
#ifdef HAVE_SECRET_CALLBACK
2926
2927
int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
2928
{
2929
    WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
2930
    if (ssl == NULL)
2931
        return WOLFSSL_FAILURE;
2932
2933
    ssl->sessionSecretCb = cb;
2934
    ssl->sessionSecretCtx = ctx;
2935
    if (cb != NULL) {
2936
        /* If using a pre-set key, assume session resumption. */
2937
        ssl->session->sessionIDSz = 0;
2938
        ssl->options.resuming = 1;
2939
    }
2940
2941
    return WOLFSSL_SUCCESS;
2942
}
2943
2944
int wolfSSL_set_session_ticket_ext_cb(WOLFSSL* ssl, TicketParseCb cb,
2945
        void *ctx)
2946
{
2947
    WOLFSSL_ENTER("wolfSSL_set_session_ticket_ext_cb");
2948
    if (ssl == NULL)
2949
        return WOLFSSL_FAILURE;
2950
2951
    ssl->ticketParseCb = cb;
2952
    ssl->ticketParseCtx = ctx;
2953
2954
    return WOLFSSL_SUCCESS;
2955
}
2956
2957
int wolfSSL_set_secret_cb(WOLFSSL* ssl, TlsSecretCb cb, void* ctx)
2958
{
2959
    WOLFSSL_ENTER("wolfSSL_set_secret_cb");
2960
    if (ssl == NULL)
2961
        return WOLFSSL_FATAL_ERROR;
2962
2963
    ssl->tlsSecretCb = cb;
2964
    ssl->tlsSecretCtx = ctx;
2965
2966
    return WOLFSSL_SUCCESS;
2967
}
2968
2969
#ifdef SHOW_SECRETS
2970
int tlsShowSecrets(WOLFSSL* ssl, void* secret, int secretSz,
2971
        void* ctx)
2972
{
2973
    /* Wireshark Pre-Master-Secret Format:
2974
     *  CLIENT_RANDOM <clientrandom> <mastersecret>
2975
     */
2976
    const char* CLIENT_RANDOM_LABEL = "CLIENT_RANDOM";
2977
    int i, pmsPos = 0;
2978
    char pmsBuf[13 + 1 + 64 + 1 + 96 + 1 + 1];
2979
    byte clientRandom[RAN_LEN];
2980
    int clientRandomSz;
2981
2982
    (void)ctx;
2983
2984
    clientRandomSz = (int)wolfSSL_get_client_random(ssl, clientRandom,
2985
        sizeof(clientRandom));
2986
2987
    if (clientRandomSz <= 0) {
2988
        printf("Error getting server random %d\n", clientRandomSz);
2989
        return BAD_FUNC_ARG;
2990
    }
2991
2992
    XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%s ",
2993
        CLIENT_RANDOM_LABEL);
2994
    pmsPos += XSTRLEN(CLIENT_RANDOM_LABEL) + 1;
2995
    for (i = 0; i < clientRandomSz; i++) {
2996
        XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
2997
            clientRandom[i]);
2998
        pmsPos += 2;
2999
    }
3000
    XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, " ");
3001
    pmsPos += 1;
3002
    for (i = 0; i < secretSz; i++) {
3003
        XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "%02x",
3004
            ((byte*)secret)[i]);
3005
        pmsPos += 2;
3006
    }
3007
    XSNPRINTF(&pmsBuf[pmsPos], sizeof(pmsBuf) - pmsPos, "\n");
3008
    pmsPos += 1;
3009
3010
    /* print master secret */
3011
    puts(pmsBuf);
3012
3013
    #if !defined(NO_FILESYSTEM) && defined(WOLFSSL_SSLKEYLOGFILE)
3014
    {
3015
        const char* keyLogFile = WOLFSSL_SSLKEYLOGFILE_OUTPUT;
3016
        FILE* f;
3017
    #ifdef WOLFSSL_SSLKEYLOGFILE_USE_ENV
3018
        /* RFC 9850: prefer the SSLKEYLOGFILE environment variable so other
3019
         * tools can share the path, else use the compile-time path. XGETENV is
3020
         * NULL where environment access is unavailable. Opt-in so a build with
3021
         * the variable exported for other applications is not affected. */
3022
        const char* keyLogEnv = XGETENV("SSLKEYLOGFILE");
3023
        if (keyLogEnv != NULL && keyLogEnv[0] != '\0')
3024
            keyLogFile = keyLogEnv;
3025
    #endif
3026
        f = XFOPEN(keyLogFile, "a");
3027
        if (f != XBADFILE) {
3028
            XFWRITE(pmsBuf, 1, pmsPos, f);
3029
            XFCLOSE(f);
3030
        }
3031
    }
3032
    #endif
3033
    return 0;
3034
}
3035
#endif /* SHOW_SECRETS */
3036
3037
#endif
3038
3039
3040
#ifdef OPENSSL_EXTRA
3041
3042
/*
3043
 * check if the list has TLS13 and pre-TLS13 suites
3044
 * @param list cipher suite list that user want to set
3045
 *         (caller required to check for NULL)
3046
 * @return mixed: 0, only pre-TLS13: 1, only TLS13: 2
3047
 */
3048
static int CheckcipherList(const char* list)
3049
{
3050
    int ret;
3051
    int findTLSv13Suites = 0;
3052
    int findbeforeSuites = 0;
3053
    byte cipherSuite0;
3054
    byte cipherSuite1;
3055
    int flags;
3056
    char* next = (char*)list;
3057
3058
    do {
3059
        char*  current = next;
3060
        char   name[MAX_SUITE_NAME + 1];
3061
        word32 length = MAX_SUITE_NAME;
3062
        word32 current_length;
3063
        byte major = INVALID_BYTE;
3064
        byte minor = INVALID_BYTE;
3065
3066
        next   = XSTRSTR(next, ":");
3067
3068
        if (next) {
3069
            current_length = (word32)(next - current);
3070
            ++next; /* increment to skip ':' */
3071
        }
3072
        else {
3073
            current_length = (word32)XSTRLEN(current);
3074
        }
3075
3076
        if (current_length == 0) {
3077
            break;
3078
        }
3079
3080
        if (current_length < length) {
3081
            length = current_length;
3082
        }
3083
        XMEMCPY(name, current, length);
3084
        name[length] = 0;
3085
3086
        if (XSTRCMP(name, "ALL") == 0 ||
3087
            XSTRCMP(name, "DEFAULT") == 0 ||
3088
            XSTRCMP(name, "HIGH") == 0)
3089
        {
3090
            findTLSv13Suites = 1;
3091
            findbeforeSuites = 1;
3092
            break;
3093
        }
3094
3095
        ret = GetCipherSuiteFromName(name, &cipherSuite0,
3096
                &cipherSuite1, &major, &minor, &flags);
3097
        if (ret == 0) {
3098
            if (cipherSuite0 == TLS13_BYTE || minor == TLSv1_3_MINOR) {
3099
                /* TLSv13 suite */
3100
                findTLSv13Suites = 1;
3101
            }
3102
            else {
3103
                findbeforeSuites = 1;
3104
            }
3105
        }
3106
3107
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
3108
        /* check if mixed due to names like RSA:ECDHE+AESGCM etc. */
3109
        if (ret != 0) {
3110
            char* subStr = name;
3111
            char* subStrNext;
3112
3113
            do {
3114
                subStrNext = XSTRSTR(subStr, "+");
3115
3116
                if ((XSTRCMP(subStr, "ECDHE") == 0) ||
3117
                    (XSTRCMP(subStr, "RSA") == 0)) {
3118
                    return 0;
3119
                }
3120
3121
                if (subStrNext && (XSTRLEN(subStrNext) > 0)) {
3122
                    subStr = subStrNext + 1; /* +1 to skip past '+' */
3123
                }
3124
            } while (subStrNext != NULL);
3125
        }
3126
    #endif
3127
3128
        if (findTLSv13Suites == 1 && findbeforeSuites == 1) {
3129
            /* list has mixed suites */
3130
            return 0;
3131
        }
3132
    } while (next);
3133
3134
    if (findTLSv13Suites == 0 && findbeforeSuites == 1) {
3135
        ret = 1;/* only before TLSv13 suites */
3136
    }
3137
    else if (findTLSv13Suites == 1 && findbeforeSuites == 0) {
3138
        ret = 2;/* only TLSv13 suties */
3139
    }
3140
    else {
3141
        ret = 0;/* handle as mixed */
3142
    }
3143
    return ret;
3144
}
3145
3146
/* parse some bulk lists like !eNULL / !aNULL
3147
 *
3148
 * returns WOLFSSL_SUCCESS on success and sets the cipher suite list
3149
 */
3150
static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
3151
        Suites* suites, const char* list)
3152
{
3153
    int     ret = 0;
3154
    int     listattribute = 0;
3155
    int     tls13Only = 0;
3156
    WC_DECLARE_VAR(suitesCpy, byte, WOLFSSL_MAX_SUITE_SZ, 0);
3157
    word16  suitesCpySz = 0;
3158
    word16  i = 0;
3159
    word16  j = 0;
3160
3161
    if (suites == NULL || list == NULL) {
3162
        WOLFSSL_MSG("NULL argument");
3163
        return WOLFSSL_FAILURE;
3164
    }
3165
3166
    listattribute = CheckcipherList(list);
3167
3168
    if (listattribute == 0) {
3169
       /* list has mixed(pre-TLSv13 and TLSv13) suites
3170
        * update cipher suites the same as before
3171
        */
3172
        return (SetCipherList_ex(ctx, ssl, suites, list)) ? WOLFSSL_SUCCESS :
3173
        WOLFSSL_FAILURE;
3174
    }
3175
    else if (listattribute == 1) {
3176
       /* list has only pre-TLSv13 suites.
3177
        * Only update before TLSv13 suites.
3178
        */
3179
        tls13Only = 0;
3180
    }
3181
    else if (listattribute == 2) {
3182
       /* list has only TLSv13 suites. Only update TLv13 suites
3183
        * simulate set_ciphersuites() compatibility layer API
3184
        */
3185
        tls13Only = 1;
3186
        if ((ctx != NULL && !IsAtLeastTLSv1_3(ctx->method->version) &&
3187
                !ctx->method->downgrade) ||
3188
                (ssl != NULL && !IsAtLeastTLSv1_3(ssl->version) &&
3189
                (!ssl->options.downgrade || ssl->options.versionSet))) {
3190
            /* Fail only for methods that can never reach TLS 1.3 (downgrade
3191
             * disabled) or when SetVersion() put the maximum below TLS 1.3.
3192
             * A minimum version does not raise the maximum, so it is not
3193
             * considered here. A version merely capped via
3194
             * set_max_proto_version() still silently ignores the list,
3195
             * matching OpenSSL. */
3196
            WOLFSSL_MSG("Cipher list has only TLS 1.3 suites but TLS 1.3 "
3197
                        "is not negotiable");
3198
            return WOLFSSL_FAILURE;
3199
        }
3200
    }
3201
3202
    /* list contains ciphers either only for TLS 1.3 or <= TLS 1.2 */
3203
#ifdef WOLFSSL_SMALL_STACK
3204
    if (suites->suiteSz > 0) {
3205
        suitesCpy = (byte*)XMALLOC(suites->suiteSz, NULL,
3206
                DYNAMIC_TYPE_TMP_BUFFER);
3207
        if (suitesCpy == NULL) {
3208
            return WOLFSSL_FAILURE;
3209
        }
3210
3211
        XMEMSET(suitesCpy, 0, suites->suiteSz);
3212
    }
3213
#else
3214
        XMEMSET(suitesCpy, 0, sizeof(suitesCpy));
3215
#endif
3216
3217
    if (suites->suiteSz > 0)
3218
        XMEMCPY(suitesCpy, suites->suites, suites->suiteSz);
3219
    suitesCpySz = suites->suiteSz;
3220
3221
    ret = SetCipherList_ex(ctx, ssl, suites, list);
3222
    if (ret != 1) {
3223
        WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3224
        return WOLFSSL_FAILURE;
3225
    }
3226
3227
    /* The idea in this section is that OpenSSL has two API to set ciphersuites.
3228
     *   - SSL_CTX_set_cipher_list for setting TLS <= 1.2 suites
3229
     *   - SSL_CTX_set_ciphersuites for setting TLS 1.3 suites
3230
     * Since we direct both API here we attempt to provide API compatibility. If
3231
     * we only get suites from <= 1.2 or == 1.3 then we will only update those
3232
     * suites and keep the suites from the other group.
3233
     * If a single version is in use, skip preserving the other group's
3234
     * suites. A min version makes it a range again, so both groups are kept. */
3235
    if ((ssl != NULL && (!ssl->options.downgrade ||
3236
            (ssl->options.versionSet && !ssl->options.minVersionSet))) ||
3237
        (ctx != NULL && !ctx->method->downgrade)) {
3238
        /* One version only - don't preserve the other group's suites */
3239
        WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3240
        return ret;
3241
    }
3242
3243
    for (i = 0; i < suitesCpySz &&
3244
                suites->suiteSz <= (WOLFSSL_MAX_SUITE_SZ - SUITE_LEN); i += 2) {
3245
        /* Check for duplicates */
3246
        int duplicate = 0;
3247
        for (j = 0; j < suites->suiteSz; j += 2) {
3248
            if (suitesCpy[i] == suites->suites[j] &&
3249
                    suitesCpy[i+1] == suites->suites[j+1]) {
3250
                duplicate = 1;
3251
                break;
3252
            }
3253
        }
3254
        if (!duplicate) {
3255
            if (tls13Only) {
3256
                /* Updating TLS 1.3 ciphers */
3257
                if (suitesCpy[i] != TLS13_BYTE) {
3258
                    /* Only copy over <= TLS 1.2 ciphers */
3259
                    /* TLS 1.3 ciphers take precedence */
3260
                    suites->suites[suites->suiteSz++] = suitesCpy[i];
3261
                    suites->suites[suites->suiteSz++] = suitesCpy[i+1];
3262
                }
3263
            }
3264
            else {
3265
                /* Updating <= TLS 1.2 ciphers */
3266
                if (suitesCpy[i] == TLS13_BYTE) {
3267
                    /* Only copy over TLS 1.3 ciphers */
3268
                    /* TLS 1.3 ciphers take precedence */
3269
                    XMEMMOVE(suites->suites + SUITE_LEN, suites->suites,
3270
                             suites->suiteSz);
3271
                    suites->suites[0] = suitesCpy[i];
3272
                    suites->suites[1] = suitesCpy[i+1];
3273
                    suites->suiteSz += 2;
3274
                }
3275
            }
3276
        }
3277
    }
3278
3279
    WC_FREE_VAR_EX(suitesCpy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3280
    return ret;
3281
}
3282
3283
#endif
3284
3285
3286
int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
3287
0
{
3288
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
3289
3290
0
    if (ctx == NULL)
3291
0
        return WOLFSSL_FAILURE;
3292
3293
0
    if (AllocateCtxSuites(ctx) != 0)
3294
0
        return WOLFSSL_FAILURE;
3295
3296
#ifdef OPENSSL_EXTRA
3297
    return wolfSSL_parse_cipher_list(ctx, NULL, ctx->suites, list);
3298
#else
3299
0
    return (SetCipherList(ctx, ctx->suites, list)) ?
3300
0
        WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3301
0
#endif
3302
0
}
3303
3304
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
3305
int wolfSSL_CTX_set_cipher_list_bytes(WOLFSSL_CTX* ctx, const byte* list,
3306
                                      const int listSz)
3307
{
3308
    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list_bytes");
3309
3310
    if (ctx == NULL)
3311
        return WOLFSSL_FAILURE;
3312
3313
    if (AllocateCtxSuites(ctx) != 0)
3314
        return WOLFSSL_FAILURE;
3315
3316
    return (SetCipherListFromBytes(ctx, ctx->suites, list, listSz)) ?
3317
        WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3318
}
3319
#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
3320
3321
int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
3322
0
{
3323
0
    WOLFSSL_ENTER("wolfSSL_set_cipher_list");
3324
3325
0
    if (ssl == NULL || ssl->ctx == NULL) {
3326
0
        return WOLFSSL_FAILURE;
3327
0
    }
3328
3329
0
    if (AllocateSuites(ssl) != 0)
3330
0
        return WOLFSSL_FAILURE;
3331
3332
#ifdef OPENSSL_EXTRA
3333
    return wolfSSL_parse_cipher_list(NULL, ssl, ssl->suites, list);
3334
#else
3335
0
    return (SetCipherList_ex(NULL, ssl, ssl->suites, list)) ?
3336
0
        WOLFSSL_SUCCESS :
3337
0
        WOLFSSL_FAILURE;
3338
0
#endif
3339
0
}
3340
3341
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
3342
int wolfSSL_set_cipher_list_bytes(WOLFSSL* ssl, const byte* list,
3343
                                  const int listSz)
3344
{
3345
    WOLFSSL_ENTER("wolfSSL_set_cipher_list_bytes");
3346
3347
    if (ssl == NULL || ssl->ctx == NULL) {
3348
        return WOLFSSL_FAILURE;
3349
    }
3350
3351
    if (AllocateSuites(ssl) != 0)
3352
        return WOLFSSL_FAILURE;
3353
3354
    return (SetCipherListFromBytes(ssl->ctx, ssl->suites, list, listSz))
3355
           ? WOLFSSL_SUCCESS
3356
           : WOLFSSL_FAILURE;
3357
}
3358
#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
3359
3360
3361
#ifdef HAVE_KEYING_MATERIAL
3362
3363
#define TLS_PRF_LABEL_CLIENT_FINISHED     "client finished"
3364
#define TLS_PRF_LABEL_SERVER_FINISHED     "server finished"
3365
#define TLS_PRF_LABEL_MASTER_SECRET       "master secret"
3366
#define TLS_PRF_LABEL_EXT_MASTER_SECRET   "extended master secret"
3367
#define TLS_PRF_LABEL_KEY_EXPANSION       "key expansion"
3368
3369
static const struct ForbiddenLabels {
3370
    const char* label;
3371
    size_t labelLen;
3372
} forbiddenLabels[] = {
3373
    {TLS_PRF_LABEL_CLIENT_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_CLIENT_FINISHED)},
3374
    {TLS_PRF_LABEL_SERVER_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_SERVER_FINISHED)},
3375
    {TLS_PRF_LABEL_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_MASTER_SECRET)},
3376
    {TLS_PRF_LABEL_EXT_MASTER_SECRET,
3377
     XSTR_SIZEOF(TLS_PRF_LABEL_EXT_MASTER_SECRET)},
3378
    {TLS_PRF_LABEL_KEY_EXPANSION, XSTR_SIZEOF(TLS_PRF_LABEL_KEY_EXPANSION)},
3379
    {NULL, 0},
3380
};
3381
3382
/**
3383
 * Implement RFC 5705
3384
 * TLS 1.3 uses a different exporter definition (section 7.5 of RFC 8446)
3385
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
3386
 */
3387
int wolfSSL_export_keying_material(WOLFSSL *ssl,
3388
        unsigned char *out, size_t outLen,
3389
        const char *label, size_t labelLen,
3390
        const unsigned char *context, size_t contextLen,
3391
        int use_context)
3392
{
3393
    byte*  seed = NULL;
3394
    word32 seedLen;
3395
    const struct ForbiddenLabels* fl;
3396
3397
    WOLFSSL_ENTER("wolfSSL_export_keying_material");
3398
3399
    if (ssl == NULL || out == NULL || label == NULL ||
3400
            (use_context && contextLen && context == NULL)) {
3401
        WOLFSSL_MSG("Bad argument");
3402
        return WOLFSSL_FAILURE;
3403
    }
3404
3405
    /* RFC 8446 Section 7.5 / RFC 5705: keying-material exporters derive from
3406
     * exporter_master_secret, which exists only after the handshake is
3407
     * complete. Refuse the export until the handshake has completed so that
3408
     * a premature call cannot derive material from an uninitialised
3409
     * exporterSecret buffer. */
3410
    if (ssl->options.handShakeDone == 0) {
3411
        WOLFSSL_MSG("Handshake not complete; refusing keying-material export");
3412
        return WOLFSSL_FAILURE;
3413
    }
3414
3415
    /* Sanity check contextLen to prevent integer overflow when cast to word32
3416
     * and to ensure it fits in the 2-byte length encoding (max 65535). */
3417
    if (use_context && contextLen > WOLFSSL_MAX_16BIT) {
3418
        WOLFSSL_MSG("contextLen too large");
3419
        return WOLFSSL_FAILURE;
3420
    }
3421
3422
    /* clientRandom + serverRandom
3423
     * OR
3424
     * clientRandom + serverRandom + ctx len encoding + ctx */
3425
    seedLen = !use_context ? (word32)SEED_LEN :
3426
                             (word32)SEED_LEN + 2 + (word32)contextLen;
3427
3428
    if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
3429
        WOLFSSL_MSG("To export keying material wolfSSL needs to keep handshake "
3430
                    "data. Call wolfSSL_KeepArrays before attempting to "
3431
                    "export keyid material.");
3432
        return WOLFSSL_FAILURE;
3433
    }
3434
3435
    /* check forbidden labels */
3436
    for (fl = &forbiddenLabels[0]; fl->label != NULL; fl++) {
3437
        if (labelLen >= fl->labelLen &&
3438
                XMEMCMP(label, fl->label, fl->labelLen) == 0) {
3439
            WOLFSSL_MSG("Forbidden label");
3440
            return WOLFSSL_FAILURE;
3441
        }
3442
    }
3443
3444
#ifdef WOLFSSL_TLS13
3445
    if (IsAtLeastTLSv1_3(ssl->version)) {
3446
        /* Path for TLS 1.3 */
3447
        if (!use_context) {
3448
            contextLen = 0;
3449
            context = (byte*)""; /* Give valid pointer for 0 length memcpy */
3450
        }
3451
3452
        if (Tls13_Exporter(ssl, out, (word32)outLen, label, labelLen,
3453
                context, contextLen) != 0) {
3454
            WOLFSSL_MSG("Tls13_Exporter error");
3455
            return WOLFSSL_FAILURE;
3456
        }
3457
        return WOLFSSL_SUCCESS;
3458
    }
3459
#endif
3460
3461
    /* Path for <=TLS 1.2 */
3462
    seed = (byte*)XMALLOC(seedLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3463
    if (seed == NULL) {
3464
        WOLFSSL_MSG("malloc error");
3465
        return WOLFSSL_FAILURE;
3466
    }
3467
3468
    XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
3469
    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
3470
3471
    if (use_context) {
3472
        /* Encode len in big endian */
3473
        seed[SEED_LEN    ] = (contextLen >> 8) & 0xFF;
3474
        seed[SEED_LEN + 1] = (contextLen) & 0xFF;
3475
        if (contextLen) {
3476
            /* 0 length context is allowed */
3477
            XMEMCPY(seed + SEED_LEN + 2, context, contextLen);
3478
        }
3479
    }
3480
3481
    PRIVATE_KEY_UNLOCK();
3482
    if (wc_PRF_TLS(out, (word32)outLen, ssl->arrays->masterSecret, SECRET_LEN,
3483
            (byte*)label, (word32)labelLen, seed, seedLen,
3484
            IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, ssl->heap,
3485
            ssl->devId) != 0) {
3486
        WOLFSSL_MSG("wc_PRF_TLS error");
3487
        PRIVATE_KEY_LOCK();
3488
        XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3489
        return WOLFSSL_FAILURE;
3490
    }
3491
    PRIVATE_KEY_LOCK();
3492
3493
    XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3494
    return WOLFSSL_SUCCESS;
3495
}
3496
#endif /* HAVE_KEYING_MATERIAL */
3497
3498
3499
/* EITHER SIDE METHODS */
3500
#if !defined(NO_TLS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE))
3501
    WOLFSSL_METHOD* wolfSSLv23_method(void)
3502
    {
3503
        return wolfSSLv23_method_ex(NULL);
3504
    }
3505
    WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap)
3506
    {
3507
        WOLFSSL_METHOD* m = NULL;
3508
        WOLFSSL_ENTER("wolfSSLv23_method");
3509
    #if !defined(NO_WOLFSSL_CLIENT)
3510
        m = wolfSSLv23_client_method_ex(heap);
3511
    #elif !defined(NO_WOLFSSL_SERVER)
3512
        m = wolfSSLv23_server_method_ex(heap);
3513
    #else
3514
        (void)heap;
3515
    #endif
3516
        if (m != NULL) {
3517
            m->side = WOLFSSL_NEITHER_END;
3518
        }
3519
3520
        return m;
3521
    }
3522
3523
    #ifndef NO_OLD_TLS
3524
    #ifdef WOLFSSL_ALLOW_SSLV3
3525
    WOLFSSL_METHOD* wolfSSLv3_method(void)
3526
    {
3527
        return wolfSSLv3_method_ex(NULL);
3528
    }
3529
    WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap)
3530
    {
3531
        WOLFSSL_METHOD* m = NULL;
3532
        WOLFSSL_ENTER("wolfSSLv3_method_ex");
3533
    #if !defined(NO_WOLFSSL_CLIENT)
3534
        m = wolfSSLv3_client_method_ex(heap);
3535
    #elif !defined(NO_WOLFSSL_SERVER)
3536
        m = wolfSSLv3_server_method_ex(heap);
3537
    #endif
3538
        if (m != NULL) {
3539
            m->side = WOLFSSL_NEITHER_END;
3540
        }
3541
3542
        return m;
3543
    }
3544
    #endif
3545
    #endif
3546
#endif /* !NO_TLS && (OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE) */
3547
3548
/* client only parts */
3549
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS)
3550
3551
    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
3552
    WOLFSSL_METHOD* wolfSSLv2_client_method(void)
3553
    {
3554
        WOLFSSL_STUB("wolfSSLv2_client_method");
3555
        return NULL;
3556
    }
3557
    #endif
3558
3559
    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
3560
    WOLFSSL_METHOD* wolfSSLv3_client_method(void)
3561
    {
3562
        return wolfSSLv3_client_method_ex(NULL);
3563
    }
3564
    WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
3565
    {
3566
        WOLFSSL_METHOD* method =
3567
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
3568
                                                     heap, DYNAMIC_TYPE_METHOD);
3569
        (void)heap;
3570
        WOLFSSL_ENTER("wolfSSLv3_client_method_ex");
3571
        if (method)
3572
            InitSSL_Method(method, MakeSSLv3());
3573
        return method;
3574
    }
3575
    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
3576
3577
3578
    WOLFSSL_METHOD* wolfSSLv23_client_method(void)
3579
0
    {
3580
0
        return wolfSSLv23_client_method_ex(NULL);
3581
0
    }
3582
    WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
3583
0
    {
3584
0
        WOLFSSL_METHOD* method =
3585
0
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
3586
0
                                                     heap, DYNAMIC_TYPE_METHOD);
3587
0
        (void)heap;
3588
0
        WOLFSSL_ENTER("wolfSSLv23_client_method_ex");
3589
0
        if (method) {
3590
0
    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \
3591
0
        defined(WOLFSSL_SHA512)
3592
0
        #if defined(WOLFSSL_TLS13)
3593
0
            InitSSL_Method(method, MakeTLSv1_3());
3594
        #elif !defined(WOLFSSL_NO_TLS12)
3595
            InitSSL_Method(method, MakeTLSv1_2());
3596
        #elif !defined(NO_OLD_TLS)
3597
            InitSSL_Method(method, MakeTLSv1_1());
3598
        #endif
3599
    #else
3600
        #ifndef NO_OLD_TLS
3601
            InitSSL_Method(method, MakeTLSv1_1());
3602
        #endif
3603
    #endif
3604
0
    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
3605
0
            method->downgrade = 1;
3606
0
    #endif
3607
0
        }
3608
0
        return method;
3609
0
    }
3610
3611
3612
#endif /* !NO_WOLFSSL_CLIENT && !NO_TLS */
3613
/* end client only parts */
3614
3615
/* server only parts */
3616
#if !defined(NO_WOLFSSL_SERVER) && !defined(NO_TLS)
3617
3618
    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
3619
    WOLFSSL_METHOD* wolfSSLv2_server_method(void)
3620
    {
3621
        WOLFSSL_STUB("wolfSSLv2_server_method");
3622
        return 0;
3623
    }
3624
    #endif
3625
3626
    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
3627
    WOLFSSL_METHOD* wolfSSLv3_server_method(void)
3628
    {
3629
        return wolfSSLv3_server_method_ex(NULL);
3630
    }
3631
    WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
3632
    {
3633
        WOLFSSL_METHOD* method =
3634
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
3635
                                                     heap, DYNAMIC_TYPE_METHOD);
3636
        (void)heap;
3637
        WOLFSSL_ENTER("wolfSSLv3_server_method_ex");
3638
        if (method) {
3639
            InitSSL_Method(method, MakeSSLv3());
3640
            method->side = WOLFSSL_SERVER_END;
3641
        }
3642
        return method;
3643
    }
3644
    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
3645
3646
    WOLFSSL_METHOD* wolfSSLv23_server_method(void)
3647
0
    {
3648
0
        return wolfSSLv23_server_method_ex(NULL);
3649
0
    }
3650
3651
    WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
3652
0
    {
3653
0
        WOLFSSL_METHOD* method =
3654
0
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
3655
0
                                                     heap, DYNAMIC_TYPE_METHOD);
3656
0
        (void)heap;
3657
0
        WOLFSSL_ENTER("wolfSSLv23_server_method_ex");
3658
0
        if (method) {
3659
0
    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || \
3660
0
        defined(WOLFSSL_SHA512)
3661
0
        #ifdef WOLFSSL_TLS13
3662
0
            InitSSL_Method(method, MakeTLSv1_3());
3663
        #elif !defined(WOLFSSL_NO_TLS12)
3664
            InitSSL_Method(method, MakeTLSv1_2());
3665
        #elif !defined(NO_OLD_TLS)
3666
            InitSSL_Method(method, MakeTLSv1_1());
3667
        #endif
3668
    #else
3669
        #ifndef NO_OLD_TLS
3670
            InitSSL_Method(method, MakeTLSv1_1());
3671
        #else
3672
            #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
3673
        #endif
3674
    #endif
3675
0
    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
3676
0
            method->downgrade = 1;
3677
0
    #endif
3678
0
            method->side      = WOLFSSL_SERVER_END;
3679
0
        }
3680
0
        return method;
3681
0
    }
3682
3683
3684
3685
#endif /* !NO_WOLFSSL_SERVER && !NO_TLS */
3686
/* end server only parts */
3687
3688
#define WOLFSSL_SSL_API_HS_INCLUDED
3689
#include "src/ssl_api_hs.c"
3690
3691
3692
3693
WOLFSSL_ABI
3694
int wolfSSL_Cleanup(void)
3695
0
{
3696
0
    int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
3697
0
    int release = 0;
3698
0
#if !defined(NO_SESSION_CACHE)
3699
0
    int i;
3700
0
    int j;
3701
0
#endif
3702
3703
0
    WOLFSSL_ENTER("wolfSSL_Cleanup");
3704
3705
#ifndef WOLFSSL_MUTEX_INITIALIZER
3706
    if (inits_count_mutex_valid == 1) {
3707
#endif
3708
0
        if (wc_LockMutex(&inits_count_mutex) != 0) {
3709
0
            WOLFSSL_MSG("Bad Lock Mutex count");
3710
0
            return BAD_MUTEX_E;
3711
0
        }
3712
#ifndef WOLFSSL_MUTEX_INITIALIZER
3713
    }
3714
#endif
3715
3716
0
    if (initRefCount > 0) {
3717
0
        initRefCount = initRefCount - 1;
3718
0
        if (initRefCount == 0)
3719
0
            release = 1;
3720
0
    }
3721
3722
#ifndef WOLFSSL_MUTEX_INITIALIZER
3723
    if (inits_count_mutex_valid == 1) {
3724
#endif
3725
0
        wc_UnLockMutex(&inits_count_mutex);
3726
#ifndef WOLFSSL_MUTEX_INITIALIZER
3727
    }
3728
#endif
3729
3730
0
    if (!release)
3731
0
        return ret;
3732
3733
#if defined(WOLFSSL_SYS_CRYPTO_POLICY)
3734
    wolfSSL_crypto_policy_disable();
3735
#endif /* WOLFSSL_SYS_CRYPTO_POLICY */
3736
3737
#ifdef OPENSSL_EXTRA
3738
    wolfSSL_BN_free_one();
3739
#endif
3740
3741
0
#ifndef NO_SESSION_CACHE
3742
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
3743
    for (i = 0; i < SESSION_ROWS; ++i) {
3744
        if ((SessionCache[i].lock_valid == 1) &&
3745
            (wc_FreeRwLock(&SessionCache[i].row_lock) != 0)) {
3746
            if (ret == WOLFSSL_SUCCESS)
3747
                ret = BAD_MUTEX_E;
3748
        }
3749
        SessionCache[i].lock_valid = 0;
3750
    }
3751
    #else
3752
0
    if ((session_lock_valid == 1) && (wc_FreeRwLock(&session_lock) != 0)) {
3753
0
        if (ret == WOLFSSL_SUCCESS)
3754
0
            ret = BAD_MUTEX_E;
3755
0
    }
3756
0
    session_lock_valid = 0;
3757
0
    #endif
3758
0
    for (i = 0; i < SESSION_ROWS; i++) {
3759
0
        for (j = 0; j < SESSIONS_PER_ROW; j++) {
3760
    #ifdef SESSION_CACHE_DYNAMIC_MEM
3761
            if (SessionCache[i].Sessions[j]) {
3762
                EvictSessionFromCache(SessionCache[i].Sessions[j]);
3763
                XFREE(SessionCache[i].Sessions[j], SessionCache[i].heap,
3764
                      DYNAMIC_TYPE_SESSION);
3765
                SessionCache[i].Sessions[j] = NULL;
3766
            }
3767
    #else
3768
0
            EvictSessionFromCache(&SessionCache[i].Sessions[j]);
3769
0
    #endif
3770
0
        }
3771
0
    }
3772
0
    #ifndef NO_CLIENT_CACHE
3773
    #ifndef WOLFSSL_MUTEX_INITIALIZER
3774
    if ((clisession_mutex_valid == 1) &&
3775
        (wc_FreeMutex(&clisession_mutex) != 0)) {
3776
        if (ret == WOLFSSL_SUCCESS)
3777
            ret = BAD_MUTEX_E;
3778
    }
3779
    clisession_mutex_valid = 0;
3780
    #endif
3781
0
    #endif
3782
0
#endif /* !NO_SESSION_CACHE */
3783
3784
#if !defined(WOLFSSL_MUTEX_INITIALIZER) && \
3785
      !WOLFSSL_CLEANUP_THREADSAFE_BY_ATOMIC_OPS
3786
    if ((inits_count_mutex_valid == 1) &&
3787
            (wc_FreeMutex(&inits_count_mutex) != 0)) {
3788
        if (ret == WOLFSSL_SUCCESS)
3789
            ret = BAD_MUTEX_E;
3790
    }
3791
    inits_count_mutex_valid = 0;
3792
#endif
3793
3794
#ifdef OPENSSL_EXTRA
3795
    wolfSSL_RAND_Cleanup();
3796
#endif
3797
3798
0
    if (wolfCrypt_Cleanup() != 0) {
3799
0
        WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
3800
0
        if (ret == WOLFSSL_SUCCESS)
3801
0
            ret = WC_CLEANUP_E;
3802
0
    }
3803
3804
#if FIPS_VERSION_GE(5,1)
3805
    if (wolfCrypt_SetPrivateKeyReadEnable_fips(0, WC_KEYTYPE_ALL) < 0) {
3806
        if (ret == WOLFSSL_SUCCESS)
3807
            ret = WC_CLEANUP_E;
3808
    }
3809
#endif
3810
3811
0
#ifdef HAVE_GLOBAL_RNG
3812
#ifndef WOLFSSL_MUTEX_INITIALIZER
3813
    if ((globalRNGMutex_valid == 1) && (wc_FreeMutex(&globalRNGMutex) != 0)) {
3814
        if (ret == WOLFSSL_SUCCESS)
3815
            ret = BAD_MUTEX_E;
3816
    }
3817
    globalRNGMutex_valid = 0;
3818
#endif /* !WOLFSSL_MUTEX_INITIALIZER */
3819
3820
    #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
3821
    wolfSSL_FIPS_drbg_free(gDrbgDefCtx);
3822
    gDrbgDefCtx = NULL;
3823
    #endif
3824
0
#endif
3825
3826
#ifdef HAVE_EX_DATA_CRYPTO
3827
    crypto_ex_cb_free(crypto_ex_cb_ctx_session);
3828
    crypto_ex_cb_ctx_session = NULL;
3829
#endif
3830
3831
#ifdef WOLFSSL_MEM_FAIL_COUNT
3832
    wc_MemFailCount_Free();
3833
#endif
3834
3835
0
    return ret;
3836
0
}
3837
3838
/* Returns 1 if name is a syntactically valid DNS FQDN per RFC 952/1123.
3839
 *
3840
 * Rules enforced:
3841
 *   - Total effective length (excluding optional trailing dot) in [1, 253]
3842
 *   - Each label is 1-63 octets of [a-zA-Z0-9-], with _ allowed in all but
3843
 *     the last label.
3844
 *   - No label starts or ends with '-'
3845
 *   - At least two labels (single-label names are not "fully qualified")
3846
 *   - Final label (TLD) contains at least one letter (rejects all-numeric
3847
 *     strings that could be confused with IPv4 literals, and matches the
3848
 *     ICANN constraint that TLDs are alphabetic)
3849
 *   - Optional trailing dot is accepted (absolute FQDN form)
3850
 *   - Internationalized names are valid in their ACE/punycode (xn--) form
3851
 */
3852
int wolfssl_local_IsValidFQDN(const char* name, word32 nameSz)
3853
0
{
3854
0
    word32 i;
3855
0
    int labelLen = 0;
3856
0
    int labelCount = 0;
3857
0
    int curLabelHasAlpha = 0;
3858
0
    int curLabelHasUnderscore = 0;
3859
3860
0
    if (name == NULL || nameSz == 0)
3861
0
        return 0;
3862
3863
    /* Strip a single optional trailing dot before measuring.  "example.com."
3864
     * is the absolute form of the same FQDN.
3865
     */
3866
0
    if (name[nameSz - 1] == '.')
3867
0
        --nameSz;
3868
3869
0
    if (nameSz < 1 || nameSz > 253)
3870
0
        return 0;
3871
3872
0
    for (i = 0; i < nameSz; i++) {
3873
0
        byte c = (byte)name[i];
3874
3875
0
        if (c == '.') {
3876
0
            if (labelLen == 0 || name[i - 1] == '-')
3877
0
                return 0;
3878
0
            ++labelCount;
3879
0
            labelLen = 0;
3880
0
            curLabelHasAlpha = 0;
3881
0
            curLabelHasUnderscore = 0;
3882
0
            continue;
3883
0
        }
3884
3885
0
        if (++labelLen > 63)
3886
0
            return 0;
3887
3888
0
        if (c == '-') {
3889
0
            if (labelLen == 1)
3890
0
                return 0;
3891
0
        }
3892
0
        else if (((c | 0x20) >= 'a') && ((c | 0x20) <= 'z')) {
3893
0
            curLabelHasAlpha = 1;
3894
0
        }
3895
0
        else if (c == '_') {
3896
0
            curLabelHasUnderscore = 1;
3897
0
        }
3898
0
        else if ((c < '0') || (c > '9')) {
3899
0
            return 0;
3900
0
        }
3901
0
    }
3902
3903
    /* Final label (no trailing dot in the effective range to close it) */
3904
0
    if ((labelLen == 0) || (name[nameSz - 1] == '-') || curLabelHasUnderscore)
3905
0
        return 0;
3906
0
    ++labelCount;
3907
3908
0
    return ((labelCount > 1) && curLabelHasAlpha);
3909
0
}
3910
3911
/* call before SSL_connect, if verifying will add name check to
3912
   date check and signature check */
3913
WOLFSSL_ABI
3914
int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
3915
0
{
3916
0
    size_t dn_len;
3917
3918
0
    WOLFSSL_ENTER("wolfSSL_check_domain_name");
3919
3920
0
    if (ssl == NULL || dn == NULL) {
3921
0
        WOLFSSL_MSG("Bad function argument: NULL");
3922
0
        return WOLFSSL_FAILURE;
3923
0
    }
3924
3925
0
    dn_len = XSTRLEN(dn);
3926
3927
0
    if ((! wolfssl_local_IsValidFQDN(dn, (word32)dn_len)) &&
3928
0
        (XSTRCMP(dn, "localhost") != 0))
3929
0
    {
3930
0
        WOLFSSL_MSG("Bad function argument: fails wolfssl_local_IsValidFQDN");
3931
0
        return WOLFSSL_FAILURE;
3932
0
    }
3933
3934
0
    if (ssl->buffers.domainName.buffer)
3935
0
        XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
3936
3937
0
    ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
3938
0
    ssl->buffers.domainName.buffer = (byte*)XMALLOC(
3939
0
            ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
3940
3941
0
    if (ssl->buffers.domainName.buffer) {
3942
0
        unsigned char* domainName = ssl->buffers.domainName.buffer;
3943
0
        XMEMCPY(domainName, dn, ssl->buffers.domainName.length);
3944
0
        domainName[ssl->buffers.domainName.length] = '\0';
3945
0
        return WOLFSSL_SUCCESS;
3946
0
    }
3947
0
    else {
3948
0
        ssl->error = MEMORY_ERROR;
3949
0
        return WOLFSSL_FAILURE;
3950
0
    }
3951
0
}
3952
3953
/* call before SSL_connect, if verifying will add IP SAN check to
3954
   date check and signature check */
3955
WOLFSSL_ABI
3956
int wolfSSL_check_ip_address(WOLFSSL* ssl, const char* ipaddr)
3957
0
{
3958
0
    WOLFSSL_ENTER("wolfSSL_check_ip_address");
3959
3960
0
    if (ssl == NULL || ipaddr == NULL) {
3961
0
        WOLFSSL_MSG("Bad function argument: NULL");
3962
0
        return WOLFSSL_FAILURE;
3963
0
    }
3964
3965
0
    if (ssl->buffers.ipasc.buffer != NULL) {
3966
0
        XFREE(ssl->buffers.ipasc.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
3967
0
        ssl->buffers.ipasc.buffer = NULL;
3968
0
        ssl->buffers.ipasc.length = 0;
3969
0
    }
3970
3971
0
    ssl->buffers.ipasc.length = (word32)XSTRLEN(ipaddr);
3972
0
    ssl->buffers.ipasc.buffer = (byte*)XMALLOC(ssl->buffers.ipasc.length + 1,
3973
0
                                               ssl->heap, DYNAMIC_TYPE_DOMAIN);
3974
0
    if (ssl->buffers.ipasc.buffer == NULL) {
3975
0
        ssl->error = MEMORY_ERROR;
3976
0
        return WOLFSSL_FAILURE;
3977
0
    }
3978
3979
0
    XMEMCPY(ssl->buffers.ipasc.buffer, ipaddr, ssl->buffers.ipasc.length);
3980
0
    ssl->buffers.ipasc.buffer[ssl->buffers.ipasc.length] = '\0';
3981
3982
#ifdef OPENSSL_EXTRA
3983
    if (ssl->param == NULL) {
3984
        return WOLFSSL_FAILURE;
3985
    }
3986
    if (wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(ssl->param, ipaddr) !=
3987
            WOLFSSL_SUCCESS) {
3988
        return WOLFSSL_FAILURE;
3989
    }
3990
#endif
3991
3992
0
    return WOLFSSL_SUCCESS;
3993
0
}
3994
3995
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
3996
const char *wolfSSL_get0_peername(WOLFSSL *ssl) {
3997
    if (ssl == NULL) {
3998
        return NULL;
3999
    }
4000
4001
    if (ssl->buffers.domainName.buffer)
4002
        return (const char *)ssl->buffers.domainName.buffer;
4003
    else if (ssl->session && ssl->session->peer)
4004
        return ssl->session->peer->subjectCN;
4005
#ifdef KEEP_PEER_CERT
4006
    else if (ssl->peerCert.subjectCN[0])
4007
        return ssl->peerCert.subjectCN;
4008
#endif
4009
    else {
4010
        ssl->error = NO_PEER_CERT;
4011
        return NULL;
4012
    }
4013
}
4014
4015
#endif /* SESSION_CERTS && OPENSSL_EXTRA */
4016
4017
/* turn on wolfSSL zlib compression
4018
   returns WOLFSSL_SUCCESS for success, else error (not built in)
4019
*/
4020
int wolfSSL_set_compression(WOLFSSL* ssl)
4021
0
{
4022
0
    WOLFSSL_ENTER("wolfSSL_set_compression");
4023
0
    (void)ssl;
4024
#ifdef HAVE_LIBZ
4025
    if (ssl == NULL)
4026
        return BAD_FUNC_ARG;
4027
#ifdef WOLFSSL_DTLS
4028
    /* zlib keeps one deflate stream running across records, so a datagram
4029
     * that is lost, duplicated or reordered desyncs the peer's inflate state
4030
     * for the rest of the connection. */
4031
    if (ssl->options.dtls) {
4032
        WOLFSSL_MSG("Compression not supported over DTLS");
4033
        return BAD_FUNC_ARG;
4034
    }
4035
#endif
4036
    ssl->options.usingCompression = 1;
4037
    return WOLFSSL_SUCCESS;
4038
#else
4039
0
    return NOT_COMPILED_IN;
4040
0
#endif
4041
0
}
4042
4043
4044
#ifndef NO_PSK
4045
4046
    void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
4047
                                         wc_psk_client_callback cb)
4048
    {
4049
        WOLFSSL_ENTER("wolfSSL_CTX_set_psk_client_callback");
4050
4051
        if (ctx == NULL)
4052
            return;
4053
4054
        ctx->havePSK = 1;
4055
        ctx->client_psk_cb = cb;
4056
    }
4057
4058
    void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
4059
    {
4060
        byte haveRSA = 1;
4061
        int  keySz   = 0;
4062
4063
        WOLFSSL_ENTER("wolfSSL_set_psk_client_callback");
4064
4065
        if (ssl == NULL)
4066
            return;
4067
4068
        ssl->options.havePSK = 1;
4069
        ssl->options.client_psk_cb = cb;
4070
4071
        #ifdef NO_RSA
4072
            haveRSA = 0;
4073
        #endif
4074
        #ifndef NO_CERTS
4075
            keySz = ssl->buffers.keySz;
4076
        #endif
4077
        if (AllocateSuites(ssl) != 0)
4078
            return;
4079
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
4080
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
4081
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
4082
                   ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
4083
    }
4084
4085
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_CERT_WITH_EXTERN_PSK)
4086
    int wolfSSL_CTX_set_cert_with_extern_psk(WOLFSSL_CTX* ctx, int state)
4087
    {
4088
        WOLFSSL_ENTER("wolfSSL_CTX_set_cert_with_extern_psk");
4089
        if (ctx == NULL)
4090
            return WOLFSSL_FAILURE;
4091
        ctx->certWithExternPsk = (byte)(state != 0);
4092
        return WOLFSSL_SUCCESS;
4093
    }
4094
4095
    int wolfSSL_set_cert_with_extern_psk(WOLFSSL* ssl, int state)
4096
    {
4097
        WOLFSSL_ENTER("wolfSSL_set_cert_with_extern_psk");
4098
        if (ssl == NULL)
4099
            return WOLFSSL_FAILURE;
4100
        ssl->options.certWithExternPsk = (word16)(state != 0);
4101
        return WOLFSSL_SUCCESS;
4102
    }
4103
#endif
4104
4105
    #ifdef OPENSSL_EXTRA
4106
    /**
4107
     * set call back function for psk session use
4108
     * @param ssl  a pointer to WOLFSSL structure
4109
     * @param cb   a function pointer to wc_psk_use_session_cb
4110
     * @return none
4111
     */
4112
    void wolfSSL_set_psk_use_session_callback(WOLFSSL* ssl,
4113
                                                wc_psk_use_session_cb_func cb)
4114
    {
4115
        WOLFSSL_ENTER("wolfSSL_set_psk_use_session_callback");
4116
4117
        if (ssl != NULL) {
4118
            ssl->options.havePSK = 1;
4119
            ssl->options.session_psk_cb = cb;
4120
        }
4121
4122
        WOLFSSL_LEAVE("wolfSSL_set_psk_use_session_callback", WOLFSSL_SUCCESS);
4123
    }
4124
    #endif
4125
4126
    void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
4127
                                         wc_psk_server_callback cb)
4128
    {
4129
        WOLFSSL_ENTER("wolfSSL_CTX_set_psk_server_callback");
4130
        if (ctx == NULL)
4131
            return;
4132
        ctx->havePSK = 1;
4133
        ctx->server_psk_cb = cb;
4134
    }
4135
4136
    void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
4137
    {
4138
        byte haveRSA = 1;
4139
        int  keySz   = 0;
4140
4141
        WOLFSSL_ENTER("wolfSSL_set_psk_server_callback");
4142
        if (ssl == NULL)
4143
            return;
4144
4145
        ssl->options.havePSK = 1;
4146
        ssl->options.server_psk_cb = cb;
4147
4148
        #ifdef NO_RSA
4149
            haveRSA = 0;
4150
        #endif
4151
        #ifndef NO_CERTS
4152
            keySz = ssl->buffers.keySz;
4153
        #endif
4154
        if (AllocateSuites(ssl) != 0)
4155
            return;
4156
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
4157
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
4158
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
4159
                   ssl->options.useAnon, TRUE, TRUE, TRUE, TRUE, ssl->options.side);
4160
    }
4161
4162
    const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
4163
    {
4164
        WOLFSSL_ENTER("wolfSSL_get_psk_identity_hint");
4165
4166
        if (ssl == NULL || ssl->arrays == NULL)
4167
            return NULL;
4168
4169
        return ssl->arrays->server_hint;
4170
    }
4171
4172
4173
    const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
4174
    {
4175
        WOLFSSL_ENTER("wolfSSL_get_psk_identity");
4176
4177
        if (ssl == NULL || ssl->arrays == NULL)
4178
            return NULL;
4179
4180
        return ssl->arrays->client_identity;
4181
    }
4182
4183
    int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
4184
    {
4185
        WOLFSSL_ENTER("wolfSSL_CTX_use_psk_identity_hint");
4186
        if (hint == 0)
4187
            ctx->server_hint[0] = '\0';
4188
        else {
4189
            /* Qt does not call CTX_set_*_psk_callbacks where havePSK is set */
4190
            #ifdef WOLFSSL_QT
4191
            ctx->havePSK=1;
4192
            #endif
4193
            XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
4194
            ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
4195
        }
4196
        return WOLFSSL_SUCCESS;
4197
    }
4198
4199
    int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
4200
    {
4201
        WOLFSSL_ENTER("wolfSSL_use_psk_identity_hint");
4202
4203
        if (ssl == NULL || ssl->arrays == NULL)
4204
            return WOLFSSL_FAILURE;
4205
4206
        if (hint == 0)
4207
            ssl->arrays->server_hint[0] = 0;
4208
        else {
4209
            XSTRNCPY(ssl->arrays->server_hint, hint,
4210
                                            sizeof(ssl->arrays->server_hint)-1);
4211
            ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
4212
        }
4213
        return WOLFSSL_SUCCESS;
4214
    }
4215
4216
    void* wolfSSL_get_psk_callback_ctx(WOLFSSL* ssl)
4217
    {
4218
        return ssl ? ssl->options.psk_ctx : NULL;
4219
    }
4220
    void* wolfSSL_CTX_get_psk_callback_ctx(WOLFSSL_CTX* ctx)
4221
    {
4222
        return ctx ? ctx->psk_ctx : NULL;
4223
    }
4224
    int wolfSSL_set_psk_callback_ctx(WOLFSSL* ssl, void* psk_ctx)
4225
    {
4226
        if (ssl == NULL)
4227
            return WOLFSSL_FAILURE;
4228
        ssl->options.psk_ctx = psk_ctx;
4229
        return WOLFSSL_SUCCESS;
4230
    }
4231
    int wolfSSL_CTX_set_psk_callback_ctx(WOLFSSL_CTX* ctx, void* psk_ctx)
4232
    {
4233
        if (ctx == NULL)
4234
            return WOLFSSL_FAILURE;
4235
        ctx->psk_ctx = psk_ctx;
4236
        return WOLFSSL_SUCCESS;
4237
    }
4238
#endif /* NO_PSK */
4239
4240
4241
#ifdef HAVE_ANON
4242
4243
    int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
4244
    {
4245
        WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
4246
4247
        if (ctx == NULL)
4248
            return WOLFSSL_FAILURE;
4249
4250
        ctx->useAnon = 1;
4251
4252
        return WOLFSSL_SUCCESS;
4253
    }
4254
4255
#endif /* HAVE_ANON */
4256
4257
#ifdef OPENSSL_EXTRA
4258
4259
    int wolfSSL_add_all_algorithms(void)
4260
    {
4261
        WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
4262
        if (initRefCount != 0 || wolfSSL_Init() == WOLFSSL_SUCCESS)
4263
            return WOLFSSL_SUCCESS;
4264
        else
4265
            return WOLFSSL_FATAL_ERROR;
4266
    }
4267
4268
    int wolfSSL_OpenSSL_add_all_algorithms_noconf(void)
4269
    {
4270
        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_noconf");
4271
4272
        if  (wolfSSL_add_all_algorithms() ==
4273
             WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR))
4274
        {
4275
            return WOLFSSL_FATAL_ERROR;
4276
        }
4277
4278
        return  WOLFSSL_SUCCESS;
4279
    }
4280
4281
    int wolfSSL_OpenSSL_add_all_algorithms_conf(void)
4282
    {
4283
        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_conf");
4284
        /* This function is currently the same as
4285
        wolfSSL_OpenSSL_add_all_algorithms_noconf since we do not employ
4286
        the use of a wolfssl.cnf type configuration file and is only used for
4287
        OpenSSL compatibility. */
4288
4289
        if (wolfSSL_add_all_algorithms() ==
4290
            WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR))
4291
        {
4292
            return WOLFSSL_FATAL_ERROR;
4293
        }
4294
        return WOLFSSL_SUCCESS;
4295
    }
4296
4297
#endif
4298
4299
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
4300
    defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4301
    void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
4302
    {
4303
        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
4304
        if (mode)
4305
            ctx->quietShutdown = 1;
4306
    }
4307
4308
4309
    void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
4310
    {
4311
        WOLFSSL_ENTER("wolfSSL_set_quiet_shutdown");
4312
        if (mode)
4313
            ssl->options.quietShutdown = 1;
4314
    }
4315
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
4316
          WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4317
4318
#ifdef OPENSSL_EXTRA
4319
#ifndef NO_BIO
4320
    static void ssl_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr, int flags)
4321
    {
4322
        WOLFSSL_ENTER("wolfSSL_set_bio");
4323
4324
        if (ssl == NULL) {
4325
            WOLFSSL_MSG("Bad argument, ssl was NULL");
4326
            return;
4327
        }
4328
4329
        /* free any existing WOLFSSL_BIOs in use but don't free those in
4330
         * a chain */
4331
        if ((flags & WOLFSSL_BIO_FLAG_READ) && (ssl->biord != NULL)) {
4332
            if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biord != ssl->biowr)) {
4333
                if (ssl->biowr != NULL && ssl->biowr->prev == NULL)
4334
                    wolfSSL_BIO_free(ssl->biowr);
4335
                ssl->biowr = NULL;
4336
            }
4337
            if (ssl->biord->prev == NULL)
4338
                wolfSSL_BIO_free(ssl->biord);
4339
            ssl->biord = NULL;
4340
        }
4341
        else if ((flags & WOLFSSL_BIO_FLAG_WRITE) && (ssl->biowr != NULL)) {
4342
            if (ssl->biowr->prev == NULL)
4343
                wolfSSL_BIO_free(ssl->biowr);
4344
            ssl->biowr = NULL;
4345
        }
4346
4347
        /* set flag obviously */
4348
        if (rd && !(rd->flags & WOLFSSL_BIO_FLAG_READ))
4349
            rd->flags |= WOLFSSL_BIO_FLAG_READ;
4350
        if (wr && !(wr->flags & WOLFSSL_BIO_FLAG_WRITE))
4351
            wr->flags |= WOLFSSL_BIO_FLAG_WRITE;
4352
4353
        if (flags & WOLFSSL_BIO_FLAG_READ)
4354
            ssl->biord = rd;
4355
        if (flags & WOLFSSL_BIO_FLAG_WRITE)
4356
            ssl->biowr = wr;
4357
4358
        /* set SSL to use BIO callbacks instead */
4359
        if ((flags & WOLFSSL_BIO_FLAG_READ) &&
4360
            (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0)))
4361
        {
4362
            ssl->CBIORecv = SslBioReceive;
4363
        }
4364
        if ((flags & WOLFSSL_BIO_FLAG_WRITE) &&
4365
            (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0)))
4366
        {
4367
            ssl->CBIOSend = SslBioSend;
4368
        }
4369
4370
        /* User programs should always retry reading from these BIOs */
4371
        if (rd) {
4372
            /* User writes to rd */
4373
            wolfSSL_BIO_set_retry_write(rd);
4374
        }
4375
        if (wr) {
4376
            /* User reads from wr */
4377
            wolfSSL_BIO_set_retry_read(wr);
4378
        }
4379
    }
4380
4381
    void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
4382
    {
4383
        ssl_set_bio(ssl, rd, wr, WOLFSSL_BIO_FLAG_READ | WOLFSSL_BIO_FLAG_WRITE);
4384
    }
4385
4386
    void wolfSSL_set_rbio(WOLFSSL* ssl, WOLFSSL_BIO* rd)
4387
    {
4388
        ssl_set_bio(ssl, rd, NULL, WOLFSSL_BIO_FLAG_READ);
4389
    }
4390
4391
    void wolfSSL_set_wbio(WOLFSSL* ssl, WOLFSSL_BIO* wr)
4392
    {
4393
        ssl_set_bio(ssl, NULL, wr, WOLFSSL_BIO_FLAG_WRITE);
4394
    }
4395
4396
#endif /* !NO_BIO */
4397
#endif /* OPENSSL_EXTRA */
4398
4399
#ifdef WOLFSSL_CERT_SETUP_CB
4400
    int wolfSSL_get_client_suites_sigalgs(const WOLFSSL* ssl,
4401
            const byte** suites, word16* suiteSz,
4402
            const byte** hashSigAlgo, word16* hashSigAlgoSz)
4403
    {
4404
        WOLFSSL_ENTER("wolfSSL_get_client_suites_sigalgs");
4405
4406
        if (suites != NULL)
4407
            *suites = NULL;
4408
        if (suiteSz != NULL)
4409
            *suiteSz = 0;
4410
        if (hashSigAlgo != NULL)
4411
            *hashSigAlgo = NULL;
4412
        if (hashSigAlgoSz != NULL)
4413
            *hashSigAlgoSz = 0;
4414
4415
        if (ssl != NULL && ssl->clSuites != NULL) {
4416
            if (suites != NULL && suiteSz != NULL) {
4417
                *suites = ssl->clSuites->suites;
4418
                *suiteSz = ssl->clSuites->suiteSz;
4419
            }
4420
            if (hashSigAlgo != NULL && hashSigAlgoSz != NULL) {
4421
                *hashSigAlgo = ssl->clSuites->hashSigAlgo;
4422
                *hashSigAlgoSz = ssl->clSuites->hashSigAlgoSz;
4423
            }
4424
            return WOLFSSL_SUCCESS;
4425
        }
4426
        return WOLFSSL_FAILURE;
4427
    }
4428
4429
#ifndef NO_TLS
4430
    WOLFSSL_CIPHERSUITE_INFO wolfSSL_get_ciphersuite_info(byte first,
4431
            byte second)
4432
    {
4433
        WOLFSSL_CIPHERSUITE_INFO info;
4434
        info.rsaAuth = (byte)(CipherRequires(first, second, REQUIRES_RSA) ||
4435
                CipherRequires(first, second, REQUIRES_RSA_SIG));
4436
        info.eccAuth = (byte)(CipherRequires(first, second, REQUIRES_ECC) ||
4437
                /* Static ECC ciphers may require RSA for authentication */
4438
                (CipherRequires(first, second, REQUIRES_ECC_STATIC) &&
4439
                        !CipherRequires(first, second, REQUIRES_RSA_SIG)));
4440
        info.eccStatic =
4441
                (byte)CipherRequires(first, second, REQUIRES_ECC_STATIC);
4442
        info.psk = (byte)CipherRequires(first, second, REQUIRES_PSK);
4443
        return info;
4444
    }
4445
#endif
4446
4447
    /**
4448
     * @param first First byte of the hash and signature algorithm
4449
     * @param second Second byte of the hash and signature algorithm
4450
     * @param hashAlgo The enum wc_HashType of the MAC algorithm
4451
     * @param sigAlgo The enum Key_Sum of the authentication algorithm
4452
     */
4453
    int wolfSSL_get_sigalg_info(byte first, byte second,
4454
            int* hashAlgo, int* sigAlgo)
4455
    {
4456
        byte input[2];
4457
        byte hashType;
4458
        byte sigType;
4459
4460
        if (hashAlgo == NULL || sigAlgo == NULL)
4461
            return BAD_FUNC_ARG;
4462
4463
        input[0] = first;
4464
        input[1] = second;
4465
        DecodeSigAlg(input, &hashType, &sigType);
4466
4467
        /* cast so that compiler reminds us of unimplemented values */
4468
        switch ((enum SignatureAlgorithm)sigType) {
4469
        case anonymous_sa_algo:
4470
            *sigAlgo = ANONk;
4471
            break;
4472
        case rsa_sa_algo:
4473
            *sigAlgo = RSAk;
4474
            break;
4475
        case dsa_sa_algo:
4476
            *sigAlgo = DSAk;
4477
            break;
4478
        case ecc_dsa_sa_algo:
4479
        case ecc_brainpool_sa_algo:
4480
            *sigAlgo = ECDSAk;
4481
            break;
4482
        case rsa_pss_sa_algo:
4483
            *sigAlgo = RSAPSSk;
4484
            break;
4485
        case ed25519_sa_algo:
4486
            *sigAlgo = ED25519k;
4487
            break;
4488
        case rsa_pss_pss_algo:
4489
            *sigAlgo = RSAPSSk;
4490
            break;
4491
        case ed448_sa_algo:
4492
            *sigAlgo = ED448k;
4493
            break;
4494
        case falcon_level1_sa_algo:
4495
            *sigAlgo = FALCON_LEVEL1k;
4496
            break;
4497
        case falcon_level5_sa_algo:
4498
            *sigAlgo = FALCON_LEVEL5k;
4499
            break;
4500
        case mldsa_44_sa_algo:
4501
            *sigAlgo = ML_DSA_44k;
4502
            break;
4503
        case mldsa_65_sa_algo:
4504
            *sigAlgo = ML_DSA_65k;
4505
            break;
4506
        case mldsa_87_sa_algo:
4507
            *sigAlgo = ML_DSA_87k;
4508
            break;
4509
        case slhdsa_sha2_128s_sa_algo:
4510
            *sigAlgo = SLH_DSA_SHA2_128Sk;
4511
            break;
4512
        case slhdsa_sha2_128f_sa_algo:
4513
            *sigAlgo = SLH_DSA_SHA2_128Fk;
4514
            break;
4515
        case slhdsa_sha2_192s_sa_algo:
4516
            *sigAlgo = SLH_DSA_SHA2_192Sk;
4517
            break;
4518
        case slhdsa_sha2_192f_sa_algo:
4519
            *sigAlgo = SLH_DSA_SHA2_192Fk;
4520
            break;
4521
        case slhdsa_sha2_256s_sa_algo:
4522
            *sigAlgo = SLH_DSA_SHA2_256Sk;
4523
            break;
4524
        case slhdsa_sha2_256f_sa_algo:
4525
            *sigAlgo = SLH_DSA_SHA2_256Fk;
4526
            break;
4527
        case slhdsa_shake_128s_sa_algo:
4528
            *sigAlgo = SLH_DSA_SHAKE_128Sk;
4529
            break;
4530
        case slhdsa_shake_128f_sa_algo:
4531
            *sigAlgo = SLH_DSA_SHAKE_128Fk;
4532
            break;
4533
        case slhdsa_shake_192s_sa_algo:
4534
            *sigAlgo = SLH_DSA_SHAKE_192Sk;
4535
            break;
4536
        case slhdsa_shake_192f_sa_algo:
4537
            *sigAlgo = SLH_DSA_SHAKE_192Fk;
4538
            break;
4539
        case slhdsa_shake_256s_sa_algo:
4540
            *sigAlgo = SLH_DSA_SHAKE_256Sk;
4541
            break;
4542
        case slhdsa_shake_256f_sa_algo:
4543
            *sigAlgo = SLH_DSA_SHAKE_256Fk;
4544
            break;
4545
        case sm2_sa_algo:
4546
            *sigAlgo = SM2k;
4547
            break;
4548
        case invalid_sa_algo:
4549
        case any_sa_algo:
4550
        default:
4551
            *hashAlgo = WC_HASH_TYPE_NONE;
4552
            *sigAlgo = 0;
4553
            return BAD_FUNC_ARG;
4554
        }
4555
4556
        /* cast so that compiler reminds us of unimplemented values */
4557
        switch((enum wc_MACAlgorithm)hashType) {
4558
        case no_mac:
4559
        case rmd_mac: /* Don't have a RIPEMD type in wc_HashType */
4560
            *hashAlgo = WC_HASH_TYPE_NONE;
4561
            break;
4562
        case md5_mac:
4563
            *hashAlgo = WC_HASH_TYPE_MD5;
4564
            break;
4565
        case sha_mac:
4566
            *hashAlgo = WC_HASH_TYPE_SHA;
4567
            break;
4568
        case sha224_mac:
4569
            *hashAlgo = WC_HASH_TYPE_SHA224;
4570
            break;
4571
        case sha256_mac:
4572
            *hashAlgo = WC_HASH_TYPE_SHA256;
4573
            break;
4574
        case sha384_mac:
4575
            *hashAlgo = WC_HASH_TYPE_SHA384;
4576
            break;
4577
        case sha512_mac:
4578
            *hashAlgo = WC_HASH_TYPE_SHA512;
4579
            break;
4580
        case blake2b_mac:
4581
            *hashAlgo = WC_HASH_TYPE_BLAKE2B;
4582
            break;
4583
        case sm3_mac:
4584
#ifdef WOLFSSL_SM3
4585
            *hashAlgo = WC_HASH_TYPE_SM3;
4586
#else
4587
            *hashAlgo = WC_HASH_TYPE_NONE;
4588
#endif
4589
            break;
4590
        default:
4591
            *hashAlgo = WC_HASH_TYPE_NONE;
4592
            *sigAlgo = 0;
4593
            return BAD_FUNC_ARG;
4594
        }
4595
        return 0;
4596
    }
4597
#endif /* WOLFSSL_CERT_SETUP_CB */
4598
4599
#ifdef OPENSSL_EXTRA
4600
4601
    /* keyblock size in bytes or -1 */
4602
    int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
4603
    {
4604
        if (ssl == NULL)
4605
            return WOLFSSL_FATAL_ERROR;
4606
4607
        return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
4608
                    ssl->specs.hash_size);
4609
    }
4610
4611
#endif /* OPENSSL_EXTRA */
4612
4613
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || \
4614
    defined(WOLFSSL_WPAS_SMALL)
4615
4616
    /* store keys returns WOLFSSL_SUCCESS or -1 on error */
4617
    int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
4618
                                     unsigned char** sr, unsigned int* srLen,
4619
                                     unsigned char** cr, unsigned int* crLen)
4620
    {
4621
        if (ssl == NULL || ssl->arrays == NULL)
4622
            return WOLFSSL_FATAL_ERROR;
4623
4624
        *ms = ssl->arrays->masterSecret;
4625
        *sr = ssl->arrays->serverRandom;
4626
        *cr = ssl->arrays->clientRandom;
4627
4628
        *msLen = SECRET_LEN;
4629
        *srLen = RAN_LEN;
4630
        *crLen = RAN_LEN;
4631
4632
        return WOLFSSL_SUCCESS;
4633
    }
4634
4635
4636
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
4637
4638
4639
#ifdef OPENSSL_EXTRA
4640
    void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
4641
                                      WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
4642
    {
4643
        /* wolfSSL verifies all these internally */
4644
        (void)ctx;
4645
        (void)f;
4646
    }
4647
4648
4649
    void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
4650
    {
4651
        WOLFSSL_ENTER("wolfSSL_set_shutdown");
4652
        if(ssl==NULL) {
4653
            WOLFSSL_MSG("Shutdown not set. ssl is null");
4654
            return;
4655
        }
4656
4657
        ssl->options.sentNotify =  (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
4658
        ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
4659
    }
4660
#endif
4661
4662
    long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
4663
0
    {
4664
0
        WOLFSSL_ENTER("wolfSSL_CTX_get_options");
4665
0
        WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
4666
0
        if(ctx == NULL)
4667
0
            return BAD_FUNC_ARG;
4668
0
        return (long)ctx->mask;
4669
0
    }
4670
4671
    /* forward declaration */
4672
    static long wolf_set_options(long old_op, long op);
4673
4674
    long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
4675
0
    {
4676
0
        WOLFSSL_ENTER("wolfSSL_CTX_set_options");
4677
4678
0
        if (ctx == NULL)
4679
0
            return BAD_FUNC_ARG;
4680
4681
0
        ctx->mask = (unsigned long)wolf_set_options((long)ctx->mask, opt);
4682
#if defined(HAVE_SESSION_TICKET) && (defined(OPENSSL_EXTRA) \
4683
        || defined(HAVE_WEBSERVER) || defined(WOLFSSL_WPAS_SMALL))
4684
        if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
4685
          ctx->noTicketTls12 = 1;
4686
        }
4687
        /* This code is here for documentation purpose. You must not turn off
4688
         * session tickets with the WOLFSSL_OP_NO_TICKET option for TLSv1.3.
4689
         * Because we need to support both stateful and stateless tickets.
4690
        #ifdef WOLFSSL_TLS13
4691
            if ((ctx->mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
4692
                ctx->noTicketTls13 = 1;
4693
            }
4694
        #endif
4695
        */
4696
#endif
4697
0
        return (long)ctx->mask;
4698
0
    }
4699
4700
    long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
4701
0
    {
4702
0
        WOLFSSL_ENTER("wolfSSL_CTX_clear_options");
4703
0
        if(ctx == NULL)
4704
0
            return BAD_FUNC_ARG;
4705
0
        ctx->mask &= (unsigned long)~opt;
4706
0
        return (long)ctx->mask;
4707
0
    }
4708
4709
#ifdef OPENSSL_EXTRA
4710
4711
    int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
4712
    {
4713
        WOLFSSL_ENTER("wolfSSL_set_rfd");
4714
        ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
4715
4716
        ssl->IOCB_ReadCtx  = &ssl->rfd;
4717
4718
    #ifdef WOLFSSL_DTLS
4719
        if (ssl->options.dtls) {
4720
            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
4721
            ssl->buffers.dtlsCtx.rfd = rfd;
4722
        #ifdef USE_WOLFSSL_IO
4723
            ssl->buffers.dtlsCtx.rfdIsDGram =
4724
                (byte)(wolfIO_SockIsDGram(rfd) != 0);
4725
        #endif
4726
        }
4727
    #endif
4728
4729
        return WOLFSSL_SUCCESS;
4730
    }
4731
4732
4733
    int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
4734
    {
4735
        WOLFSSL_ENTER("wolfSSL_set_wfd");
4736
        ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
4737
4738
        ssl->IOCB_WriteCtx  = &ssl->wfd;
4739
4740
        return WOLFSSL_SUCCESS;
4741
    }
4742
#endif /* OPENSSL_EXTRA */
4743
4744
#ifdef WOLFSSL_ENCRYPTED_KEYS
4745
4746
    void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
4747
                                                   void* userdata)
4748
    {
4749
        WOLFSSL_ENTER("wolfSSL_CTX_set_default_passwd_cb_userdata");
4750
        if (ctx)
4751
            ctx->passwd_userdata = userdata;
4752
    }
4753
4754
4755
    void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, wc_pem_password_cb*
4756
                                           cb)
4757
    {
4758
        WOLFSSL_ENTER("wolfSSL_CTX_set_default_passwd_cb");
4759
        if (ctx)
4760
            ctx->passwd_cb = cb;
4761
    }
4762
4763
    wc_pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
4764
    {
4765
        if (ctx == NULL || ctx->passwd_cb == NULL) {
4766
            return NULL;
4767
        }
4768
4769
        return ctx->passwd_cb;
4770
    }
4771
4772
4773
    void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
4774
    {
4775
        if (ctx == NULL) {
4776
            return NULL;
4777
        }
4778
4779
        return ctx->passwd_userdata;
4780
    }
4781
4782
#endif /* WOLFSSL_ENCRYPTED_KEYS */
4783
4784
4785
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
4786
#endif
4787
4788
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
4789
4790
    int wolfSSL_num_locks(void)
4791
    {
4792
        return 0;
4793
    }
4794
4795
    void wolfSSL_set_locking_callback(mutex_cb* f)
4796
    {
4797
        WOLFSSL_ENTER("wolfSSL_set_locking_callback");
4798
4799
        if (wc_SetMutexCb(f) != 0) {
4800
            WOLFSSL_MSG("Error when setting mutex call back");
4801
        }
4802
    }
4803
4804
    mutex_cb* wolfSSL_get_locking_callback(void)
4805
    {
4806
        WOLFSSL_ENTER("wolfSSL_get_locking_callback");
4807
4808
        return wc_GetMutexCb();
4809
    }
4810
4811
4812
    typedef unsigned long (idCb)(void);
4813
    static idCb* inner_idCb = NULL;
4814
4815
    unsigned long wolfSSL_thread_id(void)
4816
    {
4817
        if (inner_idCb != NULL) {
4818
            return inner_idCb();
4819
        }
4820
        else {
4821
            return 0;
4822
        }
4823
    }
4824
4825
4826
    void wolfSSL_set_id_callback(unsigned long (*f)(void))
4827
    {
4828
        inner_idCb = f;
4829
    }
4830
4831
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
4832
#ifndef NO_BIO
4833
    /* print out and clear all errors */
4834
#endif /* !NO_BIO */
4835
#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
4836
4837
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
4838
4839
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
4840
    defined(HAVE_SECRET_CALLBACK)
4841
#if !defined(NO_WOLFSSL_SERVER)
4842
/* Return the amount of random bytes copied over or error case.
4843
 * ssl : ssl struct after handshake
4844
 * out : buffer to hold random bytes
4845
 * outSz : either 0 (return max buffer sz) or size of out buffer
4846
 */
4847
size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
4848
                                                                   size_t outSz)
4849
{
4850
    size_t size;
4851
4852
    /* return max size of buffer */
4853
    if (outSz == 0) {
4854
        return RAN_LEN;
4855
    }
4856
4857
    if (ssl == NULL || out == NULL) {
4858
        return 0;
4859
    }
4860
4861
    if (ssl->arrays == NULL) {
4862
        WOLFSSL_MSG("Arrays struct not saved after handshake");
4863
        return 0;
4864
    }
4865
4866
    if (outSz > RAN_LEN) {
4867
        size = RAN_LEN;
4868
    }
4869
    else {
4870
        size = outSz;
4871
    }
4872
4873
    XMEMCPY(out, ssl->arrays->serverRandom, size);
4874
    return size;
4875
}
4876
#endif /* !NO_WOLFSSL_SERVER */
4877
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
4878
4879
#ifdef OPENSSL_EXTRA
4880
#if !defined(NO_WOLFSSL_SERVER)
4881
/* Used to get the peer ephemeral public key sent during the connection
4882
 * NOTE: currently wolfSSL_KeepHandshakeResources(WOLFSSL* ssl) must be called
4883
 *       before the ephemeral key is stored.
4884
 * return WOLFSSL_SUCCESS on success */
4885
int wolfSSL_get_peer_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey)
4886
{
4887
    WOLFSSL_EVP_PKEY* ret = NULL;
4888
4889
    WOLFSSL_ENTER("wolfSSL_get_server_tmp_key");
4890
4891
    if (ssl == NULL || pkey == NULL) {
4892
        WOLFSSL_MSG("Bad argument passed in");
4893
        return WOLFSSL_FAILURE;
4894
    }
4895
4896
    /* Clear up front: the per-curve export failures below return early, and a
4897
     * caller reusing one variable across calls must not see a stale pointer. */
4898
    *pkey = NULL;
4899
4900
#ifdef HAVE_ECC
4901
    /* Keys kept for this call outlive the connection they came from, so pick
4902
     * the one the current key exchange used rather than the first one set. */
4903
    if ((ssl->peerEccKey != NULL) && ssl->peerEccKeyPresent
4904
#ifdef HAVE_CURVE25519
4905
        && (ssl->ecdhCurveOID != ECC_X25519_OID)
4906
#endif
4907
#ifdef HAVE_CURVE448
4908
        && (ssl->ecdhCurveOID != ECC_X448_OID)
4909
#endif
4910
        ) {
4911
        unsigned char* der;
4912
        const unsigned char* pt;
4913
        unsigned int   derSz = 0;
4914
        int sz;
4915
4916
        PRIVATE_KEY_UNLOCK();
4917
        if (wc_ecc_export_x963(ssl->peerEccKey, NULL, &derSz)
4918
              != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
4919
        {
4920
            WOLFSSL_MSG("get ecc der size failed");
4921
            PRIVATE_KEY_LOCK();
4922
            return WOLFSSL_FAILURE;
4923
        }
4924
        PRIVATE_KEY_LOCK();
4925
4926
        derSz += MAX_SEQ_SZ + (2 * MAX_ALGO_SZ) + MAX_SEQ_SZ + TRAILING_ZERO;
4927
        der = (unsigned char*)XMALLOC(derSz, ssl->heap, DYNAMIC_TYPE_KEY);
4928
        if (der == NULL) {
4929
            WOLFSSL_MSG("Memory error");
4930
            return WOLFSSL_FAILURE;
4931
        }
4932
4933
        if ((sz = wc_EccPublicKeyToDer(ssl->peerEccKey, der, derSz, 1)) <= 0) {
4934
            WOLFSSL_MSG("get ecc der failed");
4935
            XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
4936
            return WOLFSSL_FAILURE;
4937
        }
4938
        pt = der; /* in case pointer gets advanced */
4939
        ret = wolfSSL_d2i_PUBKEY(NULL, &pt, sz);
4940
        XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
4941
    }
4942
#endif
4943
4944
#ifdef HAVE_CURVE25519
4945
    if ((ret == NULL) && (ssl->ecdhCurveOID == ECC_X25519_OID) &&
4946
            (ssl->peerX25519Key != NULL) && ssl->peerX25519KeyPresent) {
4947
        byte pub[CURVE25519_PUB_KEY_SIZE];
4948
        word32 pubSz = (word32)sizeof(pub);
4949
4950
        /* Raw X25519 keys are little-endian (RFC 7748). */
4951
        if (wc_curve25519_export_public_ex(ssl->peerX25519Key, pub, &pubSz,
4952
                EC25519_LITTLE_ENDIAN) != 0) {
4953
            WOLFSSL_MSG("get curve25519 public key failed");
4954
            return WOLFSSL_FAILURE;
4955
        }
4956
        ret = wolfSSL_EVP_PKEY_new_raw_public_key(WC_EVP_PKEY_X25519, NULL,
4957
            pub, (size_t)pubSz);
4958
    }
4959
#endif
4960
4961
#ifdef HAVE_CURVE448
4962
    if ((ret == NULL) && (ssl->ecdhCurveOID == ECC_X448_OID) &&
4963
            (ssl->peerX448Key != NULL) && ssl->peerX448KeyPresent) {
4964
        byte pub[CURVE448_PUB_KEY_SIZE];
4965
        word32 pubSz = (word32)sizeof(pub);
4966
4967
        /* Raw X448 keys are little-endian (RFC 7748). */
4968
        if (wc_curve448_export_public_ex(ssl->peerX448Key, pub, &pubSz,
4969
                EC448_LITTLE_ENDIAN) != 0) {
4970
            WOLFSSL_MSG("get curve448 public key failed");
4971
            return WOLFSSL_FAILURE;
4972
        }
4973
        ret = wolfSSL_EVP_PKEY_new_raw_public_key(WC_EVP_PKEY_X448, NULL,
4974
            pub, (size_t)pubSz);
4975
    }
4976
#endif
4977
4978
    *pkey = ret;
4979
4980
    return (ret != NULL) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
4981
}
4982
4983
#endif /* !NO_WOLFSSL_SERVER */
4984
4985
/**
4986
 * This function checks if any compiled in protocol versions are
4987
 * left enabled after calls to set_min or set_max API.
4988
 * @param major The SSL/TLS major version
4989
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
4990
 *         protocol versions are left enabled.
4991
 */
4992
static int CheckSslMethodVersion(byte major, unsigned long options)
4993
{
4994
    int sanityConfirmed = 0;
4995
4996
    (void)options;
4997
4998
    switch (major) {
4999
    #ifndef NO_TLS
5000
        case SSLv3_MAJOR:
5001
            #ifdef WOLFSSL_ALLOW_SSLV3
5002
                if (!(options & WOLFSSL_OP_NO_SSLv3)) {
5003
                    sanityConfirmed = 1;
5004
                }
5005
            #endif
5006
            #ifndef NO_OLD_TLS
5007
                if (!(options & WOLFSSL_OP_NO_TLSv1))
5008
                    sanityConfirmed = 1;
5009
                if (!(options & WOLFSSL_OP_NO_TLSv1_1))
5010
                    sanityConfirmed = 1;
5011
            #endif
5012
            #ifndef WOLFSSL_NO_TLS12
5013
                if (!(options & WOLFSSL_OP_NO_TLSv1_2))
5014
                    sanityConfirmed = 1;
5015
            #endif
5016
            #ifdef WOLFSSL_TLS13
5017
                if (!(options & WOLFSSL_OP_NO_TLSv1_3))
5018
                    sanityConfirmed = 1;
5019
            #endif
5020
            break;
5021
    #endif
5022
    #ifdef WOLFSSL_DTLS
5023
        case DTLS_MAJOR:
5024
            sanityConfirmed = 1;
5025
            break;
5026
    #endif
5027
        default:
5028
            WOLFSSL_MSG("Invalid major version");
5029
            return WOLFSSL_FAILURE;
5030
    }
5031
    if (!sanityConfirmed) {
5032
        WOLFSSL_MSG("All compiled in TLS versions disabled");
5033
        return WOLFSSL_FAILURE;
5034
    }
5035
    return WOLFSSL_SUCCESS;
5036
}
5037
5038
/**
5039
 * protoVerTbl holds (D)TLS version numbers in ascending order.
5040
 * Except DTLS versions, the newer version is located in the latter part of
5041
 * the table. This table is referred by wolfSSL_CTX_set_min_proto_version and
5042
 * wolfSSL_CTX_set_max_proto_version.
5043
 */
5044
static const int protoVerTbl[] = {
5045
    SSL3_VERSION,
5046
    TLS1_VERSION,
5047
    TLS1_1_VERSION,
5048
    TLS1_2_VERSION,
5049
    TLS1_3_VERSION,
5050
    DTLS1_VERSION,
5051
    DTLS1_2_VERSION
5052
};
5053
/* number of protocol versions listed in protoVerTbl */
5054
#define NUMBER_OF_PROTOCOLS (sizeof(protoVerTbl)/sizeof(int))
5055
5056
/**
5057
 * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol
5058
 * version to use by SSL objects created from this WOLFSSL_CTX.
5059
 * This API guarantees that a version of SSL/TLS lower than specified
5060
 * here will not be allowed. If the version specified is not compiled in
5061
 * then this API sets the lowest compiled in protocol version.
5062
 * This API also accept 0 as version, to set the minimum version automatically.
5063
 * CheckSslMethodVersion() is called to check if any remaining protocol versions
5064
 * are enabled.
5065
 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
5066
 * @param version Any of the following
5067
 *          * 0
5068
 *          * SSL3_VERSION
5069
 *          * TLS1_VERSION
5070
 *          * TLS1_1_VERSION
5071
 *          * TLS1_2_VERSION
5072
 *          * TLS1_3_VERSION
5073
 *          * DTLS1_VERSION
5074
 *          * DTLS1_2_VERSION
5075
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
5076
 *         protocol versions are left enabled.
5077
 */
5078
static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version)
5079
{
5080
    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version_ex");
5081
5082
    if (ctx == NULL) {
5083
        return WOLFSSL_FAILURE;
5084
    }
5085
5086
    switch (version) {
5087
#ifndef NO_TLS
5088
        case SSL3_VERSION:
5089
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
5090
            ctx->minDowngrade = SSLv3_MINOR;
5091
            break;
5092
#endif
5093
        case TLS1_VERSION:
5094
        #ifdef WOLFSSL_ALLOW_TLSV10
5095
            ctx->minDowngrade = TLSv1_MINOR;
5096
            break;
5097
        #endif
5098
        case TLS1_1_VERSION:
5099
        #ifndef NO_OLD_TLS
5100
            ctx->minDowngrade = TLSv1_1_MINOR;
5101
            break;
5102
        #endif
5103
        case TLS1_2_VERSION:
5104
        #ifndef WOLFSSL_NO_TLS12
5105
            ctx->minDowngrade = TLSv1_2_MINOR;
5106
            break;
5107
        #endif
5108
        case TLS1_3_VERSION:
5109
        #ifdef WOLFSSL_TLS13
5110
            ctx->minDowngrade = TLSv1_3_MINOR;
5111
            break;
5112
        #endif
5113
#endif
5114
#ifdef WOLFSSL_DTLS
5115
        case DTLS1_VERSION:
5116
    #ifndef NO_OLD_TLS
5117
            ctx->minDowngrade = DTLS_MINOR;
5118
            break;
5119
    #endif
5120
        case DTLS1_2_VERSION:
5121
            ctx->minDowngrade = DTLSv1_2_MINOR;
5122
            break;
5123
#endif
5124
        default:
5125
            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
5126
            return WOLFSSL_FAILURE;
5127
    }
5128
5129
    switch (version) {
5130
#ifndef NO_TLS
5131
    case TLS1_3_VERSION:
5132
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
5133
        FALL_THROUGH;
5134
    case TLS1_2_VERSION:
5135
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
5136
        FALL_THROUGH;
5137
    case TLS1_1_VERSION:
5138
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
5139
        FALL_THROUGH;
5140
    case TLS1_VERSION:
5141
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
5142
        break;
5143
    case SSL3_VERSION:
5144
    case SSL2_VERSION:
5145
        /* Nothing to do here */
5146
        break;
5147
#endif
5148
#ifdef WOLFSSL_DTLS
5149
    case DTLS1_VERSION:
5150
    case DTLS1_2_VERSION:
5151
        break;
5152
#endif
5153
    default:
5154
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
5155
        return WOLFSSL_FAILURE;
5156
    }
5157
5158
    return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
5159
}
5160
5161
/* Sets the min protocol version allowed with WOLFSSL_CTX
5162
 * returns WOLFSSL_SUCCESS on success */
5163
int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
5164
{
5165
    int ret;
5166
    int proto    = 0;
5167
    int maxProto = 0;
5168
    int i;
5169
    int idx = 0;
5170
5171
    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version");
5172
5173
    if (ctx == NULL) {
5174
        return WOLFSSL_FAILURE;
5175
    }
5176
5177
    if (version != 0) {
5178
        proto = version;
5179
        ctx->minProto = 0; /* turn min proto flag off */
5180
        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
5181
            if (protoVerTbl[i] == version) {
5182
                break;
5183
            }
5184
        }
5185
    }
5186
    else {
5187
        /* when 0 is specified as version, try to find out the min version */
5188
        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
5189
            ret = Set_CTX_min_proto_version(ctx, protoVerTbl[i]);
5190
            if (ret == WOLFSSL_SUCCESS) {
5191
                proto = protoVerTbl[i];
5192
                ctx->minProto = 1; /* turn min proto flag on */
5193
                break;
5194
            }
5195
        }
5196
    }
5197
5198
    /* check case where max > min , if so then clear the NO_* options
5199
     * i is the index into the table for proto version used, see if the max
5200
     * proto version index found is smaller */
5201
    maxProto = wolfSSL_CTX_get_max_proto_version(ctx);
5202
    for (idx = 0; (unsigned)idx < NUMBER_OF_PROTOCOLS; idx++) {
5203
        if (protoVerTbl[idx] == maxProto) {
5204
            break;
5205
        }
5206
    }
5207
    if (idx < i) {
5208
        wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_TLSv1 |
5209
                WOLFSSL_OP_NO_TLSv1_1 | WOLFSSL_OP_NO_TLSv1_2 |
5210
                WOLFSSL_OP_NO_TLSv1_3);
5211
    }
5212
5213
    ret = Set_CTX_min_proto_version(ctx, proto);
5214
    if (ret == WOLFSSL_SUCCESS) {
5215
        /* Version 0 picks the lowest, so the user set no minimum */
5216
        ctx->minVersionSet = (version != 0);
5217
    }
5218
5219
    return ret;
5220
}
5221
5222
/**
5223
 * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol
5224
 * version to use by SSL objects created from this WOLFSSL_CTX.
5225
 * This API guarantees that a version of SSL/TLS higher than specified
5226
 * here will not be allowed. If the version specified is not compiled in
5227
 * then this API sets the highest compiled in protocol version.
5228
 * This API also accept 0 as version, to set the maximum version automatically.
5229
 * CheckSslMethodVersion() is called to check if any remaining protocol versions
5230
 * are enabled.
5231
 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
5232
 * @param ver Any of the following
5233
 *          * 0
5234
 *          * SSL3_VERSION
5235
 *          * TLS1_VERSION
5236
 *          * TLS1_1_VERSION
5237
 *          * TLS1_2_VERSION
5238
 *          * TLS1_3_VERSION
5239
 *          * DTLS1_VERSION
5240
 *          * DTLS1_2_VERSION
5241
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
5242
 *         protocol versions are left enabled.
5243
 */
5244
static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver)
5245
{
5246
    int ret;
5247
    WOLFSSL_ENTER("Set_CTX_max_proto_version");
5248
5249
    if (!ctx || !ctx->method) {
5250
        WOLFSSL_MSG("Bad parameter");
5251
        return WOLFSSL_FAILURE;
5252
    }
5253
5254
    switch (ver) {
5255
#ifndef NO_TLS
5256
#ifndef NO_OLD_TLS
5257
    case SSL2_VERSION:
5258
        WOLFSSL_MSG("wolfSSL does not support SSLv2");
5259
        return WOLFSSL_FAILURE;
5260
#endif
5261
    case SSL3_VERSION:
5262
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
5263
        FALL_THROUGH;
5264
    case TLS1_VERSION:
5265
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
5266
        FALL_THROUGH;
5267
    case TLS1_1_VERSION:
5268
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
5269
        FALL_THROUGH;
5270
    case TLS1_2_VERSION:
5271
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3);
5272
        FALL_THROUGH;
5273
    case TLS1_3_VERSION:
5274
        /* Nothing to do here */
5275
        break;
5276
#endif
5277
#ifdef WOLFSSL_DTLS
5278
    case DTLS1_VERSION:
5279
    case DTLS1_2_VERSION:
5280
        break;
5281
#endif
5282
    default:
5283
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
5284
        return WOLFSSL_FAILURE;
5285
    }
5286
5287
    ret = CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
5288
    if (ret == WOLFSSL_SUCCESS) {
5289
        /* Check the major */
5290
        switch (ver) {
5291
    #ifndef NO_TLS
5292
        case SSL3_VERSION:
5293
        case TLS1_VERSION:
5294
        case TLS1_1_VERSION:
5295
        case TLS1_2_VERSION:
5296
        case TLS1_3_VERSION:
5297
            if (ctx->method->version.major != SSLv3_MAJOR) {
5298
                WOLFSSL_MSG("Mismatched protocol version");
5299
                return WOLFSSL_FAILURE;
5300
            }
5301
            break;
5302
    #endif
5303
    #ifdef WOLFSSL_DTLS
5304
        case DTLS1_VERSION:
5305
        case DTLS1_2_VERSION:
5306
            if (ctx->method->version.major != DTLS_MAJOR) {
5307
                WOLFSSL_MSG("Mismatched protocol version");
5308
                return WOLFSSL_FAILURE;
5309
            }
5310
            break;
5311
    #endif
5312
        }
5313
        /* Update the method */
5314
        switch (ver) {
5315
    #ifndef NO_TLS
5316
        case SSL3_VERSION:
5317
            ctx->method->version.minor = SSLv3_MINOR;
5318
            break;
5319
        case TLS1_VERSION:
5320
            ctx->method->version.minor = TLSv1_MINOR;
5321
            break;
5322
        case TLS1_1_VERSION:
5323
            ctx->method->version.minor = TLSv1_1_MINOR;
5324
            break;
5325
        case TLS1_2_VERSION:
5326
            ctx->method->version.minor = TLSv1_2_MINOR;
5327
            break;
5328
        case TLS1_3_VERSION:
5329
            ctx->method->version.minor = TLSv1_3_MINOR;
5330
            break;
5331
    #endif
5332
    #ifdef WOLFSSL_DTLS
5333
        case DTLS1_VERSION:
5334
            ctx->method->version.minor = DTLS_MINOR;
5335
            break;
5336
        case DTLS1_2_VERSION:
5337
            ctx->method->version.minor = DTLSv1_2_MINOR;
5338
            break;
5339
    #endif
5340
        default:
5341
            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
5342
            return WOLFSSL_FAILURE;
5343
        }
5344
    }
5345
    return ret;
5346
}
5347
5348
5349
/* Sets the max protocol version allowed with WOLFSSL_CTX
5350
 * returns WOLFSSL_SUCCESS on success */
5351
int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
5352
{
5353
    int i;
5354
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
5355
    int minProto;
5356
    byte minVersionSet;
5357
5358
    WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version");
5359
5360
    if (ctx == NULL) {
5361
        return ret;
5362
    }
5363
5364
    /* clear out flags and reset min protocol version */
5365
    minProto = wolfSSL_CTX_get_min_proto_version(ctx);
5366
    wolfSSL_CTX_clear_options(ctx,
5367
            WOLFSSL_OP_NO_TLSv1 | WOLFSSL_OP_NO_TLSv1_1 |
5368
            WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3);
5369
    minVersionSet = ctx->minVersionSet;
5370
    wolfSSL_CTX_set_min_proto_version(ctx, minProto);
5371
    ctx->minVersionSet = minVersionSet; /* restoring, not setting, a minimum */
5372
    if (version != 0) {
5373
        ctx->maxProto = 0; /* turn max proto flag off */
5374
        return Set_CTX_max_proto_version(ctx, version);
5375
    }
5376
5377
    /* when 0 is specified as version, try to find out the min version from
5378
     * the bottom to top of the protoverTbl.
5379
     */
5380
    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
5381
        ret = Set_CTX_max_proto_version(ctx, protoVerTbl[i]);
5382
        if (ret == WOLFSSL_SUCCESS) {
5383
            ctx->maxProto = 1; /* turn max proto flag on */
5384
            break;
5385
        }
5386
    }
5387
5388
    return ret;
5389
}
5390
5391
5392
static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver)
5393
{
5394
    WOLFSSL_ENTER("Set_SSL_min_proto_version");
5395
5396
    if (ssl == NULL) {
5397
        return WOLFSSL_FAILURE;
5398
    }
5399
5400
    switch (ver) {
5401
#ifndef NO_TLS
5402
        case SSL3_VERSION:
5403
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
5404
            ssl->options.minDowngrade = SSLv3_MINOR;
5405
            break;
5406
#endif
5407
        case TLS1_VERSION:
5408
        #ifdef WOLFSSL_ALLOW_TLSV10
5409
            ssl->options.minDowngrade = TLSv1_MINOR;
5410
            break;
5411
        #endif
5412
        case TLS1_1_VERSION:
5413
        #ifndef NO_OLD_TLS
5414
            ssl->options.minDowngrade = TLSv1_1_MINOR;
5415
            break;
5416
        #endif
5417
        case TLS1_2_VERSION:
5418
        #ifndef WOLFSSL_NO_TLS12
5419
            ssl->options.minDowngrade = TLSv1_2_MINOR;
5420
            break;
5421
        #endif
5422
        case TLS1_3_VERSION:
5423
        #ifdef WOLFSSL_TLS13
5424
            ssl->options.minDowngrade = TLSv1_3_MINOR;
5425
            break;
5426
        #endif
5427
#endif
5428
#ifdef WOLFSSL_DTLS
5429
        case DTLS1_VERSION:
5430
    #ifndef NO_OLD_TLS
5431
            ssl->options.minDowngrade = DTLS_MINOR;
5432
            break;
5433
    #endif
5434
        case DTLS1_2_VERSION:
5435
            ssl->options.minDowngrade = DTLSv1_2_MINOR;
5436
            break;
5437
#endif
5438
        default:
5439
            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
5440
            return WOLFSSL_FAILURE;
5441
    }
5442
5443
    switch (ver) {
5444
#ifndef NO_TLS
5445
    case TLS1_3_VERSION:
5446
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
5447
        FALL_THROUGH;
5448
    case TLS1_2_VERSION:
5449
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
5450
        FALL_THROUGH;
5451
    case TLS1_1_VERSION:
5452
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
5453
        FALL_THROUGH;
5454
    case TLS1_VERSION:
5455
        ssl->options.mask |= WOLFSSL_OP_NO_SSLv3;
5456
        break;
5457
    case SSL3_VERSION:
5458
    case SSL2_VERSION:
5459
        /* Nothing to do here */
5460
        break;
5461
#endif
5462
#ifdef WOLFSSL_DTLS
5463
    case DTLS1_VERSION:
5464
    case DTLS1_2_VERSION:
5465
        break;
5466
#endif
5467
    default:
5468
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
5469
        return WOLFSSL_FAILURE;
5470
    }
5471
5472
    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
5473
}
5474
5475
int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version)
5476
{
5477
    int i;
5478
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);;
5479
5480
    WOLFSSL_ENTER("wolfSSL_set_min_proto_version");
5481
5482
    if (ssl == NULL) {
5483
        return WOLFSSL_FAILURE;
5484
    }
5485
    if (version != 0) {
5486
        ret = Set_SSL_min_proto_version(ssl, version);
5487
    }
5488
    else {
5489
        /* when 0 is specified as version, try to find out the min version */
5490
        for (i= 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
5491
            ret = Set_SSL_min_proto_version(ssl, protoVerTbl[i]);
5492
            if (ret == WOLFSSL_SUCCESS)
5493
                break;
5494
        }
5495
    }
5496
5497
    if (ret == WOLFSSL_SUCCESS) {
5498
        /* Version 0 picks the lowest, so the user set no minimum */
5499
        ssl->options.minVersionSet = (version != 0);
5500
        RestoreDowngrade(ssl);
5501
    }
5502
5503
    return ret;
5504
}
5505
5506
static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver)
5507
{
5508
5509
    WOLFSSL_ENTER("Set_SSL_max_proto_version");
5510
5511
    if (!ssl) {
5512
        WOLFSSL_MSG("Bad parameter");
5513
        return WOLFSSL_FAILURE;
5514
    }
5515
5516
    switch (ver) {
5517
    case SSL2_VERSION:
5518
        WOLFSSL_MSG("wolfSSL does not support SSLv2");
5519
        return WOLFSSL_FAILURE;
5520
#ifndef NO_TLS
5521
    case SSL3_VERSION:
5522
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
5523
        FALL_THROUGH;
5524
    case TLS1_VERSION:
5525
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
5526
        FALL_THROUGH;
5527
    case TLS1_1_VERSION:
5528
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
5529
        FALL_THROUGH;
5530
    case TLS1_2_VERSION:
5531
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_3;
5532
        FALL_THROUGH;
5533
    case TLS1_3_VERSION:
5534
        /* Nothing to do here */
5535
        break;
5536
#endif
5537
#ifdef WOLFSSL_DTLS
5538
    case DTLS1_VERSION:
5539
    case DTLS1_2_VERSION:
5540
        break;
5541
#endif
5542
    default:
5543
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
5544
        return WOLFSSL_FAILURE;
5545
    }
5546
5547
    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
5548
}
5549
5550
int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version)
5551
{
5552
    int i;
5553
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);;
5554
5555
    WOLFSSL_ENTER("wolfSSL_set_max_proto_version");
5556
5557
    if (ssl == NULL) {
5558
        return WOLFSSL_FAILURE;
5559
    }
5560
    if (version != 0) {
5561
        return Set_SSL_max_proto_version(ssl, version);
5562
    }
5563
5564
    /* when 0 is specified as version, try to find out the min version from
5565
     * the bottom to top of the protoverTbl.
5566
     */
5567
    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
5568
        ret = Set_SSL_max_proto_version(ssl, protoVerTbl[i]);
5569
        if (ret == WOLFSSL_SUCCESS)
5570
            break;
5571
    }
5572
5573
    return ret;
5574
}
5575
5576
static int GetMinProtoVersion(int minDowngrade)
5577
{
5578
    int ret;
5579
5580
    switch (minDowngrade) {
5581
#ifndef NO_OLD_TLS
5582
    #ifdef WOLFSSL_ALLOW_SSLV3
5583
        case SSLv3_MINOR:
5584
            ret = SSL3_VERSION;
5585
            break;
5586
    #endif
5587
    #ifdef WOLFSSL_ALLOW_TLSV10
5588
        case TLSv1_MINOR:
5589
            ret = TLS1_VERSION;
5590
            break;
5591
    #endif
5592
        case TLSv1_1_MINOR:
5593
            ret = TLS1_1_VERSION;
5594
            break;
5595
#endif
5596
#ifndef WOLFSSL_NO_TLS12
5597
        case TLSv1_2_MINOR:
5598
            ret = TLS1_2_VERSION;
5599
            break;
5600
#endif
5601
#ifdef WOLFSSL_TLS13
5602
        case TLSv1_3_MINOR:
5603
            ret = TLS1_3_VERSION;
5604
            break;
5605
#endif
5606
        default:
5607
            ret = 0;
5608
            break;
5609
    }
5610
5611
    return ret;
5612
}
5613
5614
int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx)
5615
{
5616
    int ret = 0;
5617
5618
    WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version");
5619
5620
    if (ctx != NULL) {
5621
        if (ctx->minProto) {
5622
            ret = 0;
5623
        }
5624
        else {
5625
            ret = GetMinProtoVersion(ctx->minDowngrade);
5626
        }
5627
    }
5628
    else {
5629
        ret = GetMinProtoVersion(WOLFSSL_MIN_DOWNGRADE);
5630
    }
5631
5632
    WOLFSSL_LEAVE("wolfSSL_CTX_get_min_proto_version", ret);
5633
5634
    return ret;
5635
}
5636
5637
5638
/* returns the maximum allowed protocol version given the 'options' used
5639
 * returns WOLFSSL_FATAL_ERROR on no match */
5640
static int GetMaxProtoVersion(long options)
5641
{
5642
#ifndef NO_TLS
5643
#ifdef WOLFSSL_TLS13
5644
    if (!(options & WOLFSSL_OP_NO_TLSv1_3))
5645
        return TLS1_3_VERSION;
5646
#endif
5647
#ifndef WOLFSSL_NO_TLS12
5648
    if (!(options & WOLFSSL_OP_NO_TLSv1_2))
5649
        return TLS1_2_VERSION;
5650
#endif
5651
#ifndef NO_OLD_TLS
5652
    if (!(options & WOLFSSL_OP_NO_TLSv1_1))
5653
        return TLS1_1_VERSION;
5654
    #ifdef WOLFSSL_ALLOW_TLSV10
5655
    if (!(options & WOLFSSL_OP_NO_TLSv1))
5656
        return TLS1_VERSION;
5657
    #endif
5658
    #ifdef WOLFSSL_ALLOW_SSLV3
5659
    if (!(options & WOLFSSL_OP_NO_SSLv3))
5660
        return SSL3_VERSION;
5661
    #endif
5662
#endif
5663
#else
5664
    (void)options;
5665
#endif /* NO_TLS */
5666
    return WOLFSSL_FATAL_ERROR;
5667
}
5668
5669
5670
/* returns the maximum protocol version for 'ctx' */
5671
int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx)
5672
{
5673
    int ret = 0;
5674
    long options = 0; /* default to nothing set */
5675
5676
    WOLFSSL_ENTER("wolfSSL_CTX_get_max_proto_version");
5677
5678
    if (ctx != NULL) {
5679
        options = wolfSSL_CTX_get_options(ctx);
5680
    }
5681
5682
    if ((ctx != NULL) && ctx->maxProto) {
5683
        ret = 0;
5684
    }
5685
    else {
5686
        ret = GetMaxProtoVersion(options);
5687
    }
5688
5689
    WOLFSSL_LEAVE("wolfSSL_CTX_get_max_proto_version", ret);
5690
5691
    if (ret == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) {
5692
        WOLFSSL_MSG("Error getting max proto version");
5693
        ret = 0; /* setting ret to 0 to match compat return */
5694
    }
5695
    return ret;
5696
}
5697
#endif /* OPENSSL_EXTRA */
5698
5699
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
5700
    defined(HAVE_SECRET_CALLBACK)
5701
#if !defined(NO_WOLFSSL_CLIENT)
5702
/* Return the amount of random bytes copied over or error case.
5703
 * ssl : ssl struct after handshake
5704
 * out : buffer to hold random bytes
5705
 * outSz : either 0 (return max buffer sz) or size of out buffer
5706
 */
5707
size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
5708
                                                                   size_t outSz)
5709
{
5710
    size_t size;
5711
5712
    /* return max size of buffer */
5713
    if (outSz == 0) {
5714
        return RAN_LEN;
5715
    }
5716
5717
    if (ssl == NULL || out == NULL) {
5718
        return 0;
5719
    }
5720
5721
    if (ssl->arrays == NULL) {
5722
        WOLFSSL_MSG("Arrays struct not saved after handshake");
5723
        return 0;
5724
    }
5725
5726
    if (outSz > RAN_LEN) {
5727
        size = RAN_LEN;
5728
    }
5729
    else {
5730
        size = outSz;
5731
    }
5732
5733
    XMEMCPY(out, ssl->arrays->clientRandom, size);
5734
    return size;
5735
}
5736
#endif /* !NO_WOLFSSL_CLIENT */
5737
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
5738
5739
#ifdef OPENSSL_EXTRA
5740
5741
    unsigned long wolfSSLeay(void)
5742
    {
5743
#ifdef SSLEAY_VERSION_NUMBER
5744
        return SSLEAY_VERSION_NUMBER;
5745
#else
5746
        return OPENSSL_VERSION_NUMBER;
5747
#endif
5748
    }
5749
5750
    unsigned long wolfSSL_OpenSSL_version_num(void)
5751
    {
5752
        return OPENSSL_VERSION_NUMBER;
5753
    }
5754
5755
    const char* wolfSSLeay_version(int type)
5756
    {
5757
        return wolfSSL_OpenSSL_version(type);
5758
    }
5759
#endif /* OPENSSL_EXTRA */
5760
5761
#ifdef OPENSSL_EXTRA
5762
5763
    void wolfSSL_cleanup_all_ex_data(void)
5764
    {
5765
        /* nothing to do here */
5766
    }
5767
5768
#endif /* OPENSSL_EXTRA */
5769
5770
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) || \
5771
    defined(HAVE_CURL)
5772
#endif
5773
5774
    int wolfSSL_clear(WOLFSSL* ssl)
5775
0
    {
5776
0
        WOLFSSL_ENTER("wolfSSL_clear");
5777
5778
0
        if (ssl == NULL) {
5779
0
            return WOLFSSL_FAILURE;
5780
0
        }
5781
5782
0
        if (!ssl->options.handShakeDone) {
5783
            /* Only reset the session if we didn't complete a handshake */
5784
0
            wolfSSL_FreeSession(ssl->ctx, ssl->session);
5785
0
            ssl->session = wolfSSL_NewSession(ssl->heap);
5786
0
            if (ssl->session == NULL) {
5787
0
                return WOLFSSL_FAILURE;
5788
0
            }
5789
0
        }
5790
5791
        /* reset error */
5792
0
        ssl->error = 0;
5793
5794
        /* reset option bits */
5795
0
        ssl->options.isClosed = 0;
5796
0
        ssl->options.connReset = 0;
5797
0
        ssl->options.sentNotify = 0;
5798
0
        ssl->options.closeNotify = 0;
5799
0
        ssl->options.sendVerify = 0;
5800
0
        ssl->options.serverState = NULL_STATE;
5801
0
        ssl->options.clientState = NULL_STATE;
5802
0
        ssl->options.connectState = CONNECT_BEGIN;
5803
0
        ssl->options.acceptState  = ACCEPT_BEGIN;
5804
0
        ssl->options.handShakeState  = NULL_STATE;
5805
0
        ssl->options.handShakeDone = 0;
5806
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_ASYNC_CERT_YIELD)
5807
        /* A per-certificate yield (WOLFSSL_ASYNC_CERT_YIELD) sets this and it is
5808
         * normally cleared on the next ProcessPeerCerts re-entry. Clear it here
5809
         * so reusing this object after abandoning a yielded handshake cannot
5810
         * skip the ProcessPeerCerts state reset on the next fresh entry. */
5811
        ssl->options.certYieldPending = 0;
5812
#endif
5813
0
        ssl->recordSzOverhead = 0;
5814
#ifdef WOLFSSL_TLS13_STREAM_CERT_VERIFY
5815
        /* Drop any half-sent streamed CertificateVerify. Left in place, the
5816
         * resume guard in SendTls13CertificateVerify would fire on the next
5817
         * handshake and re-send the previous one's signature. */
5818
        XFREE(ssl->buffers.certVerifyMsg.buffer, ssl->heap,
5819
              DYNAMIC_TYPE_TMP_BUFFER);
5820
        ssl->buffers.certVerifyMsg.buffer = NULL;
5821
        ssl->buffers.certVerifyMsg.length = 0;
5822
        ssl->fragOffset = 0;
5823
#endif
5824
0
        ssl->options.processReply = 0; /* doProcessInit */
5825
0
        ssl->options.havePeerVerify = 0;
5826
0
        ssl->options.havePeerCert = 0;
5827
0
        ssl->options.peerAuthGood = 0;
5828
0
        ssl->options.tls1_3 = 0;
5829
0
        ssl->options.haveSessionId = 0;
5830
0
        ssl->options.tls = 0;
5831
0
        ssl->options.tls1_1 = 0;
5832
0
#ifdef HAVE_EXTENDED_MASTER
5833
        /* haveEMS is negotiated per handshake: re-arm an EMS-capable client
5834
         * unless the user disabled EMS, and clear a server until the next
5835
         * ClientHello. The requireEMS/disableEMS policy persists. */
5836
0
        ssl->options.haveEMS = 0;
5837
0
        if (ssl->options.side == WOLFSSL_CLIENT_END &&
5838
0
                !ssl->options.disableEMS) {
5839
0
            if (ssl->ctx->method->version.major == SSLv3_MAJOR &&
5840
0
                    ssl->ctx->method->version.minor >= TLSv1_MINOR) {
5841
0
                ssl->options.haveEMS = 1;
5842
0
            }
5843
        #ifdef WOLFSSL_DTLS
5844
            if (ssl->ctx->method->version.major == DTLS_MAJOR)
5845
                ssl->options.haveEMS = 1;
5846
        #endif
5847
0
        }
5848
0
#endif
5849
0
    #ifdef WOLFSSL_TLS13
5850
0
    #ifdef WOLFSSL_TLS13_COOKIE
5851
0
        ssl->options.hrrSentCookie = 0;
5852
0
    #endif
5853
0
        ssl->options.hrrSentKeyShare = 0;
5854
0
        ssl->options.sentChangeCipher = 0;
5855
        /* Matches InitSSL_Tls13Options(); the server clears it again when the
5856
         * next ClientHello carries an empty session id. */
5857
0
        ssl->options.tls13MiddleBoxCompat = 1;
5858
0
        ssl->options.shSentKeyShare = 0;
5859
0
    #endif
5860
0
    #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
5861
        /* The group the previous connection negotiated. Nothing else clears
5862
         * it, and a handshake that negotiates none - TLS 1.3 psk_ke - would
5863
         * leave it readable as this connection's. */
5864
0
        ssl->namedGroup = 0;
5865
0
    #endif
5866
0
    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
5867
0
        defined(HAVE_CURVE25519) || defined(HAVE_ED448) || \
5868
0
        defined(HAVE_CURVE448)
5869
        /* The peer's ephemeral key is now kept past the handshake for
5870
         * wolfSSL_get_peer_tmp_key(). A next handshake that negotiates no
5871
         * (EC)DH would otherwise report the previous connection's key.
5872
         * Back to what SetSSL_CTX() starts from, so a curve set with
5873
         * wolfSSL_CTX_set_tmp_ecdh() survives. */
5874
0
        ssl->ecdhCurveOID = ssl->ctx->ecdhCurveOID;
5875
0
        ssl->peerEccKeyPresent = 0;
5876
0
    #endif
5877
    #ifdef HAVE_CURVE25519
5878
        ssl->peerX25519KeyPresent = 0;
5879
    #endif
5880
    #ifdef HAVE_CURVE448
5881
        ssl->peerX448KeyPresent = 0;
5882
    #endif
5883
    #ifdef WOLFSSL_DTLS
5884
        ssl->options.dtlsStateful = 0;
5885
    #endif
5886
0
    #ifdef WOLFSSL_TLS13
5887
    #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
5888
        ssl->options.noPskDheKe = ssl->ctx->noPskDheKe;
5889
        ssl->options.noPskDheKePolicy = ssl->ctx->noPskDheKe;
5890
        #ifdef HAVE_SUPPORTED_CURVES
5891
        ssl->options.onlyPskDheKe = ssl->ctx->onlyPskDheKe;
5892
        #endif
5893
    #endif
5894
        /* An abandoned handshake can leave a key-schedule or record-build
5895
         * resume marker set; a reused object must not resume into the new
5896
         * handshake. */
5897
0
        ssl->kdfDeriveStep = TLS13_SEND_KDF_NONE;
5898
0
        ssl->kdfMsgStep = TLS13_MSG_KDF_NONE;
5899
0
        ssl->kdfMsgType = 0;
5900
        #if defined(WOLFSSL_ASYNC_REINVOKE) && !defined(NO_HMAC)
5901
        Tls13FreeHsHmac(ssl);
5902
        #endif
5903
        #ifdef WOLFSSL_ASYNC_CRYPT
5904
        ssl->options.buildArgs13Set = 0;
5905
        /* An abandoned handshake can leave a mid-flight handler resume
5906
         * state and a queued key-schedule event behind; a reused object
5907
         * must start fresh. */
5908
        ssl->options.asyncState = TLS_ASYNC_BEGIN;
5909
        if (ssl->asyncDev == &ssl->kdfAsyncDev) {
5910
            if (ssl->kdfAsyncDev.event.state == WOLF_EVENT_STATE_PENDING &&
5911
                    ssl->ctx != NULL) {
5912
                (void)wolfEventQueue_Remove(&ssl->ctx->event_queue,
5913
                                            &ssl->kdfAsyncDev.event);
5914
            }
5915
            XMEMSET(&ssl->kdfAsyncDev.event, 0, sizeof(WOLF_EVENT));
5916
            ssl->asyncDev = NULL;
5917
        }
5918
        #endif
5919
0
    #endif
5920
    #ifdef HAVE_SESSION_TICKET
5921
        #ifdef WOLFSSL_TLS13
5922
        ssl->options.ticketsSent = 0;
5923
        #if !defined(NO_WOLFSSL_SERVER) && \
5924
            defined(WOLFSSL_TLS13_TICKET_CHECK_PSK_MODES)
5925
        /* Recorded from the ClientHello, so it must not carry into the next
5926
         * connection on a reused object. */
5927
        ssl->options.pskKeModes = 0;
5928
        ssl->options.pskKeModesRecvd = 0;
5929
        #endif
5930
        #endif
5931
        ssl->options.rejectTicket = 0;
5932
    #endif
5933
    #ifdef WOLFSSL_EARLY_DATA
5934
        ssl->earlyData = no_early_data;
5935
        ssl->earlyDataSz = 0;
5936
    #endif
5937
    #ifdef HAVE_RPK
5938
        /* Drop the negotiated cert types so one peer's choice cannot carry into
5939
         * the next handshake. Clearing the counts is enough: every read of the
5940
         * type arrays is gated on its count. */
5941
        ssl->options.rpkState.sending_ClientCertTypeCnt = 0;
5942
        ssl->options.rpkState.sending_ServerCertTypeCnt = 0;
5943
        ssl->options.rpkState.received_ClientCertTypeCnt = 0;
5944
        ssl->options.rpkState.received_ServerCertTypeCnt = 0;
5945
    #endif
5946
5947
0
    #if defined(HAVE_TLS_EXTENSIONS) && !defined(NO_TLS)
5948
0
        TLSX_FreeAll(ssl->extensions, ssl->heap);
5949
0
        ssl->extensions = NULL;
5950
0
      #if defined(HAVE_SECURE_RENEGOTIATION) \
5951
0
       || defined(HAVE_SERVER_RENEGOTIATION_INFO)
5952
0
        ssl->secure_renegotiation = NULL;
5953
        /* The renegotiation_info advertising is re-established when the next
5954
         * ClientHello is built (SendClientHello), so a reused client object
5955
         * keeps the "advertise implies enforce" invariant (RFC 5746). */
5956
0
      #endif
5957
0
    #endif
5958
5959
0
        if (ssl->keys.encryptionOn) {
5960
0
            ForceZero(ssl->buffers.inputBuffer.buffer -
5961
0
                ssl->buffers.inputBuffer.offset,
5962
0
                ssl->buffers.inputBuffer.bufferSize);
5963
        #ifdef WOLFSSL_CHECK_MEM_ZERO
5964
            wc_MemZero_Check(ssl->buffers.inputBuffer.buffer -
5965
                ssl->buffers.inputBuffer.offset,
5966
                ssl->buffers.inputBuffer.bufferSize);
5967
        #endif
5968
0
        }
5969
        /* Recycling the object for a new connection must not carry the
5970
         * previous connection's key material along with it. A freshly
5971
         * created object has all of this zeroed. */
5972
0
        ForceZero(&ssl->keys, sizeof(Keys));
5973
    #ifdef WOLFSSL_MULTICAST
5974
        if (ssl->options.haveMcast) {
5975
            int i;
5976
5977
            for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++)
5978
                ssl->keys.peerSeq[i].peerId = INVALID_PEER_ID;
5979
        }
5980
    #endif
5981
0
    #ifdef WOLFSSL_TLS13
5982
0
        ForceZero(ssl->clientSecret, sizeof(ssl->clientSecret));
5983
0
        ForceZero(ssl->serverSecret, sizeof(ssl->serverSecret));
5984
        /* A key update the previous connection asked for has nothing to say
5985
         * about the next one, and the keys it would rotate are gone. */
5986
0
        ssl->options.sendKeyUpdate = 0;
5987
0
    #endif
5988
    #ifdef WOLFSSL_HAVE_TLS_UNIQUE
5989
        /* The channel binding of the connection that just ended. Leaving it
5990
         * in place would let the next caller bind to the wrong session. */
5991
        ForceZero(ssl->clientFinished, TLS_FINISHED_SZ_MAX);
5992
        ForceZero(ssl->serverFinished, TLS_FINISHED_SZ_MAX);
5993
        ssl->clientFinished_len = 0;
5994
        ssl->serverFinished_len = 0;
5995
    #endif
5996
    #ifdef WOLFSSL_DTLS13
5997
        /* Per-epoch traffic keys, IVs and sequence number keys. */
5998
        ForceZero(ssl->dtls13Epochs, sizeof(ssl->dtls13Epochs));
5999
        /* Only InitSSL() sets up the unprotected epoch 0 and aims the epoch
6000
         * pointers at it, and this object is being reused rather than freed,
6001
         * so put it back or the next handshake has no valid epoch. */
6002
        ssl->dtls13Epochs[0].isValid = 1;
6003
        ssl->dtls13Epochs[0].side = ENCRYPT_AND_DECRYPT_SIDE;
6004
        ssl->dtls13EncryptEpoch = &ssl->dtls13Epochs[0];
6005
        ssl->dtls13DecryptEpoch = &ssl->dtls13Epochs[0];
6006
        /* The numbers that say which epoch to use sit outside the table and
6007
         * only ever move up, so wiping the table has to be matched here by
6008
         * hand. InitSSL() gets this for free from clearing the whole object.
6009
         * Left behind, they ask the next handshake to send under an epoch the
6010
         * table no longer holds, and Dtls13SetEpochKeys() fails the connection
6011
         * with BAD_STATE_E. */
6012
        w64Zero(&ssl->dtls13Epoch);
6013
        w64Zero(&ssl->dtls13PeerEpoch);
6014
        w64Zero(&ssl->dtls13InvalidateBefore);
6015
        ssl->dtls13WaitKeyUpdateAck = 0;
6016
        ssl->dtls13DoKeyUpdate = 0;
6017
        ssl->dtls13SendingAckOrRtx = 0;
6018
        /* Anything still queued for retransmission or acknowledgement is
6019
         * tagged with an epoch that no longer exists, so it can never be sent
6020
         * and would only be released when the object is freed. */
6021
        Dtls13FreeFsmResources(ssl);
6022
        ssl->dtls13Rtx.sendAcks = 0;
6023
        ssl->dtls13Rtx.retransmit = 0;
6024
    #endif
6025
        /* The handshake arrays hold the master and pre-master secrets. Wipe
6026
         * those in place rather than releasing the arrays, so that the
6027
         * allocation stays valid for wolfSSL_set_secret(), the exporter and
6028
         * the other accessors that read from it once a connection has ended.
6029
         * An application that asked to keep the arrays still gets back
6030
         * everything the API can hand it, so only the rest goes. */
6031
0
        if (ssl->arrays != NULL) {
6032
0
            if (ssl->arrays->preMasterSecret != NULL) {
6033
0
                ForceZero(ssl->arrays->preMasterSecret, ENCRYPT_LEN);
6034
                /* The key agreement routines take this as the size of the
6035
                 * buffer they may write, so put back what a freshly
6036
                 * allocated Arrays would carry. */
6037
0
                ssl->arrays->preMasterSz = ENCRYPT_LEN;
6038
0
            }
6039
        #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
6040
            ForceZero(ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
6041
            ssl->arrays->psk_keySz = 0;
6042
        #endif
6043
0
        #ifdef WOLFSSL_TLS13
6044
            /* The key schedule secret. No API hands this one back. */
6045
0
            ForceZero(ssl->arrays->secret, SECRET_LEN);
6046
0
        #endif
6047
0
            if (!ssl->options.saveArrays) {
6048
0
                ForceZero(ssl->arrays->masterSecret, SECRET_LEN);
6049
            #ifdef HAVE_KEYING_MATERIAL
6050
                /* Tls13_Exporter() reads this one, and exporting keying
6051
                 * material requires the arrays to be kept, so it only goes
6052
                 * when the application did not ask for that. */
6053
                ForceZero(ssl->arrays->exporterSecret, WC_MAX_DIGEST_SIZE);
6054
            #endif
6055
0
            }
6056
0
        }
6057
0
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
6058
6059
        /* Discard any partial handshake-message reassembly on reuse. */
6060
0
        XFREE(ssl->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS);
6061
0
        ssl->pendingMsg = NULL;
6062
0
        ssl->pendingMsgSz = 0;
6063
0
        ssl->pendingMsgOffset = 0;
6064
0
        ssl->pendingMsgType = 0;
6065
6066
0
        FreeCiphers(ssl);
6067
0
        InitCiphers(ssl);
6068
0
        InitCipherSpecs(&ssl->specs);
6069
6070
0
        if (InitSSL_Suites(ssl) != WOLFSSL_SUCCESS)
6071
0
            return WOLFSSL_FAILURE;
6072
6073
0
        if (InitHandshakeHashes(ssl) != 0)
6074
0
            return WOLFSSL_FAILURE;
6075
6076
#ifdef KEEP_PEER_CERT
6077
        FreeX509(&ssl->peerCert);
6078
        InitX509(&ssl->peerCert, 0, ssl->heap);
6079
#endif
6080
6081
#ifdef WOLFSSL_QUIC
6082
        wolfSSL_quic_clear(ssl);
6083
#endif
6084
#ifdef HAVE_OCSP
6085
#if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
6086
        ssl->response_idx = 0;
6087
#endif
6088
#endif
6089
0
        return WOLFSSL_SUCCESS;
6090
0
    }
6091
6092
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || defined(HAVE_MEMCACHED)
6093
    long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
6094
    {
6095
        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
6096
6097
        WOLFSSL_ENTER("wolfSSL_CTX_set_mode");
6098
        switch(mode) {
6099
            case WOLFSSL_MODE_ENABLE_PARTIAL_WRITE:
6100
                ctx->partialWrite = 1;
6101
                break;
6102
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
6103
            case SSL_MODE_RELEASE_BUFFERS:
6104
                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
6105
                break;
6106
            #endif
6107
            case WOLFSSL_MODE_AUTO_RETRY:
6108
                ctx->autoRetry = 1;
6109
                break;
6110
            default:
6111
                WOLFSSL_MSG("Mode Not Implemented");
6112
        }
6113
6114
        /* WOLFSSL_MODE_AUTO_RETRY
6115
         * Should not return WOLFSSL_FATAL_ERROR with renegotiation on read/write */
6116
6117
        return mode;
6118
    }
6119
6120
    long wolfSSL_CTX_clear_mode(WOLFSSL_CTX* ctx, long mode)
6121
    {
6122
        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
6123
6124
        WOLFSSL_ENTER("wolfSSL_CTX_clear_mode");
6125
        switch(mode) {
6126
            case WOLFSSL_MODE_ENABLE_PARTIAL_WRITE:
6127
                ctx->partialWrite = 0;
6128
                break;
6129
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
6130
            case SSL_MODE_RELEASE_BUFFERS:
6131
                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
6132
                break;
6133
            #endif
6134
            case WOLFSSL_MODE_AUTO_RETRY:
6135
                ctx->autoRetry = 0;
6136
                break;
6137
            default:
6138
                WOLFSSL_MSG("Mode Not Implemented");
6139
        }
6140
6141
        /* WOLFSSL_MODE_AUTO_RETRY
6142
         * Should not return WOLFSSL_FATAL_ERROR with renegotiation on read/write */
6143
6144
        return 0;
6145
    }
6146
#endif
6147
6148
#ifdef OPENSSL_EXTRA
6149
6150
    #ifndef NO_WOLFSSL_STUB
6151
    long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
6152
    {
6153
        /* TODO: */
6154
        (void)ssl;
6155
        WOLFSSL_STUB("SSL_get_mode");
6156
        return 0;
6157
    }
6158
    #endif
6159
6160
    #ifndef NO_WOLFSSL_STUB
6161
    long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
6162
    {
6163
        /* TODO: */
6164
        (void)ctx;
6165
        WOLFSSL_STUB("SSL_CTX_get_mode");
6166
        return 0;
6167
    }
6168
    #endif
6169
6170
    #ifndef NO_WOLFSSL_STUB
6171
    void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
6172
    {
6173
        /* TODO: maybe? */
6174
        (void)ctx;
6175
        (void)m;
6176
        WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
6177
    }
6178
    #endif
6179
6180
6181
    /* returns the unsigned error value and increments the pointer into the
6182
     * error queue.
6183
     *
6184
     * file  pointer to file name
6185
     * line  gets set to line number of error when not NULL
6186
     */
6187
6188
6189
6190
6191
6192
#endif /* OPENSSL_EXTRA */
6193
6194
6195
6196
6197
6198
6199
6200
int wolfSSL_session_reused(WOLFSSL* ssl)
6201
0
{
6202
0
    int resuming = 0;
6203
0
    WOLFSSL_ENTER("wolfSSL_session_reused");
6204
0
    if (ssl) {
6205
0
#ifndef HAVE_SECURE_RENEGOTIATION
6206
0
        resuming = ssl->options.resuming;
6207
#else
6208
        resuming = ssl->options.resuming || ssl->options.resumed;
6209
#endif
6210
0
    }
6211
0
    WOLFSSL_LEAVE("wolfSSL_session_reused", resuming);
6212
0
    return resuming;
6213
0
}
6214
6215
/* helper function that takes in a protocol version struct and returns string */
6216
static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
6217
0
{
6218
0
    WOLFSSL_ENTER("wolfSSL_get_version");
6219
6220
0
    if (version == NULL) {
6221
0
        return "Bad arg";
6222
0
    }
6223
6224
0
    if (version->major == SSLv3_MAJOR) {
6225
0
        switch (version->minor) {
6226
0
            case SSLv3_MINOR :
6227
0
                return "SSLv3";
6228
0
            case TLSv1_MINOR :
6229
0
                return "TLSv1";
6230
0
            case TLSv1_1_MINOR :
6231
0
                return "TLSv1.1";
6232
0
            case TLSv1_2_MINOR :
6233
0
                return "TLSv1.2";
6234
0
            case TLSv1_3_MINOR :
6235
0
                return "TLSv1.3";
6236
0
            default:
6237
0
                return "unknown";
6238
0
        }
6239
0
    }
6240
#ifdef WOLFSSL_DTLS
6241
    else if (version->major == DTLS_MAJOR) {
6242
        switch (version->minor) {
6243
            case DTLS_MINOR :
6244
                return "DTLS";
6245
            case DTLSv1_2_MINOR :
6246
                return "DTLSv1.2";
6247
            case DTLSv1_3_MINOR :
6248
                return "DTLSv1.3";
6249
            default:
6250
                return "unknown";
6251
        }
6252
    }
6253
#endif /* WOLFSSL_DTLS */
6254
0
    return "unknown";
6255
0
}
6256
6257
6258
const char* wolfSSL_get_version(const WOLFSSL* ssl)
6259
0
{
6260
0
    if (ssl == NULL) {
6261
0
        WOLFSSL_MSG("Bad argument");
6262
0
        return "unknown";
6263
0
    }
6264
6265
0
    return wolfSSL_internal_get_version(&ssl->version);
6266
0
}
6267
6268
6269
/* current library version */
6270
const char* wolfSSL_lib_version(void)
6271
0
{
6272
0
    return LIBWOLFSSL_VERSION_STRING;
6273
0
}
6274
6275
#ifdef OPENSSL_EXTRA
6276
/* Signature deliberately does not depend on OPENSSL_VERSION_NUMBER. That macro
6277
 * can evaluate differently in the library and in the application (e.g. under
6278
 * OPENSSL_COEXIST the library also sees the real OpenSSL headers), which would
6279
 * make the caller and the definition disagree on the argument list. */
6280
const char* wolfSSL_OpenSSL_version(int type)
6281
{
6282
    WOLFSSL_ENTER("wolfSSL_OpenSSL_version");
6283
    switch (type) {
6284
        case OPENSSL_VERSION:
6285
            return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
6286
        case OPENSSL_CFLAGS:
6287
            return "compiler: information not available";
6288
        case OPENSSL_BUILT_ON:
6289
        /* Kernel module builds compile with -Werror=date-time.  Define
6290
         * WOLFSSL_OPENSSL_NO_BUILD_DATE to drop the date without needing the
6291
         * full reproducible-build option. */
6292
#if defined(HAVE_REPRODUCIBLE_BUILD) || defined(WOLFSSL_LINUXKM) || \
6293
    defined(WOLFSSL_OPENSSL_NO_BUILD_DATE)
6294
            return "built on: date not available";
6295
#else
6296
            return "built on: " __DATE__ " " __TIME__;
6297
#endif
6298
        case OPENSSL_PLATFORM:
6299
            return "platform: information not available";
6300
        case OPENSSL_DIR:
6301
            return "OPENSSLDIR: N/A";
6302
        case OPENSSL_ENGINES_DIR:
6303
            return "ENGINESDIR: N/A";
6304
        default:
6305
            return "not available";
6306
    }
6307
}
6308
#endif /* OPENSSL_EXTRA */
6309
6310
6311
/* current library version in hex */
6312
word32 wolfSSL_lib_version_hex(void)
6313
0
{
6314
0
    return LIBWOLFSSL_VERSION_HEX;
6315
0
}
6316
6317
6318
int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
6319
0
{
6320
0
    WOLFSSL_ENTER("wolfSSL_get_current_cipher_suite");
6321
0
    if (ssl)
6322
0
        return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
6323
0
    return 0;
6324
0
}
6325
6326
WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
6327
0
{
6328
0
    WOLFSSL_ENTER("wolfSSL_get_current_cipher");
6329
0
    if (ssl) {
6330
0
        ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
6331
0
        ssl->cipher.cipherSuite  = ssl->options.cipherSuite;
6332
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
6333
        ssl->cipher.bits = ssl->specs.key_size * 8;
6334
#endif
6335
0
        return &ssl->cipher;
6336
0
    }
6337
0
    else
6338
0
        return NULL;
6339
0
}
6340
6341
6342
const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
6343
0
{
6344
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_name");
6345
6346
0
    if (cipher == NULL) {
6347
0
        return NULL;
6348
0
    }
6349
6350
0
    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
6351
0
        !defined(WOLFSSL_QT)
6352
0
        return GetCipherNameIana(cipher->cipherSuite0, cipher->cipherSuite);
6353
    #else
6354
        return wolfSSL_get_cipher_name_from_suite(cipher->cipherSuite0,
6355
                cipher->cipherSuite);
6356
    #endif
6357
0
}
6358
6359
const char*  wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
6360
0
{
6361
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_version");
6362
6363
0
    if (cipher == NULL || cipher->ssl == NULL) {
6364
0
        return NULL;
6365
0
    }
6366
6367
0
    return wolfSSL_get_version(cipher->ssl);
6368
0
}
6369
6370
const char* wolfSSL_get_cipher(WOLFSSL* ssl)
6371
0
{
6372
0
    WOLFSSL_ENTER("wolfSSL_get_cipher");
6373
0
    return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
6374
0
}
6375
6376
/* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
6377
const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
6378
0
{
6379
    /* get access to cipher_name_idx in internal.c */
6380
0
    return wolfSSL_get_cipher_name_internal(ssl);
6381
0
}
6382
6383
const char* wolfSSL_get_cipher_name_from_suite(byte cipherSuite0,
6384
    byte cipherSuite)
6385
0
{
6386
0
    return GetCipherNameInternal(cipherSuite0, cipherSuite);
6387
0
}
6388
6389
const char* wolfSSL_get_cipher_name_iana_from_suite(byte cipherSuite0,
6390
        byte cipherSuite)
6391
0
{
6392
0
    return GetCipherNameIana(cipherSuite0, cipherSuite);
6393
0
}
6394
6395
int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0,
6396
0
                                       byte* cipherSuite, int *flags) {
6397
0
    if ((name == NULL) ||
6398
0
        (cipherSuite0 == NULL) ||
6399
0
        (cipherSuite == NULL) ||
6400
0
        (flags == NULL))
6401
0
        return BAD_FUNC_ARG;
6402
0
    return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, NULL, NULL,
6403
0
                                  flags);
6404
0
}
6405
6406
6407
word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher)
6408
0
{
6409
0
    word16 cipher_id = 0;
6410
6411
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_id");
6412
6413
0
    if (cipher && cipher->ssl) {
6414
0
        cipher_id = (word16)(cipher->ssl->options.cipherSuite0 << 8) |
6415
0
                     cipher->ssl->options.cipherSuite;
6416
0
    }
6417
6418
0
    return cipher_id;
6419
0
}
6420
6421
const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
6422
0
{
6423
0
    const WOLFSSL_CIPHER* cipher = NULL;
6424
0
    byte cipherSuite0, cipherSuite;
6425
0
    WOLFSSL_ENTER("wolfSSL_get_cipher_by_value");
6426
6427
    /* extract cipher id information */
6428
0
    cipherSuite =   (value       & 0xFF);
6429
0
    cipherSuite0 = ((value >> 8) & 0xFF);
6430
6431
    /* TODO: lookup by cipherSuite0 / cipherSuite */
6432
0
    (void)cipherSuite0;
6433
0
    (void)cipherSuite;
6434
6435
0
    return cipher;
6436
0
}
6437
6438
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
6439
    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
6440
/* Locate a cipher in the SSL's cipher list by 2-byte wire-format suite id.
6441
 *
6442
 * Mirrors OpenSSL's SSL_CIPHER_find(): the SSL's configured cipher list is
6443
 * searched first, then all cipher suites known to the library are searched as
6444
 * a fallback. This lets callers decode a suite id seen on the wire even when
6445
 * it is not enabled on the SSL object.
6446
 *
6447
 * A match found in the SSL's cipher list returns storage owned by that list.
6448
 * A match found only in the library fallback is stored in the SSL object's
6449
 * scratch cipher (ssl->cipher), as wolfSSL_get_current_cipher does. In either
6450
 * case callers must not free the returned pointer; it remains valid until the
6451
 * next call that updates ssl->cipher, or until SSL_free.
6452
 *
6453
 * @param [in] ssl  SSL/TLS object whose cipher list is searched.
6454
 * @param [in] ptr  Pointer to a 2-byte cipher suite identifier.
6455
 * @return  Matching cipher on success.
6456
 * @return  NULL if ssl or ptr is NULL, or no cipher matches.
6457
 */
6458
const WOLFSSL_CIPHER* wolfSSL_SSL_CIPHER_find(WOLFSSL* ssl,
6459
    const unsigned char* ptr)
6460
{
6461
    WOLF_STACK_OF(WOLFSSL_CIPHER)* sk;
6462
    WOLFSSL_STACK* node;
6463
    const CipherSuiteInfo* cipher_names;
6464
    int cipherSz;
6465
    int i;
6466
6467
    WOLFSSL_ENTER("wolfSSL_SSL_CIPHER_find");
6468
6469
    if (ssl == NULL || ptr == NULL)
6470
        return NULL;
6471
6472
    sk = wolfSSL_get_ciphers_compat(ssl);
6473
    for (node = sk; node != NULL; node = node->next) {
6474
        if (node->data.cipher.cipherSuite0 == ptr[0] &&
6475
            node->data.cipher.cipherSuite  == ptr[1]) {
6476
            return &node->data.cipher;
6477
        }
6478
    }
6479
6480
    /* Not enabled on this SSL - fall back to a library-wide lookup so suite
6481
     * ids seen on the wire can still be decoded, matching OpenSSL. */
6482
    cipher_names = GetCipherNames();
6483
    cipherSz = GetCipherNamesSize();
6484
    for (i = 0; i < cipherSz; i++) {
6485
        if (cipher_names[i].cipherSuite0 == ptr[0] &&
6486
            cipher_names[i].cipherSuite  == ptr[1]) {
6487
            XMEMSET(&ssl->cipher, 0, sizeof(ssl->cipher));
6488
            ssl->cipher.cipherSuite0 = ptr[0];
6489
            ssl->cipher.cipherSuite  = ptr[1];
6490
            ssl->cipher.ssl          = ssl;
6491
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
6492
            ssl->cipher.offset       = (unsigned long)i;
6493
            /* Describe from cipher_names[offset]: ssl->specs holds the
6494
             * negotiated suite, not this one. */
6495
            ssl->cipher.in_stack     = TRUE;
6496
#endif
6497
            return &ssl->cipher;
6498
        }
6499
    }
6500
6501
    return NULL;
6502
}
6503
#endif
6504
6505
6506
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
6507
    !defined(NO_DH) || (defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM))
6508
#ifdef HAVE_FFDHE
6509
static const char* wolfssl_ffdhe_name(word16 group)
6510
0
{
6511
0
    const char* str = NULL;
6512
0
    switch (group) {
6513
0
        case WOLFSSL_FFDHE_2048:
6514
0
            str = "FFDHE_2048";
6515
0
            break;
6516
0
        case WOLFSSL_FFDHE_3072:
6517
0
            str = "FFDHE_3072";
6518
0
            break;
6519
0
        case WOLFSSL_FFDHE_4096:
6520
0
            str = "FFDHE_4096";
6521
0
            break;
6522
0
        case WOLFSSL_FFDHE_6144:
6523
0
            str = "FFDHE_6144";
6524
0
            break;
6525
0
        case WOLFSSL_FFDHE_8192:
6526
0
            str = "FFDHE_8192";
6527
0
            break;
6528
0
        default:
6529
0
            break;
6530
0
    }
6531
0
    return str;
6532
0
}
6533
#endif
6534
/* Return the name of the curve used for key exchange as a printable string.
6535
 *
6536
 * ssl  The SSL/TLS object.
6537
 * returns NULL if ECDH was not used, otherwise the name as a string.
6538
 */
6539
const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
6540
0
{
6541
0
    const char* cName = NULL;
6542
6543
0
    WOLFSSL_ENTER("wolfSSL_get_curve_name");
6544
6545
0
    if (ssl == NULL)
6546
0
        return NULL;
6547
6548
0
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM)
6549
    /* Check for post-quantum groups. Return now because we do not want the ECC
6550
     * check to override this result in the case of a hybrid. */
6551
0
    if (IsAtLeastTLSv1_3(ssl->version)) {
6552
0
        switch (ssl->namedGroup) {
6553
0
#ifndef WOLFSSL_NO_ML_KEM
6554
0
    #ifndef WOLFSSL_NO_ML_KEM_512
6555
0
        case WOLFSSL_ML_KEM_512:
6556
0
            return "ML_KEM_512";
6557
        #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
6558
        #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
6559
        case WOLFSSL_P256_ML_KEM_512_OLD:
6560
            return "P256_ML_KEM_512_OLD";
6561
        #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
6562
        case WOLFSSL_SECP256R1MLKEM512:
6563
            return "SecP256r1MLKEM512";
6564
        #ifdef HAVE_CURVE25519
6565
        case WOLFSSL_X25519MLKEM512:
6566
            return "X25519MLKEM512";
6567
        #endif /* HAVE_CURVE25519 */
6568
        #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
6569
0
    #endif /* WOLFSSL_NO_ML_KEM_512 */
6570
0
    #ifndef WOLFSSL_NO_ML_KEM_768
6571
0
        case WOLFSSL_ML_KEM_768:
6572
0
            return "ML_KEM_768";
6573
0
        #ifdef WOLFSSL_PQC_HYBRIDS
6574
0
        case WOLFSSL_SECP256R1MLKEM768:
6575
0
            return "SecP256r1MLKEM768";
6576
        #ifdef HAVE_CURVE25519
6577
        case WOLFSSL_X25519MLKEM768:
6578
            return "X25519MLKEM768";
6579
        #endif
6580
0
        #endif /* WOLFSSL_PQC_HYBRIDS */
6581
        #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
6582
        #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
6583
        case WOLFSSL_P384_ML_KEM_768_OLD:
6584
            return "P384_ML_KEM_768_OLD";
6585
        #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
6586
        case WOLFSSL_SECP384R1MLKEM768:
6587
            return "SecP384r1MLKEM768";
6588
        #ifdef HAVE_CURVE448
6589
        case WOLFSSL_X448MLKEM768:
6590
            return "X448MLKEM768";
6591
        #endif /* HAVE_CURVE448 */
6592
        #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
6593
0
    #endif /* WOLFSSL_NO_ML_KEM_768 */
6594
0
    #ifndef WOLFSSL_NO_ML_KEM_1024
6595
0
        case WOLFSSL_ML_KEM_1024:
6596
0
            return "ML_KEM_1024";
6597
0
        #ifdef WOLFSSL_PQC_HYBRIDS
6598
0
        case WOLFSSL_SECP384R1MLKEM1024:
6599
0
            return "SecP384r1MLKEM1024";
6600
0
        #endif /* WOLFSSL_PQC_HYBRIDS */
6601
        #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
6602
        #ifdef WOLFSSL_ML_KEM_USE_OLD_IDS
6603
        case WOLFSSL_P521_ML_KEM_1024_OLD:
6604
            return "P521_ML_KEM_1024_OLD";
6605
        #endif /* WOLFSSL_ML_KEM_USE_OLD_IDS */
6606
        case WOLFSSL_SECP521R1MLKEM1024:
6607
            return "SecP521r1MLKEM1024";
6608
        #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
6609
0
    #endif /* WOLFSSL_NO_ML_KEM_1024 */
6610
0
#endif /* WOLFSSL_NO_ML_KEM */
6611
#ifdef WOLFSSL_MLKEM_KYBER
6612
    #ifndef WOLFSSL_NO_KYBER512
6613
        case WOLFSSL_KYBER_LEVEL1:
6614
            return "KYBER_LEVEL1";
6615
        case WOLFSSL_P256_KYBER_LEVEL1:
6616
            return "P256_KYBER_LEVEL1";
6617
        #ifdef HAVE_CURVE25519
6618
        case WOLFSSL_X25519_KYBER_LEVEL1:
6619
            return "X25519_KYBER_LEVEL1";
6620
        #endif
6621
    #endif
6622
    #ifndef WOLFSSL_NO_KYBER768
6623
        case WOLFSSL_KYBER_LEVEL3:
6624
            return "KYBER_LEVEL3";
6625
        case WOLFSSL_P384_KYBER_LEVEL3:
6626
            return "P384_KYBER_LEVEL3";
6627
        case WOLFSSL_P256_KYBER_LEVEL3:
6628
            return "P256_KYBER_LEVEL3";
6629
        #ifdef HAVE_CURVE25519
6630
        case WOLFSSL_X25519_KYBER_LEVEL3:
6631
            return "X25519_KYBER_LEVEL3";
6632
        #endif
6633
        #ifdef HAVE_CURVE448
6634
        case WOLFSSL_X448_KYBER_LEVEL3:
6635
            return "X448_KYBER_LEVEL3";
6636
        #endif
6637
    #endif
6638
    #ifndef WOLFSSL_NO_KYBER1024
6639
        case WOLFSSL_KYBER_LEVEL5:
6640
            return "KYBER_LEVEL5";
6641
        case WOLFSSL_P521_KYBER_LEVEL5:
6642
            return "P521_KYBER_LEVEL5";
6643
    #endif
6644
#endif /* WOLFSSL_MLKEM_KYBER */
6645
0
        }
6646
0
    }
6647
0
#endif /* WOLFSSL_TLS13 && WOLFSSL_HAVE_MLKEM */
6648
6649
0
#ifdef HAVE_FFDHE
6650
0
    if (ssl->namedGroup != 0) {
6651
0
        cName = wolfssl_ffdhe_name(ssl->namedGroup);
6652
0
    }
6653
0
#endif
6654
6655
#ifdef HAVE_CURVE25519
6656
    if (ssl->ecdhCurveOID == ECC_X25519_OID && cName == NULL) {
6657
        cName = "X25519";
6658
    }
6659
#endif
6660
6661
#ifdef HAVE_CURVE448
6662
    if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
6663
        cName = "X448";
6664
    }
6665
#endif
6666
6667
0
#ifdef HAVE_ECC
6668
0
    if (ssl->ecdhCurveOID != 0 && cName == NULL) {
6669
0
        cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
6670
0
                                NULL));
6671
0
    }
6672
0
#endif
6673
6674
0
    return cName;
6675
0
}
6676
#endif
6677
6678
#ifdef OPENSSL_EXTRA
6679
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
6680
/* return authentication NID corresponding to cipher suite
6681
 * @param cipher a pointer to WOLFSSL_CIPHER
6682
 * return NID if found, WC_NID_undef if not found
6683
 */
6684
int wolfSSL_CIPHER_get_auth_nid(const WOLFSSL_CIPHER* cipher)
6685
{
6686
    static const struct authnid {
6687
        const char* alg_name;
6688
        const int  nid;
6689
    } authnid_tbl[] = {
6690
        {"RSA",     WC_NID_auth_rsa},
6691
        {"PSK",     WC_NID_auth_psk},
6692
        {"SRP",     WC_NID_auth_srp},
6693
        {"ECDSA",   WC_NID_auth_ecdsa},
6694
        {"None",    WC_NID_auth_null},
6695
        {NULL,      WC_NID_undef}
6696
    };
6697
6698
    const char* authStr;
6699
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
6700
6701
    if (GetCipherSegment(cipher, n) == NULL) {
6702
        WOLFSSL_MSG("no suitable cipher name found");
6703
        return WC_NID_undef;
6704
    }
6705
6706
    /* in TLS 1.3 case, NID will be WC_NID_auth_any */
6707
    if (XSTRCMP(n[0], "TLS13") == 0) {
6708
        return WC_NID_auth_any;
6709
    }
6710
6711
    authStr = GetCipherAuthStr(n);
6712
6713
    if (authStr != NULL) {
6714
        const struct authnid* sa;
6715
        for(sa = authnid_tbl; sa->alg_name != NULL; sa++) {
6716
            if (XSTRCMP(sa->alg_name, authStr) == 0) {
6717
                return sa->nid;
6718
            }
6719
        }
6720
    }
6721
6722
    return WC_NID_undef;
6723
}
6724
/* return cipher NID corresponding to cipher suite
6725
 * @param cipher a pointer to WOLFSSL_CIPHER
6726
 * return NID if found, WC_NID_undef if not found
6727
 */
6728
int wolfSSL_CIPHER_get_cipher_nid(const WOLFSSL_CIPHER* cipher)
6729
{
6730
    static const struct ciphernid {
6731
        const char* alg_name;
6732
        const int  nid;
6733
    } ciphernid_tbl[] = {
6734
        {"AESGCM(256)",             WC_NID_aes_256_gcm},
6735
        {"AESGCM(128)",             WC_NID_aes_128_gcm},
6736
        {"AESCCM(128)",             WC_NID_aes_128_ccm},
6737
        {"AES(128)",                WC_NID_aes_128_cbc},
6738
        {"AES(256)",                WC_NID_aes_256_cbc},
6739
        {"CAMELLIA(256)",           WC_NID_camellia_256_cbc},
6740
        {"CAMELLIA(128)",           WC_NID_camellia_128_cbc},
6741
        {"RC4",                     WC_NID_rc4},
6742
        {"3DES",                    WC_NID_des_ede3_cbc},
6743
        {"CHACHA20/POLY1305(256)",  WC_NID_chacha20_poly1305},
6744
        {"None",                    WC_NID_undef},
6745
        {NULL,                      WC_NID_undef}
6746
    };
6747
6748
    const char* encStr;
6749
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
6750
6751
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_cipher_nid");
6752
6753
    if (GetCipherSegment(cipher, n) == NULL) {
6754
        WOLFSSL_MSG("no suitable cipher name found");
6755
        return WC_NID_undef;
6756
    }
6757
6758
    encStr = GetCipherEncStr(n);
6759
6760
    if (encStr != NULL) {
6761
        const struct ciphernid* c;
6762
        for(c = ciphernid_tbl; c->alg_name != NULL; c++) {
6763
            if (XSTRCMP(c->alg_name, encStr) == 0) {
6764
                return c->nid;
6765
            }
6766
        }
6767
    }
6768
6769
    return WC_NID_undef;
6770
}
6771
/* return digest NID corresponding to cipher suite
6772
 * @param cipher a pointer to WOLFSSL_CIPHER
6773
 * return NID if found, WC_NID_undef if not found
6774
 */
6775
int wolfSSL_CIPHER_get_digest_nid(const WOLFSSL_CIPHER* cipher)
6776
{
6777
    static const struct macnid {
6778
        const char* alg_name;
6779
        const int  nid;
6780
    } macnid_tbl[] = {
6781
        {"SHA1",    WC_NID_sha1},
6782
        {"SHA256",  WC_NID_sha256},
6783
        {"SHA384",  WC_NID_sha384},
6784
        {NULL,      WC_NID_undef}
6785
    };
6786
6787
    const char* name;
6788
    const char* macStr;
6789
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
6790
    (void)name;
6791
6792
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_digest_nid");
6793
6794
    if ((name = GetCipherSegment(cipher, n)) == NULL) {
6795
        WOLFSSL_MSG("no suitable cipher name found");
6796
        return WC_NID_undef;
6797
    }
6798
6799
    /* in MD5 case, NID will be WC_NID_md5 */
6800
    if (XSTRSTR(name, "MD5") != NULL) {
6801
        return WC_NID_md5;
6802
    }
6803
6804
    macStr = GetCipherMacStr(n);
6805
6806
    if (macStr != NULL) {
6807
        const struct macnid* mc;
6808
        for(mc = macnid_tbl; mc->alg_name != NULL; mc++) {
6809
            if (XSTRCMP(mc->alg_name, macStr) == 0) {
6810
                return mc->nid;
6811
            }
6812
        }
6813
    }
6814
6815
    return WC_NID_undef;
6816
}
6817
/* return key exchange NID corresponding to cipher suite
6818
 * @param cipher a pointer to WOLFSSL_CIPHER
6819
 * return NID if found, WC_NID_undef if not found
6820
 */
6821
int wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER* cipher)
6822
{
6823
    static const struct kxnid {
6824
        const char* name;
6825
        const int  nid;
6826
    } kxnid_table[] = {
6827
        {"ECDHEPSK",  WC_NID_kx_ecdhe_psk},
6828
        {"ECDH",      WC_NID_kx_ecdhe},
6829
        {"DHEPSK",    WC_NID_kx_dhe_psk},
6830
        {"DH",        WC_NID_kx_dhe},
6831
        {"RSAPSK",    WC_NID_kx_rsa_psk},
6832
        {"SRP",       WC_NID_kx_srp},
6833
        {"EDH",       WC_NID_kx_dhe},
6834
        {"PSK",       WC_NID_kx_psk},
6835
        {"RSA",       WC_NID_kx_rsa},
6836
        {NULL,        WC_NID_undef}
6837
    };
6838
6839
    const char* keaStr;
6840
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
6841
6842
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_kx_nid");
6843
6844
    if (GetCipherSegment(cipher, n) == NULL) {
6845
        WOLFSSL_MSG("no suitable cipher name found");
6846
        return WC_NID_undef;
6847
    }
6848
6849
    /* in TLS 1.3 case, NID will be WC_NID_kx_any */
6850
    if (XSTRCMP(n[0], "TLS13") == 0) {
6851
        return WC_NID_kx_any;
6852
    }
6853
6854
    keaStr = GetCipherKeaStr(n);
6855
6856
    if (keaStr != NULL) {
6857
        const struct kxnid* k;
6858
        for(k = kxnid_table; k->name != NULL; k++) {
6859
            if (XSTRCMP(k->name, keaStr) == 0) {
6860
                return k->nid;
6861
            }
6862
        }
6863
    }
6864
6865
    return WC_NID_undef;
6866
}
6867
/* check if cipher suite is AEAD
6868
 * @param cipher a pointer to WOLFSSL_CIPHER
6869
 * return 1 if cipher is AEAD, 0 otherwise
6870
 */
6871
int wolfSSL_CIPHER_is_aead(const WOLFSSL_CIPHER* cipher)
6872
{
6873
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
6874
6875
    WOLFSSL_ENTER("wolfSSL_CIPHER_is_aead");
6876
6877
    if (GetCipherSegment(cipher, n) == NULL) {
6878
        WOLFSSL_MSG("no suitable cipher name found");
6879
        return WC_NID_undef;
6880
    }
6881
6882
    return IsCipherAEAD(n);
6883
}
6884
/* Creates cipher->description based on cipher->offset
6885
 * cipher->offset is set in wolfSSL_get_ciphers_compat when it is added
6886
 * to a stack of ciphers.
6887
 * @param [in] cipher: A cipher from a stack of ciphers.
6888
 * return WOLFSSL_SUCCESS if cipher->description is set, else WOLFSSL_FAILURE
6889
 */
6890
int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher)
6891
{
6892
    int strLen;
6893
    unsigned long offset;
6894
    char* dp;
6895
    const char* name;
6896
    const char *keaStr, *authStr, *encStr, *macStr, *protocol;
6897
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
6898
    int len = MAX_DESCRIPTION_SZ-1;
6899
    const CipherSuiteInfo* cipher_names;
6900
    ProtocolVersion pv;
6901
    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description");
6902
6903
    if (cipher == NULL)
6904
        return WOLFSSL_FAILURE;
6905
6906
    dp = cipher->description;
6907
    if (dp == NULL)
6908
        return WOLFSSL_FAILURE;
6909
6910
    cipher_names = GetCipherNames();
6911
6912
    offset = cipher->offset;
6913
    if (offset >= (unsigned long)GetCipherNamesSize())
6914
        return WOLFSSL_FAILURE;
6915
    pv.major = cipher_names[offset].major;
6916
    pv.minor = cipher_names[offset].minor;
6917
    protocol = wolfSSL_internal_get_version(&pv);
6918
6919
    if ((name = GetCipherSegment(cipher, n)) == NULL) {
6920
        WOLFSSL_MSG("no suitable cipher name found");
6921
        return WOLFSSL_FAILURE;
6922
    }
6923
6924
    /* keaStr */
6925
    keaStr = GetCipherKeaStr(n);
6926
    /* authStr */
6927
    authStr = GetCipherAuthStr(n);
6928
    /* encStr */
6929
    encStr = GetCipherEncStr(n);
6930
    if ((cipher->bits = SetCipherBits(encStr)) ==
6931
        WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
6932
    {
6933
       WOLFSSL_MSG("Cipher Bits Not Set.");
6934
    }
6935
    /* macStr */
6936
    macStr = GetCipherMacStr(n);
6937
6938
6939
    /* Build up the string by copying onto the end. */
6940
    XSTRNCPY(dp, name, (size_t)len);
6941
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6942
    len -= strLen; dp += strLen;
6943
6944
    XSTRNCPY(dp, " ", (size_t)len);
6945
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6946
    len -= strLen; dp += strLen;
6947
    XSTRNCPY(dp, protocol, (size_t)len);
6948
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6949
    len -= strLen; dp += strLen;
6950
6951
    XSTRNCPY(dp, " Kx=", (size_t)len);
6952
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6953
    len -= strLen; dp += strLen;
6954
    XSTRNCPY(dp, keaStr, (size_t)len);
6955
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6956
    len -= strLen; dp += strLen;
6957
6958
    XSTRNCPY(dp, " Au=", (size_t)len);
6959
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6960
    len -= strLen; dp += strLen;
6961
    XSTRNCPY(dp, authStr, (size_t)len);
6962
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6963
    len -= strLen; dp += strLen;
6964
6965
    XSTRNCPY(dp, " Enc=", (size_t)len);
6966
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6967
    len -= strLen; dp += strLen;
6968
    XSTRNCPY(dp, encStr, (size_t)len);
6969
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6970
    len -= strLen; dp += strLen;
6971
6972
    XSTRNCPY(dp, " Mac=", (size_t)len);
6973
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
6974
    len -= strLen; dp += (size_t)strLen;
6975
    XSTRNCPY(dp, macStr, (size_t)len);
6976
    dp[len-1] = '\0';
6977
6978
    return WOLFSSL_SUCCESS;
6979
}
6980
#endif /* OPENSSL_ALL || WOLFSSL_QT */
6981
6982
static WC_INLINE const char* wolfssl_kea_to_string(int kea)
6983
{
6984
    const char* keaStr;
6985
6986
    switch (kea) {
6987
        case no_kea:
6988
            keaStr = "None";
6989
            break;
6990
#ifndef NO_RSA
6991
        case rsa_kea:
6992
            keaStr = "RSA";
6993
            break;
6994
#endif
6995
#ifndef NO_DH
6996
        case diffie_hellman_kea:
6997
            keaStr = "DHE";
6998
            break;
6999
#endif
7000
        case fortezza_kea:
7001
            keaStr = "FZ";
7002
            break;
7003
#ifndef NO_PSK
7004
        case psk_kea:
7005
            keaStr = "PSK";
7006
            break;
7007
    #ifndef NO_DH
7008
        case dhe_psk_kea:
7009
            keaStr = "DHEPSK";
7010
            break;
7011
    #endif
7012
    #ifdef HAVE_ECC
7013
        case ecdhe_psk_kea:
7014
            keaStr = "ECDHEPSK";
7015
            break;
7016
    #endif
7017
#endif
7018
#ifdef HAVE_ECC
7019
        case ecc_diffie_hellman_kea:
7020
            keaStr = "ECDHE";
7021
            break;
7022
        case ecc_static_diffie_hellman_kea:
7023
            keaStr = "ECDH";
7024
            break;
7025
#endif
7026
        case any_kea:
7027
            keaStr = "any";
7028
            break;
7029
        default:
7030
            keaStr = "unknown";
7031
            break;
7032
    }
7033
7034
    return keaStr;
7035
}
7036
7037
static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo)
7038
{
7039
    const char* authStr;
7040
7041
    switch (sig_algo) {
7042
        case anonymous_sa_algo:
7043
            authStr = "None";
7044
            break;
7045
#ifndef NO_RSA
7046
        case rsa_sa_algo:
7047
            authStr = "RSA";
7048
            break;
7049
    #ifdef WC_RSA_PSS
7050
        case rsa_pss_sa_algo:
7051
            authStr = "RSA-PSS";
7052
            break;
7053
    #endif
7054
#endif
7055
#ifndef NO_DSA
7056
        case dsa_sa_algo:
7057
            authStr = "DSA";
7058
            break;
7059
#endif
7060
#ifdef HAVE_ECC
7061
        case ecc_dsa_sa_algo:
7062
            authStr = "ECDSA";
7063
            break;
7064
#endif
7065
#ifdef WOLFSSL_SM2
7066
        case sm2_sa_algo:
7067
            authStr = "SM2";
7068
            break;
7069
#endif
7070
#ifdef HAVE_ED25519
7071
        case ed25519_sa_algo:
7072
            authStr = "Ed25519";
7073
            break;
7074
#endif
7075
#ifdef HAVE_ED448
7076
        case ed448_sa_algo:
7077
            authStr = "Ed448";
7078
            break;
7079
#endif
7080
        case any_sa_algo:
7081
            authStr = "any";
7082
            break;
7083
        default:
7084
            authStr = "unknown";
7085
            break;
7086
    }
7087
7088
    return authStr;
7089
}
7090
7091
static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size)
7092
{
7093
    const char* encStr;
7094
7095
    (void)key_size;
7096
7097
    switch (cipher) {
7098
        case wolfssl_cipher_null:
7099
            encStr = "None";
7100
            break;
7101
#ifndef NO_RC4
7102
        case wolfssl_rc4:
7103
            encStr = "RC4(128)";
7104
            break;
7105
#endif
7106
#ifndef NO_DES3
7107
        case wolfssl_triple_des:
7108
            encStr = "3DES(168)";
7109
            break;
7110
#endif
7111
#ifndef NO_AES
7112
        case wolfssl_aes:
7113
            if (key_size == AES_128_KEY_SIZE)
7114
                encStr = "AES(128)";
7115
            else if (key_size == AES_256_KEY_SIZE)
7116
                encStr = "AES(256)";
7117
            else
7118
                encStr = "AES(?)";
7119
            break;
7120
    #ifdef HAVE_AESGCM
7121
        case wolfssl_aes_gcm:
7122
            if (key_size == AES_128_KEY_SIZE)
7123
                encStr = "AESGCM(128)";
7124
            else if (key_size == AES_256_KEY_SIZE)
7125
                encStr = "AESGCM(256)";
7126
            else
7127
                encStr = "AESGCM(?)";
7128
            break;
7129
    #endif
7130
    #ifdef HAVE_AESCCM
7131
        case wolfssl_aes_ccm:
7132
            if (key_size == AES_128_KEY_SIZE)
7133
                encStr = "AESCCM(128)";
7134
            else if (key_size == AES_256_KEY_SIZE)
7135
                encStr = "AESCCM(256)";
7136
            else
7137
                encStr = "AESCCM(?)";
7138
            break;
7139
    #endif
7140
#endif
7141
#ifdef HAVE_CHACHA
7142
        case wolfssl_chacha:
7143
            encStr = "CHACHA20/POLY1305(256)";
7144
            break;
7145
#endif
7146
#ifdef HAVE_ARIA
7147
        case wolfssl_aria_gcm:
7148
            if (key_size == ARIA_128_KEY_SIZE)
7149
                encStr = "Aria(128)";
7150
            else if (key_size == ARIA_192_KEY_SIZE)
7151
                encStr = "Aria(192)";
7152
            else if (key_size == ARIA_256_KEY_SIZE)
7153
                encStr = "Aria(256)";
7154
            else
7155
                encStr = "Aria(?)";
7156
            break;
7157
#endif
7158
#ifdef HAVE_CAMELLIA
7159
        case wolfssl_camellia:
7160
            if (key_size == CAMELLIA_128_KEY_SIZE)
7161
                encStr = "Camellia(128)";
7162
            else if (key_size == CAMELLIA_256_KEY_SIZE)
7163
                encStr = "Camellia(256)";
7164
            else
7165
                encStr = "Camellia(?)";
7166
            break;
7167
#endif
7168
        default:
7169
            encStr = "unknown";
7170
            break;
7171
    }
7172
7173
    return encStr;
7174
}
7175
7176
static WC_INLINE const char* wolfssl_mac_to_string(int mac)
7177
{
7178
    const char* macStr;
7179
7180
    switch (mac) {
7181
        case no_mac:
7182
            macStr = "None";
7183
            break;
7184
#ifndef NO_MD5
7185
        case md5_mac:
7186
            macStr = "MD5";
7187
            break;
7188
#endif
7189
#ifndef NO_SHA
7190
        case sha_mac:
7191
            macStr = "SHA1";
7192
            break;
7193
#endif
7194
#ifdef WOLFSSL_SHA224
7195
        case sha224_mac:
7196
            macStr = "SHA224";
7197
            break;
7198
#endif
7199
#ifndef NO_SHA256
7200
        case sha256_mac:
7201
            macStr = "SHA256";
7202
            break;
7203
#endif
7204
#ifdef WOLFSSL_SHA384
7205
        case sha384_mac:
7206
            macStr = "SHA384";
7207
            break;
7208
#endif
7209
#ifdef WOLFSSL_SHA512
7210
        case sha512_mac:
7211
            macStr = "SHA512";
7212
            break;
7213
#endif
7214
        default:
7215
            macStr = "unknown";
7216
            break;
7217
    }
7218
7219
    return macStr;
7220
}
7221
7222
char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
7223
                                 int len)
7224
{
7225
    char *ret = in;
7226
    const char *keaStr, *authStr, *encStr, *macStr;
7227
    size_t strLen;
7228
    WOLFSSL_ENTER("wolfSSL_CIPHER_description");
7229
7230
    if (cipher == NULL || in == NULL)
7231
        return NULL;
7232
7233
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
7234
    /* if cipher is in the stack from wolfSSL_get_ciphers_compat then
7235
     * Return the description based on cipher_names[cipher->offset]
7236
     */
7237
    if (cipher->in_stack == TRUE) {
7238
        wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher);
7239
        XSTRNCPY(in,cipher->description,(size_t)len);
7240
        return ret;
7241
    }
7242
#endif
7243
7244
    /* Get the cipher description based on the SSL session cipher */
7245
    keaStr = wolfssl_kea_to_string(cipher->ssl->specs.kea);
7246
    authStr = wolfssl_sigalg_to_string(cipher->ssl->specs.sig_algo);
7247
    encStr = wolfssl_cipher_to_string(cipher->ssl->specs.bulk_cipher_algorithm,
7248
                                      cipher->ssl->specs.key_size);
7249
    if (cipher->ssl->specs.cipher_type == aead)
7250
        macStr = "AEAD";
7251
    else
7252
        macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm);
7253
7254
    /* Build up the string by copying onto the end. */
7255
    XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), (size_t)len);
7256
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7257
7258
    XSTRNCPY(in, " ", (size_t)len);
7259
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7260
    XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), (size_t)len);
7261
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7262
7263
    XSTRNCPY(in, " Kx=", (size_t)len);
7264
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7265
    XSTRNCPY(in, keaStr, (size_t)len);
7266
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7267
7268
    XSTRNCPY(in, " Au=", (size_t)len);
7269
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7270
    XSTRNCPY(in, authStr, (size_t)len);
7271
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7272
7273
    XSTRNCPY(in, " Enc=", (size_t)len);
7274
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7275
    XSTRNCPY(in, encStr, (size_t)len);
7276
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7277
7278
    XSTRNCPY(in, " Mac=", (size_t)len);
7279
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
7280
    XSTRNCPY(in, macStr, (size_t)len);
7281
    in[len-1] = '\0';
7282
7283
    return ret;
7284
}
7285
7286
#ifndef NO_WOLFSSL_STUB
7287
WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
7288
{
7289
    WOLFSSL_STUB("COMP_zlib");
7290
    return 0;
7291
}
7292
7293
WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
7294
{
7295
    WOLFSSL_STUB("COMP_rle");
7296
    return 0;
7297
}
7298
7299
int wolfSSL_COMP_add_compression_method(int method, void* data)
7300
{
7301
    (void)method;
7302
    (void)data;
7303
    WOLFSSL_STUB("COMP_add_compression_method");
7304
    return 0;
7305
}
7306
7307
const WOLFSSL_COMP_METHOD* wolfSSL_get_current_compression(const WOLFSSL *ssl) {
7308
    (void)ssl;
7309
    return NULL;
7310
}
7311
7312
const WOLFSSL_COMP_METHOD* wolfSSL_get_current_expansion(const WOLFSSL *ssl) {
7313
    (void)ssl;
7314
    return NULL;
7315
}
7316
7317
const char* wolfSSL_COMP_get_name(const WOLFSSL_COMP_METHOD *comp)
7318
{
7319
    static const char ret[] = "not supported";
7320
7321
    (void)comp;
7322
    WOLFSSL_STUB("wolfSSL_COMP_get_name");
7323
    return ret;
7324
}
7325
#endif
7326
7327
/*  wolfSSL_set_dynlock_create_callback
7328
 *  CRYPTO_set_dynlock_create_callback has been deprecated since openSSL 1.0.1.
7329
 *  This function exists for compatibility purposes because wolfSSL satisfies
7330
 *  thread safety without relying on the callback.
7331
 */
7332
void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
7333
                                                          const char*, int))
7334
{
7335
    WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
7336
    (void)f;
7337
}
7338
/*  wolfSSL_set_dynlock_lock_callback
7339
 *  CRYPTO_set_dynlock_lock_callback has been deprecated since openSSL 1.0.1.
7340
 *  This function exists for compatibility purposes because wolfSSL satisfies
7341
 *  thread safety without relying on the callback.
7342
 */
7343
void wolfSSL_set_dynlock_lock_callback(
7344
             void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
7345
{
7346
    WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
7347
    (void)f;
7348
}
7349
/*  wolfSSL_set_dynlock_destroy_callback
7350
 *  CRYPTO_set_dynlock_destroy_callback has been deprecated since openSSL 1.0.1.
7351
 *  This function exists for compatibility purposes because wolfSSL satisfies
7352
 *  thread safety without relying on the callback.
7353
 */
7354
void wolfSSL_set_dynlock_destroy_callback(
7355
                  void (*f)(WOLFSSL_dynlock_value*, const char*, int))
7356
{
7357
    WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
7358
    (void)f;
7359
}
7360
7361
/* Sets the DNS hostname to name.
7362
 * Hostname is cleared if name is NULL or empty. */
7363
int wolfSSL_set1_host(WOLFSSL * ssl, const char* name)
7364
{
7365
    if (ssl == NULL) {
7366
        return WOLFSSL_FAILURE;
7367
    }
7368
7369
    return wolfSSL_X509_VERIFY_PARAM_set1_host(ssl->param, name, 0);
7370
}
7371
7372
/******************************************************************************
7373
* wolfSSL_CTX_set1_param - set a pointer to the SSL verification parameters
7374
*
7375
* RETURNS:
7376
*   WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
7377
*   Note: Returns WOLFSSL_SUCCESS, in case either parameter is NULL,
7378
*   same as openssl.
7379
*/
7380
int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm)
7381
{
7382
    if (ctx == NULL || vpm == NULL)
7383
        return WOLFSSL_SUCCESS;
7384
7385
    return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, vpm);
7386
}
7387
7388
/******************************************************************************
7389
* wolfSSL_CTX/_get0_param - return a pointer to the SSL verification parameters
7390
*
7391
* RETURNS:
7392
* returns pointer to the SSL verification parameters on success,
7393
* otherwise returns NULL
7394
*/
7395
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx)
7396
{
7397
    if (ctx == NULL) {
7398
        return NULL;
7399
    }
7400
7401
    return ctx->param;
7402
}
7403
7404
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl)
7405
{
7406
    if (ssl == NULL) {
7407
        return NULL;
7408
    }
7409
    return ssl->param;
7410
}
7411
7412
#endif /* OPENSSL_EXTRA */
7413
7414
7415
#ifdef OPENSSL_EXTRA
7416
/* Sets a function callback that will send information about the state of all
7417
 * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
7418
 * in.
7419
 *
7420
 * ctx WOLFSSL_CTX structure to set callback function in
7421
 * f   callback function to use
7422
 */
7423
void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
7424
       void (*f)(const WOLFSSL* ssl, int type, int val))
7425
{
7426
    WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
7427
    if (ctx == NULL) {
7428
        WOLFSSL_MSG("Bad function argument");
7429
    }
7430
    else {
7431
        ctx->CBIS = f;
7432
    }
7433
}
7434
7435
void wolfSSL_set_info_callback(WOLFSSL* ssl,
7436
       void (*f)(const WOLFSSL* ssl, int type, int val))
7437
{
7438
    WOLFSSL_ENTER("wolfSSL_set_info_callback");
7439
    if (ssl == NULL) {
7440
        WOLFSSL_MSG("Bad function argument");
7441
    }
7442
    else {
7443
        ssl->CBIS = f;
7444
    }
7445
}
7446
7447
7448
7449
#ifndef NO_TLS
7450
/* The info callback (DoAlert/SendAlert) passes alerts packed as
7451
 * (level << 8) | code. Unpack for the string lookups; a raw level or code
7452
 * (high byte zero) passes through unchanged. */
7453
static int unpackAlertCode(int alertID)
7454
{
7455
    if ((alertID >> 8) != 0)
7456
        alertID = alertID & 0xff;
7457
7458
    return alertID;
7459
}
7460
7461
static int unpackAlertLevel(int alertID)
7462
{
7463
    if ((alertID >> 8) != 0)
7464
        alertID = (alertID >> 8) & 0xff;
7465
7466
    return alertID;
7467
}
7468
7469
/* returns a string that describes the alert
7470
 *
7471
 * alertID the alert value to look up
7472
 */
7473
const char* wolfSSL_alert_type_string_long(int alertID)
7474
{
7475
    WOLFSSL_ENTER("wolfSSL_alert_type_string_long");
7476
7477
    return AlertTypeToString(unpackAlertCode(alertID));
7478
}
7479
7480
const char* wolfSSL_alert_type_string(int alertID)
7481
{
7482
    WOLFSSL_ENTER("wolfSSL_alert_type_string");
7483
7484
    switch (unpackAlertLevel(alertID)) {
7485
        case alert_warning:
7486
            return "W";
7487
        case alert_fatal:
7488
            return "F";
7489
        default:
7490
            return "U";
7491
    }
7492
}
7493
7494
const char* wolfSSL_alert_desc_string_long(int alertID)
7495
{
7496
    WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
7497
7498
    return AlertTypeToString(unpackAlertCode(alertID));
7499
}
7500
7501
const char* wolfSSL_alert_desc_string(int alertID)
7502
{
7503
    WOLFSSL_ENTER("wolfSSL_alert_desc_string");
7504
7505
    switch (unpackAlertCode(alertID)) {
7506
        case close_notify:
7507
            return "CN";
7508
        case unexpected_message:
7509
            return "UM";
7510
        case bad_record_mac:
7511
            return "BM";
7512
        case record_overflow:
7513
            return "RO";
7514
        case decompression_failure:
7515
            return "DF";
7516
        case handshake_failure:
7517
            return "HF";
7518
        case no_certificate:
7519
            return "NC";
7520
        case bad_certificate:
7521
            return "BC";
7522
        case unsupported_certificate:
7523
            return "UC";
7524
        case certificate_revoked:
7525
            return "CR";
7526
        case certificate_expired:
7527
            return "CE";
7528
        case certificate_unknown:
7529
            return "CU";
7530
        case illegal_parameter:
7531
            return "IP";
7532
        case unknown_ca:
7533
            return "CA";
7534
        case access_denied:
7535
            return "AD";
7536
        case decode_error:
7537
            return "DE";
7538
        case decrypt_error:
7539
            return "DC";
7540
        case wolfssl_alert_protocol_version:
7541
            return "PV";
7542
        case insufficient_security:
7543
            return "IS";
7544
        case internal_error:
7545
            return "IE";
7546
        case inappropriate_fallback:
7547
            return "IF";
7548
        case user_canceled:
7549
            return "US";
7550
        case no_renegotiation:
7551
            return "NR";
7552
        case missing_extension:
7553
            return "ME";
7554
        case unsupported_extension:
7555
            return "UE";
7556
        case unrecognized_name:
7557
            return "UN";
7558
        case bad_certificate_status_response:
7559
            return "BR";
7560
        case unknown_psk_identity:
7561
            return "UP";
7562
        case certificate_required:
7563
            return "CQ";
7564
        case no_application_protocol:
7565
            return "AP";
7566
        default:
7567
            return "UK";
7568
    }
7569
}
7570
#endif /* !NO_TLS */
7571
7572
7573
#endif /* OPENSSL_EXTRA */
7574
7575
static long wolf_set_options(long old_op, long op)
7576
0
{
7577
    /* if SSL_OP_ALL then turn all bug workarounds on */
7578
0
    if ((op & WOLFSSL_OP_ALL) == WOLFSSL_OP_ALL) {
7579
0
        WOLFSSL_MSG("\tSSL_OP_ALL");
7580
0
    }
7581
7582
    /* by default cookie exchange is on with DTLS */
7583
0
    if ((op & WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE) {
7584
0
        WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
7585
0
    }
7586
7587
0
    if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
7588
0
        WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
7589
0
    }
7590
7591
#ifdef SSL_OP_NO_TLSv1_3
7592
    if ((op & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
7593
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
7594
    }
7595
#endif
7596
7597
0
    if ((op & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
7598
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
7599
0
    }
7600
7601
0
    if ((op & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
7602
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
7603
0
    }
7604
7605
0
    if ((op & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
7606
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
7607
0
    }
7608
7609
0
    if ((op & WOLFSSL_OP_NO_SSLv3) == WOLFSSL_OP_NO_SSLv3) {
7610
0
        WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
7611
0
    }
7612
7613
0
    if ((op & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) ==
7614
0
            WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
7615
0
        WOLFSSL_MSG("\tWOLFSSL_OP_CIPHER_SERVER_PREFERENCE");
7616
0
    }
7617
7618
0
    if ((op & WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION) {
7619
    #ifdef HAVE_LIBZ
7620
        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
7621
    #else
7622
0
        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
7623
0
    #endif
7624
0
    }
7625
7626
0
    return old_op | op;
7627
0
}
7628
7629
static int FindHashSig(const Suites* suites, byte first, byte second)
7630
0
{
7631
0
    word16 i;
7632
7633
0
    if (suites == NULL || suites->hashSigAlgoSz == 0) {
7634
0
        WOLFSSL_MSG("Suites pointer error or suiteSz 0");
7635
0
        return SUITES_ERROR;
7636
0
    }
7637
7638
0
    for (i = 0; i < suites->hashSigAlgoSz-1; i += 2) {
7639
0
        if (suites->hashSigAlgo[i]   == first &&
7640
0
            suites->hashSigAlgo[i+1] == second )
7641
0
            return i;
7642
0
    }
7643
7644
0
    return MATCH_SUITE_ERROR;
7645
0
}
7646
7647
long wolfSSL_set_options(WOLFSSL* ssl, long op)
7648
0
{
7649
0
    word16 haveRSA = 1;
7650
0
    word16 havePSK = 0;
7651
0
    int    keySz   = 0;
7652
7653
0
    WOLFSSL_ENTER("wolfSSL_set_options");
7654
7655
0
    if (ssl == NULL) {
7656
0
        return 0;
7657
0
    }
7658
7659
0
    ssl->options.mask = (unsigned long)wolf_set_options((long)ssl->options.mask, op);
7660
7661
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
7662
0
        WOLFSSL_MSG("Disabling TLS 1.3");
7663
0
        if (ssl->version.minor == TLSv1_3_MINOR)
7664
0
            ssl->version.minor = TLSv1_2_MINOR;
7665
0
    }
7666
7667
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
7668
0
        WOLFSSL_MSG("Disabling TLS 1.2");
7669
0
        if (ssl->version.minor == TLSv1_2_MINOR)
7670
0
            ssl->version.minor = TLSv1_1_MINOR;
7671
0
    }
7672
7673
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
7674
0
        WOLFSSL_MSG("Disabling TLS 1.1");
7675
0
        if (ssl->version.minor == TLSv1_1_MINOR)
7676
0
            ssl->version.minor = TLSv1_MINOR;
7677
0
    }
7678
7679
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
7680
0
        WOLFSSL_MSG("Disabling TLS 1.0");
7681
0
        if (ssl->version.minor == TLSv1_MINOR)
7682
0
            ssl->version.minor = SSLv3_MINOR;
7683
0
    }
7684
7685
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_COMPRESSION)
7686
0
        == WOLFSSL_OP_NO_COMPRESSION) {
7687
    #ifdef HAVE_LIBZ
7688
        ssl->options.usingCompression = 0;
7689
    #endif
7690
0
    }
7691
7692
#if defined(HAVE_SESSION_TICKET) && (defined(OPENSSL_EXTRA) \
7693
        || defined(HAVE_WEBSERVER) || defined(WOLFSSL_WPAS_SMALL))
7694
    if ((ssl->options.mask & WOLFSSL_OP_NO_TICKET) == WOLFSSL_OP_NO_TICKET) {
7695
      ssl->options.noTicketTls12 = 1;
7696
    }
7697
#endif
7698
7699
7700
    /* in the case of a version change the cipher suites should be reset */
7701
#ifndef NO_PSK
7702
    havePSK = ssl->options.havePSK;
7703
#endif
7704
#ifdef NO_RSA
7705
    haveRSA = 0;
7706
#endif
7707
0
#ifndef NO_CERTS
7708
0
    keySz = ssl->buffers.keySz;
7709
0
#endif
7710
7711
0
    if (ssl->options.side != WOLFSSL_NEITHER_END) {
7712
0
        if (AllocateSuites(ssl) != 0)
7713
0
            return 0;
7714
0
        if (!ssl->suites->setSuites) {
7715
            /* Client side won't set DH params, so it needs haveDH set to TRUE. */
7716
0
            if (ssl->options.side == WOLFSSL_CLIENT_END)
7717
0
                InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
7718
0
                       havePSK, TRUE, ssl->options.haveECDSAsig,
7719
0
                       ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
7720
0
                       ssl->options.useAnon,
7721
0
                       TRUE, TRUE, TRUE, TRUE, ssl->options.side);
7722
0
            else
7723
0
                InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
7724
0
                       havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig,
7725
0
                       ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
7726
0
                       ssl->options.useAnon,
7727
0
                       TRUE, TRUE, TRUE, TRUE, ssl->options.side);
7728
0
        }
7729
0
        else {
7730
            /* Only preserve overlapping suites */
7731
0
            Suites tmpSuites;
7732
0
            word16 in, out;
7733
0
            word16 haveECDSAsig, haveStaticECC;
7734
#ifdef NO_RSA
7735
            haveECDSAsig = 1;
7736
            haveStaticECC = 1;
7737
#else
7738
0
            haveECDSAsig = 0;
7739
0
            haveStaticECC = ssl->options.haveStaticECC;
7740
0
#endif
7741
0
            XMEMSET(&tmpSuites, 0, sizeof(Suites));
7742
            /* Get all possible ciphers and sigalgs for the version. Following
7743
             * options limit the allowed ciphers so let's try to get as many as
7744
             * possible.
7745
             * - haveStaticECC turns off haveRSA
7746
             * - haveECDSAsig turns off haveRSAsig
7747
             * - SUITES_NULL_EXPLICIT includes the integrity-only suites, so
7748
             *   an explicitly configured one is preserved */
7749
0
            InitSuites(&tmpSuites, ssl->version, 0, 1, 1, 1, haveECDSAsig, 1, 1,
7750
0
                    haveStaticECC, 1, SUITES_NULL_EXPLICIT, 1, 1, 1,
7751
0
                    ssl->options.side);
7752
0
            for (in = 0, out = 0; in < ssl->suites->suiteSz; in += SUITE_LEN) {
7753
0
                if (FindSuite(&tmpSuites, ssl->suites->suites[in],
7754
0
                        ssl->suites->suites[in+1]) >= 0) {
7755
0
                    ssl->suites->suites[out] = ssl->suites->suites[in];
7756
0
                    ssl->suites->suites[out+1] = ssl->suites->suites[in+1];
7757
0
                    out += SUITE_LEN;
7758
0
                }
7759
0
            }
7760
0
            ssl->suites->suiteSz = out;
7761
0
            for (in = 0, out = 0; in < ssl->suites->hashSigAlgoSz; in += 2) {
7762
0
                if (FindHashSig(&tmpSuites, ssl->suites->hashSigAlgo[in],
7763
0
                    ssl->suites->hashSigAlgo[in+1]) >= 0) {
7764
0
                    ssl->suites->hashSigAlgo[out] =
7765
0
                            ssl->suites->hashSigAlgo[in];
7766
0
                    ssl->suites->hashSigAlgo[out+1] =
7767
0
                            ssl->suites->hashSigAlgo[in+1];
7768
0
                    out += 2;
7769
0
                }
7770
0
            }
7771
0
            ssl->suites->hashSigAlgoSz = out;
7772
0
        }
7773
0
    }
7774
7775
0
    return (long)ssl->options.mask;
7776
0
}
7777
7778
7779
long wolfSSL_get_options(const WOLFSSL* ssl)
7780
0
{
7781
0
    WOLFSSL_ENTER("wolfSSL_get_options");
7782
0
    if(ssl == NULL)
7783
0
        return WOLFSSL_FAILURE;
7784
0
    return (long)ssl->options.mask;
7785
0
}
7786
7787
#if defined(HAVE_SECURE_RENEGOTIATION) \
7788
        || defined(HAVE_SERVER_RENEGOTIATION_INFO)
7789
/* clears the counter for number of renegotiations done
7790
 * returns the current count before it is cleared */
7791
long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
7792
0
{
7793
0
    long total;
7794
7795
0
    WOLFSSL_ENTER("wolfSSL_clear_num_renegotiations");
7796
0
    if (s == NULL)
7797
0
        return 0;
7798
7799
0
    total = s->secure_rene_count;
7800
0
    s->secure_rene_count = 0;
7801
0
    return total;
7802
0
}
7803
7804
7805
/* return the number of renegotiations since wolfSSL_new */
7806
long wolfSSL_total_renegotiations(WOLFSSL *s)
7807
0
{
7808
0
    WOLFSSL_ENTER("wolfSSL_total_renegotiations");
7809
0
    return wolfSSL_num_renegotiations(s);
7810
0
}
7811
7812
7813
/* return the number of renegotiations since wolfSSL_new */
7814
long wolfSSL_num_renegotiations(WOLFSSL* s)
7815
0
{
7816
0
    if (s == NULL) {
7817
0
        return 0;
7818
0
    }
7819
7820
0
    return s->secure_rene_count;
7821
0
}
7822
7823
7824
/* Is there a renegotiation currently in progress? */
7825
int  wolfSSL_SSL_renegotiate_pending(WOLFSSL *s)
7826
0
{
7827
0
    return s && s->options.handShakeDone &&
7828
0
            s->options.handShakeState != HANDSHAKE_DONE ? 1 : 0;
7829
0
}
7830
#endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
7831
7832
#ifdef OPENSSL_EXTRA
7833
7834
long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
7835
{
7836
    WOLFSSL_ENTER("wolfSSL_clear_options");
7837
    if(ssl == NULL)
7838
        return WOLFSSL_FAILURE;
7839
    ssl->options.mask &= (unsigned long)~opt;
7840
    return (long)ssl->options.mask;
7841
}
7842
7843
7844
#ifndef NO_WOLFSSL_STUB
7845
/*** TBD ***/
7846
void WOLFSSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx,
7847
    WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
7848
{
7849
    (void)ctx;
7850
    (void)dh;
7851
    WOLFSSL_STUB("WOLFSSL_CTX_set_tmp_dh_callback");
7852
}
7853
#endif
7854
7855
#ifndef NO_WOLFSSL_STUB
7856
/*** TBD ***/
7857
WOLF_STACK_OF(WOLFSSL_COMP) *WOLFSSL_COMP_get_compression_methods(void)
7858
{
7859
    WOLFSSL_STUB("WOLFSSL_COMP_get_compression_methods");
7860
    return NULL;
7861
}
7862
#endif
7863
7864
7865
#if !defined(NETOS)
7866
#endif
7867
7868
7869
#endif /* OPENSSL_EXTRA */
7870
7871
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
7872
size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count)
7873
{
7874
    byte len = 0;
7875
    byte const * src;
7876
7877
    WOLFSSL_ENTER("wolfSSL_get_finished");
7878
7879
    if (!ssl || !buf) {
7880
        WOLFSSL_MSG("Bad parameter");
7881
        return WOLFSSL_FAILURE;
7882
    }
7883
7884
    if (ssl->options.side == WOLFSSL_SERVER_END) {
7885
        src = ssl->serverFinished;
7886
        len = ssl->serverFinished_len;
7887
    }
7888
    else {
7889
        src = ssl->clientFinished;
7890
        len = ssl->clientFinished_len;
7891
    }
7892
7893
    if (count < len) {
7894
        WOLFSSL_MSG("Buffer too small");
7895
        return WOLFSSL_FAILURE;
7896
    }
7897
7898
    XMEMCPY(buf, src, len);
7899
7900
    return len;
7901
}
7902
7903
size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count)
7904
{
7905
    byte len = 0;
7906
    byte const * src;
7907
7908
    WOLFSSL_ENTER("wolfSSL_get_peer_finished");
7909
7910
    if (!ssl || !buf) {
7911
        WOLFSSL_MSG("Bad parameter");
7912
        return WOLFSSL_FAILURE;
7913
    }
7914
7915
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
7916
        src = ssl->serverFinished;
7917
        len = ssl->serverFinished_len;
7918
    }
7919
    else {
7920
        src = ssl->clientFinished;
7921
        len = ssl->clientFinished_len;
7922
    }
7923
7924
    if (count < len) {
7925
        WOLFSSL_MSG("Buffer too small");
7926
        return WOLFSSL_FAILURE;
7927
    }
7928
7929
    XMEMCPY(buf, src, len);
7930
7931
    return len;
7932
}
7933
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
7934
7935
7936
#ifdef OPENSSL_EXTRA
7937
7938
#ifndef NO_WOLFSSL_STUB
7939
/* shows the number of accepts attempted by CTX in it's lifetime */
7940
long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
7941
{
7942
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
7943
    (void)ctx;
7944
    return 0;
7945
}
7946
#endif
7947
7948
#ifndef NO_WOLFSSL_STUB
7949
/* shows the number of connects attempted CTX in it's lifetime */
7950
long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
7951
{
7952
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
7953
    (void)ctx;
7954
    return 0;
7955
}
7956
#endif
7957
7958
7959
#ifndef NO_WOLFSSL_STUB
7960
/* shows the number of accepts completed by CTX in it's lifetime */
7961
long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
7962
{
7963
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
7964
    (void)ctx;
7965
    return 0;
7966
}
7967
#endif
7968
7969
7970
#ifndef NO_WOLFSSL_STUB
7971
/* shows the number of connects completed by CTX in it's lifetime */
7972
long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
7973
{
7974
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
7975
    (void)ctx;
7976
    return 0;
7977
}
7978
#endif
7979
7980
7981
#ifndef NO_WOLFSSL_STUB
7982
/* shows the number of renegotiation accepts attempted by CTX */
7983
long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
7984
{
7985
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
7986
    (void)ctx;
7987
    return 0;
7988
}
7989
#endif
7990
7991
7992
#ifndef NO_WOLFSSL_STUB
7993
/* shows the number of renegotiation accepts attempted by CTX */
7994
long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
7995
{
7996
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
7997
    (void)ctx;
7998
    return 0;
7999
}
8000
#endif
8001
8002
8003
#ifndef NO_WOLFSSL_STUB
8004
long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
8005
{
8006
    WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
8007
    (void)ctx;
8008
    return 0;
8009
}
8010
#endif
8011
8012
8013
#ifndef NO_WOLFSSL_STUB
8014
long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
8015
{
8016
    WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
8017
    (void)ctx;
8018
    return 0;
8019
}
8020
#endif
8021
8022
8023
#ifndef NO_WOLFSSL_STUB
8024
long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
8025
{
8026
    WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
8027
    (void)ctx;
8028
    return 0;
8029
}
8030
#endif
8031
8032
8033
#ifndef NO_WOLFSSL_STUB
8034
long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
8035
{
8036
    WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
8037
    (void)ctx;
8038
    return 0;
8039
}
8040
#endif
8041
8042
8043
#ifndef NO_WOLFSSL_STUB
8044
long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
8045
{
8046
    WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
8047
    (void)ctx;
8048
    return 0;
8049
}
8050
#endif
8051
8052
#endif /* OPENSSL_EXTRA */
8053
8054
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_TLS_READ_AHEAD)
8055
int wolfSSL_get_read_ahead(const WOLFSSL* ssl)
8056
{
8057
    if (ssl == NULL) {
8058
        return WOLFSSL_FAILURE;
8059
    }
8060
8061
    return ssl->readAhead;
8062
}
8063
8064
8065
int wolfSSL_set_read_ahead(WOLFSSL* ssl, int v)
8066
{
8067
    if (ssl == NULL) {
8068
        return WOLFSSL_FAILURE;
8069
    }
8070
8071
    ssl->readAhead = (byte)v;
8072
8073
    return WOLFSSL_SUCCESS;
8074
}
8075
8076
8077
int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
8078
{
8079
    if (ctx == NULL) {
8080
        return WOLFSSL_FAILURE;
8081
    }
8082
8083
    return ctx->readAhead;
8084
}
8085
8086
8087
int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
8088
{
8089
    if (ctx == NULL) {
8090
        return WOLFSSL_FAILURE;
8091
    }
8092
8093
    ctx->readAhead = (byte)v;
8094
8095
    return WOLFSSL_SUCCESS;
8096
}
8097
8098
/* Set the read-ahead receive window size. When read-ahead is enabled, a single
8099
 * recv() pulls in up to this many bytes:
8100
 *  - 0 (the default) requests one full record.
8101
 *  - A value larger than one record lets a single recv() coalesce several
8102
 *    back-to-back records.
8103
 *  - A value smaller than one record is honoured as-is, capping the receive
8104
 *    buffer's footprint when the peer's records are known to be small.
8105
 * 'len' is only a speculative window: a record larger than it is still received
8106
 * correctly, with the buffer grown on demand. Effective only when the library
8107
 * is built with read-ahead support (WOLFSSL_TLS_READ_AHEAD). Returns int rather
8108
 * than OpenSSL's void to match wolfSSL's other read-ahead setters; callers that
8109
 * ignore the return remain source-compatible. */
8110
int wolfSSL_CTX_set_default_read_buffer_len(WOLFSSL_CTX* ctx, size_t len)
8111
{
8112
    if (ctx == NULL) {
8113
        return WOLFSSL_FAILURE;
8114
    }
8115
8116
    /* 0 selects the default one-record window (matches OpenSSL, where 0 means
8117
     * "use the built-in default"). Otherwise clamp to a sane maximum so the
8118
     * stored window cannot overflow the signed arithmetic in the receive path
8119
     * (see WOLFSSL_MAX_READ_AHEAD_SZ). */
8120
    if (len == 0) {
8121
        len = WOLFSSL_READ_AHEAD_SZ;
8122
    }
8123
    else if (len > (size_t)WOLFSSL_MAX_READ_AHEAD_SZ) {
8124
        len = (size_t)WOLFSSL_MAX_READ_AHEAD_SZ;
8125
    }
8126
    ctx->readAheadSz = (word32)len;
8127
8128
    return WOLFSSL_SUCCESS;
8129
}
8130
8131
int wolfSSL_set_default_read_buffer_len(WOLFSSL* ssl, size_t len)
8132
{
8133
    if (ssl == NULL) {
8134
        return WOLFSSL_FAILURE;
8135
    }
8136
8137
    /* 0 selects the default one-record window (matches OpenSSL, where 0 means
8138
     * "use the built-in default"). Otherwise clamp to a sane maximum so the
8139
     * stored window cannot overflow the signed arithmetic in the receive path
8140
     * (see WOLFSSL_MAX_READ_AHEAD_SZ). */
8141
    if (len == 0) {
8142
        len = WOLFSSL_READ_AHEAD_SZ;
8143
    }
8144
    else if (len > (size_t)WOLFSSL_MAX_READ_AHEAD_SZ) {
8145
        len = (size_t)WOLFSSL_MAX_READ_AHEAD_SZ;
8146
    }
8147
    ssl->readAheadSz = (word32)len;
8148
8149
    return WOLFSSL_SUCCESS;
8150
}
8151
8152
long wolfSSL_CTX_get_default_read_buffer_len(WOLFSSL_CTX* ctx)
8153
{
8154
    if (ctx == NULL) {
8155
        return WOLFSSL_FAILURE;
8156
    }
8157
8158
    return (long)ctx->readAheadSz;
8159
}
8160
8161
long wolfSSL_get_default_read_buffer_len(const WOLFSSL* ssl)
8162
{
8163
    if (ssl == NULL) {
8164
        return WOLFSSL_FAILURE;
8165
    }
8166
8167
    return (long)ssl->readAheadSz;
8168
}
8169
#endif /* OPENSSL_EXTRA || WOLFSSL_TLS_READ_AHEAD */
8170
8171
#ifdef OPENSSL_EXTRA
8172
long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
8173
        void* arg)
8174
{
8175
    if (ctx == NULL) {
8176
        return WOLFSSL_FAILURE;
8177
    }
8178
8179
    ctx->userPRFArg = arg;
8180
    return WOLFSSL_SUCCESS;
8181
}
8182
8183
#endif /* OPENSSL_EXTRA */
8184
8185
8186
8187
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
8188
/* Free the dynamically allocated data.
8189
 *
8190
 * p  Pointer to dynamically allocated memory.
8191
 */
8192
void wolfSSL_OPENSSL_free(void* p)
8193
{
8194
    WOLFSSL_MSG("wolfSSL_OPENSSL_free");
8195
8196
    XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
8197
}
8198
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
8199
8200
#ifdef OPENSSL_EXTRA
8201
8202
void *wolfSSL_OPENSSL_malloc(size_t a)
8203
{
8204
    return (void *)XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
8205
}
8206
8207
int wolfSSL_OPENSSL_hexchar2int(unsigned char c)
8208
{
8209
    /* 'char' is unsigned on some platforms. */
8210
    return (int)(signed char)HexCharToByte((char)c);
8211
}
8212
8213
unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len)
8214
{
8215
    unsigned char* targetBuf;
8216
    int srcDigitHigh = 0;
8217
    int srcDigitLow = 0;
8218
    size_t srcLen;
8219
    size_t srcIdx = 0;
8220
    long targetIdx = 0;
8221
8222
    srcLen = XSTRLEN(str);
8223
    targetBuf = (unsigned char*)XMALLOC(srcLen / 2, NULL, DYNAMIC_TYPE_OPENSSL);
8224
    if (targetBuf == NULL) {
8225
        return NULL;
8226
    }
8227
8228
    while (srcIdx < srcLen) {
8229
        if (str[srcIdx] == ':') {
8230
            srcIdx++;
8231
            continue;
8232
        }
8233
8234
        srcDigitHigh = wolfSSL_OPENSSL_hexchar2int((unsigned char)str[srcIdx++]);
8235
        srcDigitLow = wolfSSL_OPENSSL_hexchar2int((unsigned char)str[srcIdx++]);
8236
        if (srcDigitHigh < 0 || srcDigitLow < 0) {
8237
            WOLFSSL_MSG("Invalid hex character.");
8238
            XFREE(targetBuf, NULL, DYNAMIC_TYPE_OPENSSL);
8239
            return NULL;
8240
        }
8241
8242
        targetBuf[targetIdx++] = (unsigned char)((srcDigitHigh << 4) |
8243
                                                  srcDigitLow       );
8244
    }
8245
8246
    if (len != NULL)
8247
        *len = targetIdx;
8248
8249
    return targetBuf;
8250
}
8251
8252
int wolfSSL_OPENSSL_init_ssl(word64 opts, const WOLFSSL_INIT_SETTINGS *settings)
8253
{
8254
    (void)opts;
8255
    (void)settings;
8256
    return wolfSSL_library_init();
8257
}
8258
8259
int wolfSSL_OPENSSL_init_crypto(word64 opts,
8260
    const WOLFSSL_INIT_SETTINGS* settings)
8261
{
8262
    (void)opts;
8263
    (void)settings;
8264
    return wolfSSL_library_init();
8265
}
8266
8267
#endif /* OPENSSL_EXTRA */
8268
8269
8270
#ifdef HAVE_FUZZER
8271
void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
8272
{
8273
    if (ssl) {
8274
        ssl->fuzzerCb  = cbf;
8275
        ssl->fuzzerCtx = fCtx;
8276
    }
8277
}
8278
#endif
8279
8280
8281
#ifdef WOLFSSL_HAVE_WOLFSCEP
8282
    /* Used by autoconf to see if wolfSCEP is available */
8283
    void wolfSSL_wolfSCEP(void) {}
8284
#endif
8285
8286
8287
#ifdef WOLFSSL_HAVE_CERT_SERVICE
8288
    /* Used by autoconf to see if cert service is available */
8289
    void wolfSSL_cert_service(void) {}
8290
#endif
8291
8292
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
8293
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
8294
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
8295
    defined(WOLFSSL_HAPROXY)
8296
8297
    void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth)
8298
    {
8299
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
8300
        WOLFSSL_ENTER("wolfSSL_set_verify_depth");
8301
        /* Reject out-of-range depths; valid range is 0 to MAX_CHAIN_DEPTH. */
8302
        if ((ssl == NULL) || (depth < 0) || (depth > MAX_CHAIN_DEPTH)) {
8303
            WOLFSSL_MSG("Bad depth argument, too large or less than 0");
8304
        }
8305
        else {
8306
            ssl->options.verifyDepth = (byte)depth;
8307
        }
8308
    #endif
8309
    }
8310
8311
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
8312
    HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
8313
8314
#ifdef OPENSSL_EXTRA
8315
8316
/* wolfSSL uses negative values for error states. This function returns an
8317
 * unsigned type so the value returned is the absolute value of the error.
8318
 */
8319
8320
#endif /* OPENSSL_EXTRA */
8321
8322
#ifdef HAVE_EX_DATA_CRYPTO
8323
CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session = NULL;
8324
8325
static int crypto_ex_cb_new(CRYPTO_EX_cb_ctx** dst, long ctx_l, void* ctx_ptr,
8326
        WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func,
8327
        WOLFSSL_CRYPTO_EX_free* free_func)
8328
{
8329
    CRYPTO_EX_cb_ctx* new_ctx = (CRYPTO_EX_cb_ctx*)XMALLOC(
8330
            sizeof(CRYPTO_EX_cb_ctx), NULL, DYNAMIC_TYPE_OPENSSL);
8331
    if (new_ctx == NULL)
8332
        return WOLFSSL_FATAL_ERROR;
8333
    new_ctx->ctx_l = ctx_l;
8334
    new_ctx->ctx_ptr = ctx_ptr;
8335
    new_ctx->new_func = new_func;
8336
    new_ctx->free_func = free_func;
8337
    new_ctx->dup_func = dup_func;
8338
    new_ctx->next = NULL;
8339
    /* Push to end of list */
8340
    while (*dst != NULL)
8341
        dst = &(*dst)->next;
8342
    *dst = new_ctx;
8343
    return 0;
8344
}
8345
8346
void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx)
8347
{
8348
    while (cb_ctx != NULL) {
8349
        CRYPTO_EX_cb_ctx* next = cb_ctx->next;
8350
        XFREE(cb_ctx, NULL, DYNAMIC_TYPE_OPENSSL);
8351
        cb_ctx = next;
8352
    }
8353
}
8354
8355
void crypto_ex_cb_setup_new_data(void *new_obj, CRYPTO_EX_cb_ctx* cb_ctx,
8356
        WOLFSSL_CRYPTO_EX_DATA* ex_data)
8357
{
8358
    int idx = 0;
8359
    for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
8360
        if (cb_ctx->new_func != NULL)
8361
            cb_ctx->new_func(new_obj, NULL, ex_data, idx, cb_ctx->ctx_l,
8362
                    cb_ctx->ctx_ptr);
8363
    }
8364
}
8365
8366
int crypto_ex_cb_dup_data(const WOLFSSL_CRYPTO_EX_DATA *in,
8367
        WOLFSSL_CRYPTO_EX_DATA *out, CRYPTO_EX_cb_ctx* cb_ctx)
8368
{
8369
    int idx = 0;
8370
    for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
8371
        if (cb_ctx->dup_func != NULL) {
8372
            void* ptr = wolfSSL_CRYPTO_get_ex_data(in, idx);
8373
            if (!cb_ctx->dup_func(out, in,
8374
                    &ptr, idx,
8375
                    cb_ctx->ctx_l, cb_ctx->ctx_ptr)) {
8376
                return WOLFSSL_FAILURE;
8377
            }
8378
            wolfSSL_CRYPTO_set_ex_data(out, idx, ptr);
8379
        }
8380
    }
8381
    return WOLFSSL_SUCCESS;
8382
}
8383
8384
void crypto_ex_cb_free_data(void *obj, CRYPTO_EX_cb_ctx* cb_ctx,
8385
        WOLFSSL_CRYPTO_EX_DATA* ex_data)
8386
{
8387
    int idx = 0;
8388
    for (; cb_ctx != NULL; idx++, cb_ctx = cb_ctx->next) {
8389
        if (cb_ctx->free_func != NULL)
8390
            cb_ctx->free_func(obj, NULL, ex_data, idx, cb_ctx->ctx_l,
8391
                    cb_ctx->ctx_ptr);
8392
    }
8393
}
8394
8395
/**
8396
 * wolfssl_local_get_ex_new_index is a helper function for the following
8397
 * xx_get_ex_new_index functions:
8398
 *  - wolfSSL_CRYPTO_get_ex_new_index
8399
 *  - wolfSSL_CTX_get_ex_new_index
8400
 *  - wolfSSL_get_ex_new_index
8401
 * Issues a unique index number for the specified class-index.
8402
 * Returns an index number greater or equal to zero on success,
8403
 * -1 on failure.
8404
 */
8405
int wolfssl_local_get_ex_new_index(int class_index, long ctx_l, void* ctx_ptr,
8406
        WOLFSSL_CRYPTO_EX_new* new_func, WOLFSSL_CRYPTO_EX_dup* dup_func,
8407
        WOLFSSL_CRYPTO_EX_free* free_func)
8408
{
8409
    /* index counter for each class index*/
8410
    static int ctx_idx = 0;
8411
    static int ssl_idx = 0;
8412
    static int ssl_session_idx = 0;
8413
    static int x509_idx = 0;
8414
8415
    int idx = -1;
8416
8417
    switch(class_index) {
8418
        case WOLF_CRYPTO_EX_INDEX_SSL:
8419
            WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
8420
                    dup_func, free_func);
8421
            idx = ssl_idx++;
8422
            break;
8423
        case WOLF_CRYPTO_EX_INDEX_SSL_CTX:
8424
            WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
8425
                    dup_func, free_func);
8426
            idx = ctx_idx++;
8427
            break;
8428
        case WOLF_CRYPTO_EX_INDEX_X509:
8429
            WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(ctx_l, ctx_ptr, new_func,
8430
                    dup_func, free_func);
8431
            idx = x509_idx++;
8432
            break;
8433
        case WOLF_CRYPTO_EX_INDEX_SSL_SESSION:
8434
            if (crypto_ex_cb_new(&crypto_ex_cb_ctx_session, ctx_l, ctx_ptr,
8435
                    new_func, dup_func, free_func) != 0)
8436
                return WOLFSSL_FATAL_ERROR;
8437
            idx = ssl_session_idx++;
8438
            break;
8439
        /* following class indexes are not supoprted */
8440
        case WOLF_CRYPTO_EX_INDEX_X509_STORE:
8441
        case WOLF_CRYPTO_EX_INDEX_X509_STORE_CTX:
8442
        case WOLF_CRYPTO_EX_INDEX_DH:
8443
        case WOLF_CRYPTO_EX_INDEX_DSA:
8444
        case WOLF_CRYPTO_EX_INDEX_EC_KEY:
8445
        case WOLF_CRYPTO_EX_INDEX_RSA:
8446
        case WOLF_CRYPTO_EX_INDEX_ENGINE:
8447
        case WOLF_CRYPTO_EX_INDEX_UI:
8448
        case WOLF_CRYPTO_EX_INDEX_BIO:
8449
        case WOLF_CRYPTO_EX_INDEX_APP:
8450
        case WOLF_CRYPTO_EX_INDEX_UI_METHOD:
8451
        case WOLF_CRYPTO_EX_INDEX_DRBG:
8452
        default:
8453
            break;
8454
    }
8455
    if (idx >= MAX_EX_DATA)
8456
        return WOLFSSL_FATAL_ERROR;
8457
    return idx;
8458
}
8459
#endif /* HAVE_EX_DATA_CRYPTO */
8460
8461
#ifdef HAVE_EX_DATA_CRYPTO
8462
int wolfSSL_CTX_get_ex_new_index(long idx, void* arg,
8463
                                 WOLFSSL_CRYPTO_EX_new* new_func,
8464
                                 WOLFSSL_CRYPTO_EX_dup* dup_func,
8465
                                 WOLFSSL_CRYPTO_EX_free* free_func)
8466
{
8467
8468
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
8469
8470
    return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX, idx,
8471
                                    arg, new_func, dup_func, free_func);
8472
}
8473
8474
/* Return the index that can be used for the WOLFSSL structure to store
8475
 * application data.
8476
 *
8477
 */
8478
int wolfSSL_get_ex_new_index(long argValue, void* arg,
8479
        WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
8480
        WOLFSSL_CRYPTO_EX_free* cb3)
8481
{
8482
    WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
8483
8484
    return wolfssl_local_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL, argValue,
8485
            arg, cb1, cb2, cb3);
8486
}
8487
#endif /* HAVE_EX_DATA_CRYPTO */
8488
8489
#ifdef OPENSSL_EXTRA
8490
void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
8491
{
8492
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
8493
#ifdef HAVE_EX_DATA
8494
    if (ctx != NULL) {
8495
        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
8496
    }
8497
#else
8498
    (void)ctx;
8499
    (void)idx;
8500
#endif
8501
    return NULL;
8502
}
8503
8504
int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
8505
{
8506
    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
8507
#ifdef HAVE_EX_DATA
8508
    if (ctx != NULL) {
8509
        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
8510
    }
8511
#else
8512
    (void)ctx;
8513
    (void)idx;
8514
    (void)data;
8515
#endif
8516
    return WOLFSSL_FAILURE;
8517
}
8518
8519
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
8520
int wolfSSL_CTX_set_ex_data_with_cleanup(
8521
    WOLFSSL_CTX* ctx,
8522
    int idx,
8523
    void* data,
8524
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
8525
{
8526
    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data_with_cleanup");
8527
    if (ctx != NULL) {
8528
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx, data,
8529
                                                       cleanup_routine);
8530
    }
8531
    return WOLFSSL_FAILURE;
8532
}
8533
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
8534
#endif /* OPENSSL_EXTRA */
8535
8536
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
8537
8538
/* Returns char* to app data stored in ex[0].
8539
 *
8540
 * ssl WOLFSSL structure to get app data from
8541
 */
8542
void* wolfSSL_get_app_data(const WOLFSSL *ssl)
8543
{
8544
    /* checkout exdata stuff... */
8545
    WOLFSSL_ENTER("wolfSSL_get_app_data");
8546
8547
    return wolfSSL_get_ex_data(ssl, 0);
8548
}
8549
8550
8551
/* Set ex array 0 to have app data
8552
 *
8553
 * ssl WOLFSSL struct to set app data in
8554
 * arg data to be stored
8555
 *
8556
 * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
8557
 */
8558
int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
8559
    WOLFSSL_ENTER("wolfSSL_set_app_data");
8560
8561
    return wolfSSL_set_ex_data(ssl, 0, arg);
8562
}
8563
8564
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
8565
8566
int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
8567
0
{
8568
0
    WOLFSSL_ENTER("wolfSSL_set_ex_data");
8569
#ifdef HAVE_EX_DATA
8570
    if (ssl != NULL) {
8571
        return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data);
8572
    }
8573
#else
8574
0
    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
8575
0
    (void)ssl;
8576
0
    (void)idx;
8577
0
    (void)data;
8578
0
#endif
8579
0
    return WOLFSSL_FAILURE;
8580
0
}
8581
8582
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
8583
int wolfSSL_set_ex_data_with_cleanup(
8584
    WOLFSSL* ssl,
8585
    int idx,
8586
    void* data,
8587
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
8588
{
8589
    WOLFSSL_ENTER("wolfSSL_set_ex_data_with_cleanup");
8590
    if (ssl != NULL)
8591
    {
8592
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ssl->ex_data, idx, data,
8593
                                                       cleanup_routine);
8594
    }
8595
    return WOLFSSL_FAILURE;
8596
}
8597
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
8598
8599
void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
8600
0
{
8601
0
    WOLFSSL_ENTER("wolfSSL_get_ex_data");
8602
#ifdef HAVE_EX_DATA
8603
    if (ssl != NULL) {
8604
        return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx);
8605
    }
8606
#else
8607
0
    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
8608
0
    (void)ssl;
8609
0
    (void)idx;
8610
0
#endif
8611
0
    return 0;
8612
0
}
8613
8614
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
8615
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
8616
8617
#ifdef WOLFSSL_TLS_ST_OK
8618
/* The OpenSSL compat TLS_ST_OK/SSL_ST_OK constants (wolfssl/openssl/ssl.h)
8619
 * duplicate HANDSHAKE_DONE from the internal 'enum states' returned below;
8620
 * fail the build if the enum ever drifts. */
8621
wc_static_assert(WOLFSSL_TLS_ST_OK == HANDSHAKE_DONE);
8622
#endif
8623
8624
/* returns the enum value associated with handshake state
8625
 *
8626
 * ssl the WOLFSSL structure to get state of
8627
 */
8628
int wolfSSL_get_state(const WOLFSSL* ssl)
8629
{
8630
    WOLFSSL_ENTER("wolfSSL_get_state");
8631
8632
    if (ssl == NULL) {
8633
        WOLFSSL_MSG("Null argument passed in");
8634
        return WOLFSSL_FAILURE;
8635
    }
8636
8637
    return ssl->options.handShakeState;
8638
}
8639
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
8640
8641
#ifdef OPENSSL_EXTRA
8642
void wolfSSL_certs_clear(WOLFSSL* ssl)
8643
{
8644
    WOLFSSL_ENTER("wolfSSL_certs_clear");
8645
8646
    if (ssl == NULL)
8647
        return;
8648
8649
    /* ctx still owns certificate, certChain, key, dh, and cm */
8650
    if (ssl->buffers.weOwnCert) {
8651
        FreeDer(&ssl->buffers.certificate);
8652
    #ifdef KEEP_OUR_CERT
8653
        /* ourCert is only made when this SSL owns the certificate. */
8654
        if (ssl->ourCert != NULL) {
8655
            wolfSSL_X509_free(ssl->ourCert);
8656
            ssl->ourCert = NULL;
8657
        }
8658
    #endif
8659
        ssl->buffers.weOwnCert = 0;
8660
    }
8661
    ssl->buffers.certificate = NULL;
8662
    if (ssl->buffers.weOwnCertChain) {
8663
        FreeDer(&ssl->buffers.certChain);
8664
        ssl->buffers.weOwnCertChain = 0;
8665
    }
8666
    ssl->buffers.certChain = NULL;
8667
    ssl->buffers.certChainCnt = 0;
8668
#ifdef KEEP_OUR_CERT
8669
    if (ssl->ourCertChain != NULL) {
8670
        wolfSSL_sk_X509_pop_free(ssl->ourCertChain, NULL);
8671
        ssl->ourCertChain = NULL;
8672
    }
8673
#endif
8674
    if (ssl->buffers.weOwnKey) {
8675
        FreeDer(&ssl->buffers.key);
8676
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
8677
        FreeDer(&ssl->buffers.keyMask);
8678
    #endif
8679
        ssl->buffers.weOwnKey = 0;
8680
    }
8681
    ssl->buffers.key      = NULL;
8682
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
8683
    ssl->buffers.keyMask  = NULL;
8684
#endif
8685
    ssl->buffers.keyType  = 0;
8686
    ssl->buffers.keyId    = 0;
8687
    ssl->buffers.keyLabel = 0;
8688
    ssl->buffers.keySz    = 0;
8689
    ssl->buffers.keyDevId = 0;
8690
#ifdef WOLFSSL_DUAL_ALG_CERTS
8691
    if (ssl->buffers.weOwnAltKey) {
8692
        FreeDer(&ssl->buffers.altKey);
8693
    #ifdef WOLFSSL_BLIND_PRIVATE_KEY
8694
        FreeDer(&ssl->buffers.altKeyMask);
8695
    #endif
8696
        ssl->buffers.weOwnAltKey = 0;
8697
    }
8698
    ssl->buffers.altKey     = NULL;
8699
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
8700
    ssl->buffers.altKeyMask = NULL;
8701
#endif
8702
#endif /* WOLFSSL_DUAL_ALG_CERTS */
8703
}
8704
#endif
8705
8706
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
8707
    || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
8708
8709
long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
8710
{
8711
    WOLFSSL_ENTER("wolfSSL_ctrl");
8712
    if (ssl == NULL)
8713
        return BAD_FUNC_ARG;
8714
8715
    switch (cmd) {
8716
        #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || \
8717
            defined(OPENSSL_ALL)
8718
        #ifdef HAVE_SNI
8719
        case SSL_CTRL_SET_TLSEXT_HOSTNAME:
8720
            WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TLSEXT_HOSTNAME.");
8721
            if (pt == NULL) {
8722
                WOLFSSL_MSG("Passed in NULL Host Name.");
8723
                break;
8724
            }
8725
            return wolfSSL_set_tlsext_host_name(ssl, (const char*) pt);
8726
        #endif /* HAVE_SNI */
8727
        #endif /* WOLFSSL_NGINX || WOLFSSL_QT || OPENSSL_ALL */
8728
        default:
8729
            WOLFSSL_MSG("Case not implemented.");
8730
    }
8731
    (void)opt;
8732
    (void)pt;
8733
    return WOLFSSL_FAILURE;
8734
}
8735
8736
long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
8737
{
8738
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
8739
    long ctrl_opt;
8740
#endif
8741
    long ret = WOLFSSL_SUCCESS;
8742
8743
    WOLFSSL_ENTER("wolfSSL_CTX_ctrl");
8744
    if (ctx == NULL)
8745
        return WOLFSSL_FAILURE;
8746
8747
    switch (cmd) {
8748
    case SSL_CTRL_CHAIN:
8749
#ifdef SESSION_CERTS
8750
    {
8751
        /*
8752
         * We don't care about opt here because a copy of the certificate is
8753
         * stored anyway so increasing the reference counter is not necessary.
8754
         * Just check to make sure that it is set to one of the correct values.
8755
         */
8756
        WOLF_STACK_OF(WOLFSSL_X509)* sk = (WOLF_STACK_OF(WOLFSSL_X509)*) pt;
8757
        WOLFSSL_X509* x509;
8758
        int i;
8759
        if (opt != 0 && opt != 1) {
8760
            ret = WOLFSSL_FAILURE;
8761
            break;
8762
        }
8763
        /* Clear certificate chain */
8764
        FreeDer(&ctx->certChain);
8765
        if (sk) {
8766
            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
8767
                x509 = wolfSSL_sk_X509_value(sk, i);
8768
                /* Prevent wolfSSL_CTX_add_extra_chain_cert from freeing cert */
8769
                if (wolfSSL_X509_up_ref(x509) != 1) {
8770
                    WOLFSSL_MSG("Error increasing reference count");
8771
                    continue;
8772
                }
8773
                if (wolfSSL_CTX_add_extra_chain_cert(ctx, x509) !=
8774
                        WOLFSSL_SUCCESS) {
8775
                    WOLFSSL_MSG("Error adding certificate to context");
8776
                    /* Decrease reference count on failure */
8777
                    wolfSSL_X509_free(x509);
8778
                    x509 = NULL;
8779
                }
8780
            }
8781
        }
8782
        /* Free previous chain */
8783
        wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
8784
        ctx->x509Chain = sk;
8785
        if (sk && opt == 1) {
8786
            /* up all refs when opt == 1 */
8787
            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
8788
                x509 = wolfSSL_sk_X509_value(sk, i);
8789
                if (wolfSSL_X509_up_ref(x509) != 1) {
8790
                    WOLFSSL_MSG("Error increasing reference count");
8791
                    continue;
8792
                }
8793
            }
8794
        }
8795
    }
8796
#else
8797
        WOLFSSL_MSG("Session certificates not compiled in");
8798
        ret = WOLFSSL_FAILURE;
8799
#endif
8800
        break;
8801
8802
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
8803
    case SSL_CTRL_OPTIONS:
8804
        WOLFSSL_MSG("Entering Case: SSL_CTRL_OPTIONS.");
8805
        ctrl_opt = wolfSSL_CTX_set_options(ctx, opt);
8806
8807
        #ifdef WOLFSSL_QT
8808
        /* Set whether to use client or server cipher preference */
8809
        if ((ctrl_opt & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE)
8810
                     == WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
8811
            WOLFSSL_MSG("Using Server's Cipher Preference.");
8812
            ctx->useClientOrder = 0;
8813
        } else {
8814
            WOLFSSL_MSG("Using Client's Cipher Preference.");
8815
            ctx->useClientOrder = 1;
8816
        }
8817
        #endif /* WOLFSSL_QT */
8818
8819
        return ctrl_opt;
8820
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
8821
    case SSL_CTRL_EXTRA_CHAIN_CERT:
8822
        WOLFSSL_MSG("Entering Case: SSL_CTRL_EXTRA_CHAIN_CERT.");
8823
        if (pt == NULL) {
8824
            WOLFSSL_MSG("Passed in x509 pointer NULL.");
8825
            ret = WOLFSSL_FAILURE;
8826
            break;
8827
        }
8828
        return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
8829
8830
#ifndef NO_DH
8831
    case SSL_CTRL_SET_TMP_DH:
8832
        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_DH.");
8833
        if (pt == NULL) {
8834
            WOLFSSL_MSG("Passed in DH pointer NULL.");
8835
            ret = WOLFSSL_FAILURE;
8836
            break;
8837
        }
8838
        return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
8839
#endif
8840
8841
#ifdef HAVE_ECC
8842
    case SSL_CTRL_SET_TMP_ECDH:
8843
        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_ECDH.");
8844
        if (pt == NULL) {
8845
            WOLFSSL_MSG("Passed in ECDH pointer NULL.");
8846
            ret = WOLFSSL_FAILURE;
8847
            break;
8848
        }
8849
        return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
8850
#endif
8851
    case SSL_CTRL_MODE:
8852
        wolfSSL_CTX_set_mode(ctx,opt);
8853
        break;
8854
    case SSL_CTRL_SET_MIN_PROTO_VERSION:
8855
        WOLFSSL_MSG("set min proto version");
8856
        return wolfSSL_CTX_set_min_proto_version(ctx, (int)opt);
8857
    case SSL_CTRL_SET_MAX_PROTO_VERSION:
8858
        WOLFSSL_MSG("set max proto version");
8859
        return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt);
8860
    case SSL_CTRL_GET_MIN_PROTO_VERSION:
8861
        WOLFSSL_MSG("get min proto version");
8862
        return wolfSSL_CTX_get_min_proto_version(ctx);
8863
    case SSL_CTRL_GET_MAX_PROTO_VERSION:
8864
        WOLFSSL_MSG("get max proto version");
8865
        return wolfSSL_CTX_get_max_proto_version(ctx);
8866
    default:
8867
        WOLFSSL_MSG("CTX_ctrl cmd not implemented");
8868
        ret = WOLFSSL_FAILURE;
8869
        break;
8870
    }
8871
8872
    (void)ctx;
8873
    (void)cmd;
8874
    (void)opt;
8875
    (void)pt;
8876
    WOLFSSL_LEAVE("wolfSSL_CTX_ctrl", (int)ret);
8877
    return ret;
8878
}
8879
8880
#ifndef NO_WOLFSSL_STUB
8881
long wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX* ctx, int cmd, void (*fp)(void))
8882
{
8883
    (void) ctx;
8884
    (void) cmd;
8885
    (void) fp;
8886
    WOLFSSL_STUB("wolfSSL_CTX_callback_ctrl");
8887
    return WOLFSSL_FAILURE;
8888
8889
}
8890
#endif /* NO_WOLFSSL_STUB */
8891
8892
8893
#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
8894
8895
8896
/* stunnel compatibility functions*/
8897
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
8898
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
8899
     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
8900
     defined(WOLFSSL_OPENSSH)))
8901
8902
#ifndef NO_FILESYSTEM
8903
/***TBD ***/
8904
void wolfSSL_print_all_errors_fp(XFILE fp)
8905
{
8906
    (void)fp;
8907
}
8908
#endif /* !NO_FILESYSTEM */
8909
8910
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
8911
    HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH */
8912
8913
/* Note: This is a huge section of API's - through
8914
 *       wolfSSL_X509_OBJECT_get0_X509_CRL */
8915
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
8916
8917
#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_DEBUG_MEMORY) && \
8918
    !defined(WOLFSSL_STATIC_MEMORY)
8919
static wolfSSL_OSSL_Malloc_cb  ossl_malloc  = NULL;
8920
static wolfSSL_OSSL_Free_cb    ossl_free    = NULL;
8921
static wolfSSL_OSSL_Realloc_cb ossl_realloc = NULL;
8922
8923
static void* OSSL_Malloc(size_t size)
8924
{
8925
    if (ossl_malloc != NULL)
8926
        return ossl_malloc(size, NULL, 0);
8927
    else
8928
        return NULL;
8929
}
8930
8931
static void  OSSL_Free(void *ptr)
8932
{
8933
    if (ossl_free != NULL)
8934
        ossl_free(ptr, NULL, 0);
8935
}
8936
8937
static void* OSSL_Realloc(void *ptr, size_t size)
8938
{
8939
    if (ossl_realloc != NULL)
8940
        return ossl_realloc(ptr, size, NULL, 0);
8941
    else
8942
        return NULL;
8943
}
8944
#endif /* USE_WOLFSSL_MEMORY && !WOLFSSL_DEBUG_MEMORY &&
8945
        * !WOLFSSL_STATIC_MEMORY */
8946
8947
int wolfSSL_CRYPTO_set_mem_functions(
8948
        wolfSSL_OSSL_Malloc_cb  m,
8949
        wolfSSL_OSSL_Realloc_cb r,
8950
        wolfSSL_OSSL_Free_cb    f)
8951
{
8952
#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY)
8953
#ifdef WOLFSSL_DEBUG_MEMORY
8954
    WOLFSSL_MSG("mem functions will receive function name instead of "
8955
                "file name");
8956
    if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)m, (wolfSSL_Free_cb)f,
8957
            (wolfSSL_Realloc_cb)r) == 0)
8958
        return WOLFSSL_SUCCESS;
8959
#else
8960
    WOLFSSL_MSG("wolfSSL was compiled without WOLFSSL_DEBUG_MEMORY mem "
8961
                "functions will receive a NULL file name and 0 for the "
8962
                "line number.");
8963
    if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)OSSL_Malloc,
8964
           (wolfSSL_Free_cb)OSSL_Free, (wolfSSL_Realloc_cb)OSSL_Realloc) == 0) {
8965
        ossl_malloc = m;
8966
        ossl_free = f;
8967
        ossl_realloc = r;
8968
        return WOLFSSL_SUCCESS;
8969
    }
8970
#endif
8971
    else
8972
        return WOLFSSL_FAILURE;
8973
#else
8974
    (void)m;
8975
    (void)r;
8976
    (void)f;
8977
    WOLFSSL_MSG("wolfSSL allocator callback functions not compiled in");
8978
    return WOLFSSL_FAILURE;
8979
#endif
8980
}
8981
8982
int wolfSSL_FIPS_mode(void)
8983
{
8984
#ifdef HAVE_FIPS
8985
    return 1;
8986
#else
8987
    return 0;
8988
#endif
8989
}
8990
8991
int wolfSSL_FIPS_mode_set(int r)
8992
{
8993
#ifdef HAVE_FIPS
8994
    if (r == 0) {
8995
        WOLFSSL_MSG("Cannot disable FIPS at runtime.");
8996
        return WOLFSSL_FAILURE;
8997
    }
8998
    return WOLFSSL_SUCCESS;
8999
#else
9000
    if (r == 0) {
9001
        return WOLFSSL_SUCCESS;
9002
    }
9003
    WOLFSSL_MSG("Cannot enable FIPS. This isn't the wolfSSL FIPS code.");
9004
    return WOLFSSL_FAILURE;
9005
#endif
9006
}
9007
9008
int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
9009
{
9010
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
9011
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
9012
9013
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
9014
    (void)alg_bits;
9015
    if (c!= NULL)
9016
        ret = c->bits;
9017
    #else
9018
    if (c != NULL && c->ssl != NULL) {
9019
        ret = 8 * c->ssl->specs.key_size;
9020
        if (alg_bits != NULL) {
9021
            *alg_bits = ret;
9022
        }
9023
    }
9024
    #endif
9025
    return ret;
9026
}
9027
9028
9029
WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
9030
{
9031
    int ret;
9032
    /* This method requires some explanation. Its sibling is
9033
     *   int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
9034
     * which re-inits the WOLFSSL* with all settings in the new CTX.
9035
     * That one is the right one to use *before* a handshake is started.
9036
     *
9037
     * This method was added by OpenSSL to be used *during* the handshake, e.g.
9038
     * when a server inspects the SNI in a ClientHello callback and
9039
     * decides which set of certificates to use.
9040
     *
9041
     * Since, at the time the SNI callback is run, some decisions on
9042
     * Extensions or the ServerHello might already have been taken, this
9043
     * method is very restricted in what it does:
9044
     * - changing the server certificate(s)
9045
     * - changing the server id for session handling
9046
     * and everything else in WOLFSSL* needs to remain untouched.
9047
     *
9048
     * SECURITY: swapping ssl->ctx switches cm-resolved settings (CA store,
9049
     * CRL, OCSP) to the new CTX but leaves ssl-cached ones (verify mode and
9050
     * callback, minDowngrade, key-size minimums, suites, version bounds)
9051
     * pinned to the original. SNI callbacks must re-apply those ssl-level
9052
     * settings explicitly; CRL/OCSP isolation requires an SSL-local store.
9053
     */
9054
    WOLFSSL_ENTER("wolfSSL_set_SSL_CTX");
9055
    if (ssl == NULL || ctx == NULL)
9056
        return NULL;
9057
    if (ssl->ctx == ctx)
9058
        return ssl->ctx;
9059
9060
    /* suites, allocated and derived under the CTX mutex as this CTX may be
9061
     * shared with other threads. Done before taking a reference below so that
9062
     * a failure here returns without having changed anything. */
9063
    if (InitCtxSuitesWithMutex(ctx) != 0)
9064
        return NULL;
9065
9066
    wolfSSL_RefWithMutexInc(&ctx->ref, &ret);
9067
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
9068
    if (ret != 0) {
9069
        /* can only fail on serious stuff, like mutex not working
9070
         * or ctx refcount out of whack. */
9071
        return NULL;
9072
    }
9073
#else
9074
    (void)ret;
9075
#endif
9076
9077
    if (ssl->ctx != NULL)
9078
        wolfSSL_CTX_free(ssl->ctx);
9079
    ssl->ctx = ctx;
9080
9081
#ifndef NO_CERTS
9082
    /* Release the certificate, chain and keys this SSL owns so that a ctx
9083
     * without them leaves none of the old ones behind. */
9084
    wolfSSL_certs_clear(ssl);
9085
#ifdef WOLFSSL_COPY_CERT
9086
    /* If WOLFSSL_COPY_CERT defined, always make new copy of cert from ctx */
9087
    if (ctx->certificate != NULL) {
9088
        ret = AllocCopyDer(&ssl->buffers.certificate, ctx->certificate->buffer,
9089
            ctx->certificate->length, ctx->certificate->type,
9090
            ctx->certificate->heap);
9091
        if (ret != 0) {
9092
            return NULL;
9093
        }
9094
9095
        ssl->buffers.weOwnCert = 1;
9096
    }
9097
    if (ctx->certChain != NULL) {
9098
        ret = AllocCopyDer(&ssl->buffers.certChain, ctx->certChain->buffer,
9099
            ctx->certChain->length, ctx->certChain->type,
9100
            ctx->certChain->heap);
9101
        if (ret != 0) {
9102
            return NULL;
9103
        }
9104
9105
        ssl->buffers.weOwnCertChain = 1;
9106
    }
9107
#else
9108
    /* ctx owns certificate, certChain and key */
9109
    ssl->buffers.certificate = ctx->certificate;
9110
    ssl->buffers.certChain = ctx->certChain;
9111
#endif
9112
    ssl->buffers.certChainCnt = ctx->certChainCnt;
9113
#ifndef WOLFSSL_BLIND_PRIVATE_KEY
9114
#ifdef WOLFSSL_COPY_KEY
9115
    if (ctx->privateKey != NULL) {
9116
        ret = AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
9117
            ctx->privateKey->length, ctx->privateKey->type,
9118
            ctx->privateKey->heap);
9119
        if (ret != 0) {
9120
            return NULL;
9121
        }
9122
        ssl->buffers.weOwnKey = 1;
9123
    }
9124
    else {
9125
        ssl->buffers.key      = ctx->privateKey;
9126
    }
9127
#else
9128
    ssl->buffers.key      = ctx->privateKey;
9129
#endif
9130
#else
9131
    if (ctx->privateKey != NULL) {
9132
        ret = AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
9133
            ctx->privateKey->length, ctx->privateKey->type,
9134
            ctx->privateKey->heap);
9135
        if (ret != 0) {
9136
            return NULL;
9137
        }
9138
        ssl->buffers.weOwnKey = 1;
9139
        /* Blind the private key for the SSL with new random mask. */
9140
        wolfssl_priv_der_blind_toggle(ssl->buffers.key, ctx->privateKeyMask);
9141
        ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
9142
            &ssl->buffers.keyMask);
9143
        if (ret != 0) {
9144
            return NULL;
9145
        }
9146
    }
9147
#endif
9148
    ssl->buffers.keyType  = ctx->privateKeyType;
9149
    ssl->buffers.keyId    = ctx->privateKeyId;
9150
    ssl->buffers.keyLabel = ctx->privateKeyLabel;
9151
    ssl->buffers.keySz    = ctx->privateKeySz;
9152
    ssl->buffers.keyDevId = ctx->privateKeyDevId;
9153
    /* flags indicating what certs/keys are available */
9154
    ssl->options.haveRSA          = ctx->haveRSA;
9155
    ssl->options.haveDH           = ctx->haveDH;
9156
    ssl->options.haveECDSAsig     = ctx->haveECDSAsig;
9157
    ssl->options.haveECC          = ctx->haveECC;
9158
    ssl->options.haveStaticECC    = ctx->haveStaticECC;
9159
    ssl->options.haveFalconSig    = ctx->haveFalconSig;
9160
    ssl->options.haveMlDsaSig     = ctx->haveMlDsaSig;
9161
    ssl->options.haveSlhDsaSig    = ctx->haveSlhDsaSig;
9162
#ifdef WOLFSSL_DUAL_ALG_CERTS
9163
#ifndef WOLFSSL_BLIND_PRIVATE_KEY
9164
    ssl->buffers.altKey   = ctx->altPrivateKey;
9165
#else
9166
    if (ctx->altPrivateKey != NULL) {
9167
        ret = AllocCopyDer(&ssl->buffers.altKey, ctx->altPrivateKey->buffer,
9168
            ctx->altPrivateKey->length, ctx->altPrivateKey->type,
9169
            ctx->altPrivateKey->heap);
9170
        if (ret != 0) {
9171
            return NULL;
9172
        }
9173
        ssl->buffers.weOwnAltKey = 1;
9174
        /* Blind the private key for the SSL with new random mask. */
9175
        wolfssl_priv_der_blind_toggle(ssl->buffers.altKey,
9176
                                      ctx->altPrivateKeyMask);
9177
        ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
9178
            &ssl->buffers.altKeyMask);
9179
        if (ret != 0) {
9180
            return NULL;
9181
        }
9182
    }
9183
#endif
9184
    ssl->buffers.altKeySz   = ctx->altPrivateKeySz;
9185
    ssl->buffers.altKeyType = ctx->altPrivateKeyType;
9186
#endif /* WOLFSSL_DUAL_ALG_CERTS */
9187
#endif
9188
9189
#ifdef WOLFSSL_SESSION_ID_CTX
9190
    /* copy over application session context ID */
9191
    ssl->sessionCtxSz = ctx->sessionCtxSz;
9192
    XMEMCPY(ssl->sessionCtx, ctx->sessionCtx, ctx->sessionCtxSz);
9193
#endif
9194
9195
    return ssl->ctx;
9196
}
9197
9198
9199
#ifndef NO_BIO
9200
#endif
9201
9202
#ifndef NO_WOLFSSL_STUB
9203
/* Set THREADID callback, return 1 on success, 0 on error */
9204
int wolfSSL_THREADID_set_callback(
9205
        void(*threadid_func)(WOLFSSL_CRYPTO_THREADID*))
9206
{
9207
    WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
9208
    WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
9209
    (void)threadid_func;
9210
    return 1;
9211
}
9212
#endif
9213
9214
#ifndef NO_WOLFSSL_STUB
9215
void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
9216
{
9217
    WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
9218
    WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
9219
    (void)id;
9220
    (void)val;
9221
    return;
9222
}
9223
#endif
9224
9225
#endif /* OPENSSL_ALL || OPENSSL_EXTRA */
9226
9227
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
9228
/* Map a signature-algorithm NID to its digest and public-key NIDs, like
9229
 * OpenSSL's OBJ_find_sigid_algs(). */
9230
int wolfSSL_OBJ_find_sigid_algs(int sigid, int *pdig, int *ppkey)
9231
{
9232
    int dig  = 0;
9233
    int pkey = 0;
9234
    int ret  = 1;
9235
9236
    WOLFSSL_ENTER("wolfSSL_OBJ_find_sigid_algs");
9237
9238
    switch (sigid) {
9239
#ifndef NO_RSA
9240
    #ifndef NO_MD5
9241
        case WC_NID_md5WithRSAEncryption:
9242
            dig = WC_NID_md5;    pkey = WC_NID_rsaEncryption; break;
9243
    #endif
9244
        case WC_NID_sha1WithRSAEncryption:
9245
            dig = WC_NID_sha1;   pkey = WC_NID_rsaEncryption; break;
9246
        case WC_NID_sha224WithRSAEncryption:
9247
            dig = WC_NID_sha224; pkey = WC_NID_rsaEncryption; break;
9248
        case WC_NID_sha256WithRSAEncryption:
9249
            dig = WC_NID_sha256; pkey = WC_NID_rsaEncryption; break;
9250
        case WC_NID_sha384WithRSAEncryption:
9251
            dig = WC_NID_sha384; pkey = WC_NID_rsaEncryption; break;
9252
        case WC_NID_sha512WithRSAEncryption:
9253
            dig = WC_NID_sha512; pkey = WC_NID_rsaEncryption; break;
9254
    #ifdef WC_RSA_PSS
9255
        case WC_NID_rsassaPss:
9256
            dig = WC_NID_undef;  pkey = WC_NID_rsassaPss; break;
9257
    #endif
9258
#endif /* !NO_RSA */
9259
#ifdef HAVE_ECC
9260
        case WC_NID_ecdsa_with_SHA1:
9261
            dig = WC_NID_sha1;   pkey = WC_NID_X9_62_id_ecPublicKey; break;
9262
        case WC_NID_ecdsa_with_SHA224:
9263
            dig = WC_NID_sha224; pkey = WC_NID_X9_62_id_ecPublicKey; break;
9264
        case WC_NID_ecdsa_with_SHA256:
9265
            dig = WC_NID_sha256; pkey = WC_NID_X9_62_id_ecPublicKey; break;
9266
        case WC_NID_ecdsa_with_SHA384:
9267
            dig = WC_NID_sha384; pkey = WC_NID_X9_62_id_ecPublicKey; break;
9268
        case WC_NID_ecdsa_with_SHA512:
9269
            dig = WC_NID_sha512; pkey = WC_NID_X9_62_id_ecPublicKey; break;
9270
#endif /* HAVE_ECC */
9271
#ifdef HAVE_ED25519
9272
        case WC_NID_ED25519:
9273
            dig = WC_NID_undef;  pkey = WC_NID_ED25519; break;
9274
#endif
9275
#ifdef HAVE_ED448
9276
        case WC_NID_ED448:
9277
            dig = WC_NID_undef;  pkey = WC_NID_ED448; break;
9278
#endif
9279
        default:
9280
            ret = 0; break;
9281
    }
9282
9283
    if (ret == 1) {
9284
        if (pdig  != NULL) *pdig  = dig;
9285
        if (ppkey != NULL) *ppkey = pkey;
9286
    }
9287
9288
    WOLFSSL_LEAVE("wolfSSL_OBJ_find_sigid_algs", ret);
9289
    return ret;
9290
}
9291
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
9292
9293
9294
#if defined(OPENSSL_EXTRA)
9295
9296
int wolfSSL_CRYPTO_memcmp(const void *a, const void *b, size_t size)
9297
{
9298
    int ret = 0;
9299
    int chunk;
9300
    const byte* pa = (const byte*)a;
9301
    const byte* pb = (const byte*)b;
9302
9303
    if (!a || !b)
9304
        return -1;
9305
    /* ConstantCompare takes an int length. Compare in chunks of at most
9306
     * INT_MAX so a size that does not fit in an int is not narrowed into a
9307
     * negative or truncated length, which could wrongly report equality. */
9308
    while (size > 0) {
9309
        chunk = (size > (size_t)INT_MAX) ? INT_MAX : (int)size;
9310
        ret |= ConstantCompare(pa, pb, chunk);
9311
        pa += chunk;
9312
        pb += chunk;
9313
        size -= (size_t)chunk;
9314
    }
9315
    return ret;
9316
}
9317
9318
9319
#endif /* OPENSSL_EXTRA */
9320
9321
int wolfSSL_version(WOLFSSL* ssl)
9322
0
{
9323
0
    WOLFSSL_ENTER("wolfSSL_version");
9324
0
    if (ssl->version.major == SSLv3_MAJOR) {
9325
0
        switch (ssl->version.minor) {
9326
0
            case SSLv3_MINOR :
9327
0
                return SSL3_VERSION;
9328
0
            case TLSv1_MINOR :
9329
0
                return TLS1_VERSION;
9330
0
            case TLSv1_1_MINOR :
9331
0
                return TLS1_1_VERSION;
9332
0
            case TLSv1_2_MINOR :
9333
0
                return TLS1_2_VERSION;
9334
0
            case TLSv1_3_MINOR :
9335
0
                return TLS1_3_VERSION;
9336
0
            default:
9337
0
                return WOLFSSL_FAILURE;
9338
0
        }
9339
0
    }
9340
0
    else if (ssl->version.major == DTLS_MAJOR) {
9341
0
        switch (ssl->version.minor) {
9342
0
            case DTLS_MINOR :
9343
0
                return DTLS1_VERSION;
9344
0
            case DTLSv1_2_MINOR :
9345
0
                return DTLS1_2_VERSION;
9346
0
            case DTLSv1_3_MINOR:
9347
0
                return DTLS1_3_VERSION;
9348
0
            default:
9349
0
                return WOLFSSL_FAILURE;
9350
0
        }
9351
0
    }
9352
0
    return WOLFSSL_FAILURE;
9353
0
}
9354
9355
WOLFSSL_CTX* wolfSSL_get_SSL_CTX(const WOLFSSL* ssl)
9356
0
{
9357
0
    WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
9358
0
    return ssl->ctx;
9359
0
}
9360
9361
9362
#ifdef WOLFSSL_JNI
9363
9364
int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
9365
{
9366
    WOLFSSL_ENTER("wolfSSL_set_jobject");
9367
    if (ssl != NULL)
9368
    {
9369
        ssl->jObjectRef = objPtr;
9370
        return WOLFSSL_SUCCESS;
9371
    }
9372
    return WOLFSSL_FAILURE;
9373
}
9374
9375
void* wolfSSL_get_jobject(WOLFSSL* ssl)
9376
{
9377
    WOLFSSL_ENTER("wolfSSL_get_jobject");
9378
    if (ssl != NULL)
9379
        return ssl->jObjectRef;
9380
    return NULL;
9381
}
9382
9383
#endif /* WOLFSSL_JNI */
9384
9385
9386
#ifdef WOLFSSL_ASYNC_CRYPT
9387
int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
9388
    WOLF_EVENT_FLAG flags, int* eventCount)
9389
{
9390
    if (ctx == NULL) {
9391
        return BAD_FUNC_ARG;
9392
    }
9393
9394
    return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
9395
                                        events, maxEvents, flags, eventCount);
9396
}
9397
9398
int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
9399
{
9400
    int ret, eventCount = 0;
9401
    WOLF_EVENT* events[1];
9402
9403
    if (ssl == NULL) {
9404
        return BAD_FUNC_ARG;
9405
    }
9406
9407
    ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
9408
        events, sizeof(events)/sizeof(events[0]), flags, &eventCount);
9409
    if (ret == 0) {
9410
        ret = eventCount;
9411
    }
9412
9413
    return ret;
9414
}
9415
#endif /* WOLFSSL_ASYNC_CRYPT */
9416
9417
#ifdef OPENSSL_EXTRA
9418
9419
#endif
9420
9421
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \
9422
    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
9423
9424
#if !defined(WOLFSSL_USER_IO)
9425
/* converts an IPv6 or IPv4 address into an octet string for use with rfc3280
9426
 * example input would be "127.0.0.1" and the returned value would be 7F000001
9427
 */
9428
WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa)
9429
{
9430
    int ipaSz = WOLFSSL_IP4_ADDR_LEN;
9431
    char buf[WOLFSSL_IP6_ADDR_LEN + 1]; /* plus 1 for terminator */
9432
    int  af = WOLFSSL_IP4;
9433
    WOLFSSL_ASN1_STRING *ret = NULL;
9434
9435
    if (ipa == NULL)
9436
        return NULL;
9437
9438
    if (XSTRSTR(ipa, ":") != NULL) {
9439
        af = WOLFSSL_IP6;
9440
        ipaSz = WOLFSSL_IP6_ADDR_LEN;
9441
    }
9442
9443
    buf[WOLFSSL_IP6_ADDR_LEN] = '\0';
9444
#ifdef FREESCALE_MQX
9445
    if (XINET_PTON(af, ipa, (void*)buf, sizeof(buf)) != RTCS_OK) {
9446
#else
9447
    if (XINET_PTON(af, ipa, (void*)buf) != 1) {
9448
#endif
9449
        WOLFSSL_MSG("Error parsing IP address");
9450
        return NULL;
9451
    }
9452
9453
    ret = wolfSSL_ASN1_STRING_new();
9454
    if (ret != NULL) {
9455
        if (wolfSSL_ASN1_STRING_set(ret, buf, ipaSz) != WOLFSSL_SUCCESS) {
9456
            WOLFSSL_MSG("Error setting the string");
9457
            wolfSSL_ASN1_STRING_free(ret);
9458
            ret = NULL;
9459
        }
9460
    }
9461
9462
    return ret;
9463
}
9464
#endif /* !WOLFSSL_USER_IO */
9465
9466
/* Is the specified cipher suite a fake one used an an extension proxy? */
9467
static WC_INLINE int SCSV_Check(byte suite0, byte suite)
9468
{
9469
    (void)suite0;
9470
    (void)suite;
9471
#ifdef HAVE_RENEGOTIATION_INDICATION
9472
    if (suite0 == CIPHER_BYTE && suite == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
9473
        return 1;
9474
#endif
9475
    return 0;
9476
}
9477
9478
static WC_INLINE int sslCipherMinMaxCheck(const WOLFSSL *ssl, byte suite0,
9479
        byte suite)
9480
{
9481
    const CipherSuiteInfo* cipher_names = GetCipherNames();
9482
    int cipherSz = GetCipherNamesSize();
9483
    int i;
9484
    for (i = 0; i < cipherSz; i++)
9485
        if (cipher_names[i].cipherSuite0 == suite0 &&
9486
                cipher_names[i].cipherSuite == suite)
9487
            break;
9488
    if (i == cipherSz)
9489
        return 1;
9490
    /* Check min version */
9491
    if (cipher_names[i].minor < ssl->options.minDowngrade) {
9492
        if (ssl->options.minDowngrade <= TLSv1_2_MINOR &&
9493
                cipher_names[i].minor >= TLSv1_MINOR)
9494
            /* 1.0 ciphersuites are in general available in 1.1 and
9495
             * 1.1 ciphersuites are in general available in 1.2 */
9496
            return 0;
9497
        return 1;
9498
    }
9499
    /* Check max version */
9500
    switch (cipher_names[i].minor) {
9501
    case SSLv3_MINOR :
9502
        return ssl->options.mask & WOLFSSL_OP_NO_SSLv3;
9503
    case TLSv1_MINOR :
9504
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1;
9505
    case TLSv1_1_MINOR :
9506
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1;
9507
    case TLSv1_2_MINOR :
9508
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2;
9509
    case TLSv1_3_MINOR :
9510
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3;
9511
    default:
9512
        WOLFSSL_MSG("Unrecognized minor version");
9513
        return 1;
9514
    }
9515
}
9516
9517
/* returns a pointer to internal cipher suite list. Should not be free'd by
9518
 * caller.
9519
 */
9520
WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
9521
{
9522
    const Suites* suites;
9523
#if defined(OPENSSL_ALL)
9524
    const CipherSuiteInfo* cipher_names = GetCipherNames();
9525
    int cipherSz = GetCipherNamesSize();
9526
#endif
9527
9528
    WOLFSSL_ENTER("wolfSSL_get_ciphers_compat");
9529
    if (ssl == NULL)
9530
        return NULL;
9531
9532
    suites = WOLFSSL_SUITES(ssl);
9533
    if (suites == NULL)
9534
        return NULL;
9535
9536
    /* check if stack needs populated */
9537
    if (ssl->suitesStack == NULL) {
9538
        int i;
9539
9540
        ((WOLFSSL*)ssl)->suitesStack =
9541
                wolfssl_sk_new_type_ex(STACK_TYPE_CIPHER, ssl->heap);
9542
        if (ssl->suitesStack == NULL)
9543
            return NULL;
9544
9545
        /* Walk lowest priority first: each suite is inserted at index 0, so
9546
         * the highest priority suite ends up on top of the stack. */
9547
        for (i = suites->suiteSz - 2; i >= 0; i -= 2)
9548
        {
9549
            struct WOLFSSL_CIPHER cipher;
9550
9551
            /* A couple of suites are placeholders for special options,
9552
             * skip those. */
9553
            if (SCSV_Check(suites->suites[i], suites->suites[i+1])
9554
                    || sslCipherMinMaxCheck(ssl, suites->suites[i],
9555
                                            suites->suites[i+1])) {
9556
                continue;
9557
            }
9558
9559
            XMEMSET(&cipher, 0, sizeof(cipher));
9560
            cipher.cipherSuite0 = suites->suites[i];
9561
            cipher.cipherSuite  = suites->suites[i+1];
9562
            cipher.ssl          = ssl;
9563
#if defined(OPENSSL_ALL)
9564
            cipher.in_stack     = 1;
9565
            {
9566
                int j;
9567
                for (j = 0; j < cipherSz; j++) {
9568
                    if (cipher_names[j].cipherSuite0 == cipher.cipherSuite0 &&
9569
                            cipher_names[j].cipherSuite == cipher.cipherSuite) {
9570
                        cipher.offset = (unsigned long)j;
9571
                        break;
9572
                    }
9573
                }
9574
            }
9575
#endif
9576
            if (wolfSSL_sk_insert(ssl->suitesStack, &cipher, 0) <= 0) {
9577
                WOLFSSL_MSG("Error inserting cipher onto stack");
9578
                wolfSSL_sk_CIPHER_free(ssl->suitesStack);
9579
                ((WOLFSSL*)ssl)->suitesStack = NULL;
9580
                break;
9581
            }
9582
        }
9583
9584
        /* If no ciphers were added, free empty stack and return NULL */
9585
        if (ssl->suitesStack != NULL && wolfSSL_sk_num(ssl->suitesStack) == 0) {
9586
            wolfSSL_sk_CIPHER_free(ssl->suitesStack);
9587
            ((WOLFSSL*)ssl)->suitesStack = NULL;
9588
        }
9589
    }
9590
    return ssl->suitesStack;
9591
}
9592
9593
/* Get the name of the cipher at index priority in the cipher list configured
9594
 * on this SSL. Index 0 is the highest priority suite. Returns NULL once
9595
 * priority is past the end of the list. Matches OpenSSL SSL_get_cipher_list().
9596
 */
9597
const char* wolfSSL_get_cipher_list_compat(const WOLFSSL* ssl, int priority)
9598
{
9599
    const Suites* suites;
9600
    int i;
9601
    int idx = 0;
9602
9603
    WOLFSSL_ENTER("wolfSSL_get_cipher_list_compat");
9604
9605
    if (ssl == NULL || priority < 0)
9606
        return NULL;
9607
9608
    suites = WOLFSSL_SUITES(ssl);
9609
    if (suites == NULL)
9610
        return NULL;
9611
9612
    for (i = 0; i < suites->suiteSz; i += 2) {
9613
        /* A couple of suites are placeholders for special options, skip
9614
         * those. */
9615
        if (SCSV_Check(suites->suites[i], suites->suites[i+1])
9616
                || sslCipherMinMaxCheck(ssl, suites->suites[i],
9617
                                        suites->suites[i+1])) {
9618
            continue;
9619
        }
9620
9621
        if (idx++ == priority) {
9622
            /* Report the same name that SSL_CIPHER_get_name() would. */
9623
        #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && \
9624
            !defined(NO_ERROR_STRINGS) && !defined(WOLFSSL_QT)
9625
            return GetCipherNameIana(suites->suites[i], suites->suites[i+1]);
9626
        #else
9627
            return wolfSSL_get_cipher_name_from_suite(suites->suites[i],
9628
                    suites->suites[i+1]);
9629
        #endif
9630
        }
9631
    }
9632
9633
    return NULL;
9634
}
9635
#endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
9636
#ifdef OPENSSL_ALL
9637
/* returned pointer is to an internal element in WOLFSSL struct and should not
9638
 * be free'd. It gets free'd when the WOLFSSL struct is free'd. */
9639
WOLF_STACK_OF(WOLFSSL_CIPHER)*  wolfSSL_get_client_ciphers(WOLFSSL* ssl)
9640
{
9641
    WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
9642
    const CipherSuiteInfo* cipher_names = GetCipherNames();
9643
    int cipherSz = GetCipherNamesSize();
9644
    const Suites* suites;
9645
9646
    WOLFSSL_ENTER("wolfSSL_get_client_ciphers");
9647
9648
    if (ssl == NULL) {
9649
        return NULL;
9650
    }
9651
9652
    /* return NULL if is client side */
9653
    if (wolfSSL_is_server(ssl) == 0) {
9654
        return NULL;
9655
    }
9656
9657
    suites = ssl->clSuites;
9658
    if (suites == NULL) {
9659
        WOLFSSL_MSG("No client suites stored");
9660
    }
9661
    else if (ssl->clSuitesStack != NULL) {
9662
        ret = ssl->clSuitesStack;
9663
    }
9664
    else { /* generate cipher suites stack if not already done */
9665
        int i;
9666
        int j;
9667
9668
        ret = wolfSSL_sk_new_node(ssl->heap);
9669
        if (ret != NULL) {
9670
            ret->type = STACK_TYPE_CIPHER;
9671
9672
            /* higher priority of cipher suite will be on top of stack */
9673
            for (i = suites->suiteSz - 2; i >= 0; i -= 2) {
9674
                WOLFSSL_CIPHER cipher;
9675
9676
                /* A couple of suites are placeholders for special options,
9677
                 * skip those. */
9678
                if (SCSV_Check(suites->suites[i], suites->suites[i+1])
9679
                        || sslCipherMinMaxCheck(ssl, suites->suites[i],
9680
                                                suites->suites[i+1])) {
9681
                    continue;
9682
                }
9683
9684
                cipher.cipherSuite0 = suites->suites[i];
9685
                cipher.cipherSuite  = suites->suites[i+1];
9686
                cipher.ssl          = ssl;
9687
                for (j = 0; j < cipherSz; j++) {
9688
                    if (cipher_names[j].cipherSuite0 ==
9689
                            cipher.cipherSuite0 &&
9690
                            cipher_names[j].cipherSuite ==
9691
                                    cipher.cipherSuite) {
9692
                        cipher.offset = (unsigned long)j;
9693
                        break;
9694
                    }
9695
                }
9696
9697
                /* in_stack is checked in wolfSSL_CIPHER_description */
9698
                cipher.in_stack     = 1;
9699
9700
                if (wolfSSL_sk_CIPHER_push(ret, &cipher) <= 0) {
9701
                    WOLFSSL_MSG("Error pushing client cipher onto stack");
9702
                    wolfSSL_sk_CIPHER_free(ret);
9703
                    ret = NULL;
9704
                    break;
9705
                }
9706
            }
9707
        }
9708
        ssl->clSuitesStack = ret;
9709
    }
9710
    return ret;
9711
}
9712
#endif /* OPENSSL_ALL */
9713
9714
#if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK)
9715
long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
9716
{
9717
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
9718
9719
    if (ctx == NULL)
9720
        return 0;
9721
9722
    return ctx->timeout;
9723
}
9724
9725
9726
/* returns the time in seconds of the current timeout */
9727
long wolfSSL_get_timeout(WOLFSSL* ssl)
9728
{
9729
    WOLFSSL_ENTER("wolfSSL_get_timeout");
9730
9731
    if (ssl == NULL)
9732
        return 0;
9733
    return ssl->timeout;
9734
}
9735
#endif
9736
9737
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
9738
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
9739
9740
#ifndef NO_BIO
9741
WOLFSSL_BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
9742
{
9743
    WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
9744
    /* Nginx sets the buffer size if the read BIO is different to write BIO.
9745
     * The setting buffer size doesn't do anything so return NULL for both.
9746
     */
9747
    if (s == NULL)
9748
        return NULL;
9749
9750
    return s->biord;
9751
}
9752
WOLFSSL_BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
9753
{
9754
    WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
9755
    (void)s;
9756
    /* Nginx sets the buffer size if the read BIO is different to write BIO.
9757
     * The setting buffer size doesn't do anything so return NULL for both.
9758
     */
9759
    if (s == NULL)
9760
        return NULL;
9761
9762
    return s->biowr;
9763
}
9764
#endif /* !NO_BIO */
9765
9766
9767
9768
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
9769
    OPENSSL_EXTRA || HAVE_LIGHTY */
9770
9771
9772
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
9773
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
9774
9775
9776
void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s)
9777
{
9778
    WOLFSSL_ENTER("wolfSSL_WOLFSSL_STRING_free");
9779
9780
    XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
9781
}
9782
9783
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
9784
9785
9786
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
9787
9788
/* The FFDHE groups have no curve behind them, but they are named and reported
9789
 * through these same APIs, so an FFDHE-only build needs this block too. */
9790
#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
9791
    defined(HAVE_CURVE448) || !defined(NO_DH))
9792
#define CURVE_NAME(c) XSTR_SIZEOF((c)), (c)
9793
9794
const WOLF_EC_NIST_NAME kNistCurves[] = {
9795
#ifdef HAVE_ECC
9796
    {CURVE_NAME("P-160"),   WC_NID_secp160r1, WOLFSSL_ECC_SECP160R1},
9797
    {CURVE_NAME("P-160-2"), WC_NID_secp160r2, WOLFSSL_ECC_SECP160R2},
9798
    {CURVE_NAME("P-192"),   WC_NID_X9_62_prime192v1, WOLFSSL_ECC_SECP192R1},
9799
    {CURVE_NAME("P-224"),   WC_NID_secp224r1, WOLFSSL_ECC_SECP224R1},
9800
    {CURVE_NAME("P-256"),   WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
9801
    {CURVE_NAME("P-384"),   WC_NID_secp384r1, WOLFSSL_ECC_SECP384R1},
9802
    {CURVE_NAME("P-521"),   WC_NID_secp521r1, WOLFSSL_ECC_SECP521R1},
9803
    {CURVE_NAME("K-160"),   WC_NID_secp160k1, WOLFSSL_ECC_SECP160K1},
9804
    {CURVE_NAME("K-192"),   WC_NID_secp192k1, WOLFSSL_ECC_SECP192K1},
9805
    {CURVE_NAME("K-224"),   WC_NID_secp224k1, WOLFSSL_ECC_SECP224K1},
9806
    {CURVE_NAME("K-256"),   WC_NID_secp256k1, WOLFSSL_ECC_SECP256K1},
9807
    {CURVE_NAME("B-256"),   WC_NID_brainpoolP256r1,
9808
     WOLFSSL_ECC_BRAINPOOLP256R1},
9809
    {CURVE_NAME("B-384"),   WC_NID_brainpoolP384r1,
9810
     WOLFSSL_ECC_BRAINPOOLP384R1},
9811
    {CURVE_NAME("B-512"),   WC_NID_brainpoolP512r1,
9812
     WOLFSSL_ECC_BRAINPOOLP512R1},
9813
#endif
9814
#ifdef HAVE_CURVE25519
9815
    {CURVE_NAME("X25519"),  WC_NID_X25519, WOLFSSL_ECC_X25519},
9816
#endif
9817
#ifdef HAVE_CURVE448
9818
    {CURVE_NAME("X448"),    WC_NID_X448, WOLFSSL_ECC_X448},
9819
#endif
9820
#ifdef WOLFSSL_HAVE_MLKEM
9821
#ifndef WOLFSSL_NO_ML_KEM
9822
    {CURVE_NAME("ML_KEM_512"), WOLFSSL_ML_KEM_512, WOLFSSL_ML_KEM_512},
9823
    {CURVE_NAME("ML_KEM_768"), WOLFSSL_ML_KEM_768, WOLFSSL_ML_KEM_768},
9824
    {CURVE_NAME("ML_KEM_1024"), WOLFSSL_ML_KEM_1024, WOLFSSL_ML_KEM_1024},
9825
    /* Aliases accepting the OpenSSL/IANA spelling without underscores. */
9826
    {CURVE_NAME("MLKEM512"), WOLFSSL_ML_KEM_512, WOLFSSL_ML_KEM_512},
9827
    {CURVE_NAME("MLKEM768"), WOLFSSL_ML_KEM_768, WOLFSSL_ML_KEM_768},
9828
    {CURVE_NAME("MLKEM1024"), WOLFSSL_ML_KEM_1024, WOLFSSL_ML_KEM_1024},
9829
#if defined(HAVE_ECC)
9830
    #ifdef WOLFSSL_PQC_HYBRIDS
9831
    {CURVE_NAME("SecP256r1MLKEM768"), WOLFSSL_SECP256R1MLKEM768,
9832
     WOLFSSL_SECP256R1MLKEM768},
9833
    {CURVE_NAME("SecP384r1MLKEM1024"), WOLFSSL_SECP384R1MLKEM1024,
9834
     WOLFSSL_SECP384R1MLKEM1024},
9835
    {CURVE_NAME("X25519MLKEM768"), WOLFSSL_X25519MLKEM768,
9836
     WOLFSSL_X25519MLKEM768},
9837
    #endif /* WOLFSSL_PQC_HYBRIDS */
9838
    #ifdef WOLFSSL_EXTRA_PQC_HYBRIDS
9839
    {CURVE_NAME("SecP256r1MLKEM512"), WOLFSSL_SECP256R1MLKEM512,
9840
     WOLFSSL_SECP256R1MLKEM512},
9841
    {CURVE_NAME("SecP384r1MLKEM768"), WOLFSSL_SECP384R1MLKEM768,
9842
     WOLFSSL_SECP384R1MLKEM768},
9843
    {CURVE_NAME("SecP521r1MLKEM1024"), WOLFSSL_SECP521R1MLKEM1024,
9844
     WOLFSSL_SECP521R1MLKEM1024},
9845
    {CURVE_NAME("X25519MLKEM512"), WOLFSSL_X25519MLKEM512,
9846
     WOLFSSL_X25519MLKEM512},
9847
    {CURVE_NAME("X448MLKEM768"), WOLFSSL_X448MLKEM768,
9848
     WOLFSSL_X448MLKEM768},
9849
    #endif /* WOLFSSL_EXTRA_PQC_HYBRIDS */
9850
#endif
9851
#endif /* !WOLFSSL_NO_ML_KEM */
9852
#ifdef WOLFSSL_MLKEM_KYBER
9853
    {CURVE_NAME("KYBER_LEVEL1"), WOLFSSL_KYBER_LEVEL1, WOLFSSL_KYBER_LEVEL1},
9854
    {CURVE_NAME("KYBER_LEVEL3"), WOLFSSL_KYBER_LEVEL3, WOLFSSL_KYBER_LEVEL3},
9855
    {CURVE_NAME("KYBER_LEVEL5"), WOLFSSL_KYBER_LEVEL5, WOLFSSL_KYBER_LEVEL5},
9856
#if defined(HAVE_ECC)
9857
    {CURVE_NAME("P256_KYBER_LEVEL1"), WOLFSSL_P256_KYBER_LEVEL1,
9858
     WOLFSSL_P256_KYBER_LEVEL1},
9859
    {CURVE_NAME("P384_KYBER_LEVEL3"), WOLFSSL_P384_KYBER_LEVEL3,
9860
     WOLFSSL_P384_KYBER_LEVEL3},
9861
    {CURVE_NAME("P256_KYBER_LEVEL3"), WOLFSSL_P256_KYBER_LEVEL3,
9862
     WOLFSSL_P256_KYBER_LEVEL3},
9863
    {CURVE_NAME("P521_KYBER_LEVEL5"), WOLFSSL_P521_KYBER_LEVEL5,
9864
     WOLFSSL_P521_KYBER_LEVEL5},
9865
    {CURVE_NAME("X25519_KYBER_LEVEL1"), WOLFSSL_X25519_KYBER_LEVEL1,
9866
     WOLFSSL_X25519_KYBER_LEVEL1},
9867
    {CURVE_NAME("X448_KYBER_LEVEL3"), WOLFSSL_X448_KYBER_LEVEL3,
9868
     WOLFSSL_X448_KYBER_LEVEL3},
9869
    {CURVE_NAME("X25519_KYBER_LEVEL3"), WOLFSSL_X25519_KYBER_LEVEL3,
9870
     WOLFSSL_X25519_KYBER_LEVEL3},
9871
#endif
9872
#endif /* WOLFSSL_MLKEM_KYBER */
9873
#endif /* WOLFSSL_HAVE_MLKEM */
9874
#ifndef NO_DH
9875
    /* Finite field groups are not EC curves, but they do have NIDs of their
9876
     * own (RFC 7919, same values as OpenSSL). Use those rather than the TLS
9877
     * code point, which would collide with an unrelated WC_NID_* value. */
9878
    #ifdef HAVE_FFDHE_2048
9879
    {CURVE_NAME("ffdhe2048"), WC_NID_ffdhe2048, WOLFSSL_FFDHE_2048},
9880
    #endif
9881
    #ifdef HAVE_FFDHE_3072
9882
    {CURVE_NAME("ffdhe3072"), WC_NID_ffdhe3072, WOLFSSL_FFDHE_3072},
9883
    #endif
9884
    #ifdef HAVE_FFDHE_4096
9885
    {CURVE_NAME("ffdhe4096"), WC_NID_ffdhe4096, WOLFSSL_FFDHE_4096},
9886
    #endif
9887
    #ifdef HAVE_FFDHE_6144
9888
    {CURVE_NAME("ffdhe6144"), WC_NID_ffdhe6144, WOLFSSL_FFDHE_6144},
9889
    #endif
9890
    #ifdef HAVE_FFDHE_8192
9891
    {CURVE_NAME("ffdhe8192"), WC_NID_ffdhe8192, WOLFSSL_FFDHE_8192},
9892
    #endif
9893
#endif /* !NO_DH */
9894
#ifdef WOLFSSL_SM2
9895
    {CURVE_NAME("SM2"),     WC_NID_sm2, WOLFSSL_ECC_SM2P256V1},
9896
#endif
9897
#ifdef HAVE_ECC
9898
    /* Alternative curve names */
9899
    {CURVE_NAME("prime256v1"), WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
9900
    {CURVE_NAME("secp256r1"),  WC_NID_X9_62_prime256v1, WOLFSSL_ECC_SECP256R1},
9901
    {CURVE_NAME("secp384r1"),  WC_NID_secp384r1, WOLFSSL_ECC_SECP384R1},
9902
    {CURVE_NAME("secp521r1"),  WC_NID_secp521r1, WOLFSSL_ECC_SECP521R1},
9903
#endif
9904
#ifdef WOLFSSL_SM2
9905
    {CURVE_NAME("sm2p256v1"),  WC_NID_sm2, WOLFSSL_ECC_SM2P256V1},
9906
#endif
9907
    {0, NULL, 0, 0},
9908
};
9909
9910
int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names,
9911
        byte curves_only)
9912
{
9913
    int idx, start = 0, len, i, ret = WOLFSSL_FAILURE;
9914
    word16 curve;
9915
    word32 disabled;
9916
    char name[MAX_CURVE_NAME_SZ];
9917
    byte groups_len = 0;
9918
#ifdef WOLFSSL_SMALL_STACK
9919
    void *heap = ssl? ssl->heap : ctx ? ctx->heap : NULL;
9920
    int *groups;
9921
#else
9922
    int groups[WOLFSSL_MAX_GROUP_COUNT];
9923
#endif
9924
    const WOLF_EC_NIST_NAME* nist_name;
9925
9926
    WC_ALLOC_VAR_EX(groups, int, WOLFSSL_MAX_GROUP_COUNT, heap,
9927
        DYNAMIC_TYPE_TMP_BUFFER,
9928
    {
9929
        ret=MEMORY_E;
9930
        goto leave;
9931
    });
9932
9933
    for (idx = 1; names[idx-1] != '\0'; idx++) {
9934
        if (names[idx] != ':' && names[idx] != '\0')
9935
            continue;
9936
9937
        len = idx - start;
9938
        if (len > MAX_CURVE_NAME_SZ - 1)
9939
            goto leave;
9940
9941
        XMEMCPY(name, names + start, (size_t)len);
9942
        name[len] = 0;
9943
        curve = WOLFSSL_NAMED_GROUP_INVALID;
9944
9945
        for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
9946
            if (len == nist_name->name_len &&
9947
                    XSTRNCASECMP(name, nist_name->name, (size_t)len) == 0) {
9948
                curve = nist_name->curve;
9949
                break;
9950
            }
9951
        }
9952
9953
        if (curve == WOLFSSL_NAMED_GROUP_INVALID) {
9954
        #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && defined(HAVE_ECC)
9955
            int   nret;
9956
            const ecc_set_type *eccSet;
9957
9958
            nret = wc_ecc_get_curve_idx_from_name(name);
9959
            if (nret < 0) {
9960
                WOLFSSL_MSG("Could not find name in set");
9961
                goto leave;
9962
            }
9963
9964
            eccSet = wc_ecc_get_curve_params(nret);
9965
            if (eccSet == NULL) {
9966
                WOLFSSL_MSG("NULL set returned");
9967
                goto leave;
9968
            }
9969
9970
            curve = GetCurveByOID((int)eccSet->oidSum);
9971
        #else
9972
            WOLFSSL_MSG("API not present to search farther using name");
9973
            goto leave;
9974
        #endif
9975
        }
9976
9977
        if ((curves_only && curve >= WOLFSSL_ECC_MAX_AVAIL) ||
9978
                curve == WOLFSSL_NAMED_GROUP_INVALID) {
9979
            WOLFSSL_MSG("curve value is not supported");
9980
            goto leave;
9981
        }
9982
9983
        for (i = 0; i < groups_len; ++i) {
9984
            if (groups[i] == curve) {
9985
                /* silently drop duplicates */
9986
                break;
9987
            }
9988
        }
9989
        if (i >= groups_len) {
9990
            if (groups_len >= WOLFSSL_MAX_GROUP_COUNT) {
9991
                WOLFSSL_MSG_EX("setting %d or more supported "
9992
                               "curves is not permitted", groups_len);
9993
                goto leave;
9994
            }
9995
            groups[groups_len++] = (int)curve;
9996
        }
9997
9998
        start = idx + 1;
9999
    }
10000
10001
    /* Disable all curves so that only the ones the user wants are enabled. */
10002
    disabled = 0xFFFFFFFFUL;
10003
    for (i = 0; i < groups_len; ++i) {
10004
        /* Switch the bit to off and therefore is enabled. */
10005
        curve = (word16)groups[i];
10006
        if (curve >= 64) {
10007
            WC_DO_NOTHING;
10008
        }
10009
        else if (curve >= 32) {
10010
            /* 0 is for invalid and 1-14 aren't used otherwise. */
10011
            disabled &= ~(1U << (curve - 32));
10012
        }
10013
        else {
10014
            disabled &= ~(1U << curve);
10015
        }
10016
    #if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_TLS)
10017
    #if !defined(WOLFSSL_OLD_SET_CURVES_LIST)
10018
        /* using the wolfSSL API to set the groups, this will populate
10019
         * (ssl|ctx)->groups and reset any TLSX_SUPPORTED_GROUPS.
10020
         * The order in (ssl|ctx)->groups will then be respected
10021
         * when TLSX_KEY_SHARE needs to be established */
10022
        if ((ssl && wolfSSL_set_groups(ssl, groups, groups_len)
10023
                        != WOLFSSL_SUCCESS)
10024
            || (ctx && wolfSSL_CTX_set_groups(ctx, groups, groups_len)
10025
                           != WOLFSSL_SUCCESS)) {
10026
            WOLFSSL_MSG("Unable to set supported curve");
10027
            goto leave;
10028
        }
10029
    #elif !defined(NO_WOLFSSL_CLIENT)
10030
        /* set the supported curve so client TLS extension contains only the
10031
         * desired curves */
10032
        if ((ssl && wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
10033
            || (ctx && wolfSSL_CTX_UseSupportedCurve(ctx, curve)
10034
                           != WOLFSSL_SUCCESS)) {
10035
            WOLFSSL_MSG("Unable to set supported curve");
10036
            goto leave;
10037
        }
10038
    #endif
10039
    #endif /* HAVE_SUPPORTED_CURVES && !NO_TLS */
10040
    }
10041
10042
    if (ssl != NULL)
10043
        ssl->disabledCurves = disabled;
10044
    else if (ctx != NULL)
10045
        ctx->disabledCurves = disabled;
10046
    ret = WOLFSSL_SUCCESS;
10047
10048
leave:
10049
#ifdef WOLFSSL_SMALL_STACK
10050
    if (groups)
10051
        XFREE((void*)groups, heap, DYNAMIC_TYPE_TMP_BUFFER);
10052
#endif
10053
    return ret;
10054
}
10055
10056
/* Get the group used for key exchange.
10057
 *
10058
 * Mirrors OpenSSL's SSL_get_negotiated_group(): the NID is returned for groups
10059
 * wolfSSL gives one, the IANA code point otherwise. NID values are wolfSSL's
10060
 * WC_NID_* (not every one matches OpenSSL's), so compare against those rather
10061
 * than against literals. The result can be passed to wolfSSL_group_to_name().
10062
 * Only a completed handshake reports a group.
10063
 *
10064
 * @param [in] ssl  SSL/TLS object.
10065
 * @return  Group identifier on success.
10066
 * @return  0 when ssl is NULL or no group has been negotiated.
10067
 */
10068
int wolfSSL_get_negotiated_group(const WOLFSSL* ssl)
10069
{
10070
    word16 group = 0;
10071
    const WOLF_EC_NIST_NAME* nist_name;
10072
#if defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || defined(HAVE_ECC)
10073
    int ecdhDone;
10074
#endif
10075
10076
    WOLFSSL_ENTER("wolfSSL_get_negotiated_group");
10077
10078
    if (ssl == NULL)
10079
        return 0;
10080
10081
#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE)
10082
    /* Only a completed handshake has a negotiated group. Mid-handshake this
10083
     * can hold a group no key exchange used: the server seeds it from the
10084
     * resumed session in CheckPreSharedKeys(), and the client stores the group
10085
     * a HelloRetryRequest asked for. */
10086
    if (ssl->options.handShakeDone)
10087
        group = ssl->namedGroup;
10088
#endif
10089
10090
#if defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || defined(HAVE_ECC)
10091
    /* Below TLS 1.3 the negotiated curve is only in ecdhCurveOID, which
10092
     * InitSSL() also seeds from ctx->ecdhCurveOID - what
10093
     * SSL_CTX_set_tmp_ecdh() writes. Report it only once an EC(DH) exchange
10094
     * has actually run, or a configured preference reads back as a
10095
     * negotiated group on a connection that never used one. */
10096
    ecdhDone = ssl->options.handShakeDone &&
10097
               ((ssl->specs.kea == ecc_diffie_hellman_kea) ||
10098
                (ssl->specs.kea == ecdhe_psk_kea));
10099
#endif
10100
10101
#ifdef HAVE_CURVE25519
10102
    if ((group == 0) && ecdhDone && (ssl->ecdhCurveOID == ECC_X25519_OID))
10103
        group = WOLFSSL_ECC_X25519;
10104
#endif
10105
#ifdef HAVE_CURVE448
10106
    if ((group == 0) && ecdhDone && (ssl->ecdhCurveOID == ECC_X448_OID))
10107
        group = WOLFSSL_ECC_X448;
10108
#endif
10109
#ifdef HAVE_ECC
10110
    if ((group == 0) && ecdhDone && (ssl->ecdhCurveOID != 0))
10111
        group = GetCurveByOID((int)ssl->ecdhCurveOID);
10112
#endif
10113
10114
    if (group == 0)
10115
        return 0;
10116
10117
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
10118
        if (nist_name->curve == group)
10119
            return nist_name->nid;
10120
    }
10121
10122
    return (int)group;
10123
}
10124
10125
/* Names OpenSSL gives the TLS supported groups. These are the TLS group
10126
 * registry spellings, which differ from both the NIST curve names in
10127
 * kNistCurves ("P-256" is "secp256r1" here) and from wolfSSL_get_curve_name().
10128
 */
10129
static const struct {
10130
    word16      group;
10131
    const char* name;
10132
} kTlsGroupNames[] = {
10133
#ifdef HAVE_ECC
10134
    {WOLFSSL_ECC_SECP256R1,        "secp256r1"},
10135
    {WOLFSSL_ECC_SECP384R1,        "secp384r1"},
10136
    {WOLFSSL_ECC_SECP521R1,        "secp521r1"},
10137
    {WOLFSSL_ECC_SECP224R1,        "secp224r1"},
10138
    {WOLFSSL_ECC_SECP192R1,        "secp192r1"},
10139
    {WOLFSSL_ECC_SECP256K1,        "secp256k1"},
10140
#ifdef HAVE_ECC_BRAINPOOL
10141
    {WOLFSSL_ECC_BRAINPOOLP256R1,  "brainpoolP256r1"},
10142
    {WOLFSSL_ECC_BRAINPOOLP384R1,  "brainpoolP384r1"},
10143
    {WOLFSSL_ECC_BRAINPOOLP512R1,  "brainpoolP512r1"},
10144
    {WOLFSSL_ECC_BRAINPOOLP256R1TLS13, "brainpoolP256r1tls13"},
10145
    {WOLFSSL_ECC_BRAINPOOLP384R1TLS13, "brainpoolP384r1tls13"},
10146
    {WOLFSSL_ECC_BRAINPOOLP512R1TLS13, "brainpoolP512r1tls13"},
10147
#endif
10148
#endif /* HAVE_ECC */
10149
#ifdef HAVE_CURVE25519
10150
    {WOLFSSL_ECC_X25519,           "x25519"},
10151
#endif
10152
#ifdef HAVE_CURVE448
10153
    {WOLFSSL_ECC_X448,             "x448"},
10154
#endif
10155
#ifndef NO_DH
10156
    {WOLFSSL_FFDHE_2048,           "ffdhe2048"},
10157
    {WOLFSSL_FFDHE_3072,           "ffdhe3072"},
10158
    {WOLFSSL_FFDHE_4096,           "ffdhe4096"},
10159
    {WOLFSSL_FFDHE_6144,           "ffdhe6144"},
10160
    {WOLFSSL_FFDHE_8192,           "ffdhe8192"},
10161
#endif
10162
#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_NO_ML_KEM)
10163
    {WOLFSSL_ML_KEM_512,           "MLKEM512"},
10164
    {WOLFSSL_ML_KEM_768,           "MLKEM768"},
10165
    {WOLFSSL_ML_KEM_1024,          "MLKEM1024"},
10166
#if defined(HAVE_ECC) && defined(WOLFSSL_PQC_HYBRIDS)
10167
    {WOLFSSL_SECP256R1MLKEM768,    "SecP256r1MLKEM768"},
10168
    {WOLFSSL_SECP384R1MLKEM1024,   "SecP384r1MLKEM1024"},
10169
#ifdef HAVE_CURVE25519
10170
    {WOLFSSL_X25519MLKEM768,       "X25519MLKEM768"},
10171
#endif
10172
#endif
10173
#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_NO_ML_KEM */
10174
    {0, NULL}
10175
};
10176
10177
/* Get the name of a group.
10178
 *
10179
 * @param [in] ssl  SSL/TLS object. Unused, present for OpenSSL compatibility.
10180
 * @param [in] id   NID or IANA code point of the group.
10181
 * @return  Name of the group on success.
10182
 * @return  NULL when the group is unknown.
10183
 */
10184
const char* wolfSSL_group_to_name(const WOLFSSL* ssl, int id)
10185
{
10186
    const WOLF_EC_NIST_NAME* nist_name;
10187
    int group = id;
10188
    int i;
10189
10190
    WOLFSSL_ENTER("wolfSSL_group_to_name");
10191
10192
    (void)ssl;
10193
10194
    /* wolfSSL_get_negotiated_group() reports a NID where one exists, so map
10195
     * NIDs back to their code point before looking the name up. */
10196
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
10197
        if (nist_name->nid == id) {
10198
            group = (int)nist_name->curve;
10199
            break;
10200
        }
10201
    }
10202
10203
    for (i = 0; kTlsGroupNames[i].name != NULL; i++) {
10204
        if ((int)kTlsGroupNames[i].group == group)
10205
            return kTlsGroupNames[i].name;
10206
    }
10207
10208
    /* Not a group OpenSSL names - fall back to the wolfSSL name. */
10209
    for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
10210
        if ((int)nist_name->curve == group)
10211
            return nist_name->name;
10212
    }
10213
10214
    return NULL;
10215
}
10216
10217
#endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 || !NO_DH) */
10218
#endif /* OPENSSL_EXTRA || HAVE_CURL */
10219
10220
10221
#ifdef OPENSSL_EXTRA
10222
/* Sets a callback for when sending and receiving protocol messages.
10223
 * This callback is copied to all WOLFSSL objects created from the ctx.
10224
 *
10225
 * ctx WOLFSSL_CTX structure to set callback in
10226
 * cb  callback to use
10227
 *
10228
 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE with error case
10229
 */
10230
int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
10231
{
10232
    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback");
10233
    if (ctx == NULL) {
10234
        WOLFSSL_MSG("Null ctx passed in");
10235
        return WOLFSSL_FAILURE;
10236
    }
10237
10238
    ctx->protoMsgCb = cb;
10239
    return WOLFSSL_SUCCESS;
10240
}
10241
10242
10243
/* Sets a callback for when sending and receiving protocol messages.
10244
 *
10245
 * ssl WOLFSSL structure to set callback in
10246
 * cb  callback to use
10247
 *
10248
 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE with error case
10249
 */
10250
int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
10251
{
10252
    WOLFSSL_ENTER("wolfSSL_set_msg_callback");
10253
10254
    if (ssl == NULL) {
10255
        return WOLFSSL_FAILURE;
10256
    }
10257
10258
    if (cb != NULL) {
10259
        ssl->toInfoOn = 1;
10260
    }
10261
10262
    ssl->protoMsgCb = cb;
10263
    return WOLFSSL_SUCCESS;
10264
}
10265
10266
10267
/* set the user argument to pass to the msg callback when called
10268
 * return WOLFSSL_SUCCESS on success */
10269
int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
10270
{
10271
    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback_arg");
10272
    if (ctx == NULL) {
10273
        WOLFSSL_MSG("Null WOLFSSL_CTX passed in");
10274
        return WOLFSSL_FAILURE;
10275
    }
10276
10277
    ctx->protoMsgCtx = arg;
10278
    return WOLFSSL_SUCCESS;
10279
}
10280
10281
10282
int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
10283
{
10284
    WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
10285
    if (ssl == NULL)
10286
        return WOLFSSL_FAILURE;
10287
10288
    ssl->protoMsgCtx = arg;
10289
    return WOLFSSL_SUCCESS;
10290
}
10291
10292
void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file,
10293
    int line)
10294
{
10295
    void *ret;
10296
    (void)file;
10297
    (void)line;
10298
10299
    if (data == NULL || siz >= INT_MAX)
10300
        return NULL;
10301
10302
    ret = wolfSSL_OPENSSL_malloc(siz);
10303
    if (ret == NULL) {
10304
        return NULL;
10305
    }
10306
    return XMEMCPY(ret, data, siz);
10307
}
10308
10309
void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len)
10310
{
10311
    if (ptr)
10312
        ForceZero(ptr, (word32)len);
10313
}
10314
10315
#endif /* OPENSSL_EXTRA */
10316
10317
#define WOLFSSL_SSL_API_EXT_INCLUDED
10318
#include "src/ssl_api_ext.c"
10319
10320
#if defined(OPENSSL_EXTRA)
10321
10322
#ifndef NO_BIO
10323
#define WOLFSSL_BIO_INCLUDED
10324
#include "src/bio.c"
10325
#endif
10326
10327
#endif /* OPENSSL_EXTRA */
10328
10329
10330
#if defined(OPENSSL_EXTRA)
10331
10332
/* frees all nodes in the current threads error queue
10333
 *
10334
 * id  thread id. ERR_remove_state is depreciated and id is ignored. The
10335
 *     current threads queue will be free'd.
10336
 */
10337
10338
#endif /* OPENSSL_EXTRA */
10339
10340
10341
#if defined(OPENSSL_EXTRA)
10342
/* wolfSSL_THREADID_current is provided as a compat API with
10343
 * CRYPTO_THREADID_current to register current thread id into given id object.
10344
 * However, CRYPTO_THREADID_current API has been deprecated and no longer
10345
 * exists in the OpenSSL 1.0.0 or later.This API only works as a stub
10346
 * like as existing wolfSSL_THREADID_set_numeric.
10347
 */
10348
void wolfSSL_THREADID_current(WOLFSSL_CRYPTO_THREADID* id)
10349
{
10350
    (void)id;
10351
    return;
10352
}
10353
/* wolfSSL_THREADID_hash is provided as a compatible API with
10354
 * CRYPTO_THREADID_hash which returns a hash value calculated from the
10355
 * specified thread id. However, CRYPTO_THREADID_hash API has been
10356
 * deprecated and no longer exists in the OpenSSL 1.0.0 or later.
10357
 * This API only works as a stub to returns 0. This behavior is
10358
 * equivalent to the latest OpenSSL CRYPTO_THREADID_hash.
10359
 */
10360
unsigned long wolfSSL_THREADID_hash(const WOLFSSL_CRYPTO_THREADID* id)
10361
{
10362
    (void)id;
10363
    return 0UL;
10364
}
10365
10366
/**
10367
 * Set security level (wolfSSL doesn't support setting the security level).
10368
 *
10369
 * The security level can only be set through a system wide crypto-policy
10370
 * with wolfSSL_crypto_policy_enable().
10371
 *
10372
 * @param ctx  a pointer to WOLFSSL_CTX structure
10373
 * @param level security level
10374
 */
10375
void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level)
10376
{
10377
    WOLFSSL_ENTER("wolfSSL_CTX_set_security_level");
10378
    (void)ctx;
10379
    (void)level;
10380
}
10381
10382
int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX * ctx)
10383
{
10384
    WOLFSSL_ENTER("wolfSSL_CTX_get_security_level");
10385
    #if defined(WOLFSSL_SYS_CRYPTO_POLICY)
10386
    if (ctx == NULL) {
10387
        return BAD_FUNC_ARG;
10388
    }
10389
10390
    return ctx->secLevel;
10391
    #else
10392
    (void)ctx;
10393
    return 0;
10394
    #endif /* WOLFSSL_SYS_CRYPTO_POLICY */
10395
}
10396
10397
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
10398
/*
10399
 * This API accepts a user callback which puts key-log records into
10400
 * a KEY LOGFILE. The callback is stored into a CTX and propagated to
10401
 * each SSL object on its creation timing.
10402
 */
10403
void wolfSSL_CTX_set_keylog_callback(WOLFSSL_CTX* ctx,
10404
    wolfSSL_CTX_keylog_cb_func cb)
10405
{
10406
    WOLFSSL_ENTER("wolfSSL_CTX_set_keylog_callback");
10407
    /* stores the callback into WOLFSSL_CTX */
10408
    if (ctx != NULL) {
10409
        ctx->keyLogCb = cb;
10410
    }
10411
}
10412
wolfSSL_CTX_keylog_cb_func wolfSSL_CTX_get_keylog_callback(
10413
    const WOLFSSL_CTX* ctx)
10414
{
10415
    WOLFSSL_ENTER("wolfSSL_CTX_get_keylog_callback");
10416
    if (ctx != NULL)
10417
        return ctx->keyLogCb;
10418
    return NULL;
10419
}
10420
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
10421
10422
#endif /* OPENSSL_EXTRA */
10423
10424
#ifdef WOLFSSL_THREADED_CRYPT
10425
int wolfSSL_AsyncEncryptReady(WOLFSSL* ssl, int idx)
10426
{
10427
    ThreadCrypt* encrypt;
10428
10429
    if (ssl == NULL) {
10430
        return 0;
10431
    }
10432
10433
    encrypt = &ssl->buffers.encrypt[idx];
10434
    return (encrypt->avail == 0) && (encrypt->done == 0);
10435
}
10436
10437
int wolfSSL_AsyncEncryptStop(WOLFSSL* ssl, int idx)
10438
{
10439
    ThreadCrypt* encrypt;
10440
10441
    if (ssl == NULL) {
10442
        return 1;
10443
    }
10444
10445
    encrypt = &ssl->buffers.encrypt[idx];
10446
    return encrypt->stop;
10447
}
10448
10449
int wolfSSL_AsyncEncrypt(WOLFSSL* ssl, int idx)
10450
{
10451
    int ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
10452
    ThreadCrypt* encrypt = &ssl->buffers.encrypt[idx];
10453
10454
    if (ssl->specs.bulk_cipher_algorithm == wolfssl_aes_gcm) {
10455
        unsigned char* out = encrypt->buffer.buffer + encrypt->offset;
10456
        unsigned char* input = encrypt->buffer.buffer + encrypt->offset;
10457
        word32 encSz = encrypt->buffer.length - encrypt->offset;
10458
10459
        ret =
10460
#if !defined(NO_GCM_ENCRYPT_EXTRA) && \
10461
    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
10462
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
10463
              wc_AesGcmEncrypt_ex
10464
#else
10465
              wc_AesGcmEncrypt
10466
#endif
10467
              (encrypt->encrypt.aes,
10468
               out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ,
10469
               encSz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size,
10470
               encrypt->nonce, AESGCM_NONCE_SZ,
10471
               out + encSz - ssl->specs.aead_mac_size,
10472
               ssl->specs.aead_mac_size,
10473
               encrypt->additional, AEAD_AUTH_DATA_SZ);
10474
#if !defined(NO_PUBLIC_GCM_SET_IV) && \
10475
    ((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
10476
    (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
10477
        XMEMCPY(out, encrypt->nonce + AESGCM_IMP_IV_SZ, AESGCM_EXP_IV_SZ);
10478
#endif
10479
        encrypt->done = 1;
10480
    }
10481
10482
    return ret;
10483
}
10484
10485
int wolfSSL_AsyncEncryptSetSignal(WOLFSSL* ssl, int idx,
10486
    WOLFSSL_THREAD_SIGNAL signal, void* ctx)
10487
{
10488
    int ret = 0;
10489
10490
    if (ssl == NULL) {
10491
        ret = BAD_FUNC_ARG;
10492
    }
10493
    else {
10494
        ssl->buffers.encrypt[idx].signal = signal;
10495
        ssl->buffers.encrypt[idx].signalCtx = ctx;
10496
    }
10497
10498
    return ret;
10499
}
10500
#endif
10501
10502
10503
#ifndef NO_CERT
10504
#define WOLFSSL_X509_INCLUDED
10505
#include "src/x509.c"
10506
#endif
10507
10508
/*******************************************************************************
10509
 * START OF standard C library wrapping APIs
10510
 ******************************************************************************/
10511
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
10512
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
10513
     defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
10514
     defined(WOLFSSL_OPENSSH)))
10515
#ifndef NO_WOLFSSL_STUB
10516
int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
10517
                                void *(*r) (void *, size_t, const char *,
10518
                                            int), void (*f) (void *))
10519
{
10520
    (void) m;
10521
    (void) r;
10522
    (void) f;
10523
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
10524
    WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
10525
10526
    return WOLFSSL_FAILURE;
10527
}
10528
#endif
10529
#endif
10530
10531
#if defined(OPENSSL_EXTRA)
10532
10533
/**
10534
 * free allocated memory resource
10535
 * @param str  a pointer to resource to be freed
10536
 * @param file dummy argument
10537
 * @param line dummy argument
10538
 */
10539
void wolfSSL_CRYPTO_free(void *str, const char *file, int line)
10540
{
10541
    (void)file;
10542
    (void)line;
10543
    XFREE(str, 0, DYNAMIC_TYPE_TMP_BUFFER);
10544
}
10545
/**
10546
 * allocate memory with size of num
10547
 * @param num  size of memory allocation to be malloced
10548
 * @param file dummy argument
10549
 * @param line dummy argument
10550
 * @return a pointer to allocated memory on succssesful, otherwise NULL
10551
 */
10552
void *wolfSSL_CRYPTO_malloc(size_t num, const char *file, int line)
10553
{
10554
    (void)file;
10555
    (void)line;
10556
    return XMALLOC(num, 0, DYNAMIC_TYPE_TMP_BUFFER);
10557
}
10558
10559
#endif
10560
10561
/*******************************************************************************
10562
 * END OF standard C library wrapping APIs
10563
 ******************************************************************************/
10564
10565
/*******************************************************************************
10566
 * START OF EX_DATA APIs
10567
 ******************************************************************************/
10568
#ifdef HAVE_EX_DATA
10569
void wolfSSL_CRYPTO_cleanup_all_ex_data(void)
10570
{
10571
    WOLFSSL_ENTER("wolfSSL_CRYPTO_cleanup_all_ex_data");
10572
}
10573
10574
void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx)
10575
{
10576
    WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_data");
10577
#ifdef MAX_EX_DATA
10578
    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
10579
        return ex_data->ex_data[idx];
10580
    }
10581
#else
10582
    (void)ex_data;
10583
    (void)idx;
10584
#endif
10585
    return NULL;
10586
}
10587
10588
int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx,
10589
    void *data)
10590
{
10591
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data");
10592
#ifdef MAX_EX_DATA
10593
    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
10594
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
10595
        if (ex_data->ex_data_cleanup_routines[idx]) {
10596
            /* call cleanup then remove cleanup callback,
10597
             * since different value is being set */
10598
            if (ex_data->ex_data[idx])
10599
                ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
10600
            ex_data->ex_data_cleanup_routines[idx] = NULL;
10601
        }
10602
#endif
10603
        ex_data->ex_data[idx] = data;
10604
        return WOLFSSL_SUCCESS;
10605
    }
10606
#else
10607
    (void)ex_data;
10608
    (void)idx;
10609
    (void)data;
10610
#endif
10611
    return WOLFSSL_FAILURE;
10612
}
10613
10614
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
10615
int wolfSSL_CRYPTO_set_ex_data_with_cleanup(
10616
    WOLFSSL_CRYPTO_EX_DATA* ex_data,
10617
    int idx,
10618
    void *data,
10619
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
10620
{
10621
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data_with_cleanup");
10622
    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
10623
        if (ex_data->ex_data_cleanup_routines[idx] && ex_data->ex_data[idx])
10624
            ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
10625
        ex_data->ex_data[idx] = data;
10626
        ex_data->ex_data_cleanup_routines[idx] = cleanup_routine;
10627
        return WOLFSSL_SUCCESS;
10628
    }
10629
    return WOLFSSL_FAILURE;
10630
}
10631
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
10632
#endif /* HAVE_EX_DATA */
10633
10634
#ifdef HAVE_EX_DATA_CRYPTO
10635
/**
10636
 * Issues unique index for the class specified by class_index.
10637
 * Other parameter except class_index are ignored.
10638
 * Currently, following class_index are accepted:
10639
 *  - WOLF_CRYPTO_EX_INDEX_SSL
10640
 *  - WOLF_CRYPTO_EX_INDEX_SSL_CTX
10641
 *  - WOLF_CRYPTO_EX_INDEX_X509
10642
 * @param class_index index one of CRYPTO_EX_INDEX_xxx
10643
 * @param argp  parameters to be saved
10644
 * @param argl  parameters to be saved
10645
 * @param new_func a pointer to WOLFSSL_CRYPTO_EX_new
10646
 * @param dup_func a pointer to WOLFSSL_CRYPTO_EX_dup
10647
 * @param free_func a pointer to WOLFSSL_CRYPTO_EX_free
10648
 * @return index value grater or equal to zero on success, -1 on failure.
10649
 */
10650
int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
10651
                                           WOLFSSL_CRYPTO_EX_new* new_func,
10652
                                           WOLFSSL_CRYPTO_EX_dup* dup_func,
10653
                                           WOLFSSL_CRYPTO_EX_free* free_func)
10654
{
10655
    WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_new_index");
10656
10657
    return wolfssl_local_get_ex_new_index(class_index, argl, argp, new_func,
10658
            dup_func, free_func);
10659
}
10660
#endif /* HAVE_EX_DATA_CRYPTO */
10661
10662
/*******************************************************************************
10663
 * END OF EX_DATA APIs
10664
 ******************************************************************************/
10665
10666
/*******************************************************************************
10667
 * START OF BUF_MEM API
10668
 ******************************************************************************/
10669
10670
#if defined(OPENSSL_EXTRA)
10671
10672
/* Begin functions for openssl/buffer.h */
10673
WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
10674
{
10675
    WOLFSSL_BUF_MEM* buf;
10676
    buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
10677
                                                        DYNAMIC_TYPE_OPENSSL);
10678
    if (buf) {
10679
        XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
10680
    }
10681
    return buf;
10682
}
10683
10684
/* non-compat API returns length of buffer on success */
10685
int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len,
10686
        char zeroFill)
10687
{
10688
    size_t mx;
10689
    char* tmp;
10690
10691
    /* verify provided arguments. The return value is an int holding the
10692
     * resulting length, so reject any len that cannot be represented as a
10693
     * non-negative int. This also prevents truncating size_t to int. */
10694
    if (buf == NULL || len > (size_t)WC_MAX_SINT_OF(int)) {
10695
        return 0; /* BAD_FUNC_ARG; */
10696
    }
10697
10698
    /* check to see if fits in existing length */
10699
    if (buf->length > len) {
10700
        buf->length = len;
10701
        return (int)len;
10702
    }
10703
10704
    /* check to see if fits in max buffer */
10705
    if (buf->max >= len) {
10706
        if (buf->data != NULL && zeroFill) {
10707
            XMEMSET(&buf->data[buf->length], 0, len - buf->length);
10708
        }
10709
        buf->length = len;
10710
        return (int)len;
10711
    }
10712
10713
    /* expand size, to handle growth */
10714
    mx = (len + 3) / 3 * 4;
10715
10716
#ifdef WOLFSSL_NO_REALLOC
10717
    tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL);
10718
    if (tmp != NULL && buf->data != NULL) {
10719
       /* only the existing content is valid in the old buffer; copying
10720
        * len_int (the new, larger size) would read past buf->max */
10721
       XMEMCPY(tmp, buf->data, buf->length);
10722
       XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
10723
       buf->data = NULL;
10724
    }
10725
#else
10726
    /* use realloc */
10727
    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
10728
#endif
10729
10730
    if (tmp == NULL) {
10731
        return 0; /* ERR_R_MALLOC_FAILURE; */
10732
    }
10733
    buf->data = tmp;
10734
10735
    buf->max = mx;
10736
    if (zeroFill)
10737
        XMEMSET(&buf->data[buf->length], 0, len - buf->length);
10738
    buf->length = len;
10739
10740
    return (int)len;
10741
10742
}
10743
10744
/* returns length of buffer on success */
10745
int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
10746
{
10747
    return wolfSSL_BUF_MEM_grow_ex(buf, len, 1);
10748
}
10749
10750
/* non-compat API returns length of buffer on success */
10751
int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len)
10752
{
10753
    char* tmp;
10754
    size_t mx;
10755
10756
    /* verify provided arguments. The return value is an int, so reject any
10757
     * len that cannot be represented as a positive int. */
10758
    if (buf == NULL || len == 0 || len > (size_t)WC_MAX_SINT_OF(int)) {
10759
        return 0; /* BAD_FUNC_ARG; */
10760
    }
10761
10762
    if (len == buf->length)
10763
        return (int)len;
10764
10765
    if (len > buf->length)
10766
        return wolfSSL_BUF_MEM_grow_ex(buf, len, 0);
10767
10768
    /* expand size, to handle growth */
10769
    mx = (len + 3) / 3 * 4;
10770
10771
    /* We want to shrink the internal buffer */
10772
#ifdef WOLFSSL_NO_REALLOC
10773
    tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL);
10774
    if (tmp != NULL && buf->data != NULL)
10775
    {
10776
        XMEMCPY(tmp, buf->data, len);
10777
        XFREE(buf->data,NULL,DYNAMIC_TYPE_OPENSSL);
10778
        buf->data = NULL;
10779
    }
10780
#else
10781
    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
10782
#endif
10783
10784
    if (tmp == NULL)
10785
        return 0;
10786
10787
    buf->data = tmp;
10788
    buf->length = len;
10789
    buf->max = mx;
10790
10791
    return (int)len;
10792
}
10793
10794
void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
10795
{
10796
    if (buf) {
10797
        XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
10798
        buf->data = NULL;
10799
        buf->max = 0;
10800
        buf->length = 0;
10801
        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
10802
    }
10803
}
10804
/* End Functions for openssl/buffer.h */
10805
10806
#endif /* OPENSSL_EXTRA */
10807
10808
/*******************************************************************************
10809
 * END OF BUF_MEM API
10810
 ******************************************************************************/
10811
10812
#define WOLFSSL_CONF_INCLUDED
10813
#include <src/conf.c>
10814
10815
/*******************************************************************************
10816
 * START OF EVP_CIPHER API
10817
 ******************************************************************************/
10818
10819
#ifdef OPENSSL_EXTRA
10820
10821
    /* store for external read of iv, WOLFSSL_SUCCESS on success */
10822
    int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
10823
    {
10824
        WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
10825
10826
        if (ctx == NULL) {
10827
            WOLFSSL_MSG("Bad function argument");
10828
            return WOLFSSL_FATAL_ERROR;
10829
        }
10830
10831
        switch (ctx->cipherType) {
10832
#ifndef NO_AES
10833
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
10834
            case WC_AES_128_CBC_TYPE :
10835
            case WC_AES_192_CBC_TYPE :
10836
            case WC_AES_256_CBC_TYPE :
10837
                WOLFSSL_MSG("AES CBC");
10838
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
10839
                break;
10840
#endif
10841
#ifdef HAVE_AESGCM
10842
            case WC_AES_128_GCM_TYPE :
10843
            case WC_AES_192_GCM_TYPE :
10844
            case WC_AES_256_GCM_TYPE :
10845
                WOLFSSL_MSG("AES GCM");
10846
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
10847
                break;
10848
#endif /* HAVE_AESGCM */
10849
#ifdef HAVE_AESCCM
10850
            case WC_AES_128_CCM_TYPE :
10851
            case WC_AES_192_CCM_TYPE :
10852
            case WC_AES_256_CCM_TYPE :
10853
                WOLFSSL_MSG("AES CCM");
10854
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, ctx->ivSz);
10855
                break;
10856
#endif /* HAVE_AESCCM */
10857
#ifdef HAVE_AES_ECB
10858
            case WC_AES_128_ECB_TYPE :
10859
            case WC_AES_192_ECB_TYPE :
10860
            case WC_AES_256_ECB_TYPE :
10861
                WOLFSSL_MSG("AES ECB");
10862
                break;
10863
#endif
10864
#ifdef WOLFSSL_AES_COUNTER
10865
            case WC_AES_128_CTR_TYPE :
10866
            case WC_AES_192_CTR_TYPE :
10867
            case WC_AES_256_CTR_TYPE :
10868
                WOLFSSL_MSG("AES CTR");
10869
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, WC_AES_BLOCK_SIZE);
10870
                break;
10871
#endif /* WOLFSSL_AES_COUNTER */
10872
#ifdef WOLFSSL_AES_CFB
10873
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
10874
            case WC_AES_128_CFB1_TYPE:
10875
            case WC_AES_192_CFB1_TYPE:
10876
            case WC_AES_256_CFB1_TYPE:
10877
                WOLFSSL_MSG("AES CFB1");
10878
                break;
10879
            case WC_AES_128_CFB8_TYPE:
10880
            case WC_AES_192_CFB8_TYPE:
10881
            case WC_AES_256_CFB8_TYPE:
10882
                WOLFSSL_MSG("AES CFB8");
10883
                break;
10884
#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
10885
            case WC_AES_128_CFB128_TYPE:
10886
            case WC_AES_192_CFB128_TYPE:
10887
            case WC_AES_256_CFB128_TYPE:
10888
                WOLFSSL_MSG("AES CFB128");
10889
                break;
10890
#endif /* WOLFSSL_AES_CFB */
10891
#if defined(WOLFSSL_AES_OFB)
10892
            case WC_AES_128_OFB_TYPE:
10893
            case WC_AES_192_OFB_TYPE:
10894
            case WC_AES_256_OFB_TYPE:
10895
                WOLFSSL_MSG("AES OFB");
10896
                break;
10897
#endif /* WOLFSSL_AES_OFB */
10898
#ifdef WOLFSSL_AES_XTS
10899
            case WC_AES_128_XTS_TYPE:
10900
            case WC_AES_256_XTS_TYPE:
10901
                WOLFSSL_MSG("AES XTS");
10902
                break;
10903
#endif /* WOLFSSL_AES_XTS */
10904
#endif /* NO_AES */
10905
10906
#ifdef HAVE_ARIA
10907
            case WC_ARIA_128_GCM_TYPE :
10908
            case WC_ARIA_192_GCM_TYPE :
10909
            case WC_ARIA_256_GCM_TYPE :
10910
                WOLFSSL_MSG("ARIA GCM");
10911
                XMEMCPY(ctx->iv, &ctx->cipher.aria.nonce, ARIA_BLOCK_SIZE);
10912
                break;
10913
#endif /* HAVE_ARIA */
10914
10915
#ifndef NO_DES3
10916
            case WC_DES_CBC_TYPE :
10917
                WOLFSSL_MSG("DES CBC");
10918
                XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
10919
                break;
10920
10921
            case WC_DES_EDE3_CBC_TYPE :
10922
                WOLFSSL_MSG("DES EDE3 CBC");
10923
                XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
10924
                break;
10925
#endif
10926
#ifdef WOLFSSL_DES_ECB
10927
            case WC_DES_ECB_TYPE :
10928
                WOLFSSL_MSG("DES ECB");
10929
                break;
10930
            case WC_DES_EDE3_ECB_TYPE :
10931
                WOLFSSL_MSG("DES3 ECB");
10932
                break;
10933
#endif
10934
            case WC_ARC4_TYPE :
10935
                WOLFSSL_MSG("ARC4");
10936
                break;
10937
10938
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
10939
            case WC_CHACHA20_POLY1305_TYPE:
10940
                break;
10941
#endif
10942
10943
#ifdef HAVE_CHACHA
10944
            case WC_CHACHA20_TYPE:
10945
                break;
10946
#endif
10947
10948
#ifdef WOLFSSL_SM4_ECB
10949
            case WC_SM4_ECB_TYPE:
10950
                break;
10951
#endif
10952
#ifdef WOLFSSL_SM4_CBC
10953
            case WC_SM4_CBC_TYPE:
10954
                WOLFSSL_MSG("SM4 CBC");
10955
                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
10956
                break;
10957
#endif
10958
#ifdef WOLFSSL_SM4_CTR
10959
            case WC_SM4_CTR_TYPE:
10960
                WOLFSSL_MSG("SM4 CTR");
10961
                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
10962
                break;
10963
#endif
10964
#ifdef WOLFSSL_SM4_GCM
10965
            case WC_SM4_GCM_TYPE:
10966
                WOLFSSL_MSG("SM4 GCM");
10967
                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
10968
                break;
10969
#endif
10970
#ifdef WOLFSSL_SM4_CCM
10971
            case WC_SM4_CCM_TYPE:
10972
                WOLFSSL_MSG("SM4 CCM");
10973
                XMEMCPY(&ctx->cipher.sm4.iv, ctx->iv, SM4_BLOCK_SIZE);
10974
                break;
10975
#endif
10976
10977
            case WC_NULL_CIPHER_TYPE :
10978
                WOLFSSL_MSG("NULL");
10979
                break;
10980
10981
            default: {
10982
                WOLFSSL_MSG("bad type");
10983
                return WOLFSSL_FATAL_ERROR;
10984
            }
10985
        }
10986
        return WOLFSSL_SUCCESS;
10987
    }
10988
10989
    /* set internal IV from external, WOLFSSL_SUCCESS on success */
10990
    int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
10991
    {
10992
10993
        WOLFSSL_ENTER("wolfSSL_SetInternalIV");
10994
10995
        if (ctx == NULL) {
10996
            WOLFSSL_MSG("Bad function argument");
10997
            return WOLFSSL_FATAL_ERROR;
10998
        }
10999
11000
        switch (ctx->cipherType) {
11001
11002
#ifndef NO_AES
11003
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
11004
            case WC_AES_128_CBC_TYPE :
11005
            case WC_AES_192_CBC_TYPE :
11006
            case WC_AES_256_CBC_TYPE :
11007
                WOLFSSL_MSG("AES CBC");
11008
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
11009
                break;
11010
#endif
11011
#ifdef HAVE_AESGCM
11012
            case WC_AES_128_GCM_TYPE :
11013
            case WC_AES_192_GCM_TYPE :
11014
            case WC_AES_256_GCM_TYPE :
11015
                WOLFSSL_MSG("AES GCM");
11016
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
11017
                break;
11018
#endif
11019
#ifdef HAVE_AES_ECB
11020
            case WC_AES_128_ECB_TYPE :
11021
            case WC_AES_192_ECB_TYPE :
11022
            case WC_AES_256_ECB_TYPE :
11023
                WOLFSSL_MSG("AES ECB");
11024
                break;
11025
#endif
11026
#ifdef WOLFSSL_AES_COUNTER
11027
            case WC_AES_128_CTR_TYPE :
11028
            case WC_AES_192_CTR_TYPE :
11029
            case WC_AES_256_CTR_TYPE :
11030
                WOLFSSL_MSG("AES CTR");
11031
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, WC_AES_BLOCK_SIZE);
11032
                break;
11033
#endif
11034
11035
#endif /* NO_AES */
11036
11037
#ifdef HAVE_ARIA
11038
            case WC_ARIA_128_GCM_TYPE :
11039
            case WC_ARIA_192_GCM_TYPE :
11040
            case WC_ARIA_256_GCM_TYPE :
11041
                WOLFSSL_MSG("ARIA GCM");
11042
                XMEMCPY(&ctx->cipher.aria.nonce, ctx->iv, ARIA_BLOCK_SIZE);
11043
                break;
11044
#endif /* HAVE_ARIA */
11045
11046
#ifndef NO_DES3
11047
            case WC_DES_CBC_TYPE :
11048
                WOLFSSL_MSG("DES CBC");
11049
                XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
11050
                break;
11051
11052
            case WC_DES_EDE3_CBC_TYPE :
11053
                WOLFSSL_MSG("DES EDE3 CBC");
11054
                XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
11055
                break;
11056
#endif
11057
#ifdef WOLFSSL_DES_ECB
11058
            case WC_DES_ECB_TYPE :
11059
                WOLFSSL_MSG("DES ECB");
11060
                break;
11061
            case WC_DES_EDE3_ECB_TYPE :
11062
                WOLFSSL_MSG("DES3 ECB");
11063
                break;
11064
#endif
11065
11066
            case WC_ARC4_TYPE :
11067
                WOLFSSL_MSG("ARC4");
11068
                break;
11069
11070
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
11071
            case WC_CHACHA20_POLY1305_TYPE:
11072
                break;
11073
#endif
11074
11075
#ifdef HAVE_CHACHA
11076
            case WC_CHACHA20_TYPE:
11077
                break;
11078
#endif
11079
11080
#ifdef WOLFSSL_SM4_ECB
11081
            case WC_SM4_ECB_TYPE:
11082
                break;
11083
#endif
11084
#ifdef WOLFSSL_SM4_CBC
11085
            case WC_SM4_CBC_TYPE:
11086
                WOLFSSL_MSG("SM4 CBC");
11087
                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
11088
                break;
11089
#endif
11090
#ifdef WOLFSSL_SM4_CTR
11091
            case WC_SM4_CTR_TYPE:
11092
                WOLFSSL_MSG("SM4 CTR");
11093
                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
11094
                break;
11095
#endif
11096
#ifdef WOLFSSL_SM4_GCM
11097
            case WC_SM4_GCM_TYPE:
11098
                WOLFSSL_MSG("SM4 GCM");
11099
                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
11100
                break;
11101
#endif
11102
#ifdef WOLFSSL_SM4_CCM
11103
            case WC_SM4_CCM_TYPE:
11104
                WOLFSSL_MSG("SM4 CCM");
11105
                XMEMCPY(ctx->iv, &ctx->cipher.sm4.iv, ctx->ivSz);
11106
                break;
11107
#endif
11108
11109
            case WC_NULL_CIPHER_TYPE :
11110
                WOLFSSL_MSG("NULL");
11111
                break;
11112
11113
            default: {
11114
                WOLFSSL_MSG("bad type");
11115
                return WOLFSSL_FATAL_ERROR;
11116
            }
11117
        }
11118
        return WOLFSSL_SUCCESS;
11119
    }
11120
11121
#ifndef NO_DES3
11122
11123
void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
11124
                            unsigned char* iv, int len)
11125
{
11126
    (void)len;
11127
11128
    WOLFSSL_MSG("wolfSSL_3des_iv");
11129
11130
    if (ctx == NULL || iv == NULL) {
11131
        WOLFSSL_MSG("Bad function argument");
11132
        return;
11133
    }
11134
11135
    if (doset)
11136
        wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
11137
    else
11138
        XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
11139
}
11140
11141
#endif /* NO_DES3 */
11142
11143
11144
#ifndef NO_AES
11145
11146
void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
11147
                      unsigned char* iv, int len)
11148
{
11149
    (void)len;
11150
11151
    WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
11152
11153
    if (ctx == NULL || iv == NULL) {
11154
        WOLFSSL_MSG("Bad function argument");
11155
        return;
11156
    }
11157
11158
    if (doset)
11159
       (void)wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
11160
    else
11161
        XMEMCPY(iv, &ctx->cipher.aes.reg, WC_AES_BLOCK_SIZE);
11162
}
11163
11164
#endif /* NO_AES */
11165
11166
#endif /* OPENSSL_EXTRA */
11167
11168
/*******************************************************************************
11169
 * END OF EVP_CIPHER API
11170
 ******************************************************************************/
11171
11172
#ifndef NO_CERTS
11173
11174
#define WOLFSSL_X509_STORE_INCLUDED
11175
#include <src/x509_str.c>
11176
11177
#define WOLFSSL_SSL_P7P12_INCLUDED
11178
#include <src/ssl_p7p12.c>
11179
11180
#endif /* !NO_CERTS */
11181
11182
11183
/*******************************************************************************
11184
 * BEGIN OPENSSL FIPS DRBG APIs
11185
 ******************************************************************************/
11186
#if defined(OPENSSL_EXTRA) && !defined(WC_NO_RNG) && defined(HAVE_HASHDRBG)
11187
int wolfSSL_FIPS_drbg_init(WOLFSSL_DRBG_CTX *ctx, int type, unsigned int flags)
11188
{
11189
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11190
    if (ctx != NULL) {
11191
        XMEMSET(ctx, 0, sizeof(WOLFSSL_DRBG_CTX));
11192
        ctx->type = type;
11193
        ctx->xflags = (int)flags;
11194
        ctx->status = DRBG_STATUS_UNINITIALISED;
11195
        ret = WOLFSSL_SUCCESS;
11196
    }
11197
    return ret;
11198
}
11199
WOLFSSL_DRBG_CTX* wolfSSL_FIPS_drbg_new(int type, unsigned int flags)
11200
{
11201
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11202
    WOLFSSL_DRBG_CTX* ctx = (WOLFSSL_DRBG_CTX*)XMALLOC(sizeof(WOLFSSL_DRBG_CTX),
11203
        NULL, DYNAMIC_TYPE_OPENSSL);
11204
    ret = wolfSSL_FIPS_drbg_init(ctx, type, flags);
11205
    if (ret == WOLFSSL_SUCCESS && type != 0) {
11206
        ret = wolfSSL_FIPS_drbg_instantiate(ctx, NULL, 0);
11207
    }
11208
    if (ret != WOLFSSL_SUCCESS) {
11209
        WOLFSSL_ERROR(ret);
11210
        wolfSSL_FIPS_drbg_free(ctx);
11211
        ctx = NULL;
11212
    }
11213
    return ctx;
11214
}
11215
int wolfSSL_FIPS_drbg_instantiate(WOLFSSL_DRBG_CTX* ctx,
11216
    const unsigned char* pers, size_t perslen)
11217
{
11218
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11219
    if (ctx != NULL && ctx->rng == NULL) {
11220
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
11221
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
11222
        ctx->rng = wc_rng_new((byte*)pers, (word32)perslen, NULL);
11223
    #else
11224
        ctx->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
11225
        if (ctx->rng != NULL) {
11226
        #if defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)
11227
            ret = wc_InitRngNonce(ctx->rng, (byte*)pers, (word32)perslen);
11228
        #else
11229
            ret = wc_InitRng(ctx->rng);
11230
            (void)pers;
11231
            (void)perslen;
11232
        #endif
11233
            if (ret != 0) {
11234
                WOLFSSL_ERROR(ret);
11235
                XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
11236
                ctx->rng = NULL;
11237
            }
11238
        }
11239
    #endif
11240
    }
11241
    if (ctx != NULL && ctx->rng != NULL) {
11242
        ctx->status = DRBG_STATUS_READY;
11243
        ret = WOLFSSL_SUCCESS;
11244
    }
11245
    return ret;
11246
}
11247
int wolfSSL_FIPS_drbg_set_callbacks(WOLFSSL_DRBG_CTX* ctx,
11248
    drbg_entropy_get entropy_get, drbg_entropy_clean entropy_clean,
11249
    size_t entropy_blocklen,
11250
    drbg_nonce_get none_get, drbg_nonce_clean nonce_clean)
11251
{
11252
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11253
    if (ctx != NULL) {
11254
        ctx->entropy_get = entropy_get;
11255
        ctx->entropy_clean = entropy_clean;
11256
        ctx->entropy_blocklen = entropy_blocklen;
11257
        ctx->none_get = none_get;
11258
        ctx->nonce_clean = nonce_clean;
11259
        ret = WOLFSSL_SUCCESS;
11260
    }
11261
    return ret;
11262
}
11263
void wolfSSL_FIPS_rand_add(const void* buf, int num, double entropy)
11264
{
11265
    /* not implemented */
11266
    (void)buf;
11267
    (void)num;
11268
    (void)entropy;
11269
}
11270
int wolfSSL_FIPS_drbg_reseed(WOLFSSL_DRBG_CTX* ctx, const unsigned char* adin,
11271
    size_t adinlen)
11272
{
11273
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11274
    if (ctx != NULL && ctx->rng != NULL) {
11275
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
11276
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)))
11277
        if (wc_RNG_DRBG_Reseed(ctx->rng, adin, (word32)adinlen) == 0) {
11278
            ret = WOLFSSL_SUCCESS;
11279
        }
11280
    #else
11281
        ret = WOLFSSL_SUCCESS;
11282
        (void)adin;
11283
        (void)adinlen;
11284
    #endif
11285
    }
11286
    return ret;
11287
}
11288
int wolfSSL_FIPS_drbg_generate(WOLFSSL_DRBG_CTX* ctx, unsigned char* out,
11289
    size_t outlen, int prediction_resistance, const unsigned char* adin,
11290
    size_t adinlen)
11291
{
11292
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
11293
    if (ctx != NULL && ctx->rng != NULL) {
11294
        ret = wc_RNG_GenerateBlock(ctx->rng, out, (word32)outlen);
11295
        if (ret == 0) {
11296
            ret = WOLFSSL_SUCCESS;
11297
        }
11298
    }
11299
    (void)prediction_resistance;
11300
    (void)adin;
11301
    (void)adinlen;
11302
    return ret;
11303
}
11304
int wolfSSL_FIPS_drbg_uninstantiate(WOLFSSL_DRBG_CTX *ctx)
11305
{
11306
    if (ctx != NULL && ctx->rng != NULL) {
11307
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
11308
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
11309
        wc_rng_free(ctx->rng);
11310
    #else
11311
        wc_FreeRng(ctx->rng);
11312
        XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
11313
    #endif
11314
        ctx->rng = NULL;
11315
        ctx->status = DRBG_STATUS_UNINITIALISED;
11316
    }
11317
    return WOLFSSL_SUCCESS;
11318
}
11319
void wolfSSL_FIPS_drbg_free(WOLFSSL_DRBG_CTX *ctx)
11320
{
11321
    if (ctx != NULL) {
11322
        int locked = 0;
11323
        int haveMutex = 1;
11324
        /* As safety check if free'ing the default drbg, then mark global NULL.
11325
         * Technically the user should not call free on the default drbg. */
11326
    #ifndef WOLFSSL_MUTEX_INITIALIZER
11327
        /* wolfSSL_Cleanup may free the mutex before this runs. */
11328
        haveMutex = (globalRNGMutex_valid == 1);
11329
    #endif
11330
        if (haveMutex && (wc_LockMutex(&globalRNGMutex) == 0))
11331
            locked = 1;
11332
        /* Touch the global under the lock, or unlocked only when no mutex. */
11333
        if (locked || !haveMutex) {
11334
            if (ctx == gDrbgDefCtx) {
11335
                gDrbgDefCtx = NULL;
11336
            }
11337
        }
11338
        if (locked)
11339
            wc_UnLockMutex(&globalRNGMutex);
11340
        wolfSSL_FIPS_drbg_uninstantiate(ctx);
11341
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
11342
    }
11343
}
11344
WOLFSSL_DRBG_CTX* wolfSSL_FIPS_get_default_drbg(void)
11345
{
11346
    int locked = 0;
11347
    int haveMutex = 1;
11348
#ifndef WOLFSSL_MUTEX_INITIALIZER
11349
    haveMutex = (globalRNGMutex_valid == 1);
11350
#endif
11351
    if (haveMutex && (wc_LockMutex(&globalRNGMutex) == 0))
11352
        locked = 1;
11353
    if (locked || !haveMutex) {
11354
        if (gDrbgDefCtx == NULL) {
11355
            gDrbgDefCtx = wolfSSL_FIPS_drbg_new(0, 0);
11356
        }
11357
    }
11358
    if (locked)
11359
        wc_UnLockMutex(&globalRNGMutex);
11360
    return gDrbgDefCtx;
11361
}
11362
void wolfSSL_FIPS_get_timevec(unsigned char* buf, unsigned long* pctr)
11363
{
11364
    /* not implemented */
11365
    (void)buf;
11366
    (void)pctr;
11367
}
11368
void* wolfSSL_FIPS_drbg_get_app_data(WOLFSSL_DRBG_CTX *ctx)
11369
{
11370
    if (ctx != NULL) {
11371
        return ctx->app_data;
11372
    }
11373
    return NULL;
11374
}
11375
void wolfSSL_FIPS_drbg_set_app_data(WOLFSSL_DRBG_CTX *ctx, void *app_data)
11376
{
11377
    if (ctx != NULL) {
11378
        ctx->app_data = app_data;
11379
    }
11380
}
11381
#endif
11382
/*******************************************************************************
11383
 * END OF OPENSSL FIPS DRBG APIs
11384
 ******************************************************************************/
11385
11386
11387
#endif /* !WOLFCRYPT_ONLY */