Coverage Report

Created: 2023-11-19 07:14

/src/wolf-ssl-ssh-fuzzers/oss-fuzz/projects/wolf-ssl-ssh/fuzzers/wolfssl/wolfssl/src/ssl.c
Line
Count
Source (jump to first uncovered line)
1
/* ssl.c
2
 *
3
 * Copyright (C) 2006-2023 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 2 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
23
#ifdef HAVE_CONFIG_H
24
    #include <config.h>
25
#endif
26
27
#include <wolfssl/wolfcrypt/settings.h>
28
#if defined(OPENSSL_EXTRA) && !defined(_WIN32)
29
    /* turn on GNU extensions for XISASCII */
30
    #undef  _GNU_SOURCE
31
    #define _GNU_SOURCE
32
#endif
33
34
#if !defined(WOLFCRYPT_ONLY) || defined(OPENSSL_EXTRA) || \
35
    defined(OPENSSL_EXTRA_X509_SMALL)
36
37
#include <wolfssl/internal.h>
38
#include <wolfssl/error-ssl.h>
39
#include <wolfssl/wolfcrypt/coding.h>
40
#include <wolfssl/wolfcrypt/kdf.h>
41
#ifdef NO_INLINE
42
    #include <wolfssl/wolfcrypt/misc.h>
43
#else
44
    #define WOLFSSL_MISC_INCLUDED
45
    #include <wolfcrypt/src/misc.c>
46
#endif
47
48
#ifdef HAVE_ERRNO_H
49
    #include <errno.h>
50
#endif
51
52
53
#if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
54
    #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
55
                && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
56
                && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448)
57
        #error "No cipher suites defined because DH disabled, ECC disabled, 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
    /* openssl headers end, wolfssl internal headers next */
70
#endif
71
72
#include <wolfssl/wolfcrypt/wc_encrypt.h>
73
74
#ifndef NO_RSA
75
    #include <wolfssl/wolfcrypt/rsa.h>
76
#endif
77
78
#ifdef OPENSSL_EXTRA
79
    /* openssl headers begin */
80
    #include <wolfssl/openssl/ssl.h>
81
    #include <wolfssl/openssl/aes.h>
82
#ifndef WOLFCRYPT_ONLY
83
    #include <wolfssl/openssl/hmac.h>
84
    #include <wolfssl/openssl/cmac.h>
85
#endif
86
    #include <wolfssl/openssl/crypto.h>
87
    #include <wolfssl/openssl/des.h>
88
    #include <wolfssl/openssl/bn.h>
89
    #include <wolfssl/openssl/buffer.h>
90
    #include <wolfssl/openssl/dh.h>
91
    #include <wolfssl/openssl/rsa.h>
92
    #include <wolfssl/openssl/fips_rand.h>
93
    #include <wolfssl/openssl/pem.h>
94
    #include <wolfssl/openssl/ec.h>
95
    #include <wolfssl/openssl/ec25519.h>
96
    #include <wolfssl/openssl/ed25519.h>
97
    #include <wolfssl/openssl/ec448.h>
98
    #include <wolfssl/openssl/ed448.h>
99
    #include <wolfssl/openssl/ecdsa.h>
100
    #include <wolfssl/openssl/ecdh.h>
101
    #include <wolfssl/openssl/err.h>
102
    #include <wolfssl/openssl/modes.h>
103
    #include <wolfssl/openssl/opensslv.h>
104
    #include <wolfssl/openssl/rc4.h>
105
    #include <wolfssl/openssl/stack.h>
106
    #include <wolfssl/openssl/x509_vfy.h>
107
    /* openssl headers end, wolfssl internal headers next */
108
    #include <wolfssl/wolfcrypt/hmac.h>
109
    #include <wolfssl/wolfcrypt/random.h>
110
    #include <wolfssl/wolfcrypt/des3.h>
111
    #include <wolfssl/wolfcrypt/ecc.h>
112
    #include <wolfssl/wolfcrypt/md4.h>
113
    #include <wolfssl/wolfcrypt/md5.h>
114
    #include <wolfssl/wolfcrypt/arc4.h>
115
    #include <wolfssl/wolfcrypt/curve25519.h>
116
    #include <wolfssl/wolfcrypt/ed25519.h>
117
    #include <wolfssl/wolfcrypt/curve448.h>
118
    #if defined(HAVE_PQC)
119
    #if defined(HAVE_FALCON)
120
        #include <wolfssl/wolfcrypt/falcon.h>
121
    #endif /* HAVE_FALCON */
122
    #if defined(HAVE_DILITHIUM)
123
        #include <wolfssl/wolfcrypt/dilithium.h>
124
    #endif /* HAVE_DILITHIUM */
125
    #endif /* HAVE_PQC */
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
    #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
141
        #include <wolfssl/wolfcrypt/pkcs7.h>
142
    #endif
143
    #if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
144
        #include <wolfssl/openssl/pkcs7.h>
145
    #endif /* OPENSSL_ALL && HAVE_PKCS7 */
146
#endif
147
148
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
149
    #include <wolfssl/openssl/x509v3.h>
150
    int wolfssl_bn_get_value(WOLFSSL_BIGNUM* bn, mp_int* mpi);
151
    int wolfssl_bn_set_value(WOLFSSL_BIGNUM** bn, mp_int* mpi);
152
#endif
153
154
#if defined(WOLFSSL_QT)
155
    #include <wolfssl/wolfcrypt/sha.h>
156
#endif
157
158
#ifdef NO_ASN
159
    #include <wolfssl/wolfcrypt/dh.h>
160
#endif
161
#endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
162
163
#ifdef WOLFSSL_SYS_CA_CERTS
164
165
#ifdef _WIN32
166
    #include <windows.h>
167
    #include <wincrypt.h>
168
169
    /* mingw gcc does not support pragma comment, and the
170
     * linking with crypt32 is handled in configure.ac */
171
    #if !defined(__MINGW32__) && !defined(__MINGW64__)
172
        #pragma comment(lib, "crypt32")
173
    #endif
174
#endif
175
176
#if defined(__APPLE__) && defined(HAVE_SECURITY_SECTRUSTSETTINGS_H)
177
#include <Security/SecTrustSettings.h>
178
#endif
179
180
#endif /* WOLFSSL_SYS_CA_CERTS */
181
182
/*
183
 * OPENSSL_COMPATIBLE_DEFAULTS:
184
 *     Enable default behaviour that is compatible with OpenSSL. For example
185
 *     SSL_CTX by default doesn't verify the loaded certs. Enabling this
186
 *     should make porting to new projects easier.
187
 * WOLFSSL_CHECK_ALERT_ON_ERR:
188
 *     Check for alerts during the handshake in the event of an error.
189
 * NO_SESSION_CACHE_REF:
190
 *     wolfSSL_get_session on a client will return a reference to the internal
191
 *     ClientCache by default for backwards compatibility. This define will
192
 *     make wolfSSL_get_session return a reference to ssl->session. The returned
193
 *     pointer will be freed with the related WOLFSSL object.
194
 * SESSION_CACHE_DYNAMIC_MEM:
195
 *     Dynamically allocate sessions for the session cache from the heap, as
196
 *     opposed to the default which allocates from the stack.  Allocates
197
 *     memory only when a session is added to the cache, frees memory after the
198
 *     session is no longer being used.  Recommended for memory-constrained
199
 *     systems.
200
 * WOLFSSL_SYS_CA_CERTS
201
 *     Enables ability to load system CA certs from the OS via
202
 *     wolfSSL_CTX_load_system_CA_certs.
203
 */
204
205
#define WOLFSSL_SSL_MISC_INCLUDED
206
#include "src/ssl_misc.c"
207
208
#define WOLFSSL_EVP_INCLUDED
209
#include "wolfcrypt/src/evp.c"
210
211
/* Crypto code uses EVP APIs. */
212
#define WOLFSSL_SSL_CRYPTO_INCLUDED
213
#include "src/ssl_crypto.c"
214
215
#ifndef WOLFCRYPT_ONLY
216
#define WOLFSSL_SSL_CERTMAN_INCLUDED
217
#include "src/ssl_certman.c"
218
#endif
219
220
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
221
    !defined(WOLFCRYPT_ONLY)
222
/* Convert shortname to NID.
223
 *
224
 * For OpenSSL compatibility.
225
 *
226
 * This function shouldn't exist!
227
 * Uses defines in wolfssl/openssl/evp.h.
228
 * Uses EccEnumToNID which uses defines in wolfssl/openssl/ec.h.
229
 *
230
 * @param [in] sn  Short name of OID.
231
 * @return  NID corresponding to shortname on success.
232
 * @return  NID_undef when not recognized.
233
 */
234
int wc_OBJ_sn2nid(const char *sn)
235
0
{
236
0
    const struct {
237
0
        const char *sn;
238
0
        int  nid;
239
0
    } sn2nid[] = {
240
0
#ifndef NO_CERTS
241
0
        {WOLFSSL_COMMON_NAME, NID_commonName},
242
0
        {WOLFSSL_COUNTRY_NAME, NID_countryName},
243
0
        {WOLFSSL_LOCALITY_NAME, NID_localityName},
244
0
        {WOLFSSL_STATE_NAME, NID_stateOrProvinceName},
245
0
        {WOLFSSL_ORG_NAME, NID_organizationName},
246
0
        {WOLFSSL_ORGUNIT_NAME, NID_organizationalUnitName},
247
0
    #ifdef WOLFSSL_CERT_NAME_ALL
248
0
        {WOLFSSL_NAME, NID_name},
249
0
        {WOLFSSL_INITIALS, NID_initials},
250
0
        {WOLFSSL_GIVEN_NAME, NID_givenName},
251
0
        {WOLFSSL_DNQUALIFIER, NID_dnQualifier},
252
0
    #endif
253
0
        {WOLFSSL_EMAIL_ADDR, NID_emailAddress},
254
0
#endif
255
0
        {"SHA1", NID_sha1},
256
0
        {NULL, -1}};
257
0
    int i;
258
0
#ifdef HAVE_ECC
259
0
    char curveName[ECC_MAXNAME + 1];
260
0
    int eccEnum;
261
0
#endif
262
263
0
    WOLFSSL_ENTER("wc_OBJ_sn2nid");
264
265
0
    for(i=0; sn2nid[i].sn != NULL; i++) {
266
0
        if (XSTRCMP(sn, sn2nid[i].sn) == 0) {
267
0
            return sn2nid[i].nid;
268
0
        }
269
0
    }
270
271
0
#ifdef HAVE_ECC
272
0
    if (XSTRLEN(sn) > ECC_MAXNAME)
273
0
        return NID_undef;
274
275
    /* Nginx uses this OpenSSL string. */
276
0
    if (XSTRCMP(sn, "prime256v1") == 0)
277
0
        sn = "SECP256R1";
278
    /* OpenSSL allows lowercase curve names */
279
0
    for (i = 0; i < (int)(sizeof(curveName) - 1) && *sn; i++) {
280
0
        curveName[i] = (char)XTOUPPER((unsigned char) *sn++);
281
0
    }
282
0
    curveName[i] = '\0';
283
    /* find based on name and return NID */
284
0
    for (i = 0;
285
0
#ifndef WOLFSSL_ECC_CURVE_STATIC
286
0
         ecc_sets[i].size != 0 && ecc_sets[i].name != NULL;
287
#else
288
         ecc_sets[i].size != 0;
289
#endif
290
0
         i++) {
291
0
        if (XSTRCMP(curveName, ecc_sets[i].name) == 0) {
292
0
            eccEnum = ecc_sets[i].id;
293
            /* Convert enum value in ecc_curve_id to OpenSSL NID */
294
0
            return EccEnumToNID(eccEnum);
295
0
        }
296
0
    }
297
0
#endif /* HAVE_ECC */
298
299
0
    return NID_undef;
300
0
}
301
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
302
303
#ifndef WOLFCRYPT_ONLY
304
305
#if !defined(NO_RSA) || !defined(NO_DH) || defined(HAVE_ECC) || \
306
    (defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && !defined(NO_DSA))
307
308
#define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
309
static WC_RNG globalRNG;
310
static int initGlobalRNG = 0;
311
312
static wolfSSL_Mutex globalRNGMutex;
313
static int globalRNGMutex_valid = 0;
314
315
#if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
316
static WOLFSSL_DRBG_CTX* gDrbgDefCtx = NULL;
317
#endif
318
319
WC_RNG* wolfssl_get_global_rng(void)
320
1.11k
{
321
1.11k
    WC_RNG* ret = NULL;
322
323
1.11k
    if (initGlobalRNG == 0)
324
1.09k
        WOLFSSL_MSG("Global RNG no Init");
325
27
    else
326
27
        ret = &globalRNG;
327
328
1.11k
    return ret;
329
1.11k
}
330
331
/* Make a global RNG and return.
332
 *
333
 * @return  Global RNG on success.
334
 * @return  NULL on error.
335
 */
336
WC_RNG* wolfssl_make_global_rng(void)
337
0
{
338
0
    WC_RNG* ret;
339
340
0
#ifdef HAVE_GLOBAL_RNG
341
    /* Get the global random number generator instead. */
342
0
    ret = wolfssl_get_global_rng();
343
0
#ifdef OPENSSL_EXTRA
344
0
    if (ret == NULL) {
345
        /* Create a global random if possible. */
346
0
        (void)wolfSSL_RAND_Init();
347
0
        ret = wolfssl_get_global_rng();
348
0
    }
349
0
#endif
350
#else
351
    WOLFSSL_ERROR_MSG("Bad RNG Init");
352
    ret = NULL;
353
#endif
354
355
0
    return ret;
356
0
}
357
358
/* Too many defines to check explicitly - prototype it and always include
359
 * for RSA, DH, ECC and DSA for BN. */
360
WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local);
361
362
/* Make a random number generator or get global if possible.
363
 *
364
 * Global may not be available and NULL will be returned.
365
 *
366
 * @param [in, out] rng    Local random number generator.
367
 * @param [out]     local  Local random number generator returned.
368
 * @return  NULL on failure.
369
 * @return  A random number generator object.
370
 */
371
WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local)
372
354
{
373
354
    WC_RNG* ret = NULL;
374
375
    /* Assume not local until one created. */
376
354
    *local = 0;
377
378
354
#ifdef WOLFSSL_SMALL_STACK
379
    /* Allocate RNG object . */
380
354
    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
381
354
#endif
382
    /* Check we have a local RNG object and initialize. */
383
354
    if ((rng != NULL) && (wc_InitRng(rng) == 0)) {
384
354
        ret = rng;
385
354
        *local = 1;
386
354
    }
387
354
    if (ret == NULL) {
388
0
    #ifdef HAVE_GLOBAL_RNG
389
0
        WOLFSSL_MSG("Bad RNG Init, trying global");
390
0
    #endif
391
0
        ret = wolfssl_make_global_rng();
392
0
    }
393
394
354
    if (ret != rng) {
395
0
#ifdef WOLFSSL_SMALL_STACK
396
0
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
397
0
#endif
398
0
    }
399
400
354
    return ret;
401
354
}
402
#endif
403
404
#ifdef OPENSSL_EXTRA
405
    /* WOLFSSL_NO_OPENSSL_RAND_CB: Allows way to reduce code size for
406
     *                OPENSSL_EXTRA where RAND callbacks are not used */
407
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
408
        static const WOLFSSL_RAND_METHOD* gRandMethods = NULL;
409
        static int gRandMethodsInit = 0;
410
        static wolfSSL_Mutex gRandMethodMutex;
411
    #endif /* !WOLFSSL_NO_OPENSSL_RAND_CB */
412
#endif /* OPENSSL_EXTRA */
413
414
#define WOLFSSL_SSL_BN_INCLUDED
415
#include "src/ssl_bn.c"
416
417
#ifndef OPENSSL_EXTRA_NO_ASN1
418
#define WOLFSSL_SSL_ASN1_INCLUDED
419
#include "src/ssl_asn1.c"
420
#endif /* OPENSSL_EXTRA_NO_ASN1 */
421
422
#define WOLFSSL_PK_INCLUDED
423
#include "src/pk.c"
424
425
#include <wolfssl/wolfcrypt/hpke.h>
426
427
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
428
const WOLF_EC_NIST_NAME kNistCurves[] = {
429
    {XSTR_SIZEOF("P-192"),   "P-192",   NID_X9_62_prime192v1},
430
    {XSTR_SIZEOF("P-256"),   "P-256",   NID_X9_62_prime256v1},
431
    {XSTR_SIZEOF("P-112"),   "P-112",   NID_secp112r1},
432
    {XSTR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2},
433
    {XSTR_SIZEOF("P-128"),   "P-128",   NID_secp128r1},
434
    {XSTR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2},
435
    {XSTR_SIZEOF("P-160"),   "P-160",   NID_secp160r1},
436
    {XSTR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2},
437
    {XSTR_SIZEOF("P-224"),   "P-224",   NID_secp224r1},
438
    {XSTR_SIZEOF("P-384"),   "P-384",   NID_secp384r1},
439
    {XSTR_SIZEOF("P-521"),   "P-521",   NID_secp521r1},
440
    {XSTR_SIZEOF("K-160"),   "K-160",   NID_secp160k1},
441
    {XSTR_SIZEOF("K-192"),   "K-192",   NID_secp192k1},
442
    {XSTR_SIZEOF("K-224"),   "K-224",   NID_secp224k1},
443
    {XSTR_SIZEOF("K-256"),   "K-256",   NID_secp256k1},
444
    {XSTR_SIZEOF("B-160"),   "B-160",   NID_brainpoolP160r1},
445
    {XSTR_SIZEOF("B-192"),   "B-192",   NID_brainpoolP192r1},
446
    {XSTR_SIZEOF("B-224"),   "B-224",   NID_brainpoolP224r1},
447
    {XSTR_SIZEOF("B-256"),   "B-256",   NID_brainpoolP256r1},
448
    {XSTR_SIZEOF("B-320"),   "B-320",   NID_brainpoolP320r1},
449
    {XSTR_SIZEOF("B-384"),   "B-384",   NID_brainpoolP384r1},
450
    {XSTR_SIZEOF("B-512"),   "B-512",   NID_brainpoolP512r1},
451
#ifdef HAVE_PQC
452
    {XSTR_SIZEOF("KYBER_LEVEL1"), "KYBER_LEVEL1", WOLFSSL_KYBER_LEVEL1},
453
    {XSTR_SIZEOF("KYBER_LEVEL3"), "KYBER_LEVEL3", WOLFSSL_KYBER_LEVEL3},
454
    {XSTR_SIZEOF("KYBER_LEVEL5"), "KYBER_LEVEL5", WOLFSSL_KYBER_LEVEL5},
455
#ifdef HAVE_LIBOQS
456
    {XSTR_SIZEOF("P256_KYBER_LEVEL1"), "P256_KYBER_LEVEL1", WOLFSSL_P256_KYBER_LEVEL1},
457
    {XSTR_SIZEOF("P384_KYBER_LEVEL3"), "P384_KYBER_LEVEL3", WOLFSSL_P384_KYBER_LEVEL3},
458
    {XSTR_SIZEOF("P521_KYBER_LEVEL5"), "P521_KYBER_LEVEL5", WOLFSSL_P521_KYBER_LEVEL5},
459
#endif
460
#endif
461
#ifdef WOLFSSL_SM2
462
    {XSTR_SIZEOF("SM2"),     "SM2",     NID_sm2},
463
#endif
464
    {0, NULL, 0},
465
};
466
#endif
467
468
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
469
/* create the hpke key and ech config to send to clients */
470
int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName,
471
    word16 kemId, word16 kdfId, word16 aeadId)
472
{
473
    int ret = 0;
474
    word16 encLen = DHKEM_X25519_ENC_LEN;
475
#ifdef WOLFSSL_SMALL_STACK
476
    Hpke* hpke = NULL;
477
    WC_RNG* rng;
478
#else
479
    Hpke hpke[1];
480
    WC_RNG rng[1];
481
#endif
482
483
    if (ctx == NULL || publicName == NULL)
484
        return BAD_FUNC_ARG;
485
486
#ifdef WOLFSSL_SMALL_STACK
487
    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
488
    if (rng == NULL)
489
        return MEMORY_E;
490
#endif
491
    ret = wc_InitRng(rng);
492
    if (ret != 0) {
493
    #ifdef WOLFSSL_SMALL_STACK
494
        XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
495
    #endif
496
        return ret;
497
    }
498
499
    ctx->echConfigs = (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig),
500
        ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
501
    if (ctx->echConfigs == NULL)
502
        ret = MEMORY_E;
503
    else
504
        XMEMSET(ctx->echConfigs, 0, sizeof(WOLFSSL_EchConfig));
505
506
    /* set random config id */
507
    if (ret == 0)
508
        ret = wc_RNG_GenerateByte(rng, &ctx->echConfigs->configId);
509
510
    /* if 0 is selected for algorithms use default, may change with draft */
511
    if (kemId == 0)
512
        kemId = DHKEM_X25519_HKDF_SHA256;
513
514
    if (kdfId == 0)
515
        kdfId = HKDF_SHA256;
516
517
    if (aeadId == 0)
518
        aeadId = HPKE_AES_128_GCM;
519
520
    if (ret == 0) {
521
        /* set the kem id */
522
        ctx->echConfigs->kemId = kemId;
523
524
        /* set the cipher suite, only 1 for now */
525
        ctx->echConfigs->numCipherSuites = 1;
526
        ctx->echConfigs->cipherSuites = (EchCipherSuite*)XMALLOC(
527
            sizeof(EchCipherSuite), ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
528
529
        if (ctx->echConfigs->cipherSuites == NULL) {
530
            ret = MEMORY_E;
531
        }
532
        else {
533
            ctx->echConfigs->cipherSuites[0].kdfId = kdfId;
534
            ctx->echConfigs->cipherSuites[0].aeadId = aeadId;
535
        }
536
    }
537
538
#ifdef WOLFSSL_SMALL_STACK
539
    if (ret == 0) {
540
        hpke = (Hpke*)XMALLOC(sizeof(Hpke), ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
541
        if (hpke == NULL)
542
            ret = MEMORY_E;
543
    }
544
#endif
545
546
    if (ret == 0)
547
        ret = wc_HpkeInit(hpke, kemId, kdfId, aeadId, ctx->heap);
548
549
    /* generate the receiver private key */
550
    if (ret == 0)
551
        ret = wc_HpkeGenerateKeyPair(hpke, &ctx->echConfigs->receiverPrivkey,
552
            rng);
553
554
    /* done with RNG */
555
    wc_FreeRng(rng);
556
557
    /* serialize the receiver key */
558
    if (ret == 0)
559
        ret = wc_HpkeSerializePublicKey(hpke, ctx->echConfigs->receiverPrivkey,
560
            ctx->echConfigs->receiverPubkey, &encLen);
561
562
    if (ret == 0) {
563
        ctx->echConfigs->publicName = (char*)XMALLOC(XSTRLEN(publicName) + 1,
564
            ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
565
        if (ctx->echConfigs->publicName == NULL) {
566
            ret = MEMORY_E;
567
        }
568
        else {
569
            XMEMCPY(ctx->echConfigs->publicName, publicName,
570
                XSTRLEN(publicName) + 1);
571
        }
572
    }
573
574
    if (ret != 0) {
575
        if (ctx->echConfigs) {
576
            XFREE(ctx->echConfigs->cipherSuites, ctx->heap,
577
                DYNAMIC_TYPE_TMP_BUFFER);
578
            XFREE(ctx->echConfigs->publicName, ctx->heap,
579
                DYNAMIC_TYPE_TMP_BUFFER);
580
            XFREE(ctx->echConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
581
            /* set to null to avoid double free in cleanup */
582
            ctx->echConfigs = NULL;
583
        }
584
    }
585
586
    if (ret == 0)
587
        ret = WOLFSSL_SUCCESS;
588
589
#ifdef WOLFSSL_SMALL_STACK
590
    XFREE(hpke, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
591
    XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
592
#endif
593
594
    return ret;
595
}
596
597
/* get the ech configs that the server context is using */
598
int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output,
599
    word32* outputLen) {
600
    if (ctx == NULL || outputLen == NULL)
601
        return BAD_FUNC_ARG;
602
603
    /* if we don't have ech configs */
604
    if (ctx->echConfigs == NULL) {
605
        return WOLFSSL_FATAL_ERROR;
606
    }
607
608
    return GetEchConfigsEx(ctx->echConfigs, output, outputLen);
609
}
610
611
/* set the ech config from base64 for our client ssl object, base64 is the
612
 * format ech configs are sent using dns records */
613
int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, char* echConfigs64,
614
    word32 echConfigs64Len)
615
{
616
    int ret = 0;
617
    word32 decodedLen = echConfigs64Len * 3 / 4 + 1;
618
    byte* decodedConfigs;
619
620
    if (ssl == NULL || echConfigs64 == NULL || echConfigs64Len == 0)
621
        return BAD_FUNC_ARG;
622
623
    /* already have ech configs */
624
    if (ssl->options.useEch == 1) {
625
        return WOLFSSL_FATAL_ERROR;
626
    }
627
628
    decodedConfigs = (byte*)XMALLOC(decodedLen, ssl->heap,
629
        DYNAMIC_TYPE_TMP_BUFFER);
630
631
    if (decodedConfigs == NULL)
632
        return MEMORY_E;
633
634
    decodedConfigs[decodedLen - 1] = 0;
635
636
    /* decode the echConfigs */
637
    ret = Base64_Decode((byte*)echConfigs64, echConfigs64Len,
638
      decodedConfigs, &decodedLen);
639
640
    if (ret != 0) {
641
        XFREE(decodedConfigs, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
642
        return ret;
643
    }
644
645
    ret = wolfSSL_SetEchConfigs(ssl, decodedConfigs, decodedLen);
646
647
    XFREE(decodedConfigs, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
648
649
    return ret;
650
}
651
652
/* set the ech config from a raw buffer, this is the format ech configs are
653
 * sent using retry_configs from the ech server */
654
int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs,
655
  word32 echConfigsLen)
656
{
657
    int ret = 0;
658
    int i;
659
    int j;
660
    word16 totalLength;
661
    word16 version;
662
    word16 length;
663
    word16 hpkePubkeyLen;
664
    word16 cipherSuitesLen;
665
    word16 publicNameLen;
666
    WOLFSSL_EchConfig* configList = NULL;
667
    WOLFSSL_EchConfig* workingConfig = NULL;
668
    WOLFSSL_EchConfig* lastConfig = NULL;
669
    byte* echConfig = NULL;
670
671
    if (ssl == NULL || echConfigs == NULL || echConfigsLen == 0)
672
        return BAD_FUNC_ARG;
673
674
    /* already have ech configs */
675
    if (ssl->options.useEch == 1) {
676
        return WOLFSSL_FATAL_ERROR;
677
    }
678
679
    /* check that the total length is well formed */
680
    ato16(echConfigs, &totalLength);
681
682
    if (totalLength != echConfigsLen - 2) {
683
        return WOLFSSL_FATAL_ERROR;
684
    }
685
686
    /* skip the total length uint16_t */
687
    i = 2;
688
689
    do {
690
        echConfig = (byte*)echConfigs + i;
691
        ato16(echConfig, &version);
692
        ato16(echConfig + 2, &length);
693
694
        /* if the version does not match */
695
        if (version != TLSX_ECH) {
696
            /* we hit the end of the configs */
697
            if ( (word32)i + 2 >= echConfigsLen ) {
698
                break;
699
            }
700
701
            /* skip this config, +4 for version and length */
702
            i += length + 4;
703
            continue;
704
        }
705
706
        /* check if the length will overrun the buffer */
707
        if ((word32)i + length + 4 > echConfigsLen) {
708
            break;
709
        }
710
711
        if (workingConfig == NULL) {
712
            workingConfig =
713
                (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig),
714
                ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
715
            configList = workingConfig;
716
            if (workingConfig != NULL) {
717
                workingConfig->next = NULL;
718
            }
719
        }
720
        else {
721
            lastConfig = workingConfig;
722
            workingConfig->next =
723
                (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig),
724
                ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
725
            workingConfig = workingConfig->next;
726
        }
727
728
        if (workingConfig == NULL) {
729
            ret = MEMORY_E;
730
            break;
731
        }
732
733
        XMEMSET(workingConfig, 0, sizeof(WOLFSSL_EchConfig));
734
735
        /* rawLen */
736
        workingConfig->rawLen = length + 4;
737
738
        /* raw body */
739
        workingConfig->raw = (byte*)XMALLOC(workingConfig->rawLen,
740
            ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
741
        if (workingConfig->raw == NULL) {
742
            ret = MEMORY_E;
743
            break;
744
        }
745
746
        XMEMCPY(workingConfig->raw, echConfig, workingConfig->rawLen);
747
748
        /* skip over version and length */
749
        echConfig += 4;
750
751
        /* configId, 1 byte */
752
        workingConfig->configId = *(echConfig);
753
        echConfig++;
754
        /* kemId, 2 bytes */
755
        ato16(echConfig, &workingConfig->kemId);
756
        echConfig += 2;
757
        /* hpke public_key length, 2 bytes */
758
        ato16(echConfig, &hpkePubkeyLen);
759
        echConfig += 2;
760
        /* hpke public_key */
761
        XMEMCPY(workingConfig->receiverPubkey, echConfig, hpkePubkeyLen);
762
        echConfig += hpkePubkeyLen;
763
        /* cipherSuitesLen */
764
        ato16(echConfig, &cipherSuitesLen);
765
766
        workingConfig->cipherSuites = (EchCipherSuite*)XMALLOC(cipherSuitesLen,
767
            ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
768
        if (workingConfig->cipherSuites == NULL) {
769
            ret = MEMORY_E;
770
            break;
771
        }
772
773
        echConfig += 2;
774
        workingConfig->numCipherSuites = cipherSuitesLen / 4;
775
        /* cipherSuites */
776
        for (j = 0; j < workingConfig->numCipherSuites; j++) {
777
            ato16(echConfig + j * 4, &workingConfig->cipherSuites[j].kdfId);
778
            ato16(echConfig + j * 4 + 2,
779
                &workingConfig->cipherSuites[j].aeadId);
780
        }
781
        echConfig += cipherSuitesLen;
782
        /* publicNameLen */
783
        ato16(echConfig, &publicNameLen);
784
        workingConfig->publicName = (char*)XMALLOC(publicNameLen + 1,
785
            ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
786
        if (workingConfig->publicName == NULL) {
787
            ret = MEMORY_E;
788
            break;
789
        }
790
791
        echConfig += 2;
792
        /* publicName */
793
        XMEMCPY(workingConfig->publicName, echConfig, publicNameLen);
794
        /* null terminated */
795
        workingConfig->publicName[publicNameLen] = 0;
796
797
        /* add length to go to next config, +4 for version and length */
798
        i += length + 4;
799
800
        /* check that we support this config */
801
        for (j = 0; j < HPKE_SUPPORTED_KEM_LEN; j++) {
802
            if (hpkeSupportedKem[j] == workingConfig->kemId)
803
                break;
804
        }
805
806
        /* if we don't support the kem or at least one cipher suite */
807
        if (j >= HPKE_SUPPORTED_KEM_LEN ||
808
            EchConfigGetSupportedCipherSuite(workingConfig) < 0)
809
        {
810
            XFREE(workingConfig->cipherSuites, ssl->heap,
811
                DYNAMIC_TYPE_TMP_BUFFER);
812
            XFREE(workingConfig->publicName, ssl->heap,
813
                DYNAMIC_TYPE_TMP_BUFFER);
814
            XFREE(workingConfig->raw, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
815
            workingConfig = lastConfig;
816
        }
817
    } while ((word32)i < echConfigsLen);
818
819
    /* if we found valid configs */
820
    if (ret == 0 && configList != NULL) {
821
        ssl->options.useEch = 1;
822
        ssl->echConfigs = configList;
823
824
        return WOLFSSL_SUCCESS;
825
    }
826
827
    workingConfig = configList;
828
829
    while (workingConfig != NULL) {
830
        lastConfig = workingConfig;
831
        workingConfig = workingConfig->next;
832
833
        XFREE(lastConfig->cipherSuites, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
834
        XFREE(lastConfig->publicName, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
835
        XFREE(lastConfig->raw, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
836
837
        XFREE(lastConfig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
838
    }
839
840
    if (ret == 0)
841
        return WOLFSSL_FATAL_ERROR;
842
843
    return ret;
844
}
845
846
/* get the raw ech config from our struct */
847
int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
848
{
849
    int i;
850
    word16 totalLen = 0;
851
852
    if (config == NULL || (output == NULL && outputLen == NULL))
853
        return BAD_FUNC_ARG;
854
855
    /* 2 for version */
856
    totalLen += 2;
857
    /* 2 for length */
858
    totalLen += 2;
859
    /* 1 for configId */
860
    totalLen += 1;
861
    /* 2 for kemId */
862
    totalLen += 2;
863
    /* 2 for hpke_len */
864
    totalLen += 2;
865
866
    /* hpke_pub_key */
867
    switch (config->kemId) {
868
        case DHKEM_P256_HKDF_SHA256:
869
            totalLen += DHKEM_P256_ENC_LEN;
870
            break;
871
        case DHKEM_P384_HKDF_SHA384:
872
            totalLen += DHKEM_P384_ENC_LEN;
873
            break;
874
        case DHKEM_P521_HKDF_SHA512:
875
            totalLen += DHKEM_P521_ENC_LEN;
876
            break;
877
        case DHKEM_X25519_HKDF_SHA256:
878
            totalLen += DHKEM_X25519_ENC_LEN;
879
            break;
880
        case DHKEM_X448_HKDF_SHA512:
881
            totalLen += DHKEM_X448_ENC_LEN;
882
            break;
883
    }
884
885
    /* cipherSuitesLen */
886
    totalLen += 2;
887
    /* cipherSuites */
888
    totalLen += config->numCipherSuites * 4;
889
    /* public name len */
890
    totalLen += 2;
891
892
    /* public name */
893
    totalLen += XSTRLEN(config->publicName);
894
    /* trailing zeros */
895
    totalLen += 2;
896
897
    if (output == NULL) {
898
        *outputLen = totalLen;
899
        return LENGTH_ONLY_E;
900
    }
901
902
    if (totalLen > *outputLen) {
903
        *outputLen = totalLen;
904
        return INPUT_SIZE_E;
905
    }
906
907
    /* version */
908
    c16toa(TLSX_ECH, output);
909
    output += 2;
910
911
    /* length - 4 for version and length itself */
912
    c16toa(totalLen - 4, output);
913
    output += 2;
914
915
    /* configId */
916
    *output = config->configId;
917
    output++;
918
    /* kemId */
919
    c16toa(config->kemId, output);
920
    output += 2;
921
922
    /* length and key itself */
923
    switch (config->kemId) {
924
        case DHKEM_P256_HKDF_SHA256:
925
            c16toa(DHKEM_P256_ENC_LEN, output);
926
            output += 2;
927
            XMEMCPY(output, config->receiverPubkey, DHKEM_P256_ENC_LEN);
928
            output += DHKEM_P256_ENC_LEN;
929
            break;
930
        case DHKEM_P384_HKDF_SHA384:
931
            c16toa(DHKEM_P384_ENC_LEN, output);
932
            output += 2;
933
            XMEMCPY(output, config->receiverPubkey, DHKEM_P384_ENC_LEN);
934
            output += DHKEM_P384_ENC_LEN;
935
            break;
936
        case DHKEM_P521_HKDF_SHA512:
937
            c16toa(DHKEM_P521_ENC_LEN, output);
938
            output += 2;
939
            XMEMCPY(output, config->receiverPubkey, DHKEM_P521_ENC_LEN);
940
            output += DHKEM_P521_ENC_LEN;
941
            break;
942
        case DHKEM_X25519_HKDF_SHA256:
943
            c16toa(DHKEM_X25519_ENC_LEN, output);
944
            output += 2;
945
            XMEMCPY(output, config->receiverPubkey, DHKEM_X25519_ENC_LEN);
946
            output += DHKEM_X25519_ENC_LEN;
947
            break;
948
        case DHKEM_X448_HKDF_SHA512:
949
            c16toa(DHKEM_X448_ENC_LEN, output);
950
            output += 2;
951
            XMEMCPY(output, config->receiverPubkey, DHKEM_X448_ENC_LEN);
952
            output += DHKEM_X448_ENC_LEN;
953
            break;
954
    }
955
956
    /* cipherSuites len */
957
    c16toa(config->numCipherSuites * 4, output);
958
    output += 2;
959
960
    /* cipherSuites */
961
    for (i = 0; i < config->numCipherSuites; i++) {
962
        c16toa(config->cipherSuites[i].kdfId, output);
963
        output += 2;
964
        c16toa(config->cipherSuites[i].aeadId, output);
965
        output += 2;
966
    }
967
968
    /* publicName len */
969
    c16toa(XSTRLEN(config->publicName), output);
970
    output += 2;
971
972
    /* publicName */
973
    XMEMCPY(output, config->publicName,
974
        XSTRLEN(config->publicName));
975
    output += XSTRLEN(config->publicName);
976
977
    /* terminating zeros */
978
    c16toa(0, output);
979
    /* output += 2; */
980
981
    *outputLen = totalLen;
982
983
    return 0;
984
}
985
986
/* wrapper function to get ech configs from application code */
987
int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* output, word32* outputLen)
988
{
989
    if (ssl == NULL || outputLen == NULL)
990
        return BAD_FUNC_ARG;
991
992
    /* if we don't have ech configs */
993
    if (ssl->options.useEch != 1) {
994
        return WOLFSSL_FATAL_ERROR;
995
    }
996
997
    return GetEchConfigsEx(ssl->echConfigs, output, outputLen);
998
}
999
1000
/* get the raw ech configs from our linked list of ech config structs */
1001
int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen)
1002
{
1003
    int ret = 0;
1004
    WOLFSSL_EchConfig* workingConfig = NULL;
1005
    byte* outputStart = output;
1006
    word32 totalLen = 2;
1007
    word32 workingOutputLen;
1008
1009
    if (configs == NULL || outputLen == NULL)
1010
        return BAD_FUNC_ARG;
1011
1012
    workingOutputLen = *outputLen - totalLen;
1013
1014
    /* skip over total length which we fill in later */
1015
    if (output != NULL)
1016
        output += 2;
1017
1018
    workingConfig = configs;
1019
1020
    while (workingConfig != NULL) {
1021
        /* get this config */
1022
        ret = GetEchConfig(workingConfig, output, &workingOutputLen);
1023
1024
        if (output != NULL)
1025
            output += workingOutputLen;
1026
1027
        /* add this config's length to the total length */
1028
        totalLen += workingOutputLen;
1029
1030
        if (totalLen > *outputLen)
1031
            workingOutputLen = 0;
1032
        else
1033
            workingOutputLen = *outputLen - totalLen;
1034
1035
        /* only error we break on, other 2 we need to keep finding length */
1036
        if (ret == BAD_FUNC_ARG)
1037
            return BAD_FUNC_ARG;
1038
1039
        workingConfig = workingConfig->next;
1040
    }
1041
1042
    if (output == NULL) {
1043
        *outputLen = totalLen;
1044
        return LENGTH_ONLY_E;
1045
    }
1046
1047
    if (totalLen > *outputLen) {
1048
        *outputLen = totalLen;
1049
        return INPUT_SIZE_E;
1050
    }
1051
1052
    /* total size -2 for size itself */
1053
    c16toa(totalLen - 2, outputStart);
1054
1055
    *outputLen = totalLen;
1056
1057
    return WOLFSSL_SUCCESS;
1058
}
1059
#endif /* WOLFSSL_TLS13 && HAVE_ECH */
1060
1061
1062
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_FSPSM_TLS)
1063
#include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
1064
#endif
1065
1066
#ifdef WOLFSSL_SESSION_EXPORT
1067
/* Used to import a serialized TLS session.
1068
 * WARNING: buf contains sensitive information about the state and is best to be
1069
 *          encrypted before storing if stored.
1070
 *
1071
 * @param ssl WOLFSSL structure to import the session into
1072
 * @param buf serialized session
1073
 * @param sz  size of buffer 'buf'
1074
 * @return the number of bytes read from buffer 'buf'
1075
 */
1076
int wolfSSL_tls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
1077
{
1078
    if (ssl == NULL || buf == NULL) {
1079
        return BAD_FUNC_ARG;
1080
    }
1081
    return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
1082
}
1083
1084
1085
/* Used to export a serialized TLS session.
1086
 * WARNING: buf contains sensitive information about the state and is best to be
1087
 *          encrypted before storing if stored.
1088
 *
1089
 * @param ssl WOLFSSL structure to export the session from
1090
 * @param buf output of serialized session
1091
 * @param sz  size in bytes set in 'buf'
1092
 * @return the number of bytes written into buffer 'buf'
1093
 */
1094
int wolfSSL_tls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
1095
{
1096
    if (ssl == NULL || sz == NULL) {
1097
        return BAD_FUNC_ARG;
1098
    }
1099
    return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
1100
}
1101
1102
#ifdef WOLFSSL_DTLS
1103
int wolfSSL_dtls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
1104
{
1105
    WOLFSSL_ENTER("wolfSSL_session_import");
1106
1107
    if (ssl == NULL || buf == NULL) {
1108
        return BAD_FUNC_ARG;
1109
    }
1110
1111
    /* sanity checks on buffer and protocol are done in internal function */
1112
    return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
1113
}
1114
1115
1116
/* Sets the function to call for serializing the session. This function is
1117
 * called right after the handshake is completed. */
1118
int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func)
1119
{
1120
1121
    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_export");
1122
1123
    /* purposefully allow func to be NULL */
1124
    if (ctx == NULL) {
1125
        return BAD_FUNC_ARG;
1126
    }
1127
1128
    ctx->dtls_export = func;
1129
1130
    return WOLFSSL_SUCCESS;
1131
}
1132
1133
1134
/* Sets the function in WOLFSSL struct to call for serializing the session. This
1135
 * function is called right after the handshake is completed. */
1136
int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
1137
{
1138
1139
    WOLFSSL_ENTER("wolfSSL_dtls_set_export");
1140
1141
    /* purposefully allow func to be NULL */
1142
    if (ssl == NULL) {
1143
        return BAD_FUNC_ARG;
1144
    }
1145
1146
    ssl->dtls_export = func;
1147
1148
    return WOLFSSL_SUCCESS;
1149
}
1150
1151
1152
/* This function allows for directly serializing a session rather than using
1153
 * callbacks. It has less overhead by removing a temporary buffer and gives
1154
 * control over when the session gets serialized. When using callbacks the
1155
 * session is always serialized immediately after the handshake is finished.
1156
 *
1157
 * buf is the argument to contain the serialized session
1158
 * sz  is the size of the buffer passed in
1159
 * ssl is the WOLFSSL struct to serialize
1160
 * returns the size of serialized session on success, 0 on no action, and
1161
 *         negative value on error */
1162
int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
1163
{
1164
    WOLFSSL_ENTER("wolfSSL_dtls_export");
1165
1166
    if (ssl == NULL || sz == NULL) {
1167
        return BAD_FUNC_ARG;
1168
    }
1169
1170
    if (buf == NULL) {
1171
        *sz = MAX_EXPORT_BUFFER;
1172
        return 0;
1173
    }
1174
1175
    /* if not DTLS do nothing */
1176
    if (!ssl->options.dtls) {
1177
        WOLFSSL_MSG("Currently only DTLS export is supported");
1178
        return 0;
1179
    }
1180
1181
    /* copy over keys, options, and dtls state struct */
1182
    return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
1183
}
1184
1185
1186
/* This function is similar to wolfSSL_dtls_export but only exports the portion
1187
 * of the WOLFSSL structure related to the state of the connection, i.e. peer
1188
 * sequence number, epoch, AEAD state etc.
1189
 *
1190
 * buf is the argument to contain the serialized state, if null then set "sz" to
1191
 *     buffer size required
1192
 * sz  is the size of the buffer passed in
1193
 * ssl is the WOLFSSL struct to serialize
1194
 * returns the size of serialized session on success, 0 on no action, and
1195
 *         negative value on error */
1196
int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf,
1197
        unsigned int* sz)
1198
{
1199
    WOLFSSL_ENTER("wolfSSL_dtls_export_state_only");
1200
1201
    if (ssl == NULL || sz == NULL) {
1202
        return BAD_FUNC_ARG;
1203
    }
1204
1205
    if (buf == NULL) {
1206
        *sz = MAX_EXPORT_STATE_BUFFER;
1207
        return 0;
1208
    }
1209
1210
    /* if not DTLS do nothing */
1211
    if (!ssl->options.dtls) {
1212
        WOLFSSL_MSG("Currently only DTLS export state is supported");
1213
        return 0;
1214
    }
1215
1216
    /* copy over keys, options, and dtls state struct */
1217
    return wolfSSL_dtls_export_state_internal(ssl, buf, *sz);
1218
}
1219
1220
1221
/* returns 0 on success */
1222
int wolfSSL_send_session(WOLFSSL* ssl)
1223
{
1224
    int ret;
1225
    byte* buf;
1226
    word32 bufSz = MAX_EXPORT_BUFFER;
1227
1228
    WOLFSSL_ENTER("wolfSSL_send_session");
1229
1230
    if (ssl == NULL) {
1231
        return BAD_FUNC_ARG;
1232
    }
1233
1234
    buf = (byte*)XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1235
    if (buf == NULL) {
1236
        return MEMORY_E;
1237
    }
1238
1239
    /* if not DTLS do nothing */
1240
    if (!ssl->options.dtls) {
1241
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1242
        WOLFSSL_MSG("Currently only DTLS export is supported");
1243
        return 0;
1244
    }
1245
1246
    /* copy over keys, options, and dtls state struct */
1247
    ret = wolfSSL_session_export_internal(ssl, buf, &bufSz, WOLFSSL_EXPORT_DTLS);
1248
    if (ret < 0) {
1249
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1250
        return ret;
1251
    }
1252
1253
    /* if no error ret has size of buffer */
1254
    ret = ssl->dtls_export(ssl, buf, ret, NULL);
1255
    if (ret != WOLFSSL_SUCCESS) {
1256
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1257
        return ret;
1258
    }
1259
1260
    XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
1261
    return 0;
1262
}
1263
#endif /* WOLFSSL_DTLS */
1264
#endif /* WOLFSSL_SESSION_EXPORT */
1265
1266
/* prevent multiple mutex initializations */
1267
static volatile WOLFSSL_GLOBAL int initRefCount = 0;
1268
static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex;   /* init ref count mutex */
1269
static WOLFSSL_GLOBAL int count_mutex_valid = 0;
1270
1271
/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
1272
   WOLFSSL_METHOD pointer passed in is given to ctx to manage.
1273
   This function frees the passed in WOLFSSL_METHOD struct on failure and on
1274
   success is freed when ctx is freed.
1275
 */
1276
WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
1277
48
{
1278
48
    WOLFSSL_CTX* ctx = NULL;
1279
1280
48
    WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
1281
1282
48
    if (initRefCount == 0) {
1283
        /* user no longer forced to call Init themselves */
1284
0
        int ret = wolfSSL_Init();
1285
0
        if (ret != WOLFSSL_SUCCESS) {
1286
0
            WOLFSSL_MSG("wolfSSL_Init failed");
1287
0
            WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
1288
0
            if (method != NULL) {
1289
0
                XFREE(method, heap, DYNAMIC_TYPE_METHOD);
1290
0
            }
1291
0
            return NULL;
1292
0
        }
1293
0
    }
1294
1295
48
    if (method == NULL)
1296
0
        return ctx;
1297
1298
48
    ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
1299
48
    if (ctx) {
1300
48
        int ret;
1301
1302
48
        ret = InitSSL_Ctx(ctx, method, heap);
1303
    #ifdef WOLFSSL_STATIC_MEMORY
1304
        if (heap != NULL) {
1305
            ctx->onHeapHint = 1; /* free the memory back to heap when done */
1306
        }
1307
    #endif
1308
48
        if (ret < 0) {
1309
0
            WOLFSSL_MSG("Init CTX failed");
1310
0
            wolfSSL_CTX_free(ctx);
1311
0
            ctx = NULL;
1312
0
        }
1313
48
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
1314
48
                           && !defined(NO_SHA256) && !defined(WC_NO_RNG)
1315
48
        else {
1316
48
            ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
1317
48
            if (ctx->srp == NULL){
1318
0
                WOLFSSL_MSG("Init CTX failed");
1319
0
                wolfSSL_CTX_free(ctx);
1320
0
                return NULL;
1321
0
            }
1322
48
            XMEMSET(ctx->srp, 0, sizeof(Srp));
1323
48
        }
1324
48
#endif
1325
48
    }
1326
0
    else {
1327
0
        WOLFSSL_MSG("Alloc CTX failed, method freed");
1328
0
        XFREE(method, heap, DYNAMIC_TYPE_METHOD);
1329
0
    }
1330
1331
#ifdef OPENSSL_COMPATIBLE_DEFAULTS
1332
    if (ctx) {
1333
        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
1334
        wolfSSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
1335
        if (wolfSSL_CTX_set_min_proto_version(ctx,
1336
                                              (method->version.major == DTLS_MAJOR) ?
1337
                                               DTLS1_VERSION : SSL3_VERSION) != WOLFSSL_SUCCESS ||
1338
#ifdef HAVE_ANON
1339
                wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS ||
1340
#endif
1341
                wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS) {
1342
            WOLFSSL_MSG("Setting OpenSSL CTX defaults failed");
1343
            wolfSSL_CTX_free(ctx);
1344
            ctx = NULL;
1345
        }
1346
    }
1347
#endif
1348
1349
48
    WOLFSSL_LEAVE("wolfSSL_CTX_new_ex", 0);
1350
48
    return ctx;
1351
48
}
1352
1353
1354
WOLFSSL_ABI
1355
WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
1356
3.71k
{
1357
#ifdef WOLFSSL_HEAP_TEST
1358
    /* if testing the heap hint then set top level CTX to have test value */
1359
    return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
1360
#else
1361
3.71k
    return wolfSSL_CTX_new_ex(method, NULL);
1362
3.71k
#endif
1363
3.71k
}
1364
1365
/* increases CTX reference count to track proper time to "free" */
1366
int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
1367
78.4k
{
1368
78.4k
    int ret;
1369
78.4k
    wolfSSL_RefInc(&ctx->ref, &ret);
1370
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
1371
    return ((ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
1372
#else
1373
78.4k
    (void)ret;
1374
78.4k
    return WOLFSSL_SUCCESS;
1375
78.4k
#endif
1376
78.4k
}
1377
1378
WOLFSSL_ABI
1379
void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
1380
{
1381
    WOLFSSL_ENTER("wolfSSL_CTX_free");
1382
    if (ctx) {
1383
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
1384
&& !defined(NO_SHA256) && !defined(WC_NO_RNG)
1385
        if (ctx->srp != NULL) {
1386
            if (ctx->srp_password != NULL){
1387
                XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
1388
                ctx->srp_password = NULL;
1389
            }
1390
            wc_SrpTerm(ctx->srp);
1391
            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
1392
            ctx->srp = NULL;
1393
        }
1394
#endif
1395
        FreeSSL_Ctx(ctx);
1396
    }
1397
1398
    WOLFSSL_LEAVE("wolfSSL_CTX_free", 0);
1399
}
1400
1401
1402
#ifdef HAVE_ENCRYPT_THEN_MAC
1403
/**
1404
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
1405
 * The default value: enabled.
1406
 *
1407
 * ctx  SSL/TLS context.
1408
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
1409
 * returns WOLFSSL_SUCCESS
1410
 */
1411
int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
1412
0
{
1413
0
    ctx->disallowEncThenMac = !set;
1414
0
    return WOLFSSL_SUCCESS;
1415
0
}
1416
1417
/**
1418
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
1419
 * The default value comes from context.
1420
 *
1421
 * ctx  SSL/TLS context.
1422
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
1423
 * returns WOLFSSL_SUCCESS
1424
 */
1425
int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
1426
0
{
1427
0
    ssl->options.disallowEncThenMac = !set;
1428
0
    return WOLFSSL_SUCCESS;
1429
0
}
1430
#endif
1431
1432
#ifdef SINGLE_THREADED
1433
/* no locking in single threaded mode, allow a CTX level rng to be shared with
1434
 * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
1435
int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
1436
{
1437
    WC_RNG* rng;
1438
    int     ret;
1439
1440
    if (ctx == NULL) {
1441
        return BAD_FUNC_ARG;
1442
    }
1443
1444
    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
1445
    if (rng == NULL) {
1446
        return MEMORY_E;
1447
    }
1448
1449
#ifndef HAVE_FIPS
1450
    ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
1451
#else
1452
    ret = wc_InitRng(rng);
1453
#endif
1454
    if (ret != 0) {
1455
        XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
1456
        return ret;
1457
    }
1458
1459
    ctx->rng = rng;
1460
    return WOLFSSL_SUCCESS;
1461
}
1462
#endif
1463
1464
1465
WOLFSSL_ABI
1466
WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
1467
78.6k
{
1468
78.6k
    WOLFSSL* ssl = NULL;
1469
78.6k
    int ret = 0;
1470
1471
78.6k
    WOLFSSL_ENTER("wolfSSL_new");
1472
1473
78.6k
    if (ctx == NULL)
1474
0
        return ssl;
1475
1476
78.6k
    ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
1477
78.6k
    if (ssl)
1478
78.6k
        if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
1479
1.92k
            FreeSSL(ssl, ctx->heap);
1480
1.92k
            ssl = 0;
1481
1.92k
        }
1482
1483
78.6k
    WOLFSSL_LEAVE("wolfSSL_new", ret);
1484
78.6k
    (void)ret;
1485
1486
78.6k
    return ssl;
1487
78.6k
}
1488
1489
1490
WOLFSSL_ABI
1491
void wolfSSL_free(WOLFSSL* ssl)
1492
76.8k
{
1493
76.8k
    WOLFSSL_ENTER("wolfSSL_free");
1494
76.8k
    if (ssl)
1495
76.7k
        FreeSSL(ssl, ssl->ctx->heap);
1496
76.8k
    WOLFSSL_LEAVE("wolfSSL_free", 0);
1497
76.8k
}
1498
1499
1500
int wolfSSL_is_server(WOLFSSL* ssl)
1501
0
{
1502
0
    if (ssl == NULL)
1503
0
        return BAD_FUNC_ARG;
1504
0
    return ssl->options.side == WOLFSSL_SERVER_END;
1505
0
}
1506
1507
#ifdef HAVE_WRITE_DUP
1508
1509
/*
1510
 * Release resources around WriteDup object
1511
 *
1512
 * ssl WOLFSSL object
1513
 *
1514
 * no return, destruction so make best attempt
1515
*/
1516
void FreeWriteDup(WOLFSSL* ssl)
1517
{
1518
    int doFree = 0;
1519
1520
    WOLFSSL_ENTER("FreeWriteDup");
1521
1522
    if (ssl->dupWrite) {
1523
        if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
1524
            ssl->dupWrite->dupCount--;
1525
            if (ssl->dupWrite->dupCount == 0) {
1526
                doFree = 1;
1527
            } else {
1528
                WOLFSSL_MSG("WriteDup count not zero, no full free");
1529
            }
1530
            wc_UnLockMutex(&ssl->dupWrite->dupMutex);
1531
        }
1532
    }
1533
1534
    if (doFree) {
1535
        WOLFSSL_MSG("Doing WriteDup full free, count to zero");
1536
        wc_FreeMutex(&ssl->dupWrite->dupMutex);
1537
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
1538
    }
1539
}
1540
1541
1542
/*
1543
 * duplicate existing ssl members into dup needed for writing
1544
 *
1545
 * dup write only WOLFSSL
1546
 * ssl existing WOLFSSL
1547
 *
1548
 * 0 on success
1549
*/
1550
static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
1551
{
1552
    word16 tmp_weOwnRng;
1553
1554
    /* shared dupWrite setup */
1555
    ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
1556
                                       DYNAMIC_TYPE_WRITEDUP);
1557
    if (ssl->dupWrite == NULL) {
1558
        return MEMORY_E;
1559
    }
1560
    XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
1561
1562
    if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
1563
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
1564
        ssl->dupWrite = NULL;
1565
        return BAD_MUTEX_E;
1566
    }
1567
    ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
1568
    dup->dupWrite = ssl->dupWrite; /* each side uses */
1569
1570
    tmp_weOwnRng = dup->options.weOwnRng;
1571
1572
    /* copy write parts over to dup writer */
1573
    XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
1574
    XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
1575
    XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
1576
    XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
1577
    XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion));
1578
    XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion));
1579
1580
    /* dup side now owns encrypt/write ciphers */
1581
    XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
1582
1583
    dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
1584
    dup->CBIOSend = ssl->CBIOSend;
1585
#ifdef OPENSSL_EXTRA
1586
    dup->cbioFlag = ssl->cbioFlag;
1587
#endif
1588
    dup->wfd    = ssl->wfd;
1589
    dup->wflags = ssl->wflags;
1590
#ifndef WOLFSSL_AEAD_ONLY
1591
    dup->hmac   = ssl->hmac;
1592
#endif
1593
#ifdef HAVE_TRUNCATED_HMAC
1594
    dup->truncated_hmac = ssl->truncated_hmac;
1595
#endif
1596
1597
    /* Restore rng option */
1598
    dup->options.weOwnRng = tmp_weOwnRng;
1599
1600
    /* unique side dup setup */
1601
    dup->dupSide = WRITE_DUP_SIDE;
1602
    ssl->dupSide = READ_DUP_SIDE;
1603
1604
    return 0;
1605
}
1606
1607
1608
/*
1609
 * duplicate a WOLFSSL object post handshake for writing only
1610
 * turn existing object into read only.  Allows concurrent access from two
1611
 * different threads.
1612
 *
1613
 * ssl existing WOLFSSL object
1614
 *
1615
 * return dup'd WOLFSSL object on success
1616
*/
1617
WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
1618
{
1619
    WOLFSSL* dup = NULL;
1620
    int ret = 0;
1621
1622
    (void)ret;
1623
    WOLFSSL_ENTER("wolfSSL_write_dup");
1624
1625
    if (ssl == NULL) {
1626
        return ssl;
1627
    }
1628
1629
    if (ssl->options.handShakeDone == 0) {
1630
        WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
1631
        return NULL;
1632
    }
1633
1634
    if (ssl->dupWrite) {
1635
        WOLFSSL_MSG("wolfSSL_write_dup already called once");
1636
        return NULL;
1637
    }
1638
1639
    dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
1640
    if (dup) {
1641
        if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
1642
            FreeSSL(dup, ssl->ctx->heap);
1643
            dup = NULL;
1644
        } else if ( (ret = DupSSL(dup, ssl)) < 0) {
1645
            FreeSSL(dup, ssl->ctx->heap);
1646
            dup = NULL;
1647
        }
1648
    }
1649
1650
    WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
1651
1652
    return dup;
1653
}
1654
1655
1656
/*
1657
 * Notify write dup side of fatal error or close notify
1658
 *
1659
 * ssl WOLFSSL object
1660
 * err Notify err
1661
 *
1662
 * 0 on success
1663
*/
1664
int NotifyWriteSide(WOLFSSL* ssl, int err)
1665
{
1666
    int ret;
1667
1668
    WOLFSSL_ENTER("NotifyWriteSide");
1669
1670
    ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
1671
    if (ret == 0) {
1672
        ssl->dupWrite->dupErr = err;
1673
        ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
1674
    }
1675
1676
    return ret;
1677
}
1678
1679
1680
#endif /* HAVE_WRITE_DUP */
1681
1682
1683
#ifdef HAVE_POLY1305
1684
/* set if to use old poly 1 for yes 0 to use new poly */
1685
int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
1686
0
{
1687
0
    (void)ssl;
1688
0
    (void)value;
1689
1690
0
#ifndef WOLFSSL_NO_TLS12
1691
0
    WOLFSSL_ENTER("wolfSSL_use_old_poly");
1692
0
    WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
1693
0
            "is depreciated");
1694
0
    ssl->options.oldPoly = (word16)value;
1695
0
    WOLFSSL_LEAVE("wolfSSL_use_old_poly", 0);
1696
0
#endif
1697
0
    return 0;
1698
0
}
1699
#endif
1700
1701
1702
WOLFSSL_ABI
1703
int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
1704
0
{
1705
0
    int ret;
1706
1707
0
    WOLFSSL_ENTER("wolfSSL_set_fd");
1708
1709
0
    if (ssl == NULL) {
1710
0
        return BAD_FUNC_ARG;
1711
0
    }
1712
1713
0
    ret = wolfSSL_set_read_fd(ssl, fd);
1714
0
    if (ret == WOLFSSL_SUCCESS) {
1715
0
        ret = wolfSSL_set_write_fd(ssl, fd);
1716
0
    }
1717
1718
0
    return ret;
1719
0
}
1720
1721
#ifdef WOLFSSL_DTLS
1722
int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd)
1723
0
{
1724
0
    int ret;
1725
1726
0
    WOLFSSL_ENTER("wolfSSL_set_dtls_fd_connected");
1727
1728
0
    if (ssl == NULL) {
1729
0
        return BAD_FUNC_ARG;
1730
0
    }
1731
1732
0
    ret = wolfSSL_set_fd(ssl, fd);
1733
0
    if (ret == WOLFSSL_SUCCESS)
1734
0
        ssl->buffers.dtlsCtx.connected = 1;
1735
1736
0
    return ret;
1737
0
}
1738
#endif
1739
1740
1741
int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
1742
0
{
1743
0
    WOLFSSL_ENTER("wolfSSL_set_read_fd");
1744
1745
0
    if (ssl == NULL) {
1746
0
        return BAD_FUNC_ARG;
1747
0
    }
1748
1749
0
    ssl->rfd = fd;      /* not used directly to allow IO callbacks */
1750
0
    ssl->IOCB_ReadCtx  = &ssl->rfd;
1751
1752
0
    #ifdef WOLFSSL_DTLS
1753
0
        ssl->buffers.dtlsCtx.connected = 0;
1754
0
        if (ssl->options.dtls) {
1755
0
            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
1756
0
            ssl->buffers.dtlsCtx.rfd = fd;
1757
0
        }
1758
0
    #endif
1759
1760
0
    WOLFSSL_LEAVE("wolfSSL_set_read_fd", WOLFSSL_SUCCESS);
1761
0
    return WOLFSSL_SUCCESS;
1762
0
}
1763
1764
1765
int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
1766
0
{
1767
0
    WOLFSSL_ENTER("wolfSSL_set_write_fd");
1768
1769
0
    if (ssl == NULL) {
1770
0
        return BAD_FUNC_ARG;
1771
0
    }
1772
1773
0
    ssl->wfd = fd;      /* not used directly to allow IO callbacks */
1774
0
    ssl->IOCB_WriteCtx  = &ssl->wfd;
1775
1776
0
    #ifdef WOLFSSL_DTLS
1777
0
        ssl->buffers.dtlsCtx.connected = 0;
1778
0
        if (ssl->options.dtls) {
1779
0
            ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
1780
0
            ssl->buffers.dtlsCtx.wfd = fd;
1781
0
        }
1782
0
    #endif
1783
1784
0
    WOLFSSL_LEAVE("wolfSSL_set_write_fd", WOLFSSL_SUCCESS);
1785
0
    return WOLFSSL_SUCCESS;
1786
0
}
1787
1788
1789
/**
1790
  * Get the name of cipher at priority level passed in.
1791
  */
1792
char* wolfSSL_get_cipher_list(int priority)
1793
0
{
1794
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1795
1796
0
    if (priority >= GetCipherNamesSize() || priority < 0) {
1797
0
        return 0;
1798
0
    }
1799
1800
0
    return (char*)ciphers[priority].name;
1801
0
}
1802
1803
1804
/**
1805
  * Get the name of cipher at priority level passed in.
1806
  */
1807
char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
1808
0
{
1809
1810
0
    if (ssl == NULL) {
1811
0
        return NULL;
1812
0
    }
1813
0
    else {
1814
0
        const char* cipher;
1815
1816
0
        if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
1817
0
            if (priority == 0) {
1818
0
                return (char*)cipher;
1819
0
            }
1820
0
            else {
1821
0
                return NULL;
1822
0
            }
1823
0
        }
1824
0
        else {
1825
0
            return wolfSSL_get_cipher_list(priority);
1826
0
        }
1827
0
    }
1828
0
}
1829
1830
1831
int wolfSSL_get_ciphers(char* buf, int len)
1832
0
{
1833
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1834
0
    int ciphersSz = GetCipherNamesSize();
1835
0
    int i;
1836
1837
0
    if (buf == NULL || len <= 0)
1838
0
        return BAD_FUNC_ARG;
1839
1840
    /* Add each member to the buffer delimited by a : */
1841
0
    for (i = 0; i < ciphersSz; i++) {
1842
0
        int cipherNameSz = (int)XSTRLEN(ciphers[i].name);
1843
0
        if (cipherNameSz + 1 < len) {
1844
0
            XSTRNCPY(buf, ciphers[i].name, len);
1845
0
            buf += cipherNameSz;
1846
1847
0
            if (i < ciphersSz - 1)
1848
0
                *buf++ = ':';
1849
0
            *buf = 0;
1850
1851
0
            len -= cipherNameSz + 1;
1852
0
        }
1853
0
        else
1854
0
            return BUFFER_E;
1855
0
    }
1856
0
    return WOLFSSL_SUCCESS;
1857
0
}
1858
1859
1860
#ifndef NO_ERROR_STRINGS
1861
/* places a list of all supported cipher suites in TLS_* format into "buf"
1862
 * return WOLFSSL_SUCCESS on success */
1863
int wolfSSL_get_ciphers_iana(char* buf, int len)
1864
0
{
1865
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1866
0
    int ciphersSz = GetCipherNamesSize();
1867
0
    int i;
1868
0
    int cipherNameSz;
1869
1870
0
    if (buf == NULL || len <= 0)
1871
0
        return BAD_FUNC_ARG;
1872
1873
    /* Add each member to the buffer delimited by a : */
1874
0
    for (i = 0; i < ciphersSz; i++) {
1875
0
#ifndef NO_CIPHER_SUITE_ALIASES
1876
0
        if (ciphers[i].flags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS)
1877
0
            continue;
1878
0
#endif
1879
0
        cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
1880
0
        if (cipherNameSz + 1 < len) {
1881
0
            XSTRNCPY(buf, ciphers[i].name_iana, len);
1882
0
            buf += cipherNameSz;
1883
1884
0
            if (i < ciphersSz - 1)
1885
0
                *buf++ = ':';
1886
0
            *buf = 0;
1887
1888
0
            len -= cipherNameSz + 1;
1889
0
        }
1890
0
        else
1891
0
            return BUFFER_E;
1892
0
    }
1893
0
    return WOLFSSL_SUCCESS;
1894
0
}
1895
#endif /* NO_ERROR_STRINGS */
1896
1897
1898
const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
1899
0
{
1900
0
    const char* cipher;
1901
1902
0
    if (ssl == NULL)
1903
0
        return NULL;
1904
1905
0
    cipher = wolfSSL_get_cipher_name_iana(ssl);
1906
0
    len = min(len, (int)(XSTRLEN(cipher) + 1));
1907
0
    XMEMCPY(buf, cipher, len);
1908
0
    return buf;
1909
0
}
1910
1911
int wolfSSL_get_fd(const WOLFSSL* ssl)
1912
0
{
1913
0
    int fd = -1;
1914
0
    WOLFSSL_ENTER("wolfSSL_get_fd");
1915
0
    if (ssl) {
1916
0
        fd = ssl->rfd;
1917
0
    }
1918
0
    WOLFSSL_LEAVE("wolfSSL_get_fd", fd);
1919
0
    return fd;
1920
0
}
1921
1922
1923
int wolfSSL_dtls(WOLFSSL* ssl)
1924
0
{
1925
0
    int dtlsOpt = 0;
1926
0
    if (ssl)
1927
0
        dtlsOpt = ssl->options.dtls;
1928
0
    return dtlsOpt;
1929
0
}
1930
1931
#if !defined(NO_CERTS)
1932
/* Set whether mutual authentication is required for connections.
1933
 * Server side only.
1934
 *
1935
 * ctx  The SSL/TLS CTX object.
1936
 * req  1 to indicate required and 0 when not.
1937
 * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
1938
 * 0 on success.
1939
 */
1940
int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
1941
0
{
1942
0
    if (ctx == NULL)
1943
0
        return BAD_FUNC_ARG;
1944
0
    if (ctx->method->side == WOLFSSL_CLIENT_END)
1945
0
        return SIDE_ERROR;
1946
1947
0
    ctx->mutualAuth = (byte)req;
1948
1949
0
    return 0;
1950
0
}
1951
1952
/* Set whether mutual authentication is required for the connection.
1953
 * Server side only.
1954
 *
1955
 * ssl  The SSL/TLS object.
1956
 * req  1 to indicate required and 0 when not.
1957
 * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
1958
 * SIDE_ERROR when not a client and 0 on success.
1959
 */
1960
int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
1961
0
{
1962
0
    if (ssl == NULL)
1963
0
        return BAD_FUNC_ARG;
1964
0
    if (ssl->options.side == WOLFSSL_SERVER_END)
1965
0
        return SIDE_ERROR;
1966
1967
0
    ssl->options.mutualAuth = (word16)req;
1968
1969
0
    return 0;
1970
0
}
1971
#endif /* NO_CERTS */
1972
1973
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
1974
1975
int wolfSSL_CTX_set_AcceptFilter(
1976
    WOLFSSL_CTX *ctx,
1977
    NetworkFilterCallback_t AcceptFilter,
1978
    void *AcceptFilter_arg)
1979
{
1980
    if (ctx == NULL)
1981
        return BAD_FUNC_ARG;
1982
    ctx->AcceptFilter = AcceptFilter;
1983
    ctx->AcceptFilter_arg = AcceptFilter_arg;
1984
    return 0;
1985
}
1986
1987
int wolfSSL_set_AcceptFilter(
1988
    WOLFSSL *ssl,
1989
    NetworkFilterCallback_t AcceptFilter,
1990
    void *AcceptFilter_arg)
1991
{
1992
    if (ssl == NULL)
1993
        return BAD_FUNC_ARG;
1994
    ssl->AcceptFilter = AcceptFilter;
1995
    ssl->AcceptFilter_arg = AcceptFilter_arg;
1996
    return 0;
1997
}
1998
1999
int wolfSSL_CTX_set_ConnectFilter(
2000
    WOLFSSL_CTX *ctx,
2001
    NetworkFilterCallback_t ConnectFilter,
2002
    void *ConnectFilter_arg)
2003
{
2004
    if (ctx == NULL)
2005
        return BAD_FUNC_ARG;
2006
    ctx->ConnectFilter = ConnectFilter;
2007
    ctx->ConnectFilter_arg = ConnectFilter_arg;
2008
    return 0;
2009
}
2010
2011
int wolfSSL_set_ConnectFilter(
2012
    WOLFSSL *ssl,
2013
    NetworkFilterCallback_t ConnectFilter,
2014
    void *ConnectFilter_arg)
2015
{
2016
    if (ssl == NULL)
2017
        return BAD_FUNC_ARG;
2018
    ssl->ConnectFilter = ConnectFilter;
2019
    ssl->ConnectFilter_arg = ConnectFilter_arg;
2020
    return 0;
2021
}
2022
2023
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
2024
2025
#ifndef WOLFSSL_LEANPSK
2026
#if defined(WOLFSSL_DTLS) && defined(XINET_PTON) && \
2027
    !defined(WOLFSSL_NO_SOCK) && defined(HAVE_SOCKADDR)
2028
void* wolfSSL_dtls_create_peer(int port, char* ip)
2029
0
{
2030
0
    SOCKADDR_IN *addr;
2031
0
    addr = (SOCKADDR_IN*)XMALLOC(sizeof(*addr), NULL,
2032
0
            DYNAMIC_TYPE_SOCKADDR);
2033
0
    if (addr == NULL) {
2034
0
        return NULL;
2035
0
    }
2036
2037
0
    addr->sin_family = AF_INET;
2038
0
    addr->sin_port = XHTONS((word16)port);
2039
0
    if (XINET_PTON(AF_INET, ip, &addr->sin_addr) < 1) {
2040
0
        XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
2041
0
        return NULL;
2042
0
    }
2043
2044
0
    return addr;
2045
0
}
2046
2047
int wolfSSL_dtls_free_peer(void* addr)
2048
0
{
2049
0
    XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
2050
0
    return WOLFSSL_SUCCESS;
2051
0
}
2052
#endif
2053
2054
int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
2055
0
{
2056
0
#ifdef WOLFSSL_DTLS
2057
0
    void* sa;
2058
2059
0
    if (ssl == NULL)
2060
0
        return WOLFSSL_FAILURE;
2061
2062
0
    if (peer == NULL || peerSz == 0) {
2063
0
        if (ssl->buffers.dtlsCtx.peer.sa != NULL)
2064
0
            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
2065
0
        ssl->buffers.dtlsCtx.peer.sa = NULL;
2066
0
        ssl->buffers.dtlsCtx.peer.sz = 0;
2067
0
        ssl->buffers.dtlsCtx.peer.bufSz = 0;
2068
0
        ssl->buffers.dtlsCtx.userSet = 0;
2069
0
        return WOLFSSL_SUCCESS;
2070
0
    }
2071
2072
0
    sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
2073
0
    if (sa != NULL) {
2074
0
        if (ssl->buffers.dtlsCtx.peer.sa != NULL) {
2075
0
            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
2076
0
            ssl->buffers.dtlsCtx.peer.sa = NULL;
2077
0
        }
2078
0
        XMEMCPY(sa, peer, peerSz);
2079
0
        ssl->buffers.dtlsCtx.peer.sa = sa;
2080
0
        ssl->buffers.dtlsCtx.peer.sz = peerSz;
2081
0
        ssl->buffers.dtlsCtx.peer.bufSz = peerSz;
2082
0
        ssl->buffers.dtlsCtx.userSet = 1;
2083
0
        return WOLFSSL_SUCCESS;
2084
0
    }
2085
0
    return WOLFSSL_FAILURE;
2086
#else
2087
    (void)ssl;
2088
    (void)peer;
2089
    (void)peerSz;
2090
    return WOLFSSL_NOT_IMPLEMENTED;
2091
#endif
2092
0
}
2093
2094
int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
2095
0
{
2096
0
#ifdef WOLFSSL_DTLS
2097
0
    if (ssl == NULL) {
2098
0
        return WOLFSSL_FAILURE;
2099
0
    }
2100
2101
0
    if (peer != NULL && peerSz != NULL
2102
0
            && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
2103
0
            && ssl->buffers.dtlsCtx.peer.sa != NULL) {
2104
0
        *peerSz = ssl->buffers.dtlsCtx.peer.sz;
2105
0
        XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
2106
0
        return WOLFSSL_SUCCESS;
2107
0
    }
2108
0
    return WOLFSSL_FAILURE;
2109
#else
2110
    (void)ssl;
2111
    (void)peer;
2112
    (void)peerSz;
2113
    return WOLFSSL_NOT_IMPLEMENTED;
2114
#endif
2115
0
}
2116
2117
2118
#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
2119
2120
int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
2121
{
2122
    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp");
2123
2124
    if (ctx == NULL)
2125
        return BAD_FUNC_ARG;
2126
2127
    ctx->dtlsSctp = 1;
2128
    return WOLFSSL_SUCCESS;
2129
}
2130
2131
2132
int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
2133
{
2134
    WOLFSSL_ENTER("wolfSSL_dtls_set_sctp");
2135
2136
    if (ssl == NULL)
2137
        return BAD_FUNC_ARG;
2138
2139
    ssl->options.dtlsSctp = 1;
2140
    return WOLFSSL_SUCCESS;
2141
}
2142
2143
#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
2144
2145
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
2146
                                                           defined(WOLFSSL_DTLS)
2147
2148
int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
2149
{
2150
    if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
2151
        return BAD_FUNC_ARG;
2152
2153
    ctx->dtlsMtuSz = newMtu;
2154
    return WOLFSSL_SUCCESS;
2155
}
2156
2157
2158
int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
2159
{
2160
    if (ssl == NULL)
2161
        return BAD_FUNC_ARG;
2162
2163
    if (newMtu > MAX_RECORD_SIZE) {
2164
        ssl->error = BAD_FUNC_ARG;
2165
        return WOLFSSL_FAILURE;
2166
    }
2167
2168
    ssl->dtlsMtuSz = newMtu;
2169
    return WOLFSSL_SUCCESS;
2170
}
2171
2172
#endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */
2173
2174
#ifdef WOLFSSL_SRTP
2175
2176
static const WOLFSSL_SRTP_PROTECTION_PROFILE gSrtpProfiles[] = {
2177
    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 80-bits
2178
     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
2179
    {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, (((128 + 112) * 2) / 8) },
2180
    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 32-bits
2181
     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
2182
    {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, (((128 + 112) * 2) / 8) },
2183
    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 80-bits */
2184
    {"SRTP_NULL_SHA1_80", SRTP_NULL_SHA1_80, ((112 * 2) / 8)},
2185
    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 32-bits */
2186
    {"SRTP_NULL_SHA1_32", SRTP_NULL_SHA1_32, ((112 * 2) / 8)},
2187
    /* AES GCM 128, Salt: 96-bits, Auth GCM Tag 128-bits
2188
     * (master_key:128bits + master_salt:96bits) * 2 = 448 bits (56) */
2189
    {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, (((128 + 96) * 2) / 8) },
2190
    /* AES GCM 256, Salt: 96-bits, Auth GCM Tag 128-bits
2191
     * (master_key:256bits + master_salt:96bits) * 2 = 704 bits (88) */
2192
    {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, (((256 + 96) * 2) / 8) },
2193
};
2194
2195
static const WOLFSSL_SRTP_PROTECTION_PROFILE* DtlsSrtpFindProfile(
2196
    const char* profile_str, word32 profile_str_len, unsigned long id)
2197
0
{
2198
0
    int i;
2199
0
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
2200
0
    for (i=0;
2201
0
         i<(int)(sizeof(gSrtpProfiles)/sizeof(WOLFSSL_SRTP_PROTECTION_PROFILE));
2202
0
         i++) {
2203
0
        if (profile_str != NULL) {
2204
0
            word32 srtp_profile_len = (word32)XSTRLEN(gSrtpProfiles[i].name);
2205
0
            if (srtp_profile_len == profile_str_len &&
2206
0
                XMEMCMP(gSrtpProfiles[i].name, profile_str, profile_str_len)
2207
0
                                                                         == 0) {
2208
0
                profile = &gSrtpProfiles[i];
2209
0
                break;
2210
0
            }
2211
0
        }
2212
0
        else if (id != 0 && gSrtpProfiles[i].id == id) {
2213
0
            profile = &gSrtpProfiles[i];
2214
0
            break;
2215
0
        }
2216
0
    }
2217
0
    return profile;
2218
0
}
2219
2220
/* profile_str: accepts ":" colon separated list of SRTP profiles */
2221
static int DtlsSrtpSelProfiles(word16* id, const char* profile_str)
2222
0
{
2223
0
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile;
2224
0
    const char *current, *next = NULL;
2225
0
    word32 length = 0, current_length;
2226
2227
0
    *id = 0; /* reset destination ID's */
2228
2229
0
    if (profile_str == NULL) {
2230
0
        return WOLFSSL_FAILURE;
2231
0
    }
2232
2233
    /* loop on end of line or colon ":" */
2234
0
    next = profile_str;
2235
0
    length = (word32)XSTRLEN(profile_str);
2236
0
    do {
2237
0
        current = next;
2238
0
        next = XSTRSTR(current, ":");
2239
0
        current_length = (!next) ? (word32)XSTRLEN(current)
2240
0
                                 : (word32)(next - current);
2241
0
        if (current_length < length)
2242
0
            length = current_length;
2243
0
        profile = DtlsSrtpFindProfile(current, current_length, 0);
2244
0
        if (profile != NULL) {
2245
0
            *id |= (1 << profile->id); /* selected bit based on ID */
2246
0
        }
2247
0
    } while (next != NULL && next++); /* ++ needed to skip ':' */
2248
0
    return WOLFSSL_SUCCESS;
2249
0
}
2250
2251
int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str)
2252
0
{
2253
0
    int ret = WOLFSSL_FAILURE;
2254
0
    if (ctx != NULL) {
2255
0
        ret = DtlsSrtpSelProfiles(&ctx->dtlsSrtpProfiles, profile_str);
2256
0
    }
2257
0
    return ret;
2258
0
}
2259
int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str)
2260
0
{
2261
0
    int ret = WOLFSSL_FAILURE;
2262
0
    if (ssl != NULL) {
2263
0
        ret = DtlsSrtpSelProfiles(&ssl->dtlsSrtpProfiles, profile_str);
2264
0
    }
2265
0
    return ret;
2266
0
}
2267
2268
const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile(
2269
    WOLFSSL* ssl)
2270
0
{
2271
0
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
2272
0
    if (ssl) {
2273
0
        profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
2274
0
    }
2275
0
    return profile;
2276
0
}
2277
#ifndef NO_WOLFSSL_STUB
2278
WOLF_STACK_OF(WOLFSSL_SRTP_PROTECTION_PROFILE)* wolfSSL_get_srtp_profiles(
2279
    WOLFSSL* ssl)
2280
0
{
2281
    /* Not yet implemented - should return list of available SRTP profiles
2282
     * ssl->dtlsSrtpProfiles */
2283
0
    (void)ssl;
2284
0
    return NULL;
2285
0
}
2286
#endif
2287
2288
0
#define DTLS_SRTP_KEYING_MATERIAL_LABEL "EXTRACTOR-dtls_srtp"
2289
2290
int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl,
2291
    unsigned char* out, size_t* olen)
2292
0
{
2293
0
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
2294
2295
0
    if (ssl == NULL || olen == NULL) {
2296
0
        return BAD_FUNC_ARG;
2297
0
    }
2298
2299
0
    profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
2300
0
    if (profile == NULL) {
2301
0
        WOLFSSL_MSG("Not using DTLS SRTP");
2302
0
        return EXT_MISSING;
2303
0
    }
2304
0
    if (out == NULL) {
2305
0
        *olen = profile->kdfBits;
2306
0
        return LENGTH_ONLY_E;
2307
0
    }
2308
2309
0
    if (*olen < (size_t)profile->kdfBits) {
2310
0
        return BUFFER_E;
2311
0
    }
2312
2313
0
    return wolfSSL_export_keying_material(ssl, out, profile->kdfBits,
2314
0
            DTLS_SRTP_KEYING_MATERIAL_LABEL,
2315
0
            XSTR_SIZEOF(DTLS_SRTP_KEYING_MATERIAL_LABEL), NULL, 0, 0);
2316
0
}
2317
2318
#endif /* WOLFSSL_SRTP */
2319
2320
2321
#ifdef WOLFSSL_DTLS_DROP_STATS
2322
2323
int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
2324
                                word32* macDropCount, word32* replayDropCount)
2325
{
2326
    int ret;
2327
2328
    WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats");
2329
2330
    if (ssl == NULL)
2331
        ret = BAD_FUNC_ARG;
2332
    else {
2333
        ret = WOLFSSL_SUCCESS;
2334
        if (macDropCount != NULL)
2335
            *macDropCount = ssl->macDropCount;
2336
        if (replayDropCount != NULL)
2337
            *replayDropCount = ssl->replayDropCount;
2338
    }
2339
2340
    WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats", ret);
2341
    return ret;
2342
}
2343
2344
#endif /* WOLFSSL_DTLS_DROP_STATS */
2345
2346
2347
#if defined(WOLFSSL_MULTICAST)
2348
2349
int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
2350
{
2351
    int ret = 0;
2352
2353
    WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id");
2354
2355
    if (ctx == NULL || id > 255)
2356
        ret = BAD_FUNC_ARG;
2357
2358
    if (ret == 0) {
2359
        ctx->haveEMS = 0;
2360
        ctx->haveMcast = 1;
2361
        ctx->mcastID = (byte)id;
2362
#ifndef WOLFSSL_USER_IO
2363
        ctx->CBIORecv = EmbedReceiveFromMcast;
2364
#endif /* WOLFSSL_USER_IO */
2365
2366
        ret = WOLFSSL_SUCCESS;
2367
    }
2368
    WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id", ret);
2369
    return ret;
2370
}
2371
2372
int wolfSSL_mcast_get_max_peers(void)
2373
{
2374
    return WOLFSSL_MULTICAST_PEERS;
2375
}
2376
2377
#ifdef WOLFSSL_DTLS
2378
static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
2379
                                         word32 second, word32 high)
2380
{
2381
    word32 newCur = 0;
2382
2383
    if (cur < first)
2384
        newCur = first;
2385
    else if (cur < second)
2386
        newCur = second;
2387
    else if (cur < high)
2388
        newCur = high;
2389
2390
    return newCur;
2391
}
2392
#endif /* WOLFSSL_DTLS */
2393
2394
2395
int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
2396
                       const byte* preMasterSecret, word32 preMasterSz,
2397
                       const byte* clientRandom, const byte* serverRandom,
2398
                       const byte* suite)
2399
{
2400
    int ret = 0;
2401
2402
    WOLFSSL_ENTER("wolfSSL_set_secret");
2403
2404
    if (ssl == NULL || preMasterSecret == NULL ||
2405
        preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
2406
        clientRandom == NULL || serverRandom == NULL || suite == NULL) {
2407
2408
        ret = BAD_FUNC_ARG;
2409
    }
2410
2411
    if (ret == 0 && ssl->arrays->preMasterSecret == NULL) {
2412
        ssl->arrays->preMasterSz = ENCRYPT_LEN;
2413
        ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
2414
            DYNAMIC_TYPE_SECRET);
2415
        if (ssl->arrays->preMasterSecret == NULL) {
2416
            ret = MEMORY_E;
2417
        }
2418
    }
2419
2420
    if (ret == 0) {
2421
        XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
2422
        XMEMSET(ssl->arrays->preMasterSecret + preMasterSz, 0, ENCRYPT_LEN - preMasterSz);
2423
        ssl->arrays->preMasterSz = preMasterSz;
2424
        XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
2425
        XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
2426
        ssl->options.cipherSuite0 = suite[0];
2427
        ssl->options.cipherSuite = suite[1];
2428
2429
        ret = SetCipherSpecs(ssl);
2430
    }
2431
2432
    if (ret == 0)
2433
        ret = MakeTlsMasterSecret(ssl);
2434
2435
    if (ret == 0) {
2436
        ssl->keys.encryptionOn = 1;
2437
        ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
2438
    }
2439
2440
    if (ret == 0) {
2441
        if (ssl->options.dtls) {
2442
        #ifdef WOLFSSL_DTLS
2443
            WOLFSSL_DTLS_PEERSEQ* peerSeq;
2444
            int i;
2445
2446
            ssl->keys.dtls_epoch = epoch;
2447
            for (i = 0, peerSeq = ssl->keys.peerSeq;
2448
                 i < WOLFSSL_DTLS_PEERSEQ_SZ;
2449
                 i++, peerSeq++) {
2450
2451
                peerSeq->nextEpoch = epoch;
2452
                peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
2453
                peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
2454
                peerSeq->nextSeq_lo = 0;
2455
                peerSeq->nextSeq_hi = 0;
2456
                XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
2457
                XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
2458
                peerSeq->highwaterMark = UpdateHighwaterMark(0,
2459
                        ssl->ctx->mcastFirstSeq,
2460
                        ssl->ctx->mcastSecondSeq,
2461
                        ssl->ctx->mcastMaxSeq);
2462
            }
2463
        #else
2464
            (void)epoch;
2465
        #endif
2466
        }
2467
        FreeHandshakeResources(ssl);
2468
        ret = WOLFSSL_SUCCESS;
2469
    }
2470
    else {
2471
        if (ssl)
2472
            ssl->error = ret;
2473
        ret = WOLFSSL_FATAL_ERROR;
2474
    }
2475
    WOLFSSL_LEAVE("wolfSSL_set_secret", ret);
2476
    return ret;
2477
}
2478
2479
2480
#ifdef WOLFSSL_DTLS
2481
2482
int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int sub)
2483
{
2484
    WOLFSSL_DTLS_PEERSEQ* p = NULL;
2485
    int ret = WOLFSSL_SUCCESS;
2486
    int i;
2487
2488
    WOLFSSL_ENTER("wolfSSL_mcast_peer_add");
2489
    if (ssl == NULL || peerId > 255)
2490
        return BAD_FUNC_ARG;
2491
2492
    if (!sub) {
2493
        /* Make sure it isn't already present, while keeping the first
2494
         * open spot. */
2495
        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
2496
            if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
2497
                p = &ssl->keys.peerSeq[i];
2498
            if (ssl->keys.peerSeq[i].peerId == peerId) {
2499
                WOLFSSL_MSG("Peer ID already in multicast peer list.");
2500
                p = NULL;
2501
            }
2502
        }
2503
2504
        if (p != NULL) {
2505
            XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
2506
            p->peerId = peerId;
2507
            p->highwaterMark = UpdateHighwaterMark(0,
2508
                ssl->ctx->mcastFirstSeq,
2509
                ssl->ctx->mcastSecondSeq,
2510
                ssl->ctx->mcastMaxSeq);
2511
        }
2512
        else {
2513
            WOLFSSL_MSG("No room in peer list.");
2514
            ret = -1;
2515
        }
2516
    }
2517
    else {
2518
        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
2519
            if (ssl->keys.peerSeq[i].peerId == peerId)
2520
                p = &ssl->keys.peerSeq[i];
2521
        }
2522
2523
        if (p != NULL) {
2524
            p->peerId = INVALID_PEER_ID;
2525
        }
2526
        else {
2527
            WOLFSSL_MSG("Peer not found in list.");
2528
        }
2529
    }
2530
2531
    WOLFSSL_LEAVE("wolfSSL_mcast_peer_add", ret);
2532
    return ret;
2533
}
2534
2535
2536
/* If peerId is in the list of peers and its last sequence number is non-zero,
2537
 * return 1, otherwise return 0. */
2538
int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
2539
{
2540
    int known = 0;
2541
    int i;
2542
2543
    WOLFSSL_ENTER("wolfSSL_mcast_peer_known");
2544
2545
    if (ssl == NULL || peerId > 255) {
2546
        return BAD_FUNC_ARG;
2547
    }
2548
2549
    for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
2550
        if (ssl->keys.peerSeq[i].peerId == peerId) {
2551
            if (ssl->keys.peerSeq[i].nextSeq_hi ||
2552
                ssl->keys.peerSeq[i].nextSeq_lo) {
2553
2554
                known = 1;
2555
            }
2556
            break;
2557
        }
2558
    }
2559
2560
    WOLFSSL_LEAVE("wolfSSL_mcast_peer_known", known);
2561
    return known;
2562
}
2563
2564
2565
int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
2566
                                       word32 first, word32 second,
2567
                                       CallbackMcastHighwater cb)
2568
{
2569
    if (ctx == NULL || (second && first > second) ||
2570
        first > maxSeq || second > maxSeq || cb == NULL) {
2571
2572
        return BAD_FUNC_ARG;
2573
    }
2574
2575
    ctx->mcastHwCb = cb;
2576
    ctx->mcastFirstSeq = first;
2577
    ctx->mcastSecondSeq = second;
2578
    ctx->mcastMaxSeq = maxSeq;
2579
2580
    return WOLFSSL_SUCCESS;
2581
}
2582
2583
2584
int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
2585
{
2586
    if (ssl == NULL || ctx == NULL)
2587
        return BAD_FUNC_ARG;
2588
2589
    ssl->mcastHwCbCtx = ctx;
2590
2591
    return WOLFSSL_SUCCESS;
2592
}
2593
2594
#endif /* WOLFSSL_DTLS */
2595
2596
#endif /* WOLFSSL_MULTICAST */
2597
2598
2599
#endif /* WOLFSSL_LEANPSK */
2600
2601
2602
/* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
2603
int wolfSSL_negotiate(WOLFSSL* ssl)
2604
184
{
2605
184
    int err = WOLFSSL_FATAL_ERROR;
2606
2607
184
    WOLFSSL_ENTER("wolfSSL_negotiate");
2608
2609
184
    if (ssl == NULL)
2610
0
        return WOLFSSL_FATAL_ERROR;
2611
2612
184
#ifndef NO_WOLFSSL_SERVER
2613
184
    if (ssl->options.side == WOLFSSL_SERVER_END) {
2614
184
#ifdef WOLFSSL_TLS13
2615
184
        if (IsAtLeastTLSv1_3(ssl->version))
2616
184
            err = wolfSSL_accept_TLSv13(ssl);
2617
0
        else
2618
0
#endif
2619
0
            err = wolfSSL_accept(ssl);
2620
184
    }
2621
184
#endif
2622
2623
184
#ifndef NO_WOLFSSL_CLIENT
2624
184
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
2625
0
#ifdef WOLFSSL_TLS13
2626
0
        if (IsAtLeastTLSv1_3(ssl->version))
2627
0
            err = wolfSSL_connect_TLSv13(ssl);
2628
0
        else
2629
0
#endif
2630
0
            err = wolfSSL_connect(ssl);
2631
0
    }
2632
184
#endif
2633
2634
184
    (void)ssl;
2635
2636
184
    WOLFSSL_LEAVE("wolfSSL_negotiate", err);
2637
2638
184
    return err;
2639
184
}
2640
2641
2642
WOLFSSL_ABI
2643
WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
2644
0
{
2645
0
    if (ssl) {
2646
0
        return ssl->rng;
2647
0
    }
2648
2649
0
    return NULL;
2650
0
}
2651
2652
2653
#ifndef WOLFSSL_LEANPSK
2654
/* object size based on build */
2655
int wolfSSL_GetObjectSize(void)
2656
0
{
2657
#ifdef SHOW_SIZES
2658
    printf("sizeof suites           = %lu\n", (unsigned long)sizeof(Suites));
2659
    printf("sizeof ciphers(2)       = %lu\n", (unsigned long)sizeof(Ciphers));
2660
#ifndef NO_RC4
2661
    printf("\tsizeof arc4         = %lu\n", (unsigned long)sizeof(Arc4));
2662
#endif
2663
    printf("\tsizeof aes          = %lu\n", (unsigned long)sizeof(Aes));
2664
#ifndef NO_DES3
2665
    printf("\tsizeof des3         = %lu\n", (unsigned long)sizeof(Des3));
2666
#endif
2667
#ifdef HAVE_CHACHA
2668
    printf("\tsizeof chacha       = %lu\n", (unsigned long)sizeof(ChaCha));
2669
#endif
2670
#ifdef WOLFSSL_SM4
2671
    printf("\tsizeof sm4          = %lu\n", (unsigned long)sizeof(Sm4));
2672
#endif
2673
    printf("sizeof cipher specs     = %lu\n", (unsigned long)sizeof(CipherSpecs));
2674
    printf("sizeof keys             = %lu\n", (unsigned long)sizeof(Keys));
2675
    printf("sizeof Hashes(2)        = %lu\n", (unsigned long)sizeof(Hashes));
2676
#ifndef NO_MD5
2677
    printf("\tsizeof MD5          = %lu\n", (unsigned long)sizeof(wc_Md5));
2678
#endif
2679
#ifndef NO_SHA
2680
    printf("\tsizeof SHA          = %lu\n", (unsigned long)sizeof(wc_Sha));
2681
#endif
2682
#ifdef WOLFSSL_SHA224
2683
    printf("\tsizeof SHA224       = %lu\n", (unsigned long)sizeof(wc_Sha224));
2684
#endif
2685
#ifndef NO_SHA256
2686
    printf("\tsizeof SHA256       = %lu\n", (unsigned long)sizeof(wc_Sha256));
2687
#endif
2688
#ifdef WOLFSSL_SHA384
2689
    printf("\tsizeof SHA384       = %lu\n", (unsigned long)sizeof(wc_Sha384));
2690
#endif
2691
#ifdef WOLFSSL_SHA384
2692
    printf("\tsizeof SHA512       = %lu\n", (unsigned long)sizeof(wc_Sha512));
2693
#endif
2694
#ifdef WOLFSSL_SM3
2695
    printf("\tsizeof sm3          = %lu\n", (unsigned long)sizeof(Sm3));
2696
#endif
2697
    printf("sizeof Buffers          = %lu\n", (unsigned long)sizeof(Buffers));
2698
    printf("sizeof Options          = %lu\n", (unsigned long)sizeof(Options));
2699
    printf("sizeof Arrays           = %lu\n", (unsigned long)sizeof(Arrays));
2700
#ifndef NO_RSA
2701
    printf("sizeof RsaKey           = %lu\n", (unsigned long)sizeof(RsaKey));
2702
#endif
2703
#ifdef HAVE_ECC
2704
    printf("sizeof ecc_key          = %lu\n", (unsigned long)sizeof(ecc_key));
2705
#endif
2706
    printf("sizeof WOLFSSL_CIPHER    = %lu\n", (unsigned long)sizeof(WOLFSSL_CIPHER));
2707
    printf("sizeof WOLFSSL_SESSION   = %lu\n", (unsigned long)sizeof(WOLFSSL_SESSION));
2708
    printf("sizeof WOLFSSL           = %lu\n", (unsigned long)sizeof(WOLFSSL));
2709
    printf("sizeof WOLFSSL_CTX       = %lu\n", (unsigned long)sizeof(WOLFSSL_CTX));
2710
#endif
2711
2712
0
    return sizeof(WOLFSSL);
2713
0
}
2714
2715
int wolfSSL_CTX_GetObjectSize(void)
2716
0
{
2717
0
    return sizeof(WOLFSSL_CTX);
2718
0
}
2719
2720
int wolfSSL_METHOD_GetObjectSize(void)
2721
0
{
2722
0
    return sizeof(WOLFSSL_METHOD);
2723
0
}
2724
#endif
2725
2726
2727
#ifdef WOLFSSL_STATIC_MEMORY
2728
2729
int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method,
2730
                                   unsigned char* buf, unsigned int sz,
2731
                                   int flag, int maxSz)
2732
{
2733
    WOLFSSL_HEAP*      heap;
2734
    WOLFSSL_HEAP_HINT* hint;
2735
    word32 idx = 0;
2736
2737
    if (ctx == NULL || buf == NULL) {
2738
        return BAD_FUNC_ARG;
2739
    }
2740
2741
    if (*ctx == NULL && method == NULL) {
2742
        return BAD_FUNC_ARG;
2743
    }
2744
2745
    if (*ctx == NULL || (*ctx)->heap == NULL) {
2746
        if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) {
2747
            return BUFFER_E; /* not enough memory for structures */
2748
        }
2749
        heap = (WOLFSSL_HEAP*)buf;
2750
        idx += sizeof(WOLFSSL_HEAP);
2751
        if (wolfSSL_init_memory_heap(heap) != 0) {
2752
            return WOLFSSL_FAILURE;
2753
        }
2754
        hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
2755
        idx += sizeof(WOLFSSL_HEAP_HINT);
2756
        XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
2757
        hint->memory = heap;
2758
2759
        if (*ctx && (*ctx)->heap == NULL) {
2760
            (*ctx)->heap = (void*)hint;
2761
        }
2762
    }
2763
    else {
2764
#ifdef WOLFSSL_HEAP_TEST
2765
        /* do not load in memory if test has been set */
2766
        if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) {
2767
            return WOLFSSL_SUCCESS;
2768
        }
2769
#endif
2770
        hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap);
2771
        heap = hint->memory;
2772
    }
2773
2774
    if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
2775
        WOLFSSL_MSG("Error partitioning memory");
2776
        return WOLFSSL_FAILURE;
2777
    }
2778
2779
    /* create ctx if needed */
2780
    if (*ctx == NULL) {
2781
        *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
2782
        if (*ctx == NULL) {
2783
            WOLFSSL_MSG("Error creating ctx");
2784
            return WOLFSSL_FAILURE;
2785
        }
2786
    }
2787
2788
    /* determine what max applies too */
2789
    if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
2790
        heap->maxIO = maxSz;
2791
    }
2792
    else { /* general memory used in handshakes */
2793
        heap->maxHa = maxSz;
2794
    }
2795
2796
    heap->flag |= flag;
2797
2798
    (void)maxSz;
2799
    (void)method;
2800
2801
    return WOLFSSL_SUCCESS;
2802
}
2803
2804
2805
int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
2806
{
2807
    if (ssl == NULL) {
2808
        return BAD_FUNC_ARG;
2809
    }
2810
    WOLFSSL_ENTER("wolfSSL_is_static_memory");
2811
2812
    /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
2813
    if (mem_stats != NULL && ssl->heap != NULL) {
2814
        WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
2815
        WOLFSSL_HEAP* heap      = hint->memory;
2816
        if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
2817
            XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
2818
        }
2819
    }
2820
2821
    return (ssl->heap) ? 1 : 0;
2822
}
2823
2824
2825
int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
2826
{
2827
    if (ctx == NULL) {
2828
        return BAD_FUNC_ARG;
2829
    }
2830
    WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
2831
2832
    /* fill out statistics if wanted */
2833
    if (mem_stats != NULL && ctx->heap != NULL) {
2834
        WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
2835
        if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
2836
            return MEMORY_E;
2837
        }
2838
    }
2839
2840
    return (ctx->heap) ? 1 : 0;
2841
}
2842
2843
#endif /* WOLFSSL_STATIC_MEMORY */
2844
2845
2846
/* return max record layer size plaintext input size */
2847
int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
2848
0
{
2849
0
    WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
2850
2851
0
    if (ssl == NULL)
2852
0
        return BAD_FUNC_ARG;
2853
2854
0
    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
2855
0
        WOLFSSL_MSG("Handshake not complete yet");
2856
0
        return BAD_FUNC_ARG;
2857
0
    }
2858
2859
0
    return wolfSSL_GetMaxFragSize(ssl, OUTPUT_RECORD_SIZE);
2860
0
}
2861
2862
2863
/* return record layer size of plaintext input size */
2864
int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
2865
0
{
2866
0
    int maxSize;
2867
2868
0
    WOLFSSL_ENTER("wolfSSL_GetOutputSize");
2869
2870
0
    if (inSz < 0)
2871
0
        return BAD_FUNC_ARG;
2872
2873
0
    maxSize = wolfSSL_GetMaxOutputSize(ssl);
2874
0
    if (maxSize < 0)
2875
0
        return maxSize;   /* error */
2876
0
    if (inSz > maxSize)
2877
0
        return INPUT_SIZE_E;
2878
2879
0
    return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0, CUR_ORDER);
2880
0
}
2881
2882
2883
#ifdef HAVE_ECC
2884
int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2885
0
{
2886
0
    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
2887
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
2888
0
        return BAD_FUNC_ARG;
2889
0
    }
2890
2891
0
    ctx->minEccKeySz     = keySz / 8;
2892
0
#ifndef NO_CERTS
2893
0
    ctx->cm->minEccKeySz = keySz / 8;
2894
0
#endif
2895
0
    return WOLFSSL_SUCCESS;
2896
0
}
2897
2898
2899
int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
2900
0
{
2901
0
    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
2902
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
2903
0
        return BAD_FUNC_ARG;
2904
0
    }
2905
2906
0
    ssl->options.minEccKeySz = keySz / 8;
2907
0
    return WOLFSSL_SUCCESS;
2908
0
}
2909
2910
#endif /* HAVE_ECC */
2911
2912
#ifndef NO_RSA
2913
int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2914
0
{
2915
0
    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
2916
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
2917
0
        return BAD_FUNC_ARG;
2918
0
    }
2919
2920
0
    ctx->minRsaKeySz     = keySz / 8;
2921
0
    ctx->cm->minRsaKeySz = keySz / 8;
2922
0
    return WOLFSSL_SUCCESS;
2923
0
}
2924
2925
2926
int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
2927
0
{
2928
0
    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
2929
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
2930
0
        return BAD_FUNC_ARG;
2931
0
    }
2932
2933
0
    ssl->options.minRsaKeySz = keySz / 8;
2934
0
    return WOLFSSL_SUCCESS;
2935
0
}
2936
#endif /* !NO_RSA */
2937
2938
#ifndef NO_DH
2939
2940
#ifdef OPENSSL_EXTRA
2941
long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
2942
0
{
2943
0
    int pSz, gSz;
2944
0
    byte *p, *g;
2945
0
    int ret = 0;
2946
2947
0
    WOLFSSL_ENTER("wolfSSL_set_tmp_dh");
2948
2949
0
    if (!ssl || !dh)
2950
0
        return BAD_FUNC_ARG;
2951
2952
    /* Get needed size for p and g */
2953
0
    pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
2954
0
    gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
2955
2956
0
    if (pSz <= 0 || gSz <= 0)
2957
0
        return -1;
2958
2959
0
    p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2960
0
    if (!p)
2961
0
        return MEMORY_E;
2962
2963
0
    g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2964
0
    if (!g) {
2965
0
        XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2966
0
        return MEMORY_E;
2967
0
    }
2968
2969
0
    pSz = wolfSSL_BN_bn2bin(dh->p, p);
2970
0
    gSz = wolfSSL_BN_bn2bin(dh->g, g);
2971
2972
0
    if (pSz >= 0 && gSz >= 0) /* Conversion successful */
2973
0
        ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
2974
2975
0
    XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2976
0
    XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2977
2978
0
    return pSz > 0 && gSz > 0 ? ret : -1;
2979
0
}
2980
#endif /* OPENSSL_EXTRA */
2981
2982
/* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
2983
int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
2984
                    const unsigned char* g, int gSz)
2985
0
{
2986
0
    WOLFSSL_ENTER("wolfSSL_SetTmpDH");
2987
2988
0
    if (ssl == NULL || p == NULL || g == NULL)
2989
0
        return BAD_FUNC_ARG;
2990
2991
0
    if ((word16)pSz < ssl->options.minDhKeySz)
2992
0
        return DH_KEY_SIZE_E;
2993
0
    if ((word16)pSz > ssl->options.maxDhKeySz)
2994
0
        return DH_KEY_SIZE_E;
2995
2996
    /* this function is for server only */
2997
0
    if (ssl->options.side == WOLFSSL_CLIENT_END)
2998
0
        return SIDE_ERROR;
2999
3000
0
    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
3001
0
        !defined(HAVE_SELFTEST)
3002
0
        ssl->options.dhKeyTested = 0;
3003
0
        ssl->options.dhDoKeyTest = 1;
3004
0
    #endif
3005
3006
0
    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
3007
0
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3008
0
        ssl->buffers.serverDH_P.buffer = NULL;
3009
0
    }
3010
0
    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
3011
0
        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3012
0
        ssl->buffers.serverDH_G.buffer = NULL;
3013
0
    }
3014
3015
0
    ssl->buffers.weOwnDH = 1;  /* SSL owns now */
3016
0
    ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,
3017
0
                                                    DYNAMIC_TYPE_PUBLIC_KEY);
3018
0
    if (ssl->buffers.serverDH_P.buffer == NULL)
3019
0
            return MEMORY_E;
3020
3021
0
    ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->heap,
3022
0
                                                    DYNAMIC_TYPE_PUBLIC_KEY);
3023
0
    if (ssl->buffers.serverDH_G.buffer == NULL) {
3024
0
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3025
0
        ssl->buffers.serverDH_P.buffer = NULL;
3026
0
        return MEMORY_E;
3027
0
    }
3028
3029
0
    ssl->buffers.serverDH_P.length = pSz;
3030
0
    ssl->buffers.serverDH_G.length = gSz;
3031
3032
0
    XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
3033
0
    XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
3034
3035
0
    ssl->options.haveDH = 1;
3036
3037
0
    if (ssl->options.side != WOLFSSL_NEITHER_END) {
3038
0
        word16 havePSK;
3039
0
        word16 haveRSA;
3040
0
        int    keySz   = 0;
3041
0
        int    ret;
3042
3043
0
    #ifndef NO_PSK
3044
0
        havePSK = ssl->options.havePSK;
3045
    #else
3046
        havePSK = 0;
3047
    #endif
3048
    #ifdef NO_RSA
3049
        haveRSA = 0;
3050
    #else
3051
0
        haveRSA = 1;
3052
0
    #endif
3053
0
    #ifndef NO_CERTS
3054
0
        keySz = ssl->buffers.keySz;
3055
0
    #endif
3056
0
        ret = AllocateSuites(ssl);
3057
0
        if (ret != 0)
3058
0
            return ret;
3059
0
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
3060
0
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
3061
0
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
3062
0
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
3063
0
                   ssl->options.haveAnon, TRUE, ssl->options.side);
3064
0
    }
3065
3066
0
    WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
3067
3068
0
    return WOLFSSL_SUCCESS;
3069
0
}
3070
3071
3072
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
3073
    !defined(HAVE_SELFTEST)
3074
/* Enables or disables the session's DH key prime test. */
3075
int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
3076
0
{
3077
0
    WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
3078
3079
0
    if (ssl == NULL)
3080
0
        return BAD_FUNC_ARG;
3081
3082
0
    if (!enable)
3083
0
        ssl->options.dhDoKeyTest = 0;
3084
0
    else
3085
0
        ssl->options.dhDoKeyTest = 1;
3086
3087
0
    WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
3088
0
    return WOLFSSL_SUCCESS;
3089
0
}
3090
#endif
3091
3092
3093
/* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
3094
int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
3095
                         const unsigned char* g, int gSz)
3096
0
{
3097
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
3098
0
    if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
3099
3100
0
    if ((word16)pSz < ctx->minDhKeySz)
3101
0
        return DH_KEY_SIZE_E;
3102
0
    if ((word16)pSz > ctx->maxDhKeySz)
3103
0
        return DH_KEY_SIZE_E;
3104
3105
0
    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
3106
0
        !defined(HAVE_SELFTEST)
3107
0
    {
3108
0
        WC_RNG rng;
3109
0
        int error, freeKey = 0;
3110
0
    #ifdef WOLFSSL_SMALL_STACK
3111
0
        DhKey *checkKey = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
3112
0
        if (checkKey == NULL)
3113
0
            return MEMORY_E;
3114
    #else
3115
        DhKey checkKey[1];
3116
    #endif
3117
3118
0
        error = wc_InitRng(&rng);
3119
0
        if (!error)
3120
0
            error = wc_InitDhKey(checkKey);
3121
0
        if (!error) {
3122
0
            freeKey = 1;
3123
0
            error = wc_DhSetCheckKey(checkKey,
3124
0
                                 p, pSz, g, gSz, NULL, 0, 0, &rng);
3125
0
        }
3126
0
        if (freeKey)
3127
0
            wc_FreeDhKey(checkKey);
3128
0
    #ifdef WOLFSSL_SMALL_STACK
3129
0
        XFREE(checkKey, NULL, DYNAMIC_TYPE_DH);
3130
0
    #endif
3131
0
        wc_FreeRng(&rng);
3132
0
        if (error)
3133
0
            return error;
3134
3135
0
        ctx->dhKeyTested = 1;
3136
0
    }
3137
0
    #endif
3138
3139
0
    XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3140
0
    ctx->serverDH_P.buffer = NULL;
3141
0
    XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3142
0
    ctx->serverDH_G.buffer = NULL;
3143
3144
0
    ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3145
0
    if (ctx->serverDH_P.buffer == NULL)
3146
0
       return MEMORY_E;
3147
3148
0
    ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3149
0
    if (ctx->serverDH_G.buffer == NULL) {
3150
0
        XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
3151
0
        ctx->serverDH_P.buffer = NULL;
3152
0
        return MEMORY_E;
3153
0
    }
3154
3155
0
    ctx->serverDH_P.length = pSz;
3156
0
    ctx->serverDH_G.length = gSz;
3157
3158
0
    XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
3159
0
    XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
3160
3161
0
    ctx->haveDH = 1;
3162
3163
0
    WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
3164
0
    return WOLFSSL_SUCCESS;
3165
0
}
3166
3167
3168
int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
3169
0
{
3170
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
3171
0
        return BAD_FUNC_ARG;
3172
3173
0
    ctx->minDhKeySz = keySz_bits / 8;
3174
0
    return WOLFSSL_SUCCESS;
3175
0
}
3176
3177
3178
int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
3179
0
{
3180
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
3181
0
        return BAD_FUNC_ARG;
3182
3183
0
    ssl->options.minDhKeySz = keySz_bits / 8;
3184
0
    return WOLFSSL_SUCCESS;
3185
0
}
3186
3187
3188
int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
3189
0
{
3190
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
3191
0
        return BAD_FUNC_ARG;
3192
3193
0
    ctx->maxDhKeySz = keySz_bits / 8;
3194
0
    return WOLFSSL_SUCCESS;
3195
0
}
3196
3197
3198
int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
3199
0
{
3200
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
3201
0
        return BAD_FUNC_ARG;
3202
3203
0
    ssl->options.maxDhKeySz = keySz_bits / 8;
3204
0
    return WOLFSSL_SUCCESS;
3205
0
}
3206
3207
3208
int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
3209
0
{
3210
0
    if (ssl == NULL)
3211
0
        return BAD_FUNC_ARG;
3212
3213
0
    return (ssl->options.dhKeySz * 8);
3214
0
}
3215
3216
#endif /* !NO_DH */
3217
3218
3219
WOLFSSL_ABI
3220
int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
3221
184
{
3222
184
    int ret;
3223
3224
184
    WOLFSSL_ENTER("wolfSSL_write");
3225
3226
184
    if (ssl == NULL || data == NULL || sz < 0)
3227
0
        return BAD_FUNC_ARG;
3228
3229
184
#ifdef WOLFSSL_QUIC
3230
184
    if (WOLFSSL_IS_QUIC(ssl)) {
3231
0
        WOLFSSL_MSG("SSL_write() on QUIC not allowed");
3232
0
        return BAD_FUNC_ARG;
3233
0
    }
3234
184
#endif
3235
184
#ifdef WOLFSSL_EARLY_DATA
3236
184
    if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
3237
184
        ssl->error = ret;
3238
184
        return WOLFSSL_FATAL_ERROR;
3239
184
    }
3240
0
    ssl->earlyData = no_early_data;
3241
0
#endif
3242
3243
#ifdef HAVE_WRITE_DUP
3244
    { /* local variable scope */
3245
        int dupErr = 0;   /* local copy */
3246
3247
        ret = 0;
3248
3249
        if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
3250
            WOLFSSL_MSG("Read dup side cannot write");
3251
            return WRITE_DUP_WRITE_E;
3252
        }
3253
        if (ssl->dupWrite) {
3254
            if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
3255
                return BAD_MUTEX_E;
3256
            }
3257
            dupErr = ssl->dupWrite->dupErr;
3258
            ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
3259
        }
3260
3261
        if (ret != 0) {
3262
            ssl->error = ret;  /* high priority fatal error */
3263
            return WOLFSSL_FATAL_ERROR;
3264
        }
3265
        if (dupErr != 0) {
3266
            WOLFSSL_MSG("Write dup error from other side");
3267
            ssl->error = dupErr;
3268
            return WOLFSSL_FATAL_ERROR;
3269
        }
3270
    }
3271
#endif
3272
3273
0
#ifdef HAVE_ERRNO_H
3274
0
    errno = 0;
3275
0
#endif
3276
3277
0
    #ifdef OPENSSL_EXTRA
3278
0
    if (ssl->CBIS != NULL) {
3279
0
        ssl->CBIS(ssl, SSL_CB_WRITE, WOLFSSL_SUCCESS);
3280
0
        ssl->cbmode = SSL_CB_WRITE;
3281
0
    }
3282
0
    #endif
3283
0
    ret = SendData(ssl, data, sz);
3284
3285
0
    WOLFSSL_LEAVE("wolfSSL_write", ret);
3286
3287
0
    if (ret < 0)
3288
0
        return WOLFSSL_FATAL_ERROR;
3289
0
    else
3290
0
        return ret;
3291
0
}
3292
3293
static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
3294
184
{
3295
184
    int ret;
3296
3297
184
    WOLFSSL_ENTER("wolfSSL_read_internal");
3298
3299
184
    if (ssl == NULL || data == NULL || sz < 0)
3300
0
        return BAD_FUNC_ARG;
3301
3302
184
#ifdef WOLFSSL_QUIC
3303
184
    if (WOLFSSL_IS_QUIC(ssl)) {
3304
0
        WOLFSSL_MSG("SSL_read() on QUIC not allowed");
3305
0
        return BAD_FUNC_ARG;
3306
0
    }
3307
184
#endif
3308
184
#if defined(WOLFSSL_ERROR_CODE_OPENSSL) && defined(OPENSSL_EXTRA)
3309
    /* This additional logic is meant to simulate following openSSL behavior:
3310
     * After bidirectional SSL_shutdown complete, SSL_read returns 0 and
3311
     * SSL_get_error_code returns SSL_ERROR_ZERO_RETURN.
3312
     * This behavior is used to know the disconnect of the underlying
3313
     * transport layer.
3314
     *
3315
     * In this logic, CBIORecv is called with a read size of 0 to check the
3316
     * transport layer status. It also returns WOLFSSL_FAILURE so that
3317
     * SSL_read does not return a positive number on failure.
3318
     */
3319
3320
    /* make sure bidirectional TLS shutdown completes */
3321
184
    if (ssl->error == WOLFSSL_ERROR_SYSCALL || ssl->options.shutdownDone) {
3322
        /* ask the underlying transport the connection is closed */
3323
0
        if (ssl->CBIORecv(ssl, (char*)data, 0, ssl->IOCB_ReadCtx) ==
3324
0
                                            WOLFSSL_CBIO_ERR_CONN_CLOSE) {
3325
0
            ssl->options.isClosed = 1;
3326
0
            ssl->error = WOLFSSL_ERROR_ZERO_RETURN;
3327
0
        }
3328
0
        return WOLFSSL_FAILURE;
3329
0
    }
3330
184
#endif
3331
3332
#ifdef HAVE_WRITE_DUP
3333
    if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
3334
        WOLFSSL_MSG("Write dup side cannot read");
3335
        return WRITE_DUP_READ_E;
3336
    }
3337
#endif
3338
3339
184
#ifdef HAVE_ERRNO_H
3340
184
        errno = 0;
3341
184
#endif
3342
3343
184
    ret = ReceiveData(ssl, (byte*)data, sz, peek);
3344
3345
#ifdef HAVE_WRITE_DUP
3346
    if (ssl->dupWrite) {
3347
        if (ssl->error != 0 && ssl->error != WANT_READ
3348
        #ifdef WOLFSSL_ASYNC_CRYPT
3349
            && ssl->error != WC_PENDING_E
3350
        #endif
3351
        ) {
3352
            int notifyErr;
3353
3354
            WOLFSSL_MSG("Notifying write side of fatal read error");
3355
            notifyErr  = NotifyWriteSide(ssl, ssl->error);
3356
            if (notifyErr < 0) {
3357
                ret = ssl->error = notifyErr;
3358
            }
3359
        }
3360
    }
3361
#endif
3362
3363
184
    WOLFSSL_LEAVE("wolfSSL_read_internal", ret);
3364
3365
184
    if (ret < 0)
3366
66
        return WOLFSSL_FATAL_ERROR;
3367
118
    else
3368
118
        return ret;
3369
184
}
3370
3371
3372
int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
3373
0
{
3374
0
    WOLFSSL_ENTER("wolfSSL_peek");
3375
3376
0
    return wolfSSL_read_internal(ssl, data, sz, TRUE);
3377
0
}
3378
3379
3380
WOLFSSL_ABI
3381
int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
3382
184
{
3383
184
    WOLFSSL_ENTER("wolfSSL_read");
3384
3385
184
    #ifdef OPENSSL_EXTRA
3386
184
    if (ssl == NULL) {
3387
0
        return BAD_FUNC_ARG;
3388
0
    }
3389
184
    if (ssl->CBIS != NULL) {
3390
0
        ssl->CBIS(ssl, SSL_CB_READ, WOLFSSL_SUCCESS);
3391
0
        ssl->cbmode = SSL_CB_READ;
3392
0
    }
3393
184
    #endif
3394
184
    return wolfSSL_read_internal(ssl, data, sz, FALSE);
3395
184
}
3396
3397
3398
#ifdef WOLFSSL_MULTICAST
3399
3400
int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
3401
{
3402
    int ret = 0;
3403
3404
    WOLFSSL_ENTER("wolfSSL_mcast_read");
3405
3406
    if (ssl == NULL)
3407
        return BAD_FUNC_ARG;
3408
3409
    ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
3410
    if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
3411
        *id = ssl->keys.curPeerId;
3412
    return ret;
3413
}
3414
3415
#endif /* WOLFSSL_MULTICAST */
3416
3417
3418
/* helpers to set the device id, WOLFSSL_SUCCESS on ok */
3419
WOLFSSL_ABI
3420
int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
3421
0
{
3422
0
    if (ssl == NULL)
3423
0
        return BAD_FUNC_ARG;
3424
3425
0
    ssl->devId = devId;
3426
3427
0
    return WOLFSSL_SUCCESS;
3428
0
}
3429
3430
WOLFSSL_ABI
3431
int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
3432
0
{
3433
0
    if (ctx == NULL)
3434
0
        return BAD_FUNC_ARG;
3435
3436
0
    ctx->devId = devId;
3437
3438
0
    return WOLFSSL_SUCCESS;
3439
0
}
3440
3441
/* helpers to get device id and heap */
3442
WOLFSSL_ABI
3443
int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
3444
29.9k
{
3445
29.9k
    int devId = INVALID_DEVID;
3446
29.9k
    if (ssl != NULL)
3447
0
        devId = ssl->devId;
3448
29.9k
    if (ctx != NULL && devId == INVALID_DEVID)
3449
29.9k
        devId = ctx->devId;
3450
29.9k
    return devId;
3451
29.9k
}
3452
void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
3453
29.9k
{
3454
29.9k
    void* heap = NULL;
3455
29.9k
    if (ctx != NULL)
3456
29.9k
        heap = ctx->heap;
3457
0
    else if (ssl != NULL)
3458
0
        heap = ssl->heap;
3459
29.9k
    return heap;
3460
29.9k
}
3461
3462
3463
#ifdef HAVE_SNI
3464
3465
WOLFSSL_ABI
3466
int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
3467
0
{
3468
0
    if (ssl == NULL)
3469
0
        return BAD_FUNC_ARG;
3470
3471
0
    return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
3472
0
}
3473
3474
3475
WOLFSSL_ABI
3476
int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
3477
                                                                    word16 size)
3478
28
{
3479
28
    if (ctx == NULL)
3480
0
        return BAD_FUNC_ARG;
3481
3482
28
    return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
3483
28
}
3484
3485
#ifndef NO_WOLFSSL_SERVER
3486
3487
void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
3488
0
{
3489
0
    if (ssl && ssl->extensions)
3490
0
        TLSX_SNI_SetOptions(ssl->extensions, type, options);
3491
0
}
3492
3493
3494
void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
3495
0
{
3496
0
    if (ctx && ctx->extensions)
3497
0
        TLSX_SNI_SetOptions(ctx->extensions, type, options);
3498
0
}
3499
3500
3501
byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
3502
0
{
3503
0
    return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
3504
0
}
3505
3506
3507
word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
3508
0
{
3509
0
    if (data)
3510
0
        *data = NULL;
3511
3512
0
    if (ssl && ssl->extensions)
3513
0
        return TLSX_SNI_GetRequest(ssl->extensions, type, data);
3514
3515
0
    return 0;
3516
0
}
3517
3518
3519
int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
3520
                              byte type, byte* sni, word32* inOutSz)
3521
0
{
3522
0
    if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
3523
0
        return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
3524
3525
0
    return BAD_FUNC_ARG;
3526
0
}
3527
3528
#endif /* NO_WOLFSSL_SERVER */
3529
3530
#endif /* HAVE_SNI */
3531
3532
3533
#ifdef HAVE_TRUSTED_CA
3534
3535
int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
3536
    const byte* certId, word32 certIdSz)
3537
0
{
3538
0
    if (ssl == NULL)
3539
0
        return BAD_FUNC_ARG;
3540
3541
0
    if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
3542
0
        if (certId != NULL || certIdSz != 0)
3543
0
            return BAD_FUNC_ARG;
3544
0
    }
3545
0
    else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
3546
0
        if (certId == NULL || certIdSz == 0)
3547
0
            return BAD_FUNC_ARG;
3548
0
    }
3549
0
    #ifndef NO_SHA
3550
0
    else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
3551
0
            type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
3552
0
        if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
3553
0
            return BAD_FUNC_ARG;
3554
0
    }
3555
0
    #endif
3556
0
    else
3557
0
        return BAD_FUNC_ARG;
3558
3559
0
    return TLSX_UseTrustedCA(&ssl->extensions,
3560
0
            type, certId, certIdSz, ssl->heap);
3561
0
}
3562
3563
#endif /* HAVE_TRUSTED_CA */
3564
3565
3566
#ifdef HAVE_MAX_FRAGMENT
3567
#ifndef NO_WOLFSSL_CLIENT
3568
3569
int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
3570
0
{
3571
0
    if (ssl == NULL)
3572
0
        return BAD_FUNC_ARG;
3573
3574
#ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
3575
    /* The following is a non-standard way to reconfigure the max packet size
3576
        post-handshake for wolfSSL_write/wolfSSL_read */
3577
    if (ssl->options.handShakeState == HANDSHAKE_DONE) {
3578
        switch (mfl) {
3579
            case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
3580
            case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
3581
            case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
3582
            case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
3583
            case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
3584
            case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
3585
            default: ssl->max_fragment = MAX_RECORD_SIZE; break;
3586
        }
3587
        return WOLFSSL_SUCCESS;
3588
    }
3589
#endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
3590
3591
    /* This call sets the max fragment TLS extension, which gets sent to server.
3592
        The server_hello response is what sets the `ssl->max_fragment` in
3593
        TLSX_MFL_Parse */
3594
0
    return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
3595
0
}
3596
3597
3598
int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
3599
0
{
3600
0
    if (ctx == NULL)
3601
0
        return BAD_FUNC_ARG;
3602
3603
0
    return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
3604
0
}
3605
3606
#endif /* NO_WOLFSSL_CLIENT */
3607
#endif /* HAVE_MAX_FRAGMENT */
3608
3609
#ifdef HAVE_TRUNCATED_HMAC
3610
#ifndef NO_WOLFSSL_CLIENT
3611
3612
int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
3613
0
{
3614
0
    if (ssl == NULL)
3615
0
        return BAD_FUNC_ARG;
3616
3617
0
    return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
3618
0
}
3619
3620
3621
int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
3622
0
{
3623
0
    if (ctx == NULL)
3624
0
        return BAD_FUNC_ARG;
3625
3626
0
    return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
3627
0
}
3628
3629
#endif /* NO_WOLFSSL_CLIENT */
3630
#endif /* HAVE_TRUNCATED_HMAC */
3631
3632
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
3633
3634
int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
3635
14.9k
{
3636
14.9k
    WOLFSSL_ENTER("wolfSSL_UseOCSPStapling");
3637
3638
14.9k
    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
3639
0
        return BAD_FUNC_ARG;
3640
3641
14.9k
    return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
3642
14.9k
                                          options, NULL, ssl->heap, ssl->devId);
3643
14.9k
}
3644
3645
3646
int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
3647
                                                                   byte options)
3648
0
{
3649
0
    WOLFSSL_ENTER("wolfSSL_CTX_UseOCSPStapling");
3650
3651
0
    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
3652
0
        return BAD_FUNC_ARG;
3653
3654
0
    return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
3655
0
                                          options, NULL, ctx->heap, ctx->devId);
3656
0
}
3657
3658
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
3659
3660
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
3661
3662
int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
3663
0
{
3664
0
    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
3665
0
        return BAD_FUNC_ARG;
3666
3667
0
    return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
3668
0
                                                options, ssl->heap, ssl->devId);
3669
0
}
3670
3671
3672
int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
3673
                                                                   byte options)
3674
0
{
3675
0
    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
3676
0
        return BAD_FUNC_ARG;
3677
3678
0
    return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
3679
0
                                                options, ctx->heap, ctx->devId);
3680
0
}
3681
3682
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
3683
3684
/* Elliptic Curves */
3685
#if defined(HAVE_SUPPORTED_CURVES)
3686
3687
static int isValidCurveGroup(word16 name)
3688
0
{
3689
0
    switch (name) {
3690
0
        case WOLFSSL_ECC_SECP160K1:
3691
0
        case WOLFSSL_ECC_SECP160R1:
3692
0
        case WOLFSSL_ECC_SECP160R2:
3693
0
        case WOLFSSL_ECC_SECP192K1:
3694
0
        case WOLFSSL_ECC_SECP192R1:
3695
0
        case WOLFSSL_ECC_SECP224K1:
3696
0
        case WOLFSSL_ECC_SECP224R1:
3697
0
        case WOLFSSL_ECC_SECP256K1:
3698
0
        case WOLFSSL_ECC_SECP256R1:
3699
0
        case WOLFSSL_ECC_SECP384R1:
3700
0
        case WOLFSSL_ECC_SECP521R1:
3701
0
        case WOLFSSL_ECC_BRAINPOOLP256R1:
3702
0
        case WOLFSSL_ECC_BRAINPOOLP384R1:
3703
0
        case WOLFSSL_ECC_BRAINPOOLP512R1:
3704
0
        case WOLFSSL_ECC_SM2P256V1:
3705
0
        case WOLFSSL_ECC_X25519:
3706
0
        case WOLFSSL_ECC_X448:
3707
3708
0
        case WOLFSSL_FFDHE_2048:
3709
0
        case WOLFSSL_FFDHE_3072:
3710
0
        case WOLFSSL_FFDHE_4096:
3711
0
        case WOLFSSL_FFDHE_6144:
3712
0
        case WOLFSSL_FFDHE_8192:
3713
3714
#ifdef HAVE_PQC
3715
        case WOLFSSL_KYBER_LEVEL1:
3716
        case WOLFSSL_KYBER_LEVEL3:
3717
        case WOLFSSL_KYBER_LEVEL5:
3718
    #ifdef HAVE_LIBOQS
3719
        case WOLFSSL_P256_KYBER_LEVEL1:
3720
        case WOLFSSL_P384_KYBER_LEVEL3:
3721
        case WOLFSSL_P521_KYBER_LEVEL5:
3722
    #endif
3723
#endif
3724
0
            return 1;
3725
3726
0
        default:
3727
0
            return 0;
3728
0
    }
3729
0
}
3730
3731
int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
3732
0
{
3733
0
    if (ssl == NULL || !isValidCurveGroup(name))
3734
0
        return BAD_FUNC_ARG;
3735
3736
0
    ssl->options.userCurves = 1;
3737
#if defined(NO_TLS)
3738
    return WOLFSSL_FAILURE;
3739
#else
3740
0
    return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
3741
0
#endif /* NO_TLS */
3742
0
}
3743
3744
3745
int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
3746
0
{
3747
0
    if (ctx == NULL || !isValidCurveGroup(name))
3748
0
        return BAD_FUNC_ARG;
3749
3750
0
    ctx->userCurves = 1;
3751
#if defined(NO_TLS)
3752
    return WOLFSSL_FAILURE;
3753
#else
3754
0
    return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
3755
0
#endif /* NO_TLS */
3756
0
}
3757
3758
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13)
3759
int  wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
3760
                                        int count)
3761
0
{
3762
0
    int i;
3763
0
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
3764
0
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
3765
0
    if (count == 0) {
3766
0
        WOLFSSL_MSG("Group count is zero");
3767
0
        return WOLFSSL_FAILURE;
3768
0
    }
3769
0
    for (i = 0; i < count; i++) {
3770
0
        if (isValidCurveGroup((word16)groups[i])) {
3771
0
            _groups[i] = groups[i];
3772
0
        }
3773
0
#ifdef HAVE_ECC
3774
0
        else {
3775
            /* groups may be populated with curve NIDs */
3776
0
            int oid = nid2oid(groups[i], oidCurveType);
3777
0
            int name = (int)GetCurveByOID(oid);
3778
0
            if (name == 0) {
3779
0
                WOLFSSL_MSG("Invalid group name");
3780
0
                return WOLFSSL_FAILURE;
3781
0
            }
3782
0
            _groups[i] = name;
3783
0
        }
3784
#else
3785
        else {
3786
            WOLFSSL_MSG("Invalid group name");
3787
            return WOLFSSL_FAILURE;
3788
        }
3789
#endif
3790
0
    }
3791
0
    return wolfSSL_CTX_set_groups(ctx, _groups, count) == WOLFSSL_SUCCESS ?
3792
0
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3793
0
}
3794
3795
int  wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
3796
0
{
3797
0
    int i;
3798
0
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
3799
0
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
3800
0
    if (count == 0) {
3801
0
        WOLFSSL_MSG("Group count is zero");
3802
0
        return WOLFSSL_FAILURE;
3803
0
    }
3804
0
    for (i = 0; i < count; i++) {
3805
0
        if (isValidCurveGroup((word16)groups[i])) {
3806
0
            _groups[i] = groups[i];
3807
0
        }
3808
0
#ifdef HAVE_ECC
3809
0
        else {
3810
            /* groups may be populated with curve NIDs */
3811
0
            int oid = nid2oid(groups[i], oidCurveType);
3812
0
            int name = (int)GetCurveByOID(oid);
3813
0
            if (name == 0) {
3814
0
                WOLFSSL_MSG("Invalid group name");
3815
0
                return WOLFSSL_FAILURE;
3816
0
            }
3817
0
            _groups[i] = name;
3818
0
        }
3819
#else
3820
        else {
3821
            WOLFSSL_MSG("Invalid group name");
3822
            return WOLFSSL_FAILURE;
3823
        }
3824
#endif
3825
0
    }
3826
0
    return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
3827
0
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3828
0
}
3829
#endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 */
3830
#endif /* HAVE_SUPPORTED_CURVES */
3831
3832
/* Application-Layer Protocol Negotiation */
3833
#ifdef HAVE_ALPN
3834
3835
WOLFSSL_ABI
3836
int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
3837
                    word32 protocol_name_listSz, byte options)
3838
0
{
3839
0
    char    *list, *ptr, **token;
3840
0
    word16  len;
3841
0
    int     idx = 0;
3842
0
    int     ret = WOLFSSL_FAILURE;
3843
3844
0
    WOLFSSL_ENTER("wolfSSL_UseALPN");
3845
3846
0
    if (ssl == NULL || protocol_name_list == NULL)
3847
0
        return BAD_FUNC_ARG;
3848
3849
0
    if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
3850
0
                                WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
3851
0
                                WOLFSSL_MAX_ALPN_NUMBER)) {
3852
0
        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
3853
0
        return BAD_FUNC_ARG;
3854
0
    }
3855
3856
0
    if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
3857
0
        !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
3858
0
            WOLFSSL_MSG("Invalid arguments, options not supported");
3859
0
            return BAD_FUNC_ARG;
3860
0
        }
3861
3862
3863
0
    list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
3864
0
                           DYNAMIC_TYPE_ALPN);
3865
0
    if (list == NULL) {
3866
0
        WOLFSSL_MSG("Memory failure");
3867
0
        return MEMORY_ERROR;
3868
0
    }
3869
3870
0
    token = (char **)XMALLOC(sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1), ssl->heap, DYNAMIC_TYPE_ALPN);
3871
0
    if (token == NULL) {
3872
0
        XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3873
0
        WOLFSSL_MSG("Memory failure");
3874
0
        return MEMORY_ERROR;
3875
0
    }
3876
0
    XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
3877
3878
0
    XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
3879
0
    list[protocol_name_listSz] = '\0';
3880
3881
    /* read all protocol name from the list */
3882
0
    token[idx] = XSTRTOK(list, ",", &ptr);
3883
0
    while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL)
3884
0
        token[++idx] = XSTRTOK(NULL, ",", &ptr);
3885
3886
    /* add protocol name list in the TLS extension in reverse order */
3887
0
    while ((idx--) > 0) {
3888
0
        len = (word16)XSTRLEN(token[idx]);
3889
3890
0
        ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
3891
0
                                                                     ssl->heap);
3892
0
        if (ret != WOLFSSL_SUCCESS) {
3893
0
            WOLFSSL_MSG("TLSX_UseALPN failure");
3894
0
            break;
3895
0
        }
3896
0
    }
3897
3898
0
    XFREE(token, ssl->heap, DYNAMIC_TYPE_ALPN);
3899
0
    XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3900
3901
0
    return ret;
3902
0
}
3903
3904
int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
3905
0
{
3906
0
    return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
3907
0
                               (void **)protocol_name, size);
3908
0
}
3909
3910
int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
3911
0
{
3912
0
    int i, len;
3913
0
    char *p;
3914
0
    byte *s;
3915
3916
0
    if (ssl == NULL || list == NULL || listSz == NULL)
3917
0
        return BAD_FUNC_ARG;
3918
3919
0
    if (ssl->alpn_peer_requested == NULL
3920
0
        || ssl->alpn_peer_requested_length == 0)
3921
0
        return BUFFER_ERROR;
3922
3923
    /* ssl->alpn_peer_requested are the original bytes sent in a ClientHello,
3924
     * formatted as (len-byte chars+)+. To turn n protocols into a
3925
     * comma-separated C string, one needs (n-1) commas and a final 0 byte
3926
     * which has the same length as the original.
3927
     * The returned length is the strlen() of the C string, so -1 of that. */
3928
0
    *listSz = ssl->alpn_peer_requested_length-1;
3929
0
    *list = p = (char *)XMALLOC(ssl->alpn_peer_requested_length, ssl->heap,
3930
0
                                DYNAMIC_TYPE_TLSX);
3931
0
    if (p == NULL)
3932
0
        return MEMORY_ERROR;
3933
3934
0
    for (i = 0, s = ssl->alpn_peer_requested;
3935
0
         i < ssl->alpn_peer_requested_length;
3936
0
         p += len, i += len)
3937
0
    {
3938
0
        if (i)
3939
0
            *p++ = ',';
3940
0
        len = s[i++];
3941
        /* guard against bad length bytes. */
3942
0
        if (i + len > ssl->alpn_peer_requested_length) {
3943
0
            XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
3944
0
            *list = NULL;
3945
0
            return WOLFSSL_FAILURE;
3946
0
        }
3947
0
        XMEMCPY(p, s + i, len);
3948
0
    }
3949
0
    *p = 0;
3950
3951
0
    return WOLFSSL_SUCCESS;
3952
0
}
3953
3954
3955
/* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
3956
int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
3957
0
{
3958
0
    if (ssl == NULL) {
3959
0
        return BAD_FUNC_ARG;
3960
0
    }
3961
3962
0
    XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
3963
0
    *list = NULL;
3964
3965
0
    return WOLFSSL_SUCCESS;
3966
0
}
3967
3968
#endif /* HAVE_ALPN */
3969
3970
/* Secure Renegotiation */
3971
#ifdef HAVE_SERVER_RENEGOTIATION_INFO
3972
3973
/* user is forcing ability to use secure renegotiation, we discourage it */
3974
int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
3975
240
{
3976
240
    int ret = BAD_FUNC_ARG;
3977
#if defined(NO_TLS)
3978
    (void)ssl;
3979
#else
3980
240
    if (ssl)
3981
240
        ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
3982
3983
240
    if (ret == WOLFSSL_SUCCESS) {
3984
237
        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
3985
3986
237
        if (extension)
3987
237
            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
3988
237
    }
3989
240
#endif /* !NO_TLS */
3990
240
    return ret;
3991
240
}
3992
3993
int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
3994
0
{
3995
0
    if (ctx == NULL)
3996
0
        return BAD_FUNC_ARG;
3997
3998
0
    ctx->useSecureReneg = 1;
3999
0
    return WOLFSSL_SUCCESS;
4000
0
}
4001
4002
#ifdef HAVE_SECURE_RENEGOTIATION
4003
/* do a secure renegotiation handshake, user forced, we discourage */
4004
static int _Rehandshake(WOLFSSL* ssl)
4005
0
{
4006
0
    int ret;
4007
4008
0
    if (ssl == NULL)
4009
0
        return BAD_FUNC_ARG;
4010
4011
0
    if (IsAtLeastTLSv1_3(ssl->version)) {
4012
0
        WOLFSSL_MSG("Secure Renegotiation not supported in TLS 1.3");
4013
0
        return SECURE_RENEGOTIATION_E;
4014
0
    }
4015
4016
0
    if (ssl->secure_renegotiation == NULL) {
4017
0
        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
4018
0
        return SECURE_RENEGOTIATION_E;
4019
0
    }
4020
4021
0
    if (ssl->secure_renegotiation->enabled == 0) {
4022
0
        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
4023
0
        return SECURE_RENEGOTIATION_E;
4024
0
    }
4025
4026
0
#ifdef WOLFSSL_DTLS
4027
0
    if (ssl->options.dtls && ssl->keys.dtls_epoch == 0xFFFF) {
4028
0
        WOLFSSL_MSG("Secure Renegotiation not allowed. Epoch would wrap");
4029
0
        return SECURE_RENEGOTIATION_E;
4030
0
    }
4031
0
#endif
4032
4033
    /* If the client started the renegotiation, the server will already
4034
     * have processed the client's hello. */
4035
0
    if (ssl->options.side != WOLFSSL_SERVER_END ||
4036
0
        ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
4037
4038
0
        if (ssl->options.handShakeState != HANDSHAKE_DONE) {
4039
0
            if (!ssl->options.handShakeDone) {
4040
0
                WOLFSSL_MSG("Can't renegotiate until initial "
4041
0
                            "handshake complete");
4042
0
                return SECURE_RENEGOTIATION_E;
4043
0
            }
4044
0
            else {
4045
0
                WOLFSSL_MSG("Renegotiation already started. "
4046
0
                            "Moving it forward.");
4047
0
                ret = wolfSSL_negotiate(ssl);
4048
0
                if (ret == WOLFSSL_SUCCESS)
4049
0
                    ssl->secure_rene_count++;
4050
0
                return ret;
4051
0
            }
4052
0
        }
4053
4054
        /* reset handshake states */
4055
0
        ssl->options.sendVerify = 0;
4056
0
        ssl->options.serverState = NULL_STATE;
4057
0
        ssl->options.clientState = NULL_STATE;
4058
0
        ssl->options.connectState  = CONNECT_BEGIN;
4059
0
        ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
4060
0
        ssl->options.handShakeState = NULL_STATE;
4061
0
        ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
4062
4063
0
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
4064
4065
0
        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
4066
4067
0
#if !defined(NO_WOLFSSL_SERVER)
4068
0
        if (ssl->options.side == WOLFSSL_SERVER_END) {
4069
0
            ret = SendHelloRequest(ssl);
4070
0
            if (ret != 0) {
4071
0
                ssl->error = ret;
4072
0
                return WOLFSSL_FATAL_ERROR;
4073
0
            }
4074
0
        }
4075
0
#endif /* !NO_WOLFSSL_SERVER */
4076
4077
0
        ret = InitHandshakeHashes(ssl);
4078
0
        if (ret != 0) {
4079
0
            ssl->error = ret;
4080
0
            return WOLFSSL_FATAL_ERROR;
4081
0
        }
4082
0
    }
4083
0
    ret = wolfSSL_negotiate(ssl);
4084
0
    if (ret == WOLFSSL_SUCCESS)
4085
0
        ssl->secure_rene_count++;
4086
0
    return ret;
4087
0
}
4088
4089
4090
/* do a secure renegotiation handshake, user forced, we discourage */
4091
int wolfSSL_Rehandshake(WOLFSSL* ssl)
4092
0
{
4093
0
    int ret;
4094
0
    WOLFSSL_ENTER("wolfSSL_Rehandshake");
4095
4096
0
    if (ssl == NULL)
4097
0
        return WOLFSSL_FAILURE;
4098
4099
0
#ifdef HAVE_SESSION_TICKET
4100
0
    ret = WOLFSSL_SUCCESS;
4101
0
#endif
4102
4103
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
4104
        /* Reset option to send certificate verify. */
4105
0
        ssl->options.sendVerify = 0;
4106
        /* Reset resuming flag to do full secure handshake. */
4107
0
        ssl->options.resuming = 0;
4108
0
    }
4109
0
    else {
4110
        /* Reset resuming flag to do full secure handshake. */
4111
0
        ssl->options.resuming = 0;
4112
0
        #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_CLIENT)
4113
            /* Clearing the ticket. */
4114
0
            ret = wolfSSL_UseSessionTicket(ssl);
4115
0
        #endif
4116
0
    }
4117
    /* CLIENT/SERVER: Reset peer authentication for full secure handshake. */
4118
0
    ssl->options.peerAuthGood = 0;
4119
4120
0
#ifdef HAVE_SESSION_TICKET
4121
0
    if (ret == WOLFSSL_SUCCESS)
4122
0
#endif
4123
0
        ret = _Rehandshake(ssl);
4124
4125
0
    return ret;
4126
0
}
4127
4128
4129
#ifndef NO_WOLFSSL_CLIENT
4130
4131
/* do a secure resumption handshake, user forced, we discourage */
4132
int wolfSSL_SecureResume(WOLFSSL* ssl)
4133
0
{
4134
0
    WOLFSSL_ENTER("wolfSSL_SecureResume");
4135
4136
0
    if (ssl == NULL)
4137
0
        return BAD_FUNC_ARG;
4138
4139
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
4140
0
        ssl->error = SIDE_ERROR;
4141
0
        return WOLFSSL_FATAL_ERROR;
4142
0
    }
4143
4144
0
    return _Rehandshake(ssl);
4145
0
}
4146
4147
#endif /* NO_WOLFSSL_CLIENT */
4148
4149
#endif /* HAVE_SECURE_RENEGOTIATION */
4150
4151
long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
4152
0
{
4153
0
    WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
4154
4155
0
    if (!ssl || !ssl->secure_renegotiation)
4156
0
        return WOLFSSL_FAILURE;
4157
0
    return ssl->secure_renegotiation->enabled;
4158
0
}
4159
4160
#endif /* HAVE_SECURE_RENEGOTIATION_INFO */
4161
4162
#if defined(HAVE_SESSION_TICKET)
4163
/* Session Ticket */
4164
4165
#if !defined(NO_WOLFSSL_SERVER)
4166
int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
4167
0
{
4168
0
    if (ctx == NULL)
4169
0
        return BAD_FUNC_ARG;
4170
4171
0
    ctx->noTicketTls12 = 1;
4172
4173
0
    return WOLFSSL_SUCCESS;
4174
0
}
4175
4176
int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
4177
0
{
4178
0
    if (ssl == NULL)
4179
0
        return BAD_FUNC_ARG;
4180
4181
0
    ssl->options.noTicketTls12 = 1;
4182
4183
0
    return WOLFSSL_SUCCESS;
4184
0
}
4185
4186
/* WOLFSSL_SUCCESS on ok */
4187
int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
4188
20
{
4189
20
    if (ctx == NULL)
4190
0
        return BAD_FUNC_ARG;
4191
4192
20
    ctx->ticketEncCb = cb;
4193
4194
20
    return WOLFSSL_SUCCESS;
4195
20
}
4196
4197
/* set hint interval, WOLFSSL_SUCCESS on ok */
4198
int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
4199
0
{
4200
0
    if (ctx == NULL)
4201
0
        return BAD_FUNC_ARG;
4202
4203
0
    ctx->ticketHint = hint;
4204
4205
0
    return WOLFSSL_SUCCESS;
4206
0
}
4207
4208
/* set user context, WOLFSSL_SUCCESS on ok */
4209
int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
4210
0
{
4211
0
    if (ctx == NULL)
4212
0
        return BAD_FUNC_ARG;
4213
4214
0
    ctx->ticketEncCtx = userCtx;
4215
4216
0
    return WOLFSSL_SUCCESS;
4217
0
}
4218
4219
/* get user context - returns userCtx on success, NULL on failure */
4220
void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
4221
0
{
4222
0
    if (ctx == NULL)
4223
0
        return NULL;
4224
4225
0
    return ctx->ticketEncCtx;
4226
0
}
4227
4228
#ifdef WOLFSSL_TLS13
4229
/* set the maximum number of tickets to send
4230
 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
4231
 */
4232
int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
4233
0
{
4234
0
    if (ctx == NULL)
4235
0
        return WOLFSSL_FAILURE;
4236
4237
0
    ctx->maxTicketTls13 = (unsigned int)mxTickets;
4238
0
    return WOLFSSL_SUCCESS;
4239
0
}
4240
4241
/* get the maximum number of tickets to send
4242
 * return number of tickets set to be sent
4243
 */
4244
size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
4245
0
{
4246
0
    if (ctx == NULL)
4247
0
        return 0;
4248
4249
0
    return (size_t)ctx->maxTicketTls13;
4250
0
}
4251
#endif /* WOLFSSL_TLS13 */
4252
#endif /* !NO_WOLFSSL_SERVER */
4253
4254
#if !defined(NO_WOLFSSL_CLIENT)
4255
int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
4256
0
{
4257
0
    if (ssl == NULL)
4258
0
        return BAD_FUNC_ARG;
4259
4260
0
    return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
4261
0
}
4262
4263
int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
4264
28
{
4265
28
    if (ctx == NULL)
4266
0
        return BAD_FUNC_ARG;
4267
4268
28
    return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
4269
28
}
4270
4271
int wolfSSL_get_SessionTicket(WOLFSSL* ssl, byte* buf, word32* bufSz)
4272
0
{
4273
0
    if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
4274
0
        return BAD_FUNC_ARG;
4275
4276
0
    if (ssl->session->ticketLen <= *bufSz) {
4277
0
        XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen);
4278
0
        *bufSz = ssl->session->ticketLen;
4279
0
    }
4280
0
    else
4281
0
        *bufSz = 0;
4282
4283
0
    return WOLFSSL_SUCCESS;
4284
0
}
4285
4286
int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
4287
                                          word32 bufSz)
4288
0
{
4289
0
    if (ssl == NULL || (buf == NULL && bufSz > 0))
4290
0
        return BAD_FUNC_ARG;
4291
4292
0
    if (bufSz > 0) {
4293
        /* Ticket will fit into static ticket */
4294
0
        if (bufSz <= SESSION_TICKET_LEN) {
4295
0
            if (ssl->session->ticketLenAlloc > 0) {
4296
0
                XFREE(ssl->session->ticket, ssl->session->heap,
4297
0
                      DYNAMIC_TYPE_SESSION_TICK);
4298
0
                ssl->session->ticketLenAlloc = 0;
4299
0
                ssl->session->ticket = ssl->session->staticTicket;
4300
0
            }
4301
0
        }
4302
0
        else { /* Ticket requires dynamic ticket storage */
4303
0
            if (ssl->session->ticketLen < bufSz) { /* is dyn buffer big enough */
4304
0
                if (ssl->session->ticketLenAlloc > 0) {
4305
0
                    XFREE(ssl->session->ticket, ssl->session->heap,
4306
0
                          DYNAMIC_TYPE_SESSION_TICK);
4307
0
                }
4308
0
                ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
4309
0
                        DYNAMIC_TYPE_SESSION_TICK);
4310
0
                if(ssl->session->ticket == NULL) {
4311
0
                    ssl->session->ticket = ssl->session->staticTicket;
4312
0
                    ssl->session->ticketLenAlloc = 0;
4313
0
                    return MEMORY_ERROR;
4314
0
                }
4315
0
                ssl->session->ticketLenAlloc = (word16)bufSz;
4316
0
            }
4317
0
        }
4318
0
        XMEMCPY(ssl->session->ticket, buf, bufSz);
4319
0
    }
4320
0
    ssl->session->ticketLen = (word16)bufSz;
4321
4322
0
    return WOLFSSL_SUCCESS;
4323
0
}
4324
4325
4326
int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
4327
                                 CallbackSessionTicket cb, void* ctx)
4328
0
{
4329
0
    if (ssl == NULL)
4330
0
        return BAD_FUNC_ARG;
4331
4332
0
    ssl->session_ticket_cb = cb;
4333
0
    ssl->session_ticket_ctx = ctx;
4334
4335
0
    return WOLFSSL_SUCCESS;
4336
0
}
4337
#endif /* !NO_WOLFSSL_CLIENT */
4338
4339
#endif /* HAVE_SESSION_TICKET */
4340
4341
4342
#ifdef HAVE_EXTENDED_MASTER
4343
#ifndef NO_WOLFSSL_CLIENT
4344
4345
int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
4346
0
{
4347
0
    if (ctx == NULL)
4348
0
        return BAD_FUNC_ARG;
4349
4350
0
    ctx->haveEMS = 0;
4351
4352
0
    return WOLFSSL_SUCCESS;
4353
0
}
4354
4355
4356
int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
4357
0
{
4358
0
    if (ssl == NULL)
4359
0
        return BAD_FUNC_ARG;
4360
4361
0
    ssl->options.haveEMS = 0;
4362
4363
0
    return WOLFSSL_SUCCESS;
4364
0
}
4365
4366
#endif
4367
#endif
4368
4369
4370
#ifndef WOLFSSL_LEANPSK
4371
4372
int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
4373
0
{
4374
0
    int ret;
4375
0
    int oldFlags;
4376
4377
0
    WOLFSSL_ENTER("wolfSSL_send");
4378
4379
0
    if (ssl == NULL || data == NULL || sz < 0)
4380
0
        return BAD_FUNC_ARG;
4381
4382
0
    oldFlags = ssl->wflags;
4383
4384
0
    ssl->wflags = flags;
4385
0
    ret = wolfSSL_write(ssl, data, sz);
4386
0
    ssl->wflags = oldFlags;
4387
4388
0
    WOLFSSL_LEAVE("wolfSSL_send", ret);
4389
4390
0
    return ret;
4391
0
}
4392
4393
4394
int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
4395
0
{
4396
0
    int ret;
4397
0
    int oldFlags;
4398
4399
0
    WOLFSSL_ENTER("wolfSSL_recv");
4400
4401
0
    if (ssl == NULL || data == NULL || sz < 0)
4402
0
        return BAD_FUNC_ARG;
4403
4404
0
    oldFlags = ssl->rflags;
4405
4406
0
    ssl->rflags = flags;
4407
0
    ret = wolfSSL_read(ssl, data, sz);
4408
0
    ssl->rflags = oldFlags;
4409
4410
0
    WOLFSSL_LEAVE("wolfSSL_recv", ret);
4411
4412
0
    return ret;
4413
0
}
4414
#endif
4415
4416
4417
/* WOLFSSL_SUCCESS on ok */
4418
WOLFSSL_ABI
4419
int wolfSSL_shutdown(WOLFSSL* ssl)
4420
0
{
4421
0
    int  ret = WOLFSSL_FATAL_ERROR;
4422
0
    WOLFSSL_ENTER("wolfSSL_shutdown");
4423
4424
0
    if (ssl == NULL)
4425
0
        return WOLFSSL_FATAL_ERROR;
4426
4427
0
    if (ssl->options.quietShutdown) {
4428
0
        WOLFSSL_MSG("quiet shutdown, no close notify sent");
4429
0
        ret = WOLFSSL_SUCCESS;
4430
0
    }
4431
0
    else {
4432
        /* try to send close notify, not an error if can't */
4433
0
        if (!ssl->options.isClosed && !ssl->options.connReset &&
4434
0
                                      !ssl->options.sentNotify) {
4435
0
            ssl->error = SendAlert(ssl, alert_warning, close_notify);
4436
0
            if (ssl->error < 0) {
4437
0
                WOLFSSL_ERROR(ssl->error);
4438
0
                return WOLFSSL_FATAL_ERROR;
4439
0
            }
4440
0
            ssl->options.sentNotify = 1;  /* don't send close_notify twice */
4441
0
            if (ssl->options.closeNotify) {
4442
0
                ret = WOLFSSL_SUCCESS;
4443
0
                ssl->options.shutdownDone = 1;
4444
0
            }
4445
0
            else {
4446
0
                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
4447
0
                WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4448
0
                return ret;
4449
0
            }
4450
0
        }
4451
4452
#ifdef WOLFSSL_SHUTDOWNONCE
4453
        if (ssl->options.isClosed || ssl->options.connReset) {
4454
            /* Shutdown has already occurred.
4455
             * Caller is free to ignore this error. */
4456
            return SSL_SHUTDOWN_ALREADY_DONE_E;
4457
        }
4458
#endif
4459
4460
        /* call wolfSSL_shutdown again for bidirectional shutdown */
4461
0
        if (ssl->options.sentNotify && !ssl->options.closeNotify) {
4462
0
            ret = ProcessReply(ssl);
4463
0
            if ((ret == ZERO_RETURN) || (ret == SOCKET_ERROR_E)) {
4464
                /* simulate OpenSSL behavior */
4465
0
                ssl->options.shutdownDone = 1;
4466
                /* Clear error */
4467
0
                ssl->error = WOLFSSL_ERROR_NONE;
4468
0
                ret = WOLFSSL_SUCCESS;
4469
0
            } else if (ret == MEMORY_E) {
4470
0
                ret = WOLFSSL_FATAL_ERROR;
4471
0
            } else if (ssl->error == WOLFSSL_ERROR_NONE) {
4472
0
                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
4473
0
            } else {
4474
0
                WOLFSSL_ERROR(ssl->error);
4475
0
                ret = WOLFSSL_FATAL_ERROR;
4476
0
            }
4477
0
        }
4478
0
    }
4479
4480
0
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
4481
    /* reset WOLFSSL structure state for possible reuse */
4482
0
    if (ret == WOLFSSL_SUCCESS) {
4483
0
        if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
4484
0
            WOLFSSL_MSG("could not clear WOLFSSL");
4485
0
            ret = WOLFSSL_FATAL_ERROR;
4486
0
        }
4487
0
    }
4488
0
#endif
4489
4490
0
    WOLFSSL_LEAVE("wolfSSL_shutdown", ret);
4491
4492
0
    return ret;
4493
0
}
4494
4495
4496
/* get current error state value */
4497
int wolfSSL_state(WOLFSSL* ssl)
4498
0
{
4499
0
    if (ssl == NULL) {
4500
0
        return BAD_FUNC_ARG;
4501
0
    }
4502
4503
0
    return ssl->error;
4504
0
}
4505
4506
4507
WOLFSSL_ABI
4508
int wolfSSL_get_error(WOLFSSL* ssl, int ret)
4509
0
{
4510
0
    WOLFSSL_ENTER("wolfSSL_get_error");
4511
4512
0
    if (ret > 0)
4513
0
        return WOLFSSL_ERROR_NONE;
4514
0
    if (ssl == NULL)
4515
0
        return BAD_FUNC_ARG;
4516
4517
0
    WOLFSSL_LEAVE("wolfSSL_get_error", ssl->error);
4518
4519
    /* make sure converted types are handled in SetErrorString() too */
4520
0
    if (ssl->error == WANT_READ)
4521
0
        return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
4522
0
    else if (ssl->error == WANT_WRITE)
4523
0
        return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
4524
0
    else if (ssl->error == ZERO_RETURN || ssl->options.shutdownDone)
4525
0
        return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
4526
0
#ifdef OPENSSL_EXTRA
4527
0
    else if (ssl->error == SOCKET_PEER_CLOSED_E)
4528
0
        return WOLFSSL_ERROR_SYSCALL;           /* convert to OpenSSL type */
4529
0
#endif
4530
#if defined(WOLFSSL_HAPROXY)
4531
    return GetX509Error(ssl->error);
4532
#else
4533
0
    return (ssl->error);
4534
0
#endif
4535
0
}
4536
4537
4538
/* retrieve alert history, WOLFSSL_SUCCESS on ok */
4539
int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
4540
0
{
4541
0
    if (ssl && h) {
4542
0
        *h = ssl->alert_history;
4543
0
    }
4544
0
    return WOLFSSL_SUCCESS;
4545
0
}
4546
4547
#ifdef OPENSSL_EXTRA
4548
/* returns SSL_WRITING, SSL_READING or SSL_NOTHING */
4549
int wolfSSL_want(WOLFSSL* ssl)
4550
0
{
4551
0
    int rw_state = SSL_NOTHING;
4552
0
    if (ssl) {
4553
0
        if (ssl->error == WANT_READ)
4554
0
            rw_state = SSL_READING;
4555
0
        else if (ssl->error == WANT_WRITE)
4556
0
            rw_state = SSL_WRITING;
4557
0
    }
4558
0
    return rw_state;
4559
0
}
4560
#endif
4561
4562
/* return TRUE if current error is want read */
4563
int wolfSSL_want_read(WOLFSSL* ssl)
4564
0
{
4565
0
    WOLFSSL_ENTER("wolfSSL_want_read");
4566
0
    if (ssl->error == WANT_READ)
4567
0
        return 1;
4568
4569
0
    return 0;
4570
0
}
4571
4572
4573
/* return TRUE if current error is want write */
4574
int wolfSSL_want_write(WOLFSSL* ssl)
4575
0
{
4576
0
    WOLFSSL_ENTER("wolfSSL_want_write");
4577
0
    if (ssl->error == WANT_WRITE)
4578
0
        return 1;
4579
4580
0
    return 0;
4581
0
}
4582
4583
4584
char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
4585
0
{
4586
0
    WOLFSSL_ENTER("wolfSSL_ERR_error_string");
4587
0
    if (data) {
4588
0
        SetErrorString((int)errNumber, data);
4589
0
        return data;
4590
0
    }
4591
0
    else {
4592
0
        static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
4593
0
        SetErrorString((int)errNumber, tmp);
4594
0
        return tmp;
4595
0
    }
4596
0
}
4597
4598
4599
void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
4600
0
{
4601
0
    WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
4602
0
    if (len >= WOLFSSL_MAX_ERROR_SZ)
4603
0
        wolfSSL_ERR_error_string(e, buf);
4604
0
    else {
4605
0
        WOLFSSL_MSG("Error buffer too short, truncating");
4606
0
        if (len) {
4607
0
            char tmp[WOLFSSL_MAX_ERROR_SZ];
4608
0
            wolfSSL_ERR_error_string(e, tmp);
4609
0
            XMEMCPY(buf, tmp, len-1);
4610
0
            buf[len-1] = '\0';
4611
0
        }
4612
0
    }
4613
0
}
4614
4615
4616
/* don't free temporary arrays at end of handshake */
4617
void wolfSSL_KeepArrays(WOLFSSL* ssl)
4618
0
{
4619
0
    if (ssl)
4620
0
        ssl->options.saveArrays = 1;
4621
0
}
4622
4623
4624
/* user doesn't need temporary arrays anymore, Free */
4625
void wolfSSL_FreeArrays(WOLFSSL* ssl)
4626
0
{
4627
0
    if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
4628
0
        ssl->options.saveArrays = 0;
4629
0
        FreeArrays(ssl, 1);
4630
0
    }
4631
0
}
4632
4633
/* Set option to indicate that the resources are not to be freed after
4634
 * handshake.
4635
 *
4636
 * ssl  The SSL/TLS object.
4637
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4638
 */
4639
int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
4640
0
{
4641
0
    if (ssl == NULL)
4642
0
        return BAD_FUNC_ARG;
4643
4644
0
    ssl->options.keepResources = 1;
4645
4646
0
    return 0;
4647
0
}
4648
4649
/* Free the handshake resources after handshake.
4650
 *
4651
 * ssl  The SSL/TLS object.
4652
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4653
 */
4654
int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
4655
0
{
4656
0
    if (ssl == NULL)
4657
0
        return BAD_FUNC_ARG;
4658
4659
0
    FreeHandshakeResources(ssl);
4660
4661
0
    return 0;
4662
0
}
4663
4664
/* Use the client's order of preference when matching cipher suites.
4665
 *
4666
 * ssl  The SSL/TLS context object.
4667
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4668
 */
4669
int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
4670
0
{
4671
0
    if (ctx == NULL)
4672
0
        return BAD_FUNC_ARG;
4673
4674
0
    ctx->useClientOrder = 1;
4675
4676
0
    return 0;
4677
0
}
4678
4679
/* Use the client's order of preference when matching cipher suites.
4680
 *
4681
 * ssl  The SSL/TLS object.
4682
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
4683
 */
4684
int wolfSSL_UseClientSuites(WOLFSSL* ssl)
4685
0
{
4686
0
    if (ssl == NULL)
4687
0
        return BAD_FUNC_ARG;
4688
4689
0
    ssl->options.useClientOrder = 1;
4690
4691
0
    return 0;
4692
0
}
4693
4694
#ifdef WOLFSSL_DTLS
4695
const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder)
4696
0
{
4697
0
#ifndef WOLFSSL_AEAD_ONLY
4698
0
    Keys* keys = NULL;
4699
4700
0
    (void)epochOrder;
4701
4702
0
    if (ssl == NULL)
4703
0
        return NULL;
4704
4705
0
#ifdef HAVE_SECURE_RENEGOTIATION
4706
0
    switch (epochOrder) {
4707
0
    case PEER_ORDER:
4708
0
        if (IsDtlsMsgSCRKeys(ssl))
4709
0
            keys = &ssl->secure_renegotiation->tmp_keys;
4710
0
        else
4711
0
            keys = &ssl->keys;
4712
0
        break;
4713
0
    case PREV_ORDER:
4714
0
        keys = &ssl->keys;
4715
0
        break;
4716
0
    case CUR_ORDER:
4717
0
        if (DtlsUseSCRKeys(ssl))
4718
0
            keys = &ssl->secure_renegotiation->tmp_keys;
4719
0
        else
4720
0
            keys = &ssl->keys;
4721
0
        break;
4722
0
    default:
4723
0
        WOLFSSL_MSG("Unknown epoch order");
4724
0
        return NULL;
4725
0
    }
4726
#else
4727
    keys = &ssl->keys;
4728
#endif
4729
4730
0
    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
4731
0
         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
4732
0
        return keys->client_write_MAC_secret;
4733
0
    else
4734
0
        return keys->server_write_MAC_secret;
4735
#else
4736
    (void)ssl;
4737
    (void)verify;
4738
    (void)epochOrder;
4739
4740
    return NULL;
4741
#endif
4742
0
}
4743
#endif /* WOLFSSL_DTLS */
4744
4745
const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
4746
292
{
4747
292
#ifndef WOLFSSL_AEAD_ONLY
4748
292
    if (ssl == NULL)
4749
0
        return NULL;
4750
4751
292
    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
4752
292
         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
4753
240
        return ssl->keys.client_write_MAC_secret;
4754
52
    else
4755
52
        return ssl->keys.server_write_MAC_secret;
4756
#else
4757
    (void)ssl;
4758
    (void)verify;
4759
4760
    return NULL;
4761
#endif
4762
292
}
4763
4764
int wolfSSL_GetSide(WOLFSSL* ssl)
4765
0
{
4766
0
    if (ssl)
4767
0
        return ssl->options.side;
4768
4769
0
    return BAD_FUNC_ARG;
4770
0
}
4771
4772
#ifdef ATOMIC_USER
4773
4774
void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
4775
{
4776
    if (ctx)
4777
        ctx->MacEncryptCb = cb;
4778
}
4779
4780
4781
void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
4782
{
4783
    if (ssl)
4784
        ssl->MacEncryptCtx = ctx;
4785
}
4786
4787
4788
void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
4789
{
4790
    if (ssl)
4791
        return ssl->MacEncryptCtx;
4792
4793
    return NULL;
4794
}
4795
4796
4797
void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
4798
{
4799
    if (ctx)
4800
        ctx->DecryptVerifyCb = cb;
4801
}
4802
4803
4804
void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
4805
{
4806
    if (ssl)
4807
        ssl->DecryptVerifyCtx = ctx;
4808
}
4809
4810
4811
void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
4812
{
4813
    if (ssl)
4814
        return ssl->DecryptVerifyCtx;
4815
4816
    return NULL;
4817
}
4818
4819
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
4820
/**
4821
 * Set the callback, against the context, that encrypts then MACs.
4822
 *
4823
 * ctx  SSL/TLS context.
4824
 * cb   Callback function to use with Encrypt-Then-MAC.
4825
 */
4826
void  wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
4827
{
4828
    if (ctx)
4829
        ctx->EncryptMacCb = cb;
4830
}
4831
4832
/**
4833
 * Set the context to use with callback that encrypts then MACs.
4834
 *
4835
 * ssl  SSL/TLS object.
4836
 * ctx  Callback function's context.
4837
 */
4838
void  wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
4839
{
4840
    if (ssl)
4841
        ssl->EncryptMacCtx = ctx;
4842
}
4843
4844
/**
4845
 * Get the context being used with callback that encrypts then MACs.
4846
 *
4847
 * ssl  SSL/TLS object.
4848
 * returns callback function's context or NULL if SSL/TLS object is NULL.
4849
 */
4850
void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
4851
{
4852
    if (ssl)
4853
        return ssl->EncryptMacCtx;
4854
4855
    return NULL;
4856
}
4857
4858
4859
/**
4860
 * Set the callback, against the context, that MAC verifies then decrypts.
4861
 *
4862
 * ctx  SSL/TLS context.
4863
 * cb   Callback function to use with Encrypt-Then-MAC.
4864
 */
4865
void  wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
4866
{
4867
    if (ctx)
4868
        ctx->VerifyDecryptCb = cb;
4869
}
4870
4871
/**
4872
 * Set the context to use with callback that MAC verifies then decrypts.
4873
 *
4874
 * ssl  SSL/TLS object.
4875
 * ctx  Callback function's context.
4876
 */
4877
void  wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
4878
{
4879
    if (ssl)
4880
        ssl->VerifyDecryptCtx = ctx;
4881
}
4882
4883
/**
4884
 * Get the context being used with callback that MAC verifies then decrypts.
4885
 *
4886
 * ssl  SSL/TLS object.
4887
 * returns callback function's context or NULL if SSL/TLS object is NULL.
4888
 */
4889
void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
4890
{
4891
    if (ssl)
4892
        return ssl->VerifyDecryptCtx;
4893
4894
    return NULL;
4895
}
4896
#endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
4897
4898
4899
4900
const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
4901
{
4902
    if (ssl)
4903
        return ssl->keys.client_write_key;
4904
4905
    return NULL;
4906
}
4907
4908
4909
const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
4910
{
4911
    if (ssl)
4912
        return ssl->keys.client_write_IV;
4913
4914
    return NULL;
4915
}
4916
4917
4918
const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
4919
{
4920
    if (ssl)
4921
        return ssl->keys.server_write_key;
4922
4923
    return NULL;
4924
}
4925
4926
4927
const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
4928
{
4929
    if (ssl)
4930
        return ssl->keys.server_write_IV;
4931
4932
    return NULL;
4933
}
4934
4935
int wolfSSL_GetKeySize(WOLFSSL* ssl)
4936
{
4937
    if (ssl)
4938
        return ssl->specs.key_size;
4939
4940
    return BAD_FUNC_ARG;
4941
}
4942
4943
4944
int wolfSSL_GetIVSize(WOLFSSL* ssl)
4945
{
4946
    if (ssl)
4947
        return ssl->specs.iv_size;
4948
4949
    return BAD_FUNC_ARG;
4950
}
4951
4952
4953
int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
4954
{
4955
    if (ssl)
4956
        return ssl->specs.bulk_cipher_algorithm;
4957
4958
    return BAD_FUNC_ARG;
4959
}
4960
4961
4962
int wolfSSL_GetCipherType(WOLFSSL* ssl)
4963
{
4964
    if (ssl == NULL)
4965
        return BAD_FUNC_ARG;
4966
4967
#ifndef WOLFSSL_AEAD_ONLY
4968
    if (ssl->specs.cipher_type == block)
4969
        return WOLFSSL_BLOCK_TYPE;
4970
    if (ssl->specs.cipher_type == stream)
4971
        return WOLFSSL_STREAM_TYPE;
4972
#endif
4973
    if (ssl->specs.cipher_type == aead)
4974
        return WOLFSSL_AEAD_TYPE;
4975
4976
    return -1;
4977
}
4978
4979
4980
int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
4981
{
4982
    if (ssl == NULL)
4983
        return BAD_FUNC_ARG;
4984
4985
    return ssl->specs.block_size;
4986
}
4987
4988
4989
int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
4990
{
4991
    if (ssl == NULL)
4992
        return BAD_FUNC_ARG;
4993
4994
    return ssl->specs.aead_mac_size;
4995
}
4996
4997
4998
int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
4999
{
5000
    if (ssl == NULL)
5001
        return BAD_FUNC_ARG;
5002
5003
    if (ssl->options.tls1_1)
5004
        return 1;
5005
5006
    return 0;
5007
}
5008
5009
5010
5011
int wolfSSL_GetHmacSize(WOLFSSL* ssl)
5012
{
5013
    /* AEAD ciphers don't have HMAC keys */
5014
    if (ssl)
5015
        return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
5016
5017
    return BAD_FUNC_ARG;
5018
}
5019
5020
#ifdef WORD64_AVAILABLE
5021
int wolfSSL_GetPeerSequenceNumber(WOLFSSL* ssl, word64 *seq)
5022
{
5023
    if ((ssl == NULL) || (seq == NULL))
5024
        return BAD_FUNC_ARG;
5025
5026
    *seq = ((word64)ssl->keys.peer_sequence_number_hi << 32) |
5027
                    ssl->keys.peer_sequence_number_lo;
5028
    return !(*seq);
5029
}
5030
5031
int wolfSSL_GetSequenceNumber(WOLFSSL* ssl, word64 *seq)
5032
{
5033
    if ((ssl == NULL) || (seq == NULL))
5034
        return BAD_FUNC_ARG;
5035
5036
    *seq = ((word64)ssl->keys.sequence_number_hi << 32) |
5037
                    ssl->keys.sequence_number_lo;
5038
    return !(*seq);
5039
}
5040
#endif
5041
5042
#endif /* ATOMIC_USER */
5043
5044
#ifndef NO_CERTS
5045
WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
5046
0
{
5047
0
    WOLFSSL_CERT_MANAGER* cm = NULL;
5048
0
    if (ctx)
5049
0
        cm = ctx->cm;
5050
0
    return cm;
5051
0
}
5052
#endif /* NO_CERTS */
5053
5054
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) \
5055
    && defined(XFPRINTF)
5056
5057
void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
5058
0
{
5059
0
    char data[WOLFSSL_MAX_ERROR_SZ + 1];
5060
5061
0
    WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
5062
0
    SetErrorString(err, data);
5063
0
    if (XFPRINTF(fp, "%s", data) < 0)
5064
0
        WOLFSSL_MSG("fprintf failed in wolfSSL_ERR_print_errors_fp");
5065
0
}
5066
5067
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
5068
void wolfSSL_ERR_dump_errors_fp(XFILE fp)
5069
0
{
5070
0
    wc_ERR_print_errors_fp(fp);
5071
0
}
5072
5073
void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
5074
                                            void *u), void *u)
5075
0
{
5076
0
    wc_ERR_print_errors_cb(cb, u);
5077
0
}
5078
#endif
5079
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM && XFPRINTF */
5080
5081
/*
5082
 * TODO This ssl parameter needs to be changed to const once our ABI checker
5083
 *      stops flagging qualifier additions as ABI breaking.
5084
 */
5085
WOLFSSL_ABI
5086
int wolfSSL_pending(WOLFSSL* ssl)
5087
0
{
5088
0
    WOLFSSL_ENTER("wolfSSL_pending");
5089
0
    if (ssl == NULL)
5090
0
        return WOLFSSL_FAILURE;
5091
5092
0
    return ssl->buffers.clearOutputBuffer.length;
5093
0
}
5094
5095
int wolfSSL_has_pending(const WOLFSSL* ssl)
5096
0
{
5097
0
    WOLFSSL_ENTER("wolfSSL_has_pending");
5098
0
    if (ssl == NULL)
5099
0
        return WOLFSSL_FAILURE;
5100
5101
0
    return ssl->buffers.clearOutputBuffer.length > 0;
5102
0
}
5103
5104
#ifndef WOLFSSL_LEANPSK
5105
/* turn on handshake group messages for context */
5106
int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
5107
0
{
5108
0
    if (ctx == NULL)
5109
0
       return BAD_FUNC_ARG;
5110
5111
0
    ctx->groupMessages = 1;
5112
5113
0
    return WOLFSSL_SUCCESS;
5114
0
}
5115
#endif
5116
5117
5118
#ifndef NO_WOLFSSL_CLIENT
5119
/* connect enough to get peer cert chain */
5120
int wolfSSL_connect_cert(WOLFSSL* ssl)
5121
0
{
5122
0
    int  ret;
5123
5124
0
    if (ssl == NULL)
5125
0
        return WOLFSSL_FAILURE;
5126
5127
0
    ssl->options.certOnly = 1;
5128
0
    ret = wolfSSL_connect(ssl);
5129
0
    ssl->options.certOnly   = 0;
5130
5131
0
    return ret;
5132
0
}
5133
#endif
5134
5135
5136
#ifndef WOLFSSL_LEANPSK
5137
/* turn on handshake group messages for ssl object */
5138
int wolfSSL_set_group_messages(WOLFSSL* ssl)
5139
0
{
5140
0
    if (ssl == NULL)
5141
0
       return BAD_FUNC_ARG;
5142
5143
0
    ssl->options.groupMessages = 1;
5144
5145
0
    return WOLFSSL_SUCCESS;
5146
0
}
5147
5148
5149
/* make minVersion the internal equivalent SSL version */
5150
static int SetMinVersionHelper(byte* minVersion, int version)
5151
0
{
5152
#ifdef NO_TLS
5153
    (void)minVersion;
5154
#endif
5155
5156
0
    switch (version) {
5157
0
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
5158
0
        case WOLFSSL_SSLV3:
5159
0
            *minVersion = SSLv3_MINOR;
5160
0
            break;
5161
0
#endif
5162
5163
0
#ifndef NO_TLS
5164
0
    #ifndef NO_OLD_TLS
5165
0
        #ifdef WOLFSSL_ALLOW_TLSV10
5166
0
        case WOLFSSL_TLSV1:
5167
0
            *minVersion = TLSv1_MINOR;
5168
0
            break;
5169
0
        #endif
5170
5171
0
        case WOLFSSL_TLSV1_1:
5172
0
            *minVersion = TLSv1_1_MINOR;
5173
0
            break;
5174
0
    #endif
5175
0
    #ifndef WOLFSSL_NO_TLS12
5176
0
        case WOLFSSL_TLSV1_2:
5177
0
            *minVersion = TLSv1_2_MINOR;
5178
0
            break;
5179
0
    #endif
5180
0
#endif
5181
0
    #ifdef WOLFSSL_TLS13
5182
0
        case WOLFSSL_TLSV1_3:
5183
0
            *minVersion = TLSv1_3_MINOR;
5184
0
            break;
5185
0
    #endif
5186
5187
0
#ifdef WOLFSSL_DTLS
5188
0
        case WOLFSSL_DTLSV1:
5189
0
            *minVersion = DTLS_MINOR;
5190
0
            break;
5191
0
        case WOLFSSL_DTLSV1_2:
5192
0
            *minVersion = DTLSv1_2_MINOR;
5193
0
            break;
5194
0
#ifdef WOLFSSL_DTLS13
5195
0
        case WOLFSSL_DTLSV1_3:
5196
0
            *minVersion = DTLSv1_3_MINOR;
5197
0
            break;
5198
0
#endif /* WOLFSSL_DTLS13 */
5199
0
#endif /* WOLFSSL_DTLS */
5200
5201
0
        default:
5202
0
            WOLFSSL_MSG("Bad function argument");
5203
0
            return BAD_FUNC_ARG;
5204
0
    }
5205
5206
0
    return WOLFSSL_SUCCESS;
5207
0
}
5208
5209
5210
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
5211
WOLFSSL_ABI
5212
int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
5213
0
{
5214
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
5215
5216
0
    if (ctx == NULL) {
5217
0
        WOLFSSL_MSG("Bad function argument");
5218
0
        return BAD_FUNC_ARG;
5219
0
    }
5220
5221
0
    return SetMinVersionHelper(&ctx->minDowngrade, version);
5222
0
}
5223
5224
5225
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
5226
int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
5227
0
{
5228
0
    WOLFSSL_ENTER("wolfSSL_SetMinVersion");
5229
5230
0
    if (ssl == NULL) {
5231
0
        WOLFSSL_MSG("Bad function argument");
5232
0
        return BAD_FUNC_ARG;
5233
0
    }
5234
5235
0
    return SetMinVersionHelper(&ssl->options.minDowngrade, version);
5236
0
}
5237
5238
5239
/* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
5240
int wolfSSL_GetVersion(const WOLFSSL* ssl)
5241
0
{
5242
0
    if (ssl == NULL)
5243
0
        return BAD_FUNC_ARG;
5244
5245
0
    if (ssl->version.major == SSLv3_MAJOR) {
5246
0
        switch (ssl->version.minor) {
5247
0
            case SSLv3_MINOR :
5248
0
                return WOLFSSL_SSLV3;
5249
0
            case TLSv1_MINOR :
5250
0
                return WOLFSSL_TLSV1;
5251
0
            case TLSv1_1_MINOR :
5252
0
                return WOLFSSL_TLSV1_1;
5253
0
            case TLSv1_2_MINOR :
5254
0
                return WOLFSSL_TLSV1_2;
5255
0
            case TLSv1_3_MINOR :
5256
0
                return WOLFSSL_TLSV1_3;
5257
0
            default:
5258
0
                break;
5259
0
        }
5260
0
    }
5261
5262
0
    return VERSION_ERROR;
5263
0
}
5264
5265
int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
5266
0
{
5267
0
    word16 haveRSA = 1;
5268
0