Coverage Report

Created: 2023-02-22 06:39

/src/wolfssl/src/ssl.c
Line
Count
Source (jump to first uncovered line)
1
/* ssl.c
2
 *
3
 * Copyright (C) 2006-2022 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
#ifndef WOLFCRYPT_ONLY
94
    #include <wolfssl/openssl/pem.h>
95
#endif
96
    #include <wolfssl/openssl/ec.h>
97
    #include <wolfssl/openssl/ec25519.h>
98
    #include <wolfssl/openssl/ed25519.h>
99
    #include <wolfssl/openssl/ec448.h>
100
    #include <wolfssl/openssl/ed448.h>
101
    #include <wolfssl/openssl/ecdsa.h>
102
    #include <wolfssl/openssl/ecdh.h>
103
    #include <wolfssl/openssl/err.h>
104
    #include <wolfssl/openssl/modes.h>
105
    #include <wolfssl/openssl/opensslv.h>
106
    #include <wolfssl/openssl/rc4.h>
107
    #include <wolfssl/openssl/stack.h>
108
    #include <wolfssl/openssl/x509_vfy.h>
109
    /* openssl headers end, wolfssl internal headers next */
110
    #include <wolfssl/wolfcrypt/hmac.h>
111
    #include <wolfssl/wolfcrypt/random.h>
112
    #include <wolfssl/wolfcrypt/des3.h>
113
    #include <wolfssl/wolfcrypt/ecc.h>
114
    #include <wolfssl/wolfcrypt/md4.h>
115
    #include <wolfssl/wolfcrypt/md5.h>
116
    #include <wolfssl/wolfcrypt/arc4.h>
117
    #include <wolfssl/wolfcrypt/curve25519.h>
118
    #include <wolfssl/wolfcrypt/ed25519.h>
119
    #include <wolfssl/wolfcrypt/curve448.h>
120
    #if defined(HAVE_PQC)
121
    #if defined(HAVE_FALCON)
122
        #include <wolfssl/wolfcrypt/falcon.h>
123
    #endif /* HAVE_FALCON */
124
    #if defined(HAVE_DILITHIUM)
125
        #include <wolfssl/wolfcrypt/dilithium.h>
126
    #endif /* HAVE_DILITHIUM */
127
    #endif /* HAVE_PQC */
128
    #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
129
        #ifdef HAVE_OCSP
130
            #include <wolfssl/openssl/ocsp.h>
131
        #endif
132
        #include <wolfssl/openssl/lhash.h>
133
        #include <wolfssl/openssl/txt_db.h>
134
    #endif /* WITH_STUNNEL */
135
    #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
136
        #include <wolfssl/wolfcrypt/sha512.h>
137
    #endif
138
    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
139
        && !defined(WC_NO_RNG)
140
        #include <wolfssl/wolfcrypt/srp.h>
141
    #endif
142
    #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST)
143
        #include <wolfssl/wolfcrypt/pkcs7.h>
144
    #endif
145
    #if defined(OPENSSL_ALL) && defined(HAVE_PKCS7)
146
        #include <wolfssl/openssl/pkcs7.h>
147
    #endif /* OPENSSL_ALL && HAVE_PKCS7 */
148
#endif
149
150
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
151
    #include <wolfssl/openssl/x509v3.h>
152
    int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi);
153
    int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi);
154
#endif
155
156
#if defined(WOLFSSL_QT)
157
    #include <wolfssl/wolfcrypt/sha.h>
158
#endif
159
160
#ifdef NO_ASN
161
    #include <wolfssl/wolfcrypt/dh.h>
162
#endif
163
#endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */
164
165
/*
166
 * OPENSSL_COMPATIBLE_DEFAULTS:
167
 *     Enable default behaviour that is compatible with OpenSSL. For example
168
 *     SSL_CTX by default doesn't verify the loaded certs. Enabling this
169
 *     should make porting to new projects easier.
170
 * WOLFSSL_CHECK_ALERT_ON_ERR:
171
 *     Check for alerts during the handshake in the event of an error.
172
 * NO_SESSION_CACHE_REF:
173
 *     wolfSSL_get_session on a client will return a reference to the internal
174
 *     ClientCache by default for backwards compatibility. This define will
175
 *     make wolfSSL_get_session return a reference to ssl->session. The returned
176
 *     pointer will be freed with the related WOLFSSL object.
177
 */
178
179
#define WOLFSSL_EVP_INCLUDED
180
#include "wolfcrypt/src/evp.c"
181
182
#ifndef WOLFCRYPT_ONLY
183
184
#define WOLFSSL_PK_INCLUDED
185
#include "src/pk.c"
186
187
#ifdef OPENSSL_EXTRA
188
    /* Global pointer to constant BN on */
189
    static WOLFSSL_BIGNUM* bn_one = NULL;
190
191
    /* WOLFSSL_NO_OPENSSL_RAND_CB: Allows way to reduce code size for
192
     *                OPENSSL_EXTRA where RAND callbacks are not used */
193
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
194
        static const WOLFSSL_RAND_METHOD* gRandMethods = NULL;
195
        static int gRandMethodsInit = 0;
196
        static wolfSSL_Mutex gRandMethodMutex;
197
    #endif /* !WOLFSSL_NO_OPENSSL_RAND_CB */
198
#endif /* OPENSSL_EXTRA */
199
200
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
201
const WOLF_EC_NIST_NAME kNistCurves[] = {
202
    {XSTR_SIZEOF("P-192"),   "P-192",   NID_X9_62_prime192v1},
203
    {XSTR_SIZEOF("P-256"),   "P-256",   NID_X9_62_prime256v1},
204
    {XSTR_SIZEOF("P-112"),   "P-112",   NID_secp112r1},
205
    {XSTR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2},
206
    {XSTR_SIZEOF("P-128"),   "P-128",   NID_secp128r1},
207
    {XSTR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2},
208
    {XSTR_SIZEOF("P-160"),   "P-160",   NID_secp160r1},
209
    {XSTR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2},
210
    {XSTR_SIZEOF("P-224"),   "P-224",   NID_secp224r1},
211
    {XSTR_SIZEOF("P-384"),   "P-384",   NID_secp384r1},
212
    {XSTR_SIZEOF("P-521"),   "P-521",   NID_secp521r1},
213
    {XSTR_SIZEOF("K-160"),   "K-160",   NID_secp160k1},
214
    {XSTR_SIZEOF("K-192"),   "K-192",   NID_secp192k1},
215
    {XSTR_SIZEOF("K-224"),   "K-224",   NID_secp224k1},
216
    {XSTR_SIZEOF("K-256"),   "K-256",   NID_secp256k1},
217
    {XSTR_SIZEOF("B-160"),   "B-160",   NID_brainpoolP160r1},
218
    {XSTR_SIZEOF("B-192"),   "B-192",   NID_brainpoolP192r1},
219
    {XSTR_SIZEOF("B-224"),   "B-224",   NID_brainpoolP224r1},
220
    {XSTR_SIZEOF("B-256"),   "B-256",   NID_brainpoolP256r1},
221
    {XSTR_SIZEOF("B-320"),   "B-320",   NID_brainpoolP320r1},
222
    {XSTR_SIZEOF("B-384"),   "B-384",   NID_brainpoolP384r1},
223
    {XSTR_SIZEOF("B-512"),   "B-512",   NID_brainpoolP512r1},
224
#ifdef HAVE_PQC
225
    {XSTR_SIZEOF("KYBER_LEVEL1"), "KYBER_LEVEL1", WOLFSSL_KYBER_LEVEL1},
226
    {XSTR_SIZEOF("KYBER_LEVEL3"), "KYBER_LEVEL3", WOLFSSL_KYBER_LEVEL3},
227
    {XSTR_SIZEOF("KYBER_LEVEL5"), "KYBER_LEVEL5", WOLFSSL_KYBER_LEVEL5},
228
#ifdef HAVE_LIBOQS
229
    {XSTR_SIZEOF("NTRU_HPS_LEVEL1"), "NTRU_HPS_LEVEL1", WOLFSSL_NTRU_HPS_LEVEL1},
230
    {XSTR_SIZEOF("NTRU_HPS_LEVEL3"), "NTRU_HPS_LEVEL3", WOLFSSL_NTRU_HPS_LEVEL3},
231
    {XSTR_SIZEOF("NTRU_HPS_LEVEL5"), "NTRU_HPS_LEVEL5", WOLFSSL_NTRU_HPS_LEVEL5},
232
    {XSTR_SIZEOF("NTRU_HRSS_LEVEL3"), "NTRU_HRSS_LEVEL3", WOLFSSL_NTRU_HRSS_LEVEL3},
233
    {XSTR_SIZEOF("SABER_LEVEL1"), "SABER_LEVEL1", WOLFSSL_SABER_LEVEL1},
234
    {XSTR_SIZEOF("SABER_LEVEL3"), "SABER_LEVEL3", WOLFSSL_SABER_LEVEL3},
235
    {XSTR_SIZEOF("SABER_LEVEL5"), "SABER_LEVEL5", WOLFSSL_SABER_LEVEL5},
236
    {XSTR_SIZEOF("KYBER_90S_LEVEL1"), "KYBER_90S_LEVEL1", WOLFSSL_KYBER_90S_LEVEL1},
237
    {XSTR_SIZEOF("KYBER_90S_LEVEL3"), "KYBER_90S_LEVEL3", WOLFSSL_KYBER_90S_LEVEL3},
238
    {XSTR_SIZEOF("KYBER_90S_LEVEL5"), "KYBER_90S_LEVEL5", WOLFSSL_KYBER_90S_LEVEL5},
239
    {XSTR_SIZEOF("P256_NTRU_HPS_LEVEL1"), "P256_NTRU_HPS_LEVEL1", WOLFSSL_P256_NTRU_HPS_LEVEL1},
240
    {XSTR_SIZEOF("P384_NTRU_HPS_LEVEL3"), "P384_NTRU_HPS_LEVEL3", WOLFSSL_P384_NTRU_HPS_LEVEL3},
241
    {XSTR_SIZEOF("P521_NTRU_HPS_LEVEL5"), "P521_NTRU_HPS_LEVEL5", WOLFSSL_P521_NTRU_HPS_LEVEL5},
242
    {XSTR_SIZEOF("P384_NTRU_HRSS_LEVEL3"), "P384_NTRU_HRSS_LEVEL3", WOLFSSL_P384_NTRU_HRSS_LEVEL3},
243
    {XSTR_SIZEOF("P256_SABER_LEVEL1"), "P256_SABER_LEVEL1", WOLFSSL_P256_SABER_LEVEL1},
244
    {XSTR_SIZEOF("P384_SABER_LEVEL3"), "P384_SABER_LEVEL3", WOLFSSL_P384_SABER_LEVEL3},
245
    {XSTR_SIZEOF("P521_SABER_LEVEL5"), "P521_SABER_LEVEL5", WOLFSSL_P521_SABER_LEVEL5},
246
    {XSTR_SIZEOF("P256_KYBER_LEVEL1"), "P256_KYBER_LEVEL1", WOLFSSL_P256_KYBER_LEVEL1},
247
    {XSTR_SIZEOF("P384_KYBER_LEVEL3"), "P384_KYBER_LEVEL3", WOLFSSL_P384_KYBER_LEVEL3},
248
    {XSTR_SIZEOF("P521_KYBER_LEVEL5"), "P521_KYBER_LEVEL5", WOLFSSL_P521_KYBER_LEVEL5},
249
    {XSTR_SIZEOF("P256_KYBER_90S_LEVEL1"), "P256_KYBER_90S_LEVEL1", WOLFSSL_P256_KYBER_90S_LEVEL1},
250
    {XSTR_SIZEOF("P384_KYBER_90S_LEVEL3"), "P384_KYBER_90S_LEVEL3", WOLFSSL_P384_KYBER_90S_LEVEL3},
251
    {XSTR_SIZEOF("P521_KYBER_90S_LEVEL5"), "P521_KYBER_90S_LEVEL5", WOLFSSL_P521_KYBER_90S_LEVEL5},
252
#endif
253
#endif
254
    {0, NULL, 0},
255
};
256
#endif
257
258
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
259
#include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
260
#endif
261
262
#ifdef WOLFSSL_SESSION_EXPORT
263
/* Used to import a serialized TLS session.
264
 * WARNING: buf contains sensitive information about the state and is best to be
265
 *          encrypted before storing if stored.
266
 *
267
 * @param ssl WOLFSSL structure to import the session into
268
 * @param buf serialized session
269
 * @param sz  size of buffer 'buf'
270
 * @return the number of bytes read from buffer 'buf'
271
 */
272
int wolfSSL_tls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
273
{
274
    if (ssl == NULL || buf == NULL) {
275
        return BAD_FUNC_ARG;
276
    }
277
    return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
278
}
279
280
281
/* Used to export a serialized TLS session.
282
 * WARNING: buf contains sensitive information about the state and is best to be
283
 *          encrypted before storing if stored.
284
 *
285
 * @param ssl WOLFSSL structure to export the session from
286
 * @param buf output of serialized session
287
 * @param sz  size in bytes set in 'buf'
288
 * @return the number of bytes written into buffer 'buf'
289
 */
290
int wolfSSL_tls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
291
{
292
    if (ssl == NULL || sz == NULL) {
293
        return BAD_FUNC_ARG;
294
    }
295
    return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
296
}
297
298
#ifdef WOLFSSL_DTLS
299
int wolfSSL_dtls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
300
{
301
    WOLFSSL_ENTER("wolfSSL_session_import");
302
303
    if (ssl == NULL || buf == NULL) {
304
        return BAD_FUNC_ARG;
305
    }
306
307
    /* sanity checks on buffer and protocol are done in internal function */
308
    return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
309
}
310
311
312
/* Sets the function to call for serializing the session. This function is
313
 * called right after the handshake is completed. */
314
int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func)
315
{
316
317
    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_export");
318
319
    /* purposefully allow func to be NULL */
320
    if (ctx == NULL) {
321
        return BAD_FUNC_ARG;
322
    }
323
324
    ctx->dtls_export = func;
325
326
    return WOLFSSL_SUCCESS;
327
}
328
329
330
/* Sets the function in WOLFSSL struct to call for serializing the session. This
331
 * function is called right after the handshake is completed. */
332
int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
333
{
334
335
    WOLFSSL_ENTER("wolfSSL_dtls_set_export");
336
337
    /* purposefully allow func to be NULL */
338
    if (ssl == NULL) {
339
        return BAD_FUNC_ARG;
340
    }
341
342
    ssl->dtls_export = func;
343
344
    return WOLFSSL_SUCCESS;
345
}
346
347
348
/* This function allows for directly serializing a session rather than using
349
 * callbacks. It has less overhead by removing a temporary buffer and gives
350
 * control over when the session gets serialized. When using callbacks the
351
 * session is always serialized immediately after the handshake is finished.
352
 *
353
 * buf is the argument to contain the serialized session
354
 * sz  is the size of the buffer passed in
355
 * ssl is the WOLFSSL struct to serialize
356
 * returns the size of serialized session on success, 0 on no action, and
357
 *         negative value on error */
358
int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
359
{
360
    WOLFSSL_ENTER("wolfSSL_dtls_export");
361
362
    if (ssl == NULL || sz == NULL) {
363
        return BAD_FUNC_ARG;
364
    }
365
366
    if (buf == NULL) {
367
        *sz = MAX_EXPORT_BUFFER;
368
        return 0;
369
    }
370
371
    /* if not DTLS do nothing */
372
    if (!ssl->options.dtls) {
373
        WOLFSSL_MSG("Currently only DTLS export is supported");
374
        return 0;
375
    }
376
377
    /* copy over keys, options, and dtls state struct */
378
    return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
379
}
380
381
382
/* This function is similar to wolfSSL_dtls_export but only exports the portion
383
 * of the WOLFSSL structure related to the state of the connection, i.e. peer
384
 * sequence number, epoch, AEAD state etc.
385
 *
386
 * buf is the argument to contain the serialized state, if null then set "sz" to
387
 *     buffer size required
388
 * sz  is the size of the buffer passed in
389
 * ssl is the WOLFSSL struct to serialize
390
 * returns the size of serialized session on success, 0 on no action, and
391
 *         negative value on error */
392
int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf,
393
        unsigned int* sz)
394
{
395
    WOLFSSL_ENTER("wolfSSL_dtls_export_state_only");
396
397
    if (ssl == NULL || sz == NULL) {
398
        return BAD_FUNC_ARG;
399
    }
400
401
    if (buf == NULL) {
402
        *sz = MAX_EXPORT_STATE_BUFFER;
403
        return 0;
404
    }
405
406
    /* if not DTLS do nothing */
407
    if (!ssl->options.dtls) {
408
        WOLFSSL_MSG("Currently only DTLS export state is supported");
409
        return 0;
410
    }
411
412
    /* copy over keys, options, and dtls state struct */
413
    return wolfSSL_dtls_export_state_internal(ssl, buf, *sz);
414
}
415
416
417
/* returns 0 on success */
418
int wolfSSL_send_session(WOLFSSL* ssl)
419
{
420
    int ret;
421
    byte* buf;
422
    word32 bufSz = MAX_EXPORT_BUFFER;
423
424
    WOLFSSL_ENTER("wolfSSL_send_session");
425
426
    if (ssl == NULL) {
427
        return BAD_FUNC_ARG;
428
    }
429
430
    buf = (byte*)XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
431
    if (buf == NULL) {
432
        return MEMORY_E;
433
    }
434
435
    /* if not DTLS do nothing */
436
    if (!ssl->options.dtls) {
437
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
438
        WOLFSSL_MSG("Currently only DTLS export is supported");
439
        return 0;
440
    }
441
442
    /* copy over keys, options, and dtls state struct */
443
    ret = wolfSSL_session_export_internal(ssl, buf, &bufSz, WOLFSSL_EXPORT_DTLS);
444
    if (ret < 0) {
445
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
446
        return ret;
447
    }
448
449
    /* if no error ret has size of buffer */
450
    ret = ssl->dtls_export(ssl, buf, ret, NULL);
451
    if (ret != WOLFSSL_SUCCESS) {
452
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
453
        return ret;
454
    }
455
456
    XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
457
    return 0;
458
}
459
#endif /* WOLFSSL_DTLS */
460
#endif /* WOLFSSL_SESSION_EXPORT */
461
462
/* prevent multiple mutex initializations */
463
static volatile WOLFSSL_GLOBAL int initRefCount = 0;
464
static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex;   /* init ref count mutex */
465
static WOLFSSL_GLOBAL int count_mutex_valid = 0;
466
467
/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
468
   WOLFSSL_METHOD pointer passed in is given to ctx to manage.
469
   This function frees the passed in WOLFSSL_METHOD struct on failure and on
470
   success is freed when ctx is freed.
471
 */
472
WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
473
0
{
474
0
    WOLFSSL_CTX* ctx = NULL;
475
476
0
    WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
477
478
0
    if (initRefCount == 0) {
479
        /* user no longer forced to call Init themselves */
480
0
        int ret = wolfSSL_Init();
481
0
        if (ret != WOLFSSL_SUCCESS) {
482
0
            WOLFSSL_MSG("wolfSSL_Init failed");
483
0
            WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
484
0
            if (method != NULL) {
485
0
                XFREE(method, heap, DYNAMIC_TYPE_METHOD);
486
0
            }
487
0
            return NULL;
488
0
        }
489
0
    }
490
491
0
    if (method == NULL)
492
0
        return ctx;
493
494
0
    ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
495
0
    if (ctx) {
496
0
        int ret;
497
498
0
        ret = InitSSL_Ctx(ctx, method, heap);
499
    #ifdef WOLFSSL_STATIC_MEMORY
500
        if (heap != NULL) {
501
            ctx->onHeapHint = 1; /* free the memory back to heap when done */
502
        }
503
    #endif
504
0
        if (ret < 0) {
505
0
            WOLFSSL_MSG("Init CTX failed");
506
0
            wolfSSL_CTX_free(ctx);
507
0
            ctx = NULL;
508
0
        }
509
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
510
                           && !defined(NO_SHA256) && !defined(WC_NO_RNG)
511
        else {
512
            ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
513
            if (ctx->srp == NULL){
514
                WOLFSSL_MSG("Init CTX failed");
515
                wolfSSL_CTX_free(ctx);
516
                return NULL;
517
            }
518
            XMEMSET(ctx->srp, 0, sizeof(Srp));
519
        }
520
#endif
521
0
    }
522
0
    else {
523
0
        WOLFSSL_MSG("Alloc CTX failed, method freed");
524
0
        XFREE(method, heap, DYNAMIC_TYPE_METHOD);
525
0
    }
526
527
#ifdef OPENSSL_COMPATIBLE_DEFAULTS
528
    if (ctx) {
529
        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
530
        wolfSSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
531
        if (wolfSSL_CTX_set_min_proto_version(ctx,
532
                                              (method->version.major == DTLS_MAJOR) ?
533
                                               DTLS1_VERSION : SSL3_VERSION) != WOLFSSL_SUCCESS ||
534
#ifdef HAVE_ANON
535
                wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS ||
536
#endif
537
                wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS) {
538
            WOLFSSL_MSG("Setting OpenSSL CTX defaults failed");
539
            wolfSSL_CTX_free(ctx);
540
            ctx = NULL;
541
        }
542
    }
543
#endif
544
545
0
    WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
546
0
    return ctx;
547
0
}
548
549
550
WOLFSSL_ABI
551
WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
552
0
{
553
#ifdef WOLFSSL_HEAP_TEST
554
    /* if testing the heap hint then set top level CTX to have test value */
555
    return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
556
#else
557
0
    return wolfSSL_CTX_new_ex(method, NULL);
558
0
#endif
559
0
}
560
561
/* increases CTX reference count to track proper time to "free" */
562
int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
563
0
{
564
0
    int refCount = SSL_CTX_RefCount(ctx, 1);
565
0
    return ((refCount > 1) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
566
0
}
567
568
WOLFSSL_ABI
569
void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
570
0
{
571
0
    WOLFSSL_ENTER("SSL_CTX_free");
572
0
    if (ctx) {
573
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
574
&& !defined(NO_SHA256) && !defined(WC_NO_RNG)
575
        if (ctx->srp != NULL) {
576
            if (ctx->srp_password != NULL){
577
                XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
578
                ctx->srp_password = NULL;
579
            }
580
            wc_SrpTerm(ctx->srp);
581
            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
582
            ctx->srp = NULL;
583
        }
584
#endif
585
0
        FreeSSL_Ctx(ctx);
586
0
    }
587
588
0
    WOLFSSL_LEAVE("SSL_CTX_free", 0);
589
0
}
590
591
592
#ifdef HAVE_ENCRYPT_THEN_MAC
593
/**
594
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
595
 * The default value: enabled.
596
 *
597
 * ctx  SSL/TLS context.
598
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
599
 * returns WOLFSSL_SUCCESS
600
 */
601
int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
602
0
{
603
0
    ctx->disallowEncThenMac = !set;
604
0
    return WOLFSSL_SUCCESS;
605
0
}
606
607
/**
608
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
609
 * The default value comes from context.
610
 *
611
 * ctx  SSL/TLS context.
612
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
613
 * returns WOLFSSL_SUCCESS
614
 */
615
int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
616
0
{
617
0
    ssl->options.disallowEncThenMac = !set;
618
0
    return WOLFSSL_SUCCESS;
619
0
}
620
#endif
621
622
#ifdef SINGLE_THREADED
623
/* no locking in single threaded mode, allow a CTX level rng to be shared with
624
 * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
625
int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
626
{
627
    WC_RNG* rng;
628
    int     ret;
629
630
    if (ctx == NULL) {
631
        return BAD_FUNC_ARG;
632
    }
633
634
    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
635
    if (rng == NULL) {
636
        return MEMORY_E;
637
    }
638
639
#ifndef HAVE_FIPS
640
    ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
641
#else
642
    ret = wc_InitRng(rng);
643
#endif
644
    if (ret != 0) {
645
        XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
646
        return ret;
647
    }
648
649
    ctx->rng = rng;
650
    return WOLFSSL_SUCCESS;
651
}
652
#endif
653
654
655
WOLFSSL_ABI
656
WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
657
0
{
658
0
    WOLFSSL* ssl = NULL;
659
0
    int ret = 0;
660
661
0
    WOLFSSL_ENTER("SSL_new");
662
663
0
    if (ctx == NULL)
664
0
        return ssl;
665
666
0
    ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
667
0
    if (ssl)
668
0
        if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
669
0
            FreeSSL(ssl, ctx->heap);
670
0
            ssl = 0;
671
0
        }
672
673
0
    WOLFSSL_LEAVE("SSL_new", ret);
674
0
    (void)ret;
675
676
0
    return ssl;
677
0
}
678
679
680
WOLFSSL_ABI
681
void wolfSSL_free(WOLFSSL* ssl)
682
0
{
683
0
    WOLFSSL_ENTER("SSL_free");
684
0
    if (ssl)
685
0
        FreeSSL(ssl, ssl->ctx->heap);
686
0
    WOLFSSL_LEAVE("SSL_free", 0);
687
0
}
688
689
690
int wolfSSL_is_server(WOLFSSL* ssl)
691
0
{
692
0
    if (ssl == NULL)
693
0
        return BAD_FUNC_ARG;
694
0
    return ssl->options.side == WOLFSSL_SERVER_END;
695
0
}
696
697
#ifdef HAVE_WRITE_DUP
698
699
/*
700
 * Release resources around WriteDup object
701
 *
702
 * ssl WOLFSSL object
703
 *
704
 * no return, destruction so make best attempt
705
*/
706
void FreeWriteDup(WOLFSSL* ssl)
707
{
708
    int doFree = 0;
709
710
    WOLFSSL_ENTER("FreeWriteDup");
711
712
    if (ssl->dupWrite) {
713
        if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
714
            ssl->dupWrite->dupCount--;
715
            if (ssl->dupWrite->dupCount == 0) {
716
                doFree = 1;
717
            } else {
718
                WOLFSSL_MSG("WriteDup count not zero, no full free");
719
            }
720
            wc_UnLockMutex(&ssl->dupWrite->dupMutex);
721
        }
722
    }
723
724
    if (doFree) {
725
        WOLFSSL_MSG("Doing WriteDup full free, count to zero");
726
        wc_FreeMutex(&ssl->dupWrite->dupMutex);
727
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
728
    }
729
}
730
731
732
/*
733
 * duplicate existing ssl members into dup needed for writing
734
 *
735
 * dup write only WOLFSSL
736
 * ssl existing WOLFSSL
737
 *
738
 * 0 on success
739
*/
740
static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
741
{
742
    /* shared dupWrite setup */
743
    ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
744
                                       DYNAMIC_TYPE_WRITEDUP);
745
    if (ssl->dupWrite == NULL) {
746
        return MEMORY_E;
747
    }
748
    XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
749
750
    if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
751
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
752
        ssl->dupWrite = NULL;
753
        return BAD_MUTEX_E;
754
    }
755
    ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
756
    dup->dupWrite = ssl->dupWrite; /* each side uses */
757
758
    /* copy write parts over to dup writer */
759
    XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
760
    XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
761
    XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
762
    XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
763
    XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion));
764
    XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion));
765
766
    /* dup side now owns encrypt/write ciphers */
767
    XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
768
769
    dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
770
    dup->CBIOSend = ssl->CBIOSend;
771
#ifdef OPENSSL_EXTRA
772
    dup->cbioFlag = ssl->cbioFlag;
773
#endif
774
    dup->wfd    = ssl->wfd;
775
    dup->wflags = ssl->wflags;
776
#ifndef WOLFSSL_AEAD_ONLY
777
    dup->hmac   = ssl->hmac;
778
#endif
779
#ifdef HAVE_TRUNCATED_HMAC
780
    dup->truncated_hmac = ssl->truncated_hmac;
781
#endif
782
783
    /* unique side dup setup */
784
    dup->dupSide = WRITE_DUP_SIDE;
785
    ssl->dupSide = READ_DUP_SIDE;
786
787
    return 0;
788
}
789
790
791
/*
792
 * duplicate a WOLFSSL object post handshake for writing only
793
 * turn existing object into read only.  Allows concurrent access from two
794
 * different threads.
795
 *
796
 * ssl existing WOLFSSL object
797
 *
798
 * return dup'd WOLFSSL object on success
799
*/
800
WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
801
{
802
    WOLFSSL* dup = NULL;
803
    int ret = 0;
804
805
    (void)ret;
806
    WOLFSSL_ENTER("wolfSSL_write_dup");
807
808
    if (ssl == NULL) {
809
        return ssl;
810
    }
811
812
    if (ssl->options.handShakeDone == 0) {
813
        WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
814
        return NULL;
815
    }
816
817
    if (ssl->dupWrite) {
818
        WOLFSSL_MSG("wolfSSL_write_dup already called once");
819
        return NULL;
820
    }
821
822
    dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
823
    if (dup) {
824
        if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
825
            FreeSSL(dup, ssl->ctx->heap);
826
            dup = NULL;
827
        } else if ( (ret = DupSSL(dup, ssl)) < 0) {
828
            FreeSSL(dup, ssl->ctx->heap);
829
            dup = NULL;
830
        }
831
    }
832
833
    WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
834
835
    return dup;
836
}
837
838
839
/*
840
 * Notify write dup side of fatal error or close notify
841
 *
842
 * ssl WOLFSSL object
843
 * err Notify err
844
 *
845
 * 0 on success
846
*/
847
int NotifyWriteSide(WOLFSSL* ssl, int err)
848
{
849
    int ret;
850
851
    WOLFSSL_ENTER("NotifyWriteSide");
852
853
    ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
854
    if (ret == 0) {
855
        ssl->dupWrite->dupErr = err;
856
        ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
857
    }
858
859
    return ret;
860
}
861
862
863
#endif /* HAVE_WRITE_DUP */
864
865
866
#ifdef HAVE_POLY1305
867
/* set if to use old poly 1 for yes 0 to use new poly */
868
int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
869
0
{
870
0
    (void)ssl;
871
0
    (void)value;
872
873
0
#ifndef WOLFSSL_NO_TLS12
874
0
    WOLFSSL_ENTER("SSL_use_old_poly");
875
0
    WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
876
0
            "is depreciated");
877
0
    ssl->options.oldPoly = (word16)value;
878
0
    WOLFSSL_LEAVE("SSL_use_old_poly", 0);
879
0
#endif
880
0
    return 0;
881
0
}
882
#endif
883
884
885
WOLFSSL_ABI
886
int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
887
0
{
888
0
    int ret;
889
890
0
    WOLFSSL_ENTER("SSL_set_fd");
891
892
0
    if (ssl == NULL) {
893
0
        return BAD_FUNC_ARG;
894
0
    }
895
896
0
    ret = wolfSSL_set_read_fd(ssl, fd);
897
0
    if (ret == WOLFSSL_SUCCESS) {
898
0
        ret = wolfSSL_set_write_fd(ssl, fd);
899
0
    }
900
901
0
    return ret;
902
0
}
903
904
#ifdef WOLFSSL_DTLS
905
int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd)
906
{
907
    int ret;
908
909
    WOLFSSL_ENTER("SSL_set_dtls_fd_connected");
910
911
    if (ssl == NULL) {
912
        return BAD_FUNC_ARG;
913
    }
914
915
    ret = wolfSSL_set_fd(ssl, fd);
916
    if (ret == WOLFSSL_SUCCESS)
917
        ssl->buffers.dtlsCtx.connected = 1;
918
919
    return ret;
920
}
921
#endif
922
923
924
int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
925
0
{
926
0
    WOLFSSL_ENTER("SSL_set_read_fd");
927
928
0
    if (ssl == NULL) {
929
0
        return BAD_FUNC_ARG;
930
0
    }
931
932
0
    ssl->rfd = fd;      /* not used directly to allow IO callbacks */
933
0
    ssl->IOCB_ReadCtx  = &ssl->rfd;
934
935
    #ifdef WOLFSSL_DTLS
936
        ssl->buffers.dtlsCtx.connected = 0;
937
        if (ssl->options.dtls) {
938
            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
939
            ssl->buffers.dtlsCtx.rfd = fd;
940
        }
941
    #endif
942
943
0
    WOLFSSL_LEAVE("SSL_set_read_fd", WOLFSSL_SUCCESS);
944
0
    return WOLFSSL_SUCCESS;
945
0
}
946
947
948
int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
949
0
{
950
0
    WOLFSSL_ENTER("SSL_set_write_fd");
951
952
0
    if (ssl == NULL) {
953
0
        return BAD_FUNC_ARG;
954
0
    }
955
956
0
    ssl->wfd = fd;      /* not used directly to allow IO callbacks */
957
0
    ssl->IOCB_WriteCtx  = &ssl->wfd;
958
959
    #ifdef WOLFSSL_DTLS
960
        ssl->buffers.dtlsCtx.connected = 0;
961
        if (ssl->options.dtls) {
962
            ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
963
            ssl->buffers.dtlsCtx.wfd = fd;
964
        }
965
    #endif
966
967
0
    WOLFSSL_LEAVE("SSL_set_write_fd", WOLFSSL_SUCCESS);
968
0
    return WOLFSSL_SUCCESS;
969
0
}
970
971
972
/**
973
  * Get the name of cipher at priority level passed in.
974
  */
975
char* wolfSSL_get_cipher_list(int priority)
976
0
{
977
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
978
979
0
    if (priority >= GetCipherNamesSize() || priority < 0) {
980
0
        return 0;
981
0
    }
982
983
0
    return (char*)ciphers[priority].name;
984
0
}
985
986
987
/**
988
  * Get the name of cipher at priority level passed in.
989
  */
990
char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
991
0
{
992
993
0
    if (ssl == NULL) {
994
0
        return NULL;
995
0
    }
996
0
    else {
997
0
        const char* cipher;
998
999
0
        if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
1000
0
            if (priority == 0) {
1001
0
                return (char*)cipher;
1002
0
            }
1003
0
            else {
1004
0
                return NULL;
1005
0
            }
1006
0
        }
1007
0
        else {
1008
0
            return wolfSSL_get_cipher_list(priority);
1009
0
        }
1010
0
    }
1011
0
}
1012
1013
1014
int wolfSSL_get_ciphers(char* buf, int len)
1015
0
{
1016
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1017
0
    int ciphersSz = GetCipherNamesSize();
1018
0
    int i;
1019
0
    int cipherNameSz;
1020
1021
0
    if (buf == NULL || len <= 0)
1022
0
        return BAD_FUNC_ARG;
1023
1024
    /* Add each member to the buffer delimited by a : */
1025
0
    for (i = 0; i < ciphersSz; i++) {
1026
0
        cipherNameSz = (int)XSTRLEN(ciphers[i].name);
1027
0
        if (cipherNameSz + 1 < len) {
1028
0
            XSTRNCPY(buf, ciphers[i].name, len);
1029
0
            buf += cipherNameSz;
1030
1031
0
            if (i < ciphersSz - 1)
1032
0
                *buf++ = ':';
1033
0
            *buf = 0;
1034
1035
0
            len -= cipherNameSz + 1;
1036
0
        }
1037
0
        else
1038
0
            return BUFFER_E;
1039
0
    }
1040
0
    return WOLFSSL_SUCCESS;
1041
0
}
1042
1043
1044
#ifndef NO_ERROR_STRINGS
1045
/* places a list of all supported cipher suites in TLS_* format into "buf"
1046
 * return WOLFSSL_SUCCESS on success */
1047
int wolfSSL_get_ciphers_iana(char* buf, int len)
1048
0
{
1049
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1050
0
    int ciphersSz = GetCipherNamesSize();
1051
0
    int i;
1052
0
    int cipherNameSz;
1053
1054
0
    if (buf == NULL || len <= 0)
1055
0
        return BAD_FUNC_ARG;
1056
1057
    /* Add each member to the buffer delimited by a : */
1058
0
    for (i = 0; i < ciphersSz; i++) {
1059
0
#ifndef NO_CIPHER_SUITE_ALIASES
1060
0
        if (ciphers[i].flags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS)
1061
0
            continue;
1062
0
#endif
1063
0
        cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
1064
0
        if (cipherNameSz + 1 < len) {
1065
0
            XSTRNCPY(buf, ciphers[i].name_iana, len);
1066
0
            buf += cipherNameSz;
1067
1068
0
            if (i < ciphersSz - 1)
1069
0
                *buf++ = ':';
1070
0
            *buf = 0;
1071
1072
0
            len -= cipherNameSz + 1;
1073
0
        }
1074
0
        else
1075
0
            return BUFFER_E;
1076
0
    }
1077
0
    return WOLFSSL_SUCCESS;
1078
0
}
1079
#endif /* NO_ERROR_STRINGS */
1080
1081
1082
const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
1083
0
{
1084
0
    const char* cipher;
1085
1086
0
    if (ssl == NULL)
1087
0
        return NULL;
1088
1089
0
    cipher = wolfSSL_get_cipher_name_iana(ssl);
1090
0
    len = min(len, (int)(XSTRLEN(cipher) + 1));
1091
0
    XMEMCPY(buf, cipher, len);
1092
0
    return buf;
1093
0
}
1094
1095
int wolfSSL_get_fd(const WOLFSSL* ssl)
1096
0
{
1097
0
    int fd = -1;
1098
0
    WOLFSSL_ENTER("SSL_get_fd");
1099
0
    if (ssl) {
1100
0
        fd = ssl->rfd;
1101
0
    }
1102
0
    WOLFSSL_LEAVE("SSL_get_fd", fd);
1103
0
    return fd;
1104
0
}
1105
1106
1107
int wolfSSL_dtls(WOLFSSL* ssl)
1108
0
{
1109
0
    int dtlsOpt = 0;
1110
0
    if (ssl)
1111
0
        dtlsOpt = ssl->options.dtls;
1112
0
    return dtlsOpt;
1113
0
}
1114
1115
#if !defined(NO_CERTS)
1116
/* Set whether mutual authentication is required for connections.
1117
 * Server side only.
1118
 *
1119
 * ctx  The SSL/TLS CTX object.
1120
 * req  1 to indicate required and 0 when not.
1121
 * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
1122
 * 0 on success.
1123
 */
1124
int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
1125
0
{
1126
0
    if (ctx == NULL)
1127
0
        return BAD_FUNC_ARG;
1128
0
    if (ctx->method->side == WOLFSSL_CLIENT_END)
1129
0
        return SIDE_ERROR;
1130
1131
0
    ctx->mutualAuth = (byte)req;
1132
1133
0
    return 0;
1134
0
}
1135
1136
/* Set whether mutual authentication is required for the connection.
1137
 * Server side only.
1138
 *
1139
 * ssl  The SSL/TLS object.
1140
 * req  1 to indicate required and 0 when not.
1141
 * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
1142
 * SIDE_ERROR when not a client and 0 on success.
1143
 */
1144
int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
1145
0
{
1146
0
    if (ssl == NULL)
1147
0
        return BAD_FUNC_ARG;
1148
0
    if (ssl->options.side == WOLFSSL_SERVER_END)
1149
0
        return SIDE_ERROR;
1150
1151
0
    ssl->options.mutualAuth = (word16)req;
1152
1153
0
    return 0;
1154
0
}
1155
#endif /* NO_CERTS */
1156
1157
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
1158
1159
int wolfSSL_CTX_set_AcceptFilter(
1160
    WOLFSSL_CTX *ctx,
1161
    NetworkFilterCallback_t AcceptFilter,
1162
    void *AcceptFilter_arg)
1163
{
1164
    if (ctx == NULL)
1165
        return BAD_FUNC_ARG;
1166
    ctx->AcceptFilter = AcceptFilter;
1167
    ctx->AcceptFilter_arg = AcceptFilter_arg;
1168
    return 0;
1169
}
1170
1171
int wolfSSL_set_AcceptFilter(
1172
    WOLFSSL *ssl,
1173
    NetworkFilterCallback_t AcceptFilter,
1174
    void *AcceptFilter_arg)
1175
{
1176
    if (ssl == NULL)
1177
        return BAD_FUNC_ARG;
1178
    ssl->AcceptFilter = AcceptFilter;
1179
    ssl->AcceptFilter_arg = AcceptFilter_arg;
1180
    return 0;
1181
}
1182
1183
int wolfSSL_CTX_set_ConnectFilter(
1184
    WOLFSSL_CTX *ctx,
1185
    NetworkFilterCallback_t ConnectFilter,
1186
    void *ConnectFilter_arg)
1187
{
1188
    if (ctx == NULL)
1189
        return BAD_FUNC_ARG;
1190
    ctx->ConnectFilter = ConnectFilter;
1191
    ctx->ConnectFilter_arg = ConnectFilter_arg;
1192
    return 0;
1193
}
1194
1195
int wolfSSL_set_ConnectFilter(
1196
    WOLFSSL *ssl,
1197
    NetworkFilterCallback_t ConnectFilter,
1198
    void *ConnectFilter_arg)
1199
{
1200
    if (ssl == NULL)
1201
        return BAD_FUNC_ARG;
1202
    ssl->ConnectFilter = ConnectFilter;
1203
    ssl->ConnectFilter_arg = ConnectFilter_arg;
1204
    return 0;
1205
}
1206
1207
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
1208
1209
#ifndef WOLFSSL_LEANPSK
1210
#if defined(WOLFSSL_DTLS) && defined(XINET_PTON) && \
1211
    !defined(WOLFSSL_NO_SOCK) && defined(HAVE_SOCKADDR)
1212
void* wolfSSL_dtls_create_peer(int port, char* ip)
1213
{
1214
    SOCKADDR_IN *addr;
1215
    addr = (SOCKADDR_IN*)XMALLOC(sizeof(*addr), NULL,
1216
            DYNAMIC_TYPE_SOCKADDR);
1217
    if (addr == NULL) {
1218
        return NULL;
1219
    }
1220
1221
    addr->sin_family = AF_INET;
1222
    addr->sin_port = XHTONS((word16)port);
1223
    if (XINET_PTON(AF_INET, ip, &addr->sin_addr) < 1) {
1224
        XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
1225
        return NULL;
1226
    }
1227
1228
    return addr;
1229
}
1230
1231
int wolfSSL_dtls_free_peer(void* addr)
1232
{
1233
    XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
1234
    return WOLFSSL_SUCCESS;
1235
}
1236
#endif
1237
1238
int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
1239
0
{
1240
#ifdef WOLFSSL_DTLS
1241
    void* sa;
1242
1243
    if (ssl == NULL)
1244
        return WOLFSSL_FAILURE;
1245
1246
    if (peer == NULL || peerSz == 0) {
1247
        if (ssl->buffers.dtlsCtx.peer.sa != NULL)
1248
            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
1249
        ssl->buffers.dtlsCtx.peer.sa = NULL;
1250
        ssl->buffers.dtlsCtx.peer.sz = 0;
1251
        ssl->buffers.dtlsCtx.peer.bufSz = 0;
1252
        ssl->buffers.dtlsCtx.userSet = 0;
1253
        return WOLFSSL_SUCCESS;
1254
    }
1255
1256
    sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
1257
    if (sa != NULL) {
1258
        if (ssl->buffers.dtlsCtx.peer.sa != NULL) {
1259
            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
1260
            ssl->buffers.dtlsCtx.peer.sa = NULL;
1261
        }
1262
        XMEMCPY(sa, peer, peerSz);
1263
        ssl->buffers.dtlsCtx.peer.sa = sa;
1264
        ssl->buffers.dtlsCtx.peer.sz = peerSz;
1265
        ssl->buffers.dtlsCtx.peer.bufSz = peerSz;
1266
        ssl->buffers.dtlsCtx.userSet = 1;
1267
        return WOLFSSL_SUCCESS;
1268
    }
1269
    return WOLFSSL_FAILURE;
1270
#else
1271
0
    (void)ssl;
1272
0
    (void)peer;
1273
0
    (void)peerSz;
1274
0
    return WOLFSSL_NOT_IMPLEMENTED;
1275
0
#endif
1276
0
}
1277
1278
int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
1279
0
{
1280
#ifdef WOLFSSL_DTLS
1281
    if (ssl == NULL) {
1282
        return WOLFSSL_FAILURE;
1283
    }
1284
1285
    if (peer != NULL && peerSz != NULL
1286
            && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
1287
            && ssl->buffers.dtlsCtx.peer.sa != NULL) {
1288
        *peerSz = ssl->buffers.dtlsCtx.peer.sz;
1289
        XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
1290
        return WOLFSSL_SUCCESS;
1291
    }
1292
    return WOLFSSL_FAILURE;
1293
#else
1294
0
    (void)ssl;
1295
0
    (void)peer;
1296
0
    (void)peerSz;
1297
0
    return WOLFSSL_NOT_IMPLEMENTED;
1298
0
#endif
1299
0
}
1300
1301
1302
#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
1303
1304
int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
1305
{
1306
    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()");
1307
1308
    if (ctx == NULL)
1309
        return BAD_FUNC_ARG;
1310
1311
    ctx->dtlsSctp = 1;
1312
    return WOLFSSL_SUCCESS;
1313
}
1314
1315
1316
int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
1317
{
1318
    WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()");
1319
1320
    if (ssl == NULL)
1321
        return BAD_FUNC_ARG;
1322
1323
    ssl->options.dtlsSctp = 1;
1324
    return WOLFSSL_SUCCESS;
1325
}
1326
1327
#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
1328
1329
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
1330
                                                           defined(WOLFSSL_DTLS)
1331
1332
int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
1333
{
1334
    if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
1335
        return BAD_FUNC_ARG;
1336
1337
    ctx->dtlsMtuSz = newMtu;
1338
    return WOLFSSL_SUCCESS;
1339
}
1340
1341
1342
int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
1343
{
1344
    if (ssl == NULL)
1345
        return BAD_FUNC_ARG;
1346
1347
    if (newMtu > MAX_RECORD_SIZE) {
1348
        ssl->error = BAD_FUNC_ARG;
1349
        return WOLFSSL_FAILURE;
1350
    }
1351
1352
    ssl->dtlsMtuSz = newMtu;
1353
    return WOLFSSL_SUCCESS;
1354
}
1355
1356
#endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */
1357
1358
#ifdef WOLFSSL_SRTP
1359
1360
static const WOLFSSL_SRTP_PROTECTION_PROFILE gSrtpProfiles[] = {
1361
    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 80-bits
1362
     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
1363
    {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, (((128 + 112) * 2) / 8) },
1364
    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 32-bits
1365
     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
1366
    {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, (((128 + 112) * 2) / 8) },
1367
    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 80-bits */
1368
    {"SRTP_NULL_SHA1_80", SRTP_NULL_SHA1_80, ((112 * 2) / 8)},
1369
    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 32-bits */
1370
    {"SRTP_NULL_SHA1_32", SRTP_NULL_SHA1_32, ((112 * 2) / 8)},
1371
    /* AES GCM 128, Salt: 96-bits, Auth GCM Tag 128-bits
1372
     * (master_key:128bits + master_salt:96bits) * 2 = 448 bits (56) */
1373
    {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, (((128 + 96) * 2) / 8) },
1374
    /* AES GCM 256, Salt: 96-bits, Auth GCM Tag 128-bits
1375
     * (master_key:256bits + master_salt:96bits) * 2 = 704 bits (88) */
1376
    {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, (((256 + 96) * 2) / 8) },
1377
};
1378
1379
static const WOLFSSL_SRTP_PROTECTION_PROFILE* DtlsSrtpFindProfile(
1380
    const char* profile_str, word32 profile_str_len, unsigned long id)
1381
{
1382
    int i;
1383
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1384
    for (i=0;
1385
         i<(int)(sizeof(gSrtpProfiles)/sizeof(WOLFSSL_SRTP_PROTECTION_PROFILE));
1386
         i++) {
1387
        if (profile_str != NULL) {
1388
            word32 srtp_profile_len = (word32)XSTRLEN(gSrtpProfiles[i].name);
1389
            if (srtp_profile_len == profile_str_len &&
1390
                XMEMCMP(gSrtpProfiles[i].name, profile_str, profile_str_len)
1391
                                                                         == 0) {
1392
                profile = &gSrtpProfiles[i];
1393
                break;
1394
            }
1395
        }
1396
        else if (id != 0 && gSrtpProfiles[i].id == id) {
1397
            profile = &gSrtpProfiles[i];
1398
            break;
1399
        }
1400
    }
1401
    return profile;
1402
}
1403
1404
/* profile_str: accepts ":" colon separated list of SRTP profiles */
1405
static int DtlsSrtpSelProfiles(word16* id, const char* profile_str)
1406
{
1407
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile;
1408
    const char *current, *next = NULL;
1409
    word32 length = 0, current_length;
1410
1411
    *id = 0; /* reset destination ID's */
1412
1413
    if (profile_str == NULL) {
1414
        return WOLFSSL_FAILURE;
1415
    }
1416
1417
    /* loop on end of line or colon ":" */
1418
    next = profile_str;
1419
    length = (word32)XSTRLEN(profile_str);
1420
    do {
1421
        current = next;
1422
        next = XSTRSTR(current, ":");
1423
        current_length = (!next) ? (word32)XSTRLEN(current)
1424
                                 : (word32)(next - current);
1425
        if (current_length < length)
1426
            length = current_length;
1427
        profile = DtlsSrtpFindProfile(current, current_length, 0);
1428
        if (profile != NULL) {
1429
            *id |= (1 << profile->id); /* selected bit based on ID */
1430
        }
1431
    } while (next != NULL && next++); /* ++ needed to skip ':' */
1432
    return WOLFSSL_SUCCESS;
1433
}
1434
1435
int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str)
1436
{
1437
    int ret = WOLFSSL_FAILURE;
1438
    if (ctx != NULL) {
1439
        ret = DtlsSrtpSelProfiles(&ctx->dtlsSrtpProfiles, profile_str);
1440
    }
1441
    return ret;
1442
}
1443
int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str)
1444
{
1445
    int ret = WOLFSSL_FAILURE;
1446
    if (ssl != NULL) {
1447
        ret = DtlsSrtpSelProfiles(&ssl->dtlsSrtpProfiles, profile_str);
1448
    }
1449
    return ret;
1450
}
1451
1452
const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile(
1453
    WOLFSSL* ssl)
1454
{
1455
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1456
    if (ssl) {
1457
        profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
1458
    }
1459
    return profile;
1460
}
1461
#ifndef NO_WOLFSSL_STUB
1462
WOLF_STACK_OF(WOLFSSL_SRTP_PROTECTION_PROFILE)* wolfSSL_get_srtp_profiles(
1463
    WOLFSSL* ssl)
1464
{
1465
    /* Not yet implemented - should return list of available SRTP profiles
1466
     * ssl->dtlsSrtpProfiles */
1467
    (void)ssl;
1468
    return NULL;
1469
}
1470
#endif
1471
1472
int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl,
1473
    unsigned char* out, size_t* olen)
1474
{
1475
    int ret = WOLFSSL_FAILURE;
1476
    const char* label = "EXTRACTOR-dtls_srtp";
1477
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1478
    byte seed[SEED_LEN];
1479
1480
    if (ssl == NULL || olen == NULL) {
1481
        return BAD_FUNC_ARG;
1482
    }
1483
1484
    profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
1485
    if (profile == NULL) {
1486
        WOLFSSL_MSG("Not using DTLS SRTP");
1487
        return EXT_MISSING;
1488
    }
1489
    if (out == NULL) {
1490
        *olen = profile->kdfBits;
1491
        return LENGTH_ONLY_E;
1492
    }
1493
1494
    if (*olen < (size_t)profile->kdfBits) {
1495
        return BUFFER_E;
1496
    }
1497
1498
#ifdef WOLFSSL_HAVE_PRF
1499
    XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
1500
    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
1501
1502
    PRIVATE_KEY_UNLOCK();
1503
    ret = wc_PRF_TLS(out, profile->kdfBits,   /* out: generated keys / salt */
1504
        ssl->arrays->masterSecret, SECRET_LEN,  /* existing master secret */
1505
        (const byte*)label, (int)XSTRLEN(label),/* label */
1506
        seed, SEED_LEN,                         /* seed: client/server random */
1507
        IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
1508
        ssl->heap, INVALID_DEVID);
1509
    if (ret == 0) {
1510
        *olen = profile->kdfBits;
1511
        ret = WOLFSSL_SUCCESS;
1512
    }
1513
    PRIVATE_KEY_LOCK();
1514
#else
1515
    /* Pseudo random function must be enabled in the configuration */
1516
    ret = PRF_MISSING;
1517
#endif
1518
1519
    return ret;
1520
}
1521
1522
#endif /* WOLFSSL_SRTP */
1523
1524
1525
#ifdef WOLFSSL_DTLS_DROP_STATS
1526
1527
int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
1528
                                word32* macDropCount, word32* replayDropCount)
1529
{
1530
    int ret;
1531
1532
    WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats()");
1533
1534
    if (ssl == NULL)
1535
        ret = BAD_FUNC_ARG;
1536
    else {
1537
        ret = WOLFSSL_SUCCESS;
1538
        if (macDropCount != NULL)
1539
            *macDropCount = ssl->macDropCount;
1540
        if (replayDropCount != NULL)
1541
            *replayDropCount = ssl->replayDropCount;
1542
    }
1543
1544
    WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats()", ret);
1545
    return ret;
1546
}
1547
1548
#endif /* WOLFSSL_DTLS_DROP_STATS */
1549
1550
1551
#if defined(WOLFSSL_MULTICAST)
1552
1553
int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
1554
{
1555
    int ret = 0;
1556
1557
    WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id()");
1558
1559
    if (ctx == NULL || id > 255)
1560
        ret = BAD_FUNC_ARG;
1561
1562
    if (ret == 0) {
1563
        ctx->haveEMS = 0;
1564
        ctx->haveMcast = 1;
1565
        ctx->mcastID = (byte)id;
1566
#ifndef WOLFSSL_USER_IO
1567
        ctx->CBIORecv = EmbedReceiveFromMcast;
1568
#endif /* WOLFSSL_USER_IO */
1569
1570
        ret = WOLFSSL_SUCCESS;
1571
    }
1572
    WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id()", ret);
1573
    return ret;
1574
}
1575
1576
int wolfSSL_mcast_get_max_peers(void)
1577
{
1578
    return WOLFSSL_MULTICAST_PEERS;
1579
}
1580
1581
#ifdef WOLFSSL_DTLS
1582
static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
1583
                                         word32 second, word32 high)
1584
{
1585
    word32 newCur = 0;
1586
1587
    if (cur < first)
1588
        newCur = first;
1589
    else if (cur < second)
1590
        newCur = second;
1591
    else if (cur < high)
1592
        newCur = high;
1593
1594
    return newCur;
1595
}
1596
#endif /* WOLFSSL_DTLS */
1597
1598
1599
int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
1600
                       const byte* preMasterSecret, word32 preMasterSz,
1601
                       const byte* clientRandom, const byte* serverRandom,
1602
                       const byte* suite)
1603
{
1604
    int ret = 0;
1605
1606
    WOLFSSL_ENTER("wolfSSL_set_secret()");
1607
1608
    if (ssl == NULL || preMasterSecret == NULL ||
1609
        preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
1610
        clientRandom == NULL || serverRandom == NULL || suite == NULL) {
1611
1612
        ret = BAD_FUNC_ARG;
1613
    }
1614
1615
    if (ret == 0 && ssl->arrays->preMasterSecret == NULL) {
1616
        ssl->arrays->preMasterSz = ENCRYPT_LEN;
1617
        ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
1618
            DYNAMIC_TYPE_SECRET);
1619
        if (ssl->arrays->preMasterSecret == NULL) {
1620
            ret = MEMORY_E;
1621
        }
1622
    }
1623
1624
    if (ret == 0) {
1625
        XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
1626
        XMEMSET(ssl->arrays->preMasterSecret + preMasterSz, 0, ENCRYPT_LEN - preMasterSz);
1627
        ssl->arrays->preMasterSz = preMasterSz;
1628
        XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
1629
        XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
1630
        ssl->options.cipherSuite0 = suite[0];
1631
        ssl->options.cipherSuite = suite[1];
1632
1633
        ret = SetCipherSpecs(ssl);
1634
    }
1635
1636
    if (ret == 0)
1637
        ret = MakeTlsMasterSecret(ssl);
1638
1639
    if (ret == 0) {
1640
        ssl->keys.encryptionOn = 1;
1641
        ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
1642
    }
1643
1644
    if (ret == 0) {
1645
        if (ssl->options.dtls) {
1646
        #ifdef WOLFSSL_DTLS
1647
            WOLFSSL_DTLS_PEERSEQ* peerSeq;
1648
            int i;
1649
1650
            ssl->keys.dtls_epoch = epoch;
1651
            for (i = 0, peerSeq = ssl->keys.peerSeq;
1652
                 i < WOLFSSL_DTLS_PEERSEQ_SZ;
1653
                 i++, peerSeq++) {
1654
1655
                peerSeq->nextEpoch = epoch;
1656
                peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
1657
                peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
1658
                peerSeq->nextSeq_lo = 0;
1659
                peerSeq->nextSeq_hi = 0;
1660
                XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
1661
                XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
1662
                peerSeq->highwaterMark = UpdateHighwaterMark(0,
1663
                        ssl->ctx->mcastFirstSeq,
1664
                        ssl->ctx->mcastSecondSeq,
1665
                        ssl->ctx->mcastMaxSeq);
1666
            }
1667
        #else
1668
            (void)epoch;
1669
        #endif
1670
        }
1671
        FreeHandshakeResources(ssl);
1672
        ret = WOLFSSL_SUCCESS;
1673
    }
1674
    else {
1675
        if (ssl)
1676
            ssl->error = ret;
1677
        ret = WOLFSSL_FATAL_ERROR;
1678
    }
1679
    WOLFSSL_LEAVE("wolfSSL_set_secret()", ret);
1680
    return ret;
1681
}
1682
1683
1684
#ifdef WOLFSSL_DTLS
1685
1686
int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int sub)
1687
{
1688
    WOLFSSL_DTLS_PEERSEQ* p = NULL;
1689
    int ret = WOLFSSL_SUCCESS;
1690
    int i;
1691
1692
    WOLFSSL_ENTER("wolfSSL_mcast_peer_add()");
1693
    if (ssl == NULL || peerId > 255)
1694
        return BAD_FUNC_ARG;
1695
1696
    if (!sub) {
1697
        /* Make sure it isn't already present, while keeping the first
1698
         * open spot. */
1699
        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1700
            if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
1701
                p = &ssl->keys.peerSeq[i];
1702
            if (ssl->keys.peerSeq[i].peerId == peerId) {
1703
                WOLFSSL_MSG("Peer ID already in multicast peer list.");
1704
                p = NULL;
1705
            }
1706
        }
1707
1708
        if (p != NULL) {
1709
            XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
1710
            p->peerId = peerId;
1711
            p->highwaterMark = UpdateHighwaterMark(0,
1712
                ssl->ctx->mcastFirstSeq,
1713
                ssl->ctx->mcastSecondSeq,
1714
                ssl->ctx->mcastMaxSeq);
1715
        }
1716
        else {
1717
            WOLFSSL_MSG("No room in peer list.");
1718
            ret = -1;
1719
        }
1720
    }
1721
    else {
1722
        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1723
            if (ssl->keys.peerSeq[i].peerId == peerId)
1724
                p = &ssl->keys.peerSeq[i];
1725
        }
1726
1727
        if (p != NULL) {
1728
            p->peerId = INVALID_PEER_ID;
1729
        }
1730
        else {
1731
            WOLFSSL_MSG("Peer not found in list.");
1732
        }
1733
    }
1734
1735
    WOLFSSL_LEAVE("wolfSSL_mcast_peer_add()", ret);
1736
    return ret;
1737
}
1738
1739
1740
/* If peerId is in the list of peers and its last sequence number is non-zero,
1741
 * return 1, otherwise return 0. */
1742
int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
1743
{
1744
    int known = 0;
1745
    int i;
1746
1747
    WOLFSSL_ENTER("wolfSSL_mcast_peer_known()");
1748
1749
    if (ssl == NULL || peerId > 255) {
1750
        return BAD_FUNC_ARG;
1751
    }
1752
1753
    for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1754
        if (ssl->keys.peerSeq[i].peerId == peerId) {
1755
            if (ssl->keys.peerSeq[i].nextSeq_hi ||
1756
                ssl->keys.peerSeq[i].nextSeq_lo) {
1757
1758
                known = 1;
1759
            }
1760
            break;
1761
        }
1762
    }
1763
1764
    WOLFSSL_LEAVE("wolfSSL_mcast_peer_known()", known);
1765
    return known;
1766
}
1767
1768
1769
int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
1770
                                       word32 first, word32 second,
1771
                                       CallbackMcastHighwater cb)
1772
{
1773
    if (ctx == NULL || (second && first > second) ||
1774
        first > maxSeq || second > maxSeq || cb == NULL) {
1775
1776
        return BAD_FUNC_ARG;
1777
    }
1778
1779
    ctx->mcastHwCb = cb;
1780
    ctx->mcastFirstSeq = first;
1781
    ctx->mcastSecondSeq = second;
1782
    ctx->mcastMaxSeq = maxSeq;
1783
1784
    return WOLFSSL_SUCCESS;
1785
}
1786
1787
1788
int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
1789
{
1790
    if (ssl == NULL || ctx == NULL)
1791
        return BAD_FUNC_ARG;
1792
1793
    ssl->mcastHwCbCtx = ctx;
1794
1795
    return WOLFSSL_SUCCESS;
1796
}
1797
1798
#endif /* WOLFSSL_DTLS */
1799
1800
#endif /* WOLFSSL_MULTICAST */
1801
1802
1803
#endif /* WOLFSSL_LEANPSK */
1804
1805
1806
/* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
1807
int wolfSSL_negotiate(WOLFSSL* ssl)
1808
0
{
1809
0
    int err = WOLFSSL_FATAL_ERROR;
1810
1811
0
    WOLFSSL_ENTER("wolfSSL_negotiate");
1812
1813
0
    if (ssl == NULL)
1814
0
        return WOLFSSL_FATAL_ERROR;
1815
1816
0
#ifndef NO_WOLFSSL_SERVER
1817
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
1818
0
#ifdef WOLFSSL_TLS13
1819
0
        if (IsAtLeastTLSv1_3(ssl->version))
1820
0
            err = wolfSSL_accept_TLSv13(ssl);
1821
0
        else
1822
0
#endif
1823
0
            err = wolfSSL_accept(ssl);
1824
0
    }
1825
0
#endif
1826
1827
0
#ifndef NO_WOLFSSL_CLIENT
1828
0
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
1829
0
#ifdef WOLFSSL_TLS13
1830
0
        if (IsAtLeastTLSv1_3(ssl->version))
1831
0
            err = wolfSSL_connect_TLSv13(ssl);
1832
0
        else
1833
0
#endif
1834
0
            err = wolfSSL_connect(ssl);
1835
0
    }
1836
0
#endif
1837
1838
0
    (void)ssl;
1839
1840
0
    WOLFSSL_LEAVE("wolfSSL_negotiate", err);
1841
1842
0
    return err;
1843
0
}
1844
1845
1846
WOLFSSL_ABI
1847
WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
1848
0
{
1849
0
    if (ssl) {
1850
0
        return ssl->rng;
1851
0
    }
1852
1853
0
    return NULL;
1854
0
}
1855
1856
1857
#ifndef WOLFSSL_LEANPSK
1858
/* object size based on build */
1859
int wolfSSL_GetObjectSize(void)
1860
0
{
1861
#ifdef SHOW_SIZES
1862
    printf("sizeof suites           = %lu\n", (unsigned long)sizeof(Suites));
1863
    printf("sizeof ciphers(2)       = %lu\n", (unsigned long)sizeof(Ciphers));
1864
#ifndef NO_RC4
1865
    printf("\tsizeof arc4         = %lu\n", (unsigned long)sizeof(Arc4));
1866
#endif
1867
    printf("\tsizeof aes          = %lu\n", (unsigned long)sizeof(Aes));
1868
#ifndef NO_DES3
1869
    printf("\tsizeof des3         = %lu\n", (unsigned long)sizeof(Des3));
1870
#endif
1871
#ifdef HAVE_CHACHA
1872
    printf("\tsizeof chacha       = %lu\n", (unsigned long)sizeof(ChaCha));
1873
#endif
1874
    printf("sizeof cipher specs     = %lu\n", (unsigned long)sizeof(CipherSpecs));
1875
    printf("sizeof keys             = %lu\n", (unsigned long)sizeof(Keys));
1876
    printf("sizeof Hashes(2)        = %lu\n", (unsigned long)sizeof(Hashes));
1877
#ifndef NO_MD5
1878
    printf("\tsizeof MD5          = %lu\n", (unsigned long)sizeof(wc_Md5));
1879
#endif
1880
#ifndef NO_SHA
1881
    printf("\tsizeof SHA          = %lu\n", (unsigned long)sizeof(wc_Sha));
1882
#endif
1883
#ifdef WOLFSSL_SHA224
1884
    printf("\tsizeof SHA224       = %lu\n", (unsigned long)sizeof(wc_Sha224));
1885
#endif
1886
#ifndef NO_SHA256
1887
    printf("\tsizeof SHA256       = %lu\n", (unsigned long)sizeof(wc_Sha256));
1888
#endif
1889
#ifdef WOLFSSL_SHA384
1890
    printf("\tsizeof SHA384       = %lu\n", (unsigned long)sizeof(wc_Sha384));
1891
#endif
1892
#ifdef WOLFSSL_SHA384
1893
    printf("\tsizeof SHA512       = %lu\n", (unsigned long)sizeof(wc_Sha512));
1894
#endif
1895
    printf("sizeof Buffers          = %lu\n", (unsigned long)sizeof(Buffers));
1896
    printf("sizeof Options          = %lu\n", (unsigned long)sizeof(Options));
1897
    printf("sizeof Arrays           = %lu\n", (unsigned long)sizeof(Arrays));
1898
#ifndef NO_RSA
1899
    printf("sizeof RsaKey           = %lu\n", (unsigned long)sizeof(RsaKey));
1900
#endif
1901
#ifdef HAVE_ECC
1902
    printf("sizeof ecc_key          = %lu\n", (unsigned long)sizeof(ecc_key));
1903
#endif
1904
    printf("sizeof WOLFSSL_CIPHER    = %lu\n", (unsigned long)sizeof(WOLFSSL_CIPHER));
1905
    printf("sizeof WOLFSSL_SESSION   = %lu\n", (unsigned long)sizeof(WOLFSSL_SESSION));
1906
    printf("sizeof WOLFSSL           = %lu\n", (unsigned long)sizeof(WOLFSSL));
1907
    printf("sizeof WOLFSSL_CTX       = %lu\n", (unsigned long)sizeof(WOLFSSL_CTX));
1908
#endif
1909
1910
0
    return sizeof(WOLFSSL);
1911
0
}
1912
1913
int wolfSSL_CTX_GetObjectSize(void)
1914
0
{
1915
0
    return sizeof(WOLFSSL_CTX);
1916
0
}
1917
1918
int wolfSSL_METHOD_GetObjectSize(void)
1919
0
{
1920
0
    return sizeof(WOLFSSL_METHOD);
1921
0
}
1922
#endif
1923
1924
1925
#ifdef WOLFSSL_STATIC_MEMORY
1926
1927
int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method,
1928
                                   unsigned char* buf, unsigned int sz,
1929
                                   int flag, int maxSz)
1930
{
1931
    WOLFSSL_HEAP*      heap;
1932
    WOLFSSL_HEAP_HINT* hint;
1933
    word32 idx = 0;
1934
1935
    if (ctx == NULL || buf == NULL) {
1936
        return BAD_FUNC_ARG;
1937
    }
1938
1939
    if (*ctx == NULL && method == NULL) {
1940
        return BAD_FUNC_ARG;
1941
    }
1942
1943
    if (*ctx == NULL || (*ctx)->heap == NULL) {
1944
        if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) {
1945
            return BUFFER_E; /* not enough memory for structures */
1946
        }
1947
        heap = (WOLFSSL_HEAP*)buf;
1948
        idx += sizeof(WOLFSSL_HEAP);
1949
        if (wolfSSL_init_memory_heap(heap) != 0) {
1950
            return WOLFSSL_FAILURE;
1951
        }
1952
        hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
1953
        idx += sizeof(WOLFSSL_HEAP_HINT);
1954
        XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
1955
        hint->memory = heap;
1956
1957
        if (*ctx && (*ctx)->heap == NULL) {
1958
            (*ctx)->heap = (void*)hint;
1959
        }
1960
    }
1961
    else {
1962
#ifdef WOLFSSL_HEAP_TEST
1963
        /* do not load in memory if test has been set */
1964
        if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) {
1965
            return WOLFSSL_SUCCESS;
1966
        }
1967
#endif
1968
        hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap);
1969
        heap = hint->memory;
1970
    }
1971
1972
    if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
1973
        WOLFSSL_MSG("Error partitioning memory");
1974
        return WOLFSSL_FAILURE;
1975
    }
1976
1977
    /* create ctx if needed */
1978
    if (*ctx == NULL) {
1979
        *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
1980
        if (*ctx == NULL) {
1981
            WOLFSSL_MSG("Error creating ctx");
1982
            return WOLFSSL_FAILURE;
1983
        }
1984
    }
1985
1986
    /* determine what max applies too */
1987
    if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
1988
        heap->maxIO = maxSz;
1989
    }
1990
    else { /* general memory used in handshakes */
1991
        heap->maxHa = maxSz;
1992
    }
1993
1994
    heap->flag |= flag;
1995
1996
    (void)maxSz;
1997
    (void)method;
1998
1999
    return WOLFSSL_SUCCESS;
2000
}
2001
2002
2003
int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
2004
{
2005
    if (ssl == NULL) {
2006
        return BAD_FUNC_ARG;
2007
    }
2008
    WOLFSSL_ENTER("wolfSSL_is_static_memory");
2009
2010
    /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
2011
    if (mem_stats != NULL && ssl->heap != NULL) {
2012
        WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
2013
        WOLFSSL_HEAP* heap      = hint->memory;
2014
        if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
2015
            XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
2016
        }
2017
    }
2018
2019
    return (ssl->heap) ? 1 : 0;
2020
}
2021
2022
2023
int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
2024
{
2025
    if (ctx == NULL) {
2026
        return BAD_FUNC_ARG;
2027
    }
2028
    WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
2029
2030
    /* fill out statistics if wanted */
2031
    if (mem_stats != NULL && ctx->heap != NULL) {
2032
        WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
2033
        if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
2034
            return MEMORY_E;
2035
        }
2036
    }
2037
2038
    return (ctx->heap) ? 1 : 0;
2039
}
2040
2041
#endif /* WOLFSSL_STATIC_MEMORY */
2042
2043
2044
/* return max record layer size plaintext input size */
2045
int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
2046
0
{
2047
0
    WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
2048
2049
0
    if (ssl == NULL)
2050
0
        return BAD_FUNC_ARG;
2051
2052
0
    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
2053
0
        WOLFSSL_MSG("Handshake not complete yet");
2054
0
        return BAD_FUNC_ARG;
2055
0
    }
2056
2057
0
    return wolfSSL_GetMaxFragSize(ssl, OUTPUT_RECORD_SIZE);
2058
0
}
2059
2060
2061
/* return record layer size of plaintext input size */
2062
int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
2063
0
{
2064
0
    int maxSize;
2065
2066
0
    WOLFSSL_ENTER("wolfSSL_GetOutputSize");
2067
2068
0
    if (inSz < 0)
2069
0
        return BAD_FUNC_ARG;
2070
2071
0
    maxSize = wolfSSL_GetMaxOutputSize(ssl);
2072
0
    if (maxSize < 0)
2073
0
        return maxSize;   /* error */
2074
0
    if (inSz > maxSize)
2075
0
        return INPUT_SIZE_E;
2076
2077
0
    return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0, CUR_ORDER);
2078
0
}
2079
2080
2081
#ifdef HAVE_ECC
2082
int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2083
0
{
2084
0
    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
2085
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
2086
0
        return BAD_FUNC_ARG;
2087
0
    }
2088
2089
0
    ctx->minEccKeySz     = keySz / 8;
2090
0
#ifndef NO_CERTS
2091
0
    ctx->cm->minEccKeySz = keySz / 8;
2092
0
#endif
2093
0
    return WOLFSSL_SUCCESS;
2094
0
}
2095
2096
2097
int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
2098
0
{
2099
0
    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
2100
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
2101
0
        return BAD_FUNC_ARG;
2102
0
    }
2103
2104
0
    ssl->options.minEccKeySz = keySz / 8;
2105
0
    return WOLFSSL_SUCCESS;
2106
0
}
2107
2108
#endif /* HAVE_ECC */
2109
2110
#ifndef NO_RSA
2111
int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2112
0
{
2113
0
    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
2114
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
2115
0
        return BAD_FUNC_ARG;
2116
0
    }
2117
2118
0
    ctx->minRsaKeySz     = keySz / 8;
2119
0
    ctx->cm->minRsaKeySz = keySz / 8;
2120
0
    return WOLFSSL_SUCCESS;
2121
0
}
2122
2123
2124
int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
2125
0
{
2126
0
    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
2127
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
2128
0
        return BAD_FUNC_ARG;
2129
0
    }
2130
2131
0
    ssl->options.minRsaKeySz = keySz / 8;
2132
0
    return WOLFSSL_SUCCESS;
2133
0
}
2134
#endif /* !NO_RSA */
2135
2136
#ifndef NO_DH
2137
/* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
2138
int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
2139
                    const unsigned char* g, int gSz)
2140
0
{
2141
0
    WOLFSSL_ENTER("wolfSSL_SetTmpDH");
2142
2143
0
    if (ssl == NULL || p == NULL || g == NULL)
2144
0
        return BAD_FUNC_ARG;
2145
2146
0
    if ((word16)pSz < ssl->options.minDhKeySz)
2147
0
        return DH_KEY_SIZE_E;
2148
0
    if ((word16)pSz > ssl->options.maxDhKeySz)
2149
0
        return DH_KEY_SIZE_E;
2150
2151
    /* this function is for server only */
2152
0
    if (ssl->options.side == WOLFSSL_CLIENT_END)
2153
0
        return SIDE_ERROR;
2154
2155
0
    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2156
0
        !defined(HAVE_SELFTEST)
2157
0
        ssl->options.dhKeyTested = 0;
2158
0
        ssl->options.dhDoKeyTest = 1;
2159
0
    #endif
2160
2161
0
    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
2162
0
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2163
0
        ssl->buffers.serverDH_P.buffer = NULL;
2164
0
    }
2165
0
    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
2166
0
        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2167
0
        ssl->buffers.serverDH_G.buffer = NULL;
2168
0
    }
2169
2170
0
    ssl->buffers.weOwnDH = 1;  /* SSL owns now */
2171
0
    ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,
2172
0
                                                    DYNAMIC_TYPE_PUBLIC_KEY);
2173
0
    if (ssl->buffers.serverDH_P.buffer == NULL)
2174
0
            return MEMORY_E;
2175
2176
0
    ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->heap,
2177
0
                                                    DYNAMIC_TYPE_PUBLIC_KEY);
2178
0
    if (ssl->buffers.serverDH_G.buffer == NULL) {
2179
0
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2180
0
        ssl->buffers.serverDH_P.buffer = NULL;
2181
0
        return MEMORY_E;
2182
0
    }
2183
2184
0
    ssl->buffers.serverDH_P.length = pSz;
2185
0
    ssl->buffers.serverDH_G.length = gSz;
2186
2187
0
    XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
2188
0
    XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
2189
2190
0
    ssl->options.haveDH = 1;
2191
2192
0
    if (ssl->options.side != WOLFSSL_NEITHER_END) {
2193
0
        word16 havePSK;
2194
0
        word16 haveRSA;
2195
0
        int    keySz   = 0;
2196
2197
    #ifndef NO_PSK
2198
        havePSK = ssl->options.havePSK;
2199
    #else
2200
0
        havePSK = 0;
2201
0
    #endif
2202
    #ifdef NO_RSA
2203
        haveRSA = 0;
2204
    #else
2205
0
        haveRSA = 1;
2206
0
    #endif
2207
0
    #ifndef NO_CERTS
2208
0
        keySz = ssl->buffers.keySz;
2209
0
    #endif
2210
0
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
2211
0
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
2212
0
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
2213
0
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
2214
0
                   ssl->options.haveAnon, TRUE, ssl->options.side);
2215
0
    }
2216
2217
0
    WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
2218
2219
0
    return WOLFSSL_SUCCESS;
2220
0
}
2221
2222
2223
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2224
    !defined(HAVE_SELFTEST)
2225
/* Enables or disables the session's DH key prime test. */
2226
int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
2227
0
{
2228
0
    WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
2229
2230
0
    if (ssl == NULL)
2231
0
        return BAD_FUNC_ARG;
2232
2233
0
    if (!enable)
2234
0
        ssl->options.dhDoKeyTest = 0;
2235
0
    else
2236
0
        ssl->options.dhDoKeyTest = 1;
2237
2238
0
    WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
2239
0
    return WOLFSSL_SUCCESS;
2240
0
}
2241
#endif
2242
2243
2244
/* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
2245
int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
2246
                         const unsigned char* g, int gSz)
2247
0
{
2248
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
2249
0
    if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
2250
2251
0
    if ((word16)pSz < ctx->minDhKeySz)
2252
0
        return DH_KEY_SIZE_E;
2253
0
    if ((word16)pSz > ctx->maxDhKeySz)
2254
0
        return DH_KEY_SIZE_E;
2255
2256
0
    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2257
0
        !defined(HAVE_SELFTEST)
2258
0
    {
2259
0
        WC_RNG rng;
2260
0
        int error, freeKey = 0;
2261
0
    #ifdef WOLFSSL_SMALL_STACK
2262
0
        DhKey *checkKey = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
2263
0
        if (checkKey == NULL)
2264
0
            return MEMORY_E;
2265
    #else
2266
        DhKey checkKey[1];
2267
    #endif
2268
2269
0
        error = wc_InitRng(&rng);
2270
0
        if (!error)
2271
0
            error = wc_InitDhKey(checkKey);
2272
0
        if (!error) {
2273
0
            freeKey = 1;
2274
0
            error = wc_DhSetCheckKey(checkKey,
2275
0
                                 p, pSz, g, gSz, NULL, 0, 0, &rng);
2276
0
        }
2277
0
        if (freeKey)
2278
0
            wc_FreeDhKey(checkKey);
2279
0
    #ifdef WOLFSSL_SMALL_STACK
2280
0
        XFREE(checkKey, NULL, DYNAMIC_TYPE_DH);
2281
0
    #endif
2282
0
        wc_FreeRng(&rng);
2283
0
        if (error)
2284
0
            return error;
2285
2286
0
        ctx->dhKeyTested = 1;
2287
0
    }
2288
0
    #endif
2289
2290
0
    XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2291
0
    ctx->serverDH_P.buffer = NULL;
2292
0
    XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2293
0
    ctx->serverDH_G.buffer = NULL;
2294
2295
0
    ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2296
0
    if (ctx->serverDH_P.buffer == NULL)
2297
0
       return MEMORY_E;
2298
2299
0
    ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2300
0
    if (ctx->serverDH_G.buffer == NULL) {
2301
0
        XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2302
0
        ctx->serverDH_P.buffer = NULL;
2303
0
        return MEMORY_E;
2304
0
    }
2305
2306
0
    ctx->serverDH_P.length = pSz;
2307
0
    ctx->serverDH_G.length = gSz;
2308
2309
0
    XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
2310
0
    XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
2311
2312
0
    ctx->haveDH = 1;
2313
2314
0
    WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
2315
0
    return WOLFSSL_SUCCESS;
2316
0
}
2317
2318
2319
int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2320
0
{
2321
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2322
0
        return BAD_FUNC_ARG;
2323
2324
0
    ctx->minDhKeySz = keySz_bits / 8;
2325
0
    return WOLFSSL_SUCCESS;
2326
0
}
2327
2328
2329
int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2330
0
{
2331
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2332
0
        return BAD_FUNC_ARG;
2333
2334
0
    ssl->options.minDhKeySz = keySz_bits / 8;
2335
0
    return WOLFSSL_SUCCESS;
2336
0
}
2337
2338
2339
int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2340
0
{
2341
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2342
0
        return BAD_FUNC_ARG;
2343
2344
0
    ctx->maxDhKeySz = keySz_bits / 8;
2345
0
    return WOLFSSL_SUCCESS;
2346
0
}
2347
2348
2349
int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2350
0
{
2351
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2352
0
        return BAD_FUNC_ARG;
2353
2354
0
    ssl->options.maxDhKeySz = keySz_bits / 8;
2355
0
    return WOLFSSL_SUCCESS;
2356
0
}
2357
2358
2359
int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
2360
0
{
2361
0
    if (ssl == NULL)
2362
0
        return BAD_FUNC_ARG;
2363
2364
0
    return (ssl->options.dhKeySz * 8);
2365
0
}
2366
2367
#endif /* !NO_DH */
2368
2369
2370
WOLFSSL_ABI
2371
int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
2372
0
{
2373
0
    int ret;
2374
2375
0
    WOLFSSL_ENTER("SSL_write()");
2376
2377
0
    if (ssl == NULL || data == NULL || sz < 0)
2378
0
        return BAD_FUNC_ARG;
2379
2380
#ifdef WOLFSSL_QUIC
2381
    if (WOLFSSL_IS_QUIC(ssl)) {
2382
        WOLFSSL_MSG("SSL_write() on QUIC not allowed");
2383
        return BAD_FUNC_ARG;
2384
    }
2385
#endif
2386
#ifdef WOLFSSL_EARLY_DATA
2387
    if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
2388
        ssl->error = ret;
2389
        return WOLFSSL_FATAL_ERROR;
2390
    }
2391
    ssl->earlyData = no_early_data;
2392
#endif
2393
2394
#ifdef HAVE_WRITE_DUP
2395
    { /* local variable scope */
2396
        int dupErr = 0;   /* local copy */
2397
2398
        ret = 0;
2399
2400
        if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
2401
            WOLFSSL_MSG("Read dup side cannot write");
2402
            return WRITE_DUP_WRITE_E;
2403
        }
2404
        if (ssl->dupWrite) {
2405
            if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
2406
                return BAD_MUTEX_E;
2407
            }
2408
            dupErr = ssl->dupWrite->dupErr;
2409
            ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
2410
        }
2411
2412
        if (ret != 0) {
2413
            ssl->error = ret;  /* high priority fatal error */
2414
            return WOLFSSL_FATAL_ERROR;
2415
        }
2416
        if (dupErr != 0) {
2417
            WOLFSSL_MSG("Write dup error from other side");
2418
            ssl->error = dupErr;
2419
            return WOLFSSL_FATAL_ERROR;
2420
        }
2421
    }
2422
#endif
2423
2424
0
#ifdef HAVE_ERRNO_H
2425
0
    errno = 0;
2426
0
#endif
2427
2428
    #ifdef OPENSSL_EXTRA
2429
    if (ssl->CBIS != NULL) {
2430
        ssl->CBIS(ssl, SSL_CB_WRITE, WOLFSSL_SUCCESS);
2431
        ssl->cbmode = SSL_CB_WRITE;
2432
    }
2433
    #endif
2434
0
    ret = SendData(ssl, data, sz);
2435
2436
0
    WOLFSSL_LEAVE("SSL_write()", ret);
2437
2438
0
    if (ret < 0)
2439
0
        return WOLFSSL_FATAL_ERROR;
2440
0
    else
2441
0
        return ret;
2442
0
}
2443
2444
static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
2445
0
{
2446
0
    int ret;
2447
2448
0
    WOLFSSL_ENTER("wolfSSL_read_internal()");
2449
2450
0
    if (ssl == NULL || data == NULL || sz < 0)
2451
0
        return BAD_FUNC_ARG;
2452
2453
#ifdef WOLFSSL_QUIC
2454
    if (WOLFSSL_IS_QUIC(ssl)) {
2455
        WOLFSSL_MSG("SSL_read() on QUIC not allowed");
2456
        return BAD_FUNC_ARG;
2457
    }
2458
#endif
2459
#if defined(WOLFSSL_ERROR_CODE_OPENSSL) && defined(OPENSSL_EXTRA)
2460
    /* This additional logic is meant to simulate following openSSL behavior:
2461
     * After bidirectional SSL_shutdown complete, SSL_read returns 0 and
2462
     * SSL_get_error_code returns SSL_ERROR_ZERO_RETURN.
2463
     * This behavior is used to know the disconnect of the underlying
2464
     * transport layer.
2465
     *
2466
     * In this logic, CBIORecv is called with a read size of 0 to check the
2467
     * transport layer status. It also returns WOLFSSL_FAILURE so that
2468
     * SSL_read does not return a positive number on failure.
2469
     */
2470
2471
    /* make sure bidirectional TLS shutdown completes */
2472
    if (ssl->error == WOLFSSL_ERROR_SYSCALL) {
2473
        /* ask the underlying transport the connection is closed */
2474
        if (ssl->CBIORecv(ssl, (char*)data, 0, ssl->IOCB_ReadCtx) ==
2475
                                            WOLFSSL_CBIO_ERR_CONN_CLOSE) {
2476
            ssl->options.isClosed = 1;
2477
            ssl->error = WOLFSSL_ERROR_ZERO_RETURN;
2478
        }
2479
        return WOLFSSL_FAILURE;
2480
    }
2481
#endif
2482
2483
#ifdef HAVE_WRITE_DUP
2484
    if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
2485
        WOLFSSL_MSG("Write dup side cannot read");
2486
        return WRITE_DUP_READ_E;
2487
    }
2488
#endif
2489
2490
0
#ifdef HAVE_ERRNO_H
2491
0
        errno = 0;
2492
0
#endif
2493
2494
#ifdef WOLFSSL_DTLS
2495
    if (ssl->options.dtls) {
2496
        ssl->dtls_expected_rx = max(sz + DTLS_MTU_ADDITIONAL_READ_BUFFER,
2497
                MAX_MTU);
2498
#ifdef WOLFSSL_SCTP
2499
        if (ssl->options.dtlsSctp)
2500
#endif
2501
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
2502
            /* Add some bytes so that we can operate with slight difference
2503
             * in set MTU size on each peer */
2504
            ssl->dtls_expected_rx = max(ssl->dtls_expected_rx,
2505
                    ssl->dtlsMtuSz + (word32)DTLS_MTU_ADDITIONAL_READ_BUFFER);
2506
#endif
2507
    }
2508
#endif
2509
2510
0
    ret = ReceiveData(ssl, (byte*)data, sz, peek);
2511
2512
#ifdef HAVE_WRITE_DUP
2513
    if (ssl->dupWrite) {
2514
        if (ssl->error != 0 && ssl->error != WANT_READ
2515
        #ifdef WOLFSSL_ASYNC_CRYPT
2516
            && ssl->error != WC_PENDING_E
2517
        #endif
2518
        ) {
2519
            int notifyErr;
2520
2521
            WOLFSSL_MSG("Notifying write side of fatal read error");
2522
            notifyErr  = NotifyWriteSide(ssl, ssl->error);
2523
            if (notifyErr < 0) {
2524
                ret = ssl->error = notifyErr;
2525
            }
2526
        }
2527
    }
2528
#endif
2529
2530
0
    WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
2531
2532
0
    if (ret < 0)
2533
0
        return WOLFSSL_FATAL_ERROR;
2534
0
    else
2535
0
        return ret;
2536
0
}
2537
2538
2539
int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
2540
0
{
2541
0
    WOLFSSL_ENTER("wolfSSL_peek()");
2542
2543
0
    return wolfSSL_read_internal(ssl, data, sz, TRUE);
2544
0
}
2545
2546
2547
WOLFSSL_ABI
2548
int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
2549
0
{
2550
0
    WOLFSSL_ENTER("wolfSSL_read()");
2551
2552
    #ifdef OPENSSL_EXTRA
2553
    if (ssl == NULL) {
2554
        return BAD_FUNC_ARG;
2555
    }
2556
    if (ssl->CBIS != NULL) {
2557
        ssl->CBIS(ssl, SSL_CB_READ, WOLFSSL_SUCCESS);
2558
        ssl->cbmode = SSL_CB_READ;
2559
    }
2560
    #endif
2561
0
    return wolfSSL_read_internal(ssl, data, sz, FALSE);
2562
0
}
2563
2564
2565
#ifdef WOLFSSL_MULTICAST
2566
2567
int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
2568
{
2569
    int ret = 0;
2570
2571
    WOLFSSL_ENTER("wolfSSL_mcast_read()");
2572
2573
    if (ssl == NULL)
2574
        return BAD_FUNC_ARG;
2575
2576
    ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
2577
    if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
2578
        *id = ssl->keys.curPeerId;
2579
    return ret;
2580
}
2581
2582
#endif /* WOLFSSL_MULTICAST */
2583
2584
2585
/* helpers to set the device id, WOLFSSL_SUCCESS on ok */
2586
WOLFSSL_ABI
2587
int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
2588
0
{
2589
0
    if (ssl == NULL)
2590
0
        return BAD_FUNC_ARG;
2591
2592
0
    ssl->devId = devId;
2593
2594
0
    return WOLFSSL_SUCCESS;
2595
0
}
2596
2597
WOLFSSL_ABI
2598
int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
2599
0
{
2600
0
    if (ctx == NULL)
2601
0
        return BAD_FUNC_ARG;
2602
2603
0
    ctx->devId = devId;
2604
2605
0
    return WOLFSSL_SUCCESS;
2606
0
}
2607
2608
/* helpers to get device id and heap */
2609
WOLFSSL_ABI
2610
int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2611
0
{
2612
0
    int devId = INVALID_DEVID;
2613
0
    if (ssl != NULL)
2614
0
        devId = ssl->devId;
2615
0
    if (ctx != NULL && devId == INVALID_DEVID)
2616
0
        devId = ctx->devId;
2617
0
    return devId;
2618
0
}
2619
void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2620
0
{
2621
0
    void* heap = NULL;
2622
0
    if (ctx != NULL)
2623
0
        heap = ctx->heap;
2624
0
    else if (ssl != NULL)
2625
0
        heap = ssl->heap;
2626
0
    return heap;
2627
0
}
2628
2629
2630
#ifdef HAVE_SNI
2631
2632
WOLFSSL_ABI
2633
int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
2634
{
2635
    if (ssl == NULL)
2636
        return BAD_FUNC_ARG;
2637
2638
    return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
2639
}
2640
2641
2642
WOLFSSL_ABI
2643
int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
2644
                                                                    word16 size)
2645
{
2646
    if (ctx == NULL)
2647
        return BAD_FUNC_ARG;
2648
2649
    return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
2650
}
2651
2652
#ifndef NO_WOLFSSL_SERVER
2653
2654
void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
2655
{
2656
    if (ssl && ssl->extensions)
2657
        TLSX_SNI_SetOptions(ssl->extensions, type, options);
2658
}
2659
2660
2661
void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
2662
{
2663
    if (ctx && ctx->extensions)
2664
        TLSX_SNI_SetOptions(ctx->extensions, type, options);
2665
}
2666
2667
2668
byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
2669
{
2670
    return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
2671
}
2672
2673
2674
word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
2675
{
2676
    if (data)
2677
        *data = NULL;
2678
2679
    if (ssl && ssl->extensions)
2680
        return TLSX_SNI_GetRequest(ssl->extensions, type, data);
2681
2682
    return 0;
2683
}
2684
2685
2686
int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
2687
                              byte type, byte* sni, word32* inOutSz)
2688
{
2689
    if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
2690
        return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
2691
2692
    return BAD_FUNC_ARG;
2693
}
2694
2695
#endif /* NO_WOLFSSL_SERVER */
2696
2697
#endif /* HAVE_SNI */
2698
2699
2700
#ifdef HAVE_TRUSTED_CA
2701
2702
WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
2703
            const byte* certId, word32 certIdSz)
2704
{
2705
    if (ssl == NULL)
2706
        return BAD_FUNC_ARG;
2707
2708
    if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
2709
        if (certId != NULL || certIdSz != 0)
2710
            return BAD_FUNC_ARG;
2711
    }
2712
    else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
2713
        if (certId == NULL || certIdSz == 0)
2714
            return BAD_FUNC_ARG;
2715
    }
2716
    #ifndef NO_SHA
2717
    else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
2718
            type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
2719
        if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
2720
            return BAD_FUNC_ARG;
2721
    }
2722
    #endif
2723
    else
2724
        return BAD_FUNC_ARG;
2725
2726
    return TLSX_UseTrustedCA(&ssl->extensions,
2727
            type, certId, certIdSz, ssl->heap);
2728
}
2729
2730
#endif /* HAVE_TRUSTED_CA */
2731
2732
2733
#ifdef HAVE_MAX_FRAGMENT
2734
#ifndef NO_WOLFSSL_CLIENT
2735
2736
int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
2737
{
2738
    if (ssl == NULL)
2739
        return BAD_FUNC_ARG;
2740
2741
#ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
2742
    /* The following is a non-standard way to reconfigure the max packet size
2743
        post-handshake for wolfSSL_write/wolfSSL_read */
2744
    if (ssl->options.handShakeState == HANDSHAKE_DONE) {
2745
        switch (mfl) {
2746
            case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
2747
            case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
2748
            case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
2749
            case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
2750
            case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
2751
            case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
2752
            default: ssl->max_fragment = MAX_RECORD_SIZE; break;
2753
        }
2754
        return WOLFSSL_SUCCESS;
2755
    }
2756
#endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
2757
2758
    /* This call sets the max fragment TLS extension, which gets sent to server.
2759
        The server_hello response is what sets the `ssl->max_fragment` in
2760
        TLSX_MFL_Parse */
2761
    return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
2762
}
2763
2764
2765
int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
2766
{
2767
    if (ctx == NULL)
2768
        return BAD_FUNC_ARG;
2769
2770
    return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
2771
}
2772
2773
#endif /* NO_WOLFSSL_CLIENT */
2774
#endif /* HAVE_MAX_FRAGMENT */
2775
2776
#ifdef HAVE_TRUNCATED_HMAC
2777
#ifndef NO_WOLFSSL_CLIENT
2778
2779
int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
2780
{
2781
    if (ssl == NULL)
2782
        return BAD_FUNC_ARG;
2783
2784
    return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
2785
}
2786
2787
2788
int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
2789
{
2790
    if (ctx == NULL)
2791
        return BAD_FUNC_ARG;
2792
2793
    return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
2794
}
2795
2796
#endif /* NO_WOLFSSL_CLIENT */
2797
#endif /* HAVE_TRUNCATED_HMAC */
2798
2799
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
2800
2801
int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
2802
{
2803
    WOLFSSL_ENTER("wolfSSL_UseOCSPStapling");
2804
2805
    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
2806
        return BAD_FUNC_ARG;
2807
2808
    return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
2809
                                          options, NULL, ssl->heap, ssl->devId);
2810
}
2811
2812
2813
int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
2814
                                                                   byte options)
2815
{
2816
    WOLFSSL_ENTER("wolfSSL_CTX_UseOCSPStapling");
2817
2818
    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
2819
        return BAD_FUNC_ARG;
2820
2821
    return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
2822
                                          options, NULL, ctx->heap, ctx->devId);
2823
}
2824
2825
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
2826
2827
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
2828
2829
int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
2830
{
2831
    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
2832
        return BAD_FUNC_ARG;
2833
2834
    return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
2835
                                                options, ssl->heap, ssl->devId);
2836
}
2837
2838
2839
int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
2840
                                                                   byte options)
2841
{
2842
    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
2843
        return BAD_FUNC_ARG;
2844
2845
    return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
2846
                                                options, ctx->heap, ctx->devId);
2847
}
2848
2849
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
2850
2851
/* Elliptic Curves */
2852
#if defined(HAVE_SUPPORTED_CURVES)
2853
2854
static int isValidCurveGroup(word16 name)
2855
0
{
2856
0
    switch (name) {
2857
0
        case WOLFSSL_ECC_SECP160K1:
2858
0
        case WOLFSSL_ECC_SECP160R1:
2859
0
        case WOLFSSL_ECC_SECP160R2:
2860
0
        case WOLFSSL_ECC_SECP192K1:
2861
0
        case WOLFSSL_ECC_SECP192R1:
2862
0
        case WOLFSSL_ECC_SECP224K1:
2863
0
        case WOLFSSL_ECC_SECP224R1:
2864
0
        case WOLFSSL_ECC_SECP256K1:
2865
0
        case WOLFSSL_ECC_SECP256R1:
2866
0
        case WOLFSSL_ECC_SECP384R1:
2867
0
        case WOLFSSL_ECC_SECP521R1:
2868
0
        case WOLFSSL_ECC_BRAINPOOLP256R1:
2869
0
        case WOLFSSL_ECC_BRAINPOOLP384R1:
2870
0
        case WOLFSSL_ECC_BRAINPOOLP512R1:
2871
0
        case WOLFSSL_ECC_X25519:
2872
0
        case WOLFSSL_ECC_X448:
2873
2874
0
        case WOLFSSL_FFDHE_2048:
2875
0
        case WOLFSSL_FFDHE_3072:
2876
0
        case WOLFSSL_FFDHE_4096:
2877
0
        case WOLFSSL_FFDHE_6144:
2878
0
        case WOLFSSL_FFDHE_8192:
2879
2880
#ifdef HAVE_PQC
2881
        case WOLFSSL_KYBER_LEVEL1:
2882
        case WOLFSSL_KYBER_LEVEL3:
2883
        case WOLFSSL_KYBER_LEVEL5:
2884
    #ifdef HAVE_LIBOQS
2885
        case WOLFSSL_NTRU_HPS_LEVEL1:
2886
        case WOLFSSL_NTRU_HPS_LEVEL3:
2887
        case WOLFSSL_NTRU_HPS_LEVEL5:
2888
        case WOLFSSL_NTRU_HRSS_LEVEL3:
2889
        case WOLFSSL_SABER_LEVEL1:
2890
        case WOLFSSL_SABER_LEVEL3:
2891
        case WOLFSSL_SABER_LEVEL5:
2892
        case WOLFSSL_KYBER_90S_LEVEL1:
2893
        case WOLFSSL_KYBER_90S_LEVEL3:
2894
        case WOLFSSL_KYBER_90S_LEVEL5:
2895
        case WOLFSSL_P256_NTRU_HPS_LEVEL1:
2896
        case WOLFSSL_P384_NTRU_HPS_LEVEL3:
2897
        case WOLFSSL_P521_NTRU_HPS_LEVEL5:
2898
        case WOLFSSL_P384_NTRU_HRSS_LEVEL3:
2899
        case WOLFSSL_P256_SABER_LEVEL1:
2900
        case WOLFSSL_P384_SABER_LEVEL3:
2901
        case WOLFSSL_P521_SABER_LEVEL5:
2902
        case WOLFSSL_P256_KYBER_LEVEL1:
2903
        case WOLFSSL_P384_KYBER_LEVEL3:
2904
        case WOLFSSL_P521_KYBER_LEVEL5:
2905
        case WOLFSSL_P256_KYBER_90S_LEVEL1:
2906
        case WOLFSSL_P384_KYBER_90S_LEVEL3:
2907
        case WOLFSSL_P521_KYBER_90S_LEVEL5:
2908
    #endif
2909
#endif
2910
0
            return 1;
2911
2912
0
        default:
2913
0
            return 0;
2914
0
    }
2915
0
}
2916
2917
int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
2918
0
{
2919
0
    if (ssl == NULL || !isValidCurveGroup(name))
2920
0
        return BAD_FUNC_ARG;
2921
2922
0
    ssl->options.userCurves = 1;
2923
#if defined(NO_TLS)
2924
    return WOLFSSL_FAILURE;
2925
#else
2926
0
    return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
2927
0
#endif /* NO_TLS */
2928
0
}
2929
2930
2931
int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
2932
0
{
2933
0
    if (ctx == NULL || !isValidCurveGroup(name))
2934
0
        return BAD_FUNC_ARG;
2935
2936
0
    ctx->userCurves = 1;
2937
#if defined(NO_TLS)
2938
    return WOLFSSL_FAILURE;
2939
#else
2940
0
    return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
2941
0
#endif /* NO_TLS */
2942
0
}
2943
2944
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13)
2945
int  wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
2946
                                        int count)
2947
{
2948
    int i;
2949
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
2950
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
2951
    if (count == 0) {
2952
        WOLFSSL_MSG("Group count is zero");
2953
        return WOLFSSL_FAILURE;
2954
    }
2955
    for (i = 0; i < count; i++) {
2956
        if (isValidCurveGroup((word16)groups[i])) {
2957
            _groups[i] = groups[i];
2958
        }
2959
#ifdef HAVE_ECC
2960
        else {
2961
            /* groups may be populated with curve NIDs */
2962
            int oid = nid2oid(groups[i], oidCurveType);
2963
            int name = (int)GetCurveByOID(oid);
2964
            if (name == 0) {
2965
                WOLFSSL_MSG("Invalid group name");
2966
                return WOLFSSL_FAILURE;
2967
            }
2968
            _groups[i] = name;
2969
        }
2970
#else
2971
        else {
2972
            WOLFSSL_MSG("Invalid group name");
2973
            return WOLFSSL_FAILURE;
2974
        }
2975
#endif
2976
    }
2977
    return wolfSSL_CTX_set_groups(ctx, _groups, count) == WOLFSSL_SUCCESS ?
2978
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
2979
}
2980
2981
int  wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
2982
{
2983
    int i;
2984
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
2985
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
2986
    if (count == 0) {
2987
        WOLFSSL_MSG("Group count is zero");
2988
        return WOLFSSL_FAILURE;
2989
    }
2990
    for (i = 0; i < count; i++) {
2991
        if (isValidCurveGroup((word16)groups[i])) {
2992
            _groups[i] = groups[i];
2993
        }
2994
#ifdef HAVE_ECC
2995
        else {
2996
            /* groups may be populated with curve NIDs */
2997
            int oid = nid2oid(groups[i], oidCurveType);
2998
            int name = (int)GetCurveByOID(oid);
2999
            if (name == 0) {
3000
                WOLFSSL_MSG("Invalid group name");
3001
                return WOLFSSL_FAILURE;
3002
            }
3003
            _groups[i] = name;
3004
        }
3005
#else
3006
        else {
3007
            WOLFSSL_MSG("Invalid group name");
3008
            return WOLFSSL_FAILURE;
3009
        }
3010
#endif
3011
    }
3012
    return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
3013
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3014
}
3015
#endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 */
3016
#endif /* HAVE_SUPPORTED_CURVES */
3017
3018
/* Application-Layer Protocol Negotiation */
3019
#ifdef HAVE_ALPN
3020
3021
WOLFSSL_ABI
3022
int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
3023
                    word32 protocol_name_listSz, byte options)
3024
{
3025
    char    *list, *ptr, **token;
3026
    word16  len;
3027
    int     idx = 0;
3028
    int     ret = WOLFSSL_FAILURE;
3029
3030
    WOLFSSL_ENTER("wolfSSL_UseALPN");
3031
3032
    if (ssl == NULL || protocol_name_list == NULL)
3033
        return BAD_FUNC_ARG;
3034
3035
    if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
3036
                                WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
3037
                                WOLFSSL_MAX_ALPN_NUMBER)) {
3038
        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
3039
        return BAD_FUNC_ARG;
3040
    }
3041
3042
    if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
3043
        !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
3044
            WOLFSSL_MSG("Invalid arguments, options not supported");
3045
            return BAD_FUNC_ARG;
3046
        }
3047
3048
3049
    list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
3050
                           DYNAMIC_TYPE_ALPN);
3051
    if (list == NULL) {
3052
        WOLFSSL_MSG("Memory failure");
3053
        return MEMORY_ERROR;
3054
    }
3055
3056
    token = (char **)XMALLOC(sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1), ssl->heap, DYNAMIC_TYPE_ALPN);
3057
    if (token == NULL) {
3058
        XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3059
        WOLFSSL_MSG("Memory failure");
3060
        return MEMORY_ERROR;
3061
    }
3062
    XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
3063
3064
    XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
3065
    list[protocol_name_listSz] = '\0';
3066
3067
    /* read all protocol name from the list */
3068
    token[idx] = XSTRTOK(list, ",", &ptr);
3069
    while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL)
3070
        token[++idx] = XSTRTOK(NULL, ",", &ptr);
3071
3072
    /* add protocol name list in the TLS extension in reverse order */
3073
    while ((idx--) > 0) {
3074
        len = (word16)XSTRLEN(token[idx]);
3075
3076
        ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
3077
                                                                     ssl->heap);
3078
        if (ret != WOLFSSL_SUCCESS) {
3079
            WOLFSSL_MSG("TLSX_UseALPN failure");
3080
            break;
3081
        }
3082
    }
3083
3084
    XFREE(token, ssl->heap, DYNAMIC_TYPE_ALPN);
3085
    XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3086
3087
    return ret;
3088
}
3089
3090
int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
3091
{
3092
    return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
3093
                               (void **)protocol_name, size);
3094
}
3095
3096
int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
3097
{
3098
    if (list == NULL || listSz == NULL)
3099
        return BAD_FUNC_ARG;
3100
3101
    if (ssl->alpn_client_list == NULL)
3102
        return BUFFER_ERROR;
3103
3104
    *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
3105
    if (*listSz == 0)
3106
        return BUFFER_ERROR;
3107
3108
    *list = (char *)XMALLOC((*listSz)+1, ssl->heap, DYNAMIC_TYPE_TLSX);
3109
    if (*list == NULL)
3110
        return MEMORY_ERROR;
3111
3112
    XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
3113
    (*list)[*listSz] = 0;
3114
3115
    return WOLFSSL_SUCCESS;
3116
}
3117
3118
3119
/* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
3120
int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
3121
{
3122
    if (ssl == NULL) {
3123
        return BAD_FUNC_ARG;
3124
    }
3125
3126
    XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
3127
    *list = NULL;
3128
3129
    return WOLFSSL_SUCCESS;
3130
}
3131
3132
#endif /* HAVE_ALPN */
3133
3134
/* Secure Renegotiation */
3135
#ifdef HAVE_SERVER_RENEGOTIATION_INFO
3136
3137
/* user is forcing ability to use secure renegotiation, we discourage it */
3138
int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
3139
0
{
3140
0
    int ret = BAD_FUNC_ARG;
3141
#if defined(NO_TLS)
3142
    (void)ssl;
3143
#else
3144
0
    if (ssl)
3145
0
        ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
3146
3147
0
    if (ret == WOLFSSL_SUCCESS) {
3148
0
        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
3149
3150
0
        if (extension)
3151
0
            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
3152
0
    }
3153
0
#endif /* !NO_TLS */
3154
0
    return ret;
3155
0
}
3156
3157
int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
3158
0
{
3159
0
    if (ctx == NULL)
3160
0
        return BAD_FUNC_ARG;
3161
3162
0
    ctx->useSecureReneg = 1;
3163
0
    return WOLFSSL_SUCCESS;
3164
0
}
3165
3166
3167
/* do a secure renegotiation handshake, user forced, we discourage */
3168
static int _Rehandshake(WOLFSSL* ssl)
3169
0
{
3170
0
    int ret;
3171
3172
0
    if (ssl == NULL)
3173
0
        return BAD_FUNC_ARG;
3174
3175
0
    if (IsAtLeastTLSv1_3(ssl->version)) {
3176
0
        WOLFSSL_MSG("Secure Renegotiation not supported in TLS 1.3");
3177
0
        return SECURE_RENEGOTIATION_E;
3178
0
    }
3179
3180
0
    if (ssl->secure_renegotiation == NULL) {
3181
0
        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
3182
0
        return SECURE_RENEGOTIATION_E;
3183
0
    }
3184
3185
0
    if (ssl->secure_renegotiation->enabled == 0) {
3186
0
        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
3187
0
        return SECURE_RENEGOTIATION_E;
3188
0
    }
3189
3190
#ifdef WOLFSSL_DTLS
3191
    if (ssl->options.dtls && ssl->keys.dtls_epoch == 0xFFFF) {
3192
        WOLFSSL_MSG("Secure Renegotiation not allowed. Epoch would wrap");
3193
        return SECURE_RENEGOTIATION_E;
3194
    }
3195
#endif
3196
3197
    /* If the client started the renegotiation, the server will already
3198
     * have processed the client's hello. */
3199
0
    if (ssl->options.side != WOLFSSL_SERVER_END ||
3200
0
        ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
3201
3202
0
        if (ssl->options.handShakeState != HANDSHAKE_DONE) {
3203
0
            if (!ssl->options.handShakeDone) {
3204
0
                WOLFSSL_MSG("Can't renegotiate until initial "
3205
0
                            "handshake complete");
3206
0
                return SECURE_RENEGOTIATION_E;
3207
0
            }
3208
0
            else {
3209
0
                WOLFSSL_MSG("Renegotiation already started. "
3210
0
                            "Moving it forward.");
3211
0
                ret = wolfSSL_negotiate(ssl);
3212
0
                if (ret == WOLFSSL_SUCCESS)
3213
0
                    ssl->secure_rene_count++;
3214
0
                return ret;
3215
0
            }
3216
0
        }
3217
3218
0
#ifndef NO_FORCE_SCR_SAME_SUITE
3219
        /* force same suite */
3220
0
        if (ssl->suites) {
3221
0
            ssl->suites->suiteSz = SUITE_LEN;
3222
0
            ssl->suites->suites[0] = ssl->options.cipherSuite0;
3223
0
            ssl->suites->suites[1] = ssl->options.cipherSuite;
3224
0
        }
3225
0
#endif
3226
3227
        /* reset handshake states */
3228
0
        ssl->options.sendVerify = 0;
3229
0
        ssl->options.serverState = NULL_STATE;
3230
0
        ssl->options.clientState = NULL_STATE;
3231
0
        ssl->options.connectState  = CONNECT_BEGIN;
3232
0
        ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
3233
0
        ssl->options.handShakeState = NULL_STATE;
3234
0
        ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
3235
3236
0
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
3237
3238
0
        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
3239
3240
#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SECURE_RENEGOTIATION)
3241
        if (ssl->options.side == WOLFSSL_SERVER_END) {
3242
            ret = SendHelloRequest(ssl);
3243
            if (ret != 0) {
3244
                ssl->error = ret;
3245
                return WOLFSSL_FATAL_ERROR;
3246
            }
3247
        }
3248
#endif /* !NO_WOLFSSL_SERVER && HAVE_SECURE_RENEGOTIATION */
3249
3250
0
        ret = InitHandshakeHashes(ssl);
3251
0
        if (ret != 0) {
3252
0
            ssl->error = ret;
3253
0
            return WOLFSSL_FATAL_ERROR;
3254
0
        }
3255
0
    }
3256
0
    ret = wolfSSL_negotiate(ssl);
3257
0
    if (ret == WOLFSSL_SUCCESS)
3258
0
        ssl->secure_rene_count++;
3259
0
    return ret;
3260
0
}
3261
3262
3263
/* do a secure renegotiation handshake, user forced, we discourage */
3264
int wolfSSL_Rehandshake(WOLFSSL* ssl)
3265
0
{
3266
0
    int ret;
3267
0
    WOLFSSL_ENTER("wolfSSL_Rehandshake");
3268
3269
0
    if (ssl == NULL)
3270
0
        return WOLFSSL_FAILURE;
3271
3272
#ifdef HAVE_SESSION_TICKET
3273
    ret = WOLFSSL_SUCCESS;
3274
#endif
3275
3276
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
3277
        /* Reset option to send certificate verify. */
3278
0
        ssl->options.sendVerify = 0;
3279
0
    }
3280
0
    else {
3281
        /* Reset resuming flag to do full secure handshake. */
3282
0
        ssl->options.resuming = 0;
3283
        #ifdef HAVE_SESSION_TICKET
3284
            /* Clearing the ticket. */
3285
            ret = wolfSSL_UseSessionTicket(ssl);
3286
        #endif
3287
0
    }
3288
    /* CLIENT/SERVER: Reset peer authentication for full secure handshake. */
3289
0
    ssl->options.peerAuthGood = 0;
3290
3291
#ifdef HAVE_SESSION_TICKET
3292
    if (ret == WOLFSSL_SUCCESS)
3293
#endif
3294
0
        ret = _Rehandshake(ssl);
3295
3296
0
    return ret;
3297
0
}
3298
3299
3300
#ifndef NO_WOLFSSL_CLIENT
3301
3302
/* do a secure resumption handshake, user forced, we discourage */
3303
int wolfSSL_SecureResume(WOLFSSL* ssl)
3304
0
{
3305
0
    WOLFSSL_ENTER("wolfSSL_SecureResume");
3306
3307
0
    if (ssl == NULL)
3308
0
        return BAD_FUNC_ARG;
3309
3310
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
3311
0
        ssl->error = SIDE_ERROR;
3312
0
        return WOLFSSL_FATAL_ERROR;
3313
0
    }
3314
3315
0
    return _Rehandshake(ssl);
3316
0
}
3317
3318
#endif /* NO_WOLFSSL_CLIENT */
3319
3320
long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
3321
0
{
3322
0
    WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
3323
3324
0
    if (!ssl || !ssl->secure_renegotiation)
3325
0
        return WOLFSSL_FAILURE;
3326
0
    return ssl->secure_renegotiation->enabled;
3327
0
}
3328
3329
#endif /* HAVE_SECURE_RENEGOTIATION_INFO */
3330
3331
#if defined(HAVE_SESSION_TICKET)
3332
/* Session Ticket */
3333
3334
#if !defined(NO_WOLFSSL_SERVER)
3335
int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
3336
{
3337
    if (ctx == NULL)
3338
        return BAD_FUNC_ARG;
3339
3340
    ctx->noTicketTls12 = 1;
3341
3342
    return WOLFSSL_SUCCESS;
3343
}
3344
3345
int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
3346
{
3347
    if (ssl == NULL)
3348
        return BAD_FUNC_ARG;
3349
3350
    ssl->options.noTicketTls12 = 1;
3351
3352
    return WOLFSSL_SUCCESS;
3353
}
3354
3355
/* WOLFSSL_SUCCESS on ok */
3356
int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
3357
{
3358
    if (ctx == NULL)
3359
        return BAD_FUNC_ARG;
3360
3361
    ctx->ticketEncCb = cb;
3362
3363
    return WOLFSSL_SUCCESS;
3364
}
3365
3366
/* set hint interval, WOLFSSL_SUCCESS on ok */
3367
int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
3368
{
3369
    if (ctx == NULL)
3370
        return BAD_FUNC_ARG;
3371
3372
    ctx->ticketHint = hint;
3373
3374
    return WOLFSSL_SUCCESS;
3375
}
3376
3377
/* set user context, WOLFSSL_SUCCESS on ok */
3378
int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
3379
{
3380
    if (ctx == NULL)
3381
        return BAD_FUNC_ARG;
3382
3383
    ctx->ticketEncCtx = userCtx;
3384
3385
    return WOLFSSL_SUCCESS;
3386
}
3387
3388
/* get user context - returns userCtx on success, NULL on failure */
3389
void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
3390
{
3391
    if (ctx == NULL)
3392
        return NULL;
3393
3394
    return ctx->ticketEncCtx;
3395
}
3396
3397
#ifdef WOLFSSL_TLS13
3398
/* set the maximum number of tickets to send
3399
 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
3400
 */
3401
int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
3402
{
3403
    if (ctx == NULL)
3404
        return WOLFSSL_FAILURE;
3405
3406
    ctx->maxTicketTls13 = (unsigned int)mxTickets;
3407
    return WOLFSSL_SUCCESS;
3408
}
3409
3410
/* get the maximum number of tickets to send
3411
 * return number of tickets set to be sent
3412
 */
3413
size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
3414
{
3415
    if (ctx == NULL)
3416
        return 0;
3417
3418
    return (size_t)ctx->maxTicketTls13;
3419
}
3420
#endif /* WOLFSSL_TLS13 */
3421
#endif /* !NO_WOLFSSL_SERVER */
3422
3423
#if !defined(NO_WOLFSSL_CLIENT)
3424
int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
3425
{
3426
    if (ssl == NULL)
3427
        return BAD_FUNC_ARG;
3428
3429
    return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
3430
}
3431
3432
int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
3433
{
3434
    if (ctx == NULL)
3435
        return BAD_FUNC_ARG;
3436
3437
    return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
3438
}
3439
3440
WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
3441
                                          byte* buf, word32* bufSz)
3442
{
3443
    if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
3444
        return BAD_FUNC_ARG;
3445
3446
    if (ssl->session->ticketLen <= *bufSz) {
3447
        XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen);
3448
        *bufSz = ssl->session->ticketLen;
3449
    }
3450
    else
3451
        *bufSz = 0;
3452
3453
    return WOLFSSL_SUCCESS;
3454
}
3455
3456
WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
3457
                                          word32 bufSz)
3458
{
3459
    if (ssl == NULL || (buf == NULL && bufSz > 0))
3460
        return BAD_FUNC_ARG;
3461
3462
    if (bufSz > 0) {
3463
        /* Ticket will fit into static ticket */
3464
        if (bufSz <= SESSION_TICKET_LEN) {
3465
            if (ssl->session->ticketLenAlloc > 0) {
3466
                XFREE(ssl->session->ticket, ssl->session->heap,
3467
                      DYNAMIC_TYPE_SESSION_TICK);
3468
                ssl->session->ticketLenAlloc = 0;
3469
                ssl->session->ticket = ssl->session->staticTicket;
3470
            }
3471
        }
3472
        else { /* Ticket requires dynamic ticket storage */
3473
            if (ssl->session->ticketLen < bufSz) { /* is dyn buffer big enough */
3474
                if (ssl->session->ticketLenAlloc > 0) {
3475
                    XFREE(ssl->session->ticket, ssl->session->heap,
3476
                          DYNAMIC_TYPE_SESSION_TICK);
3477
                }
3478
                ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
3479
                        DYNAMIC_TYPE_SESSION_TICK);
3480
                if(ssl->session->ticket == NULL) {
3481
                    ssl->session->ticket = ssl->session->staticTicket;
3482
                    ssl->session->ticketLenAlloc = 0;
3483
                    return MEMORY_ERROR;
3484
                }
3485
                ssl->session->ticketLenAlloc = (word16)bufSz;
3486
            }
3487
        }
3488
        XMEMCPY(ssl->session->ticket, buf, bufSz);
3489
    }
3490
    ssl->session->ticketLen = (word16)bufSz;
3491
3492
    return WOLFSSL_SUCCESS;
3493
}
3494
3495
3496
WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
3497
                                            CallbackSessionTicket cb, void* ctx)
3498
{
3499
    if (ssl == NULL)
3500
        return BAD_FUNC_ARG;
3501
3502
    ssl->session_ticket_cb = cb;
3503
    ssl->session_ticket_ctx = ctx;
3504
3505
    return WOLFSSL_SUCCESS;
3506
}
3507
#endif /* !NO_WOLFSSL_CLIENT */
3508
3509
#endif /* HAVE_SESSION_TICKET */
3510
3511
3512
#ifdef HAVE_EXTENDED_MASTER
3513
#ifndef NO_WOLFSSL_CLIENT
3514
3515
int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
3516
0
{
3517
0
    if (ctx == NULL)
3518
0
        return BAD_FUNC_ARG;
3519
3520
0
    ctx->haveEMS = 0;
3521
3522
0
    return WOLFSSL_SUCCESS;
3523
0
}
3524
3525
3526
int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
3527
0
{
3528
0
    if (ssl == NULL)
3529
0
        return BAD_FUNC_ARG;
3530
3531
0
    ssl->options.haveEMS = 0;
3532
3533
0
    return WOLFSSL_SUCCESS;
3534
0
}
3535
3536
#endif
3537
#endif
3538
3539
3540
#ifndef WOLFSSL_LEANPSK
3541
3542
int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
3543
0
{
3544
0
    int ret;
3545
0
    int oldFlags;
3546
3547
0
    WOLFSSL_ENTER("wolfSSL_send()");
3548
3549
0
    if (ssl == NULL || data == NULL || sz < 0)
3550
0
        return BAD_FUNC_ARG;
3551
3552
0
    oldFlags = ssl->wflags;
3553
3554
0
    ssl->wflags = flags;
3555
0
    ret = wolfSSL_write(ssl, data, sz);
3556
0
    ssl->wflags = oldFlags;
3557
3558
0
    WOLFSSL_LEAVE("wolfSSL_send()", ret);
3559
3560
0
    return ret;
3561
0
}
3562
3563
3564
int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
3565
0
{
3566
0
    int ret;
3567
0
    int oldFlags;
3568
3569
0
    WOLFSSL_ENTER("wolfSSL_recv()");
3570
3571
0
    if (ssl == NULL || data == NULL || sz < 0)
3572
0
        return BAD_FUNC_ARG;
3573
3574
0
    oldFlags = ssl->rflags;
3575
3576
0
    ssl->rflags = flags;
3577
0
    ret = wolfSSL_read(ssl, data, sz);
3578
0
    ssl->rflags = oldFlags;
3579
3580
0
    WOLFSSL_LEAVE("wolfSSL_recv()", ret);
3581
3582
0
    return ret;
3583
0
}
3584
#endif
3585
3586
3587
/* WOLFSSL_SUCCESS on ok */
3588
WOLFSSL_ABI
3589
int wolfSSL_shutdown(WOLFSSL* ssl)
3590
0
{
3591
0
    int  ret = WOLFSSL_FATAL_ERROR;
3592
0
    WOLFSSL_ENTER("SSL_shutdown()");
3593
3594
0
    if (ssl == NULL)
3595
0
        return WOLFSSL_FATAL_ERROR;
3596
3597
0
    if (ssl->options.quietShutdown) {
3598
0
        WOLFSSL_MSG("quiet shutdown, no close notify sent");
3599
0
        ret = WOLFSSL_SUCCESS;
3600
0
    }
3601
0
    else {
3602
        /* try to send close notify, not an error if can't */
3603
0
        if (!ssl->options.isClosed && !ssl->options.connReset &&
3604
0
                                      !ssl->options.sentNotify) {
3605
0
            ssl->error = SendAlert(ssl, alert_warning, close_notify);
3606
0
            if (ssl->error < 0) {
3607
0
                WOLFSSL_ERROR(ssl->error);
3608
0
                return WOLFSSL_FATAL_ERROR;
3609
0
            }
3610
0
            ssl->options.sentNotify = 1;  /* don't send close_notify twice */
3611
0
            if (ssl->options.closeNotify)
3612
0
                ret = WOLFSSL_SUCCESS;
3613
0
            else {
3614
0
                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
3615
0
                WOLFSSL_LEAVE("SSL_shutdown()", ret);
3616
0
                return ret;
3617
0
            }
3618
0
        }
3619
3620
#ifdef WOLFSSL_SHUTDOWNONCE
3621
        if (ssl->options.isClosed || ssl->options.connReset) {
3622
            /* Shutdown has already occurred.
3623
             * Caller is free to ignore this error. */
3624
            return SSL_SHUTDOWN_ALREADY_DONE_E;
3625
        }
3626
#endif
3627
3628
        /* call wolfSSL_shutdown again for bidirectional shutdown */
3629
0
        if (ssl->options.sentNotify && !ssl->options.closeNotify) {
3630
0
            ret = ProcessReply(ssl);
3631
0
            if (ret == ZERO_RETURN) {
3632
                /* simulate OpenSSL behavior */
3633
0
                ssl->error = WOLFSSL_ERROR_SYSCALL;
3634
0
                ret = WOLFSSL_SUCCESS;
3635
0
            } else if (ssl->error == WOLFSSL_ERROR_NONE) {
3636
0
                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
3637
0
            } else {
3638
0
                WOLFSSL_ERROR(ssl->error);
3639
0
                ret = WOLFSSL_FATAL_ERROR;
3640
0
            }
3641
0
        }
3642
0
    }
3643
3644
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
3645
    /* reset WOLFSSL structure state for possible re-use */
3646
    if (ret == WOLFSSL_SUCCESS) {
3647
        if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
3648
            WOLFSSL_MSG("could not clear WOLFSSL");
3649
            ret = WOLFSSL_FATAL_ERROR;
3650
        }
3651
    }
3652
#endif
3653
3654
0
    WOLFSSL_LEAVE("SSL_shutdown()", ret);
3655
3656
0
    return ret;
3657
0
}
3658
3659
3660
/* get current error state value */
3661
int wolfSSL_state(WOLFSSL* ssl)
3662
0
{
3663
0
    if (ssl == NULL) {
3664
0
        return BAD_FUNC_ARG;
3665
0
    }
3666
3667
0
    return ssl->error;
3668
0
}
3669
3670
3671
WOLFSSL_ABI
3672
int wolfSSL_get_error(WOLFSSL* ssl, int ret)
3673
0
{
3674
0
    WOLFSSL_ENTER("SSL_get_error");
3675
3676
0
    if (ret > 0)
3677
0
        return WOLFSSL_ERROR_NONE;
3678
0
    if (ssl == NULL)
3679
0
        return BAD_FUNC_ARG;
3680
3681
0
    WOLFSSL_LEAVE("SSL_get_error", ssl->error);
3682
3683
    /* make sure converted types are handled in SetErrorString() too */
3684
0
    if (ssl->error == WANT_READ)
3685
0
        return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
3686
0
    else if (ssl->error == WANT_WRITE)
3687
0
        return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
3688
0
    else if (ssl->error == ZERO_RETURN)
3689
0
        return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
3690
0
    return ssl->error;
3691
0
}
3692
3693
3694
/* retrieve alert history, WOLFSSL_SUCCESS on ok */
3695
int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
3696
0
{
3697
0
    if (ssl && h) {
3698
0
        *h = ssl->alert_history;
3699
0
    }
3700
0
    return WOLFSSL_SUCCESS;
3701
0
}
3702
3703
#ifdef OPENSSL_EXTRA
3704
/* returns SSL_WRITING, SSL_READING or SSL_NOTHING */
3705
int wolfSSL_want(WOLFSSL* ssl)
3706
{
3707
    int rw_state = SSL_NOTHING;
3708
    if (ssl) {
3709
        if (ssl->error == WANT_READ)
3710
            rw_state = SSL_READING;
3711
        else if (ssl->error == WANT_WRITE)
3712
            rw_state = SSL_WRITING;
3713
    }
3714
    return rw_state;
3715
}
3716
#endif
3717
3718
/* return TRUE if current error is want read */
3719
int wolfSSL_want_read(WOLFSSL* ssl)
3720
0
{
3721
0
    WOLFSSL_ENTER("SSL_want_read");
3722
0
    if (ssl->error == WANT_READ)
3723
0
        return 1;
3724
3725
0
    return 0;
3726
0
}
3727
3728
3729
/* return TRUE if current error is want write */
3730
int wolfSSL_want_write(WOLFSSL* ssl)
3731
0
{
3732
0
    WOLFSSL_ENTER("SSL_want_write");
3733
0
    if (ssl->error == WANT_WRITE)
3734
0
        return 1;
3735
3736
0
    return 0;
3737
0
}
3738
3739
3740
char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
3741
0
{
3742
0
    static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
3743
3744
0
    WOLFSSL_ENTER("ERR_error_string");
3745
0
    if (data) {
3746
0
        SetErrorString((int)errNumber, data);
3747
0
        return data;
3748
0
    }
3749
0
    else {
3750
0
        SetErrorString((int)errNumber, tmp);
3751
0
        return tmp;
3752
0
    }
3753
0
}
3754
3755
3756
void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
3757
0
{
3758
0
    WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
3759
0
    if (len >= WOLFSSL_MAX_ERROR_SZ)
3760
0
        wolfSSL_ERR_error_string(e, buf);
3761
0
    else {
3762
0
        char tmp[WOLFSSL_MAX_ERROR_SZ];
3763
3764
0
        WOLFSSL_MSG("Error buffer too short, truncating");
3765
0
        if (len) {
3766
0
            wolfSSL_ERR_error_string(e, tmp);
3767
0
            XMEMCPY(buf, tmp, len-1);
3768
0
            buf[len-1] = '\0';
3769
0
        }
3770
0
    }
3771
0
}
3772
3773
3774
/* don't free temporary arrays at end of handshake */
3775
void wolfSSL_KeepArrays(WOLFSSL* ssl)
3776
0
{
3777
0
    if (ssl)
3778
0
        ssl->options.saveArrays = 1;
3779
0
}
3780
3781
3782
/* user doesn't need temporary arrays anymore, Free */
3783
void wolfSSL_FreeArrays(WOLFSSL* ssl)
3784
0
{
3785
0
    if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
3786
0
        ssl->options.saveArrays = 0;
3787
0
        FreeArrays(ssl, 1);
3788
0
    }
3789
0
}
3790
3791
/* Set option to indicate that the resources are not to be freed after
3792
 * handshake.
3793
 *
3794
 * ssl  The SSL/TLS object.
3795
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3796
 */
3797
int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
3798
0
{
3799
0
    if (ssl == NULL)
3800
0
        return BAD_FUNC_ARG;
3801
3802
0
    ssl->options.keepResources = 1;
3803
3804
0
    return 0;
3805
0
}
3806
3807
/* Free the handshake resources after handshake.
3808
 *
3809
 * ssl  The SSL/TLS object.
3810
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3811
 */
3812
int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
3813
0
{
3814
0
    if (ssl == NULL)
3815
0
        return BAD_FUNC_ARG;
3816
3817
0
    FreeHandshakeResources(ssl);
3818
3819
0
    return 0;
3820
0
}
3821
3822
/* Use the client's order of preference when matching cipher suites.
3823
 *
3824
 * ssl  The SSL/TLS context object.
3825
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3826
 */
3827
int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
3828
0
{
3829
0
    if (ctx == NULL)
3830
0
        return BAD_FUNC_ARG;
3831
3832
0
    ctx->useClientOrder = 1;
3833
3834
0
    return 0;
3835
0
}
3836
3837
/* Use the client's order of preference when matching cipher suites.
3838
 *
3839
 * ssl  The SSL/TLS object.
3840
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3841
 */
3842
int wolfSSL_UseClientSuites(WOLFSSL* ssl)
3843
0
{
3844
0
    if (ssl == NULL)
3845
0
        return BAD_FUNC_ARG;
3846
3847
0
    ssl->options.useClientOrder = 1;
3848
3849
0
    return 0;
3850
0
}
3851
3852
#ifdef WOLFSSL_DTLS
3853
const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder)
3854
{
3855
#ifndef WOLFSSL_AEAD_ONLY
3856
    Keys* keys = NULL;
3857
3858
    (void)epochOrder;
3859
3860
    if (ssl == NULL)
3861
        return NULL;
3862
3863
#ifdef HAVE_SECURE_RENEGOTIATION
3864
    switch (epochOrder) {
3865
    case PEER_ORDER:
3866
        if (IsDtlsMsgSCRKeys(ssl))
3867
            keys = &ssl->secure_renegotiation->tmp_keys;
3868
        else
3869
            keys = &ssl->keys;
3870
        break;
3871
    case PREV_ORDER:
3872
        keys = &ssl->keys;
3873
        break;
3874
    case CUR_ORDER:
3875
        if (DtlsUseSCRKeys(ssl))
3876
            keys = &ssl->secure_renegotiation->tmp_keys;
3877
        else
3878
            keys = &ssl->keys;
3879
        break;
3880
    default:
3881
        WOLFSSL_MSG("Unknown epoch order");
3882
        return NULL;
3883
    }
3884
#else
3885
    keys = &ssl->keys;
3886
#endif
3887
3888
    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
3889
         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
3890
        return keys->client_write_MAC_secret;
3891
    else
3892
        return keys->server_write_MAC_secret;
3893
#else
3894
    (void)ssl;
3895
    (void)verify;
3896
    (void)epochOrder;
3897
3898
    return NULL;
3899
#endif
3900
}
3901
#endif /* WOLFSSL_DTLS */
3902
3903
const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
3904
0
{
3905
0
#ifndef WOLFSSL_AEAD_ONLY
3906
0
    if (ssl == NULL)
3907
0
        return NULL;
3908
3909
0
    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
3910
0
         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
3911
0
        return ssl->keys.client_write_MAC_secret;
3912
0
    else
3913
0
        return ssl->keys.server_write_MAC_secret;
3914
#else
3915
    (void)ssl;
3916
    (void)verify;
3917
3918
    return NULL;
3919
#endif
3920
0
}
3921
3922
int wolfSSL_GetSide(WOLFSSL* ssl)
3923
0
{
3924
0
    if (ssl)
3925
0
        return ssl->options.side;
3926
3927
0
    return BAD_FUNC_ARG;
3928
0
}
3929
3930
#ifdef ATOMIC_USER
3931
3932
void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
3933
{
3934
    if (ctx)
3935
        ctx->MacEncryptCb = cb;
3936
}
3937
3938
3939
void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
3940
{
3941
    if (ssl)
3942
        ssl->MacEncryptCtx = ctx;
3943
}
3944
3945
3946
void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
3947
{
3948
    if (ssl)
3949
        return ssl->MacEncryptCtx;
3950
3951
    return NULL;
3952
}
3953
3954
3955
void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
3956
{
3957
    if (ctx)
3958
        ctx->DecryptVerifyCb = cb;
3959
}
3960
3961
3962
void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
3963
{
3964
    if (ssl)
3965
        ssl->DecryptVerifyCtx = ctx;
3966
}
3967
3968
3969
void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
3970
{
3971
    if (ssl)
3972
        return ssl->DecryptVerifyCtx;
3973
3974
    return NULL;
3975
}
3976
3977
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
3978
/**
3979
 * Set the callback, against the context, that encrypts then MACs.
3980
 *
3981
 * ctx  SSL/TLS context.
3982
 * cb   Callback function to use with Encrypt-Then-MAC.
3983
 */
3984
void  wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
3985
{
3986
    if (ctx)
3987
        ctx->EncryptMacCb = cb;
3988
}
3989
3990
/**
3991
 * Set the context to use with callback that encrypts then MACs.
3992
 *
3993
 * ssl  SSL/TLS object.
3994
 * ctx  Callback function's context.
3995
 */
3996
void  wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
3997
{
3998
    if (ssl)
3999
        ssl->EncryptMacCtx = ctx;
4000
}
4001
4002
/**
4003
 * Get the context being used with callback that encrypts then MACs.
4004
 *
4005
 * ssl  SSL/TLS object.
4006
 * returns callback function's context or NULL if SSL/TLS object is NULL.
4007
 */
4008
void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
4009
{
4010
    if (ssl)
4011
        return ssl->EncryptMacCtx;
4012
4013
    return NULL;
4014
}
4015
4016
4017
/**
4018
 * Set the callback, against the context, that MAC verifies then decrypts.
4019
 *
4020
 * ctx  SSL/TLS context.
4021
 * cb   Callback function to use with Encrypt-Then-MAC.
4022
 */
4023
void  wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
4024
{
4025
    if (ctx)
4026
        ctx->VerifyDecryptCb = cb;
4027
}
4028
4029
/**
4030
 * Set the context to use with callback that MAC verifies then decrypts.
4031
 *
4032
 * ssl  SSL/TLS object.
4033
 * ctx  Callback function's context.
4034
 */
4035
void  wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
4036
{
4037
    if (ssl)
4038
        ssl->VerifyDecryptCtx = ctx;
4039
}
4040
4041
/**
4042
 * Get the context being used with callback that MAC verifies then decrypts.
4043
 *
4044
 * ssl  SSL/TLS object.
4045
 * returns callback function's context or NULL if SSL/TLS object is NULL.
4046
 */
4047
void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
4048
{
4049
    if (ssl)
4050
        return ssl->VerifyDecryptCtx;
4051
4052
    return NULL;
4053
}
4054
#endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
4055
4056
4057
4058
const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
4059
{
4060
    if (ssl)
4061
        return ssl->keys.client_write_key;
4062
4063
    return NULL;
4064
}
4065
4066
4067
const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
4068
{
4069
    if (ssl)
4070
        return ssl->keys.client_write_IV;
4071
4072
    return NULL;
4073
}
4074
4075
4076
const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
4077
{
4078
    if (ssl)
4079
        return ssl->keys.server_write_key;
4080
4081
    return NULL;
4082
}
4083
4084
4085
const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
4086
{
4087
    if (ssl)
4088
        return ssl->keys.server_write_IV;
4089
4090
    return NULL;
4091
}
4092
4093
int wolfSSL_GetKeySize(WOLFSSL* ssl)
4094
{
4095
    if (ssl)
4096
        return ssl->specs.key_size;
4097
4098
    return BAD_FUNC_ARG;
4099
}
4100
4101
4102
int wolfSSL_GetIVSize(WOLFSSL* ssl)
4103
{
4104
    if (ssl)
4105
        return ssl->specs.iv_size;
4106
4107
    return BAD_FUNC_ARG;
4108
}
4109
4110
4111
int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
4112
{
4113
    if (ssl)
4114
        return ssl->specs.bulk_cipher_algorithm;
4115
4116
    return BAD_FUNC_ARG;
4117
}
4118
4119
4120
int wolfSSL_GetCipherType(WOLFSSL* ssl)
4121
{
4122
    if (ssl == NULL)
4123
        return BAD_FUNC_ARG;
4124
4125
#ifndef WOLFSSL_AEAD_ONLY
4126
    if (ssl->specs.cipher_type == block)
4127
        return WOLFSSL_BLOCK_TYPE;
4128
    if (ssl->specs.cipher_type == stream)
4129
        return WOLFSSL_STREAM_TYPE;
4130
#endif
4131
    if (ssl->specs.cipher_type == aead)
4132
        return WOLFSSL_AEAD_TYPE;
4133
4134
    return -1;
4135
}
4136
4137
4138
int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
4139
{
4140
    if (ssl == NULL)
4141
        return BAD_FUNC_ARG;
4142
4143
    return ssl->specs.block_size;
4144
}
4145
4146
4147
int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
4148
{
4149
    if (ssl == NULL)
4150
        return BAD_FUNC_ARG;
4151
4152
    return ssl->specs.aead_mac_size;
4153
}
4154
4155
4156
int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
4157
{
4158
    if (ssl == NULL)
4159
        return BAD_FUNC_ARG;
4160
4161
    if (ssl->options.tls1_1)
4162
        return 1;
4163
4164
    return 0;
4165
}
4166
4167
4168
4169
int wolfSSL_GetHmacSize(WOLFSSL* ssl)
4170
{
4171
    /* AEAD ciphers don't have HMAC keys */
4172
    if (ssl)
4173
        return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
4174
4175
    return BAD_FUNC_ARG;
4176
}
4177
4178
#ifdef WORD64_AVAILABLE
4179
int wolfSSL_GetPeerSequenceNumber(WOLFSSL* ssl, word64 *seq)
4180
{
4181
    if ((ssl == NULL) || (seq == NULL))
4182
        return BAD_FUNC_ARG;
4183
4184
    *seq = ((word64)ssl->keys.peer_sequence_number_hi << 32) |
4185
                    ssl->keys.peer_sequence_number_lo;
4186
    return !(*seq);
4187
}
4188
4189
int wolfSSL_GetSequenceNumber(WOLFSSL* ssl, word64 *seq)
4190
{
4191
    if ((ssl == NULL) || (seq == NULL))
4192
        return BAD_FUNC_ARG;
4193
4194
    *seq = ((word64)ssl->keys.sequence_number_hi << 32) |
4195
                    ssl->keys.sequence_number_lo;
4196
    return !(*seq);
4197
}
4198
#endif
4199
4200
#endif /* ATOMIC_USER */
4201
4202
#ifndef NO_CERTS
4203
4204
WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
4205
0
{
4206
0
    WOLFSSL_CERT_MANAGER* cm = NULL;
4207
0
    if (ctx)
4208
0
        cm = ctx->cm;
4209
0
    return cm;
4210
0
}
4211
4212
WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
4213
0
{
4214
0
    WOLFSSL_CERT_MANAGER* cm;
4215
4216
0
    WOLFSSL_ENTER("wolfSSL_CertManagerNew");
4217
4218
0
    cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap,
4219
0
                                         DYNAMIC_TYPE_CERT_MANAGER);
4220
0
    if (cm) {
4221
0
        XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
4222
0
        cm->refCount = 1;
4223
4224
0
        if (wc_InitMutex(&cm->caLock) != 0) {
4225
0
            WOLFSSL_MSG("Bad mutex init");
4226
0
            wolfSSL_CertManagerFree(cm);
4227
0
            return NULL;
4228
0
        }
4229
0
        #ifndef SINGLE_THREADED
4230
0
        if (wc_InitMutex(&cm->refMutex) != 0) {
4231
0
            WOLFSSL_MSG("Bad mutex init");
4232
0
            wolfSSL_CertManagerFree(cm);
4233
0
            return NULL;
4234
0
        }
4235
0
        #endif
4236
4237
        #ifdef WOLFSSL_TRUST_PEER_CERT
4238
        if (wc_InitMutex(&cm->tpLock) != 0) {
4239
            WOLFSSL_MSG("Bad mutex init");
4240
            wolfSSL_CertManagerFree(cm);
4241
            return NULL;
4242
        }
4243
        #endif
4244
4245
        /* set default minimum key size allowed */
4246
0
        #ifndef NO_RSA
4247
0
            cm->minRsaKeySz = MIN_RSAKEY_SZ;
4248
0
        #endif
4249
0
        #ifdef HAVE_ECC
4250
0
            cm->minEccKeySz = MIN_ECCKEY_SZ;
4251
0
        #endif
4252
        #ifdef HAVE_PQC
4253
        #ifdef HAVE_FALCON
4254
            cm->minFalconKeySz = MIN_FALCONKEY_SZ;
4255
        #endif /* HAVE_FALCON */
4256
        #ifdef HAVE_DILITHIUM
4257
            cm->minDilithiumKeySz = MIN_DILITHIUMKEY_SZ;
4258
        #endif /* HAVE_DILITHIUM */
4259
        #endif /* HAVE_PQC */
4260
4261
0
            cm->heap = heap;
4262
0
    }
4263
4264
0
    return cm;
4265
0
}
4266
4267
4268
WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
4269
0
{
4270
0
    return wolfSSL_CertManagerNew_ex(NULL);
4271
0
}
4272
4273
4274
void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
4275
0
{
4276
0
    int doFree = 0;
4277
0
    WOLFSSL_ENTER("wolfSSL_CertManagerFree");
4278
4279
0
    if (cm) {
4280
0
        #ifndef SINGLE_THREADED
4281
0
        if (wc_LockMutex(&cm->refMutex) != 0) {
4282
0
            WOLFSSL_MSG("Couldn't lock cm mutex");
4283
0
        }
4284
0
        #endif
4285
0
        cm->refCount--;
4286
0
        if (cm->refCount == 0)
4287
0
            doFree = 1;
4288
0
        #ifndef SINGLE_THREADED
4289
0
        wc_UnLockMutex(&cm->refMutex);
4290
0
        #endif
4291
0
        if (doFree) {
4292
            #ifdef HAVE_CRL
4293
                if (cm->crl)
4294
                    FreeCRL(cm->crl, 1);
4295
            #endif
4296
            #ifdef HAVE_OCSP
4297
                if (cm->ocsp)
4298
                    FreeOCSP(cm->ocsp, 1);
4299
                XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
4300
            #if !defined(NO_WOLFSSL_SERVER) && \
4301
                (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
4302
                 defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
4303
                if (cm->ocsp_stapling)
4304
                    FreeOCSP(cm->ocsp_stapling, 1);
4305
            #endif
4306
            #endif
4307
0
            FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
4308
0
            wc_FreeMutex(&cm->caLock);
4309
4310
            #ifdef WOLFSSL_TRUST_PEER_CERT
4311
            FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
4312
            wc_FreeMutex(&cm->tpLock);
4313
            #endif
4314
0
            #ifndef SINGLE_THREADED
4315
0
            if (wc_FreeMutex(&cm->refMutex) != 0) {
4316
0
                WOLFSSL_MSG("Couldn't free refMutex mutex");
4317
0
            }
4318
0
            #endif
4319
0
            XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
4320
0
        }
4321
0
    }
4322
4323
0
}
4324
4325
int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm)
4326
0
{
4327
0
    if (cm) {
4328
0
#ifndef SINGLE_THREADED
4329
0
        if (wc_LockMutex(&cm->refMutex) != 0) {
4330
0
            WOLFSSL_MSG("Failed to lock cm mutex");
4331
0
            return WOLFSSL_FAILURE;
4332
0
        }
4333
0
#endif
4334
0
        cm->refCount++;
4335
0
#ifndef SINGLE_THREADED
4336
0
        wc_UnLockMutex(&cm->refMutex);
4337
0
#endif
4338
4339
0
        return WOLFSSL_SUCCESS;
4340
0
    }
4341
4342
0
    return WOLFSSL_FAILURE;
4343
0
}
4344
4345
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
4346
#if defined(WOLFSSL_SIGNER_DER_CERT)
4347
/******************************************************************************
4348
* wolfSSL_CertManagerGetCerts - retrieve stack of X509 certificates in a
4349
* certificate manager (CM).
4350
*
4351
* RETURNS:
4352
* returns stack of X509 certs on success, otherwise returns a NULL.
4353
*/
4354
WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm)
4355
{
4356
    WOLFSSL_STACK* sk = NULL;
4357
    int numCerts = 0;
4358
    DerBuffer** certBuffers = NULL;
4359
    const byte* derBuffer = NULL;
4360
    Signer* signers = NULL;
4361
    word32  row = 0;
4362
    WOLFSSL_X509* x509 = NULL;
4363
    int i = 0;
4364
    int ret = 0;
4365
4366
    if (cm == NULL)
4367
        return NULL;
4368
4369
    sk = wolfSSL_sk_X509_new_null();
4370
    if (sk == NULL)
4371
        goto error;
4372
4373
    if (wc_LockMutex(&cm->caLock) != 0)
4374
        goto error;
4375
4376
    /* Iterate once to get the number of certs, for memory allocation
4377
       purposes. */
4378
    for (row = 0; row < CA_TABLE_SIZE; row++) {
4379
        signers = cm->caTable[row];
4380
        while (signers && signers->derCert && signers->derCert->buffer) {
4381
            ++numCerts;
4382
            signers = signers->next;
4383
        }
4384
    }
4385
4386
    if (numCerts == 0) {
4387
        wc_UnLockMutex(&cm->caLock);
4388
        goto error;
4389
    }
4390
4391
    certBuffers = (DerBuffer**)XMALLOC(sizeof(DerBuffer*) * numCerts, cm->heap,
4392
                                       DYNAMIC_TYPE_TMP_BUFFER);
4393
    if (certBuffers == NULL) {
4394
        wc_UnLockMutex(&cm->caLock);
4395
        goto error;
4396
    }
4397
    XMEMSET(certBuffers, 0, sizeof(DerBuffer*) * numCerts);
4398
4399
    /* Copy the certs locally so that we can release the caLock. If the lock is
4400
       held when wolfSSL_d2i_X509 is called, GetCA will also try to get the
4401
       lock, leading to deadlock. */
4402
    for (row = 0; row < CA_TABLE_SIZE; row++) {
4403
        signers = cm->caTable[row];
4404
        while (signers && signers->derCert && signers->derCert->buffer) {
4405
            ret = AllocDer(&certBuffers[i], signers->derCert->length, CA_TYPE,
4406
                           cm->heap);
4407
            if (ret < 0) {
4408
                wc_UnLockMutex(&cm->caLock);
4409
                goto error;
4410
            }
4411
4412
            XMEMCPY(certBuffers[i]->buffer, signers->derCert->buffer,
4413
                    signers->derCert->length);
4414
            certBuffers[i]->length = signers->derCert->length;
4415
4416
            ++i;
4417
            signers = signers->next;
4418
        }
4419
    }
4420
4421
    wc_UnLockMutex(&cm->caLock);
4422
4423
    for (i = 0; i < numCerts; ++i) {
4424
        derBuffer = certBuffers[i]->buffer;
4425
        wolfSSL_d2i_X509(&x509, &derBuffer, certBuffers[i]->length);
4426
        if (x509 == NULL)
4427
            goto error;
4428
4429
        if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS)
4430
            goto error;
4431
    }
4432
4433
    for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
4434
        FreeDer(&certBuffers[i]);
4435
    }
4436
4437
    XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4438
4439
    return sk;
4440
4441
error:
4442
    if (sk)
4443
        wolfSSL_sk_X509_pop_free(sk, NULL);
4444
4445
    if (certBuffers != NULL) {
4446
        for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
4447
            FreeDer(&certBuffers[i]);
4448
        }
4449
    }
4450
4451
    if (certBuffers)
4452
        XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4453
4454
    return NULL;
4455
}
4456
4457
#endif /* WOLFSSL_SIGNER_DER_CERT */
4458
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
4459
4460
/* Unload the CA signer list */
4461
int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
4462
0
{
4463
0
    WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
4464
4465
0
    if (cm == NULL)
4466
0
        return BAD_FUNC_ARG;
4467
4468
0
    if (wc_LockMutex(&cm->caLock) != 0)
4469
0
        return BAD_MUTEX_E;
4470
4471
0
    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
4472
4473
0
    wc_UnLockMutex(&cm->caLock);
4474
4475
4476
0
    return WOLFSSL_SUCCESS;
4477
0
}
4478
4479
4480
#ifdef WOLFSSL_TRUST_PEER_CERT
4481
int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
4482
{
4483
    WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
4484
4485
    if (cm == NULL)
4486
        return BAD_FUNC_ARG;
4487
4488
    if (wc_LockMutex(&cm->tpLock) != 0)
4489
        return BAD_MUTEX_E;
4490
4491
    FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
4492
4493
    wc_UnLockMutex(&cm->tpLock);
4494
4495
4496
    return WOLFSSL_SUCCESS;
4497
}
4498
#endif /* WOLFSSL_TRUST_PEER_CERT */
4499
4500
#endif /* NO_CERTS */
4501
4502
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
4503
4504
void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
4505
0
{
4506
0
    char data[WOLFSSL_MAX_ERROR_SZ + 1];
4507
4508
0
    WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
4509
0
    SetErrorString(err, data);
4510
0
    if (XFPRINTF(fp, "%s", data) < 0)
4511
0
        WOLFSSL_MSG("fprintf failed in wolfSSL_ERR_print_errors_fp");
4512
0
}
4513
4514
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
4515
void wolfSSL_ERR_dump_errors_fp(XFILE fp)
4516
{
4517
    wc_ERR_print_errors_fp(fp);
4518
}
4519
4520
void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
4521
                                            void *u), void *u)
4522
{
4523
    wc_ERR_print_errors_cb(cb, u);
4524
}
4525
#endif
4526
#endif
4527
4528
/*
4529
 * TODO This ssl parameter needs to be changed to const once our ABI checker
4530
 *      stops flagging qualifier additions as ABI breaking.
4531
 */
4532
WOLFSSL_ABI
4533
int wolfSSL_pending(WOLFSSL* ssl)
4534
0
{
4535
0
    WOLFSSL_ENTER("SSL_pending");
4536
0
    if (ssl == NULL)
4537
0
        return WOLFSSL_FAILURE;
4538
4539
0
    return ssl->buffers.clearOutputBuffer.length;
4540
0
}
4541
4542
int wolfSSL_has_pending(const WOLFSSL* ssl)
4543
0
{
4544
0
    WOLFSSL_ENTER("wolfSSL_has_pending");
4545
0
    if (ssl == NULL)
4546
0
        return WOLFSSL_FAILURE;
4547
4548
0
    return ssl->buffers.clearOutputBuffer.length > 0;
4549
0
}
4550
4551
#ifndef WOLFSSL_LEANPSK
4552
/* turn on handshake group messages for context */
4553
int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
4554
0
{
4555
0
    if (ctx == NULL)
4556
0
       return BAD_FUNC_ARG;
4557
4558
0
    ctx->groupMessages = 1;
4559
4560
0
    return WOLFSSL_SUCCESS;
4561
0
}
4562
#endif
4563
4564
4565
#ifndef NO_WOLFSSL_CLIENT
4566
/* connect enough to get peer cert chain */
4567
int wolfSSL_connect_cert(WOLFSSL* ssl)
4568
0
{
4569
0
    int  ret;
4570
4571
0
    if (ssl == NULL)
4572
0
        return WOLFSSL_FAILURE;
4573
4574
0
    ssl->options.certOnly = 1;
4575
0
    ret = wolfSSL_connect(ssl);
4576
0
    ssl->options.certOnly   = 0;
4577
4578
0
    return ret;
4579
0
}
4580
#endif
4581
4582
4583
#ifndef WOLFSSL_LEANPSK
4584
/* turn on handshake group messages for ssl object */
4585
int wolfSSL_set_group_messages(WOLFSSL* ssl)
4586
0
{
4587
0
    if (ssl == NULL)
4588
0
       return BAD_FUNC_ARG;
4589
4590
0
    ssl->options.groupMessages = 1;
4591
4592
0
    return WOLFSSL_SUCCESS;
4593
0
}
4594
4595
4596
/* make minVersion the internal equivalent SSL version */
4597
static int SetMinVersionHelper(byte* minVersion, int version)
4598
0
{
4599
#ifdef NO_TLS
4600
    (void)minVersion;
4601
#endif
4602
4603
0
    switch (version) {
4604
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4605
        case WOLFSSL_SSLV3:
4606
            *minVersion = SSLv3_MINOR;
4607
            break;
4608
#endif
4609
4610
0
#ifndef NO_TLS
4611
0
    #ifndef NO_OLD_TLS
4612
        #ifdef WOLFSSL_ALLOW_TLSV10
4613
        case WOLFSSL_TLSV1:
4614
            *minVersion = TLSv1_MINOR;
4615
            break;
4616
        #endif
4617
4618
0
        case WOLFSSL_TLSV1_1:
4619
0
            *minVersion = TLSv1_1_MINOR;
4620
0
            break;
4621
0
    #endif
4622
0
    #ifndef WOLFSSL_NO_TLS12
4623
0
        case WOLFSSL_TLSV1_2:
4624
0
            *minVersion = TLSv1_2_MINOR;
4625
0
            break;
4626
0
    #endif
4627
0
#endif
4628
0
    #ifdef WOLFSSL_TLS13
4629
0
        case WOLFSSL_TLSV1_3:
4630
0
            *minVersion = TLSv1_3_MINOR;
4631
0
            break;
4632
0
    #endif
4633
4634
#ifdef WOLFSSL_DTLS
4635
        case WOLFSSL_DTLSV1:
4636
            *minVersion = DTLS_MINOR;
4637
            break;
4638
        case WOLFSSL_DTLSV1_2:
4639
            *minVersion = DTLSv1_2_MINOR;
4640
            break;
4641
#ifdef WOLFSSL_DTLS13
4642
        case WOLFSSL_DTLSV1_3:
4643
            *minVersion = DTLSv1_3_MINOR;
4644
            break;
4645
#endif /* WOLFSSL_DTLS13 */
4646
#endif /* WOLFSSL_DTLS */
4647
4648
0
        default:
4649
0
            WOLFSSL_MSG("Bad function argument");
4650
0
            return BAD_FUNC_ARG;
4651
0
    }
4652
4653
0
    return WOLFSSL_SUCCESS;
4654
0
}
4655
4656
4657
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
4658
WOLFSSL_ABI
4659
int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
4660
0
{
4661
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
4662
4663
0
    if (ctx == NULL) {
4664
0
        WOLFSSL_MSG("Bad function argument");
4665
0
        return BAD_FUNC_ARG;
4666
0
    }
4667
4668
0
    return SetMinVersionHelper(&ctx->minDowngrade, version);
4669
0
}
4670
4671
4672
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
4673
int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
4674
0
{
4675
0
    WOLFSSL_ENTER("wolfSSL_SetMinVersion");
4676
4677
0
    if (ssl == NULL) {
4678
0
        WOLFSSL_MSG("Bad function argument");
4679
0
        return BAD_FUNC_ARG;
4680
0
    }
4681
4682
0
    return SetMinVersionHelper(&ssl->options.minDowngrade, version);
4683
0
}
4684
4685
4686
/* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
4687
int wolfSSL_GetVersion(const WOLFSSL* ssl)
4688
0
{
4689
0
    if (ssl == NULL)
4690
0
        return BAD_FUNC_ARG;
4691
4692
0
    if (ssl->version.major == SSLv3_MAJOR) {
4693
0
        switch (ssl->version.minor) {
4694
0
            case SSLv3_MINOR :
4695
0
                return WOLFSSL_SSLV3;
4696
0
            case TLSv1_MINOR :
4697
0
                return WOLFSSL_TLSV1;
4698
0
            case TLSv1_1_MINOR :
4699
0
                return WOLFSSL_TLSV1_1;
4700
0
            case TLSv1_2_MINOR :
4701
0
                return WOLFSSL_TLSV1_2;
4702
0
            case TLSv1_3_MINOR :
4703
0
                return WOLFSSL_TLSV1_3;
4704
0
            default:
4705
0
                break;
4706
0
        }
4707
0
    }
4708
4709
0
    return VERSION_ERROR;
4710
0
}
4711
4712
int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
4713
0
{
4714
0
    word16 haveRSA = 1;
4715
0
    word16 havePSK = 0;
4716
0
    int    keySz   = 0;
4717
4718
0
    WOLFSSL_ENTER("wolfSSL_SetVersion");
4719
4720
0
    if (ssl == NULL) {
4721
0
        WOLFSSL_MSG("Bad function argument");
4722
0
        return BAD_FUNC_ARG;
4723
0
    }
4724
4725
0
    switch (version) {
4726
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4727
        case WOLFSSL_SSLV3:
4728
            ssl->version = MakeSSLv3();
4729
            break;
4730
#endif
4731
4732
0
#ifndef NO_TLS
4733
0
    #ifndef NO_OLD_TLS
4734
        #ifdef WOLFSSL_ALLOW_TLSV10
4735
        case WOLFSSL_TLSV1:
4736
            ssl->version = MakeTLSv1();
4737
            break;
4738
        #endif
4739
4740
0
        case WOLFSSL_TLSV1_1:
4741
0
            ssl->version = MakeTLSv1_1();
4742
0
            break;
4743
0
    #endif
4744
0
    #ifndef WOLFSSL_NO_TLS12
4745
0
        case WOLFSSL_TLSV1_2:
4746
0
            ssl->version = MakeTLSv1_2();
4747
0
            break;
4748
0
    #endif
4749
4750
0
    #ifdef WOLFSSL_TLS13
4751
0
        case WOLFSSL_TLSV1_3:
4752
0
            ssl->version = MakeTLSv1_3();
4753
0
            break;
4754
0
    #endif /* WOLFSSL_TLS13 */
4755
0
#endif
4756
4757
0
        default:
4758
0
            WOLFSSL_MSG("Bad function argument");
4759
0
            return BAD_FUNC_ARG;
4760
0
    }
4761
4762
    #ifdef NO_RSA
4763
        haveRSA = 0;
4764
    #endif
4765
    #ifndef NO_PSK
4766
        havePSK = ssl->options.havePSK;
4767
    #endif
4768
0
    #ifndef NO_CERTS
4769
0
        keySz = ssl->buffers.keySz;
4770
0
    #endif
4771
4772
0
    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
4773
0
               ssl->options.haveDH, ssl->options.haveECDSAsig,
4774
0
               ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
4775
0
               ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
4776
0
               ssl->options.haveAnon, TRUE, ssl->options.side);
4777
0
    return WOLFSSL_SUCCESS;
4778
0
}
4779
#endif /* !leanpsk */
4780
4781
#ifndef NO_CERTS
4782
4783
/* hash is the SHA digest of name, just use first 32 bits as hash */
4784
static WC_INLINE word32 HashSigner(const byte* hash)
4785
0
{
4786
0
    return MakeWordFromHash(hash) % CA_TABLE_SIZE;
4787
0
}
4788
4789
4790
/* does CA already exist on signer list */
4791
int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
4792
0
{
4793
0
    Signer* signers;
4794
0
    int     ret = 0;
4795
0
    word32  row;
4796
4797
0
    if (cm == NULL || hash == NULL) {
4798
0
        return ret;
4799
0
    }
4800
4801
0
    row = HashSigner(hash);
4802
4803
0
    if (wc_LockMutex(&cm->caLock) != 0) {
4804
0
        return ret;
4805
0
    }
4806
0
    signers = cm->caTable[row];
4807
0
    while (signers) {
4808
0
        byte* subjectHash;
4809
4810
0
    #ifndef NO_SKID
4811
0
        subjectHash = signers->subjectKeyIdHash;
4812
    #else
4813
        subjectHash = signers->subjectNameHash;
4814
    #endif
4815
4816
0
        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4817
0
            ret = 1; /* success */
4818
0
            break;
4819
0
        }
4820
0
        signers = signers->next;
4821
0
    }
4822
0
    wc_UnLockMutex(&cm->caLock);
4823
4824
0
    return ret;
4825
0
}
4826
4827
4828
#ifdef WOLFSSL_TRUST_PEER_CERT
4829
/* hash is the SHA digest of name, just use first 32 bits as hash */
4830
static WC_INLINE word32 TrustedPeerHashSigner(const byte* hash)
4831
{
4832
    return MakeWordFromHash(hash) % TP_TABLE_SIZE;
4833
}
4834
4835
/* does trusted peer already exist on signer list */
4836
int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DecodedCert* cert)
4837
{
4838
    TrustedPeerCert* tp;
4839
    int     ret = 0;
4840
    word32  row = TrustedPeerHashSigner(cert->subjectHash);
4841
4842
    if (wc_LockMutex(&cm->tpLock) != 0)
4843
        return  ret;
4844
    tp = cm->tpTable[row];
4845
    while (tp) {
4846
        if (XMEMCMP(cert->subjectHash, tp->subjectNameHash,
4847
                SIGNER_DIGEST_SIZE) == 0)
4848
            ret = 1;
4849
    #ifndef NO_SKID
4850
        if (cert->extSubjKeyIdSet) {
4851
            /* Compare SKID as well if available */
4852
            if (ret == 1 && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
4853
                    SIGNER_DIGEST_SIZE) != 0)
4854
                ret = 0;
4855
        }
4856
    #endif
4857
        if (ret == 1)
4858
            break;
4859
        tp = tp->next;
4860
    }
4861
    wc_UnLockMutex(&cm->tpLock);
4862
4863
    return ret;
4864
}
4865
4866
4867
/* return Trusted Peer if found, otherwise NULL
4868
    type is what to match on
4869
 */
4870
TrustedPeerCert* GetTrustedPeer(void* vp, DecodedCert* cert)
4871
{
4872
    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4873
    TrustedPeerCert* ret = NULL;
4874
    TrustedPeerCert* tp  = NULL;
4875
    word32  row;
4876
4877
    if (cm == NULL || cert == NULL)
4878
        return NULL;
4879
4880
    row = TrustedPeerHashSigner(cert->subjectHash);
4881
4882
    if (wc_LockMutex(&cm->tpLock) != 0)
4883
        return ret;
4884
4885
    tp = cm->tpTable[row];
4886
    while (tp) {
4887
        if (XMEMCMP(cert->subjectHash, tp->subjectNameHash,
4888
                SIGNER_DIGEST_SIZE) == 0)
4889
            ret = tp;
4890
    #ifndef NO_SKID
4891
        if (cert->extSubjKeyIdSet) {
4892
            /* Compare SKID as well if available */
4893
            if (ret != NULL && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
4894
                    SIGNER_DIGEST_SIZE) != 0)
4895
                ret = NULL;
4896
        }
4897
    #endif
4898
        if (ret != NULL)
4899
            break;
4900
        tp = tp->next;
4901
    }
4902
    wc_UnLockMutex(&cm->tpLock);
4903
4904
    return ret;
4905
}
4906
4907
4908
int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
4909
{
4910
    if (tp == NULL || cert == NULL)
4911
        return BAD_FUNC_ARG;
4912
4913
    /* subject key id or subject hash has been compared when searching
4914
       tpTable for the cert from function GetTrustedPeer */
4915
4916
    /* compare signatures */
4917
    if (tp->sigLen == cert->sigLength) {
4918
        if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
4919
            return WOLFSSL_FAILURE;
4920
        }
4921
    }
4922
    else {
4923
        return WOLFSSL_FAILURE;
4924
    }
4925
4926
    return WOLFSSL_SUCCESS;
4927
}
4928
#endif /* WOLFSSL_TRUST_PEER_CERT */
4929
4930
4931
/* return CA if found, otherwise NULL */
4932
Signer* GetCA(void* vp, byte* hash)
4933
0
{
4934
0
    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4935
0
    Signer* ret = NULL;
4936
0
    Signer* signers;
4937
0
    word32  row = 0;
4938
4939
0
    if (cm == NULL || hash == NULL)
4940
0
        return NULL;
4941
4942
0
    row = HashSigner(hash);
4943
4944
0
    if (wc_LockMutex(&cm->caLock) != 0)
4945
0
        return ret;
4946
4947
0
    signers = cm->caTable[row];
4948
0
    while (signers) {
4949
0
        byte* subjectHash;
4950
0
        #ifndef NO_SKID
4951
0
            subjectHash = signers->subjectKeyIdHash;
4952
        #else
4953
            subjectHash = signers->subjectNameHash;
4954
        #endif
4955
0
        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4956
0
            ret = signers;
4957
0
            break;
4958
0
        }
4959
0
        signers = signers->next;
4960
0
    }
4961
0
    wc_UnLockMutex(&cm->caLock);
4962
4963
0
    return ret;
4964
0
}
4965
4966
4967
#ifndef NO_SKID
4968
/* return CA if found, otherwise NULL. Walk through hash table. */
4969
Signer* GetCAByName(void* vp, byte* hash)
4970
0
{
4971
0
    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4972
0
    Signer* ret = NULL;
4973
0
    Signer* signers;
4974
0
    word32  row;
4975
4976
0
    if (cm == NULL)
4977
0
        return NULL;
4978
4979
0
    if (wc_LockMutex(&cm->caLock) != 0)
4980
0
        return ret;
4981
4982
0
    for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
4983
0
        signers = cm->caTable[row];
4984
0
        while (signers && ret == NULL) {
4985
0
            if (XMEMCMP(hash, signers->subjectNameHash,
4986
0
                        SIGNER_DIGEST_SIZE) == 0) {
4987
0
                ret = signers;
4988
0
            }
4989
0
            signers = signers->next;
4990
0
        }
4991
0
    }
4992
0
    wc_UnLockMutex(&cm->caLock);
4993
4994
0
    return ret;
4995
0
}
4996
#endif
4997
4998
4999
#ifdef WOLFSSL_TRUST_PEER_CERT
5000
/* add a trusted peer cert to linked list */
5001
int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
5002
{
5003
    int ret, row;
5004
    TrustedPeerCert* peerCert;
5005
    DecodedCert* cert;
5006
    DerBuffer*   der = *pDer;
5007
5008
    WOLFSSL_MSG("Adding a Trusted Peer Cert");
5009
5010
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
5011
                                 DYNAMIC_TYPE_DCERT);
5012
    if (cert == NULL) {
5013
        FreeDer(&der);
5014
        return MEMORY_E;
5015
    }
5016
5017
    InitDecodedCert(cert, der->buffer, der->length, cm->heap);
5018
    if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
5019
        FreeDecodedCert(cert);
5020
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
5021
        FreeDer(&der);
5022
        return ret;
5023
    }
5024
    WOLFSSL_MSG("\tParsed new trusted peer cert");
5025
5026
    peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), cm->heap,
5027
                                                             DYNAMIC_TYPE_CERT);
5028
    if (peerCert == NULL) {
5029
        FreeDecodedCert(cert);
5030
        XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5031
        FreeDer(&der);
5032
        return MEMORY_E;
5033
    }
5034
    XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
5035
5036
    #ifndef IGNORE_NAME_CONSTRAINTS
5037
        if (peerCert->permittedNames)
5038
            FreeNameSubtrees(peerCert->permittedNames, cm->heap);
5039
        if (peerCert->excludedNames)
5040
            FreeNameSubtrees(peerCert->excludedNames, cm->heap);
5041
    #endif
5042
5043
    if (AlreadyTrustedPeer(cm, cert)) {
5044
        WOLFSSL_MSG("\tAlready have this CA, not adding again");
5045
        FreeTrustedPeer(peerCert, cm->heap);
5046
        (void)ret;
5047
    }
5048
    else {
5049
        /* add trusted peer signature */
5050
        peerCert->sigLen = cert->sigLength;
5051
        peerCert->sig = (byte *)XMALLOC(cert->sigLength, cm->heap,
5052
                                                        DYNAMIC_TYPE_SIGNATURE);
5053
        if (peerCert->sig == NULL) {
5054
            FreeDecodedCert(cert);
5055
            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5056
            FreeTrustedPeer(peerCert, cm->heap);
5057
            FreeDer(&der);
5058
            return MEMORY_E;
5059
        }
5060
        XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
5061
5062
        /* add trusted peer name */
5063
        peerCert->nameLen = cert->subjectCNLen;
5064
        peerCert->name    = cert->subjectCN;
5065
        #ifndef IGNORE_NAME_CONSTRAINTS
5066
            peerCert->permittedNames = cert->permittedNames;
5067
            peerCert->excludedNames  = cert->excludedNames;
5068
        #endif
5069
5070
        /* add SKID when available and hash of name */
5071
        #ifndef NO_SKID
5072
            XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
5073
                    SIGNER_DIGEST_SIZE);
5074
        #endif
5075
            XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
5076
                    SIGNER_DIGEST_SIZE);
5077
            peerCert->next    = NULL; /* If Key Usage not set, all uses valid. */
5078
            cert->subjectCN = 0;
5079
        #ifndef IGNORE_NAME_CONSTRAINTS
5080
            cert->permittedNames = NULL;
5081
            cert->excludedNames = NULL;
5082
        #endif
5083
5084
            row = TrustedPeerHashSigner(peerCert->subjectNameHash);
5085
5086
            if (wc_LockMutex(&cm->tpLock) == 0) {
5087
                peerCert->next = cm->tpTable[row];
5088
                cm->tpTable[row] = peerCert;   /* takes ownership */
5089
                wc_UnLockMutex(&cm->tpLock);
5090
            }
5091
            else {
5092
                WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
5093
                FreeDecodedCert(cert);
5094
                XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5095
                FreeTrustedPeer(peerCert, cm->heap);
5096
                FreeDer(&der);
5097
                return BAD_MUTEX_E;
5098
            }
5099
        }
5100
5101
    WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
5102
    FreeDecodedCert(cert);
5103
    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5104
    WOLFSSL_MSG("\tFreeing der trusted peer cert");
5105
    FreeDer(&der);
5106
    WOLFSSL_MSG("\t\tOK Freeing der trusted peer cert");
5107
    WOLFSSL_LEAVE("AddTrustedPeer", ret);
5108
5109
    return WOLFSSL_SUCCESS;
5110
}
5111
#endif /* WOLFSSL_TRUST_PEER_CERT */
5112
5113
5114
/* owns der, internal now uses too */
5115
/* type flag ids from user or from chain received during verify
5116
   don't allow chain ones to be added w/o isCA extension */
5117
int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
5118
0
{
5119
0
    int         ret;
5120
0
    Signer*     signer = NULL;
5121
0
    word32      row;
5122
0
    byte*       subjectHash;
5123
0
#ifdef WOLFSSL_SMALL_STACK
5124
0
    DecodedCert* cert = NULL;
5125
#else
5126
    DecodedCert  cert[1];
5127
#endif
5128
0
    DerBuffer*   der = *pDer;
5129
5130
0
    WOLFSSL_MSG("Adding a CA");
5131
5132
0
    if (cm == NULL) {
5133
0
        FreeDer(pDer);
5134
0
        return BAD_FUNC_ARG;
5135
0
    }
5136
5137
0
#ifdef WOLFSSL_SMALL_STACK
5138
0
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
5139
0
                                 DYNAMIC_TYPE_DCERT);
5140
0
    if (cert == NULL) {
5141
0
        FreeDer(pDer);
5142
0
        return MEMORY_E;
5143
0
    }
5144
0
#endif
5145
5146
0
    InitDecodedCert(cert, der->buffer, der->length, cm->heap);
5147
0
    ret = ParseCert(cert, CA_TYPE, verify, cm);
5148
0
    WOLFSSL_MSG("\tParsed new CA");
5149
5150
0
#ifndef NO_SKID
5151
0
    subjectHash = cert->extSubjKeyId;
5152
#else
5153
    subjectHash = cert->subjectHash;
5154
#endif
5155
5156
    /* check CA key size */
5157
0
    if (verify) {
5158
0
        switch (cert->keyOID) {
5159
0
        #ifndef NO_RSA
5160
0
            #ifdef WC_RSA_PSS
5161
0
            case RSAPSSk:
5162
0
            #endif
5163
0
            case RSAk:
5164
0
                if (cm->minRsaKeySz < 0 ||
5165
0
                                   cert->pubKeySize < (word16)cm->minRsaKeySz) {
5166
0
                    ret = RSA_KEY_SIZE_E;
5167
0
                    WOLFSSL_MSG("\tCA RSA key size error");
5168
0
                }
5169
0
                break;
5170
0
        #endif /* !NO_RSA */
5171
0
            #ifdef HAVE_ECC
5172
0
            case ECDSAk:
5173
0
                if (cm->minEccKeySz < 0 ||
5174
0
                                   cert->pubKeySize < (word16)cm->minEccKeySz) {
5175
0
                    ret = ECC_KEY_SIZE_E;
5176
0
                    WOLFSSL_MSG("\tCA ECC key size error");
5177
0
                }
5178
0
                break;
5179
0
            #endif /* HAVE_ECC */
5180
0
            #ifdef HAVE_ED25519
5181
0
            case ED25519k:
5182
0
                if (cm->minEccKeySz < 0 ||
5183
0
                                   ED25519_KEY_SIZE < (word16)cm->minEccKeySz) {
5184
0
                    ret = ECC_KEY_SIZE_E;
5185
0
                    WOLFSSL_MSG("\tCA ECC key size error");
5186
0
                }
5187
0
                break;
5188
0
            #endif /* HAVE_ED25519 */
5189
0
            #ifdef HAVE_ED448
5190
0
            case ED448k:
5191
0
                if (cm->minEccKeySz < 0 ||
5192
0
                                     ED448_KEY_SIZE < (word16)cm->minEccKeySz) {
5193
0
                    ret = ECC_KEY_SIZE_E;
5194
0
                    WOLFSSL_MSG("\tCA ECC key size error");
5195
0
                }
5196
0
                break;
5197
0
            #endif /* HAVE_ED448 */
5198
            #if defined(HAVE_PQC)
5199
            #if defined(HAVE_FALCON)
5200
            case FALCON_LEVEL1k:
5201
                if (cm->minFalconKeySz < 0 ||
5202
                          FALCON_LEVEL1_KEY_SIZE < (word16)cm->minFalconKeySz) {
5203
                    ret = FALCON_KEY_SIZE_E;
5204
                    WOLFSSL_MSG("\tCA Falcon level 1 key size error");
5205
                }
5206
                break;
5207
            case FALCON_LEVEL5k:
5208
                if (cm->minFalconKeySz < 0 ||
5209
                          FALCON_LEVEL5_KEY_SIZE < (word16)cm->minFalconKeySz) {
5210
                    ret = FALCON_KEY_SIZE_E;
5211
                    WOLFSSL_MSG("\tCA Falcon level 5 key size error");
5212
                }
5213
                break;
5214
            #endif /* HAVE_FALCON */
5215
            #if defined(HAVE_DILITHIUM)
5216
            case DILITHIUM_LEVEL2k:
5217
            case DILITHIUM_AES_LEVEL2k:
5218
                if (cm->minDilithiumKeySz < 0 ||
5219
                    DILITHIUM_LEVEL2_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
5220
                    ret = DILITHIUM_KEY_SIZE_E;
5221
                    WOLFSSL_MSG("\tCA Dilithium level 2 key size error");
5222
                }
5223
                break;
5224
            case DILITHIUM_LEVEL3k:
5225
            case DILITHIUM_AES_LEVEL3k:
5226
                if (cm->minDilithiumKeySz < 0 ||
5227
                    DILITHIUM_LEVEL3_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
5228
                    ret = DILITHIUM_KEY_SIZE_E;
5229
                    WOLFSSL_MSG("\tCA Dilithium level 3 key size error");
5230
                }
5231
                break;
5232
            case DILITHIUM_LEVEL5k:
5233
            case DILITHIUM_AES_LEVEL5k:
5234
                if (cm->minDilithiumKeySz < 0 ||
5235
                    DILITHIUM_LEVEL5_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
5236
                    ret = DILITHIUM_KEY_SIZE_E;
5237
                    WOLFSSL_MSG("\tCA Dilithium level 5 key size error");
5238
                }
5239
                break;
5240
            #endif /* HAVE_DILITHIUM */
5241
            #endif /* HAVE_PQC */
5242
5243
0
            default:
5244
0
                WOLFSSL_MSG("\tNo key size check done on CA");
5245
0
                break; /* no size check if key type is not in switch */
5246
0
        }
5247
0
    }
5248
5249
0
    if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
5250
0
        WOLFSSL_MSG("\tCan't add as CA if not actually one");
5251
0
        ret = NOT_CA_ERROR;
5252
0
    }
5253
0
#ifndef ALLOW_INVALID_CERTSIGN
5254
0
    else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
5255
0
        !cert->selfSigned && (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
5256
        /* Intermediate CA certs are required to have the keyCertSign
5257
        * extension set. User loaded root certs are not. */
5258
0
        WOLFSSL_MSG("\tDoesn't have key usage certificate signing");
5259
0
        ret = NOT_CA_ERROR;
5260
0
    }
5261
0
#endif
5262
0
    else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
5263
0
        WOLFSSL_MSG("\tAlready have this CA, not adding again");
5264
0
        (void)ret;
5265
0
    }
5266
0
    else if (ret == 0) {
5267
        /* take over signer parts */
5268
0
        signer = MakeSigner(cm->heap);
5269
0
        if (!signer)
5270
0
            ret = MEMORY_ERROR;
5271
0
    }
5272
0
    if (ret == 0 && signer != NULL) {
5273
    #ifdef WOLFSSL_SIGNER_DER_CERT
5274
        ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
5275
    }
5276
    if (ret == 0 && signer != NULL) {
5277
        XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
5278
    #endif
5279
0
        signer->keyOID         = cert->keyOID;
5280
0
        if (cert->pubKeyStored) {
5281
0
            signer->publicKey      = cert->publicKey;
5282
0
            signer->pubKeySize     = cert->pubKeySize;
5283
0
        }
5284
0
        if (cert->subjectCNStored) {
5285
0
            signer->nameLen        = cert->subjectCNLen;
5286
0
            signer->name           = cert->subjectCN;
5287
0
        }
5288
0
        signer->pathLength     = cert->pathLength;
5289
0
        signer->maxPathLen     = cert->maxPathLen;
5290
0
        signer->pathLengthSet  = cert->pathLengthSet;
5291
0
        signer->selfSigned     = cert->selfSigned;
5292
0
    #ifndef IGNORE_NAME_CONSTRAINTS
5293
0
        signer->permittedNames = cert->permittedNames;
5294
0
        signer->excludedNames  = cert->excludedNames;
5295
0
    #endif
5296
0
    #ifndef NO_SKID
5297
0
        XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
5298
0
                SIGNER_DIGEST_SIZE);
5299
0
    #endif
5300
0
        XMEMCPY(signer->subjectNameHash, cert->subjectHash,
5301
0
                SIGNER_DIGEST_SIZE);
5302
    #ifdef HAVE_OCSP
5303
        XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash,
5304
                KEYID_SIZE);
5305
    #endif
5306
0
        signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
5307
0
                                                : 0xFFFF;
5308
0
        signer->next    = NULL; /* If Key Usage not set, all uses valid. */
5309
0
        cert->publicKey = 0;    /* in case lock fails don't free here.   */
5310
0
        cert->subjectCN = 0;
5311
0
    #ifndef IGNORE_NAME_CONSTRAINTS
5312
0
        cert->permittedNames = NULL;
5313
0
        cert->excludedNames = NULL;
5314
0
    #endif
5315
5316
0
    #ifndef NO_SKID
5317
0
        row = HashSigner(signer->subjectKeyIdHash);
5318
    #else
5319
        row = HashSigner(signer->subjectNameHash);
5320
    #endif
5321
5322
0
        if (wc_LockMutex(&cm->caLock) == 0) {
5323
0
            signer->next = cm->caTable[row];
5324
0
            cm->caTable[row] = signer;   /* takes ownership */
5325
0
            wc_UnLockMutex(&cm->caLock);
5326
0
            if (cm->caCacheCallback)
5327
0
                cm->caCacheCallback(der->buffer, (int)der->length, type);
5328
0
        }
5329
0
        else {
5330
0
            WOLFSSL_MSG("\tCA Mutex Lock failed");
5331
0
            ret = BAD_MUTEX_E;
5332
0
            FreeSigner(signer, cm->heap);
5333
0
        }
5334
0
    }
5335
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
5336
    /* Verify CA by TSIP so that generated tsip key is going to be able to */
5337
    /* be used for peer's cert verification                                */
5338
    /* TSIP is only able to handle USER CA, and only one CA.               */
5339
    /* Therefore, it doesn't need to call TSIP again if there is already   */
5340
    /* verified CA.                                                        */
5341
    if ( ret == 0 && signer != NULL ) {
5342
        signer->cm_idx = row;
5343
        if (type == WOLFSSL_USER_CA) {
5344
            if ((ret = wc_Renesas_cmn_RootCertVerify(cert->source, cert->maxIdx,
5345
                 cert->sigCtx.CertAtt.pubkey_n_start,
5346
                 cert->sigCtx.CertAtt.pubkey_n_len - 1,
5347
                 cert->sigCtx.CertAtt.pubkey_e_start,
5348
                cert->sigCtx.CertAtt.pubkey_e_len - 1,
5349
                 row/* cm index */))
5350
                < 0)
5351
                WOLFSSL_MSG("Renesas_RootCertVerify() failed");
5352
            else
5353
                WOLFSSL_MSG("Renesas_RootCertVerify() succeed or skipped");
5354
        }
5355
    }
5356
#endif /* TSIP or SCE */
5357
5358
0
    WOLFSSL_MSG("\tFreeing Parsed CA");
5359
0
    FreeDecodedCert(cert);
5360
0
#ifdef WOLFSSL_SMALL_STACK
5361
0
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
5362
0
#endif
5363
0
    WOLFSSL_MSG("\tFreeing der CA");
5364
0
    FreeDer(pDer);
5365
0
    WOLFSSL_MSG("\t\tOK Freeing der CA");
5366
5367
0
    WOLFSSL_LEAVE("AddCA", ret);
5368
5369
0
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
5370
0
}
5371
5372
#endif /* !NO_CERTS */
5373
5374
5375
#ifndef NO_SESSION_CACHE
5376
5377
    /* basic config gives a cache with 33 sessions, adequate for clients and
5378
       embedded servers
5379
5380
       TITAN_SESSION_CACHE allows just over 2 million sessions, for servers
5381
       with titanic amounts of memory with long session ID timeouts and high
5382
       levels of traffic.
5383
5384
       ENABLE_SESSION_CACHE_ROW_LOCK: Allows row level locking for increased
5385
       performance with large session caches
5386
5387
       HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
5388
       allows over 13,000 new sessions per minute or over 200 new sessions per
5389
       second
5390
5391
       BIG_SESSION_CACHE yields 20,027 sessions
5392
5393
       MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
5394
       aren't under heavy load, basically allows 200 new sessions per minute
5395
5396
       SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
5397
       or systems where the default of nearly 3kB is too much RAM, this define
5398
       uses less than 500 bytes RAM
5399
5400
       default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
5401
    */
5402
    #if defined(TITAN_SESSION_CACHE)
5403
        #define SESSIONS_PER_ROW 31
5404
        #define SESSION_ROWS 64937
5405
        #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5406
        #define ENABLE_SESSION_CACHE_ROW_LOCK
5407
        #endif
5408
    #elif defined(HUGE_SESSION_CACHE)
5409
        #define SESSIONS_PER_ROW 11
5410
        #define SESSION_ROWS 5981
5411
    #elif defined(BIG_SESSION_CACHE)
5412
        #define SESSIONS_PER_ROW 7
5413
        #define SESSION_ROWS 2861
5414
    #elif defined(MEDIUM_SESSION_CACHE)
5415
        #define SESSIONS_PER_ROW 5
5416
        #define SESSION_ROWS 211
5417
    #elif defined(SMALL_SESSION_CACHE)
5418
        #define SESSIONS_PER_ROW 2
5419
        #define SESSION_ROWS 3
5420
    #else
5421
0
        #define SESSIONS_PER_ROW 3
5422
0
        #define SESSION_ROWS 11
5423
    #endif
5424
0
    #define INVALID_SESSION_ROW (-1)
5425
5426
    #ifdef NO_SESSION_CACHE_ROW_LOCK
5427
        #undef ENABLE_SESSION_CACHE_ROW_LOCK
5428
    #endif
5429
5430
    typedef struct SessionRow {
5431
        int nextIdx;                           /* where to place next one   */
5432
        int totalCount;                        /* sessions ever on this row */
5433
        WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
5434
5435
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5436
        /* not included in import/export */
5437
        wolfSSL_Mutex row_mutex;
5438
        int mutex_valid;
5439
    #endif
5440
    } SessionRow;
5441
    #define SIZEOF_SESSION_ROW (sizeof(WOLFSSL_SESSION) + (sizeof(int) * 2))
5442
5443
    static WOLFSSL_GLOBAL SessionRow SessionCache[SESSION_ROWS];
5444
5445
    #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
5446
        static WOLFSSL_GLOBAL word32 PeakSessions;
5447
    #endif
5448
5449
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5450
    #define SESSION_ROW_LOCK(row)   wc_LockMutex(&(row)->row_mutex)
5451
    #define SESSION_ROW_UNLOCK(row) wc_UnLockMutex(&(row)->row_mutex);
5452
    #else
5453
    static WOLFSSL_GLOBAL wolfSSL_Mutex session_mutex; /* SessionCache mutex */
5454
    static WOLFSSL_GLOBAL int session_mutex_valid = 0;
5455
0
    #define SESSION_ROW_LOCK(row)   wc_LockMutex(&session_mutex)
5456
0
    #define SESSION_ROW_UNLOCK(row) wc_UnLockMutex(&session_mutex);
5457
    #endif
5458
5459
    #if !defined(NO_SESSION_CACHE_REF) && defined(NO_CLIENT_CACHE)
5460
    #error ClientCache is required when not using NO_SESSION_CACHE_REF
5461
    #endif
5462
5463
    #ifndef NO_CLIENT_CACHE
5464
5465
        #ifndef CLIENT_SESSIONS_MULTIPLIER
5466
            #ifdef NO_SESSION_CACHE_REF
5467
                #define CLIENT_SESSIONS_MULTIPLIER 1
5468
            #else
5469
                /* ClientSession objects are lightweight (compared to
5470
                 * WOLFSSL_SESSION) so to decrease chance that user will reuse
5471
                 * thse wrong session, increase the ClientCache size. This will
5472
                 * make the entire ClientCache about the size of one
5473
                 * WOLFSSL_SESSION object. */
5474
0
                #define CLIENT_SESSIONS_MULTIPLIER 8
5475
            #endif
5476
        #endif
5477
        #define CLIENT_SESSIONS_PER_ROW \
5478
0
                                (SESSIONS_PER_ROW * CLIENT_SESSIONS_MULTIPLIER)
5479
0
        #define CLIENT_SESSION_ROWS (SESSION_ROWS * CLIENT_SESSIONS_MULTIPLIER)
5480
5481
        #if CLIENT_SESSIONS_PER_ROW > 65535
5482
        #error CLIENT_SESSIONS_PER_ROW too big
5483
        #endif
5484
        #if CLIENT_SESSION_ROWS > 65535
5485
        #error CLIENT_SESSION_ROWS too big
5486
        #endif
5487
5488
        struct ClientSession {
5489
            word16 serverRow;            /* SessionCache Row id */
5490
            word16 serverIdx;            /* SessionCache Idx (column) */
5491
            word32 sessionIDHash;
5492
        };
5493
    #ifndef WOLFSSL_CLIENT_SESSION_DEFINED
5494
        typedef struct ClientSession ClientSession;
5495
        #define WOLFSSL_CLIENT_SESSION_DEFINED
5496
    #endif
5497
5498
        typedef struct ClientRow {
5499
            int nextIdx;                /* where to place next one   */
5500
            int totalCount;             /* sessions ever on this row */
5501
            ClientSession Clients[CLIENT_SESSIONS_PER_ROW];
5502
        } ClientRow;
5503
5504
        static WOLFSSL_GLOBAL ClientRow ClientCache[CLIENT_SESSION_ROWS];
5505
                                                     /* Client Cache */
5506
                                                     /* uses session mutex */
5507
5508
        static WOLFSSL_GLOBAL wolfSSL_Mutex clisession_mutex; /* ClientCache mutex */
5509
        static WOLFSSL_GLOBAL int clisession_mutex_valid = 0;
5510
    #endif /* !NO_CLIENT_CACHE */
5511
5512
#endif /* !NO_SESSION_CACHE */
5513
5514
#if !defined(WC_NO_RNG) && (defined(OPENSSL_EXTRA) || \
5515
    (defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA)))
5516
5517
    #define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
5518
    static WC_RNG globalRNG;
5519
    static int initGlobalRNG = 0;
5520
    static wolfSSL_Mutex globalRNGMutex;
5521
    static int globalRNGMutex_valid = 0;
5522
5523
    #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
5524
    static WOLFSSL_DRBG_CTX* gDrbgDefCtx = NULL;
5525
    #endif
5526
5527
    WC_RNG* wolfssl_get_global_rng(void)
5528
    {
5529
        WC_RNG* ret = NULL;
5530
5531
        if (initGlobalRNG == 0)
5532
            WOLFSSL_MSG("Global RNG no Init");
5533
        else
5534
            ret = &globalRNG;
5535
5536
        return ret;
5537
    }
5538
#endif
5539
5540
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
5541
static int wolfSSL_RAND_InitMutex(void);
5542
#endif
5543
5544
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
5545
static void AtExitCleanup(void)
5546
{
5547
    if (initRefCount > 0) {
5548
        initRefCount = 1;
5549
        (void)wolfSSL_Cleanup();
5550
    }
5551
}
5552
#endif
5553
5554
WOLFSSL_ABI
5555
int wolfSSL_Init(void)
5556
0
{
5557
0
    int ret = WOLFSSL_SUCCESS;
5558
#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
5559
    int i;
5560
#endif
5561
5562
0
    WOLFSSL_ENTER("wolfSSL_Init");
5563
5564
    #if FIPS_VERSION_GE(5,1)
5565
        ret = wolfCrypt_SetPrivateKeyReadEnable_fips(1, WC_KEYTYPE_ALL);
5566
        if (ret != 0)
5567
            return ret;
5568
        else
5569
            ret = WOLFSSL_SUCCESS;
5570
    #endif
5571
5572
0
    if (initRefCount == 0) {
5573
        /* Initialize crypto for use with TLS connection */
5574
0
        if (wolfCrypt_Init() != 0) {
5575
0
            WOLFSSL_MSG("Bad wolfCrypt Init");
5576
0
            ret = WC_INIT_E;
5577
0
        }
5578
5579
#ifdef HAVE_GLOBAL_RNG
5580
        if (ret == WOLFSSL_SUCCESS) {
5581
            if (wc_InitMutex(&globalRNGMutex) != 0) {
5582
                WOLFSSL_MSG("Bad Init Mutex rng");
5583
                ret = BAD_MUTEX_E;
5584
            }
5585
            else {
5586
                globalRNGMutex_valid = 1;
5587
            }
5588
        }
5589
#endif
5590
5591
    #ifdef WC_RNG_SEED_CB
5592
        wc_SetSeed_Cb(wc_GenerateSeed);
5593
    #endif
5594
5595
#ifdef OPENSSL_EXTRA
5596
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
5597
        if ((ret == WOLFSSL_SUCCESS) && (wolfSSL_RAND_InitMutex() != 0)) {
5598
            ret = BAD_MUTEX_E;
5599
        }
5600
    #endif
5601
        if ((ret == WOLFSSL_SUCCESS) &&
5602
            (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS)) {
5603
            WOLFSSL_MSG("wolfSSL_RAND_Seed failed");
5604
            ret = WC_INIT_E;
5605
        }
5606
#endif
5607
5608
0
#ifndef NO_SESSION_CACHE
5609
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5610
        for (i = 0; i < SESSION_ROWS; ++i) {
5611
            SessionCache[i].mutex_valid = 0;
5612
        }
5613
        for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < SESSION_ROWS); ++i) {
5614
            if (wc_InitMutex(&SessionCache[i].row_mutex) != 0) {
5615
                WOLFSSL_MSG("Bad Init Mutex session");
5616
                ret = BAD_MUTEX_E;
5617
            }
5618
            else {
5619
                SessionCache[i].mutex_valid = 1;
5620
            }
5621
        }
5622
    #else
5623
0
        if (ret == WOLFSSL_SUCCESS) {
5624
0
            if (wc_InitMutex(&session_mutex) != 0) {
5625
0
                WOLFSSL_MSG("Bad Init Mutex session");
5626
0
                ret = BAD_MUTEX_E;
5627
0
            }
5628
0
            else {
5629
0
                session_mutex_valid = 1;
5630
0
            }
5631
0
        }
5632
0
    #endif
5633
0
    #ifndef NO_CLIENT_CACHE
5634
0
        if (ret == WOLFSSL_SUCCESS) {
5635
0
            if (wc_InitMutex(&clisession_mutex) != 0) {
5636
0
                WOLFSSL_MSG("Bad Init Mutex session");
5637
0
                ret = BAD_MUTEX_E;
5638
0
            }
5639
0
            else {
5640
0
                clisession_mutex_valid = 1;
5641
0
            }
5642
0
        }
5643
0
    #endif
5644
0
#endif
5645
0
        if (ret == WOLFSSL_SUCCESS) {
5646
0
            if (wc_InitMutex(&count_mutex) != 0) {
5647
0
                WOLFSSL_MSG("Bad Init Mutex count");
5648
0
                ret = BAD_MUTEX_E;
5649
0
            }
5650
0
            else {
5651
0
                count_mutex_valid = 1;
5652
0
            }
5653
0
        }
5654
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
5655
        /* OpenSSL registers cleanup using atexit */
5656
        if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
5657
            WOLFSSL_MSG("Bad atexit registration");
5658
            ret = WC_INIT_E;
5659
        }
5660
#endif
5661
0
    }
5662
5663
0
    if (ret == WOLFSSL_SUCCESS) {
5664
0
        if (wc_LockMutex(&count_mutex) != 0) {
5665
0
            WOLFSSL_MSG("Bad Lock Mutex count");
5666
0
            ret = BAD_MUTEX_E;
5667
0
        }
5668
0
        else {
5669
0
            initRefCount++;
5670
0
            wc_UnLockMutex(&count_mutex);
5671
0
        }
5672
0
    }
5673
5674
0
    if (ret != WOLFSSL_SUCCESS) {
5675
0
        initRefCount = 1; /* Force cleanup */
5676
0
        (void)wolfSSL_Cleanup(); /* Ignore any error from cleanup */
5677
0
    }
5678
5679
0
    return ret;
5680
0
}
5681
5682
5683
#ifndef NO_CERTS
5684
5685
/* process user cert chain to pass during the handshake */
5686
static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
5687
                         long sz, int format, int type, WOLFSSL* ssl,
5688
                         long* used, EncryptedInfo* info, int verify)
5689
0
{
5690
0
    int ret = 0;
5691
0
    void* heap = wolfSSL_CTX_GetHeap(ctx, ssl);
5692
0
#ifdef WOLFSSL_TLS13
5693
0
    int cnt = 0;
5694
0
#endif
5695
5696
0
    if ((type == CA_TYPE) && (ctx == NULL)) {
5697
0
        WOLFSSL_MSG("Need context for CA load");
5698
0
        return BAD_FUNC_ARG;
5699
0
    }
5700
5701
    /* we may have a user cert chain, try to consume */
5702
0
    if ((type == CERT_TYPE || type == CA_TYPE) && (info->consumed < sz)) {
5703
0
    #ifdef WOLFSSL_SMALL_STACK
5704
0
        byte   staticBuffer[1];                 /* force heap usage */
5705
    #else
5706
        byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
5707
    #endif
5708
0
        byte*  chainBuffer = staticBuffer;
5709
0
        int    dynamicBuffer = 0;
5710
0
        word32 bufferSz;
5711
0
        long   consumed = info->consumed;
5712
0
        word32 idx = 0;
5713
0
        int    gotOne = 0;
5714
5715
        /* Calculate max possible size, including max headers */
5716
0
        bufferSz = (word32)(sz - consumed) + (CERT_HEADER_SZ * MAX_CHAIN_DEPTH);
5717
0
        if (bufferSz > sizeof(staticBuffer)) {
5718
0
            WOLFSSL_MSG("Growing Tmp Chain Buffer");
5719
            /* will shrink to actual size */
5720
0
            chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
5721
0
            if (chainBuffer == NULL) {
5722
0
                return MEMORY_E;
5723
0
            }
5724
0
            dynamicBuffer = 1;
5725
0
        }
5726
5727
0
        WOLFSSL_MSG("Processing Cert Chain");
5728
0
        while (consumed < sz) {
5729
0
            DerBuffer* part = NULL;
5730
0
            word32 remain = (word32)(sz - consumed);
5731
0
            info->consumed = 0;
5732
5733
0
            if (format == WOLFSSL_FILETYPE_PEM) {
5734
0
            #ifdef WOLFSSL_PEM_TO_DER
5735
0
                ret = PemToDer(buff + consumed, remain, type, &part,
5736
0
                               heap, info, NULL);
5737
            #else
5738
                ret = NOT_COMPILED_IN;
5739
            #endif
5740
0
            }
5741
0
            else {
5742
0
                int length = remain;
5743
0
                if (format == WOLFSSL_FILETYPE_ASN1) {
5744
                    /* get length of der (read sequence) */
5745
0
                    word32 inOutIdx = 0;
5746
0
                    if (GetSequence(buff + consumed, &inOutIdx, &length,
5747
0
                            remain) < 0) {
5748
0
                        ret = ASN_NO_PEM_HEADER;
5749
0
                    }
5750
0
                    length += inOutIdx; /* include leading sequence */
5751
0
                }
5752
0
                info->consumed = length;
5753
0
                if (ret == 0) {
5754
0
                    ret = AllocDer(&part, length, type, heap);
5755
0
                    if (ret == 0) {
5756
0
                        XMEMCPY(part->buffer, buff + consumed, length);
5757
0
                    }
5758
0
                }
5759
0
            }
5760
0
            if (ret == 0) {
5761
0
                gotOne = 1;
5762
0
#ifdef WOLFSSL_TLS13
5763
0
                cnt++;
5764
0
#endif
5765
0
                if ((idx + part->length + CERT_HEADER_SZ) > bufferSz) {
5766
0
                    WOLFSSL_MSG("   Cert Chain bigger than buffer. "
5767
0
                                "Consider increasing MAX_CHAIN_DEPTH");
5768
0
                    ret = BUFFER_E;
5769
0
                }
5770
0
                else {
5771
0
                    c32to24(part->length, &chainBuffer[idx]);
5772
0
                    idx += CERT_HEADER_SZ;
5773
0
                    XMEMCPY(&chainBuffer[idx], part->buffer, part->length);
5774
0
                    idx += part->length;
5775
0
                    consumed  += info->consumed;
5776
0
                    if (used)
5777
0
                        *used += info->consumed;
5778
0
                }
5779
5780
                /* add CA's to certificate manager */
5781
0
                if (ret == 0 && type == CA_TYPE) {
5782
                    /* verify CA unless user set to no verify */
5783
0
                    ret = AddCA(ctx->cm, &part, WOLFSSL_USER_CA, verify);
5784
0
                    if (ret == WOLFSSL_SUCCESS) {
5785
0
                        ret = 0; /* converted success case */
5786
0
                    }
5787
0
                    gotOne = 0; /* don't exit loop for CA type */
5788
0
                }
5789
0
            }
5790
5791
0
            FreeDer(&part);
5792
5793
0
            if (ret == ASN_NO_PEM_HEADER && gotOne) {
5794
0
                WOLFSSL_MSG("We got one good cert, so stuff at end ok");
5795
0
                break;
5796
0
            }
5797
5798
0
            if (ret < 0) {
5799
0
                WOLFSSL_MSG("   Error in Cert in Chain");
5800
0
                if (dynamicBuffer)
5801
0
                    XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
5802
0
                return ret;
5803
0
            }
5804
0
            WOLFSSL_MSG("   Consumed another Cert in Chain");
5805
0
        }
5806
0
        WOLFSSL_MSG("Finished Processing Cert Chain");
5807
5808
        /* only retain actual size used */
5809
0
        ret = 0;
5810
0
        if (idx > 0) {
5811
0
            if (ssl) {
5812
0
                if (ssl->buffers.weOwnCertChain) {
5813
0
                    FreeDer(&ssl->buffers.certChain);
5814
0
                }
5815
0
                ret = AllocDer(&ssl->buffers.certChain, idx, type, heap);
5816
0
                if (ret == 0) {
5817
0
                    XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer,
5818
0
                            idx);
5819
0
                    ssl->buffers.weOwnCertChain = 1;
5820
0
                }
5821
0
            #ifdef WOLFSSL_TLS13
5822
0
                ssl->buffers.certChainCnt = cnt;
5823
0
            #endif
5824
0
            } else if (ctx) {
5825
0
                FreeDer(&ctx->certChain);
5826
0
                ret = AllocDer(&ctx->certChain, idx, type, heap);
5827
0
                if (ret == 0) {
5828
0
                    XMEMCPY(ctx->certChain->buffer, chainBuffer, idx);
5829
0
                }
5830
0
            #ifdef WOLFSSL_TLS13
5831
0
                ctx->certChainCnt = cnt;
5832
0
            #endif
5833
0
            }
5834
0
        }
5835
5836
0
        if (dynamicBuffer)
5837
0
            XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
5838
0
    }
5839
5840
0
    return ret;
5841
0
}
5842
5843
static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der,
5844
    int* keySz, word32* idx, int* resetSuites, int* keyFormat, void* heap, int devId)
5845
0
{
5846
0
    int ret = 0;
5847
5848
0
    (void)heap;
5849
0
    (void)devId;
5850
5851
0
    if (ctx == NULL && ssl == NULL)
5852
0
        return BAD_FUNC_ARG;
5853
0
    if (!der || !keySz || !idx || !resetSuites || !keyFormat)
5854
0
        return BAD_FUNC_ARG;
5855
5856
0
#ifndef NO_RSA
5857
0
    if ((*keyFormat == 0 || *keyFormat == RSAk)) {
5858
        /* make sure RSA key can be used */
5859
0
    #ifdef WOLFSSL_SMALL_STACK
5860
0
        RsaKey* key;
5861
    #else
5862
        RsaKey  key[1];
5863
    #endif
5864
5865
0
    #ifdef WOLFSSL_SMALL_STACK
5866
0
        key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
5867
0
        if (key == NULL)
5868
0
            return MEMORY_E;
5869
0
    #endif
5870
5871
0
        ret = wc_InitRsaKey_ex(key, heap, devId);
5872
0
        if (ret == 0) {
5873
0
            *idx = 0;
5874
0
            ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length);
5875
0
        #ifdef WOLF_PRIVATE_KEY_ID
5876
0
            if (ret != 0 && (devId != INVALID_DEVID
5877
            #ifdef HAVE_PK_CALLBACKS
5878
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
5879
            #endif
5880
0
            )) {
5881
                /* if using crypto or PK callbacks, try public key decode */
5882
0
                *idx = 0;
5883
0
                ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length);
5884
0
            }
5885
0
        #endif
5886
0
            if (ret != 0) {
5887
            #if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
5888
                !defined(HAVE_ED448) && !defined(HAVE_PQC)
5889
                WOLFSSL_MSG("RSA decode failed and other algorithms "
5890
                            "not enabled to try");
5891
                ret = WOLFSSL_BAD_FILE;
5892
            #else
5893
0
                ret = 0; /* continue trying other algorithms */
5894
0
            #endif
5895
0
            }
5896
0
            else {
5897
                /* check that the size of the RSA key is enough */
5898
0
                int minRsaSz = ssl ? ssl->options.minRsaKeySz :
5899
0
                    ctx->minRsaKeySz;
5900
0
                *keySz = wc_RsaEncryptSize((RsaKey*)key);
5901
0
                if (*keySz < minRsaSz) {
5902
0
                    ret = RSA_KEY_SIZE_E;
5903
0
                    WOLFSSL_MSG("Private Key size too small");
5904
0
                }
5905
5906
0
                if (ssl) {
5907
0
                    ssl->buffers.keyType = rsa_sa_algo;
5908
0
                    ssl->buffers.keySz = *keySz;
5909
0
                }
5910
0
                else {
5911
0
                    ctx->privateKeyType = rsa_sa_algo;
5912
0
                    ctx->privateKeySz = *keySz;
5913
0
                }
5914
5915
0
                *keyFormat = RSAk;
5916
5917
0
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
5918
0
                    ssl->options.haveStaticECC = 0;
5919
0
                    *resetSuites = 1;
5920
0
                }
5921
0
            }
5922
5923
0
            wc_FreeRsaKey(key);
5924
0
        }
5925
5926
0
    #ifdef WOLFSSL_SMALL_STACK
5927
0
        XFREE(key, heap, DYNAMIC_TYPE_RSA);
5928
0
    #endif
5929
0
        if (ret != 0)
5930
0
            return ret;
5931
0
    }
5932
0
#endif
5933
0
#ifdef HAVE_ECC
5934
0
    if ((*keyFormat == 0 || *keyFormat == ECDSAk)) {
5935
        /* make sure ECC key can be used */
5936
0
    #ifdef WOLFSSL_SMALL_STACK
5937
0
        ecc_key* key;
5938
    #else
5939
        ecc_key  key[1];
5940
    #endif
5941
5942
0
    #ifdef WOLFSSL_SMALL_STACK
5943
0
        key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
5944
0
        if (key == NULL)
5945
0
            return MEMORY_E;
5946
0
    #endif
5947
5948
0
        if (wc_ecc_init_ex(key, heap, devId) == 0) {
5949
0
            *idx = 0;
5950
0
            ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length);
5951
0
        #ifdef WOLF_PRIVATE_KEY_ID
5952
0
            if (ret != 0 && (devId != INVALID_DEVID
5953
            #ifdef HAVE_PK_CALLBACKS
5954
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
5955
            #endif
5956
0
            )) {
5957
                /* if using crypto or PK callbacks, try public key decode */
5958
0
                *idx = 0;
5959
0
                ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length);
5960
0
            }
5961
0
        #endif
5962
0
            if (ret == 0) {
5963
                /* check for minimum ECC key size and then free */
5964
0
                int minKeySz = ssl ? ssl->options.minEccKeySz :
5965
0
                                                        ctx->minEccKeySz;
5966
0
                *keySz = wc_ecc_size(key);
5967
0
                if (*keySz < minKeySz) {
5968
0
                    WOLFSSL_MSG("ECC private key too small");
5969
0
                    ret = ECC_KEY_SIZE_E;
5970
0
                }
5971
5972
0
                *keyFormat = ECDSAk;
5973
0
                if (ssl) {
5974
0
                    ssl->options.haveStaticECC = 1;
5975
0
                    ssl->buffers.keyType = ecc_dsa_sa_algo;
5976
0
                    ssl->buffers.keySz = *keySz;
5977
0
                }
5978
0
                else {
5979
0
                    ctx->haveStaticECC = 1;
5980
0
                    ctx->privateKeyType = ecc_dsa_sa_algo;
5981
0
                    ctx->privateKeySz = *keySz;
5982
0
                }
5983
5984
0
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
5985
0
                    *resetSuites = 1;
5986
0
                }
5987
0
            }
5988
0
            else {
5989
0
                ret = 0; /* continue trying other algorithms */
5990
0
            }
5991
5992
0
            wc_ecc_free(key);
5993
0
        }
5994
5995
0
    #ifdef WOLFSSL_SMALL_STACK
5996
0
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
5997
0
    #endif
5998
0
        if (ret != 0)
5999
0
            return ret;
6000
0
    }
6001
0
#endif /* HAVE_ECC */
6002
0
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
6003
0
    if ((*keyFormat == 0 || *keyFormat == ED25519k)) {
6004
        /* make sure Ed25519 key can be used */
6005
0
    #ifdef WOLFSSL_SMALL_STACK
6006
0
        ed25519_key* key;
6007
    #else
6008
        ed25519_key  key[1];
6009
    #endif
6010
6011
0
    #ifdef WOLFSSL_SMALL_STACK
6012
0
        key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
6013
0
                                                      DYNAMIC_TYPE_ED25519);
6014
0
        if (key == NULL)
6015
0
            return MEMORY_E;
6016
0
    #endif
6017
6018
0
        ret = wc_ed25519_init_ex(key, heap, devId);
6019
0
        if (ret == 0) {
6020
0
            *idx = 0;
6021
0
            ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length);
6022
0
        #ifdef WOLF_PRIVATE_KEY_ID
6023
0
            if (ret != 0 && (devId != INVALID_DEVID
6024
            #ifdef HAVE_PK_CALLBACKS
6025
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
6026
            #endif
6027
0
            )) {
6028
                /* if using crypto or PK callbacks, try public key decode */
6029
0
                *idx = 0;
6030
0
                ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key,
6031
0
                                                der->length);
6032
0
            }
6033
0
        #endif
6034
0
            if (ret == 0) {
6035
                /* check for minimum key size and then free */
6036
0
                int minKeySz = ssl ? ssl->options.minEccKeySz :
6037
0
                                                           ctx->minEccKeySz;
6038
0
                *keySz = ED25519_KEY_SIZE;
6039
0
                if (*keySz < minKeySz) {
6040
0
                    WOLFSSL_MSG("ED25519 private key too small");
6041
0
                    ret = ECC_KEY_SIZE_E;
6042
0
                }
6043
0
                if (ret == 0) {
6044
0
                    if (ssl) {
6045
0
                        ssl->buffers.keyType = ed25519_sa_algo;
6046
0
                        ssl->buffers.keySz = *keySz;
6047
0
                    }
6048
0
                    else if (ctx) {
6049
0
                        ctx->privateKeyType = ed25519_sa_algo;
6050
0
                        ctx->privateKeySz = *keySz;
6051
0
                    }
6052
6053
0
                    *keyFormat = ED25519k;
6054
0
                    if (ssl != NULL) {
6055
                        /* ED25519 requires caching enabled for tracking message
6056
                         * hash used in EdDSA_Update for signing */
6057
0
                        ssl->options.cacheMessages = 1;
6058
0
                        if (ssl->options.side == WOLFSSL_SERVER_END) {
6059
0
                            *resetSuites = 1;
6060
0
                        }
6061
0
                    }
6062
0
                }
6063
0
            }
6064
0
            else {
6065
0
                ret = 0; /* continue trying other algorithms */
6066
0
            }
6067
6068
0
            wc_ed25519_free(key);
6069
0
        }
6070
6071
0
    #ifdef WOLFSSL_SMALL_STACK
6072
0
        XFREE(key, heap, DYNAMIC_TYPE_ED25519);
6073
0
    #endif
6074
0
        if (ret != 0)
6075
0
            return ret;
6076
0
    }
6077
0
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
6078
0
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
6079
0
    if ((*keyFormat == 0 || *keyFormat == ED448k)) {
6080
        /* make sure Ed448 key can be used */
6081
0
    #ifdef WOLFSSL_SMALL_STACK
6082
0
        ed448_key* key = NULL;
6083
    #else
6084
        ed448_key  key[1];
6085
    #endif
6086
6087
0
    #ifdef WOLFSSL_SMALL_STACK
6088
0
        key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
6089
0
        if (key == NULL)
6090
0
            return MEMORY_E;
6091
0
    #endif
6092
6093
0
        ret = wc_ed448_init(key);
6094
0
        if (ret == 0) {
6095
0
            *idx = 0;
6096
0
            ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length);
6097
0
        #ifdef WOLF_PRIVATE_KEY_ID
6098
0
            if (ret != 0 && (devId != INVALID_DEVID
6099
            #ifdef HAVE_PK_CALLBACKS
6100
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
6101
            #endif
6102
0
            )) {
6103
                /* if using crypto or PK callbacks, try public key decode */
6104
0
                *idx = 0;
6105
0
                ret = wc_Ed448PublicKeyDecode(der->buffer, idx, key,
6106
0
                                              der->length);
6107
0
            }
6108
0
        #endif
6109
0
            if (ret == 0) {
6110
                /* check for minimum key size and then free */
6111
0
                int minKeySz = ssl ? ssl->options.minEccKeySz :
6112
0
                                                               ctx->minEccKeySz;
6113
0
                *keySz = ED448_KEY_SIZE;
6114
0
                if (*keySz < minKeySz) {
6115
0
                    WOLFSSL_MSG("ED448 private key too small");
6116
0
                    ret = ECC_KEY_SIZE_E;
6117
0
                }
6118
0
            }
6119
0
            if (ret == 0) {
6120
0
                if (ssl) {
6121
0
                    ssl->buffers.keyType = ed448_sa_algo;
6122
0
                    ssl->buffers.keySz = *keySz;
6123
0
                }
6124
0
                else if (ctx) {
6125
0
                    ctx->privateKeyType = ed448_sa_algo;
6126
0
                    ctx->privateKeySz = *keySz;
6127
0
                }
6128
6129
0
                *keyFormat = ED448k;
6130
0
                if (ssl != NULL) {
6131
                    /* ED448 requires caching enabled for tracking message
6132
                     * hash used in EdDSA_Update for signing */
6133
0
                    ssl->options.cacheMessages = 1;
6134
0
                    if (ssl->options.side == WOLFSSL_SERVER_END) {
6135
0
                        *resetSuites = 1;
6136
0
                    }
6137
0
                }
6138
0
            }
6139
6140
0
            wc_ed448_free(key);
6141
0
        }
6142
6143
0
    #ifdef WOLFSSL_SMALL_STACK
6144
0
        XFREE(key, heap, DYNAMIC_TYPE_ED448);
6145
0
    #endif
6146
0
        if (ret != 0)
6147
0
            return ret;
6148
0
    }
6149
0
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
6150
#if defined(HAVE_PQC)
6151
#if defined(HAVE_FALCON)
6152
    if (((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
6153
         (*keyFormat == FALCON_LEVEL5k))) {
6154
        /* make sure Falcon key can be used */
6155
        falcon_key* key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap,
6156
                                               DYNAMIC_TYPE_FALCON);
6157
        if (key == NULL) {
6158
            return MEMORY_E;
6159
        }
6160
        ret = wc_falcon_init(key);
6161
        if (ret == 0) {
6162
            if (*keyFormat == FALCON_LEVEL1k) {
6163
                ret = wc_falcon_set_level(key, 1);
6164
            }
6165
            else if (*keyFormat == FALCON_LEVEL5k) {
6166
                ret = wc_falcon_set_level(key, 5);
6167
            }
6168
            else {
6169
                /* What if *keyformat is 0? We might want to do something more
6170
                 * graceful here. */
6171
                wc_falcon_free(key);
6172
                ret = ALGO_ID_E;
6173
            }
6174
        }
6175
6176
        if (ret == 0) {
6177
            *idx = 0;
6178
            ret = wc_falcon_import_private_only(der->buffer, der->length, key);
6179
            if (ret == 0) {
6180
                /* check for minimum key size and then free */
6181
                int minKeySz = ssl ? ssl->options.minFalconKeySz :
6182
                                     ctx->minFalconKeySz;
6183
                *keySz = FALCON_MAX_KEY_SIZE;
6184
                if (*keySz < minKeySz) {
6185
                    WOLFSSL_MSG("Falcon private key too small");
6186
                    ret = FALCON_KEY_SIZE_E;
6187
                }
6188
                if (ssl) {
6189
                    if (*keyFormat == FALCON_LEVEL1k) {
6190
                        ssl->buffers.keyType = falcon_level1_sa_algo;
6191
                    }
6192
                    else {
6193
                        ssl->buffers.keyType = falcon_level5_sa_algo;
6194
                    }
6195
                    ssl->buffers.keySz = *keySz;
6196
                }
6197
                else {
6198
                    if (*keyFormat == FALCON_LEVEL1k) {
6199
                        ctx->privateKeyType = falcon_level1_sa_algo;
6200
                    }
6201
                    else {
6202
                        ctx->privateKeyType = falcon_level5_sa_algo;
6203
                    }
6204
                    ctx->privateKeySz = *keySz;
6205
                }
6206
6207
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
6208
                    *resetSuites = 1;
6209
                }
6210
            }
6211
            wc_falcon_free(key);
6212
        }
6213
        XFREE(key, heap, DYNAMIC_TYPE_FALCON);
6214
        if (ret != 0)
6215
            return ret;
6216
    }
6217
#endif /* HAVE_FALCON */
6218
#if defined(HAVE_DILITHIUM)
6219
    if ((*keyFormat == 0) ||
6220
        (*keyFormat == DILITHIUM_LEVEL2k) ||
6221
        (*keyFormat == DILITHIUM_LEVEL3k) ||
6222
        (*keyFormat == DILITHIUM_LEVEL5k) ||
6223
        (*keyFormat == DILITHIUM_AES_LEVEL2k) ||
6224
        (*keyFormat == DILITHIUM_AES_LEVEL3k) ||
6225
        (*keyFormat == DILITHIUM_AES_LEVEL5k)) {
6226
        /* make sure Dilithium key can be used */
6227
        dilithium_key* key = (dilithium_key*)XMALLOC(sizeof(dilithium_key),
6228
                                                     heap,
6229
                                                     DYNAMIC_TYPE_DILITHIUM);
6230
        if (key == NULL) {
6231
            return MEMORY_E;
6232
        }
6233
        ret = wc_dilithium_init(key);
6234
        if (ret == 0) {
6235
            if (*keyFormat == DILITHIUM_LEVEL2k) {
6236
                ret = wc_dilithium_set_level_and_sym(key, 2, SHAKE_VARIANT);
6237
            }
6238
            else if (*keyFormat == DILITHIUM_LEVEL3k) {
6239
                ret = wc_dilithium_set_level_and_sym(key, 3, SHAKE_VARIANT);
6240
            }
6241
            else if (*keyFormat == DILITHIUM_LEVEL5k) {
6242
                ret = wc_dilithium_set_level_and_sym(key, 5, SHAKE_VARIANT);
6243
            }
6244
            else if (*keyFormat == DILITHIUM_AES_LEVEL2k) {
6245
                ret = wc_dilithium_set_level_and_sym(key, 2, AES_VARIANT);
6246
            }
6247
            else if (*keyFormat == DILITHIUM_AES_LEVEL3k) {
6248
                ret = wc_dilithium_set_level_and_sym(key, 3, AES_VARIANT);
6249
            }
6250
            else if (*keyFormat == DILITHIUM_AES_LEVEL5k) {
6251
                ret = wc_dilithium_set_level_and_sym(key, 5, AES_VARIANT);
6252
            }
6253
            else {
6254
                /* What if *keyformat is 0? We might want to do something more
6255
                 * graceful here. */
6256
                wc_dilithium_free(key);
6257
                ret = ALGO_ID_E;
6258
            }
6259
        }
6260
6261
        if (ret == 0) {
6262
            *idx = 0;
6263
            ret = wc_dilithium_import_private_only(der->buffer, der->length,
6264
                                                   key);
6265
            if (ret == 0) {
6266
                /* check for minimum key size and then free */
6267
                int minKeySz = ssl ? ssl->options.minDilithiumKeySz :
6268
                                     ctx->minDilithiumKeySz;
6269
                *keySz = DILITHIUM_MAX_KEY_SIZE;
6270
                if (*keySz < minKeySz) {
6271
                    WOLFSSL_MSG("Dilithium private key too small");
6272
                    ret = DILITHIUM_KEY_SIZE_E;
6273
                }
6274
                if (ssl) {
6275
                    if (*keyFormat == DILITHIUM_LEVEL2k) {
6276
                        ssl->buffers.keyType = dilithium_level2_sa_algo;
6277
                    }
6278
                    else if (*keyFormat == DILITHIUM_LEVEL3k) {
6279
                        ssl->buffers.keyType = dilithium_level3_sa_algo;
6280
                    }
6281
                    else if (*keyFormat == DILITHIUM_LEVEL5k) {
6282
                        ssl->buffers.keyType = dilithium_level5_sa_algo;
6283
                    }
6284
                    else if (*keyFormat == DILITHIUM_AES_LEVEL2k) {
6285
                        ssl->buffers.keyType = dilithium_aes_level2_sa_algo;
6286
                    }
6287
                    else if (*keyFormat == DILITHIUM_AES_LEVEL3k) {
6288
                        ssl->buffers.keyType = dilithium_aes_level3_sa_algo;
6289
                    }
6290
                    else if (*keyFormat == DILITHIUM_AES_LEVEL5k) {
6291
                        ssl->buffers.keyType = dilithium_aes_level5_sa_algo;
6292
                    }
6293
                    ssl->buffers.keySz = *keySz;
6294
                }
6295
                else {
6296
                    if (*keyFormat == DILITHIUM_LEVEL2k) {
6297
                        ctx->privateKeyType = dilithium_level2_sa_algo;
6298
                    }
6299
                    else if (*keyFormat == DILITHIUM_LEVEL3k) {
6300
                        ctx->privateKeyType = dilithium_level3_sa_algo;
6301
                    }
6302
                    else if (*keyFormat == DILITHIUM_LEVEL5k) {
6303
                        ctx->privateKeyType = dilithium_level5_sa_algo;
6304
                    }
6305
                    else if (*keyFormat == DILITHIUM_AES_LEVEL2k) {
6306
                        ctx->privateKeyType = dilithium_aes_level2_sa_algo;
6307
                    }
6308
                    else if (*keyFormat == DILITHIUM_AES_LEVEL3k) {
6309
                        ctx->privateKeyType = dilithium_aes_level3_sa_algo;
6310
                    }
6311
                    else if (*keyFormat == DILITHIUM_AES_LEVEL5k) {
6312
                        ctx->privateKeyType = dilithium_aes_level5_sa_algo;
6313
                    }
6314
                    ctx->privateKeySz = *keySz;
6315
                }
6316
6317
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
6318
                    *resetSuites = 1;
6319
                }
6320
            }
6321
            wc_dilithium_free(key);
6322
        }
6323
        XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM);
6324
        if (ret != 0) {
6325
            return ret;
6326
        }
6327
    }
6328
#endif /* HAVE_DILITHIUM */
6329
#endif /* HAVE_PQC */
6330
0
    return ret;
6331
0
}
6332
6333
/* process the buffer buff, length sz, into ctx of format and type
6334
   used tracks bytes consumed, userChain specifies a user cert chain
6335
   to pass during the handshake */
6336
int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
6337
                         long sz, int format, int type, WOLFSSL* ssl,
6338
                         long* used, int userChain, int verify)
6339
0
{
6340
0
    DerBuffer*    der = NULL;
6341
0
    int           ret = 0;
6342
0
    int           done = 0;
6343
0
    int           keyFormat = 0;
6344
0
    int           resetSuites = 0;
6345
0
    void*         heap = wolfSSL_CTX_GetHeap(ctx, ssl);
6346
0
    int           devId = wolfSSL_CTX_GetDevId(ctx, ssl);
6347
0
    word32        idx = 0;
6348
0
    int           keySz = 0;
6349
0
#if (defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)) || \
6350
0
     defined(HAVE_PKCS8)
6351
0
    word32        algId = 0;
6352
0
#endif
6353
0
#ifdef WOLFSSL_SMALL_STACK
6354
0
    EncryptedInfo* info = NULL;
6355
#else
6356
    EncryptedInfo  info[1];
6357
#endif
6358
6359
0
    (void)devId;
6360
0
    (void)idx;
6361
0
    (void)keySz;
6362
6363
0
    if (used)
6364
0
        *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
6365
6366
    /* check args */
6367
0
    if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
6368
0
        return WOLFSSL_BAD_FILETYPE;
6369
6370
0
    if (ctx == NULL && ssl == NULL)
6371
0
        return BAD_FUNC_ARG;
6372
6373
0
#ifdef WOLFSSL_SMALL_STACK
6374
0
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
6375
0
                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
6376
0
    if (info == NULL)
6377
0
        return MEMORY_E;
6378
0
#endif
6379
6380
0
    XMEMSET(info, 0, sizeof(EncryptedInfo));
6381
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
6382
    if (ctx) {
6383
        info->passwd_cb       = ctx->passwd_cb;
6384
        info->passwd_userdata = ctx->passwd_userdata;
6385
    }
6386
#endif
6387
6388
0
    if (format == WOLFSSL_FILETYPE_PEM) {
6389
0
    #ifdef WOLFSSL_PEM_TO_DER
6390
0
        ret = PemToDer(buff, sz, type, &der, heap, info, &keyFormat);
6391
    #else
6392
        ret = NOT_COMPILED_IN;
6393
    #endif
6394
0
    }
6395
0
    else {
6396
        /* ASN1 (DER) */
6397
0
        int length = (int)sz;
6398
0
        if (format == WOLFSSL_FILETYPE_ASN1) {
6399
            /* get length of der (read sequence or octet string) */
6400
0
            word32 inOutIdx = 0;
6401
0
            if (GetSequence(buff, &inOutIdx, &length, (word32)sz) >= 0) {
6402
0
                length += inOutIdx; /* include leading sequence */
6403
0
            }
6404
            /* get length using octect string (allowed for private key types) */
6405
0
            else if (type == PRIVATEKEY_TYPE &&
6406
0
                    GetOctetString(buff, &inOutIdx, &length, (word32)sz) >= 0) {
6407
0
                length += inOutIdx; /* include leading oct string */
6408
0
            }
6409
0
            else {
6410
0
                ret = ASN_PARSE_E;
6411
0
            }
6412
0
        }
6413
6414
0
        info->consumed = length;
6415
6416
0
        if (ret == 0) {
6417
0
            ret = AllocDer(&der, (word32)length, type, heap);
6418
0
            if (ret == 0) {
6419
0
                XMEMCPY(der->buffer, buff, length);
6420
0
            }
6421
6422
0
        #ifdef HAVE_PKCS8
6423
            /* if private key try and remove PKCS8 header */
6424
0
            if (type == PRIVATEKEY_TYPE) {
6425
0
                if ((ret = ToTraditional_ex(der->buffer, der->length,
6426
0
                                                                 &algId)) > 0) {
6427
                    /* Found PKCS8 header */
6428
                    /* ToTraditional_ex moves buff and returns adjusted length */
6429
0
                    der->length = ret;
6430
0
                    keyFormat = algId;
6431
0
                }
6432
0
                ret = 0; /* failures should be ignored */
6433
0
            }
6434
0
        #endif
6435
0
        }
6436
0
    }
6437
6438
0
    if (used) {
6439
0
        *used = info->consumed;
6440
0
    }
6441
6442
    /* process user chain */
6443
0
    if (ret >= 0) {
6444
        /* Chain should have server cert first, then intermediates, then root.
6445
         * First certificate in chain is processed below after ProcessUserChain
6446
         *   and is loaded into ssl->buffers.certificate.
6447
         * Remainder are processed using ProcessUserChain and are loaded into
6448
         *   ssl->buffers.certChain. */
6449
0
        if (userChain) {
6450
0
            ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info,
6451
0
                                   verify);
6452
0
            if (ret == ASN_NO_PEM_HEADER) { /* Additional chain is optional */
6453
0
                unsigned long pemErr;
6454
0
                CLEAR_ASN_NO_PEM_HEADER_ERROR(pemErr);
6455
0
                ret = 0;
6456
0
            }
6457
0
        }
6458
0
    }
6459
6460
    /* info is only used for private key with DER or PEM, so free now */
6461
0
    if (ret < 0 || type != PRIVATEKEY_TYPE) {
6462
0
    #ifdef WOLFSSL_SMALL_STACK
6463
0
        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6464
0
    #endif
6465
0
    }
6466
6467
    /* check for error */
6468
0
    if (ret < 0) {
6469
0
        FreeDer(&der);
6470
0
        done = 1;
6471
0
    }
6472
6473
0
    if (done == 1) {
6474
        /* No operation, just skip the next section */
6475
0
    }
6476
    /* Handle DER owner */
6477
0
    else if (type == CA_TYPE) {
6478
0
        if (ctx == NULL) {
6479
0
            WOLFSSL_MSG("Need context for CA load");
6480
0
            FreeDer(&der);
6481
0
            return BAD_FUNC_ARG;
6482
0
        }
6483
        /* verify CA unless user set to no verify */
6484
0
        ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
6485
0
        done = 1;
6486
0
    }
6487
#ifdef WOLFSSL_TRUST_PEER_CERT
6488
    else if (type == TRUSTED_PEER_TYPE) {
6489
        /* add trusted peer cert. der is freed within */
6490
        if (ctx != NULL)
6491
            ret = AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
6492
        else
6493
            ret = AddTrustedPeer(SSL_CM(ssl), &der, !ssl->options.verifyNone);
6494
        if (ret != WOLFSSL_SUCCESS) {
6495
            WOLFSSL_MSG("Error adding trusted peer");
6496
        }
6497
        done = 1;
6498
    }
6499
#endif /* WOLFSSL_TRUST_PEER_CERT */
6500
0
    else if (type == CERT_TYPE) {
6501
0
        if (ssl != NULL) {
6502
             /* Make sure previous is free'd */
6503
0
            if (ssl->buffers.weOwnCert) {
6504
0
                FreeDer(&ssl->buffers.certificate);
6505
            #ifdef KEEP_OUR_CERT
6506
                wolfSSL_X509_free(ssl->ourCert);
6507
                ssl->ourCert = NULL;
6508
            #endif
6509
0
            }
6510
0
            ssl->buffers.certificate = der;
6511
        #ifdef KEEP_OUR_CERT
6512
            ssl->keepCert = 1; /* hold cert for ssl lifetime */
6513
        #endif
6514
0
            ssl->buffers.weOwnCert = 1;
6515
0
        }
6516
0
        else if (ctx != NULL) {
6517
0
            FreeDer(&ctx->certificate); /* Make sure previous is free'd */
6518
        #ifdef KEEP_OUR_CERT
6519
            if (ctx->ourCert) {
6520
                if (ctx->ownOurCert)
6521
                    wolfSSL_X509_free(ctx->ourCert);
6522
                ctx->ourCert = NULL;
6523
            }
6524
        #endif
6525
0
            ctx->certificate = der;
6526
0
        }
6527
0
    }
6528
0
    else if (type == PRIVATEKEY_TYPE) {
6529
0
        if (ssl != NULL) {
6530
             /* Make sure previous is free'd */
6531
0
            if (ssl->buffers.weOwnKey) {
6532
0
                ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
6533
0
                FreeDer(&ssl->buffers.key);
6534
0
            }
6535
0
            ssl->buffers.key = der;
6536
#ifdef WOLFSSL_CHECK_MEM_ZERO
6537
            wc_MemZero_Add("SSL Buffers key", der->buffer, der->length);
6538
#endif
6539
0
            ssl->buffers.weOwnKey = 1;
6540
0
        }
6541
0
        else if (ctx != NULL) {
6542
0
            if (ctx->privateKey != NULL && ctx->privateKey->buffer != NULL) {
6543
0
                ForceZero(ctx->privateKey->buffer, ctx->privateKey->length);
6544
0
            }
6545
0
            FreeDer(&ctx->privateKey);
6546
0
            ctx->privateKey = der;
6547
#ifdef WOLFSSL_CHECK_MEM_ZERO
6548
            wc_MemZero_Add("CTX private key", der->buffer, der->length);
6549
#endif
6550
0
        }
6551
0
    }
6552
0
    else {
6553
0
        FreeDer(&der);
6554
0
        return WOLFSSL_BAD_CERTTYPE;
6555
0
    }
6556
6557
0
    if (done == 1) {
6558
        /* No operation, just skip the next section */
6559
0
    }
6560
0
    else if (type == PRIVATEKEY_TYPE) {
6561
0
        ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites,
6562
0
                &keyFormat, heap, devId);
6563
6564
    #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
6565
        /* for WOLFSSL_FILETYPE_PEM, PemToDer manages the decryption */
6566
        /* If private key type PKCS8 header wasn't already removed (algoId == 0) */
6567
        if ((ret != 0 || keyFormat == 0)
6568
            && format != WOLFSSL_FILETYPE_PEM && info->passwd_cb && algId == 0)
6569
        {
6570
            int   passwordSz = NAME_SZ;
6571
        #ifndef WOLFSSL_SMALL_STACK
6572
            char  password[NAME_SZ];
6573
        #else
6574
            char* password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
6575
            if (password == NULL) {
6576
                XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6577
                FreeDer(&der);
6578
                return MEMORY_E;
6579
            }
6580
        #endif
6581
            /* get password */
6582
            ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
6583
                info->passwd_userdata);
6584
            if (ret >= 0) {
6585
                passwordSz = ret;
6586
            #ifdef WOLFSSL_CHECK_MEM_ZERO
6587
                wc_MemZero_Add("ProcessBuffer password", password, passwordSz);
6588
            #endif
6589
6590
                /* PKCS8 decrypt */
6591
                ret = ToTraditionalEnc(der->buffer, der->length,
6592
                                       password, passwordSz, &algId);
6593
                if (ret >= 0) {
6594
                    ForceZero(der->buffer + ret, der->length - ret);
6595
                    der->length = ret;
6596
                }
6597
                /* ignore failures and try parsing as unencrypted */
6598
6599
                ForceZero(password, passwordSz);
6600
            }
6601
6602
        #ifdef WOLFSSL_SMALL_STACK
6603
            XFREE(password, heap, DYNAMIC_TYPE_STRING);
6604
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
6605
            wc_MemZero_Check(password, NAME_SZ);
6606
        #endif
6607
            ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx,
6608
                &resetSuites, &keyFormat, heap, devId);
6609
        }
6610
    #endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
6611
6612
0
    #ifdef WOLFSSL_SMALL_STACK
6613
0
        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6614
0
    #endif
6615
6616
0
        if (ret != 0)
6617
0
            return ret;
6618
0
        if (keyFormat == 0) {
6619
#ifdef OPENSSL_EXTRA
6620
            /* Reaching this point probably means that the
6621
             * decryption password is wrong */
6622
            if (info->passwd_cb)
6623
                EVPerr(0, EVP_R_BAD_DECRYPT);
6624
#endif
6625
0
            WOLFSSL_ERROR(WOLFSSL_BAD_FILE);
6626
0
            return WOLFSSL_BAD_FILE;
6627
0
        }
6628
6629
0
        (void)devId;
6630
0
    }
6631
0
    else if (type == CERT_TYPE) {
6632
0
    #ifdef WOLFSSL_SMALL_STACK
6633
0
        DecodedCert* cert;
6634
    #else
6635
        DecodedCert  cert[1];
6636
    #endif
6637
0
    #ifdef WOLF_PRIVATE_KEY_ID
6638
0
        int keyType = 0;
6639
0
    #endif
6640
6641
0
    #ifdef WOLFSSL_SMALL_STACK
6642
0
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
6643
0
                                     DYNAMIC_TYPE_DCERT);
6644
0
        if (cert == NULL)
6645
0
            return MEMORY_E;
6646
0
    #endif
6647
6648
0
        WOLFSSL_MSG("Checking cert signature type");
6649
0
        InitDecodedCert(cert, der->buffer, der->length, heap);
6650
6651
0
        if (DecodeToKey(cert, 0) < 0) {
6652
0
            WOLFSSL_MSG("Decode to key failed");
6653
0
            FreeDecodedCert(cert);
6654
0
        #ifdef WOLFSSL_SMALL_STACK
6655
0
            XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
6656
0
        #endif
6657
0
            return WOLFSSL_BAD_FILE;
6658
0
        }
6659
6660
0
        if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
6661
0
            resetSuites = 1;
6662
0
        }
6663
0
        if (ssl && ssl->ctx->haveECDSAsig) {
6664
0
            WOLFSSL_MSG("SSL layer setting cert, CTX had ECDSA, turning off");
6665
0
            ssl->options.haveECDSAsig = 0;   /* may turn back on next */
6666
0
        }
6667
6668
0
        switch (cert->signatureOID) {
6669
0
            case CTC_SHAwECDSA:
6670
0
            case CTC_SHA256wECDSA:
6671
0
            case CTC_SHA384wECDSA:
6672
0
            case CTC_SHA512wECDSA:
6673
0
            case CTC_ED25519:
6674
0
            case CTC_ED448:
6675
0
                WOLFSSL_MSG("ECDSA/ED25519/ED448 cert signature");
6676
0
                if (ssl)
6677
0
                    ssl->options.haveECDSAsig = 1;
6678
0
                else if (ctx)
6679
0
                    ctx->haveECDSAsig = 1;
6680
0
                break;
6681
0
            case CTC_FALCON_LEVEL1:
6682
0
            case CTC_FALCON_LEVEL5:
6683
0
                WOLFSSL_MSG("Falcon cert signature");
6684
0
                if (ssl)
6685
0
                    ssl->options.haveFalconSig = 1;
6686
0
                else if (ctx)
6687
0
                    ctx->haveFalconSig = 1;
6688
0
                break;
6689
0
            case CTC_DILITHIUM_LEVEL2:
6690
0
            case CTC_DILITHIUM_LEVEL3:
6691
0
            case CTC_DILITHIUM_LEVEL5:
6692
0
            case CTC_DILITHIUM_AES_LEVEL2:
6693
0
            case CTC_DILITHIUM_AES_LEVEL3:
6694
0
            case CTC_DILITHIUM_AES_LEVEL5:
6695
0
                WOLFSSL_MSG("Dilithium cert signature");
6696
0
                if (ssl)
6697
0
                    ssl->options.haveDilithiumSig = 1;
6698
0
                else if (ctx)
6699
0
                    ctx->haveDilithiumSig = 1;
6700
0
                break;
6701
0
            default:
6702
0
                WOLFSSL_MSG("Not ECDSA cert signature");
6703
0
                break;
6704
0
        }
6705
6706
0
    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
6707
0
        (defined(HAVE_PQC) && defined(HAVE_LIBOQS)) || !defined(NO_RSA)
6708
0
        if (ssl) {
6709
0
        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
6710
0
            (defined(HAVE_CURVE448) && defined(HAVE_ED448))
6711
0
            ssl->pkCurveOID = cert->pkCurveOID;
6712
0
        #endif
6713
0
        #ifndef WC_STRICT_SIG
6714
0
            if (cert->keyOID == ECDSAk) {
6715
0
                ssl->options.haveECC = 1;
6716
0
            }
6717
0
            #ifndef NO_RSA
6718
0
            else if (cert->keyOID == RSAk) {
6719
0
                ssl->options.haveRSA = 1;
6720
0
            }
6721
0
            #ifdef WC_RSA_PSS
6722
0
            else if (cert->keyOID == RSAPSSk) {
6723
0
                ssl->options.haveRSA = 1;
6724
0
            }
6725
0
            #endif
6726
0
            #endif
6727
0
            #ifdef HAVE_ED25519
6728
0
                else if (cert->keyOID == ED25519k) {
6729
0
                    ssl->options.haveECC = 1;
6730
0
                }
6731
0
            #endif
6732
0
            #ifdef HAVE_ED448
6733
0
                else if (cert->keyOID == ED448k) {
6734
0
                    ssl->options.haveECC = 1;
6735
0
                }
6736
0
            #endif
6737
            #ifdef HAVE_PQC
6738
            #ifdef HAVE_FALCON
6739
                else if (cert->keyOID == FALCON_LEVEL1k ||
6740
                         cert->keyOID == FALCON_LEVEL5k) {
6741
                    ssl->options.haveFalconSig = 1;
6742
                }
6743
            #endif /* HAVE_FALCON */
6744
            #ifdef HAVE_DILITHIUM
6745
                else if (cert->keyOID == DILITHIUM_LEVEL2k ||
6746
                         cert->keyOID == DILITHIUM_LEVEL3k ||
6747
                         cert->keyOID == DILITHIUM_LEVEL5k ||
6748
                         cert->keyOID == DILITHIUM_AES_LEVEL2k ||
6749
                         cert->keyOID == DILITHIUM_AES_LEVEL3k ||
6750
                         cert->keyOID == DILITHIUM_AES_LEVEL5k) {
6751
                    ssl->options.haveDilithiumSig = 1;
6752
                }
6753
            #endif /* HAVE_DILITHIUM */
6754
            #endif /* HAVE_PQC */
6755
        #else
6756
            ssl->options.haveECC = ssl->options.haveECDSAsig;
6757
        #endif
6758
0
        }
6759
0
        else if (ctx) {
6760
0
        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
6761
0
            ctx->pkCurveOID = cert->pkCurveOID;
6762
0
        #endif
6763
0
        #ifndef WC_STRICT_SIG
6764
0
            if (cert->keyOID == ECDSAk) {
6765
0
                ctx->haveECC = 1;
6766
0
            }
6767
0
            #ifndef NO_RSA
6768
0
            else if (cert->keyOID == RSAk) {
6769
0
                ctx->haveRSA = 1;
6770
0
            }
6771
0
            #ifdef WC_RSA_PSS
6772
0
            else if (cert->keyOID == RSAPSSk) {
6773
0
                ctx->haveRSA = 1;
6774
0
            }
6775
0
            #endif
6776
0
            #endif
6777
0
            #ifdef HAVE_ED25519
6778
0
                else if (cert->keyOID == ED25519k) {
6779
0
                    ctx->haveECC = 1;
6780
0
                }
6781
0
            #endif
6782
0
            #ifdef HAVE_ED448
6783
0
                else if (cert->keyOID == ED448k) {
6784
0
                    ctx->haveECC = 1;
6785
0
                }
6786
0
            #endif
6787
            #ifdef HAVE_PQC
6788
            #ifdef HAVE_FALCON
6789
                else if (cert->keyOID == FALCON_LEVEL1k ||
6790
                         cert->keyOID == FALCON_LEVEL5k) {
6791
                    ctx->haveFalconSig = 1;
6792
                }
6793
            #endif /* HAVE_FALCON */
6794
            #ifdef HAVE_DILITHIUM
6795
                else if (cert->keyOID == DILITHIUM_LEVEL2k ||
6796
                         cert->keyOID == DILITHIUM_LEVEL3k ||
6797
                         cert->keyOID == DILITHIUM_LEVEL5k ||
6798
                         cert->keyOID == DILITHIUM_AES_LEVEL2k ||
6799
                         cert->keyOID == DILITHIUM_AES_LEVEL3k ||
6800
                         cert->keyOID == DILITHIUM_AES_LEVEL5k) {
6801
                    ctx->haveDilithiumSig = 1;
6802
                }
6803
            #endif /* HAVE_DILITHIUM */
6804
            #endif /* HAVE_PQC */
6805
        #else
6806
            ctx->haveECC = ctx->haveECDSAsig;
6807
        #endif
6808
0
        }
6809
0
    #endif
6810
6811
        /* check key size of cert unless specified not to */
6812
0
        switch (cert->keyOID) {
6813
0
        #ifndef NO_RSA
6814
0
            #ifdef WC_RSA_PSS
6815
0
            case RSAPSSk:
6816
0
            #endif
6817
0
            case RSAk:
6818
0
            #ifdef WOLF_PRIVATE_KEY_ID
6819
0
                keyType = rsa_sa_algo;
6820
0
            #endif
6821
                /* Determine RSA key size by parsing public key */
6822
0
                idx = 0;
6823
0
                ret = wc_RsaPublicKeyDecode_ex(cert->publicKey, &idx,
6824
0
                    cert->pubKeySize, NULL, (word32*)&keySz, NULL, NULL);
6825
0
                if (ret < 0)
6826
0
                    break;
6827
6828
0
                if (ssl && !ssl->options.verifyNone) {
6829
0
                    if (ssl->options.minRsaKeySz < 0 ||
6830
0
                          keySz < (int)ssl->options.minRsaKeySz ||
6831
0
                          keySz > (RSA_MAX_SIZE / 8)) {
6832
0
                        ret = RSA_KEY_SIZE_E;
6833
0
                        WOLFSSL_MSG("Certificate RSA key size too small");
6834
0
                    }
6835
0
                }
6836
0
                else if (ctx && !ctx->verifyNone) {
6837
0
                    if (ctx->minRsaKeySz < 0 ||
6838
0
                            keySz < (int)ctx->minRsaKeySz ||
6839
0
                            keySz > (RSA_MAX_SIZE / 8)) {
6840
0
                        ret = RSA_KEY_SIZE_E;
6841
0
                        WOLFSSL_MSG("Certificate RSA key size too small");
6842
0
                    }
6843
0
                }
6844
0
                break;
6845
0
        #endif /* !NO_RSA */
6846
0
        #ifdef HAVE_ECC
6847
0
            case ECDSAk:
6848
0
            #ifdef WOLF_PRIVATE_KEY_ID
6849
0
                keyType = ecc_dsa_sa_algo;
6850
0
            #endif
6851
                /* Determine ECC key size based on curve */
6852
0
                keySz = wc_ecc_get_curve_size_from_id(
6853
0
                    wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL));
6854
6855
0
                if (ssl && !ssl->options.verifyNone) {
6856
0
                    if (ssl->options.minEccKeySz < 0 ||
6857
0
                          keySz < (int)ssl->options.minEccKeySz) {
6858
0
                        ret = ECC_KEY_SIZE_E;
6859
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6860
0
                    }
6861
0
                }
6862
0
                else if (ctx && !ctx->verifyNone) {
6863
0
                    if (ctx->minEccKeySz < 0 ||
6864
0
                                  keySz < (int)ctx->minEccKeySz) {
6865
0
                        ret = ECC_KEY_SIZE_E;
6866
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6867
0
                    }
6868
0
                }
6869
0
                break;
6870
0
        #endif /* HAVE_ECC */
6871
0
        #ifdef HAVE_ED25519
6872
0
            case ED25519k:
6873
0
            #ifdef WOLF_PRIVATE_KEY_ID
6874
0
                keyType = ed25519_sa_algo;
6875
0
            #endif
6876
                /* ED25519 is fixed key size */
6877
0
                keySz = ED25519_KEY_SIZE;
6878
0
                if (ssl && !ssl->options.verifyNone) {
6879
0
                    if (ssl->options.minEccKeySz < 0 ||
6880
0
                          keySz < (int)ssl->options.minEccKeySz) {
6881
0
                        ret = ECC_KEY_SIZE_E;
6882
0
                        WOLFSSL_MSG("Certificate Ed key size error");
6883
0
                    }
6884
0
                }
6885
0
                else if (ctx && !ctx->verifyNone) {
6886
0
                    if (ctx->minEccKeySz < 0 ||
6887
0
                                  keySz < (int)ctx->minEccKeySz) {
6888
0
                        ret = ECC_KEY_SIZE_E;
6889
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6890
0
                    }
6891
0
                }
6892
0
                break;
6893
0
        #endif /* HAVE_ED25519 */
6894
0
        #ifdef HAVE_ED448
6895
0
            case ED448k:
6896
0
            #ifdef WOLF_PRIVATE_KEY_ID
6897
0
                keyType = ed448_sa_algo;
6898
0
            #endif
6899
                /* ED448 is fixed key size */
6900
0
                keySz = ED448_KEY_SIZE;
6901
0
                if (ssl && !ssl->options.verifyNone) {
6902
0
                    if (ssl->options.minEccKeySz < 0 ||
6903
0
                          keySz < (int)ssl->options.minEccKeySz) {
6904
0
                        ret = ECC_KEY_SIZE_E;
6905
0
                        WOLFSSL_MSG("Certificate Ed key size error");
6906
0
                    }
6907
0
                }
6908
0
                else if (ctx && !ctx->verifyNone) {
6909
0
                    if (ctx->minEccKeySz < 0 ||
6910
0
                                  keySz < (int)ctx->minEccKeySz) {
6911
0
                        ret = ECC_KEY_SIZE_E;
6912
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6913
0
                    }
6914
0
                }
6915
0
                break;
6916
0
        #endif /* HAVE_ED448 */
6917
        #if defined(HAVE_PQC)
6918
        #if defined(HAVE_FALCON)
6919
            case FALCON_LEVEL1k:
6920
            case FALCON_LEVEL5k:
6921
                /* Falcon is fixed key size */
6922
                keySz = FALCON_MAX_KEY_SIZE;
6923
                if (ssl && !ssl->options.verifyNone) {
6924
                    if (ssl->options.minFalconKeySz < 0 ||
6925
                          keySz < (int)ssl->options.minFalconKeySz) {
6926
                        ret = FALCON_KEY_SIZE_E;
6927
                        WOLFSSL_MSG("Certificate Falcon key size error");
6928
                    }
6929
                }
6930
                else if (ctx && !ctx->verifyNone) {
6931
                    if (ctx->minFalconKeySz < 0 ||
6932
                                  keySz < (int)ctx->minFalconKeySz) {
6933
                        ret = FALCON_KEY_SIZE_E;
6934
                        WOLFSSL_MSG("Certificate Falcon key size error");
6935
                    }
6936
                }
6937
                break;
6938
        #endif /* HAVE_FALCON */
6939
        #if defined(HAVE_DILITHIUM)
6940
            case DILITHIUM_LEVEL2k:
6941
            case DILITHIUM_LEVEL3k:
6942
            case DILITHIUM_LEVEL5k:
6943
            case DILITHIUM_AES_LEVEL2k:
6944
            case DILITHIUM_AES_LEVEL3k:
6945
            case DILITHIUM_AES_LEVEL5k:
6946
                /* Dilithium is fixed key size */
6947
                keySz = DILITHIUM_MAX_KEY_SIZE;
6948
                if (ssl && !ssl->options.verifyNone) {
6949
                    if (ssl->options.minDilithiumKeySz < 0 ||
6950
                          keySz < (int)ssl->options.minDilithiumKeySz) {
6951
                        ret = DILITHIUM_KEY_SIZE_E;
6952
                        WOLFSSL_MSG("Certificate Dilithium key size error");
6953
                    }
6954
                }
6955
                else if (ctx && !ctx->verifyNone) {
6956
                    if (ctx->minDilithiumKeySz < 0 ||
6957
                                  keySz < (int)ctx->minDilithiumKeySz) {
6958
                        ret = DILITHIUM_KEY_SIZE_E;
6959
                        WOLFSSL_MSG("Certificate Dilithium key size error");
6960
                    }
6961
                }
6962
                break;
6963
        #endif /* HAVE_DILITHIUM */
6964
        #endif /* HAVE_PQC */
6965
6966
0
            default:
6967
0
                WOLFSSL_MSG("No key size check done on certificate");
6968
0
                break; /* do no check if not a case for the key */
6969
0
        }
6970
6971
0
    #ifdef WOLF_PRIVATE_KEY_ID
6972
0
        if (ssl != NULL && ssl->buffers.keyType == 0) {
6973
0
            ssl->buffers.keyType = keyType;
6974
0
            ssl->buffers.keySz = keySz;
6975
0
        }
6976
0
        else if (ctx != NULL && ctx->privateKeyType == 0) {
6977
0
            ctx->privateKeyType = keyType;
6978
0
            ctx->privateKeySz = keySz;
6979
0
        }
6980
0
    #endif
6981
6982
0
        FreeDecodedCert(cert);
6983
0
    #ifdef WOLFSSL_SMALL_STACK
6984
0
        XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
6985
0
    #endif
6986
6987
0
        if (ret != 0) {
6988
0
            done = 1;
6989
0
        }
6990
0
    }
6991
6992
0
    if (done == 1) {
6993
0
    #if !defined(NO_WOLFSSL_CM_VERIFY) && (!defined(NO_WOLFSSL_CLIENT) || \
6994
0
                                           !defined(WOLFSSL_NO_CLIENT_AUTH))
6995
0
        if ((type == CA_TYPE) || (type == CERT_TYPE)) {
6996
            /* Call to over-ride status */
6997
0
            if ((ctx != NULL) && (ctx->cm != NULL) &&
6998
0
                (ctx->cm->verifyCallback != NULL)) {
6999
0
                ret = CM_VerifyBuffer_ex(ctx->cm, buff,
7000
0
                        sz, format, (ret == WOLFSSL_SUCCESS ? 0 : ret));
7001
0
            }
7002
0
        }
7003
0
    #endif /* NO_WOLFSSL_CM_VERIFY */
7004
7005
0
        return ret;
7006
0
    }
7007
7008
7009
0
    if (ssl && resetSuites) {
7010
0
        word16 havePSK = 0;
7011
0
        word16 haveRSA = 0;
7012
7013
        #ifndef NO_PSK
7014
        if (ssl->options.havePSK) {
7015
            havePSK = 1;
7016
        }
7017
        #endif
7018
0
        #ifndef NO_RSA
7019
0
            haveRSA = 1;
7020
0
        #endif
7021
0
            keySz = ssl->buffers.keySz;
7022
7023
        /* let's reset suites */
7024
0
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
7025
0
                   havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig,
7026
0
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
7027
0
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
7028
0
                   ssl->options.haveAnon, TRUE, ssl->options.side);
7029
0
    }
7030
7031
0
    return WOLFSSL_SUCCESS;
7032
0
}
7033
7034
7035
/* CA PEM file for verification, may have multiple/chain certs to process */
7036
static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
7037
                        long sz, int format, int type, WOLFSSL* ssl, int verify)
7038
0
{
7039
0
    long used   = 0;
7040
0
    int  ret    = 0;
7041
0
    int  gotOne = 0;
7042
7043
0
    WOLFSSL_MSG("Processing CA PEM file");
7044
0
    while (used < sz) {
7045
0
        long consumed = 0;
7046
7047
0
        ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
7048
0
                            &consumed, 0, verify);
7049
7050
0
        if (ret < 0) {
7051
#if defined(WOLFSSL_WPAS) && defined(HAVE_CRL)
7052
            DerBuffer*    der = NULL;
7053
            EncryptedInfo info;
7054
7055
            WOLFSSL_MSG("Trying a CRL");
7056
            if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info,
7057
                                                                   NULL) == 0) {
7058
                WOLFSSL_MSG("   Processed a CRL");
7059
                wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer,
7060
                                            der->length, WOLFSSL_FILETYPE_ASN1);
7061
                FreeDer(&der);
7062
                used += info.consumed;
7063
                continue;
7064
            }
7065
#endif
7066
7067
0
            if (consumed > 0) { /* Made progress in file */
7068
0
                WOLFSSL_ERROR(ret);
7069
0
                WOLFSSL_MSG("CA Parse failed, with progress in file.");
7070
0
                WOLFSSL_MSG("Search for other certs in file");
7071
0
            }
7072
0
            else {
7073
0
                WOLFSSL_MSG("CA Parse failed, no progress in file.");
7074
0
                WOLFSSL_MSG("Do not continue search for other certs in file");
7075
0
                break;
7076
0
            }
7077
0
        }
7078
0
        else {
7079
0
            WOLFSSL_MSG("   Processed a CA");
7080
0
            gotOne = 1;
7081
0
        }
7082
0
        used += consumed;
7083
0
    }
7084
7085
0
    if (gotOne) {
7086
0
        WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
7087
0
        return WOLFSSL_SUCCESS;
7088
0
    }
7089
0
    return ret;
7090
0
}
7091
7092
7093
static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void)
7094
0
{
7095
0
    #ifndef NO_WOLFSSL_CLIENT
7096
        #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
7097
            return wolfSSLv3_client_method();
7098
        #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
7099
            return wolfTLSv1_client_method();
7100
        #elif !defined(NO_OLD_TLS)
7101
0
            return wolfTLSv1_1_client_method();
7102
        #elif !defined(WOLFSSL_NO_TLS12)
7103
            return wolfTLSv1_2_client_method();
7104
        #elif defined(WOLFSSL_TLS13)
7105
            return wolfTLSv1_3_client_method();
7106
        #else
7107
            return NULL;
7108
        #endif
7109
    #elif !defined(NO_WOLFSSL_SERVER)
7110
        #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
7111
            return wolfSSLv3_server_method();
7112
        #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
7113
            return wolfTLSv1_server_method();
7114
        #elif !defined(NO_OLD_TLS)
7115
            return wolfTLSv1_1_server_method();
7116
        #elif !defined(WOLFSSL_NO_TLS12)
7117
            return wolfTLSv1_2_server_method();
7118
        #elif defined(WOLFSSL_TLS13)
7119
            return wolfTLSv1_3_server_method();
7120
        #else
7121
            return NULL;
7122
        #endif
7123
    #else
7124
        return NULL;
7125
    #endif
7126
0
}
7127
7128
7129
/* like load verify locations, 1 for success, < 0 for error */
7130
int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
7131
                                   const unsigned char* in, long sz, int format)
7132
0
{
7133
0
    int ret = WOLFSSL_FATAL_ERROR;
7134
0
    WOLFSSL_CTX* tmp;
7135
7136
0
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
7137
7138
0
    if (cm == NULL) {
7139
0
        WOLFSSL_MSG("No CertManager error");
7140
0
        return ret;
7141
0
    }
7142
0
    tmp = wolfSSL_CTX_new(cm_pick_method());
7143
7144
0
    if (tmp == NULL) {
7145
0
        WOLFSSL_MSG("CTX new failed");
7146
0
        return ret;
7147
0
    }
7148
7149
    /* for tmp use */
7150
0
    wolfSSL_CertManagerFree(tmp->cm);
7151
0
    tmp->cm = cm;
7152
7153
0
    ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
7154
7155
    /* don't loose our good one */
7156
0
    tmp->cm = NULL;
7157
0
    wolfSSL_CTX_free(tmp);
7158
7159
0
    return ret;
7160
0
}
7161
7162
#ifdef HAVE_CRL
7163
7164
int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
7165
                                   const unsigned char* buff, long sz, int type)
7166
{
7167
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
7168
    if (cm == NULL)
7169
        return BAD_FUNC_ARG;
7170
7171
    if (cm->crl == NULL) {
7172
        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
7173
            WOLFSSL_MSG("Enable CRL failed");
7174
            return WOLFSSL_FATAL_ERROR;
7175
        }
7176
    }
7177
7178
    return BufferLoadCRL(cm->crl, buff, sz, type, VERIFY);
7179
}
7180
7181
int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm)
7182
{
7183
    WOLFSSL_ENTER("wolfSSL_CertManagerFreeCRL");
7184
    if (cm == NULL)
7185
        return BAD_FUNC_ARG;
7186
    if (cm->crl != NULL){
7187
        FreeCRL(cm->crl, 1);
7188
        cm->crl = NULL;
7189
    }
7190
    return WOLFSSL_SUCCESS;
7191
}
7192
7193
int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
7194
                              long sz, int type)
7195
{
7196
    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRLBuffer");
7197
7198
    if (ctx == NULL)
7199
        return BAD_FUNC_ARG;
7200
7201
    return wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, buff, sz, type);
7202
}
7203
7204
7205
int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff,
7206
                          long sz, int type)
7207
{
7208
    WOLFSSL_ENTER("wolfSSL_LoadCRLBuffer");
7209
7210
    if (ssl == NULL || ssl->ctx == NULL)
7211
        return BAD_FUNC_ARG;
7212
7213
    return wolfSSL_CertManagerLoadCRLBuffer(SSL_CM(ssl), buff, sz, type);
7214
}
7215
7216
7217
#endif /* HAVE_CRL */
7218
7219
/* turn on CRL if off and compiled in, set options */
7220
int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
7221
0
{
7222
0
    int ret = WOLFSSL_SUCCESS;
7223
7224
0
    (void)options;
7225
7226
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
7227
0
    if (cm == NULL)
7228
0
        return BAD_FUNC_ARG;
7229
7230
    #ifdef HAVE_CRL
7231
        if (cm->crl == NULL) {
7232
            cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
7233
                                            DYNAMIC_TYPE_CRL);
7234
            if (cm->crl == NULL)
7235
                return MEMORY_E;
7236
7237
            if (InitCRL(cm->crl, cm) != 0) {
7238
                WOLFSSL_MSG("Init CRL failed");
7239
                FreeCRL(cm->crl, 1);
7240
                cm->crl = NULL;
7241
                return WOLFSSL_FAILURE;
7242
            }
7243
7244
        #if defined(HAVE_CRL_IO) && defined(USE_WOLFSSL_IO)
7245
            cm->crl->crlIOCb = EmbedCrlLookup;
7246
        #endif
7247
        }
7248
7249
        cm->crlEnabled = 1;
7250
        if (options & WOLFSSL_CRL_CHECKALL)
7251
            cm->crlCheckAll = 1;
7252
    #else
7253
0
        ret = NOT_COMPILED_IN;
7254
0
    #endif
7255
7256
0
    return ret;
7257
0
}
7258
7259
7260
int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
7261
0
{
7262
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
7263
0
    if (cm == NULL)
7264
0
        return BAD_FUNC_ARG;
7265
7266
0
    cm->crlEnabled = 0;
7267
7268
0
    return WOLFSSL_SUCCESS;
7269
0
}
7270
7271
#ifndef NO_WOLFSSL_CM_VERIFY
7272
void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc)
7273
0
{
7274
0
    WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify");
7275
0
    if (cm == NULL)
7276
0
        return;
7277
7278
0
    cm->verifyCallback = vc;
7279
0
}
7280
#endif /* NO_WOLFSSL_CM_VERIFY */
7281
7282
#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
7283
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
7284
int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
7285
                                    long sz, int format, int err_val)
7286
0
{
7287
0
    int ret = 0;
7288
0
    DerBuffer* der = NULL;
7289
0
#ifdef WOLFSSL_SMALL_STACK
7290
0
    DecodedCert* cert;
7291
#else
7292
    DecodedCert  cert[1];
7293
#endif
7294
7295
0
    WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
7296
7297
0
#ifdef WOLFSSL_SMALL_STACK
7298
0
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
7299
0
                                 DYNAMIC_TYPE_DCERT);
7300
0
    if (cert == NULL)
7301
0
        return MEMORY_E;
7302
0
#endif
7303
7304
0
    if (format == WOLFSSL_FILETYPE_PEM) {
7305
0
#ifdef WOLFSSL_PEM_TO_DER
7306
0
        ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL);
7307
0
        if (ret != 0) {
7308
0
            FreeDer(&der);
7309
0
        #ifdef WOLFSSL_SMALL_STACK
7310
0
            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7311
0
        #endif
7312
0
            return ret;
7313
0
        }
7314
0
        InitDecodedCert(cert, der->buffer, der->length, cm->heap);
7315
#else
7316
        ret = NOT_COMPILED_IN;
7317
#endif
7318
0
    }
7319
0
    else {
7320
0
        InitDecodedCert(cert, buff, (word32)sz, cm->heap);
7321
0
    }
7322
7323
0
    if (ret == 0)
7324
0
        ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
7325
7326
#ifdef HAVE_CRL
7327
    if (ret == 0 && cm->crlEnabled)
7328
        ret = CheckCertCRL(cm->crl, cert);
7329
#endif
7330
7331
0
#ifndef NO_WOLFSSL_CM_VERIFY
7332
    /* if verify callback has been set */
7333
0
    if (cm->verifyCallback) {
7334
0
        buffer certBuf;
7335
0
    #ifdef WOLFSSL_SMALL_STACK
7336
0
        ProcPeerCertArgs* args;
7337
0
        args = (ProcPeerCertArgs*)XMALLOC(
7338
0
            sizeof(ProcPeerCertArgs), cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
7339
0
        if (args == NULL) {
7340
0
            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7341
0
            return MEMORY_E;
7342
0
        }
7343
    #else
7344
        ProcPeerCertArgs  args[1];
7345
    #endif
7346
7347
0
        certBuf.buffer = (byte*)buff;
7348
0
        certBuf.length = (unsigned int)sz;
7349
0
        XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
7350
7351
0
        args->totalCerts = 1;
7352
0
        args->certs = &certBuf;
7353
0
        args->dCert = cert;
7354
0
        args->dCertInit = 1;
7355
7356
0
        if (err_val != 0) {
7357
0
            ret = err_val;
7358
0
        }
7359
0
        ret = DoVerifyCallback(cm, NULL, ret, args);
7360
0
    #ifdef WOLFSSL_SMALL_STACK
7361
0
        XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
7362
0
    #endif
7363
0
    }
7364
#else
7365
    (void)err_val;
7366
#endif
7367
7368
0
    FreeDecodedCert(cert);
7369
0
    FreeDer(&der);
7370
0
#ifdef WOLFSSL_SMALL_STACK
7371
0
    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7372
0
#endif
7373
7374
0
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
7375
0
}
7376
7377
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
7378
int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
7379
                                    long sz, int format)
7380
0
{
7381
0
    return CM_VerifyBuffer_ex(cm, buff, sz, format, 0);
7382
0
}
7383
#endif /* !NO_WOLFSSL_CLIENT || !WOLFSSL_NO_CLIENT_AUTH */
7384
7385
/* turn on OCSP if off and compiled in, set options */
7386
int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
7387
0
{
7388
0
    int ret = WOLFSSL_SUCCESS;
7389
7390
0
    (void)options;
7391
7392
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
7393
0
    if (cm == NULL)
7394
0
        return BAD_FUNC_ARG;
7395
7396
    #ifdef HAVE_OCSP
7397
        if (cm->ocsp == NULL) {
7398
            cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
7399
                                              DYNAMIC_TYPE_OCSP);
7400
            if (cm->ocsp == NULL)
7401
                return MEMORY_E;
7402
7403
            if (InitOCSP(cm->ocsp, cm) != 0) {
7404
                WOLFSSL_MSG("Init OCSP failed");
7405
                FreeOCSP(cm->ocsp, 1);
7406
                cm->ocsp = NULL;
7407
                return WOLFSSL_FAILURE;
7408
            }
7409
        }
7410
        cm->ocspEnabled = 1;
7411
        if (options & WOLFSSL_OCSP_URL_OVERRIDE)
7412
            cm->ocspUseOverrideURL = 1;
7413
        if (options & WOLFSSL_OCSP_NO_NONCE)
7414
            cm->ocspSendNonce = 0;
7415
        else
7416
            cm->ocspSendNonce = 1;
7417
        if (options & WOLFSSL_OCSP_CHECKALL)
7418
            cm->ocspCheckAll = 1;
7419
        #ifndef WOLFSSL_USER_IO
7420
            cm->ocspIOCb = EmbedOcspLookup;
7421
            cm->ocspRespFreeCb = EmbedOcspRespFree;
7422
            cm->ocspIOCtx = cm->heap;
7423
        #endif /* WOLFSSL_USER_IO */
7424
    #else
7425
0
        ret = NOT_COMPILED_IN;
7426
0
    #endif
7427
7428
0
    return ret;
7429
0
}
7430
7431
7432
int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
7433
0
{
7434
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
7435
0
    if (cm == NULL)
7436
0
        return BAD_FUNC_ARG;
7437
7438
0
    cm->ocspEnabled = 0;
7439
7440
0
    return WOLFSSL_SUCCESS;
7441
0
}
7442
7443
/* turn on OCSP Stapling if off and compiled in, set options */
7444
int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
7445
0
{
7446
0
    int ret = WOLFSSL_SUCCESS;
7447
7448
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
7449
7450
0
    if (cm == NULL)
7451
0
        return BAD_FUNC_ARG;
7452
7453
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7454
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7455
    #ifndef NO_WOLFSSL_SERVER
7456
    if (cm->ocsp_stapling == NULL) {
7457
        cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
7458
                                               cm->heap, DYNAMIC_TYPE_OCSP);
7459
        if (cm->ocsp_stapling == NULL)
7460
            return MEMORY_E;
7461
7462
        if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
7463
            WOLFSSL_MSG("Init OCSP failed");
7464
            FreeOCSP(cm->ocsp_stapling, 1);
7465
            cm->ocsp_stapling = NULL;
7466
            return WOLFSSL_FAILURE;
7467
        }
7468
    }
7469
7470
    #ifndef WOLFSSL_USER_IO
7471
        cm->ocspIOCb = EmbedOcspLookup;
7472
        cm->ocspRespFreeCb = EmbedOcspRespFree;
7473
        cm->ocspIOCtx = cm->heap;
7474
    #endif /* WOLFSSL_USER_IO */
7475
    #endif /* NO_WOLFSSL_SERVER */
7476
    cm->ocspStaplingEnabled = 1;
7477
#else
7478
0
    ret = NOT_COMPILED_IN;
7479
0
#endif
7480
7481
0
    return ret;
7482
0
}
7483
7484
int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
7485
0
{
7486
0
    int ret = WOLFSSL_SUCCESS;
7487
7488
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling");
7489
7490
0
    if (cm == NULL)
7491
0
        return BAD_FUNC_ARG;
7492
7493
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7494
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7495
    cm->ocspStaplingEnabled = 0;
7496
#else
7497
0
    ret = NOT_COMPILED_IN;
7498
0
#endif
7499
0
    return ret;
7500
0
}
7501
7502
/* require OCSP stapling response */
7503
int wolfSSL_CertManagerEnableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
7504
0
{
7505
0
    int ret;
7506
7507
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPMustStaple");
7508
7509
0
    if (cm == NULL)
7510
0
        return BAD_FUNC_ARG;
7511
7512
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7513
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7514
    #ifndef NO_WOLFSSL_CLIENT
7515
        cm->ocspMustStaple = 1;
7516
    #endif
7517
    ret = WOLFSSL_SUCCESS;
7518
#else
7519
0
    ret = NOT_COMPILED_IN;
7520
0
#endif
7521
7522
0
    return ret;
7523
0
}
7524
7525
int wolfSSL_CertManagerDisableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
7526
0
{
7527
0
    int ret;
7528
7529
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPMustStaple");
7530
7531
0
    if (cm == NULL)
7532
0
        return BAD_FUNC_ARG;
7533
7534
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7535
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7536
    #ifndef NO_WOLFSSL_CLIENT
7537
        cm->ocspMustStaple = 0;
7538
    #endif
7539
    ret = WOLFSSL_SUCCESS;
7540
#else
7541
0
    ret = NOT_COMPILED_IN;
7542
0
#endif
7543
0
    return ret;
7544
0
}
7545
7546
#ifdef HAVE_OCSP
7547
/* check CRL if enabled, WOLFSSL_SUCCESS  */
7548
int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
7549
{
7550
    int ret;
7551
#ifdef WOLFSSL_SMALL_STACK
7552
    DecodedCert* cert = NULL;
7553
#else
7554
    DecodedCert  cert[1];
7555
#endif
7556
7557
    WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
7558
7559
    if (cm == NULL)
7560
        return BAD_FUNC_ARG;
7561
7562
    if (cm->ocspEnabled == 0)
7563
        return WOLFSSL_SUCCESS;
7564
7565
#ifdef WOLFSSL_SMALL_STACK
7566
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, DYNAMIC_TYPE_DCERT);
7567
    if (cert == NULL)
7568
        return MEMORY_E;
7569
#endif
7570
7571
    InitDecodedCert(cert, der, sz, NULL);
7572
7573
    if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) {
7574
        WOLFSSL_MSG("ParseCert failed");
7575
    }
7576
    else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
7577
        WOLFSSL_MSG("CheckCertOCSP failed");
7578
    }
7579
7580
    FreeDecodedCert(cert);
7581
#ifdef WOLFSSL_SMALL_STACK
7582
    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7583
#endif
7584
7585
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
7586
}
7587
7588
WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm,
7589
                                                    byte *response, int responseSz, buffer *responseBuffer,
7590
                                                    CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest)
7591
{
7592
    int ret;
7593
7594
    WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSPResponse");
7595
    if (cm == NULL || response == NULL)
7596
        return BAD_FUNC_ARG;
7597
    if (cm->ocspEnabled == 0)
7598
        return WOLFSSL_SUCCESS;
7599
7600
    ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer, status,
7601
                        entry, ocspRequest);
7602
7603
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
7604
}
7605
7606
int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
7607
                                          const char* url)
7608
{
7609
    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
7610
    if (cm == NULL)
7611
        return BAD_FUNC_ARG;
7612
7613
    XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
7614
    if (url != NULL) {
7615
        int urlSz = (int)XSTRLEN(url) + 1;
7616
        cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL);
7617
        if (cm->ocspOverrideURL != NULL) {
7618
            XMEMCPY(cm->ocspOverrideURL, url, urlSz);
7619
        }
7620
        else
7621
            return MEMORY_E;
7622
    }
7623
    else
7624
        cm->ocspOverrideURL = NULL;
7625
7626
    return WOLFSSL_SUCCESS;
7627
}
7628
7629
7630
int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
7631
                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
7632
{
7633
    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
7634
    if (cm == NULL)
7635
        return BAD_FUNC_ARG;
7636
7637
    cm->ocspIOCb = ioCb;
7638
    cm->ocspRespFreeCb = respFreeCb;
7639
    cm->ocspIOCtx = ioCbCtx;
7640
7641
    return WOLFSSL_SUCCESS;
7642
}
7643
7644
7645
int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
7646
{
7647
    WOLFSSL_ENTER("wolfSSL_EnableOCSP");
7648
    if (ssl)
7649
        return wolfSSL_CertManagerEnableOCSP(SSL_CM(ssl), options);
7650
    else
7651
        return BAD_FUNC_ARG;
7652
}
7653
7654
int wolfSSL_DisableOCSP(WOLFSSL* ssl)
7655
{
7656
    WOLFSSL_ENTER("wolfSSL_DisableOCSP");
7657
    if (ssl)
7658
        return wolfSSL_CertManagerDisableOCSP(SSL_CM(ssl));
7659
    else
7660
        return BAD_FUNC_ARG;
7661
}
7662
7663
7664
int wolfSSL_EnableOCSPStapling(WOLFSSL* ssl)
7665
{
7666
    WOLFSSL_ENTER("wolfSSL_EnableOCSPStapling");
7667
    if (ssl)
7668
        return wolfSSL_CertManagerEnableOCSPStapling(SSL_CM(ssl));
7669
    else
7670
        return BAD_FUNC_ARG;
7671
}
7672
7673
int wolfSSL_DisableOCSPStapling(WOLFSSL* ssl)
7674
{
7675
    WOLFSSL_ENTER("wolfSSL_DisableOCSPStapling");
7676
    if (ssl)
7677
        return wolfSSL_CertManagerDisableOCSPStapling(SSL_CM(ssl));
7678
    else
7679
        return BAD_FUNC_ARG;
7680
}
7681
7682
int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
7683
{
7684
    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
7685
    if (ssl)
7686
        return wolfSSL_CertManagerSetOCSPOverrideURL(SSL_CM(ssl), url);
7687
    else
7688
        return BAD_FUNC_ARG;
7689
}
7690
7691
7692
int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
7693
                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
7694
{
7695
    WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
7696
    if (ssl) {
7697
        ssl->ocspIOCtx = ioCbCtx; /* use SSL specific ioCbCtx */
7698
        return wolfSSL_CertManagerSetOCSP_Cb(SSL_CM(ssl),
7699
                                             ioCb, respFreeCb, NULL);
7700
    }
7701
    else
7702
        return BAD_FUNC_ARG;
7703
}
7704
7705
7706
int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
7707
{
7708
    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
7709
    if (ctx)
7710
        return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
7711
    else
7712
        return BAD_FUNC_ARG;
7713
}
7714
7715
7716
int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
7717
{
7718
    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
7719
    if (ctx)
7720
        return wolfSSL_CertManagerDisableOCSP(ctx->cm);
7721
    else
7722
        return BAD_FUNC_ARG;
7723
}
7724
7725
7726
int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
7727
{
7728
    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
7729
    if (ctx)
7730
        return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
7731
    else
7732
        return BAD_FUNC_ARG;
7733
}
7734
7735
7736
int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
7737
                           CbOCSPRespFree respFreeCb, void* ioCbCtx)
7738
{
7739
    WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
7740
    if (ctx)
7741
        return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
7742
                                             respFreeCb, ioCbCtx);
7743
    else
7744
        return BAD_FUNC_ARG;
7745
}
7746
7747
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7748
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7749
int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
7750
{
7751
    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
7752
    if (ctx)
7753
        return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
7754
    else
7755
        return BAD_FUNC_ARG;
7756
}
7757
7758
int wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX* ctx)
7759
{
7760
    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPStapling");
7761
    if (ctx)
7762
        return wolfSSL_CertManagerDisableOCSPStapling(ctx->cm);
7763
    else
7764
        return BAD_FUNC_ARG;
7765
}
7766
7767
int wolfSSL_CTX_EnableOCSPMustStaple(WOLFSSL_CTX* ctx)
7768
{
7769
    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPMustStaple");
7770
    if (ctx)
7771
        return wolfSSL_CertManagerEnableOCSPMustStaple(ctx->cm);
7772
    else
7773
        return BAD_FUNC_ARG;
7774
}
7775
7776
int wolfSSL_CTX_DisableOCSPMustStaple(WOLFSSL_CTX* ctx)
7777
{
7778
    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPMustStaple");
7779
    if (ctx)
7780
        return wolfSSL_CertManagerDisableOCSPMustStaple(ctx->cm);
7781
    else
7782
        return BAD_FUNC_ARG;
7783
}
7784
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST || HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
7785
7786
#endif /* HAVE_OCSP */
7787
7788
/* macro to get verify settings for AddCA */
7789
#define GET_VERIFY_SETTING_CTX(ctx) \
7790
0
    ((ctx) && (ctx)->verifyNone ? NO_VERIFY : VERIFY)
7791
#define GET_VERIFY_SETTING_SSL(ssl) \
7792
0
    ((ssl)->options.verifyNone ? NO_VERIFY : VERIFY)
7793
7794
#ifndef NO_FILESYSTEM
7795
7796
/* process a file with name fname into ctx of format and type
7797
   userChain specifies a user certificate chain to pass during handshake */
7798
int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
7799
                WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl, int verify)
7800
0
{
7801
0
#ifdef WOLFSSL_SMALL_STACK
7802
0
    byte   staticBuffer[1]; /* force heap usage */
7803
#else
7804
    byte   staticBuffer[FILE_BUFFER_SIZE];
7805
#endif
7806
0
    byte*  myBuffer = staticBuffer;
7807
0
    int    dynamic = 0;
7808
0
    int    ret;
7809
0
    long   sz = 0;
7810
0
    XFILE  file;
7811
0
    void*  heapHint = wolfSSL_CTX_GetHeap(ctx, ssl);
7812
0
#ifndef NO_CODING
7813
0
    const char* header = NULL;
7814
0
    const char* footer = NULL;
7815
0
#endif
7816
7817
0
    (void)crl;
7818
0
    (void)heapHint;
7819
7820
0
    if (fname == NULL) return WOLFSSL_BAD_FILE;
7821
7822
0
    file = XFOPEN(fname, "rb");
7823
0
    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
7824
0
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
7825
0
        XFCLOSE(file);
7826
0
        return WOLFSSL_BAD_FILE;
7827
0
    }
7828
0
    sz = XFTELL(file);
7829
0
    XREWIND(file);
7830
7831
0
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7832
0
        WOLFSSL_MSG("ProcessFile file size error");
7833
0
        XFCLOSE(file);
7834
0
        return WOLFSSL_BAD_FILE;
7835
0
    }
7836
7837
0
    if (sz > (long)sizeof(staticBuffer)) {
7838
0
        WOLFSSL_MSG("Getting dynamic buffer");
7839
0
        myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
7840
0
        if (myBuffer == NULL) {
7841
0
            XFCLOSE(file);
7842
0
            return WOLFSSL_BAD_FILE;
7843
0
        }
7844
0
        dynamic = 1;
7845
0
    }
7846
7847
0
    if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
7848
0
        ret = WOLFSSL_BAD_FILE;
7849
0
    else {
7850
        /* Try to detect type by parsing cert header and footer */
7851
0
        if (type == DETECT_CERT_TYPE) {
7852
0
#ifndef NO_CODING
7853
0
            if (wc_PemGetHeaderFooter(CA_TYPE, &header, &footer) == 0 &&
7854
0
               (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7855
0
                type = CA_TYPE;
7856
0
            }
7857
#ifdef HAVE_CRL
7858
            else if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
7859
                    (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7860
                type = CRL_TYPE;
7861
            }
7862
#endif
7863
0
            else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
7864
0
                    (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7865
0
                type = CERT_TYPE;
7866
0
            }
7867
0
            else
7868
0
#endif
7869
0
            {
7870
0
                WOLFSSL_MSG("Failed to detect certificate type");
7871
0
                if (dynamic)
7872
0
                    XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
7873
0
                XFCLOSE(file);
7874
0
                return WOLFSSL_BAD_CERTTYPE;
7875
0
            }
7876
0
        }
7877
0
        if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
7878
0
                                          && format == WOLFSSL_FILETYPE_PEM) {
7879
0
            ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl,
7880
0
                                     verify);
7881
0
        }
7882
#ifdef HAVE_CRL
7883
        else if (type == CRL_TYPE)
7884
            ret = BufferLoadCRL(crl, myBuffer, sz, format, verify);
7885
#endif
7886
0
        else
7887
0
            ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
7888
0
                                userChain, verify);
7889
0
    }
7890
7891
0
    XFCLOSE(file);
7892
0
    if (dynamic)
7893
0
        XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
7894
7895
0
    return ret;
7896
0
}
7897
7898
/* loads file then loads each file in path, no c_rehash */
7899
int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
7900
                                     const char* path, word32 flags)
7901
0
{
7902
0
    int ret = WOLFSSL_SUCCESS;
7903
0
#ifndef NO_WOLFSSL_DIR
7904
0
    int fileRet;
7905
0
    int successCount = 0;
7906
0
    int failCount = 0;
7907
0
#endif
7908
0
    int verify;
7909
7910
0
    WOLFSSL_MSG("wolfSSL_CTX_load_verify_locations_ex");
7911
7912
0
    if (ctx == NULL || (file == NULL && path == NULL)) {
7913
0
        return WOLFSSL_FAILURE;
7914
0
    }
7915
7916
0
    verify = GET_VERIFY_SETTING_CTX(ctx);
7917
0
    if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
7918
0
        verify = VERIFY_SKIP_DATE;
7919
7920
0
    if (file) {
7921
0
        ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0,
7922
0
                          NULL, verify);
7923
0
#ifndef NO_WOLFSSL_DIR
7924
0
        if (ret == WOLFSSL_SUCCESS)
7925
0
            successCount++;
7926
0
#endif
7927
#if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
7928
        ret = wolfSSL_CTX_trust_peer_cert(ctx, file, WOLFSSL_FILETYPE_PEM);
7929
        if (ret != WOLFSSL_SUCCESS) {
7930
            WOLFSSL_MSG("wolfSSL_CTX_trust_peer_cert error");
7931
        }
7932
#endif
7933
0
    }
7934
7935
0
    if (ret == WOLFSSL_SUCCESS && path) {
7936
0
#ifndef NO_WOLFSSL_DIR
7937
0
        char* name = NULL;
7938
0
    #ifdef WOLFSSL_SMALL_STACK
7939
0
        ReadDirCtx* readCtx;
7940
0
        readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
7941
0
                                                       DYNAMIC_TYPE_DIRCTX);
7942
0
        if (readCtx == NULL)
7943
0
            return MEMORY_E;
7944
    #else
7945
        ReadDirCtx readCtx[1];
7946
    #endif
7947
7948
        /* try to load each regular file in path */
7949
0
        fileRet = wc_ReadDirFirst(readCtx, path, &name);
7950
0
        while (fileRet == 0 && name) {
7951
0
            WOLFSSL_MSG(name); /* log file name */
7952
0
            ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, CA_TYPE,
7953
0
                              NULL, 0, NULL, verify);
7954
0
            if (ret != WOLFSSL_SUCCESS) {
7955
                /* handle flags for ignoring errors, skipping expired certs or
7956
                   by PEM certificate header error */
7957
0
                if ( (flags & WOLFSSL_LOAD_FLAG_IGNORE_ERR) ||
7958
0
                    ((flags & WOLFSSL_LOAD_FLAG_PEM_CA_ONLY) &&
7959
0
                       (ret == ASN_NO_PEM_HEADER))) {
7960
                    /* Do not fail here if a certificate fails to load,
7961
                       continue to next file */
7962
0
                    unsigned long err;
7963
0
                    CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
7964
    #if defined(WOLFSSL_QT)
7965
                    ret = WOLFSSL_SUCCESS;
7966
    #endif
7967
0
                }
7968
0
                else {
7969
0
                    WOLFSSL_ERROR(ret);
7970
0
                    WOLFSSL_MSG("Load CA file failed, continuing");
7971
0
                    failCount++;
7972
0
                }
7973
0
            }
7974
0
            else {
7975
    #if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
7976
                ret = wolfSSL_CTX_trust_peer_cert(ctx, file, WOLFSSL_FILETYPE_PEM);
7977
                if (ret != WOLFSSL_SUCCESS) {
7978
                    WOLFSSL_MSG("wolfSSL_CTX_trust_peer_cert error. Ignoring"
7979
                            "this error.");
7980
                }
7981
    #endif
7982
0
                successCount++;
7983
0
            }
7984
0
            fileRet = wc_ReadDirNext(readCtx, path, &name);
7985
0
        }
7986
0
        wc_ReadDirClose(readCtx);
7987
7988
        /* pass directory read failure to response code */
7989
0
        if (fileRet != WC_READDIR_NOFILE) {
7990
0
            ret = fileRet;
7991
    #if defined(WOLFSSL_QT)
7992
            if (ret == BAD_PATH_ERROR &&
7993
                flags & WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR) {
7994
               /* QSslSocket always loads certs in system folder
7995
                * when it is initialized.
7996
                * Compliant with OpenSSL when flag sets.
7997
                */
7998
                ret = WOLFSSL_SUCCESS;
7999
            }
8000
            else {
8001
                /* qssl socket wants to know errors. */
8002
                WOLFSSL_ERROR(ret);
8003
            }
8004
    #endif
8005
0
        }
8006
        /* report failure if no files were loaded or there were failures */
8007
0
        else if (successCount == 0 || failCount > 0) {
8008
            /* use existing error code if exists */
8009
    #if defined(WOLFSSL_QT)
8010
            /* compliant with OpenSSL when flag sets*/
8011
            if (!(flags & WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE))
8012
    #endif
8013
0
            {
8014
0
                ret = WOLFSSL_FAILURE;
8015
0
            }
8016
0
        }
8017
0
        else {
8018
0
            ret = WOLFSSL_SUCCESS;
8019
0
        }
8020
8021
0
    #ifdef WOLFSSL_SMALL_STACK
8022
0
        XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
8023
0
    #endif
8024
#else
8025
        ret = NOT_COMPILED_IN;
8026
        (void)flags;
8027
#endif
8028
0
    }
8029
8030
0
    return ret;
8031
0
}
8032
8033
WOLFSSL_ABI
8034
int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
8035
                                     const char* path)
8036
0
{
8037
0
    int ret = wolfSSL_CTX_load_verify_locations_ex(ctx, file, path,
8038
0
        WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
8039
8040
0
    return WS_RETURN_CODE(ret,WOLFSSL_FAILURE);
8041
0
}
8042
8043
#ifndef _WIN32
8044
/* Potential system CA certs directories on Linux distros. */
8045
static const char* systemCaDirs[] = {
8046
    "/etc/ssl/certs",                   /* Debian, Ubuntu, Gentoo, others */
8047
    "/etc/pki/ca-trust/source/anchors", /* Fedora, RHEL */
8048
    "/etc/pki/tls/certs"                /* Older RHEL */
8049
};
8050
8051
const char** wolfSSL_get_system_CA_dirs(word32* num)
8052
0
{
8053
0
    const char** ret;
8054
8055
0
    if (num == NULL) {
8056
0
        ret = NULL;
8057
0
    }
8058
0
    else {
8059
0
        ret = systemCaDirs;
8060
0
        *num = sizeof(systemCaDirs)/sizeof(*systemCaDirs);
8061
0
    }
8062
8063
0
    return ret;
8064
0
}
8065
#endif /* !_WIN32 */
8066
8067
int wolfSSL_CTX_load_system_CA_certs(WOLFSSL_CTX* ctx)
8068
0
{
8069
0
    int ret;
8070
0
#ifndef _WIN32
8071
0
    word32 i;
8072
0
    byte loaded = 0;
8073
0
#endif
8074
8075
0
    WOLFSSL_ENTER("wolfSSL_CTX_load_system_CA_certs");
8076
8077
#ifdef _WIN32
8078
    (void)ctx;
8079
    ret = WOLFSSL_NOT_IMPLEMENTED;
8080
#else
8081
0
    if (ctx != NULL) {
8082
0
        for (i = 0; i < sizeof(systemCaDirs)/sizeof(*systemCaDirs); ++i) {
8083
0
            WOLFSSL_MSG_EX("Attempting to load system CA certs from %s.",
8084
0
                systemCaDirs[i]);
8085
            /*
8086
             * We want to keep trying to load more CAs even if one cert in
8087
             * the directory is bad and can't be used (e.g. if one is expired),
8088
             * so we use WOLFSSL_LOAD_FLAG_IGNORE_ERR.
8089
             */
8090
0
            if (wolfSSL_CTX_load_verify_locations_ex(ctx, NULL, systemCaDirs[i],
8091
0
                    WOLFSSL_LOAD_FLAG_IGNORE_ERR) != WOLFSSL_SUCCESS) {
8092
0
                WOLFSSL_MSG_EX("Failed to load CA certs from %s, trying "
8093
0
                    "next possible location.", systemCaDirs[i]);
8094
0
            }
8095
0
            else {
8096
0
                WOLFSSL_MSG_EX("Loaded CA certs from %s.",
8097
0
                    systemCaDirs[i]);
8098
0
                loaded = 1;
8099
                /* Stop searching after we've loaded one directory. */
8100
0
                break;
8101
0
            }
8102
0
        }
8103
0
    }
8104
8105
0
    if (loaded) {
8106
0
        ret = WOLFSSL_SUCCESS;
8107
0
    }
8108
0
    else {
8109
0
        ret = WOLFSSL_BAD_PATH;
8110
0
    }
8111
0
#endif
8112
8113
0
    WOLFSSL_LEAVE("wolfSSL_CTX_load_system_CA_certs", ret);
8114
8115
0
    return ret;
8116
0
}
8117
8118
#ifdef WOLFSSL_TRUST_PEER_CERT
8119
/* Used to specify a peer cert to match when connecting
8120
    ctx : the ctx structure to load in peer cert
8121
    file: the string name of cert file
8122
    type: type of format such as PEM/DER
8123
 */
8124
int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type)
8125
{
8126
    WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
8127
8128
    if (ctx == NULL || file == NULL) {
8129
        return WOLFSSL_FAILURE;
8130
    }
8131
8132
    return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL,
8133
                       GET_VERIFY_SETTING_CTX(ctx));
8134
}
8135
8136
int wolfSSL_trust_peer_cert(WOLFSSL* ssl, const char* file, int type)
8137
{
8138
    WOLFSSL_ENTER("wolfSSL_trust_peer_cert");
8139
8140
    if (ssl == NULL || file == NULL) {
8141
        return WOLFSSL_FAILURE;
8142
    }
8143
8144
    return ProcessFile(NULL, file, type, TRUSTED_PEER_TYPE, ssl, 0, NULL,
8145
                       GET_VERIFY_SETTING_SSL(ssl));
8146
}
8147
#endif /* WOLFSSL_TRUST_PEER_CERT */
8148
8149
8150
#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
8151
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
8152
int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
8153
                             int format)
8154
0
{
8155
0
    int    ret = WOLFSSL_FATAL_ERROR;
8156
0
#ifdef WOLFSSL_SMALL_STACK
8157
0
    byte   staticBuffer[1]; /* force heap usage */
8158
#else
8159
    byte   staticBuffer[FILE_BUFFER_SIZE];
8160
#endif
8161
0
    byte*  myBuffer = staticBuffer;
8162
0
    int    dynamic = 0;
8163
0
    long   sz = 0;
8164
0
    XFILE  file = XFOPEN(fname, "rb");
8165
8166
0
    WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
8167
8168
0
    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
8169
0
    if(XFSEEK(file, 0, XSEEK_END) != 0) {
8170
0
        XFCLOSE(file);
8171
0
        return WOLFSSL_BAD_FILE;
8172
0
    }
8173
0
    sz = XFTELL(file);
8174
0
    XREWIND(file);
8175
8176
0
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
8177
0
        WOLFSSL_MSG("CertManagerVerify file size error");
8178
0
        XFCLOSE(file);
8179
0
        return WOLFSSL_BAD_FILE;
8180
0
    }
8181
8182
0
    if (sz > (long)sizeof(staticBuffer)) {
8183
0
        WOLFSSL_MSG("Getting dynamic buffer");
8184
0
        myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
8185
0
        if (myBuffer == NULL) {
8186
0
            XFCLOSE(file);
8187
0
            return WOLFSSL_BAD_FILE;
8188
0
        }
8189
0
        dynamic = 1;
8190
0
    }
8191
8192
0
    if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
8193
0
        ret = WOLFSSL_BAD_FILE;
8194
0
    else
8195
0
        ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
8196
8197
0
    XFCLOSE(file);
8198
0
    if (dynamic)
8199
0
        XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
8200
8201
0
    return ret;
8202
0
}
8203
#endif
8204
8205
/* like load verify locations, 1 for success, < 0 for error */
8206
int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
8207
                             const char* path)
8208
0
{
8209
0
    int ret = WOLFSSL_FATAL_ERROR;
8210
0
    WOLFSSL_CTX* tmp;
8211
8212
0
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
8213
8214
0
    if (cm == NULL) {
8215
0
        WOLFSSL_MSG("No CertManager error");
8216
0
        return ret;
8217
0
    }
8218
0
    tmp = wolfSSL_CTX_new(cm_pick_method());
8219
8220
0
    if (tmp == NULL) {
8221
0
        WOLFSSL_MSG("CTX new failed");
8222
0
        return ret;
8223
0
    }
8224
8225
    /* for tmp use */
8226
0
    wolfSSL_CertManagerFree(tmp->cm);
8227
0
    tmp->cm = cm;
8228
8229
0
    ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
8230
8231
    /* don't lose our good one */
8232
0
    tmp->cm = NULL;
8233
0
    wolfSSL_CTX_free(tmp);
8234
8235
0
    return ret;
8236
0
}
8237
8238
8239
#endif /* NO_FILESYSTEM */
8240
8241
#ifdef HAVE_CRL
8242
8243
/* check CRL if enabled, WOLFSSL_SUCCESS  */
8244
int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
8245
{
8246
    int ret = 0;
8247
#ifdef WOLFSSL_SMALL_STACK
8248
    DecodedCert* cert = NULL;
8249
#else
8250
    DecodedCert  cert[1];
8251
#endif
8252
8253
    WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
8254
8255
    if (cm == NULL)
8256
        return BAD_FUNC_ARG;
8257
8258
    if (cm->crlEnabled == 0)
8259
        return WOLFSSL_SUCCESS;
8260
8261
#ifdef WOLFSSL_SMALL_STACK
8262
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
8263
    if (cert == NULL)
8264
        return MEMORY_E;
8265
#endif
8266
8267
    InitDecodedCert(cert, der, sz, NULL);
8268
8269
    if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) {
8270
        WOLFSSL_MSG("ParseCert failed");
8271
    }
8272
    else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
8273
        WOLFSSL_MSG("CheckCertCRL failed");
8274
    }
8275
8276
    FreeDecodedCert(cert);
8277
#ifdef WOLFSSL_SMALL_STACK
8278
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
8279
#endif
8280
8281
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
8282
}
8283
8284
8285
int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
8286
{
8287
    WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
8288
    if (cm == NULL)
8289
        return BAD_FUNC_ARG;
8290
8291
    cm->cbMissingCRL = cb;
8292
8293
    return WOLFSSL_SUCCESS;
8294
}
8295
8296
#ifdef HAVE_CRL_IO
8297
int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb)
8298
{
8299
    if (cm == NULL)
8300
        return BAD_FUNC_ARG;
8301
8302
    cm->crl->crlIOCb = cb;
8303
8304
    return WOLFSSL_SUCCESS;
8305
}
8306
#endif
8307
8308
#ifndef NO_FILESYSTEM
8309
int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
8310
                              int type, int monitor)
8311
{
8312
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
8313
    if (cm == NULL)
8314
        return BAD_FUNC_ARG;
8315
8316
    if (cm->crl == NULL) {
8317
        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
8318
            WOLFSSL_MSG("Enable CRL failed");
8319
            return WOLFSSL_FATAL_ERROR;
8320
        }
8321
    }
8322
8323
    return LoadCRL(cm->crl, path, type, monitor);
8324
}
8325
8326
int wolfSSL_CertManagerLoadCRLFile(WOLFSSL_CERT_MANAGER* cm, const char* file,
8327
                              int type)
8328
{
8329
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLFile");
8330
    if (cm == NULL || file == NULL)
8331
        return BAD_FUNC_ARG;
8332
8333
    if (cm->crl == NULL) {
8334
        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
8335
            WOLFSSL_MSG("Enable CRL failed");
8336
            return WOLFSSL_FATAL_ERROR;
8337
        }
8338
    }
8339
8340
    return ProcessFile(NULL, file, type, CRL_TYPE, NULL, 0, cm->crl,
8341
            VERIFY);
8342
}
8343
#endif
8344
8345
int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
8346
{
8347
    WOLFSSL_ENTER("wolfSSL_EnableCRL");
8348
    if (ssl)
8349
        return wolfSSL_CertManagerEnableCRL(SSL_CM(ssl), options);
8350
    else
8351
        return BAD_FUNC_ARG;
8352
}
8353
8354
8355
int wolfSSL_DisableCRL(WOLFSSL* ssl)
8356
{
8357
    WOLFSSL_ENTER("wolfSSL_DisableCRL");
8358
    if (ssl)
8359
        return wolfSSL_CertManagerDisableCRL(SSL_CM(ssl));
8360
    else
8361
        return BAD_FUNC_ARG;
8362
}
8363
8364
#ifndef NO_FILESYSTEM
8365
int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
8366
{
8367
    WOLFSSL_ENTER("wolfSSL_LoadCRL");
8368
    if (ssl)
8369
        return wolfSSL_CertManagerLoadCRL(SSL_CM(ssl), path, type, monitor);
8370
    else
8371
        return BAD_FUNC_ARG;
8372
}
8373
8374
int wolfSSL_LoadCRLFile(WOLFSSL* ssl, const char* file, int type)
8375
{
8376
    WOLFSSL_ENTER("wolfSSL_LoadCRL");
8377
    if (ssl)
8378
        return wolfSSL_CertManagerLoadCRLFile(SSL_CM(ssl), file, type);
8379
    else
8380
        return BAD_FUNC_ARG;
8381
}
8382
#endif
8383
8384
8385
int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
8386
{
8387
    WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
8388
    if (ssl)
8389
        return wolfSSL_CertManagerSetCRL_Cb(SSL_CM(ssl), cb);
8390
    else
8391
        return BAD_FUNC_ARG;
8392
}
8393
8394
#ifdef HAVE_CRL_IO
8395
int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb)
8396
{
8397
    WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
8398
    if (ssl)
8399
        return wolfSSL_CertManagerSetCRL_IOCb(SSL_CM(ssl), cb);
8400
    else
8401
        return BAD_FUNC_ARG;
8402
}
8403
#endif
8404
8405
int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
8406
{
8407
    WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
8408
    if (ctx)
8409
        return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
8410
    else
8411
        return BAD_FUNC_ARG;
8412
}
8413
8414
8415
int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
8416
{
8417
    WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
8418
    if (ctx)
8419
        return wolfSSL_CertManagerDisableCRL(ctx->cm);
8420
    else
8421
        return BAD_FUNC_ARG;
8422
}
8423
8424
8425
#ifndef NO_FILESYSTEM
8426
int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
8427
                        int type, int monitor)
8428
{
8429
    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
8430
    if (ctx)
8431
        return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
8432
    else
8433
        return BAD_FUNC_ARG;
8434
}
8435
8436
int wolfSSL_CTX_LoadCRLFile(WOLFSSL_CTX* ctx, const char* file,
8437
                        int type)
8438
{
8439
    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
8440
    if (ctx)
8441
        return wolfSSL_CertManagerLoadCRLFile(ctx->cm, file, type);
8442
    else
8443
        return BAD_FUNC_ARG;
8444
}
8445
#endif
8446
8447
8448
int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
8449
{
8450
    WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
8451
    if (ctx)
8452
        return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
8453
    else
8454
        return BAD_FUNC_ARG;
8455
}
8456
8457
#ifdef HAVE_CRL_IO
8458
int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb)
8459
{
8460
    WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_IOCb");
8461
    if (ctx)
8462
        return wolfSSL_CertManagerSetCRL_IOCb(ctx->cm, cb);
8463
    else
8464
        return BAD_FUNC_ARG;
8465
}
8466
#endif
8467
8468
8469
#endif /* HAVE_CRL */
8470
8471
8472
#ifndef NO_FILESYSTEM
8473
8474
8475
#ifdef WOLFSSL_DER_LOAD
8476
8477
/* Add format parameter to allow DER load of CA files */
8478
int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
8479
                                          int format)
8480
{
8481
    WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
8482
    if (ctx == NULL || file == NULL)
8483
        return WOLFSSL_FAILURE;
8484
8485
    if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL,
8486
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8487
        return WOLFSSL_SUCCESS;
8488
    }
8489
8490
    return WOLFSSL_FAILURE;
8491
}
8492
8493
#endif /* WOLFSSL_DER_LOAD */
8494
8495
8496
8497
WOLFSSL_ABI
8498
int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
8499
                                     int format)
8500
0
{
8501
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
8502
8503
0
    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL,
8504
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8505
0
        return WOLFSSL_SUCCESS;
8506
0
    }
8507
8508
0
    return WOLFSSL_FAILURE;
8509
0
}
8510
8511
8512
WOLFSSL_ABI
8513
int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
8514
                                    int format)
8515
0
{
8516
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
8517
8518
0
    if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL,
8519
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8520
0
        return WOLFSSL_SUCCESS;
8521
0
    }
8522
8523
0
    return WOLFSSL_FAILURE;
8524
0
}
8525
8526
8527
#endif /* NO_FILESYSTEM */
8528
8529
8530
/* Sets the max chain depth when verifying a certificate chain. Default depth
8531
 * is set to MAX_CHAIN_DEPTH.
8532
 *
8533
 * ctx   WOLFSSL_CTX structure to set depth in
8534
 * depth max depth
8535
 */
8536
0
void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
8537
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
8538
8539
0
    if (ctx == NULL || depth < 0 || depth > MAX_CHAIN_DEPTH) {
8540
0
        WOLFSSL_MSG("Bad depth argument, too large or less than 0");
8541
0
        return;
8542
0
    }
8543
8544
0
    ctx->verifyDepth = (byte)depth;
8545
0
}
8546
8547
8548
/* get cert chaining depth using ssl struct */
8549
long wolfSSL_get_verify_depth(WOLFSSL* ssl)
8550
0
{
8551
0
    if(ssl == NULL) {
8552
0
        return BAD_FUNC_ARG;
8553
0
    }
8554
0
#ifndef OPENSSL_EXTRA
8555
0
    return MAX_CHAIN_DEPTH;
8556
#else
8557
    return ssl->options.verifyDepth;
8558
#endif
8559
0
}
8560
8561
8562
/* get cert chaining depth using ctx struct */
8563
long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
8564
0
{
8565
0
    if (ctx == NULL) {
8566
0
        return BAD_FUNC_ARG;
8567
0
    }
8568
0
#ifndef OPENSSL_EXTRA
8569
0
    return MAX_CHAIN_DEPTH;
8570
#else
8571
    return ctx->verifyDepth;
8572
#endif
8573
0
}
8574
8575
8576
#ifndef NO_FILESYSTEM
8577
8578
8579
WOLFSSL_ABI
8580
int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
8581
0
{
8582
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
8583
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
8584
8585
0
    if (ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, NULL, 1, NULL,
8586
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8587
0
        return WOLFSSL_SUCCESS;
8588
0
    }
8589
8590
0
   return WOLFSSL_FAILURE;
8591
0
}
8592
8593
8594
int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,
8595
                                                  const char* file, int format)
8596
0
{
8597
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
8598
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file_format");
8599
8600
0
    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 1, NULL,
8601
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8602
0
        return WOLFSSL_SUCCESS;
8603
0
    }
8604
8605
0
   return WOLFSSL_FAILURE;
8606
0
}
8607
8608
8609
#ifndef NO_DH
8610
8611
/* server Diffie-Hellman parameters */
8612
static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
8613
                                        const char* fname, int format)
8614
0
{
8615
0
#ifdef WOLFSSL_SMALL_STACK
8616
0
    byte   staticBuffer[1]; /* force heap usage */
8617
#else
8618
    byte   staticBuffer[FILE_BUFFER_SIZE];
8619
#endif
8620
0
    byte*  myBuffer = staticBuffer;
8621
0
    int    dynamic = 0;
8622
0
    int    ret;
8623
0
    long   sz = 0;
8624
0
    XFILE  file;
8625
8626
0
    if (ctx == NULL || fname == NULL)
8627
0
        return BAD_FUNC_ARG;
8628
8629
0
    file = XFOPEN(fname, "rb");
8630
0
    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
8631
0
    if(XFSEEK(file, 0, XSEEK_END) != 0) {
8632
0
        XFCLOSE(file);
8633
0
        return WOLFSSL_BAD_FILE;
8634
0
    }
8635
0
    sz = XFTELL(file);
8636
0
    XREWIND(file);
8637
8638
0
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
8639
0
        WOLFSSL_MSG("SetTmpDH file size error");
8640
0
        XFCLOSE(file);
8641
0
        return WOLFSSL_BAD_FILE;
8642
0
    }
8643
8644
0
    if (sz > (long)sizeof(staticBuffer)) {
8645
0
        WOLFSSL_MSG("Getting dynamic buffer");
8646
0
        myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
8647
0
        if (myBuffer == NULL) {
8648
0
            XFCLOSE(file);
8649
0
            return WOLFSSL_BAD_FILE;
8650
0
        }
8651
0
        dynamic = 1;
8652
0
    }
8653
8654
0
    if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
8655
0
        ret = WOLFSSL_BAD_FILE;
8656
0
    else {
8657
0
        if (ssl)
8658
0
            ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
8659
0
        else
8660
0
            ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
8661
0
    }
8662
8663
0
    XFCLOSE(file);
8664
0
    if (dynamic)
8665
0
        XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
8666
8667
0
    return ret;
8668
0
}
8669
8670
/* server Diffie-Hellman parameters */
8671
int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
8672
0
{
8673
0
    if (ssl == NULL)
8674
0
        return BAD_FUNC_ARG;
8675
8676
0
    return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
8677
0
}
8678
8679
8680
/* server Diffie-Hellman parameters */
8681
int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
8682
0
{
8683
0
    return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
8684
0
}
8685
8686
#endif /* NO_DH */
8687
8688
#endif /* NO_FILESYSTEM */
8689
8690
#ifndef NO_CHECK_PRIVATE_KEY
8691
/* Check private against public in certificate for match
8692
 *
8693
 * Returns WOLFSSL_SUCCESS on good private key
8694
 *         WOLFSSL_FAILURE if mismatched */
8695
static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap,
8696
    int devId, int isKeyLabel, int isKeyId)
8697
0
{
8698
0
#ifdef WOLFSSL_SMALL_STACK
8699
0
    DecodedCert* der = NULL;
8700
#else
8701
    DecodedCert  der[1];
8702
#endif
8703
0
    word32 size;
8704
0
    byte*  buff;
8705
0
    int    ret = WOLFSSL_FAILURE;
8706
8707
0
    WOLFSSL_ENTER("check_cert_key");
8708
8709
0
    if (cert == NULL || key == NULL) {
8710
0
        return WOLFSSL_FAILURE;
8711
0
    }
8712
8713
0
#ifdef WOLFSSL_SMALL_STACK
8714
0
    der = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
8715
0
    if (der == NULL)
8716
0
        return MEMORY_E;
8717
0
#endif
8718
8719
0
    size = cert->length;
8720
0
    buff = cert->buffer;
8721
0
    InitDecodedCert(der, buff, size, heap);
8722
0
    if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
8723
0
        FreeDecodedCert(der);
8724
0
    #ifdef WOLFSSL_SMALL_STACK
8725
0
        XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
8726
0
    #endif
8727
0
        return WOLFSSL_FAILURE;
8728
0
    }
8729
8730
0
    size = key->length;
8731
0
    buff = key->buffer;
8732
0
#ifdef WOLF_PRIVATE_KEY_ID
8733
0
    if (devId != INVALID_DEVID) {
8734
0
        int type = 0;
8735
0
        void *pkey = NULL;
8736
8737
0
    #ifndef NO_RSA
8738
0
        if (der->keyOID == RSAk) {
8739
0
            type = DYNAMIC_TYPE_RSA;
8740
0
        }
8741
0
    #ifdef WC_RSA_PSS
8742
0
        if (der->keyOID == RSAPSSk) {
8743
0
            type = DYNAMIC_TYPE_RSA;
8744
0
        }
8745
0
    #endif
8746
0
    #endif
8747
0
    #ifdef HAVE_ECC
8748
0
        if (der->keyOID == ECDSAk) {
8749
0
            type = DYNAMIC_TYPE_ECC;
8750
0
        }
8751
0
    #endif
8752
8753
0
        ret = CreateDevPrivateKey(&pkey, buff, size, type,
8754
0
                                  isKeyLabel, isKeyId, heap, devId);
8755
0
        #ifdef WOLF_CRYPTO_CB
8756
0
        if (ret == 0) {
8757
0
            #ifndef NO_RSA
8758
0
            if (der->keyOID == RSAk
8759
0
            #ifdef WC_RSA_PSS
8760
0
                || der->keyOID == RSAPSSk
8761
0
            #endif
8762
0
                ) {
8763
0
                ret = wc_CryptoCb_RsaCheckPrivKey((RsaKey*)pkey,
8764
0
                                               der->publicKey, der->pubKeySize);
8765
0
            }
8766
0
            #endif
8767
0
            #ifdef HAVE_ECC
8768
0
            if (der->keyOID == ECDSAk) {
8769
0
                ret = wc_CryptoCb_EccCheckPrivKey((ecc_key*)pkey,
8770
0
                                               der->publicKey, der->pubKeySize);
8771
0
            }
8772
0
            #endif
8773
0
        }
8774
        #else
8775
            /* devId was set, don't check, for now */
8776
            /* TODO: Add callback for private key check? */
8777
        #endif
8778
0
        if (pkey != NULL) {
8779
0
        #ifndef NO_RSA
8780
0
            if (der->keyOID == RSAk
8781
0
            #ifdef WC_RSA_PSS
8782
0
                || der->keyOID == RSAPSSk
8783
0
            #endif
8784
0
                ) {
8785
0
                wc_FreeRsaKey((RsaKey*)pkey);
8786
0
            }
8787
0
        #endif
8788
0
        #ifdef HAVE_ECC
8789
0
            if (der->keyOID == ECDSAk) {
8790
0
                wc_ecc_free((ecc_key*)pkey);
8791
0
            }
8792
0
        #endif
8793
0
            XFREE(pkey, heap, type);
8794
0
        }
8795
0
        if (ret != CRYPTOCB_UNAVAILABLE) {
8796
0
            ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
8797
0
        }
8798
0
    }
8799
0
    else {
8800
        /* fall through if unavailable */
8801
0
        ret = CRYPTOCB_UNAVAILABLE;
8802
0
    }
8803
8804
0
    if (ret == CRYPTOCB_UNAVAILABLE)
8805
0
#endif /* WOLF_PRIVATE_KEY_ID */
8806
0
    {
8807
0
        ret = wc_CheckPrivateKeyCert(buff, size, der);
8808
0
        ret = (ret == 1) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
8809
0
    }
8810
0
    FreeDecodedCert(der);
8811
0
#ifdef WOLFSSL_SMALL_STACK
8812
0
    XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
8813
0
#endif
8814
8815
0
    (void)devId;
8816
0
    (void)isKeyLabel;
8817
0
    (void)isKeyId;
8818
8819
0
    return ret;
8820
0
}
8821
8822
/* Check private against public in certificate for match
8823
 *
8824
 * ctx  WOLFSSL_CTX structure to check private key in
8825
 *
8826
 * Returns WOLFSSL_SUCCESS on good private key
8827
 *         WOLFSSL_FAILURE if mismatched. */
8828
int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
8829
0
{
8830
0
    if (ctx == NULL) {
8831
0
        return WOLFSSL_FAILURE;
8832
0
    }
8833
0
    return check_cert_key(ctx->certificate, ctx->privateKey, ctx->heap,
8834
0
        ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId);
8835
0
}
8836
#endif /* !NO_CHECK_PRIVATE_KEY */
8837
8838
#ifdef OPENSSL_ALL
8839
/**
8840
 * Return the private key of the WOLFSSL_CTX struct
8841
 * @return WOLFSSL_EVP_PKEY* The caller doesn *NOT*` free the returned object.
8842
 */
8843
WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
8844
{
8845
    const unsigned char *key;
8846
    int type;
8847
8848
    WOLFSSL_ENTER("wolfSSL_CTX_get0_privatekey");
8849
8850
    if (ctx == NULL || ctx->privateKey == NULL ||
8851
            ctx->privateKey->buffer == NULL) {
8852
        WOLFSSL_MSG("Bad parameter or key not set");
8853
        return NULL;
8854
    }
8855
8856
    switch (ctx->privateKeyType) {
8857
#ifndef NO_RSA
8858
        case rsa_sa_algo:
8859
            type = EVP_PKEY_RSA;
8860
            break;
8861
#endif
8862
#ifdef HAVE_ECC
8863
        case ecc_dsa_sa_algo:
8864
            type = EVP_PKEY_EC;
8865
            break;
8866
#endif
8867
        default:
8868
            /* Other key types not supported either as ssl private keys
8869
             * or in the EVP layer */
8870
            WOLFSSL_MSG("Unsupported key type");
8871
            return NULL;
8872
    }
8873
8874
    key = ctx->privateKey->buffer;
8875
8876
    if (ctx->privateKeyPKey != NULL)
8877
        return ctx->privateKeyPKey;
8878
    else
8879
        return wolfSSL_d2i_PrivateKey(type,
8880
                (WOLFSSL_EVP_PKEY**)&ctx->privateKeyPKey, &key,
8881
                (long)ctx->privateKey->length);
8882
}
8883
#endif
8884
8885
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
8886
8887
static WOLFSSL_EVP_PKEY* d2iGenericKey(WOLFSSL_EVP_PKEY** out,
8888
                                 const unsigned char** in, long inSz, int priv)
8889
{
8890
8891
    WOLFSSL_EVP_PKEY* pkey = NULL;
8892
    const unsigned char* mem;
8893
    long memSz = inSz;
8894
8895
    WOLFSSL_ENTER("d2iGenericKey");
8896
8897
    if (in == NULL || *in == NULL || inSz < 0) {
8898
        WOLFSSL_MSG("Bad argument");
8899
        return NULL;
8900
    }
8901
    mem = *in;
8902
8903
    #if !defined(NO_RSA)
8904
    {
8905
        word32 keyIdx = 0;
8906
        int isRsaKey;
8907
    #ifdef WOLFSSL_SMALL_STACK
8908
        RsaKey *rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
8909
        if (rsa == NULL)
8910
            return NULL;
8911
    #else
8912
        RsaKey rsa[1];
8913
    #endif
8914
        XMEMSET(rsa, 0, sizeof(RsaKey));
8915
8916
        /* test if RSA key */
8917
        if (priv)
8918
            isRsaKey = wc_InitRsaKey(rsa, NULL) == 0 &&
8919
                wc_RsaPrivateKeyDecode(mem, &keyIdx, rsa, (word32)memSz) == 0;
8920
        else
8921
            isRsaKey = wc_InitRsaKey(rsa, NULL) == 0 &&
8922
                wc_RsaPublicKeyDecode(mem, &keyIdx, rsa, (word32)memSz) == 0;
8923
        wc_FreeRsaKey(rsa);
8924
    #ifdef WOLFSSL_SMALL_STACK
8925
        XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
8926
    #endif
8927
8928
        if (isRsaKey) {
8929
            pkey = wolfSSL_EVP_PKEY_new();
8930
            if (pkey != NULL) {
8931
                pkey->pkey_sz = keyIdx;
8932
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
8933
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8934
                               DYNAMIC_TYPE_PUBLIC_KEY);
8935
                if (pkey->pkey.ptr == NULL) {
8936
                    wolfSSL_EVP_PKEY_free(pkey);
8937
                    return NULL;
8938
                }
8939
                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
8940
                pkey->type = EVP_PKEY_RSA;
8941
                if (out != NULL) {
8942
                    *out = pkey;
8943
                }
8944
8945
                pkey->ownRsa = 1;
8946
                pkey->rsa = wolfSSL_RSA_new();
8947
                if (pkey->rsa == NULL) {
8948
                    wolfSSL_EVP_PKEY_free(pkey);
8949
                    return NULL;
8950
                }
8951
8952
                if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
8953
                        (const unsigned char*)pkey->pkey.ptr,
8954
                        pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
8955
                                            : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
8956
                    wolfSSL_EVP_PKEY_free(pkey);
8957
                    return NULL;
8958
                }
8959
8960
                return pkey;
8961
            }
8962
            else {
8963
                WOLFSSL_MSG("RSA wolfSSL_EVP_PKEY_new error");
8964
            }
8965
        }
8966
    }
8967
    #endif /* NO_RSA */
8968
8969
    #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
8970
    {
8971
        word32  keyIdx = 0;
8972
        int     isEccKey;
8973
    #ifdef WOLFSSL_SMALL_STACK
8974
        ecc_key *ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
8975
        if (ecc == NULL)
8976
            return NULL;
8977
    #else
8978
        ecc_key ecc[1];
8979
    #endif
8980
        XMEMSET(ecc, 0, sizeof(ecc_key));
8981
8982
        if (priv)
8983
            isEccKey = wc_ecc_init(ecc) == 0 &&
8984
                wc_EccPrivateKeyDecode(mem, &keyIdx, ecc, (word32)memSz) == 0;
8985
        else
8986
            isEccKey = wc_ecc_init(ecc) == 0 &&
8987
                wc_EccPublicKeyDecode(mem, &keyIdx, ecc, (word32)memSz) == 0;
8988
        wc_ecc_free(ecc);
8989
    #ifdef WOLFSSL_SMALL_STACK
8990
        XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
8991
    #endif
8992
8993
        if (isEccKey) {
8994
            pkey = wolfSSL_EVP_PKEY_new();
8995
            if (pkey != NULL) {
8996
                pkey->pkey_sz = keyIdx;
8997
                pkey->pkey.ptr = (char*)XMALLOC(keyIdx, NULL,
8998
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8999
                               DYNAMIC_TYPE_PUBLIC_KEY);
9000
                if (pkey->pkey.ptr == NULL) {
9001
                    wolfSSL_EVP_PKEY_free(pkey);
9002
                    return NULL;
9003
                }
9004
                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
9005
                pkey->type = EVP_PKEY_EC;
9006
                if (out != NULL) {
9007
                    *out = pkey;
9008
                }
9009
9010
                pkey->ownEcc = 1;
9011
                pkey->ecc = wolfSSL_EC_KEY_new();
9012
                if (pkey->ecc == NULL) {
9013
                    wolfSSL_EVP_PKEY_free(pkey);
9014
                    return NULL;
9015
                }
9016
9017
                if (wolfSSL_EC_KEY_LoadDer_ex(pkey->ecc,
9018
                        (const unsigned char*)pkey->pkey.ptr,
9019
                        pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
9020
                                            : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
9021
                    wolfSSL_EVP_PKEY_free(pkey);
9022
                    return NULL;
9023
                }
9024
9025
                return pkey;
9026
            }
9027
            else {
9028
                WOLFSSL_MSG("ECC wolfSSL_EVP_PKEY_new error");
9029
            }
9030
        }
9031
    }
9032
    #endif /* HAVE_ECC && OPENSSL_EXTRA */
9033
9034
    #if !defined(NO_DSA)
9035
    {
9036
        word32 keyIdx = 0;
9037
        int     isDsaKey;
9038
    #ifdef WOLFSSL_SMALL_STACK
9039
        DsaKey *dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
9040
        if (dsa == NULL)
9041
            return NULL;
9042
    #else
9043
        DsaKey dsa[1];
9044
    #endif
9045
        XMEMSET(dsa, 0, sizeof(DsaKey));
9046
9047
        if (priv)
9048
            isDsaKey = wc_InitDsaKey(dsa) == 0 &&
9049
                wc_DsaPrivateKeyDecode(mem, &keyIdx, dsa, (word32)memSz) == 0;
9050
        else
9051
            isDsaKey = wc_InitDsaKey(dsa) == 0 &&
9052
                wc_DsaPublicKeyDecode(mem, &keyIdx, dsa, (word32)memSz) == 0;
9053
        wc_FreeDsaKey(dsa);
9054
    #ifdef WOLFSSL_SMALL_STACK
9055
        XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
9056
    #endif
9057
9058
        /* test if DSA key */
9059
        if (isDsaKey) {
9060
            pkey = wolfSSL_EVP_PKEY_new();
9061
9062
            if (pkey != NULL) {
9063
                pkey->pkey_sz = keyIdx;
9064
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
9065
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
9066
                               DYNAMIC_TYPE_PUBLIC_KEY);
9067
                if (pkey->pkey.ptr == NULL) {
9068
                    wolfSSL_EVP_PKEY_free(pkey);
9069
                    return NULL;
9070
                }
9071
                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
9072
                pkey->type = EVP_PKEY_DSA;
9073
                if (out != NULL) {
9074
                    *out = pkey;
9075
                }
9076
9077
                pkey->ownDsa = 1;
9078
                pkey->dsa = wolfSSL_DSA_new();
9079
                if (pkey->dsa == NULL) {
9080
                    wolfSSL_EVP_PKEY_free(pkey);
9081
                    return NULL;
9082
                }
9083
9084
                if (wolfSSL_DSA_LoadDer_ex(pkey->dsa,
9085
                        (const unsigned char*)pkey->pkey.ptr,
9086
                        pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
9087
                                            : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
9088
                    wolfSSL_EVP_PKEY_free(pkey);
9089
                    return NULL;
9090
                }
9091
9092
                return pkey;
9093
            }
9094
            else {
9095
                WOLFSSL_MSG("DSA wolfSSL_EVP_PKEY_new error");
9096
            }
9097
        }
9098
    }
9099
    #endif /* NO_DSA */
9100
9101
    #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
9102
    #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
9103
        (HAVE_FIPS_VERSION > 2))
9104
    {
9105
        int isDhKey;
9106
        word32 keyIdx = 0;
9107
    #ifdef WOLFSSL_SMALL_STACK
9108
        DhKey *dh = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
9109
        if (dh == NULL)
9110
            return NULL;
9111
    #else
9112
        DhKey dh[1];
9113
    #endif
9114
        XMEMSET(dh, 0, sizeof(DhKey));
9115
9116
        isDhKey = wc_InitDhKey(dh) == 0 &&
9117
                  wc_DhKeyDecode(mem, &keyIdx, dh, (word32)memSz) == 0;
9118
        wc_FreeDhKey(dh);
9119
    #ifdef WOLFSSL_SMALL_STACK
9120
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
9121
    #endif
9122
9123
        /* test if DH key */
9124
        if (isDhKey) {
9125
            pkey = wolfSSL_EVP_PKEY_new();
9126
9127
            if (pkey != NULL) {
9128
                pkey->pkey_sz = (int)memSz;
9129
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
9130
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
9131
                               DYNAMIC_TYPE_PUBLIC_KEY);
9132
                if (pkey->pkey.ptr == NULL) {
9133
                    wolfSSL_EVP_PKEY_free(pkey);
9134
                    return NULL;
9135
                }
9136
                XMEMCPY(pkey->pkey.ptr, mem, memSz);
9137
                pkey->type = EVP_PKEY_DH;
9138
                if (out != NULL) {
9139
                    *out = pkey;
9140
                }
9141
9142
                pkey->ownDh = 1;
9143
                pkey->dh = wolfSSL_DH_new();
9144
                if (pkey->dh == NULL) {
9145
                    wolfSSL_EVP_PKEY_free(pkey);
9146
                    return NULL;
9147
                }
9148
9149
                if (wolfSSL_DH_LoadDer(pkey->dh,
9150
                            (const unsigned char*)pkey->pkey.ptr,
9151
                            pkey->pkey_sz) != WOLFSSL_SUCCESS) {
9152
                    wolfSSL_EVP_PKEY_free(pkey);
9153
                    return NULL;
9154
                }
9155
9156
                return pkey;
9157
            }
9158
            else {
9159
                WOLFSSL_MSG("DH wolfSSL_EVP_PKEY_new error");
9160
            }
9161
        }
9162
    }
9163
    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9164
    #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
9165
9166
    #if !defined(NO_DH) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA)
9167
    #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
9168
            (HAVE_FIPS_VERSION > 2))
9169
    {
9170
        word32  keyIdx = 0;
9171
        DhKey*  key = NULL;
9172
        int ret;
9173
        int elements;
9174
    #ifdef WOLFSSL_SMALL_STACK
9175
        DhKey* dh = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
9176
        if (dh == NULL)
9177
            return NULL;
9178
    #else
9179
        DhKey  dh[1];
9180
    #endif
9181
        XMEMSET(dh, 0, sizeof(DhKey));
9182
9183
        /* test if DH-public key */
9184
        if (wc_InitDhKey(dh) != 0)
9185
            return NULL;
9186
9187
        ret = wc_DhKeyDecode(mem, &keyIdx, dh, (word32)memSz);
9188
        wc_FreeDhKey(dh);
9189
    #ifdef WOLFSSL_SMALL_STACK
9190
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
9191
    #endif
9192
9193
        if (ret == 0) {
9194
            pkey = wolfSSL_EVP_PKEY_new();
9195
            if (pkey != NULL) {
9196
                pkey->type     = EVP_PKEY_DH;
9197
                pkey->pkey_sz  = (int)memSz;
9198
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
9199
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
9200
                               DYNAMIC_TYPE_PUBLIC_KEY);
9201
                if (pkey->pkey.ptr == NULL) {
9202
                    wolfSSL_EVP_PKEY_free(pkey);
9203
                    return NULL;
9204
                }
9205
                XMEMCPY(pkey->pkey.ptr, mem, memSz);
9206
                if (out != NULL) {
9207
                    *out = pkey;
9208
                }
9209
                pkey->ownDh = 1;
9210
                pkey->dh = wolfSSL_DH_new();
9211
                if (pkey->dh == NULL) {
9212
                    wolfSSL_EVP_PKEY_free(pkey);
9213
                    return NULL;
9214
                }
9215
9216
                key = (DhKey*)pkey->dh->internal;
9217
9218
                keyIdx = 0;
9219
                if (wc_DhKeyDecode(mem, &keyIdx, key, (word32)memSz) == 0)
9220
                {
9221
                    elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q | ELEMENT_PUB;
9222
                    if (priv)
9223
                        elements |= ELEMENT_PRV;
9224
                    if(SetDhExternal_ex(pkey->dh, elements)
9225
                            == WOLFSSL_SUCCESS ) {
9226
                        return pkey;
9227
                    }
9228
                }
9229
                else {
9230
                    wolfSSL_EVP_PKEY_free(pkey);
9231
                    return NULL;
9232
                }
9233
            }
9234
        }
9235
    }
9236
    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9237
    #endif /* !NO_DH &&  OPENSSL_EXTRA && WOLFSSL_DH_EXTRA */
9238
9239
    #ifdef HAVE_PQC
9240
    #ifdef HAVE_FALCON
9241
    {
9242
        int isFalcon = 0;
9243
    #ifdef WOLFSSL_SMALL_STACK
9244
        falcon_key *falcon = (falcon_key *)XMALLOC(sizeof(falcon_key), NULL,
9245
                                                  DYNAMIC_TYPE_FALCON);
9246
        if (falcon == NULL) {
9247
            return NULL;
9248
        }
9249
    #else
9250
        falcon_key falcon[1];
9251
    #endif
9252
9253
        if (wc_falcon_init(falcon) == 0) {
9254
            /* test if Falcon key */
9255
            if (priv) {
9256
                /* Try level 1 */
9257
                isFalcon = wc_falcon_set_level(falcon, 1) == 0 &&
9258
                           wc_falcon_import_private_only(mem, (word32)memSz,
9259
                                                         falcon) == 0;
9260
                if (!isFalcon) {
9261
                    /* Try level 5 */
9262
                    isFalcon = wc_falcon_set_level(falcon, 5) == 0 &&
9263
                               wc_falcon_import_private_only(mem, (word32)memSz,
9264
                                                             falcon) == 0;
9265
                }
9266
            } else {
9267
                /* Try level 1 */
9268
                isFalcon = wc_falcon_set_level(falcon, 1) == 0 &&
9269
                           wc_falcon_import_public(mem, (word32)memSz, falcon)
9270
                           == 0;
9271
9272
                if (!isFalcon) {
9273
                    /* Try level 5 */
9274
                    isFalcon = wc_falcon_set_level(falcon, 5) == 0 &&
9275
                               wc_falcon_import_public(mem, (word32)memSz,
9276
                                                       falcon) == 0;
9277
                }
9278
            }
9279
            wc_falcon_free(falcon);
9280
        }
9281
9282
    #ifdef WOLFSSL_SMALL_STACK
9283
        XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
9284
    #endif
9285
        if (isFalcon) {
9286
            /* Create a fake Falcon EVP_PKEY. In the future, we might integrate
9287
             * Falcon into the compatibility layer. */
9288
            pkey = wolfSSL_EVP_PKEY_new();
9289
            if (pkey == NULL) {
9290
                WOLFSSL_MSG("Falcon wolfSSL_EVP_PKEY_new error");
9291
                return NULL;
9292
            }
9293
            pkey->type = EVP_PKEY_FALCON;
9294
            pkey->pkey.ptr = NULL;
9295
            pkey->pkey_sz = 0;
9296
            return pkey;
9297
        }
9298
9299
    }
9300
    #endif /* HAVE_FALCON */
9301
    #ifdef HAVE_DILITHIUM
9302
    {
9303
        int isDilithium = 0;
9304
    #ifdef WOLFSSL_SMALL_STACK
9305
        dilithium_key *dilithium = (dilithium_key *)
9306
            XMALLOC(sizeof(dilithium_key), NULL, DYNAMIC_TYPE_DILITHIUM);
9307
        if (dilithium == NULL) {
9308
            return NULL;
9309
        }
9310
    #else
9311
        dilithium_key dilithium[1];
9312
    #endif
9313
9314
        if (wc_dilithium_init(dilithium) == 0) {
9315
            /* Test if Dilithium key. Try all levels for both SHAKE and AES */
9316
            if (priv) {
9317
                isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9318
                                  SHAKE_VARIANT) == 0 &&
9319
                              wc_dilithium_import_private_only(mem,
9320
                                  (word32)memSz, dilithium) == 0;
9321
                if (!isDilithium) {
9322
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9323
                                      SHAKE_VARIANT) == 0 &&
9324
                                  wc_dilithium_import_private_only(mem,
9325
                                      (word32)memSz, dilithium) == 0;
9326
                }
9327
                if (!isDilithium) {
9328
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9329
                                      SHAKE_VARIANT) == 0 &&
9330
                                  wc_dilithium_import_private_only(mem,
9331
                                      (word32)memSz, dilithium) == 0;
9332
                }
9333
                if (!isDilithium) {
9334
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9335
                                      AES_VARIANT) == 0 &&
9336
                                  wc_dilithium_import_private_only(mem,
9337
                                      (word32)memSz, dilithium) == 0;
9338
                }
9339
                if (!isDilithium) {
9340
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9341
                                      AES_VARIANT) == 0 &&
9342
                                  wc_dilithium_import_private_only(mem,
9343
                                      (word32)memSz, dilithium) == 0;
9344
                }
9345
                if (!isDilithium) {
9346
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9347
                                      AES_VARIANT) == 0 &&
9348
                                  wc_dilithium_import_private_only(mem,
9349
                                      (word32)memSz, dilithium) == 0;
9350
                }
9351
            } else {
9352
                isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9353
                                  SHAKE_VARIANT) == 0 &&
9354
                              wc_dilithium_import_public(mem, (word32)memSz,
9355
                                  dilithium) == 0;
9356
                if (!isDilithium) {
9357
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9358
                                      SHAKE_VARIANT) == 0 &&
9359
                                  wc_dilithium_import_public(mem, (word32)memSz,
9360
                                      dilithium) == 0;
9361
                }
9362
                if (!isDilithium) {
9363
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9364
                                      SHAKE_VARIANT) == 0 &&
9365
                                  wc_dilithium_import_public(mem, (word32)memSz,
9366
                                      dilithium) == 0;
9367
                }
9368
                if (!isDilithium) {
9369
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9370
                                      AES_VARIANT) == 0 &&
9371
                                  wc_dilithium_import_public(mem, (word32)memSz,
9372
                                      dilithium) == 0;
9373
                }
9374
                if (!isDilithium) {
9375
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9376
                                      AES_VARIANT) == 0 &&
9377
                                  wc_dilithium_import_public(mem, (word32)memSz,
9378
                                      dilithium) == 0;
9379
                }
9380
                if (!isDilithium) {
9381
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9382
                                      AES_VARIANT) == 0 &&
9383
                                  wc_dilithium_import_public(mem, (word32)memSz,
9384
                                      dilithium) == 0;
9385
                }
9386
            }
9387
            wc_dilithium_free(dilithium);
9388
        }
9389
9390
    #ifdef WOLFSSL_SMALL_STACK
9391
        XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
9392
    #endif
9393
        if (isDilithium) {
9394
            /* Create a fake Dilithium EVP_PKEY. In the future, we might
9395
             * integrate Dilithium into the compatibility layer. */
9396
            pkey = wolfSSL_EVP_PKEY_new();
9397
            if (pkey == NULL) {
9398
                WOLFSSL_MSG("Dilithium wolfSSL_EVP_PKEY_new error");
9399
                return NULL;
9400
            }
9401
            pkey->type = EVP_PKEY_DILITHIUM;
9402
            pkey->pkey.ptr = NULL;
9403
            pkey->pkey_sz = 0;
9404
            return pkey;
9405
        }
9406
9407
    }
9408
    #endif /* HAVE_DILITHIUM */
9409
    #endif /* HAVE_PQC */
9410
9411
    if (pkey == NULL) {
9412
        WOLFSSL_MSG("wolfSSL_d2i_PUBKEY couldn't determine key type");
9413
    }
9414
9415
    return pkey;
9416
9417
}
9418
#endif /* OPENSSL_EXTRA || WPA_SMALL */
9419
9420
#ifdef OPENSSL_EXTRA
9421
9422
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
9423
    WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey, const unsigned char** keyBuf, long keyLen)
9424
{
9425
    WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
9426
#ifdef WOLFSSL_PEM_TO_DER
9427
    int ret;
9428
    DerBuffer* der = NULL;
9429
9430
    if (keyBuf == NULL || *keyBuf == NULL || keyLen <= 0) {
9431
        WOLFSSL_MSG("Bad key PEM/DER args");
9432
        return NULL;
9433
    }
9434
9435
    ret = PemToDer(*keyBuf, keyLen, PRIVATEKEY_TYPE, &der, NULL, NULL, NULL);
9436
    if (ret < 0) {
9437
        WOLFSSL_MSG("Not PEM format");
9438
        ret = AllocDer(&der, (word32)keyLen, PRIVATEKEY_TYPE, NULL);
9439
        if (ret == 0) {
9440
            XMEMCPY(der->buffer, *keyBuf, keyLen);
9441
        }
9442
    }
9443
9444
    if (ret == 0) {
9445
        /* Verify this is PKCS8 Key */
9446
        word32 inOutIdx = 0;
9447
        word32 algId;
9448
        ret = ToTraditionalInline_ex(der->buffer, &inOutIdx, der->length, &algId);
9449
        if (ret >= 0) {
9450
            ret = 0; /* good DER */
9451
        }
9452
    }
9453
9454
    if (ret == 0) {
9455
        pkcs8 = wolfSSL_EVP_PKEY_new();
9456
        if (pkcs8 == NULL)
9457
            ret = MEMORY_E;
9458
    }
9459
    if (ret == 0) {
9460
        pkcs8->pkey.ptr = (char*)XMALLOC(der->length, NULL,
9461
            DYNAMIC_TYPE_PUBLIC_KEY);
9462
        if (pkcs8->pkey.ptr == NULL)
9463
            ret = MEMORY_E;
9464
    }
9465
    if (ret == 0) {
9466
        XMEMCPY(pkcs8->pkey.ptr, der->buffer, der->length);
9467
        pkcs8->pkey_sz = der->length;
9468
    }
9469
9470
    FreeDer(&der);
9471
    if (ret != 0) {
9472
        wolfSSL_EVP_PKEY_free(pkcs8);
9473
        pkcs8 = NULL;
9474
    }
9475
    if (pkey != NULL) {
9476
        *pkey = pkcs8;
9477
    }
9478
9479
#else
9480
    (void)bio;
9481
    (void)pkey;
9482
#endif /* WOLFSSL_PEM_TO_DER */
9483
9484
    return pkcs8;
9485
}
9486
9487
9488
#ifndef NO_BIO
9489
/* put SSL type in extra for now, not very common */
9490
9491
/* Converts a DER format key read from "bio" to a PKCS8 structure.
9492
 *
9493
 * bio  input bio to read DER from
9494
 * pkey If not NULL then this pointer will be overwritten with a new PKCS8
9495
 *      structure.
9496
 *
9497
 * returns a WOLFSSL_PKCS8_PRIV_KEY_INFO pointer on success and NULL in fail
9498
 *         case.
9499
 */
9500
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio(WOLFSSL_BIO* bio,
9501
        WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey)
9502
{
9503
    WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
9504
#ifdef WOLFSSL_PEM_TO_DER
9505
    unsigned char* mem = NULL;
9506
    int memSz;
9507
9508
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS8_PKEY_bio");
9509
9510
    if (bio == NULL) {
9511
        return NULL;
9512
    }
9513
9514
    if ((memSz = wolfSSL_BIO_get_mem_data(bio, &mem)) < 0) {
9515
        return NULL;
9516
    }
9517
9518
    pkcs8 = wolfSSL_d2i_PKCS8_PKEY(pkey, (const unsigned char**)&mem, memSz);
9519
#else
9520
    (void)bio;
9521
    (void)pkey;
9522
#endif /* WOLFSSL_PEM_TO_DER */
9523
9524
    return pkcs8;
9525
}
9526
9527
9528
/* expecting DER format public key
9529
 *
9530
 * bio  input bio to read DER from
9531
 * out  If not NULL then this pointer will be overwritten with a new
9532
 * WOLFSSL_EVP_PKEY pointer
9533
 *
9534
 * returns a WOLFSSL_EVP_PKEY pointer on success and NULL in fail case.
9535
 */
9536
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio,
9537
                                         WOLFSSL_EVP_PKEY** out)
9538
{
9539
    unsigned char* mem;
9540
    long memSz;
9541
    WOLFSSL_EVP_PKEY* pkey = NULL;
9542
9543
    WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY_bio()");
9544
9545
    if (bio == NULL) {
9546
        return NULL;
9547
    }
9548
    (void)out;
9549
9550
    memSz = wolfSSL_BIO_get_len(bio);
9551
    if (memSz <= 0) {
9552
        return NULL;
9553
    }
9554
9555
    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
9556
    if (mem == NULL) {
9557
        return NULL;
9558
    }
9559
9560
    if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
9561
        pkey = wolfSSL_d2i_PUBKEY(NULL, (const unsigned char**)&mem, memSz);
9562
        if (out != NULL && pkey != NULL) {
9563
            *out = pkey;
9564
        }
9565
    }
9566
9567
    XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
9568
    return pkey;
9569
}
9570
9571
#endif /* !NO_BIO */
9572
9573
9574
/* Converts a DER encoded public key to a WOLFSSL_EVP_PKEY structure.
9575
 *
9576
 * out  pointer to new WOLFSSL_EVP_PKEY structure. Can be NULL
9577
 * in   DER buffer to convert
9578
 * inSz size of in buffer
9579
 *
9580
 * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
9581
 *         on fail
9582
 */
9583
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
9584
                                     const unsigned char** in, long inSz)
9585
{
9586
    WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY");
9587
    return d2iGenericKey(out, in, inSz, 0);
9588
}
9589
9590
/* helper function to get raw pointer to DER buffer from WOLFSSL_EVP_PKEY */
9591
static int wolfSSL_EVP_PKEY_get_der(const WOLFSSL_EVP_PKEY* key, unsigned char** der)
9592
{
9593
    unsigned char* pt;
9594
    int sz;
9595
    word16 pkcs8HeaderSz;
9596
9597
    if (!key || !key->pkey_sz)
9598
        return WOLFSSL_FATAL_ERROR;
9599
9600
    /* return the key without PKCS8 for compatibility */
9601
    /* if pkcs8HeaderSz is invalid, use 0 and return all of pkey */
9602
    pkcs8HeaderSz = 0;
9603
    if (key->pkey_sz > key->pkcs8HeaderSz)
9604
        pkcs8HeaderSz = key->pkcs8HeaderSz;
9605
    sz = key->pkey_sz - pkcs8HeaderSz;
9606
    if (der) {
9607
        pt = (unsigned char*)key->pkey.ptr;
9608
        if (*der) {
9609
            /* since this function signature has no size value passed in it is
9610
             * assumed that the user has allocated a large enough buffer */
9611
            XMEMCPY(*der, pt + pkcs8HeaderSz, sz);
9612
            *der += sz;
9613
        }
9614
        else {
9615
            *der = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
9616
            if (*der == NULL) {
9617
                return WOLFSSL_FATAL_ERROR;
9618
            }
9619
            XMEMCPY(*der, pt + pkcs8HeaderSz, sz);
9620
        }
9621
    }
9622
    return sz;
9623
}
9624
9625
int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
9626
{
9627
    return wolfSSL_EVP_PKEY_get_der(key, der);
9628
}
9629
9630
static WOLFSSL_EVP_PKEY* _d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out,
9631
    const unsigned char **in, long inSz, int priv)
9632
{
9633
    int ret = 0;
9634
    word32 idx = 0, algId;
9635
    word16 pkcs8HeaderSz = 0;
9636
    WOLFSSL_EVP_PKEY* local;
9637
    int opt;
9638
9639
    (void)opt;
9640
9641
    if (in == NULL || inSz < 0) {
9642
        WOLFSSL_MSG("Bad argument");
9643
        return NULL;
9644
    }
9645
9646
    if (priv == 1) {
9647
        /* Check if input buffer has PKCS8 header. In the case that it does not
9648
         * have a PKCS8 header then do not error out. */
9649
        if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx,
9650
                                          (word32)inSz, &algId)) > 0) {
9651
            WOLFSSL_MSG("Found PKCS8 header");
9652
            pkcs8HeaderSz = (word16)idx;
9653
9654
            if ((type == EVP_PKEY_RSA && algId != RSAk
9655
            #ifdef WC_RSA_PSS
9656
                 && algId != RSAPSSk
9657
            #endif
9658
                 ) ||
9659
                (type == EVP_PKEY_EC && algId != ECDSAk) ||
9660
                (type == EVP_PKEY_DSA && algId != DSAk) ||
9661
                (type == EVP_PKEY_DH && algId != DHk)) {
9662
                WOLFSSL_MSG("PKCS8 does not match EVP key type");
9663
                return NULL;
9664
            }
9665
9666
            (void)idx; /* not used */
9667
        }
9668
        else {
9669
            if (ret != ASN_PARSE_E) {
9670
                WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 "
9671
                    "header");
9672
                return NULL;
9673
            }
9674
        }
9675
    }
9676
9677
    if (out != NULL && *out != NULL) {
9678
        wolfSSL_EVP_PKEY_free(*out);
9679
        *out = NULL;
9680
    }
9681
    local = wolfSSL_EVP_PKEY_new();
9682
    if (local == NULL) {
9683
        return NULL;
9684
    }
9685
9686
    local->type     = type;
9687
    local->pkey_sz  = (int)inSz;
9688
    local->pkcs8HeaderSz = pkcs8HeaderSz;
9689
    local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
9690
    if (local->pkey.ptr == NULL) {
9691
        wolfSSL_EVP_PKEY_free(local);
9692
        local = NULL;
9693
        return NULL;
9694
    }
9695
    else {
9696
        XMEMCPY(local->pkey.ptr, *in, inSz);
9697
    }
9698
9699
    switch (type) {
9700
#ifndef NO_RSA
9701
        case EVP_PKEY_RSA:
9702
            local->ownRsa = 1;
9703
            local->rsa = wolfSSL_RSA_new();
9704
            if (local->rsa == NULL) {
9705
                wolfSSL_EVP_PKEY_free(local);
9706
                return NULL;
9707
            }
9708
            opt = priv ? WOLFSSL_RSA_LOAD_PRIVATE : WOLFSSL_RSA_LOAD_PUBLIC;
9709
            if (wolfSSL_RSA_LoadDer_ex(local->rsa,
9710
                      (const unsigned char*)local->pkey.ptr, local->pkey_sz,
9711
                      opt) != WOLFSSL_SUCCESS) {
9712
                wolfSSL_EVP_PKEY_free(local);
9713
                return NULL;
9714
            }
9715
            break;
9716
#endif /* NO_RSA */
9717
#ifdef HAVE_ECC
9718
        case EVP_PKEY_EC:
9719
            local->ownEcc = 1;
9720
            local->ecc = wolfSSL_EC_KEY_new();
9721
            if (local->ecc == NULL) {
9722
                wolfSSL_EVP_PKEY_free(local);
9723
                return NULL;
9724
            }
9725
            opt = priv ? WOLFSSL_EC_KEY_LOAD_PRIVATE :
9726
                         WOLFSSL_EC_KEY_LOAD_PUBLIC;
9727
            if (wolfSSL_EC_KEY_LoadDer_ex(local->ecc,
9728
                      (const unsigned char*)local->pkey.ptr, local->pkey_sz,
9729
                      opt)
9730
                      != WOLFSSL_SUCCESS) {
9731
                wolfSSL_EVP_PKEY_free(local);
9732
                return NULL;
9733
            }
9734
            break;
9735
#endif /* HAVE_ECC */
9736
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
9737
#ifndef NO_DSA
9738
        case EVP_PKEY_DSA:
9739
            local->ownDsa = 1;
9740
            local->dsa = wolfSSL_DSA_new();
9741
            if (local->dsa == NULL) {
9742
                wolfSSL_EVP_PKEY_free(local);
9743
                return NULL;
9744
            }
9745
            opt = priv ? WOLFSSL_DSA_LOAD_PRIVATE : WOLFSSL_DSA_LOAD_PUBLIC;
9746
            if (wolfSSL_DSA_LoadDer_ex(local->dsa,
9747
                    (const unsigned char*)local->pkey.ptr, local->pkey_sz,
9748
                    opt)
9749
                    != WOLFSSL_SUCCESS) {
9750
                wolfSSL_EVP_PKEY_free(local);
9751
                return NULL;
9752
            }
9753
            break;
9754
#endif /* NO_DSA */
9755
#ifndef NO_DH
9756
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
9757
        case EVP_PKEY_DH:
9758
            local->ownDh = 1;
9759
            local->dh = wolfSSL_DH_new();
9760
            if (local->dh == NULL) {
9761
                wolfSSL_EVP_PKEY_free(local);
9762
                return NULL;
9763
            }
9764
            if (wolfSSL_DH_LoadDer(local->dh,
9765
                      (const unsigned char*)local->pkey.ptr, local->pkey_sz)
9766
                      != WOLFSSL_SUCCESS) {
9767
                wolfSSL_EVP_PKEY_free(local);
9768
                return NULL;
9769
            }
9770
            break;
9771
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9772
#endif /* HAVE_DH */
9773
#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH */
9774
        default:
9775
            WOLFSSL_MSG("Unsupported key type");
9776
            wolfSSL_EVP_PKEY_free(local);
9777
            return NULL;
9778
    }
9779
9780
    /* advance pointer with success */
9781
    if (local != NULL) {
9782
        if (local->pkey_sz <= (int)inSz) {
9783
            *in += local->pkey_sz;
9784
        }
9785
9786
        if (out != NULL) {
9787
            *out = local;
9788
        }
9789
    }
9790
9791
    return local;
9792
}
9793
9794
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out,
9795
        const unsigned char **in, long inSz)
9796
{
9797
    WOLFSSL_ENTER("wolfSSL_d2i_PublicKey");
9798
9799
    return _d2i_PublicKey(type, out, in, inSz, 0);
9800
}
9801
/* Reads in a DER format key. If PKCS8 headers are found they are stripped off.
9802
 *
9803
 * type  type of key
9804
 * out   newly created WOLFSSL_EVP_PKEY structure
9805
 * in    pointer to input key DER
9806
 * inSz  size of in buffer
9807
 *
9808
 * On success a non null pointer is returned and the pointer in is advanced the
9809
 * same number of bytes read.
9810
 */
9811
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
9812
        const unsigned char **in, long inSz)
9813
{
9814
    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey");
9815
9816
    return _d2i_PublicKey(type, out, in, inSz, 1);
9817
}
9818
9819
#ifdef WOLF_PRIVATE_KEY_ID
9820
/* Create an EVP structure for use with crypto callbacks */
9821
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_id(int type, WOLFSSL_EVP_PKEY** out,
9822
    void* heap, int devId)
9823
{
9824
    WOLFSSL_EVP_PKEY* local;
9825
9826
    if (out != NULL && *out != NULL) {
9827
        wolfSSL_EVP_PKEY_free(*out);
9828
        *out = NULL;
9829
    }
9830
9831
    local = wolfSSL_EVP_PKEY_new_ex(heap);
9832
    if (local == NULL) {
9833
        return NULL;
9834
    }
9835
9836
    local->type     = type;
9837
    local->pkey_sz  = 0;
9838
    local->pkcs8HeaderSz = 0;
9839
9840
    switch (type) {
9841
#ifndef NO_RSA
9842
        case EVP_PKEY_RSA:
9843
        {
9844
            RsaKey* key;
9845
            local->ownRsa = 1;
9846
            local->rsa = wolfSSL_RSA_new_ex(heap, devId);
9847
            if (local->rsa == NULL) {
9848
                wolfSSL_EVP_PKEY_free(local);
9849
                return NULL;
9850
            }
9851
            key = (RsaKey*)local->rsa->internal;
9852
        #ifdef WOLF_CRYPTO_CB
9853
            key->devId = devId;
9854
        #endif
9855
            (void)key;
9856
            local->rsa->inSet = 1;
9857
            break;
9858
        }
9859
#endif /* !NO_RSA */
9860
#ifdef HAVE_ECC
9861
        case EVP_PKEY_EC:
9862
        {
9863
            ecc_key* key;
9864
            local->ownEcc = 1;
9865
            local->ecc = wolfSSL_EC_KEY_new_ex(heap, devId);
9866
            if (local->ecc == NULL) {
9867
                wolfSSL_EVP_PKEY_free(local);
9868
                return NULL;
9869
            }
9870
            key = (ecc_key*)local->ecc->internal;
9871
        #ifdef WOLF_CRYPTO_CB
9872
            key->devId = devId;
9873
        #endif
9874
            key->type = ECC_PRIVATEKEY;
9875
            /* key is required to have a key size / curve set, although
9876
             * actual one used is determined by devId callback function */
9877
            wc_ecc_set_curve(key, ECDHE_SIZE, ECC_CURVE_DEF);
9878
9879
            local->ecc->inSet = 1;
9880
            break;
9881
        }
9882
#endif /* HAVE_ECC */
9883
        default:
9884
            WOLFSSL_MSG("Unsupported private key id type");
9885
            wolfSSL_EVP_PKEY_free(local);
9886
            return NULL;
9887
    }
9888
9889
    if (local != NULL && out != NULL) {
9890
        *out = local;
9891
    }
9892
9893
    return local;
9894
}
9895
#endif /* WOLF_PRIVATE_KEY_ID */
9896
9897
#ifndef NO_CERTS // NOLINT(readability-redundant-preprocessor)
9898
9899
#ifndef NO_CHECK_PRIVATE_KEY
9900
/* Check private against public in certificate for match
9901
 *
9902
 * ssl  WOLFSSL structure to check private key in
9903
 *
9904
 * Returns WOLFSSL_SUCCESS on good private key
9905
 *         WOLFSSL_FAILURE if mismatched. */
9906
int wolfSSL_check_private_key(const WOLFSSL* ssl)
9907
{
9908
    if (ssl == NULL) {
9909
        return WOLFSSL_FAILURE;
9910
    }
9911
    return check_cert_key(ssl->buffers.certificate, ssl->buffers.key, ssl->heap,
9912
        ssl->buffers.keyDevId, ssl->buffers.keyLabel, ssl->buffers.keyId);
9913
}
9914
#endif /* !NO_CHECK_PRIVATE_KEY */
9915
9916
#if defined(OPENSSL_ALL)
9917
9918
int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* str, int pos,
9919
    int val)
9920
{
9921
    int bytes_cnt, bit;
9922
    byte* temp;
9923
9924
    if (!str || (val != 0 && val != 1) || pos < 0) {
9925
        return WOLFSSL_FAILURE;
9926
    }
9927
9928
    bytes_cnt = pos/8;
9929
    bit = 1<<(7-(pos%8));
9930
9931
    if (bytes_cnt+1 > str->length) {
9932
        if (!(temp = (byte*)XREALLOC(str->data, bytes_cnt+1, NULL,
9933
                DYNAMIC_TYPE_OPENSSL))) {
9934
            return WOLFSSL_FAILURE;
9935
        }
9936
        XMEMSET(temp+str->length, 0, bytes_cnt+1 - str->length);
9937
        str->data = temp;
9938
        str->length = bytes_cnt+1;
9939
    }
9940
9941
    str->data[bytes_cnt] &= ~bit;
9942
    str->data[bytes_cnt] |= val ? bit : 0;
9943
9944
    return WOLFSSL_SUCCESS;
9945
}
9946
9947
#endif /* OPENSSL_ALL */
9948
9949
#endif /* !NO_CERTS */
9950
#endif /* OPENSSL_EXTRA */
9951
9952
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9953
WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void)
9954
{
9955
    WOLFSSL_ASN1_BIT_STRING* str;
9956
9957
    str = (WOLFSSL_ASN1_BIT_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_BIT_STRING),
9958
                                                  NULL, DYNAMIC_TYPE_OPENSSL);
9959
    if (str) {
9960
        XMEMSET(str, 0, sizeof(WOLFSSL_ASN1_BIT_STRING));
9961
    }
9962
    return str;
9963
}
9964
9965
void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING* str)
9966
{
9967
    if (str) {
9968
        if (str->data) {
9969
            XFREE(str->data, NULL, DYNAMIC_TYPE_OPENSSL);
9970
            str->data = NULL;
9971
        }
9972
        XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
9973
    }
9974
}
9975
9976
int wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING* str, int i)
9977
{
9978
    if (!str || !str->data || str->length <= (i/8) || i < 0) {
9979
        return WOLFSSL_FAILURE;
9980
    }
9981
9982
    return (str->data[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
9983
}
9984
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9985
9986
#ifdef OPENSSL_EXTRA
9987
9988
int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey)
9989
{
9990
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey");
9991
    if (ssl == NULL || pkey == NULL ) {
9992
        return WOLFSSL_FAILURE;
9993
    }
9994
9995
    return wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr,
9996
                                         pkey->pkey_sz, WOLFSSL_FILETYPE_ASN1);
9997
}
9998
9999
10000
int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, const unsigned char* der,
10001
                                long derSz)
10002
{
10003
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1");
10004
    if (ssl == NULL || der == NULL ) {
10005
        return WOLFSSL_FAILURE;
10006
    }
10007
10008
    (void)pri; /* type of private key */
10009
    return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
10010
}
10011
/******************************************************************************
10012
* wolfSSL_CTX_use_PrivateKey_ASN1 - loads a private key buffer into the SSL ctx
10013
*
10014
* RETURNS:
10015
* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
10016
*/
10017
10018
int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx,
10019
                                            unsigned char* der, long derSz)
10020
{
10021
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_ASN1");
10022
    if (ctx == NULL || der == NULL ) {
10023
        return WOLFSSL_FAILURE;
10024
    }
10025
10026
    (void)pri; /* type of private key */
10027
    return wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1);
10028
}
10029
10030
10031
#ifndef NO_RSA
10032
int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz)
10033
{
10034
    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1");
10035
    if (ssl == NULL || der == NULL ) {
10036
        return WOLFSSL_FAILURE;
10037
    }
10038
10039
    return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
10040
}
10041
#endif
10042
10043
int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509)
10044
{
10045
    long idx;
10046
10047
    WOLFSSL_ENTER("wolfSSL_use_certificate");
10048
    if (x509 != NULL && ssl != NULL && x509->derCert != NULL) {
10049
        if (ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length,
10050
                          WOLFSSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0,
10051
                          GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10052
            return WOLFSSL_SUCCESS;
10053
        }
10054
    }
10055
10056
    (void)idx;
10057
    return WOLFSSL_FAILURE;
10058
}
10059
10060
#endif /* OPENSSL_EXTRA */
10061
10062
int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, const unsigned char* der,
10063
                                 int derSz)
10064
0
{
10065
0
    long idx;
10066
10067
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1");
10068
0
    if (der != NULL && ssl != NULL) {
10069
0
        if (ProcessBuffer(NULL, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
10070
0
                ssl, &idx, 0, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10071
0
            return WOLFSSL_SUCCESS;
10072
0
        }
10073
0
    }
10074
10075
0
    (void)idx;
10076
0
    return WOLFSSL_FAILURE;
10077
0
}
10078
10079
#ifndef NO_FILESYSTEM
10080
10081
WOLFSSL_ABI
10082
int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
10083
0
{
10084
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_file");
10085
10086
0
    if (ssl == NULL) {
10087
0
        return BAD_FUNC_ARG;
10088
0
    }
10089
10090
0
    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
10091
0
                ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10092
0
        return WOLFSSL_SUCCESS;
10093
0
    }
10094
10095
0
    return WOLFSSL_FAILURE;
10096
0
}
10097
10098
10099
WOLFSSL_ABI
10100
int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
10101
0
{
10102
0
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
10103
10104
0
    if (ssl == NULL) {
10105
0
        return BAD_FUNC_ARG;
10106
0
    }
10107
10108
0
    if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
10109
0
                ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10110
0
        return WOLFSSL_SUCCESS;
10111
0
    }
10112
10113
0
    return WOLFSSL_FAILURE;
10114
0
}
10115
10116
10117
WOLFSSL_ABI
10118
int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
10119
0
{
10120
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
10121
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
10122
10123
0
    if (ssl == NULL) {
10124
0
        return BAD_FUNC_ARG;
10125
0
    }
10126
10127
0
    if (ProcessFile(ssl->ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE,
10128
0
               ssl, 1, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10129
0
        return WOLFSSL_SUCCESS;
10130
0
    }
10131
10132
0
   return WOLFSSL_FAILURE;
10133
0
}
10134
10135
int wolfSSL_use_certificate_chain_file_format(WOLFSSL* ssl, const char* file,
10136
                                              int format)
10137
0
{
10138
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
10139
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file_format");
10140
10141
0
    if (ssl == NULL) {
10142
0
        return BAD_FUNC_ARG;
10143
0
    }
10144
10145
0
    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 1,
10146
0
                    NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10147
0
        return WOLFSSL_SUCCESS;
10148
0
    }
10149
0
    return WOLFSSL_FAILURE;
10150
0
}
10151
10152
#endif /* !NO_FILESYSTEM */
10153
10154
#ifdef HAVE_ECC
10155
10156
/* Set Temp CTX EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
10157
int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
10158
0
{
10159
0
    if (ctx == NULL)
10160
0
        return BAD_FUNC_ARG;
10161
10162
    /* if 0 then get from loaded private key */
10163
0
    if (sz == 0) {
10164
        /* applies only to ECDSA */
10165
0
        if (ctx->privateKeyType != ecc_dsa_sa_algo)
10166
0
            return WOLFSSL_SUCCESS;
10167
10168
0
        if (ctx->privateKeySz == 0) {
10169
0
            WOLFSSL_MSG("Must set private key/cert first");
10170
0
            return BAD_FUNC_ARG;
10171
0
        }
10172
10173
0
        sz = (word16)ctx->privateKeySz;
10174
0
    }
10175
10176
    /* check size */
10177
0
    if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
10178
0
        return BAD_FUNC_ARG;
10179
10180
0
    ctx->eccTempKeySz = sz;
10181
10182
0
    return WOLFSSL_SUCCESS;
10183
0
}
10184
10185
10186
/* Set Temp SSL EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
10187
int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
10188
0
{
10189
0
    if (ssl == NULL)
10190
0
        return BAD_FUNC_ARG;
10191
10192
    /* check size */
10193
0
    if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
10194
0
        return BAD_FUNC_ARG;
10195
10196
0
    ssl->eccTempKeySz = sz;
10197
10198
0
    return WOLFSSL_SUCCESS;
10199
0
}
10200
10201
#endif /* HAVE_ECC */
10202
10203
10204
#ifdef OPENSSL_EXTRA
10205
10206
#ifndef NO_FILESYSTEM
10207
int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
10208
                                   int format)
10209
{
10210
    WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
10211
10212
    return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
10213
}
10214
10215
10216
int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
10217
{
10218
    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
10219
10220
    return wolfSSL_use_PrivateKey_file(ssl, file, format);
10221
}
10222
#endif /* NO_FILESYSTEM */
10223
10224
10225
/* Copies the master secret over to out buffer. If outSz is 0 returns the size
10226
 * of master secret.
10227
 *
10228
 * ses : a session from completed TLS/SSL handshake
10229
 * out : buffer to hold copy of master secret
10230
 * outSz : size of out buffer
10231
 * returns : number of bytes copied into out buffer on success
10232
 *           less then or equal to 0 is considered a failure case
10233
 */
10234
int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
10235
        unsigned char* out, int outSz)
10236
{
10237
    int size;
10238
10239
    ses = ClientSessionToSession(ses);
10240
10241
    if (outSz == 0) {
10242
        return SECRET_LEN;
10243
    }
10244
10245
    if (ses == NULL || out == NULL || outSz < 0) {
10246
        return 0;
10247
    }
10248
10249
    if (outSz > SECRET_LEN) {
10250
        size = SECRET_LEN;
10251
    }
10252
    else {
10253
        size = outSz;
10254
    }
10255
10256
    XMEMCPY(out, ses->masterSecret, size);
10257
    return size;
10258
}
10259
10260
10261
int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses)
10262
{
10263
    (void)ses;
10264
    return SECRET_LEN;
10265
}
10266
10267
#ifdef WOLFSSL_EARLY_DATA
10268
unsigned int wolfSSL_SESSION_get_max_early_data(const WOLFSSL_SESSION *session)
10269
{
10270
    return session->maxEarlyDataSz;
10271
}
10272
#endif /* WOLFSSL_EARLY_DATA */
10273
10274
#endif /* OPENSSL_EXTRA */
10275
10276
typedef struct {
10277
    byte verifyPeer:1;
10278
    byte verifyNone:1;
10279
    byte failNoCert:1;
10280
    byte failNoCertxPSK:1;
10281
    byte verifyPostHandshake:1;
10282
} SetVerifyOptions;
10283
10284
static SetVerifyOptions ModeToVerifyOptions(int mode)
10285
0
{
10286
0
    SetVerifyOptions opts;
10287
0
    XMEMSET(&opts, 0, sizeof(SetVerifyOptions));
10288
10289
0
    if (mode != WOLFSSL_VERIFY_DEFAULT) {
10290
0
        opts.verifyNone = (mode == WOLFSSL_VERIFY_NONE);
10291
0
        if (!opts.verifyNone) {
10292
0
            opts.verifyPeer =
10293
0
                    (mode & WOLFSSL_VERIFY_PEER) != 0;
10294
0
            opts.failNoCertxPSK =
10295
0
                    (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) != 0;
10296
0
            opts.failNoCert =
10297
0
                    (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) != 0;
10298
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10299
            opts.verifyPostHandshake =
10300
                    (mode & WOLFSSL_VERIFY_POST_HANDSHAKE) != 0;
10301
#endif
10302
0
        }
10303
0
    }
10304
10305
0
    return opts;
10306
0
}
10307
10308
WOLFSSL_ABI
10309
void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
10310
0
{
10311
0
    SetVerifyOptions opts;
10312
10313
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
10314
0
    if (ctx == NULL)
10315
0
        return;
10316
10317
0
    opts = ModeToVerifyOptions(mode);
10318
10319
0
    ctx->verifyNone     = opts.verifyNone;
10320
0
    ctx->verifyPeer     = opts.verifyPeer;
10321
0
    ctx->failNoCert     = opts.failNoCert;
10322
0
    ctx->failNoCertxPSK = opts.failNoCertxPSK;
10323
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10324
    ctx->verifyPostHandshake = opts.verifyPostHandshake;
10325
#endif
10326
10327
0
    ctx->verifyCallback = vc;
10328
0
}
10329
10330
#ifdef OPENSSL_ALL
10331
void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx,
10332
    CertVerifyCallback cb, void* arg)
10333
{
10334
    WOLFSSL_ENTER("SSL_CTX_set_cert_verify_callback");
10335
    if (ctx == NULL)
10336
        return;
10337
10338
    ctx->verifyCertCb = cb;
10339
    ctx->verifyCertCbArg = arg;
10340
}
10341
#endif
10342
10343
10344
void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
10345
0
{
10346
0
    SetVerifyOptions opts;
10347
10348
0
    WOLFSSL_ENTER("wolfSSL_set_verify");
10349
0
    if (ssl == NULL)
10350
0
        return;
10351
10352
0
    opts = ModeToVerifyOptions(mode);
10353
10354
0
    ssl->options.verifyNone = opts.verifyNone;
10355
0
    ssl->options.verifyPeer = opts.verifyPeer;
10356
0
    ssl->options.failNoCert = opts.failNoCert;
10357
0
    ssl->options.failNoCertxPSK = opts.failNoCertxPSK;
10358
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10359
    ssl->options.verifyPostHandshake = opts.verifyPostHandshake;
10360
#endif
10361
10362
0
    ssl->verifyCallback = vc;
10363
0
}
10364
10365
void wolfSSL_set_verify_result(WOLFSSL *ssl, long v)
10366
0
{
10367
0
    WOLFSSL_ENTER("wolfSSL_set_verify_result");
10368
10369
0
    if (ssl == NULL)
10370
0
        return;
10371
10372
#ifdef OPENSSL_ALL
10373
    ssl->verifyCallbackResult = v;
10374
#else
10375
0
    (void)v;
10376
0
    WOLFSSL_STUB("wolfSSL_set_verify_result");
10377
0
#endif
10378
0
}
10379
10380
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
10381
    defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10382
/* For TLS v1.3 send handshake messages after handshake completes. */
10383
/* Returns 1=WOLFSSL_SUCCESS or 0=WOLFSSL_FAILURE */
10384
int wolfSSL_verify_client_post_handshake(WOLFSSL* ssl)
10385
{
10386
    int ret = wolfSSL_request_certificate(ssl);
10387
    if (ret != WOLFSSL_SUCCESS) {
10388
        if (!IsAtLeastTLSv1_3(ssl->version)) {
10389
            /* specific error of wrong version expected */
10390
            WOLFSSL_ERROR(UNSUPPORTED_PROTO_VERSION);
10391
10392
        }
10393
        else {
10394
            WOLFSSL_ERROR(ret); /* log the error in the error queue */
10395
        }
10396
    }
10397
    return (ret == WOLFSSL_SUCCESS) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
10398
}
10399
10400
int wolfSSL_CTX_set_post_handshake_auth(WOLFSSL_CTX* ctx, int val)
10401
{
10402
    int ret = wolfSSL_CTX_allow_post_handshake_auth(ctx);
10403
    if (ret == 0) {
10404
        ctx->postHandshakeAuth = (val != 0);
10405
    }
10406
    return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
10407
}
10408
int wolfSSL_set_post_handshake_auth(WOLFSSL* ssl, int val)
10409
{
10410
    int ret = wolfSSL_allow_post_handshake_auth(ssl);
10411
    if (ret == 0) {
10412
        ssl->options.postHandshakeAuth = (val != 0);
10413
    }
10414
    return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
10415
}
10416
#endif /* OPENSSL_EXTRA && !NO_CERTS && WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
10417
10418
/* store user ctx for verify callback */
10419
void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
10420
0
{
10421
0
    WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
10422
0
    if (ssl)
10423
0
        ssl->verifyCbCtx = ctx;
10424
0
}
10425
10426
10427
/* store user ctx for verify callback */
10428
void wolfSSL_CTX_SetCertCbCtx(WOLFSSL_CTX* ctx, void* userCtx)
10429
0
{
10430
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetCertCbCtx");
10431
0
    if (ctx)
10432
0
        ctx->verifyCbCtx = userCtx;
10433
0
}
10434
10435
10436
/* store context CA Cache addition callback */
10437
void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
10438
0
{
10439
0
    if (ctx && ctx->cm)
10440
0
        ctx->cm->caCacheCallback = cb;
10441
0
}
10442
10443
10444
#if defined(PERSIST_CERT_CACHE)
10445
10446
#if !defined(NO_FILESYSTEM)
10447
10448
/* Persist cert cache to file */
10449
int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
10450
{
10451
    WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
10452
10453
    if (ctx == NULL || fname == NULL)
10454
        return BAD_FUNC_ARG;
10455
10456
    return CM_SaveCertCache(ctx->cm, fname);
10457
}
10458
10459
10460
/* Persist cert cache from file */
10461
int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
10462
{
10463
    WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
10464
10465
    if (ctx == NULL || fname == NULL)
10466
        return BAD_FUNC_ARG;
10467
10468
    return CM_RestoreCertCache(ctx->cm, fname);
10469
}
10470
10471
#endif /* NO_FILESYSTEM */
10472
10473
/* Persist cert cache to memory */
10474
int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
10475
                                   int sz, int* used)
10476
{
10477
    WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
10478
10479
    if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
10480
        return BAD_FUNC_ARG;
10481
10482
    return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
10483
}
10484
10485
10486
/* Restore cert cache from memory */
10487
int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
10488
{
10489
    WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
10490
10491
    if (ctx == NULL || mem == NULL || sz <= 0)
10492
        return BAD_FUNC_ARG;
10493
10494
    return CM_MemRestoreCertCache(ctx->cm, mem, sz);
10495
}
10496
10497
10498
/* get how big the the cert cache save buffer needs to be */
10499
int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
10500
{
10501
    WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
10502
10503
    if (ctx == NULL)
10504
        return BAD_FUNC_ARG;
10505
10506
    return CM_GetCertCacheMemSize(ctx->cm);
10507
}
10508
10509
#endif /* PERSIST_CERT_CACHE */
10510
#endif /* !NO_CERTS */
10511
10512
10513
#ifndef NO_SESSION_CACHE
10514
10515
WOLFSSL_ABI
10516
WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
10517
0
{
10518
0
    WOLFSSL_ENTER("SSL_get_session");
10519
0
    if (ssl) {
10520
#ifdef NO_SESSION_CACHE_REF
10521
        return ssl->session;
10522
#else
10523
0
        if (ssl->options.side == WOLFSSL_CLIENT_END) {
10524
            /* On the client side we want to return a persistant reference for
10525
             * backwards compatibility. */
10526
0
#ifndef NO_CLIENT_CACHE
10527
0
            if (ssl->clientSession) {
10528
0
                return (WOLFSSL_SESSION*)ssl->clientSession;
10529
0
            }
10530
0
            else {
10531
                /* Try to add a ClientCache entry to associate with the current
10532
                 * session. Ignore any session cache options. */
10533
0
                int err;
10534
0
                const byte* id = ssl->session->sessionID;
10535
0
                byte idSz = ssl->session->sessionIDSz;
10536
0
                if (ssl->session->haveAltSessionID) {
10537
0
                    id = ssl->session->altSessionID;
10538
0
                    idSz = ID_LEN;
10539
0
                }
10540
0
                err = AddSessionToCache(ssl->ctx, ssl->session, id, idSz,
10541
0
                        NULL, ssl->session->side,
10542
                #ifdef HAVE_SESSION_TICKET
10543
                        ssl->session->ticketLen > 0,
10544
                #else
10545
0
                        0,
10546
0
                #endif
10547
0
                        &ssl->clientSession);
10548
0
                if (err == 0) {
10549
0
                    return (WOLFSSL_SESSION*)ssl->clientSession;
10550
0
                }
10551
0
            }
10552
0
#endif
10553
0
        }
10554
0
        else {
10555
0
            return ssl->session;
10556
0
        }
10557
0
#endif
10558
0
    }
10559
10560
0
    return NULL;
10561
0
}
10562
10563
/* The get1 version requires caller to call SSL_SESSION_free */
10564
WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
10565
0
{
10566
0
    WOLFSSL_SESSION* sess = NULL;
10567
0
    WOLFSSL_ENTER("SSL_get1_session");
10568
0
    if (ssl != NULL) {
10569
0
        sess = ssl->session;
10570
0
        if (sess != NULL) {
10571
            /* increase reference count if allocated session */
10572
0
            if (sess->type == WOLFSSL_SESSION_TYPE_HEAP) {
10573
0
                if (wolfSSL_SESSION_up_ref(sess) != WOLFSSL_SUCCESS)
10574
0
                    sess = NULL;
10575
0
            }
10576
0
        }
10577
0
    }
10578
0
    return sess;
10579
0
}
10580
10581
10582
/*
10583
 * Sets the session object to use when establishing a TLS/SSL session using
10584
 * the ssl object. Therefore, this function must be called before
10585
 * wolfSSL_connect. The session object to use can be obtained in a previous
10586
 * TLS/SSL connection using wolfSSL_get_session.
10587
 *
10588
 * This function rejects the session if it has been expired when this function
10589
 * is called. Note that this expiration check is wolfSSL specific and differs
10590
 * from OpenSSL return code behavior.
10591
 *
10592
 * By default, wolfSSL_set_session returns WOLFSSL_SUCCESS on successfully
10593
 * setting the session, WOLFSSL_FAILURE on failure due to the session cache
10594
 * being disabled, or the session has expired.
10595
 *
10596
 * To match OpenSSL return code behavior when session is expired, define
10597
 * OPENSSL_EXTRA and WOLFSSL_ERROR_CODE_OPENSSL. This behavior will return
10598
 * WOLFSSL_SUCCESS even when the session is expired and rejected.
10599
 */
10600
WOLFSSL_ABI
10601
int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
10602
0
{
10603
0
    WOLFSSL_ENTER("SSL_set_session");
10604
0
    if (session)
10605
0
        return wolfSSL_SetSession(ssl, session);
10606
10607
0
    return WOLFSSL_FAILURE;
10608
0
}
10609
10610
10611
#ifndef NO_CLIENT_CACHE
10612
10613
/* Associate client session with serverID, find existing or store for saving
10614
   if newSession flag on, don't reuse existing session
10615
   WOLFSSL_SUCCESS on ok */
10616
int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
10617
0
{
10618
0
    WOLFSSL_SESSION* session = NULL;
10619
10620
0
    WOLFSSL_ENTER("wolfSSL_SetServerID");
10621
10622
0
    if (ssl == NULL || id == NULL || len <= 0)
10623
0
        return BAD_FUNC_ARG;
10624
10625
0
    if (newSession == 0) {
10626
0
        session = wolfSSL_GetSessionClient(ssl, id, len);
10627
0
        if (session) {
10628
0
            if (wolfSSL_SetSession(ssl, session) != WOLFSSL_SUCCESS) {
10629
            #ifdef HAVE_EXT_CACHE
10630
                wolfSSL_FreeSession(ssl->ctx, session);
10631
            #endif
10632
0
                WOLFSSL_MSG("wolfSSL_SetSession failed");
10633
0
                session = NULL;
10634
0
            }
10635
0
        }
10636
0
    }
10637
10638
0
    if (session == NULL) {
10639
0
        WOLFSSL_MSG("Valid ServerID not cached already");
10640
10641
0
        ssl->session->idLen = (word16)min(SERVER_ID_LEN, (word32)len);
10642
0
        XMEMCPY(ssl->session->serverID, id, ssl->session->idLen);
10643
0
    }
10644
#ifdef HAVE_EXT_CACHE
10645
    else {
10646
        wolfSSL_FreeSession(ssl->ctx, session);
10647
    }
10648
#endif
10649
10650
0
    return WOLFSSL_SUCCESS;
10651
0
}
10652
10653
#endif /* !NO_CLIENT_CACHE */
10654
10655
#if defined(PERSIST_SESSION_CACHE)
10656
10657
/* for persistence, if changes to layout need to increment and modify
10658
   save_session_cache() and restore_session_cache and memory versions too */
10659
#define WOLFSSL_CACHE_VERSION 2
10660
10661
/* Session Cache Header information */
10662
typedef struct {
10663
    int version;     /* cache layout version id */
10664
    int rows;        /* session rows */
10665
    int columns;     /* session columns */
10666
    int sessionSz;   /* sizeof WOLFSSL_SESSION */
10667
} cache_header_t;
10668
10669
/* current persistence layout is:
10670
10671
   1) cache_header_t
10672
   2) SessionCache
10673
   3) ClientCache
10674
10675
   update WOLFSSL_CACHE_VERSION if change layout for the following
10676
   PERSISTENT_SESSION_CACHE functions
10677
*/
10678
10679
10680
/* get how big the the session cache save buffer needs to be */
10681
int wolfSSL_get_session_cache_memsize(void)
10682
{
10683
    int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
10684
#ifndef NO_CLIENT_CACHE
10685
    sz += (int)(sizeof(ClientCache));
10686
#endif
10687
    return sz;
10688
}
10689
10690
10691
/* Persist session cache to memory */
10692
int wolfSSL_memsave_session_cache(void* mem, int sz)
10693
{
10694
    int i;
10695
    cache_header_t cache_header;
10696
    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
10697
10698
    WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
10699
10700
    if (sz < wolfSSL_get_session_cache_memsize()) {
10701
        WOLFSSL_MSG("Memory buffer too small");
10702
        return BUFFER_E;
10703
    }
10704
10705
    cache_header.version   = WOLFSSL_CACHE_VERSION;
10706
    cache_header.rows      = SESSION_ROWS;
10707
    cache_header.columns   = SESSIONS_PER_ROW;
10708
    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
10709
    XMEMCPY(mem, &cache_header, sizeof(cache_header));
10710
10711
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10712
    if (wc_LockMutex(&session_mutex) != 0) {
10713
        WOLFSSL_MSG("Session cache mutex lock failed");
10714
        return BAD_MUTEX_E;
10715
    }
10716
#endif
10717
    for (i = 0; i < cache_header.rows; ++i) {
10718
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10719
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10720
            WOLFSSL_MSG("Session row cache mutex lock failed");
10721
            return BAD_MUTEX_E;
10722
        }
10723
    #endif
10724
10725
        XMEMCPY(row++, &SessionCache[i], SIZEOF_SESSION_ROW);
10726
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10727
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10728
    #endif
10729
    }
10730
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10731
    wc_UnLockMutex(&session_mutex);
10732
#endif
10733
10734
#ifndef NO_CLIENT_CACHE
10735
    if (wc_LockMutex(&clisession_mutex) != 0) {
10736
        WOLFSSL_MSG("Client cache mutex lock failed");
10737
        return BAD_MUTEX_E;
10738
    }
10739
    XMEMCPY(row, ClientCache, sizeof(ClientCache));
10740
    wc_UnLockMutex(&clisession_mutex);
10741
#endif
10742
10743
    WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", WOLFSSL_SUCCESS);
10744
10745
    return WOLFSSL_SUCCESS;
10746
}
10747
10748
10749
/* Restore the persistent session cache from memory */
10750
int wolfSSL_memrestore_session_cache(const void* mem, int sz)
10751
{
10752
    int    i;
10753
    cache_header_t cache_header;
10754
    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
10755
10756
    WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
10757
10758
    if (sz < wolfSSL_get_session_cache_memsize()) {
10759
        WOLFSSL_MSG("Memory buffer too small");
10760
        return BUFFER_E;
10761
    }
10762
10763
    XMEMCPY(&cache_header, mem, sizeof(cache_header));
10764
    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
10765
        cache_header.rows      != SESSION_ROWS ||
10766
        cache_header.columns   != SESSIONS_PER_ROW ||
10767
        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
10768
10769
        WOLFSSL_MSG("Session cache header match failed");
10770
        return CACHE_MATCH_ERROR;
10771
    }
10772
10773
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10774
    if (wc_LockMutex(&session_mutex) != 0) {
10775
        WOLFSSL_MSG("Session cache mutex lock failed");
10776
        return BAD_MUTEX_E;
10777
    }
10778
#endif
10779
    for (i = 0; i < cache_header.rows; ++i) {
10780
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10781
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10782
            WOLFSSL_MSG("Session row cache mutex lock failed");
10783
            return BAD_MUTEX_E;
10784
        }
10785
    #endif
10786
10787
        XMEMCPY(&SessionCache[i], row++, SIZEOF_SESSION_ROW);
10788
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10789
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10790
    #endif
10791
    }
10792
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10793
    wc_UnLockMutex(&session_mutex);
10794
#endif
10795
10796
#ifndef NO_CLIENT_CACHE
10797
    if (wc_LockMutex(&clisession_mutex) != 0) {
10798
        WOLFSSL_MSG("Client cache mutex lock failed");
10799
        return BAD_MUTEX_E;
10800
    }
10801
    XMEMCPY(ClientCache, row, sizeof(ClientCache));
10802
    wc_UnLockMutex(&clisession_mutex);
10803
#endif
10804
10805
    WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", WOLFSSL_SUCCESS);
10806
10807
    return WOLFSSL_SUCCESS;
10808
}
10809
10810
#if !defined(NO_FILESYSTEM)
10811
10812
/* Persist session cache to file */
10813
/* doesn't use memsave because of additional memory use */
10814
int wolfSSL_save_session_cache(const char *fname)
10815
{
10816
    XFILE  file;
10817
    int    ret;
10818
    int    rc = WOLFSSL_SUCCESS;
10819
    int    i;
10820
    cache_header_t cache_header;
10821
10822
    WOLFSSL_ENTER("wolfSSL_save_session_cache");
10823
10824
    file = XFOPEN(fname, "w+b");
10825
    if (file == XBADFILE) {
10826
        WOLFSSL_MSG("Couldn't open session cache save file");
10827
        return WOLFSSL_BAD_FILE;
10828
    }
10829
    cache_header.version   = WOLFSSL_CACHE_VERSION;
10830
    cache_header.rows      = SESSION_ROWS;
10831
    cache_header.columns   = SESSIONS_PER_ROW;
10832
    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
10833
10834
    /* cache header */
10835
    ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
10836
    if (ret != 1) {
10837
        WOLFSSL_MSG("Session cache header file write failed");
10838
        XFCLOSE(file);
10839
        return FWRITE_ERROR;
10840
    }
10841
10842
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10843
    if (wc_LockMutex(&session_mutex) != 0) {
10844
        WOLFSSL_MSG("Session cache mutex lock failed");
10845
        XFCLOSE(file);
10846
        return BAD_MUTEX_E;
10847
    }
10848
#endif
10849
    /* session cache */
10850
    for (i = 0; i < cache_header.rows; ++i) {
10851
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10852
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10853
            WOLFSSL_MSG("Session row cache mutex lock failed");
10854
            XFCLOSE(file);
10855
            return BAD_MUTEX_E;
10856
        }
10857
    #endif
10858
10859
        ret = (int)XFWRITE(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
10860
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10861
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10862
    #endif
10863
        if (ret != 1) {
10864
            WOLFSSL_MSG("Session cache member file write failed");
10865
            rc = FWRITE_ERROR;
10866
            break;
10867
        }
10868
    }
10869
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10870
    wc_UnLockMutex(&session_mutex);
10871
#endif
10872
10873
#ifndef NO_CLIENT_CACHE
10874
    /* client cache */
10875
    if (wc_LockMutex(&clisession_mutex) != 0) {
10876
        WOLFSSL_MSG("Client cache mutex lock failed");
10877
        XFCLOSE(file);
10878
        return BAD_MUTEX_E;
10879
    }
10880
    ret = (int)XFWRITE(ClientCache, sizeof(ClientCache), 1, file);
10881
    if (ret != 1) {
10882
        WOLFSSL_MSG("Client cache member file write failed");
10883
        rc = FWRITE_ERROR;
10884
    }
10885
    wc_UnLockMutex(&clisession_mutex);
10886
#endif /* !NO_CLIENT_CACHE */
10887
10888
    XFCLOSE(file);
10889
    WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
10890
10891
    return rc;
10892
}
10893
10894
10895
/* Restore the persistent session cache from file */
10896
/* doesn't use memstore because of additional memory use */
10897
int wolfSSL_restore_session_cache(const char *fname)
10898
{
10899
    XFILE  file;
10900
    int    rc = WOLFSSL_SUCCESS;
10901
    int    ret;
10902
    int    i;
10903
    cache_header_t cache_header;
10904
10905
    WOLFSSL_ENTER("wolfSSL_restore_session_cache");
10906
10907
    file = XFOPEN(fname, "rb");
10908
    if (file == XBADFILE) {
10909
        WOLFSSL_MSG("Couldn't open session cache save file");
10910
        return WOLFSSL_BAD_FILE;
10911
    }
10912
    /* cache header */
10913
    ret = (int)XFREAD(&cache_header, sizeof(cache_header), 1, file);
10914
    if (ret != 1) {
10915
        WOLFSSL_MSG("Session cache header file read failed");
10916
        XFCLOSE(file);
10917
        return FREAD_ERROR;
10918
    }
10919
    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
10920
        cache_header.rows      != SESSION_ROWS ||
10921
        cache_header.columns   != SESSIONS_PER_ROW ||
10922
        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
10923
10924
        WOLFSSL_MSG("Session cache header match failed");
10925
        XFCLOSE(file);
10926
        return CACHE_MATCH_ERROR;
10927
    }
10928
10929
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10930
    if (wc_LockMutex(&session_mutex) != 0) {
10931
        WOLFSSL_MSG("Session cache mutex lock failed");
10932
        XFCLOSE(file);
10933
        return BAD_MUTEX_E;
10934
    }
10935
#endif
10936
    /* session cache */
10937
    for (i = 0; i < cache_header.rows; ++i) {
10938
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10939
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10940
            WOLFSSL_MSG("Session row cache mutex lock failed");
10941
            XFCLOSE(file);
10942
            return BAD_MUTEX_E;
10943
        }
10944
    #endif
10945
10946
        ret = (int)XFREAD(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
10947
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10948
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10949
    #endif
10950
        if (ret != 1) {
10951
            WOLFSSL_MSG("Session cache member file read failed");
10952
            XMEMSET(SessionCache, 0, sizeof SessionCache);
10953
            rc = FREAD_ERROR;
10954
            break;
10955
        }
10956
    }
10957
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10958
    wc_UnLockMutex(&session_mutex);
10959
#endif
10960
10961
#ifndef NO_CLIENT_CACHE
10962
    /* client cache */
10963
    if (wc_LockMutex(&clisession_mutex) != 0) {
10964
        WOLFSSL_MSG("Client cache mutex lock failed");
10965
        XFCLOSE(file);
10966
        return BAD_MUTEX_E;
10967
    }
10968
    ret = (int)XFREAD(ClientCache, sizeof(ClientCache), 1, file);
10969
    if (ret != 1) {
10970
        WOLFSSL_MSG("Client cache member file read failed");
10971
        XMEMSET(ClientCache, 0, sizeof ClientCache);
10972
        rc = FREAD_ERROR;
10973
    }
10974
    wc_UnLockMutex(&clisession_mutex);
10975
#endif /* !NO_CLIENT_CACHE */
10976
10977
    XFCLOSE(file);
10978
    WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
10979
10980
    return rc;
10981
}
10982
10983
#endif /* !NO_FILESYSTEM */
10984
#endif /* PERSIST_SESSION_CACHE */
10985
#endif /* NO_SESSION_CACHE */
10986
10987
10988
void wolfSSL_load_error_strings(void)
10989
0
{
10990
    /* compatibility only */
10991
0
}
10992
10993
10994
int wolfSSL_library_init(void)
10995
0
{
10996
0
    WOLFSSL_ENTER("SSL_library_init");
10997
0
    if (wolfSSL_Init() == WOLFSSL_SUCCESS)
10998
0
        return WOLFSSL_SUCCESS;
10999
0
    else
11000
0
        return WOLFSSL_FATAL_ERROR;
11001
0
}
11002
11003
11004
#ifdef HAVE_SECRET_CALLBACK
11005
11006
int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
11007
{
11008
    WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
11009
    if (ssl == NULL)
11010
        return WOLFSSL_FATAL_ERROR;
11011
11012
    ssl->sessionSecretCb = cb;
11013
    ssl->sessionSecretCtx = ctx;
11014
    if (cb != NULL) {
11015
        /* If using a pre-set key, assume session resumption. */
11016
        ssl->session->sessionIDSz = 0;
11017
        ssl->options.resuming = 1;
11018
    }
11019
11020
    return WOLFSSL_SUCCESS;
11021
}
11022
11023
#endif
11024
11025
11026
#ifndef NO_SESSION_CACHE
11027
11028
/* on by default if built in but allow user to turn off */
11029
WOLFSSL_ABI
11030
long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
11031
0
{
11032
0
    WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
11033
11034
0
    if (ctx == NULL)
11035
0
        return WOLFSSL_FAILURE;
11036
11037
0
    if (mode == WOLFSSL_SESS_CACHE_OFF)
11038
0
        ctx->sessionCacheOff = 1;
11039
11040
0
    if ((mode & WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
11041
0
        ctx->sessionCacheFlushOff = 1;
11042
11043
#ifdef HAVE_EXT_CACHE
11044
    if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
11045
        ctx->internalCacheOff = 1;
11046
    if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP) != 0)
11047
        ctx->internalCacheLookupOff = 1;
11048
#endif
11049
11050
0
    return WOLFSSL_SUCCESS;
11051
0
}
11052
11053
#endif /* NO_SESSION_CACHE */
11054
11055
11056
#if !defined(NO_CERTS)
11057
#if defined(PERSIST_CERT_CACHE)
11058
11059
11060
#define WOLFSSL_CACHE_CERT_VERSION 1
11061
11062
typedef struct {
11063
    int version;                 /* cache cert layout version id */
11064
    int rows;                    /* hash table rows, CA_TABLE_SIZE */
11065
    int columns[CA_TABLE_SIZE];  /* columns per row on list */
11066
    int signerSz;                /* sizeof Signer object */
11067
} CertCacheHeader;
11068
11069
/* current cert persistence layout is:
11070
11071
   1) CertCacheHeader
11072
   2) caTable
11073
11074
   update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
11075
   PERSIST_CERT_CACHE functions
11076
*/
11077
11078
11079
/* Return memory needed to persist this signer, have lock */
11080
static WC_INLINE int GetSignerMemory(Signer* signer)
11081
{
11082
    int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
11083
           + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
11084
11085
#if !defined(NO_SKID)
11086
        sz += (int)sizeof(signer->subjectKeyIdHash);
11087
#endif
11088
11089
    /* add dynamic bytes needed */
11090
    sz += signer->pubKeySize;
11091
    sz += signer->nameLen;
11092
11093
    return sz;
11094
}
11095
11096
11097
/* Return memory needed to persist this row, have lock */
11098
static WC_INLINE int GetCertCacheRowMemory(Signer* row)
11099
{
11100
    int sz = 0;
11101
11102
    while (row) {
11103
        sz += GetSignerMemory(row);
11104
        row = row->next;
11105
    }
11106
11107
    return sz;
11108
}
11109
11110
11111
/* get the size of persist cert cache, have lock */
11112
static WC_INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
11113
{
11114
    int sz;
11115
    int i;
11116
11117
    sz = sizeof(CertCacheHeader);
11118
11119
    for (i = 0; i < CA_TABLE_SIZE; i++)
11120
        sz += GetCertCacheRowMemory(cm->caTable[i]);
11121
11122
    return sz;
11123
}
11124
11125
11126
/* Store cert cache header columns with number of items per list, have lock */
11127
static WC_INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
11128
{
11129
    int     i;
11130
    Signer* row;
11131
11132
    for (i = 0; i < CA_TABLE_SIZE; i++) {
11133
        int count = 0;
11134
        row = cm->caTable[i];
11135
11136
        while (row) {
11137
            ++count;
11138
            row = row->next;
11139
        }
11140
        columns[i] = count;
11141
    }
11142
}
11143
11144
11145
/* Restore whole cert row from memory, have lock, return bytes consumed,
11146
   < 0 on error, have lock */
11147
static WC_INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
11148
                                 int row, int listSz, const byte* end)
11149
{
11150
    int idx = 0;
11151
11152
    if (listSz < 0) {
11153
        WOLFSSL_MSG("Row header corrupted, negative value");
11154
        return PARSE_ERROR;
11155
    }
11156
11157
    while (listSz) {
11158
        Signer* signer;
11159
        byte*   publicKey;
11160
        byte*   start = current + idx;  /* for end checks on this signer */
11161
        int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
11162
                      sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
11163
        #ifndef NO_SKID
11164
                minSz += (int)sizeof(signer->subjectKeyIdHash);
11165
        #endif
11166
11167
        if (start + minSz > end) {
11168
            WOLFSSL_MSG("Would overread restore buffer");
11169
            return BUFFER_E;
11170
        }
11171
        signer = MakeSigner(cm->heap);
11172
        if (signer == NULL)
11173
            return MEMORY_E;
11174
11175
        /* pubKeySize */
11176
        XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
11177
        idx += (int)sizeof(signer->pubKeySize);
11178
11179
        /* keyOID */
11180
        XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
11181
        idx += (int)sizeof(signer->keyOID);
11182
11183
        /* publicKey */
11184
        if (start + minSz + signer->pubKeySize > end) {
11185
            WOLFSSL_MSG("Would overread restore buffer");
11186
            FreeSigner(signer, cm->heap);
11187
            return BUFFER_E;
11188
        }
11189
        publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
11190
                                   DYNAMIC_TYPE_KEY);
11191
        if (publicKey == NULL) {
11192
            FreeSigner(signer, cm->heap);
11193
            return MEMORY_E;
11194
        }
11195
11196
        XMEMCPY(publicKey, current + idx, signer->pubKeySize);
11197
        signer->publicKey = publicKey;
11198
        idx += signer->pubKeySize;
11199
11200
        /* nameLen */
11201
        XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
11202
        idx += (int)sizeof(signer->nameLen);
11203
11204
        /* name */
11205
        if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
11206
            WOLFSSL_MSG("Would overread restore buffer");
11207
            FreeSigner(signer, cm->heap);
11208
            return BUFFER_E;
11209
        }
11210
        signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
11211
                                      DYNAMIC_TYPE_SUBJECT_CN);
11212
        if (signer->name == NULL) {
11213
            FreeSigner(signer, cm->heap);
11214
            return MEMORY_E;
11215
        }
11216
11217
        XMEMCPY(signer->name, current + idx, signer->nameLen);
11218
        idx += signer->nameLen;
11219
11220
        /* subjectNameHash */
11221
        XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
11222
        idx += SIGNER_DIGEST_SIZE;
11223
11224
        #ifndef NO_SKID
11225
            /* subjectKeyIdHash */
11226
            XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
11227
            idx += SIGNER_DIGEST_SIZE;
11228
        #endif
11229
11230
        signer->next = cm->caTable[row];
11231
        cm->caTable[row] = signer;
11232
11233
        --listSz;
11234
    }
11235
11236
    return idx;
11237
}
11238
11239
11240
/* Store whole cert row into memory, have lock, return bytes added */
11241
static WC_INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
11242
{
11243
    int     added  = 0;
11244
    Signer* list   = cm->caTable[row];
11245
11246
    while (list) {
11247
        XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
11248
        added += (int)sizeof(list->pubKeySize);
11249
11250
        XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
11251
        added += (int)sizeof(list->keyOID);
11252
11253
        XMEMCPY(current + added, list->publicKey, list->pubKeySize);
11254
        added += list->pubKeySize;
11255
11256
        XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
11257
        added += (int)sizeof(list->nameLen);
11258
11259
        XMEMCPY(current + added, list->name, list->nameLen);
11260
        added += list->nameLen;
11261
11262
        XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
11263
        added += SIGNER_DIGEST_SIZE;
11264
11265
        #ifndef NO_SKID
11266
            XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
11267
            added += SIGNER_DIGEST_SIZE;
11268
        #endif
11269
11270
        list = list->next;
11271
    }
11272
11273
    return added;
11274
}
11275
11276
11277
/* Persist cert cache to memory, have lock */
11278
static WC_INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
11279
                                     void* mem, int sz)
11280
{
11281
    int realSz;
11282
    int ret = WOLFSSL_SUCCESS;
11283
    int i;
11284
11285
    WOLFSSL_ENTER("DoMemSaveCertCache");
11286
11287
    realSz = GetCertCacheMemSize(cm);
11288
    if (realSz > sz) {
11289
        WOLFSSL_MSG("Mem output buffer too small");
11290
        ret = BUFFER_E;
11291
    }
11292
    else {
11293
        byte*           current;
11294
        CertCacheHeader hdr;
11295
11296
        hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
11297
        hdr.rows     = CA_TABLE_SIZE;
11298
        SetCertHeaderColumns(cm, hdr.columns);
11299
        hdr.signerSz = (int)sizeof(Signer);
11300
11301
        XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
11302
        current = (byte*)mem + sizeof(CertCacheHeader);
11303
11304
        for (i = 0; i < CA_TABLE_SIZE; ++i)
11305
            current += StoreCertRow(cm, current, i);
11306
    }
11307
11308
    return ret;
11309
}
11310
11311
11312
#if !defined(NO_FILESYSTEM)
11313
11314
/* Persist cert cache to file */
11315
int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
11316
{
11317
    XFILE file;
11318
    int   rc = WOLFSSL_SUCCESS;
11319
    int   memSz;
11320
    byte* mem;
11321
11322
    WOLFSSL_ENTER("CM_SaveCertCache");
11323
11324
    file = XFOPEN(fname, "w+b");
11325
    if (file == XBADFILE) {
11326
       WOLFSSL_MSG("Couldn't open cert cache save file");
11327
       return WOLFSSL_BAD_FILE;
11328
    }
11329
11330
    if (wc_LockMutex(&cm->caLock) != 0) {
11331
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11332
        XFCLOSE(file);
11333
        return BAD_MUTEX_E;
11334
    }
11335
11336
    memSz = GetCertCacheMemSize(cm);
11337
    mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11338
    if (mem == NULL) {
11339
        WOLFSSL_MSG("Alloc for tmp buffer failed");
11340
        rc = MEMORY_E;
11341
    } else {
11342
        rc = DoMemSaveCertCache(cm, mem, memSz);
11343
        if (rc == WOLFSSL_SUCCESS) {
11344
            int ret = (int)XFWRITE(mem, memSz, 1, file);
11345
            if (ret != 1) {
11346
                WOLFSSL_MSG("Cert cache file write failed");
11347
                rc = FWRITE_ERROR;
11348
            }
11349
        }
11350
        XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11351
    }
11352
11353
    wc_UnLockMutex(&cm->caLock);
11354
    XFCLOSE(file);
11355
11356
    return rc;
11357
}
11358
11359
11360
/* Restore cert cache from file */
11361
int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
11362
{
11363
    XFILE file;
11364
    int   rc = WOLFSSL_SUCCESS;
11365
    int   ret;
11366
    int   memSz;
11367
    byte* mem;
11368
11369
    WOLFSSL_ENTER("CM_RestoreCertCache");
11370
11371
    file = XFOPEN(fname, "rb");
11372
    if (file == XBADFILE) {
11373
       WOLFSSL_MSG("Couldn't open cert cache save file");
11374
       return WOLFSSL_BAD_FILE;
11375
    }
11376
11377
    if(XFSEEK(file, 0, XSEEK_END) != 0) {
11378
        XFCLOSE(file);
11379
        return WOLFSSL_BAD_FILE;
11380
    }
11381
    memSz = (int)XFTELL(file);
11382
    XREWIND(file);
11383
11384
    if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz <= 0) {
11385
        WOLFSSL_MSG("CM_RestoreCertCache file size error");
11386
        XFCLOSE(file);
11387
        return WOLFSSL_BAD_FILE;
11388
    }
11389
11390
    mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11391
    if (mem == NULL) {
11392
        WOLFSSL_MSG("Alloc for tmp buffer failed");
11393
        XFCLOSE(file);
11394
        return MEMORY_E;
11395
    }
11396
11397
    ret = (int)XFREAD(mem, memSz, 1, file);
11398
    if (ret != 1) {
11399
        WOLFSSL_MSG("Cert file read error");
11400
        rc = FREAD_ERROR;
11401
    } else {
11402
        rc = CM_MemRestoreCertCache(cm, mem, memSz);
11403
        if (rc != WOLFSSL_SUCCESS) {
11404
            WOLFSSL_MSG("Mem restore cert cache failed");
11405
        }
11406
    }
11407
11408
    XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11409
    XFCLOSE(file);
11410
11411
    return rc;
11412
}
11413
11414
#endif /* NO_FILESYSTEM */
11415
11416
11417
/* Persist cert cache to memory */
11418
int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
11419
{
11420
    int ret = WOLFSSL_SUCCESS;
11421
11422
    WOLFSSL_ENTER("CM_MemSaveCertCache");
11423
11424
    if (wc_LockMutex(&cm->caLock) != 0) {
11425
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11426
        return BAD_MUTEX_E;
11427
    }
11428
11429
    ret = DoMemSaveCertCache(cm, mem, sz);
11430
    if (ret == WOLFSSL_SUCCESS)
11431
        *used  = GetCertCacheMemSize(cm);
11432
11433
    wc_UnLockMutex(&cm->caLock);
11434
11435
    return ret;
11436
}
11437
11438
11439
/* Restore cert cache from memory */
11440
int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
11441
{
11442
    int ret = WOLFSSL_SUCCESS;
11443
    int i;
11444
    CertCacheHeader* hdr = (CertCacheHeader*)mem;
11445
    byte*            current = (byte*)mem + sizeof(CertCacheHeader);
11446
    byte*            end     = (byte*)mem + sz;  /* don't go over */
11447
11448
    WOLFSSL_ENTER("CM_MemRestoreCertCache");
11449
11450
    if (current > end) {
11451
        WOLFSSL_MSG("Cert Cache Memory buffer too small");
11452
        return BUFFER_E;
11453
    }
11454
11455
    if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
11456
        hdr->rows     != CA_TABLE_SIZE ||
11457
        hdr->signerSz != (int)sizeof(Signer)) {
11458
11459
        WOLFSSL_MSG("Cert Cache Memory header mismatch");
11460
        return CACHE_MATCH_ERROR;
11461
    }
11462
11463
    if (wc_LockMutex(&cm->caLock) != 0) {
11464
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11465
        return BAD_MUTEX_E;
11466
    }
11467
11468
    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
11469
11470
    for (i = 0; i < CA_TABLE_SIZE; ++i) {
11471
        int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
11472
        if (added < 0) {
11473
            WOLFSSL_MSG("RestoreCertRow error");
11474
            ret = added;
11475
            break;
11476
        }
11477
        current += added;
11478
    }
11479
11480
    wc_UnLockMutex(&cm->caLock);
11481
11482
    return ret;
11483
}
11484
11485
11486
/* get how big the the cert cache save buffer needs to be */
11487
int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
11488
{
11489
    int sz;
11490
11491
    WOLFSSL_ENTER("CM_GetCertCacheMemSize");
11492
11493
    if (wc_LockMutex(&cm->caLock) != 0) {
11494
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11495
        return BAD_MUTEX_E;
11496
    }
11497
11498
    sz = GetCertCacheMemSize(cm);
11499
11500
    wc_UnLockMutex(&cm->caLock);
11501
11502
    return sz;
11503
}
11504
11505
#endif /* PERSIST_CERT_CACHE */
11506
#endif /* NO_CERTS */
11507
11508
#ifdef OPENSSL_EXTRA
11509
11510
/*
11511
 * build enabled cipher list w/ TLS13 or w/o TLS13 suites
11512
 * @param ctx    a pointer to WOLFSSL_CTX structure
11513
 * @param suites currently enabled suites
11514
 * @param onlytlsv13suites flag whether correcting w/ TLS13 suites
11515
 *                         or w/o TLS13 suties
11516
 * @param list   suites list that user wants to update
11517
 * @return suites list on success, otherwise NULL
11518
 */
11519
static char* buildEnabledCipherList(WOLFSSL_CTX* ctx, Suites* suites,
11520
           int tls13Only, const char* list)
11521
{
11522
    word32 idx = 0;
11523
    word32 listsz = 0;
11524
    word32 len = 0;
11525
    word32 ianasz = 0;
11526
    const char* enabledcs = NULL;
11527
    char* locallist = NULL;
11528
    char* head = NULL;
11529
    byte cipherSuite0;
11530
    byte cipherSuite;
11531
11532
    /* sanity check */
11533
    if (ctx == NULL || suites == NULL || list == NULL)
11534
        return NULL;
11535
11536
    if (!suites->setSuites)
11537
        return NULL;
11538
11539
    listsz = (word32)XSTRLEN(list);
11540
11541
    /* calculate necessary buffer length */
11542
    for(idx = 0; idx < suites->suiteSz; idx++) {
11543
11544
        cipherSuite0 = suites->suites[idx];
11545
        cipherSuite  = suites->suites[++idx];
11546
11547
        if (tls13Only && cipherSuite0 == TLS13_BYTE) {
11548
            enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11549
        }
11550
        else if (!tls13Only && cipherSuite0 != TLS13_BYTE) {
11551
            enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11552
        }
11553
        else
11554
            continue;
11555
11556
        if (XSTRCMP(enabledcs, "None") != 0) {
11557
            len += (word32)XSTRLEN(enabledcs) + 2;
11558
        }
11559
    }
11560
11561
    len += listsz + 2;
11562
11563
    /* build string */
11564
    if (len > (listsz + 2)) {
11565
        locallist = (char*)XMALLOC(len, ctx->heap,
11566
                                           DYNAMIC_TYPE_TMP_BUFFER);
11567
        /* sanity check */
11568
        if (!locallist)
11569
            return NULL;
11570
11571
        XMEMSET(locallist, 0, len);
11572
11573
        head = locallist;
11574
11575
        if (!tls13Only)
11576
        {
11577
            /* always tls13 suites in the head position */
11578
            XSTRNCPY(locallist, list, len);
11579
            locallist += listsz;
11580
            *locallist++ = ':';
11581
            *locallist = 0;
11582
            len -= listsz + 1;
11583
        }
11584
11585
        for(idx = 0; idx < suites->suiteSz; idx++) {
11586
            cipherSuite0 = suites->suites[idx];
11587
            cipherSuite  = suites->suites[++idx];
11588
11589
            if (tls13Only && cipherSuite0 == TLS13_BYTE) {
11590
                enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11591
            }
11592
            else if (!tls13Only && cipherSuite0 != TLS13_BYTE) {
11593
                enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11594
            }
11595
            else
11596
                continue;
11597
11598
            ianasz = (int)XSTRLEN(enabledcs);
11599
            if (ianasz + 1 < len) {
11600
                XSTRNCPY(locallist, enabledcs, len);
11601
                locallist += ianasz;
11602
11603
                *locallist++ = ':';
11604
                *locallist = 0;
11605
                len -= ianasz + 1;
11606
            }
11607
            else{
11608
                XFREE(locallist, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
11609
                return NULL;
11610
            }
11611
        }
11612
11613
        if (tls13Only) {
11614
            XSTRNCPY(locallist, list, len);
11615
            locallist += listsz;
11616
            *locallist = 0;
11617
        }
11618
11619
        return head;
11620
    }
11621
    else
11622
        return NULL;
11623
}
11624
11625
/*
11626
 * check if the list has TLS13 and pre-TLS13 suites
11627
 * @param list cipher suite list that user want to set
11628
 * @return mixed: 0, only pre-TLS13: 1, only TLS13: 2
11629
 */
11630
static int CheckcipherList(const char* list)
11631
{
11632
    int ret;
11633
    int findTLSv13Suites = 0;
11634
    int findbeforeSuites = 0;
11635
    byte cipherSuite0;
11636
    byte cipherSuite1;
11637
    int flags;
11638
    char* next = (char*)list;
11639
11640
    do {
11641
        char*  current = next;
11642
        char   name[MAX_SUITE_NAME + 1];
11643
        word32 length = MAX_SUITE_NAME;
11644
        word32 current_length;
11645
11646
        next   = XSTRSTR(next, ":");
11647
11648
        current_length = (!next) ? (word32)XSTRLEN(current)
11649
                                 : (word32)(next - current);
11650
11651
        if (current_length < length) {
11652
            length = current_length;
11653
        }
11654
        XMEMCPY(name, current, length);
11655
        name[length] = 0;
11656
11657
        ret = wolfSSL_get_cipher_suite_from_name(name, &cipherSuite0,
11658
                                                        &cipherSuite1, &flags);
11659
        if (ret == 0) {
11660
            if (cipherSuite0 == TLS13_BYTE) {
11661
                /* TLSv13 suite */
11662
                findTLSv13Suites = 1;
11663
                break;
11664
            }
11665
            else {
11666
                findbeforeSuites = 1;
11667
                break;
11668
            }
11669
        }
11670
        if (findTLSv13Suites == 1 && findbeforeSuites == 1) {
11671
            /* list has mixed suites */
11672
            return 0;
11673
        }
11674
    }  while (next++); /* ++ needed to skip ':' */
11675
11676
    if (findTLSv13Suites == 0 && findbeforeSuites == 1) {
11677
        return 1;/* only before TLSv13 suites */
11678
    }
11679
    else if (findTLSv13Suites == 1 && findbeforeSuites == 0) {
11680
        return 2;/* only TLSv13 suties */
11681
    }
11682
    else {
11683
        return 0;/* handle as mixed */
11684
    }
11685
}
11686
11687
/* parse some bulk lists like !eNULL / !aNULL
11688
 *
11689
 * returns WOLFSSL_SUCCESS on success and sets the cipher suite list
11690
 */
11691
static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, Suites* suites,
11692
        const char* list)
11693
{
11694
    int       ret          = 0;
11695
    int listattribute = 0;
11696
    char*     buildcipherList = NULL;
11697
    int tls13Only = 0;
11698
11699
    if (suites == NULL || list == NULL) {
11700
        WOLFSSL_MSG("NULL argument");
11701
        return WOLFSSL_FAILURE;
11702
    }
11703
11704
    listattribute = CheckcipherList(list);
11705
11706
    if (listattribute == 0) {
11707
       /* list has mixed(pre-TLSv13 and TLSv13) suites
11708
        * update cipher suites the same as before
11709
        */
11710
        return (SetCipherList(ctx, suites, list)) ? WOLFSSL_SUCCESS :
11711
        WOLFSSL_FAILURE;
11712
    }
11713
    else if (listattribute == 1) {
11714
       /* list has only pre-TLSv13 suites.
11715
        * Only update before TLSv13 suites.
11716
        */
11717
        tls13Only = 1;
11718
    }
11719
    else if (listattribute == 2) {
11720
       /* list has only TLSv13 suites. Only update TLv13 suites
11721
        * simulate set_ciphersuites() compatibility layer API
11722
        */
11723
        tls13Only = 0;
11724
    }
11725
11726
    buildcipherList = buildEnabledCipherList(ctx, ctx->suites,
11727
                                            tls13Only, list);
11728
11729
    if (buildcipherList) {
11730
        ret = SetCipherList(ctx, suites, buildcipherList);
11731
        XFREE(buildcipherList, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
11732
    }
11733
    else {
11734
        ret = SetCipherList(ctx, suites, list);
11735
    }
11736
11737
    return ret;
11738
}
11739
11740
#endif
11741
11742
11743
int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
11744
0
{
11745
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
11746
11747
0
    if (ctx == NULL)
11748
0
        return WOLFSSL_FAILURE;
11749
11750
    /* alloc/init on demand only */
11751
0
    if (ctx->suites == NULL) {
11752
0
        ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
11753
0
                                       DYNAMIC_TYPE_SUITES);
11754
0
        if (ctx->suites == NULL) {
11755
0
            WOLFSSL_MSG("Memory alloc for Suites failed");
11756
0
            return WOLFSSL_FAILURE;
11757
0
        }
11758
0
        XMEMSET(ctx->suites, 0, sizeof(Suites));
11759
0
    }
11760
11761
#ifdef OPENSSL_EXTRA
11762
    return wolfSSL_parse_cipher_list(ctx, ctx->suites, list);
11763
#else
11764
0
    return (SetCipherList(ctx, ctx->suites, list)) ?
11765
0
        WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
11766
0
#endif
11767
0
}
11768
11769
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
11770
int wolfSSL_CTX_set_cipher_list_bytes(WOLFSSL_CTX* ctx, const byte* list,
11771
                                      const int listSz)
11772
{
11773
    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list_bytes");
11774
11775
    if (ctx == NULL)
11776
        return WOLFSSL_FAILURE;
11777
11778
    /* alloc/init on demand only */
11779
    if (ctx->suites == NULL) {
11780
        ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
11781
                                       DYNAMIC_TYPE_SUITES);
11782
        if (ctx->suites == NULL) {
11783
            WOLFSSL_MSG("Memory alloc for Suites failed");
11784
            return WOLFSSL_FAILURE;
11785
        }
11786
        XMEMSET(ctx->suites, 0, sizeof(Suites));
11787
    }
11788
11789
    return (SetCipherListFromBytes(ctx, ctx->suites, list, listSz)) ?
11790
        WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
11791
}
11792
#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
11793
11794
int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
11795
0
{
11796
0
    WOLFSSL_ENTER("wolfSSL_set_cipher_list");
11797
11798
0
    if (ssl == NULL || ssl->ctx == NULL) {
11799
0
        return WOLFSSL_FAILURE;
11800
0
    }
11801
11802
#ifdef SINGLE_THREADED
11803
    if (ssl->ctx->suites == ssl->suites) {
11804
        ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
11805
                                       DYNAMIC_TYPE_SUITES);
11806
        if (ssl->suites == NULL) {
11807
            WOLFSSL_MSG("Suites Memory error");
11808
            return MEMORY_E;
11809
        }
11810
        *ssl->suites = *ssl->ctx->suites;
11811
        ssl->options.ownSuites = 1;
11812
    }
11813
#endif
11814
11815
#ifdef OPENSSL_EXTRA
11816
    return wolfSSL_parse_cipher_list(ssl->ctx, ssl->suites, list);
11817
#else
11818
0
    return (SetCipherList(ssl->ctx, ssl->suites, list)) ?
11819
0
        WOLFSSL_SUCCESS :
11820
0
        WOLFSSL_FAILURE;
11821
0
#endif
11822
0
}
11823
11824
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_SET_CIPHER_BYTES)
11825
int wolfSSL_set_cipher_list_bytes(WOLFSSL* ssl, const byte* list,
11826
                                  const int listSz)
11827
{
11828
    WOLFSSL_ENTER("wolfSSL_set_cipher_list_bytes");
11829
11830
    if (ssl == NULL || ssl->ctx == NULL) {
11831
        return WOLFSSL_FAILURE;
11832
    }
11833
11834
#ifdef SINGLE_THREADED
11835
    if (ssl->ctx->suites == ssl->suites) {
11836
        ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
11837
                                       DYNAMIC_TYPE_SUITES);
11838
        if (ssl->suites == NULL) {
11839
            WOLFSSL_MSG("Suites Memory error");
11840
            return MEMORY_E;
11841
        }
11842
        *ssl->suites = *ssl->ctx->suites;
11843
        ssl->options.ownSuites = 1;
11844
    }
11845
#endif
11846
11847
    return (SetCipherListFromBytes(ssl->ctx, ssl->suites, list, listSz))
11848
           ? WOLFSSL_SUCCESS
11849
           : WOLFSSL_FAILURE;
11850
}
11851
#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */
11852
11853
11854
#ifdef HAVE_KEYING_MATERIAL
11855
11856
#define TLS_PRF_LABEL_CLIENT_FINISHED     "client finished"
11857
#define TLS_PRF_LABEL_SERVER_FINISHED     "server finished"
11858
#define TLS_PRF_LABEL_MASTER_SECRET       "master secret"
11859
#define TLS_PRF_LABEL_EXT_MASTER_SECRET   "extended master secret"
11860
#define TLS_PRF_LABEL_KEY_EXPANSION       "key expansion"
11861
11862
static const struct ForbiddenLabels {
11863
    const char* label;
11864
    size_t labelLen;
11865
} forbiddenLabels[] = {
11866
    {TLS_PRF_LABEL_CLIENT_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_CLIENT_FINISHED)},
11867
    {TLS_PRF_LABEL_SERVER_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_SERVER_FINISHED)},
11868
    {TLS_PRF_LABEL_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_MASTER_SECRET)},
11869
    {TLS_PRF_LABEL_EXT_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_EXT_MASTER_SECRET)},
11870
    {TLS_PRF_LABEL_KEY_EXPANSION, XSTR_SIZEOF(TLS_PRF_LABEL_KEY_EXPANSION)},
11871
    {NULL, 0},
11872
};
11873
11874
/**
11875
 * Implement RFC 5705
11876
 * TLS 1.3 uses a different exporter definition (section 7.5 of RFC 8446)
11877
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
11878
 */
11879
int wolfSSL_export_keying_material(WOLFSSL *ssl,
11880
        unsigned char *out, size_t outLen,
11881
        const char *label, size_t labelLen,
11882
        const unsigned char *context, size_t contextLen,
11883
        int use_context)
11884
{
11885
    byte*  seed = NULL;
11886
    word32 seedLen;
11887
    const struct ForbiddenLabels* fl;
11888
11889
    WOLFSSL_ENTER("wolfSSL_export_keying_material");
11890
11891
    if (ssl == NULL || out == NULL || label == NULL ||
11892
            (use_context && contextLen && context == NULL)) {
11893
        WOLFSSL_MSG("Bad argument");
11894
        return WOLFSSL_FAILURE;
11895
    }
11896
11897
    /* clientRandom + serverRandom
11898
     * OR
11899
     * clientRandom + serverRandom + ctx len encoding + ctx */
11900
    seedLen = !use_context ? (word32)SEED_LEN :
11901
                             (word32)SEED_LEN + 2 + (word32)contextLen;
11902
11903
    if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
11904
        WOLFSSL_MSG("To export keying material wolfSSL needs to keep handshake "
11905
                    "data. Call wolfSSL_KeepArrays before attempting to "
11906
                    "export keyid material.");
11907
        return WOLFSSL_FAILURE;
11908
    }
11909
11910
    /* check forbidden labels */
11911
    for (fl = &forbiddenLabels[0]; fl->label != NULL; fl++) {
11912
        if (labelLen >= fl->labelLen &&
11913
                XMEMCMP(label, fl->label, fl->labelLen) == 0) {
11914
            WOLFSSL_MSG("Forbidden label");
11915
            return WOLFSSL_FAILURE;
11916
        }
11917
    }
11918
11919
#ifdef WOLFSSL_TLS13
11920
    if (IsAtLeastTLSv1_3(ssl->version)) {
11921
        /* Path for TLS 1.3 */
11922
        if (!use_context) {
11923
            contextLen = 0;
11924
            context = (byte*)""; /* Give valid pointer for 0 length memcpy */
11925
        }
11926
11927
        if (Tls13_Exporter(ssl, out, (word32)outLen, label, labelLen,
11928
                context, contextLen) != 0) {
11929
            WOLFSSL_MSG("Tls13_Exporter error");
11930
            return WOLFSSL_FAILURE;
11931
        }
11932
        return WOLFSSL_SUCCESS;
11933
    }
11934
#endif
11935
11936
    /* Path for <=TLS 1.2 */
11937
    seed = (byte*)XMALLOC(seedLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11938
    if (seed == NULL) {
11939
        WOLFSSL_MSG("malloc error");
11940
        return WOLFSSL_FAILURE;
11941
    }
11942
11943
    XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
11944
    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
11945
11946
    if (use_context) {
11947
        /* Encode len in big endian */
11948
        seed[SEED_LEN    ] = (contextLen >> 8) & 0xFF;
11949
        seed[SEED_LEN + 1] = (contextLen) & 0xFF;
11950
        if (contextLen) {
11951
            /* 0 length context is allowed */
11952
            XMEMCPY(seed + SEED_LEN + 2, context, contextLen);
11953
        }
11954
    }
11955
11956
    PRIVATE_KEY_UNLOCK();
11957
    if (wc_PRF_TLS(out, (word32)outLen, ssl->arrays->masterSecret, SECRET_LEN,
11958
            (byte*)label, (word32)labelLen, seed, seedLen, IsAtLeastTLSv1_2(ssl),
11959
            ssl->specs.mac_algorithm, ssl->heap, ssl->devId) != 0) {
11960
        WOLFSSL_MSG("wc_PRF_TLS error");
11961
        PRIVATE_KEY_LOCK();
11962
        XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11963
        return WOLFSSL_FAILURE;
11964
    }
11965
    PRIVATE_KEY_LOCK();
11966
11967
    XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11968
    return WOLFSSL_SUCCESS;
11969
}
11970
#endif /* HAVE_KEYING_MATERIAL */
11971
11972
int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
11973
0
{
11974
0
    int useNb = 0;
11975
11976
0
    if (ssl == NULL)
11977
0
        return WOLFSSL_FAILURE;
11978
11979
0
    WOLFSSL_ENTER("wolfSSL_dtls_get_using_nonblock");
11980
0
    if (ssl->options.dtls) {
11981
#ifdef WOLFSSL_DTLS
11982
        useNb = ssl->options.dtlsUseNonblock;
11983
#endif
11984
0
    }
11985
0
    else {
11986
0
        WOLFSSL_MSG("wolfSSL_dtls_get_using_nonblock() is "
11987
0
                    "DEPRECATED for non-DTLS use.");
11988
0
    }
11989
0
    return useNb;
11990
0
}
11991
11992
11993
#ifndef WOLFSSL_LEANPSK
11994
11995
void wolfSSL_dtls_set_using_nonblock(WOLFSSL* ssl, int nonblock)
11996
0
{
11997
0
    (void)nonblock;
11998
11999
0
    WOLFSSL_ENTER("wolfSSL_dtls_set_using_nonblock");
12000
12001
0
    if (ssl == NULL)
12002
0
        return;
12003
12004
0
    if (ssl->options.dtls) {
12005
#ifdef WOLFSSL_DTLS
12006
        ssl->options.dtlsUseNonblock = (nonblock != 0);
12007
#endif
12008
0
    }
12009
0
    else {
12010
0
        WOLFSSL_MSG("wolfSSL_dtls_set_using_nonblock() is "
12011
0
                    "DEPRECATED for non-DTLS use.");
12012
0
    }
12013
0
}
12014
12015
12016
#ifdef WOLFSSL_DTLS
12017
12018
int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
12019
{
12020
    int timeout = 0;
12021
    if (ssl)
12022
        timeout = ssl->dtls_timeout;
12023
12024
    WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout()", timeout);
12025
    return timeout;
12026
}
12027
12028
#ifdef WOLFSSL_DTLS13
12029
12030
/*
12031
 * This API returns 1 when the user should set a short timeout for receiving
12032
 * data. It is recommended that it is at most 1/4 the value returned by
12033
 * wolfSSL_dtls_get_current_timeout().
12034
 */
12035
int wolfSSL_dtls13_use_quick_timeout(WOLFSSL* ssl)
12036
{
12037
    return ssl->dtls13FastTimeout;
12038
}
12039
12040
/*
12041
 * When this is set, a DTLS 1.3 connection will send acks immediately when a
12042
 * disruption is detected to shortcut timeouts. This results in potentially
12043
 * more traffic but may make the handshake quicker.
12044
 */
12045
void wolfSSL_dtls13_set_send_more_acks(WOLFSSL* ssl, int value)
12046
{
12047
    if (ssl != NULL)
12048
        ssl->options.dtls13SendMoreAcks = !!value;
12049
}
12050
#endif /* WOLFSSL_DTLS13 */
12051
12052
int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft)
12053
{
12054
    if (ssl && timeleft) {
12055
        XMEMSET(timeleft, 0, sizeof(WOLFSSL_TIMEVAL));
12056
        timeleft->tv_sec = ssl->dtls_timeout;
12057
    }
12058
    return 0;
12059
}
12060
12061
#ifndef NO_WOLFSSL_STUB
12062
int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl)
12063
{
12064
    WOLFSSL_STUB("SSL_DTLSv1_handle_timeout");
12065
    (void)ssl;
12066
    return 0;
12067
}
12068
#endif
12069
12070
#ifndef NO_WOLFSSL_STUB
12071
void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl, word32 duration_ms)
12072
{
12073
    WOLFSSL_STUB("SSL_DTLSv1_set_initial_timeout_duration");
12074
    (void)ssl;
12075
    (void)duration_ms;
12076
}
12077
#endif
12078
12079
/* user may need to alter init dtls recv timeout, WOLFSSL_SUCCESS on ok */
12080
int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
12081
{
12082
    if (ssl == NULL || timeout < 0)
12083
        return BAD_FUNC_ARG;
12084
12085
    if (timeout > ssl->dtls_timeout_max) {
12086
        WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
12087
        return BAD_FUNC_ARG;
12088
    }
12089
12090
    ssl->dtls_timeout_init = timeout;
12091
    ssl->dtls_timeout = timeout;
12092
12093
    return WOLFSSL_SUCCESS;
12094
}
12095
12096
12097
/* user may need to alter max dtls recv timeout, WOLFSSL_SUCCESS on ok */
12098
int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
12099
{
12100
    if (ssl == NULL || timeout < 0)
12101
        return BAD_FUNC_ARG;
12102
12103
    if (timeout < ssl->dtls_timeout_init) {
12104
        WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
12105
        return BAD_FUNC_ARG;
12106
    }
12107
12108
    ssl->dtls_timeout_max = timeout;
12109
12110
    return WOLFSSL_SUCCESS;
12111
}
12112
12113
12114
int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
12115
{
12116
    int result = WOLFSSL_SUCCESS;
12117
    WOLFSSL_ENTER("wolfSSL_dtls_got_timeout()");
12118
12119
    if (ssl == NULL)
12120
        return WOLFSSL_FATAL_ERROR;
12121
12122
#ifdef WOLFSSL_DTLS13
12123
    if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
12124
        result = Dtls13RtxTimeout(ssl);
12125
        if (result < 0) {
12126
            if (result == WANT_WRITE)
12127
                ssl->dtls13SendingAckOrRtx = 1;
12128
            ssl->error = result;
12129
            WOLFSSL_ERROR(result);
12130
            return WOLFSSL_FATAL_ERROR;
12131
        }
12132
12133
        return WOLFSSL_SUCCESS;
12134
    }
12135
#endif /* WOLFSSL_DTLS13 */
12136
12137
    if ((IsSCR(ssl) || !ssl->options.handShakeDone)) {
12138
        if (DtlsMsgPoolTimeout(ssl) < 0){
12139
            ssl->error = SOCKET_ERROR_E;
12140
            WOLFSSL_ERROR(ssl->error);
12141
            result = WOLFSSL_FATAL_ERROR;
12142
        }
12143
        else if ((result = DtlsMsgPoolSend(ssl, 0)) < 0)  {
12144
            ssl->error = result;
12145
            WOLFSSL_ERROR(result);
12146
            result = WOLFSSL_FATAL_ERROR;
12147
        }
12148
        else {
12149
            /* Reset return value to success */
12150
            result = WOLFSSL_SUCCESS;
12151
        }
12152
    }
12153
12154
    WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout()", result);
12155
    return result;
12156
}
12157
12158
12159
/* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
12160
int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
12161
{
12162
    WOLFSSL_ENTER("wolfSSL_dtls_retransmit()");
12163
12164
    if (ssl == NULL)
12165
        return WOLFSSL_FATAL_ERROR;
12166
12167
    if (!ssl->options.handShakeDone) {
12168
        int result = DtlsMsgPoolSend(ssl, 0);
12169
        if (result < 0) {
12170
            ssl->error = result;
12171
            WOLFSSL_ERROR(result);
12172
            return WOLFSSL_FATAL_ERROR;
12173
        }
12174
    }
12175
12176
    return 0;
12177
}
12178
12179
#endif /* DTLS */
12180
#endif /* LEANPSK */
12181
12182
12183
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
12184
12185
/* Not an SSL function, return 0 for success, error code otherwise */
12186
/* Prereq: ssl's RNG needs to be initialized. */
12187
int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
12188
                                 const byte* secret, word32 secretSz)
12189
{
12190
    int ret = 0;
12191
12192
    WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
12193
12194
    if (ssl == NULL) {
12195
        WOLFSSL_MSG("need a SSL object");
12196
        return BAD_FUNC_ARG;
12197
    }
12198
12199
    if (secret != NULL && secretSz == 0) {
12200
        WOLFSSL_MSG("can't have a new secret without a size");
12201
        return BAD_FUNC_ARG;
12202
    }
12203
12204
    /* If secretSz is 0, use the default size. */
12205
    if (secretSz == 0)
12206
        secretSz = COOKIE_SECRET_SZ;
12207
12208
    if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
12209
        byte* newSecret;
12210
12211
        if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
12212
            ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
12213
                      ssl->buffers.dtlsCookieSecret.length);
12214
            XFREE(ssl->buffers.dtlsCookieSecret.buffer,
12215
                  ssl->heap, DYNAMIC_TYPE_NONE);
12216
        }
12217
12218
        newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
12219
        if (newSecret == NULL) {
12220
            ssl->buffers.dtlsCookieSecret.buffer = NULL;
12221
            ssl->buffers.dtlsCookieSecret.length = 0;
12222
            WOLFSSL_MSG("couldn't allocate new cookie secret");
12223
            return MEMORY_ERROR;
12224
        }
12225
        ssl->buffers.dtlsCookieSecret.buffer = newSecret;
12226
        ssl->buffers.dtlsCookieSecret.length = secretSz;
12227
    #ifdef WOLFSSL_CHECK_MEM_ZERO
12228
        wc_MemZero_Add("wolfSSL_DTLS_SetCookieSecret secret",
12229
            ssl->buffers.dtlsCookieSecret.buffer,
12230
            ssl->buffers.dtlsCookieSecret.length);
12231
    #endif
12232
    }
12233
12234
    /* If the supplied secret is NULL, randomly generate a new secret. */
12235
    if (secret == NULL) {
12236
        ret = wc_RNG_GenerateBlock(ssl->rng,
12237
                             ssl->buffers.dtlsCookieSecret.buffer, secretSz);
12238
    }
12239
    else
12240
        XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
12241
12242
    WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
12243
    return ret;
12244
}
12245
12246
#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
12247
12248
12249
/* EITHER SIDE METHODS */
12250
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
12251
    WOLFSSL_METHOD* wolfSSLv23_method(void)
12252
    {
12253
        return wolfSSLv23_method_ex(NULL);
12254
    }
12255
    WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap)
12256
    {
12257
        WOLFSSL_METHOD* m = NULL;
12258
        WOLFSSL_ENTER("SSLv23_method");
12259
    #if !defined(NO_WOLFSSL_CLIENT)
12260
        m = wolfSSLv23_client_method_ex(heap);
12261
    #elif !defined(NO_WOLFSSL_SERVER)
12262
        m = wolfSSLv23_server_method_ex(heap);
12263
    #else
12264
        (void)heap;
12265
    #endif
12266
        if (m != NULL) {
12267
            m->side = WOLFSSL_NEITHER_END;
12268
        }
12269
12270
        return m;
12271
    }
12272
12273
    #ifdef WOLFSSL_ALLOW_SSLV3
12274
    WOLFSSL_METHOD* wolfSSLv3_method(void)
12275
    {
12276
        return wolfSSLv3_method_ex(NULL);
12277
    }
12278
    WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap)
12279
    {
12280
        WOLFSSL_METHOD* m = NULL;
12281
        WOLFSSL_ENTER("SSLv3_method");
12282
    #if !defined(NO_WOLFSSL_CLIENT)
12283
        m = wolfSSLv3_client_method_ex(heap);
12284
    #elif !defined(NO_WOLFSSL_SERVER)
12285
        m = wolfSSLv3_server_method_ex(heap);
12286
    #endif
12287
        if (m != NULL) {
12288
            m->side = WOLFSSL_NEITHER_END;
12289
        }
12290
12291
        return m;
12292
    }
12293
    #endif
12294
#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
12295
12296
/* client only parts */
12297
#ifndef NO_WOLFSSL_CLIENT
12298
12299
    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
12300
    WOLFSSL_METHOD* wolfSSLv2_client_method(void)
12301
    {
12302
        WOLFSSL_STUB("wolfSSLv2_client_method");
12303
        return NULL;
12304
    }
12305
    #endif
12306
12307
    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
12308
    WOLFSSL_METHOD* wolfSSLv3_client_method(void)
12309
    {
12310
        return wolfSSLv3_client_method_ex(NULL);
12311
    }
12312
    WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
12313
    {
12314
        WOLFSSL_METHOD* method =
12315
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12316
                                                     heap, DYNAMIC_TYPE_METHOD);
12317
        (void)heap;
12318
        WOLFSSL_ENTER("SSLv3_client_method_ex");
12319
        if (method)
12320
            InitSSL_Method(method, MakeSSLv3());
12321
        return method;
12322
    }
12323
    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
12324
12325
12326
    WOLFSSL_METHOD* wolfSSLv23_client_method(void)
12327
0
    {
12328
0
        return wolfSSLv23_client_method_ex(NULL);
12329
0
    }
12330
    WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
12331
0
    {
12332
0
        WOLFSSL_METHOD* method =
12333
0
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12334
0
                                                     heap, DYNAMIC_TYPE_METHOD);
12335
0
        (void)heap;
12336
0
        WOLFSSL_ENTER("SSLv23_client_method_ex");
12337
0
        if (method) {
12338
0
    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
12339
0
        #if defined(WOLFSSL_TLS13)
12340
0
            InitSSL_Method(method, MakeTLSv1_3());
12341
        #elif !defined(WOLFSSL_NO_TLS12)
12342
            InitSSL_Method(method, MakeTLSv1_2());
12343
        #elif !defined(NO_OLD_TLS)
12344
            InitSSL_Method(method, MakeTLSv1_1());
12345
        #endif
12346
    #else
12347
        #ifndef NO_OLD_TLS
12348
            InitSSL_Method(method, MakeTLSv1_1());
12349
        #endif
12350
    #endif
12351
0
    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
12352
0
            method->downgrade = 1;
12353
0
    #endif
12354
0
        }
12355
0
        return method;
12356
0
    }
12357
12358
    /* please see note at top of README if you get an error from connect */
12359
    WOLFSSL_ABI
12360
    int wolfSSL_connect(WOLFSSL* ssl)
12361
0
    {
12362
0
    #if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
12363
0
        int neededState;
12364
0
        byte advanceState;
12365
0
    #endif
12366
0
        int ret = 0;
12367
12368
0
        (void)ret;
12369
12370
0
        #ifdef HAVE_ERRNO_H
12371
0
            errno = 0;
12372
0
        #endif
12373
12374
0
        if (ssl == NULL)
12375
0
            return BAD_FUNC_ARG;
12376
12377
    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
12378
        if (ssl->options.side == WOLFSSL_NEITHER_END) {
12379
            ssl->error = InitSSL_Side(ssl, WOLFSSL_CLIENT_END);
12380
            if (ssl->error != WOLFSSL_SUCCESS) {
12381
                WOLFSSL_ERROR(ssl->error);
12382
                return WOLFSSL_FATAL_ERROR;
12383
            }
12384
            ssl->error = 0; /* expected to be zero here */
12385
        }
12386
12387
    #ifdef OPENSSL_EXTRA
12388
        if (ssl->CBIS != NULL) {
12389
            ssl->CBIS(ssl, SSL_ST_CONNECT, WOLFSSL_SUCCESS);
12390
            ssl->cbmode = SSL_CB_WRITE;
12391
        }
12392
    #endif
12393
    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
12394
12395
    #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
12396
        return wolfSSL_connect_TLSv13(ssl);
12397
    #else
12398
0
        #ifdef WOLFSSL_TLS13
12399
0
        if (ssl->options.tls1_3)
12400
0
            return wolfSSL_connect_TLSv13(ssl);
12401
0
        #endif
12402
12403
0
        WOLFSSL_ENTER("SSL_connect()");
12404
12405
        /* make sure this wolfSSL object has arrays and rng setup. Protects
12406
         * case where the WOLFSSL object is re-used via wolfSSL_clear() */
12407
0
        if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
12408
0
            return ret;
12409
0
        }
12410
12411
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
12412
        if ((ssl->ConnectFilter != NULL) &&
12413
            (ssl->options.connectState == CONNECT_BEGIN)) {
12414
            wolfSSL_netfilter_decision_t res;
12415
            if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
12416
                 WOLFSSL_SUCCESS) &&
12417
                (res == WOLFSSL_NETFILTER_REJECT)) {
12418
                ssl->error = SOCKET_FILTERED_E;
12419
                WOLFSSL_ERROR(ssl->error);
12420
                return WOLFSSL_FATAL_ERROR;
12421
            }
12422
        }
12423
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
12424
12425
0
        if (ssl->options.side != WOLFSSL_CLIENT_END) {
12426
0
            ssl->error = SIDE_ERROR;
12427
0
            WOLFSSL_ERROR(ssl->error);
12428
0
            return WOLFSSL_FATAL_ERROR;
12429
0
        }
12430
12431
        #ifdef WOLFSSL_DTLS
12432
        if (ssl->version.major == DTLS_MAJOR) {
12433
            ssl->options.dtls   = 1;
12434
            ssl->options.tls    = 1;
12435
            ssl->options.tls1_1 = 1;
12436
        }
12437
        #endif
12438
12439
        /* fragOffset is non-zero when sending fragments. On the last
12440
         * fragment, fragOffset is zero again, and the state can be
12441
         * advanced. */
12442
0
        advanceState = ssl->fragOffset == 0 &&
12443
0
            (ssl->options.connectState == CONNECT_BEGIN ||
12444
0
             ssl->options.connectState == HELLO_AGAIN ||
12445
0
             (ssl->options.connectState >= FIRST_REPLY_DONE &&
12446
0
              ssl->options.connectState <= FIRST_REPLY_FOURTH));
12447
12448
#ifdef WOLFSSL_DTLS13
12449
        if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
12450
            advanceState = advanceState && !ssl->dtls13SendingAckOrRtx;
12451
#endif /* WOLFSSL_DTLS13 */
12452
12453
0
        if (ssl->buffers.outputBuffer.length > 0
12454
        #ifdef WOLFSSL_ASYNC_CRYPT
12455
            /* do not send buffered or advance state if last error was an
12456
                async pending operation */
12457
            && ssl->error != WC_PENDING_E
12458
        #endif
12459
0
        ) {
12460
0
            ret = SendBuffered(ssl);
12461
0
            if (ret == 0) {
12462
0
                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
12463
0
                    if (advanceState) {
12464
0
                        ssl->options.connectState++;
12465
0
                        WOLFSSL_MSG("connect state: "
12466
0
                                    "Advanced from last buffered fragment send");
12467
0
                    #ifdef WOLFSSL_ASYNC_IO
12468
                        /* Cleanup async */
12469
0
                        FreeAsyncCtx(ssl, 0);
12470
0
                    #endif
12471
0
                    }
12472
0
                }
12473
0
                else {
12474
0
                    WOLFSSL_MSG("connect state: "
12475
0
                                "Not advanced, more fragments to send");
12476
0
                }
12477
0
            }
12478
0
            else {
12479
0
                ssl->error = ret;
12480
0
                WOLFSSL_ERROR(ssl->error);
12481
0
                return WOLFSSL_FATAL_ERROR;
12482
0
            }
12483
#ifdef WOLFSSL_DTLS13
12484
            if (ssl->options.dtls)
12485
                ssl->dtls13SendingAckOrRtx = 0;
12486
#endif /* WOLFSSL_DTLS13 */
12487
0
        }
12488
12489
0
        ret = RetrySendAlert(ssl);
12490
0
        if (ret != 0) {
12491
0
            ssl->error = ret;
12492
0
            WOLFSSL_ERROR(ssl->error);
12493
0
            return WOLFSSL_FATAL_ERROR;
12494
0
        }
12495
12496
0
        switch (ssl->options.connectState) {
12497
12498
0
        case CONNECT_BEGIN :
12499
            /* always send client hello first */
12500
0
            if ( (ssl->error = SendClientHello(ssl)) != 0) {
12501
0
                WOLFSSL_ERROR(ssl->error);
12502
0
                return WOLFSSL_FATAL_ERROR;
12503
0
            }
12504
0
            ssl->options.connectState = CLIENT_HELLO_SENT;
12505
0
            WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
12506
0
            FALL_THROUGH;
12507
12508
0
        case CLIENT_HELLO_SENT :
12509
0
            neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
12510
0
                                          SERVER_HELLODONE_COMPLETE;
12511
            #ifdef WOLFSSL_DTLS
12512
                /* In DTLS, when resuming, we can go straight to FINISHED,
12513
                 * or do a cookie exchange and then skip to FINISHED, assume
12514
                 * we need the cookie exchange first. */
12515
                if (IsDtlsNotSctpMode(ssl))
12516
                    neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
12517
            #endif
12518
            /* get response */
12519
0
            while (ssl->options.serverState < neededState) {
12520
0
                #ifdef WOLFSSL_TLS13
12521
0
                    if (ssl->options.tls1_3)
12522
0
                        return wolfSSL_connect_TLSv13(ssl);
12523
0
                #endif
12524
0
                if ( (ssl->error = ProcessReply(ssl)) < 0) {
12525
0
                    WOLFSSL_ERROR(ssl->error);
12526
0
                    return WOLFSSL_FATAL_ERROR;
12527
0
                }
12528
                /* if resumption failed, reset needed state */
12529
0
                else if (neededState == SERVER_FINISHED_COMPLETE)
12530
0
                    if (!ssl->options.resuming) {
12531
                    #ifdef WOLFSSL_DTLS
12532
                        if (IsDtlsNotSctpMode(ssl))
12533
                            neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
12534
                        else
12535
                    #endif
12536
0
                            neededState = SERVER_HELLODONE_COMPLETE;
12537
0
                    }
12538
#ifdef WOLFSSL_DTLS13
12539
12540
                if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)
12541
                    && ssl->dtls13Rtx.sendAcks == 1) {
12542
                    ssl->dtls13Rtx.sendAcks = 0;
12543
                    /* we aren't negotiated the version yet, so we aren't sure
12544
                     * the other end can speak v1.3. On the other side we have
12545
                     * received a unified records, assuming that the
12546
                     * ServerHello got lost, we will send an empty ACK. In case
12547
                     * the server is a DTLS with version less than 1.3, it
12548
                     * should just ignore the message */
12549
                    if ((ssl->error = SendDtls13Ack(ssl)) < 0) {
12550
                        if (ssl->error == WANT_WRITE)
12551
                            ssl->dtls13SendingAckOrRtx = 1;
12552
                        WOLFSSL_ERROR(ssl->error);
12553
                        return WOLFSSL_FATAL_ERROR;
12554
                    }
12555
                }
12556
12557
12558
#endif /* WOLFSSL_DTLS13 */
12559
0
            }
12560
12561
0
            ssl->options.connectState = HELLO_AGAIN;
12562
0
            WOLFSSL_MSG("connect state: HELLO_AGAIN");
12563
0
            FALL_THROUGH;
12564
12565
0
        case HELLO_AGAIN :
12566
12567
0
        #ifdef WOLFSSL_TLS13
12568
0
            if (ssl->options.tls1_3)
12569
0
                return wolfSSL_connect_TLSv13(ssl);
12570
0
        #endif
12571
12572
            #ifdef WOLFSSL_DTLS
12573
            if (ssl->options.serverState ==
12574
                    SERVER_HELLOVERIFYREQUEST_COMPLETE) {
12575
                if (IsDtlsNotSctpMode(ssl)) {
12576
                    /* re-init hashes, exclude first hello and verify request */
12577
                    if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
12578
                        WOLFSSL_ERROR(ssl->error);
12579
                        return WOLFSSL_FATAL_ERROR;
12580
                    }
12581
                    if ( (ssl->error = SendClientHello(ssl)) != 0) {
12582
                        WOLFSSL_ERROR(ssl->error);
12583
                        return WOLFSSL_FATAL_ERROR;
12584
                    }
12585
                }
12586
            }
12587
            #endif
12588
12589
0
            ssl->options.connectState = HELLO_AGAIN_REPLY;
12590
0
            WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
12591
0
            FALL_THROUGH;
12592
12593
0
        case HELLO_AGAIN_REPLY :
12594
            #ifdef WOLFSSL_DTLS
12595
                if (IsDtlsNotSctpMode(ssl)) {
12596
                    neededState = ssl->options.resuming ?
12597
                           SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
12598
12599
                    /* get response */
12600
                    while (ssl->options.serverState < neededState) {
12601
                        if ( (ssl->error = ProcessReply(ssl)) < 0) {
12602
                            WOLFSSL_ERROR(ssl->error);
12603
                            return WOLFSSL_FATAL_ERROR;
12604
                        }
12605
                        /* if resumption failed, reset needed state */
12606
                        if (neededState == SERVER_FINISHED_COMPLETE) {
12607
                            if (!ssl->options.resuming)
12608
                                neededState = SERVER_HELLODONE_COMPLETE;
12609
                        }
12610
                    }
12611
                }
12612
            #endif
12613
12614
0
            ssl->options.connectState = FIRST_REPLY_DONE;
12615
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
12616
0
            FALL_THROUGH;
12617
12618
0
        case FIRST_REPLY_DONE :
12619
0
            if (ssl->options.certOnly)
12620
0
                return WOLFSSL_SUCCESS;
12621
0
            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
12622
0
                #ifdef WOLFSSL_TLS13
12623
0
                    if (ssl->options.tls1_3)
12624
0
                        return wolfSSL_connect_TLSv13(ssl);
12625
0
                #endif
12626
0
                if (ssl->options.sendVerify) {
12627
0
                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
12628
                    #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12629
                        ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12630
                    #endif
12631
0
                        WOLFSSL_ERROR(ssl->error);
12632
0
                        return WOLFSSL_FATAL_ERROR;
12633
0
                    }
12634
0
                    WOLFSSL_MSG("sent: certificate");
12635
0
                }
12636
12637
0
            #endif
12638
0
            ssl->options.connectState = FIRST_REPLY_FIRST;
12639
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
12640
0
            FALL_THROUGH;
12641
12642
0
        case FIRST_REPLY_FIRST :
12643
0
        #ifdef WOLFSSL_TLS13
12644
0
            if (ssl->options.tls1_3)
12645
0
                return wolfSSL_connect_TLSv13(ssl);
12646
0
        #endif
12647
0
            if (!ssl->options.resuming) {
12648
0
                if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
12649
                #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12650
                    ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12651
                #endif
12652
0
                    WOLFSSL_ERROR(ssl->error);
12653
0
                    return WOLFSSL_FATAL_ERROR;
12654
0
                }
12655
0
                WOLFSSL_MSG("sent: client key exchange");
12656
0
            }
12657
12658
0
            ssl->options.connectState = FIRST_REPLY_SECOND;
12659
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
12660
0
            FALL_THROUGH;
12661
12662
0
    #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
12663
0
        case FIRST_REPLY_SECOND :
12664
            /* CLIENT: Fail-safe for Server Authentication. */
12665
0
            if (!ssl->options.peerAuthGood) {
12666
0
                WOLFSSL_MSG("Server authentication did not happen");
12667
0
                ssl->error = NO_PEER_VERIFY;
12668
0
                return WOLFSSL_FATAL_ERROR;
12669
0
            }
12670
12671
0
            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
12672
0
                if (ssl->options.sendVerify) {
12673
0
                    if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
12674
                    #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12675
                        ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12676
                    #endif
12677
0
                        WOLFSSL_ERROR(ssl->error);
12678
0
                        return WOLFSSL_FATAL_ERROR;
12679
0
                    }
12680
0
                    WOLFSSL_MSG("sent: certificate verify");
12681
0
                }
12682
0
            #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */
12683
0
            ssl->options.connectState = FIRST_REPLY_THIRD;
12684
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
12685
0
            FALL_THROUGH;
12686
12687
0
        case FIRST_REPLY_THIRD :
12688
0
            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
12689
            #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12690
                ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12691
            #endif
12692
0
                WOLFSSL_ERROR(ssl->error);
12693
0
                return WOLFSSL_FATAL_ERROR;
12694
0
            }
12695
0
            WOLFSSL_MSG("sent: change cipher spec");
12696
0
            ssl->options.connectState = FIRST_REPLY_FOURTH;
12697
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
12698
0
            FALL_THROUGH;
12699
12700
0
        case FIRST_REPLY_FOURTH :
12701
0
            if ( (ssl->error = SendFinished(ssl)) != 0) {
12702
            #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12703
                ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12704
            #endif
12705
0
                WOLFSSL_ERROR(ssl->error);
12706
0
                return WOLFSSL_FATAL_ERROR;
12707
0
            }
12708
0
            WOLFSSL_MSG("sent: finished");
12709
0
            ssl->options.connectState = FINISHED_DONE;
12710
0
            WOLFSSL_MSG("connect state: FINISHED_DONE");
12711
0
            FALL_THROUGH;
12712
12713
#ifdef WOLFSSL_DTLS13
12714
        case WAIT_FINISHED_ACK:
12715
            ssl->options.connectState = FINISHED_DONE;
12716
            FALL_THROUGH;
12717
#endif /* WOLFSSL_DTLS13 */
12718
12719
0
        case FINISHED_DONE :
12720
            /* get response */
12721
0
            while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
12722
0
                if ( (ssl->error = ProcessReply(ssl)) < 0) {
12723
0
                    WOLFSSL_ERROR(ssl->error);
12724
0
                    return WOLFSSL_FATAL_ERROR;
12725
0
                }
12726
12727
0
            ssl->options.connectState = SECOND_REPLY_DONE;
12728
0
            WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
12729
0
            FALL_THROUGH;
12730
12731
0
        case SECOND_REPLY_DONE:
12732
0
        #ifndef NO_HANDSHAKE_DONE_CB
12733
0
            if (ssl->hsDoneCb) {
12734
0
                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
12735
0
                if (cbret < 0) {
12736
0
                    ssl->error = cbret;
12737
0
                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
12738
0
                    return WOLFSSL_FATAL_ERROR;
12739
0
                }
12740
0
            }
12741
0
        #endif /* NO_HANDSHAKE_DONE_CB */
12742
12743
0
            if (!ssl->options.dtls) {
12744
0
                if (!ssl->options.keepResources) {
12745
0
                    FreeHandshakeResources(ssl);
12746
0
                }
12747
0
            }
12748
        #ifdef WOLFSSL_DTLS
12749
            else {
12750
                ssl->options.dtlsHsRetain = 1;
12751
            }
12752
        #endif /* WOLFSSL_DTLS */
12753
12754
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
12755
            /* This may be necessary in async so that we don't try to
12756
             * renegotiate again */
12757
            if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
12758
                ssl->secure_renegotiation->startScr = 0;
12759
            }
12760
        #endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
12761
0
        #if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
12762
            /* Free the remaining async context if not using it for crypto */
12763
0
            FreeAsyncCtx(ssl, 1);
12764
0
        #endif
12765
12766
0
            ssl->error = 0; /* clear the error */
12767
12768
0
            WOLFSSL_LEAVE("SSL_connect()", WOLFSSL_SUCCESS);
12769
0
            return WOLFSSL_SUCCESS;
12770
0
    #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
12771
12772
0
        default:
12773
0
            WOLFSSL_MSG("Unknown connect state ERROR");
12774
0
            return WOLFSSL_FATAL_ERROR; /* unknown connect state */
12775
0
        }
12776
0
    #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS || !WOLFSSL_TLS13 */
12777
0
    }
12778
12779
#endif /* NO_WOLFSSL_CLIENT */
12780
12781
12782
/* server only parts */
12783
#ifndef NO_WOLFSSL_SERVER
12784
12785
    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
12786
    WOLFSSL_METHOD* wolfSSLv2_server_method(void)
12787
    {
12788
        WOLFSSL_STUB("wolfSSLv2_server_method");
12789
        return 0;
12790
    }
12791
    #endif
12792
12793
    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
12794
    WOLFSSL_METHOD* wolfSSLv3_server_method(void)
12795
    {
12796
        return wolfSSLv3_server_method_ex(NULL);
12797
    }
12798
    WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
12799
    {
12800
        WOLFSSL_METHOD* method =
12801
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12802
                                                     heap, DYNAMIC_TYPE_METHOD);
12803
        (void)heap;
12804
        WOLFSSL_ENTER("SSLv3_server_method_ex");
12805
        if (method) {
12806
            InitSSL_Method(method, MakeSSLv3());
12807
            method->side = WOLFSSL_SERVER_END;
12808
        }
12809
        return method;
12810
    }
12811
    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
12812
12813
    WOLFSSL_METHOD* wolfSSLv23_server_method(void)
12814
0
    {
12815
0
        return wolfSSLv23_server_method_ex(NULL);
12816
0
    }
12817
12818
    WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
12819
0
    {
12820
0
        WOLFSSL_METHOD* method =
12821
0
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12822
0
                                                     heap, DYNAMIC_TYPE_METHOD);
12823
0
        (void)heap;
12824
0
        WOLFSSL_ENTER("SSLv23_server_method_ex");
12825
0
        if (method) {
12826
0
    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
12827
0
        #ifdef WOLFSSL_TLS13
12828
0
            InitSSL_Method(method, MakeTLSv1_3());
12829
        #elif !defined(WOLFSSL_NO_TLS12)
12830
            InitSSL_Method(method, MakeTLSv1_2());
12831
        #elif !defined(NO_OLD_TLS)
12832
            InitSSL_Method(method, MakeTLSv1_1());
12833
        #endif
12834
    #else
12835
        #ifndef NO_OLD_TLS
12836
            InitSSL_Method(method, MakeTLSv1_1());
12837
        #else
12838
            #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
12839
        #endif
12840
    #endif
12841
0
    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
12842
0
            method->downgrade = 1;
12843
0
    #endif
12844
0
            method->side      = WOLFSSL_SERVER_END;
12845
0
        }
12846
0
        return method;
12847
0
    }
12848
12849
12850
    WOLFSSL_ABI
12851
    int wolfSSL_accept(WOLFSSL* ssl)
12852
0
    {
12853
0
#if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
12854
0
        word16 havePSK = 0;
12855
0
        word16 haveAnon = 0;
12856
0
        word16 haveMcast = 0;
12857
0
#endif
12858
0
        int ret = 0;
12859
12860
0
        (void)ret;
12861
12862
0
        if (ssl == NULL)
12863
0
            return WOLFSSL_FATAL_ERROR;
12864
12865
    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
12866
        if (ssl->options.side == WOLFSSL_NEITHER_END) {
12867
            WOLFSSL_MSG("Setting WOLFSSL_SSL to be server side");
12868
            ssl->error = InitSSL_Side(ssl, WOLFSSL_SERVER_END);
12869
            if (ssl->error != WOLFSSL_SUCCESS) {
12870
                WOLFSSL_ERROR(ssl->error);
12871
                return WOLFSSL_FATAL_ERROR;
12872
            }
12873
            ssl->error = 0; /* expected to be zero here */
12874
        }
12875
    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
12876
12877
#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
12878
        return wolfSSL_accept_TLSv13(ssl);
12879
#else
12880
0
    #ifdef WOLFSSL_TLS13
12881
0
        if (ssl->options.tls1_3)
12882
0
            return wolfSSL_accept_TLSv13(ssl);
12883
0
    #endif
12884
0
        WOLFSSL_ENTER("SSL_accept()");
12885
12886
        /* make sure this wolfSSL object has arrays and rng setup. Protects
12887
         * case where the WOLFSSL object is re-used via wolfSSL_clear() */
12888
0
        if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
12889
0
            return ret;
12890
0
        }
12891
12892
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
12893
        if ((ssl->AcceptFilter != NULL) &&
12894
            ((ssl->options.acceptState == ACCEPT_BEGIN)
12895
#ifdef HAVE_SECURE_RENEGOTIATION
12896
             || (ssl->options.acceptState == ACCEPT_BEGIN_RENEG)
12897
#endif
12898
                ))
12899
        {
12900
            wolfSSL_netfilter_decision_t res;
12901
            if ((ssl->AcceptFilter(ssl, ssl->AcceptFilter_arg, &res) ==
12902
                 WOLFSSL_SUCCESS) &&
12903
                (res == WOLFSSL_NETFILTER_REJECT)) {
12904
                ssl->error = SOCKET_FILTERED_E;
12905
                WOLFSSL_ERROR(ssl->error);
12906
                return WOLFSSL_FATAL_ERROR;
12907
            }
12908
        }
12909
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
12910
12911
0
        #ifdef HAVE_ERRNO_H
12912
0
            errno = 0;
12913
0
        #endif
12914
12915
        #ifndef NO_PSK
12916
            havePSK = ssl->options.havePSK;
12917
        #endif
12918
0
        (void)havePSK;
12919
12920
        #ifdef HAVE_ANON
12921
            haveAnon = ssl->options.haveAnon;
12922
        #endif
12923
0
        (void)haveAnon;
12924
12925
        #ifdef WOLFSSL_MULTICAST
12926
            haveMcast = ssl->options.haveMcast;
12927
        #endif
12928
0
        (void)haveMcast;
12929
12930
0
        if (ssl->options.side != WOLFSSL_SERVER_END) {
12931
0
            ssl->error = SIDE_ERROR;
12932
0
            WOLFSSL_ERROR(ssl->error);
12933
0
            return WOLFSSL_FATAL_ERROR;
12934
0
        }
12935
12936
0
    #ifndef NO_CERTS
12937
        /* in case used set_accept_state after init */
12938
0
        if (!havePSK && !haveAnon && !haveMcast) {
12939
        #ifdef OPENSSL_EXTRA
12940
            if (ssl->ctx->certSetupCb != NULL) {
12941
                WOLFSSL_MSG("CertSetupCb set. server cert and "
12942
                            "key not checked");
12943
            }
12944
            else
12945
        #endif
12946
0
            {
12947
0
                if (!ssl->buffers.certificate ||
12948
0
                    !ssl->buffers.certificate->buffer) {
12949
12950
0
                    WOLFSSL_MSG("accept error: server cert required");
12951
0
                    ssl->error = NO_PRIVATE_KEY;
12952
0
                    WOLFSSL_ERROR(ssl->error);
12953
0
                    return WOLFSSL_FATAL_ERROR;
12954
0
                }
12955
12956
0
                if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
12957
                    /* allow no private key if using existing key */
12958
0
                #ifdef WOLF_PRIVATE_KEY_ID
12959
0
                    if (ssl->devId != INVALID_DEVID
12960
                    #ifdef HAVE_PK_CALLBACKS
12961
                        || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
12962
                    #endif
12963
0
                    ) {
12964
0
                        WOLFSSL_MSG("Allowing no server private key "
12965
0
                                    "(external)");
12966
0
                    }
12967
0
                    else
12968
0
                #endif
12969
0
                    {
12970
0
                        WOLFSSL_MSG("accept error: server key required");
12971
0
                        ssl->error = NO_PRIVATE_KEY;
12972
0
                        WOLFSSL_ERROR(ssl->error);
12973
0
                        return WOLFSSL_FATAL_ERROR;
12974
0
                    }
12975
0
                }
12976
0
            }
12977
0
        }
12978
0
    #endif
12979
12980
    #ifdef WOLFSSL_DTLS
12981
        if (ssl->version.major == DTLS_MAJOR) {
12982
            ssl->options.dtls   = 1;
12983
            ssl->options.tls    = 1;
12984
            ssl->options.tls1_1 = 1;
12985
        }
12986
    #endif
12987
12988
0
        if (ssl->buffers.outputBuffer.length > 0
12989
        #ifdef WOLFSSL_ASYNC_CRYPT
12990
            /* do not send buffered or advance state if last error was an
12991
                async pending operation */
12992
            && ssl->error != WC_PENDING_E
12993
        #endif
12994
0
        ) {
12995
0
            ret = SendBuffered(ssl);
12996
0
            if (ret == 0) {
12997
                /* fragOffset is non-zero when sending fragments. On the last
12998
                 * fragment, fragOffset is zero again, and the state can be
12999
                 * advanced. */
13000
0
                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
13001
0
                    if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE ||
13002
0
                        ssl->options.acceptState == SERVER_HELLO_SENT ||
13003
0
                        ssl->options.acceptState == CERT_SENT ||
13004
0
                        ssl->options.acceptState == CERT_STATUS_SENT ||
13005
0
                        ssl->options.acceptState == KEY_EXCHANGE_SENT ||
13006
0
                        ssl->options.acceptState == CERT_REQ_SENT ||
13007
0
                        ssl->options.acceptState == ACCEPT_SECOND_REPLY_DONE ||
13008
0
                        ssl->options.acceptState == TICKET_SENT ||
13009
0
                        ssl->options.acceptState == CHANGE_CIPHER_SENT) {
13010
0
                        ssl->options.acceptState++;
13011
0
                        WOLFSSL_MSG("accept state: "
13012
0
                                    "Advanced from last buffered fragment send");
13013
0
                    #ifdef WOLFSSL_ASYNC_IO
13014
                        /* Cleanup async */
13015
0
                        FreeAsyncCtx(ssl, 0);
13016
0
                    #endif
13017
0
                    }
13018
0
                }
13019
0
                else {
13020
0
                    WOLFSSL_MSG("accept state: "
13021
0
                                "Not advanced, more fragments to send");
13022
0
                }
13023
0
            }
13024
0
            else {
13025
0
                ssl->error = ret;
13026
0
                WOLFSSL_ERROR(ssl->error);
13027
0
                return WOLFSSL_FATAL_ERROR;
13028
0
            }
13029
#ifdef WOLFSSL_DTLS13
13030
            if (ssl->options.dtls)
13031
                ssl->dtls13SendingAckOrRtx = 0;
13032
#endif /* WOLFSSL_DTLS13 */
13033
0
        }
13034
13035
0
        ret = RetrySendAlert(ssl);
13036
0
        if (ret != 0) {
13037
0
            ssl->error = ret;
13038
0
            WOLFSSL_ERROR(ssl->error);
13039
0
            return WOLFSSL_FATAL_ERROR;
13040
0
        }
13041
13042
0
        switch (ssl->options.acceptState) {
13043
13044
0
        case ACCEPT_BEGIN :
13045
#ifdef HAVE_SECURE_RENEGOTIATION
13046
        case ACCEPT_BEGIN_RENEG:
13047
#endif
13048
            /* get response */
13049
0
            while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
13050
0
                if ( (ssl->error = ProcessReply(ssl)) < 0) {
13051
0
                    WOLFSSL_ERROR(ssl->error);
13052
0
                    return WOLFSSL_FATAL_ERROR;
13053
0
                }
13054
0
#ifdef WOLFSSL_TLS13
13055
0
            ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
13056
0
            WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
13057
0
            FALL_THROUGH;
13058
13059
0
        case ACCEPT_CLIENT_HELLO_DONE :
13060
0
            if (ssl->options.tls1_3) {
13061
0
                return wolfSSL_accept_TLSv13(ssl);
13062
0
            }
13063
0
#endif
13064
13065
#ifdef WOLFSSL_DTLS
13066
            if (ssl->chGoodCb != NULL && !IsSCR(ssl)) {
13067
                int cbret = ssl->chGoodCb(ssl, ssl->chGoodCtx);
13068
                if (cbret < 0) {
13069
                    ssl->error = cbret;
13070
                    WOLFSSL_MSG("ClientHello Good Cb don't continue error");
13071
                    return WOLFSSL_FATAL_ERROR;
13072
                }
13073
            }
13074
#endif
13075
13076
0
            ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
13077
0
            WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
13078
0
            FALL_THROUGH;
13079
13080
0
        case ACCEPT_FIRST_REPLY_DONE :
13081
0
            if ( (ssl->error = SendServerHello(ssl)) != 0) {
13082
0
                WOLFSSL_ERROR(ssl->error);
13083
0
                return WOLFSSL_FATAL_ERROR;
13084
0
            }
13085
0
            ssl->options.acceptState = SERVER_HELLO_SENT;
13086
0
            WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
13087
0
            FALL_THROUGH;
13088
13089
0
        case SERVER_HELLO_SENT :
13090
0
        #ifdef WOLFSSL_TLS13
13091
0
            if (ssl->options.tls1_3) {
13092
0
                return wolfSSL_accept_TLSv13(ssl);
13093
0
            }
13094
0
        #endif
13095
0
            #ifndef NO_CERTS
13096
0
                if (!ssl->options.resuming)
13097
0
                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
13098
0
                        WOLFSSL_ERROR(ssl->error);
13099
0
                        return WOLFSSL_FATAL_ERROR;
13100
0
                    }
13101
0
            #endif
13102
0
            ssl->options.acceptState = CERT_SENT;
13103
0
            WOLFSSL_MSG("accept state CERT_SENT");
13104
0
            FALL_THROUGH;
13105
13106
0
        case CERT_SENT :
13107
0
            #ifndef NO_CERTS
13108
0
            if (!ssl->options.resuming)
13109
0
                if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
13110
0
                    WOLFSSL_ERROR(ssl->error);
13111
0
                    return WOLFSSL_FATAL_ERROR;
13112
0
                }
13113
0
            #endif
13114
0
            ssl->options.acceptState = CERT_STATUS_SENT;
13115
0
            WOLFSSL_MSG("accept state CERT_STATUS_SENT");
13116
0
            FALL_THROUGH;
13117
13118
0
        case CERT_STATUS_SENT :
13119
0
        #ifdef WOLFSSL_TLS13
13120
0
            if (ssl->options.tls1_3) {
13121
0
                return wolfSSL_accept_TLSv13(ssl);
13122
0
            }
13123
0
        #endif
13124
0
            if (!ssl->options.resuming)
13125
0
                if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
13126
0
                    WOLFSSL_ERROR(ssl->error);
13127
0
                    return WOLFSSL_FATAL_ERROR;
13128
0
                }
13129
0
            ssl->options.acceptState = KEY_EXCHANGE_SENT;
13130
0
            WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
13131
0
            FALL_THROUGH;
13132
13133
0
        case KEY_EXCHANGE_SENT :
13134
0
            #ifndef NO_CERTS
13135
0
                if (!ssl->options.resuming) {
13136
0
                    if (ssl->options.verifyPeer) {
13137
0
                        if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
13138
0
                            WOLFSSL_ERROR(ssl->error);
13139
0
                            return WOLFSSL_FATAL_ERROR;
13140
0
                        }
13141
0
                    }
13142
0
                    else {
13143
                        /* SERVER: Peer auth good if not verifying client. */
13144
0
                        ssl->options.peerAuthGood = 1;
13145
0
                    }
13146
0
                }
13147
0
            #endif
13148
0
            ssl->options.acceptState = CERT_REQ_SENT;
13149
0
            WOLFSSL_MSG("accept state CERT_REQ_SENT");
13150
0
            FALL_THROUGH;
13151
13152
0
        case CERT_REQ_SENT :
13153
0
            if (!ssl->options.resuming)
13154
0
                if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
13155
0
                    WOLFSSL_ERROR(ssl->error);
13156
0
                    return WOLFSSL_FATAL_ERROR;
13157
0
                }
13158
0
            ssl->options.acceptState = SERVER_HELLO_DONE;
13159
0
            WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
13160
0
            FALL_THROUGH;
13161
13162
0
        case SERVER_HELLO_DONE :
13163
0
            if (!ssl->options.resuming) {
13164
0
                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
13165
0
                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
13166
0
                        WOLFSSL_ERROR(ssl->error);
13167
0
                        return WOLFSSL_FATAL_ERROR;
13168
0
                    }
13169
0
            }
13170
0
            ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
13171
0
            WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
13172
0
            FALL_THROUGH;
13173
13174
0
        case ACCEPT_SECOND_REPLY_DONE :
13175
0
        #ifndef NO_CERTS
13176
            /* SERVER: When not resuming and verifying peer but no certificate
13177
             * received and not failing when not received then peer auth good.
13178
             */
13179
0
            if (!ssl->options.resuming && ssl->options.verifyPeer &&
13180
0
                !ssl->options.havePeerCert && !ssl->options.failNoCert) {
13181
0
                ssl->options.peerAuthGood = 1;
13182
0
            }
13183
0
        #endif /* !NO_CERTS  */
13184
        #ifdef WOLFSSL_NO_CLIENT_AUTH
13185
            if (!ssl->options.resuming) {
13186
                ssl->options.peerAuthGood = 1;
13187
            }
13188
        #endif
13189
13190
#ifdef HAVE_SESSION_TICKET
13191
            if (ssl->options.createTicket && !ssl->options.noTicketTls12) {
13192
                if ( (ssl->error = SendTicket(ssl)) != 0) {
13193
                    WOLFSSL_ERROR(ssl->error);
13194
                    return WOLFSSL_FATAL_ERROR;
13195
                }
13196
            }
13197
#endif /* HAVE_SESSION_TICKET */
13198
0
            ssl->options.acceptState = TICKET_SENT;
13199
0
            WOLFSSL_MSG("accept state  TICKET_SENT");
13200
0
            FALL_THROUGH;
13201
13202
0
        case TICKET_SENT:
13203
            /* SERVER: Fail-safe for CLient Authentication. */
13204
0
            if (!ssl->options.peerAuthGood) {
13205
0
                WOLFSSL_MSG("Client authentication did not happen");
13206
0
                return WOLFSSL_FATAL_ERROR;
13207
0
            }
13208
13209
0
            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
13210
0
                WOLFSSL_ERROR(ssl->error);
13211
0
                return WOLFSSL_FATAL_ERROR;
13212
0
            }
13213
0
            ssl->options.acceptState = CHANGE_CIPHER_SENT;
13214
0
            WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
13215
0
            FALL_THROUGH;
13216
13217
0
        case CHANGE_CIPHER_SENT :
13218
0
            if ( (ssl->error = SendFinished(ssl)) != 0) {
13219
0
                WOLFSSL_ERROR(ssl->error);
13220
0
                return WOLFSSL_FATAL_ERROR;
13221
0
            }
13222
13223
0
            ssl->options.acceptState = ACCEPT_FINISHED_DONE;
13224
0
            WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
13225
0
            FALL_THROUGH;
13226
13227
0
        case ACCEPT_FINISHED_DONE :
13228
0
            if (ssl->options.resuming) {
13229
0
                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
13230
0
                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
13231
0
                        WOLFSSL_ERROR(ssl->error);
13232
0
                        return WOLFSSL_FATAL_ERROR;
13233
0
                    }
13234
0
                }
13235
0
            }
13236
0
            ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
13237
0
            WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
13238
0
            FALL_THROUGH;
13239
13240
0
        case ACCEPT_THIRD_REPLY_DONE :
13241
0
#ifndef NO_HANDSHAKE_DONE_CB
13242
0
            if (ssl->hsDoneCb) {
13243
0
                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
13244
0
                if (cbret < 0) {
13245
0
                    ssl->error = cbret;
13246
0
                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
13247
0
                    return WOLFSSL_FATAL_ERROR;
13248
0
                }
13249
0
            }
13250
0
#endif /* NO_HANDSHAKE_DONE_CB */
13251
13252
0
            if (!ssl->options.dtls) {
13253
0
                if (!ssl->options.keepResources) {
13254
0
                    FreeHandshakeResources(ssl);
13255
0
                }
13256
0
            }
13257
#ifdef WOLFSSL_DTLS
13258
            else {
13259
                ssl->options.dtlsHsRetain = 1;
13260
            }
13261
#endif /* WOLFSSL_DTLS */
13262
13263
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
13264
            /* This may be necessary in async so that we don't try to
13265
             * renegotiate again */
13266
            if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
13267
                ssl->secure_renegotiation->startScr = 0;
13268
            }
13269
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
13270
0
#if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
13271
            /* Free the remaining async context if not using it for crypto */
13272
0
            FreeAsyncCtx(ssl, 1);
13273
0
#endif
13274
13275
#if defined(WOLFSSL_SESSION_EXPORT) && defined(WOLFSSL_DTLS)
13276
            if (ssl->dtls_export) {
13277
                if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
13278
                    WOLFSSL_MSG("Export DTLS session error");
13279
                    WOLFSSL_ERROR(ssl->error);
13280
                    return WOLFSSL_FATAL_ERROR;
13281
                }
13282
            }
13283
#endif
13284
0
            ssl->error = 0; /* clear the error */
13285
13286
0
            WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
13287
0
            return WOLFSSL_SUCCESS;
13288
13289
0
        default :
13290
0
            WOLFSSL_MSG("Unknown accept state ERROR");
13291
0
            return WOLFSSL_FATAL_ERROR;
13292
0
        }
13293
0
#endif /* !WOLFSSL_NO_TLS12 */
13294
0
    }
13295
13296
#endif /* NO_WOLFSSL_SERVER */
13297
13298
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
13299
int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx)
13300
{
13301
    WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
13302
13303
    if (ssl == NULL)
13304
        return BAD_FUNC_ARG;
13305
13306
    ssl->chGoodCb  = cb;
13307
    ssl->chGoodCtx = user_ctx;
13308
13309
    return WOLFSSL_SUCCESS;
13310
}
13311
#endif
13312
13313
#ifndef NO_HANDSHAKE_DONE_CB
13314
13315
int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
13316
0
{
13317
0
    WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
13318
13319
0
    if (ssl == NULL)
13320
0
        return BAD_FUNC_ARG;
13321
13322
0
    ssl->hsDoneCb  = cb;
13323
0
    ssl->hsDoneCtx = user_ctx;
13324
13325
13326
0
    return WOLFSSL_SUCCESS;
13327
0
}
13328
13329
#endif /* NO_HANDSHAKE_DONE_CB */
13330
13331
WOLFSSL_ABI
13332
int wolfSSL_Cleanup(void)
13333
0
{
13334
0
    int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
13335
0
    int release = 0;
13336
#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
13337
    int i;
13338
#endif
13339
13340
0
    WOLFSSL_ENTER("wolfSSL_Cleanup");
13341
13342
0
    if (initRefCount == 0)
13343
0
        return ret;  /* possibly no init yet, but not failure either way */
13344
13345
0
    if ((count_mutex_valid == 1) && (wc_LockMutex(&count_mutex) != 0)) {
13346
0
        WOLFSSL_MSG("Bad Lock Mutex count");
13347
0
        ret = BAD_MUTEX_E;
13348
0
    }
13349
13350
0
    release = initRefCount-- == 1;
13351
0
    if (initRefCount < 0)
13352
0
        initRefCount = 0;
13353
13354
0
    if (count_mutex_valid == 1) {
13355
0
        wc_UnLockMutex(&count_mutex);
13356
0
    }
13357
13358
0
    if (!release)
13359
0
        return ret;
13360
13361
#ifdef OPENSSL_EXTRA
13362
    if (bn_one) {
13363
        wolfSSL_BN_free(bn_one);
13364
        bn_one = NULL;
13365
    }
13366
#endif
13367
13368
0
#ifndef NO_SESSION_CACHE
13369
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
13370
    for (i = 0; i < SESSION_ROWS; ++i) {
13371
        if ((SessionCache[i].mutex_valid == 1) &&
13372
            (wc_FreeMutex(&SessionCache[i].row_mutex) != 0)) {
13373
            if (ret == WOLFSSL_SUCCESS)
13374
                ret = BAD_MUTEX_E;
13375
        }
13376
        SessionCache[i].mutex_valid = 0;
13377
    }
13378
    #else
13379
0
    if ((session_mutex_valid == 1) && (wc_FreeMutex(&session_mutex) != 0)) {
13380
0
        if (ret == WOLFSSL_SUCCESS)
13381
0
            ret = BAD_MUTEX_E;
13382
0
    }
13383
0
    session_mutex_valid = 0;
13384
0
    #endif
13385
0
    #ifndef NO_CLIENT_CACHE
13386
0
    if ((clisession_mutex_valid == 1) &&
13387
0
        (wc_FreeMutex(&clisession_mutex) != 0)) {
13388
0
        if (ret == WOLFSSL_SUCCESS)
13389
0
            ret = BAD_MUTEX_E;
13390
0
    }
13391
0
    clisession_mutex_valid = 0;
13392
0
    #endif
13393
0
#endif /* !NO_SESSION_CACHE */
13394
13395
0
    if ((count_mutex_valid == 1) && (wc_FreeMutex(&count_mutex) != 0)) {
13396
0
        if (ret == WOLFSSL_SUCCESS)
13397
0
            ret = BAD_MUTEX_E;
13398
0
    }
13399
0
    count_mutex_valid = 0;
13400
13401
#ifdef OPENSSL_EXTRA
13402
    wolfSSL_RAND_Cleanup();
13403
#endif
13404
13405
0
    if (wolfCrypt_Cleanup() != 0) {
13406
0
        WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
13407
0
        if (ret == WOLFSSL_SUCCESS)
13408
0
            ret = WC_CLEANUP_E;
13409
0
    }
13410
13411
#if FIPS_VERSION_GE(5,1)
13412
    if (wolfCrypt_SetPrivateKeyReadEnable_fips(0, WC_KEYTYPE_ALL) < 0) {
13413
        if (ret == WOLFSSL_SUCCESS)
13414
            ret = WC_CLEANUP_E;
13415
    }
13416
#endif
13417
13418
#ifdef HAVE_GLOBAL_RNG
13419
    if ((globalRNGMutex_valid == 1) && (wc_FreeMutex(&globalRNGMutex) != 0)) {
13420
        if (ret == WOLFSSL_SUCCESS)
13421
            ret = BAD_MUTEX_E;
13422
    }
13423
    globalRNGMutex_valid = 0;
13424
13425
    #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
13426
    wolfSSL_FIPS_drbg_free(gDrbgDefCtx);
13427
    gDrbgDefCtx = NULL;
13428
    #endif
13429
#endif
13430
13431
0
    return ret;
13432
0
}
13433
13434
13435
#ifndef NO_SESSION_CACHE
13436
13437
WOLFSSL_ABI
13438
void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
13439
0
{
13440
    /* static table now, no flushing needed */
13441
0
    (void)ctx;
13442
0
    (void)tm;
13443
0
}
13444
13445
13446
/* set ssl session timeout in seconds */
13447
WOLFSSL_ABI
13448
int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
13449
0
{
13450
0
    if (ssl == NULL)
13451
0
        return BAD_FUNC_ARG;
13452
13453
0
    if (to == 0)
13454
0
        to = WOLFSSL_SESSION_TIMEOUT;
13455
0
    ssl->timeout = to;
13456
13457
0
    return WOLFSSL_SUCCESS;
13458
0
}
13459
13460
13461
/**
13462
 * Sets ctx session timeout in seconds.
13463
 * The timeout value set here should be reflected in the
13464
 * "session ticket lifetime hint" if this API works in the openssl compat-layer.
13465
 * Therefore wolfSSL_CTX_set_TicketHint is called internally.
13466
 * Arguments:
13467
 *  - ctx  WOLFSSL_CTX object which the timeout is set to
13468
 *  - to   timeout value in second
13469
 * Returns:
13470
 *  WOLFSSL_SUCCESS on success, BAD_FUNC_ARG on failure.
13471
 *  When WOLFSSL_ERROR_CODE_OPENSSL is defined, returns previous timeout value
13472
 *  on success, BAD_FUNC_ARG on failure.
13473
 */
13474
WOLFSSL_ABI
13475
int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
13476
0
{
13477
    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
13478
    word32 prev_timeout = 0;
13479
    #endif
13480
13481
0
    int ret = WOLFSSL_SUCCESS;
13482
0
    (void)ret;
13483
13484
0
    if (ctx == NULL)
13485
0
        ret = BAD_FUNC_ARG;
13486
13487
0
    if (ret == WOLFSSL_SUCCESS) {
13488
    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
13489
        prev_timeout = ctx->timeout;
13490
    #endif
13491
0
        if (to == 0) {
13492
0
            ctx->timeout = WOLFSSL_SESSION_TIMEOUT;
13493
0
        }
13494
0
        else {
13495
0
            ctx->timeout = to;
13496
0
        }
13497
0
    }
13498
#if defined(OPENSSL_EXTRA) && defined(HAVE_SESSION_TICKET) && \
13499
   !defined(NO_WOLFSSL_SERVER)
13500
    if (ret == WOLFSSL_SUCCESS) {
13501
        if (to == 0) {
13502
            ret = wolfSSL_CTX_set_TicketHint(ctx, SESSION_TICKET_HINT_DEFAULT);
13503
        }
13504
        else {
13505
            ret = wolfSSL_CTX_set_TicketHint(ctx, to);
13506
        }
13507
    }
13508
#endif /* OPENSSL_EXTRA && HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER */
13509
13510
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
13511
    if (ret == WOLFSSL_SUCCESS) {
13512
        return prev_timeout;
13513
    }
13514
    else {
13515
        return ret;
13516
    }
13517
#else
13518
0
    return ret;
13519
0
#endif /* WOLFSSL_ERROR_CODE_OPENSSL */
13520
0
}
13521
13522
13523
#ifndef NO_CLIENT_CACHE
13524
13525
/* Get Session from Client cache based on id/len, return NULL on failure */
13526
WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
13527
0
{
13528
0
    WOLFSSL_SESSION* ret = NULL;
13529
0
    word32          row;
13530
0
    int             idx;
13531
0
    int             count;
13532
0
    int             error = 0;
13533
0
    ClientSession*  clSess;
13534
13535
0
    WOLFSSL_ENTER("GetSessionClient");
13536
13537
0
    if (ssl->ctx->sessionCacheOff) {
13538
0
        WOLFSSL_MSG("Session Cache off");
13539
0
        return NULL;
13540
0
    }
13541
13542
0
    if (ssl->options.side == WOLFSSL_SERVER_END)
13543
0
        return NULL;
13544
13545
0
    len = min(SERVER_ID_LEN, (word32)len);
13546
13547
#ifdef HAVE_EXT_CACHE
13548
    if (ssl->ctx->get_sess_cb != NULL) {
13549
        int copy = 0;
13550
        WOLFSSL_MSG("Calling external session cache");
13551
        ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, &copy);
13552
        if (ret != NULL) {
13553
            WOLFSSL_MSG("Session found in external cache");
13554
            return ret;
13555
        }
13556
        WOLFSSL_MSG("Session not found in external cache");
13557
    }
13558
13559
    if (ssl->ctx->internalCacheLookupOff) {
13560
        WOLFSSL_MSG("Internal cache turned off");
13561
        return NULL;
13562
    }
13563
#endif
13564
13565
0
    row = HashObject(id, len, &error) % CLIENT_SESSION_ROWS;
13566
0
    if (error != 0) {
13567
0
        WOLFSSL_MSG("Hash session failed");
13568
0
        return NULL;
13569
0
    }
13570
13571
0
    if (wc_LockMutex(&clisession_mutex) != 0) {
13572
0
        WOLFSSL_MSG("Client cache mutex lock failed");
13573
0
        return NULL;
13574
0
    }
13575
13576
    /* start from most recently used */
13577
0
    count = min((word32)ClientCache[row].totalCount, CLIENT_SESSIONS_PER_ROW);
13578
0
    idx = ClientCache[row].nextIdx - 1;
13579
0
    if (idx < 0 || idx >= CLIENT_SESSIONS_PER_ROW) {
13580
0
        idx = CLIENT_SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
13581
0
    }
13582
0
    clSess = ClientCache[row].Clients;
13583
13584
0
    for (; count > 0; --count) {
13585
0
        WOLFSSL_SESSION* current;
13586
0
        SessionRow* sessRow;
13587
13588
0
        if (clSess[idx].serverRow >= SESSION_ROWS) {
13589
0
            WOLFSSL_MSG("Client cache serverRow invalid");
13590
0
            break;
13591
0
        }
13592
13593
        /* lock row */
13594
0
        sessRow = &SessionCache[clSess[idx].serverRow];
13595
0
        if (SESSION_ROW_LOCK(sessRow) != 0) {
13596
0
            WOLFSSL_MSG("Session cache row lock failure");
13597
0
            break;
13598
0
        }
13599
13600
0
        current = &sessRow->Sessions[clSess[idx].serverIdx];
13601
0
        if (XMEMCMP(current->serverID, id, len) == 0) {
13602
0
            WOLFSSL_MSG("Found a serverid match for client");
13603
0
            if (LowResTimer() < (current->bornOn + current->timeout)) {
13604
0
                WOLFSSL_MSG("Session valid");
13605
0
                ret = current;
13606
0
                SESSION_ROW_UNLOCK(sessRow);
13607
0
                break;
13608
0
            } else {
13609
0
                WOLFSSL_MSG("Session timed out");  /* could have more for id */
13610
0
            }
13611
0
        } else {
13612
0
            WOLFSSL_MSG("ServerID not a match from client table");
13613
0
        }
13614
0
        SESSION_ROW_UNLOCK(sessRow);
13615
13616
0
        idx = idx > 0 ? idx - 1 : CLIENT_SESSIONS_PER_ROW - 1;
13617
0
    }
13618
13619
0
    wc_UnLockMutex(&clisession_mutex);
13620
13621
0
    return ret;
13622
0
}
13623
13624
#endif /* !NO_CLIENT_CACHE */
13625
13626
static int SslSessionCacheOff(const WOLFSSL* ssl, const WOLFSSL_SESSION* session)
13627
0
{
13628
0
    (void)session;
13629
0
    return ssl->options.sessionCacheOff
13630
    #if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_FORCE_CACHE_ON_TICKET)
13631
                && session->ticketLen == 0
13632
    #endif
13633
    #ifdef OPENSSL_EXTRA
13634
                && ssl->options.side != WOLFSSL_CLIENT_END
13635
    #endif
13636
0
                ;
13637
0
}
13638
13639
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) &&                  \
13640
    defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
13641
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
13642
/**
13643
 * SessionTicketNoncePrealloc() - prealloc a buffer for ticket nonces
13644
 * @output: [in] pointer to WOLFSSL_SESSION object that will soon be a
13645
 * destination of a session duplication
13646
 * @buf: [out] address of the preallocated buf
13647
 * @len: [out] len of the preallocated buf
13648
 *
13649
 * prealloc a buffer that will likely suffice to contain a ticket nonce. It's
13650
 * used when copying session under lock, when syscalls need to be avoided. If
13651
 * output already has a dynamic buffer, it's reused.
13652
 */
13653
static int SessionTicketNoncePrealloc(byte** buf, byte* len, void *heap)
13654
{
13655
    (void)heap;
13656
13657
    *buf = (byte*)XMALLOC(PREALLOC_SESSION_TICKET_NONCE_LEN, heap,
13658
        DYNAMIC_TYPE_SESSION_TICK);
13659
    if (*buf == NULL) {
13660
        WOLFSSL_MSG("Failed to preallocate ticket nonce buffer");
13661
        *len = 0;
13662
        return WOLFSSL_FAILURE;
13663
    }
13664
13665
    *len = PREALLOC_SESSION_TICKET_NONCE_LEN;
13666
    return 0;
13667
}
13668
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 */
13669
13670
static int wolfSSL_DupSessionEx(const WOLFSSL_SESSION* input,
13671
    WOLFSSL_SESSION* output, int avoidSysCalls, byte* ticketNonceBuf,
13672
    byte* ticketNonceLen, byte* preallocUsed);
13673
13674
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
13675
0
{
13676
0
    WOLFSSL_SESSION* sess = NULL;
13677
0
    const byte*  id = NULL;
13678
0
    word32       row;
13679
0
    int          idx;
13680
0
    int          count;
13681
0
    int          error = 0;
13682
0
    SessionRow*  sessRow;
13683
#ifdef HAVE_SESSION_TICKET
13684
#ifndef WOLFSSL_SMALL_STACK
13685
    byte         tmpTicket[PREALLOC_SESSION_TICKET_LEN];
13686
#else
13687
    byte*        tmpTicket = NULL;
13688
#endif
13689
#ifdef WOLFSSL_TLS13
13690
    byte *preallocNonce = NULL;
13691
    byte preallocNonceLen = 0;
13692
    byte preallocNonceUsed = 0;
13693
#endif /* WOLFSSL_TLS13 */
13694
    byte         tmpBufSet = 0;
13695
#endif
13696
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13697
    WOLFSSL_X509* peer = NULL;
13698
#endif
13699
0
    byte         bogusID[ID_LEN];
13700
0
    byte         bogusIDSz = 0;
13701
13702
0
    WOLFSSL_ENTER("wolfSSL_GetSessionFromCache");
13703
13704
0
    if (output == NULL) {
13705
0
        WOLFSSL_MSG("NULL output");
13706
0
        return WOLFSSL_FAILURE;
13707
0
    }
13708
13709
0
    if (SslSessionCacheOff(ssl, ssl->session))
13710
0
        return WOLFSSL_FAILURE;
13711
13712
0
    if (ssl->options.haveSessionId == 0)
13713
0
        return WOLFSSL_FAILURE;
13714
13715
#ifdef HAVE_SESSION_TICKET
13716
    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
13717
        return WOLFSSL_FAILURE;
13718
#endif
13719
13720
0
    XMEMSET(bogusID, 0, sizeof(bogusID));
13721
0
    if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
13722
0
        id = ssl->arrays->sessionID;
13723
0
    else if (ssl->session->haveAltSessionID) {
13724
0
        id = ssl->session->altSessionID;
13725
        /* We want to restore the bogus ID for TLS compatibility */
13726
0
        if (output == ssl->session) {
13727
0
            XMEMCPY(bogusID, ssl->session->sessionID, ID_LEN);
13728
0
            bogusIDSz = ssl->session->sessionIDSz;
13729
0
        }
13730
0
    }
13731
0
    else
13732
0
        id = ssl->session->sessionID;
13733
13734
13735
#ifdef HAVE_EXT_CACHE
13736
    if (ssl->ctx->get_sess_cb != NULL) {
13737
        int copy = 0;
13738
        /* Attempt to retrieve the session from the external cache. */
13739
        WOLFSSL_MSG("Calling external session cache");
13740
        sess = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, &copy);
13741
        if (sess != NULL) {
13742
            WOLFSSL_MSG("Session found in external cache");
13743
            error = wolfSSL_DupSession(sess, output, 0);
13744
#ifdef HAVE_EX_DATA
13745
            output->ownExData = 0; /* Session cache owns external data */
13746
#endif
13747
            /* If copy not set then free immediately */
13748
            if (!copy)
13749
                wolfSSL_FreeSession(ssl->ctx, sess);
13750
            /* We want to restore the bogus ID for TLS compatibility */
13751
            if (ssl->session->haveAltSessionID &&
13752
                    output == ssl->session) {
13753
                XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN);
13754
                ssl->session->sessionIDSz = bogusIDSz;
13755
            }
13756
            return error;
13757
        }
13758
        WOLFSSL_MSG("Session not found in external cache");
13759
    }
13760
13761
    if (ssl->ctx->internalCacheLookupOff) {
13762
        WOLFSSL_MSG("Internal cache lookup turned off");
13763
        return WOLFSSL_FAILURE;
13764
    }
13765
#endif
13766
13767
0
    row = HashObject(id, ID_LEN, &error) % SESSION_ROWS;
13768
0
    if (error != 0) {
13769
0
        WOLFSSL_MSG("Hash session failed");
13770
0
        return WOLFSSL_FAILURE;
13771
0
    }
13772
13773
13774
#ifdef HAVE_SESSION_TICKET
13775
    if (output->ticket == NULL ||
13776
            output->ticketLenAlloc < PREALLOC_SESSION_TICKET_LEN) {
13777
#ifdef WOLFSSL_SMALL_STACK
13778
        tmpTicket = (byte*)XMALLOC(PREALLOC_SESSION_TICKET_LEN, output->heap,
13779
                DYNAMIC_TYPE_TMP_BUFFER);
13780
        if (tmpTicket == NULL) {
13781
            WOLFSSL_MSG("tmpTicket malloc failed");
13782
            return WOLFSSL_FAILURE;
13783
        }
13784
#endif
13785
        if (output->ticketLenAlloc)
13786
            XFREE(output->ticket, output->heap, DYNAMIC_TYPE_SESSION_TICK);
13787
        output->ticket = tmpTicket;
13788
        output->ticketLenAlloc = PREALLOC_SESSION_TICKET_LEN;
13789
        output->ticketLen = 0;
13790
        tmpBufSet = 1;
13791
    }
13792
#endif
13793
13794
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13795
    if (output->peer != NULL) {
13796
        wolfSSL_X509_free(output->peer);
13797
        output->peer = NULL;
13798
    }
13799
#endif
13800
13801
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) &&                  \
13802
    defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                                    \
13803
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
13804
    if (output->ticketNonce.data != output->ticketNonce.dataStatic) {
13805
        XFREE(output->ticketNonce.data, output->heap,
13806
            DYNAMIC_TYPE_SESSION_TICK);
13807
        output->ticketNonce.data = output->ticketNonce.dataStatic;
13808
        output->ticketNonce.len = 0;
13809
    }
13810
    error = SessionTicketNoncePrealloc(&preallocNonce, &preallocNonceLen,
13811
        output->heap);
13812
    if (error != 0) {
13813
        if (tmpBufSet) {
13814
            output->ticket = output->staticTicket;
13815
            output->ticketLenAlloc = 0;
13816
        }
13817
#ifdef WOLFSSL_SMALL_STACK
13818
        if (tmpTicket != NULL)
13819
            XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
13820
#endif
13821
        return WOLFSSL_FAILURE;
13822
    }
13823
#endif /* WOLFSSL_TLS13 && HAVE_SESSION_TICKET*/
13824
13825
    /* lock row */
13826
0
    sessRow = &SessionCache[row];
13827
0
    if (SESSION_ROW_LOCK(sessRow) != 0) {
13828
0
        WOLFSSL_MSG("Session cache row lock failure");
13829
#ifdef HAVE_SESSION_TICKET
13830
        if (tmpBufSet) {
13831
            output->ticket = output->staticTicket;
13832
            output->ticketLenAlloc = 0;
13833
        }
13834
#ifdef WOLFSSL_TLS13
13835
        if (preallocNonce != NULL)
13836
            XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
13837
#endif /* WOLFSSL_TLS13 */
13838
#ifdef WOLFSSL_SMALL_STACK
13839
        if (tmpTicket != NULL)
13840
            XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
13841
#endif
13842
#endif
13843
0
        return WOLFSSL_FAILURE;
13844
0
    }
13845
13846
    /* start from most recently used */
13847
0
    count = min((word32)sessRow->totalCount, SESSIONS_PER_ROW);
13848
0
    idx = sessRow->nextIdx - 1;
13849
0
    if (idx < 0 || idx >= SESSIONS_PER_ROW) {
13850
0
        idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
13851
0
    }
13852
13853
0
    for (; count > 0; --count) {
13854
0
        WOLFSSL_SESSION* current;
13855
13856
0
        current = &sessRow->Sessions[idx];
13857
0
        if (XMEMCMP(current->sessionID, id, ID_LEN) == 0 &&
13858
0
                current->side == ssl->options.side) {
13859
0
            WOLFSSL_MSG("Found a session match");
13860
0
            if (LowResTimer() < (current->bornOn + current->timeout)) {
13861
0
                WOLFSSL_MSG("Session valid");
13862
0
                sess = current;
13863
0
            } else {
13864
0
                WOLFSSL_MSG("Session timed out");
13865
0
            }
13866
0
            break;  /* no more sessionIDs whether valid or not that match */
13867
0
        } else {
13868
0
            WOLFSSL_MSG("SessionID not a match at this idx");
13869
0
        }
13870
13871
0
        idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
13872
0
    }
13873
13874
0
    if (sess != NULL) {
13875
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13876
        /* We don't want the peer member. We will free it at the end. */
13877
        if (sess->peer != NULL) {
13878
            peer = sess->peer;
13879
            sess->peer = NULL;
13880
        }
13881
#endif
13882
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13)
13883
        error = wolfSSL_DupSessionEx(sess, output, 1,
13884
            preallocNonce, &preallocNonceLen, &preallocNonceUsed);
13885
#else
13886
0
        error = wolfSSL_DupSession(sess, output, 1);
13887
0
#endif /* WOLFSSL_TSL */
13888
13889
#ifdef HAVE_EX_DATA
13890
        output->ownExData = 0; /* Session cache owns external data */
13891
#endif
13892
0
    }
13893
0
    else {
13894
0
        error = WOLFSSL_FAILURE;
13895
0
    }
13896
13897
0
    SESSION_ROW_UNLOCK(sessRow);
13898
13899
    /* We want to restore the bogus ID for TLS compatibility */
13900
0
    if (ssl->session->haveAltSessionID &&
13901
0
            output == ssl->session) {
13902
0
        XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN);
13903
0
        ssl->session->sessionIDSz = bogusIDSz;
13904
0
    }
13905
13906
#ifdef HAVE_SESSION_TICKET
13907
    if (tmpBufSet) {
13908
        if (error == WOLFSSL_SUCCESS) {
13909
            if (output->ticketLen > SESSION_TICKET_LEN) {
13910
                output->ticket = (byte*)XMALLOC(output->ticketLen, output->heap,
13911
                        DYNAMIC_TYPE_SESSION_TICK);
13912
                if (output->ticket == NULL) {
13913
                    error = WOLFSSL_FAILURE;
13914
                    output->ticket = output->staticTicket;
13915
                    output->ticketLenAlloc = 0;
13916
                    output->ticketLen = 0;
13917
                }
13918
            }
13919
            else {
13920
                output->ticket = output->staticTicket;
13921
                output->ticketLenAlloc = 0;
13922
            }
13923
        }
13924
        else {
13925
            output->ticket = output->staticTicket;
13926
            output->ticketLenAlloc = 0;
13927
            output->ticketLen = 0;
13928
        }
13929
        if (error == WOLFSSL_SUCCESS) {
13930
            XMEMCPY(output->ticket, tmpTicket, output->ticketLen);
13931
        }
13932
    }
13933
#ifdef WOLFSSL_SMALL_STACK
13934
    if (tmpTicket != NULL)
13935
        XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
13936
#endif
13937
13938
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&          \
13939
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
13940
    if (error == WOLFSSL_SUCCESS && preallocNonceUsed) {
13941
        if (preallocNonceLen < PREALLOC_SESSION_TICKET_NONCE_LEN) {
13942
            /* buffer bigger than needed */
13943
#ifndef XREALLOC
13944
            output->ticketNonce.data = (byte*)XMALLOC(preallocNonceLen,
13945
                output->heap, DYNAMIC_TYPE_SESSION_TICK);
13946
            if (output->ticketNonce.data != NULL)
13947
                XMEMCPY(output->ticketNonce.data, preallocNonce,
13948
                    preallocNonceLen);
13949
            XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
13950
            preallocNonce = NULL;
13951
#else
13952
            output->ticketNonce.data = XREALLOC(preallocNonce,
13953
                preallocNonceLen, output->heap, DYNAMIC_TYPE_SESSION_TICK);
13954
            if (output->ticketNonce.data != NULL) {
13955
                /* don't free the reallocated pointer */
13956
                preallocNonce = NULL;
13957
            }
13958
#endif /* !XREALLOC */
13959
            if (output->ticketNonce.data == NULL) {
13960
                output->ticketNonce.data = output->ticketNonce.dataStatic;
13961
                output->ticketNonce.len = 0;
13962
                error = WOLFSSL_FAILURE;
13963
                /* preallocNonce will be free'd after the if */
13964
            }
13965
        }
13966
        else {
13967
            output->ticketNonce.data = preallocNonce;
13968
            output->ticketNonce.len = preallocNonceLen;
13969
            preallocNonce = NULL;
13970
        }
13971
    }
13972
    if (preallocNonce != NULL)
13973
        XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK);
13974
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
13975
13976
#endif
13977
13978
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13979
    if (peer != NULL) {
13980
        wolfSSL_X509_free(peer);
13981
    }
13982
#endif
13983
13984
0
    return error;
13985
0
}
13986
13987
WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret,
13988
        byte restoreSessionCerts)
13989
0
{
13990
0
    WOLFSSL_SESSION* ret = NULL;
13991
13992
0
    (void)restoreSessionCerts; /* Kept for compatibility */
13993
13994
0
    if (wolfSSL_GetSessionFromCache(ssl, ssl->session) == WOLFSSL_SUCCESS) {
13995
0
        ret = ssl->session;
13996
0
    }
13997
0
    else {
13998
0
        WOLFSSL_MSG("wolfSSL_GetSessionFromCache did not return a session");
13999
0
    }
14000
14001
0
    if (ret != NULL && masterSecret != NULL)
14002
0
        XMEMCPY(masterSecret, ret->masterSecret, SECRET_LEN);
14003
14004
0
    return ret;
14005
0
}
14006
14007
int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
14008
0
{
14009
0
    SessionRow* sessRow = NULL;
14010
0
    int ret = WOLFSSL_SUCCESS;
14011
14012
0
    session = ClientSessionToSession(session);
14013
14014
0
    if (ssl == NULL || session == NULL) {
14015
0
        return WOLFSSL_FAILURE;
14016
0
    }
14017
14018
0
    if (session->type == WOLFSSL_SESSION_TYPE_CACHE) {
14019
0
        if (session->cacheRow < SESSION_ROWS) {
14020
0
            sessRow = &SessionCache[session->cacheRow];
14021
0
            if (SESSION_ROW_LOCK(sessRow) != 0) {
14022
0
                WOLFSSL_MSG("Session row lock failed");
14023
0
                return WOLFSSL_FAILURE;
14024
0
            }
14025
0
        }
14026
0
    }
14027
14028
0
    if (ret == WOLFSSL_SUCCESS && SslSessionCacheOff(ssl, session)) {
14029
0
        WOLFSSL_MSG("Session cache off");
14030
0
        ret = WOLFSSL_FAILURE;
14031
0
    }
14032
14033
0
    if (ret == WOLFSSL_SUCCESS && ssl->options.side != WOLFSSL_NEITHER_END &&
14034
0
            (byte)ssl->options.side != session->side) {
14035
0
        WOLFSSL_MSG("Setting session for wrong role");
14036
0
        ret = WOLFSSL_FAILURE;
14037
0
    }
14038
14039
14040
0
    if (ret == WOLFSSL_SUCCESS &&
14041
0
            wolfSSL_DupSession(session, ssl->session, 0) != WOLFSSL_SUCCESS) {
14042
0
        WOLFSSL_MSG("Session duplicate failed");
14043
0
        ret = WOLFSSL_FAILURE;
14044
0
    }
14045
14046
    /* Let's copy over the altSessionID for local cache purposes */
14047
0
    if (ret == WOLFSSL_SUCCESS && session->haveAltSessionID) {
14048
0
        ssl->session->haveAltSessionID = 1;
14049
0
        XMEMCPY(ssl->session->altSessionID, session->altSessionID, ID_LEN);
14050
0
    }
14051
14052
0
    if (sessRow != NULL) {
14053
0
        SESSION_ROW_UNLOCK(sessRow);
14054
0
        sessRow = NULL;
14055
0
    }
14056
14057
    /* Note: the `session` variable cannot be used below, since the row is
14058
     * un-locked */
14059
14060
0
    if (ret != WOLFSSL_SUCCESS)
14061
0
        return ret;
14062
14063
#ifdef OPENSSL_EXTRA
14064
    /* check for application context id */
14065
    if (ssl->sessionCtxSz > 0) {
14066
        if (XMEMCMP(ssl->sessionCtx, ssl->session->sessionCtx, ssl->sessionCtxSz)) {
14067
            /* context id did not match! */
14068
            WOLFSSL_MSG("Session context did not match");
14069
            return WOLFSSL_FAILURE;
14070
        }
14071
    }
14072
#endif /* OPENSSL_EXTRA */
14073
14074
0
    if (LowResTimer() < (ssl->session->bornOn + ssl->session->timeout)) {
14075
0
        ssl->options.resuming = 1;
14076
0
        ssl->options.haveEMS = ssl->session->haveEMS;
14077
14078
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
14079
                               defined(HAVE_SESSION_TICKET))
14080
        ssl->version              = ssl->session->version;
14081
        if (IsAtLeastTLSv1_3(ssl->version))
14082
            ssl->options.tls1_3 = 1;
14083
#endif
14084
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
14085
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
14086
0
        ssl->options.cipherSuite0 = ssl->session->cipherSuite0;
14087
0
        ssl->options.cipherSuite  = ssl->session->cipherSuite;
14088
0
#endif
14089
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14090
        ssl->peerVerifyRet = (unsigned long)ssl->session->peerVerifyRet;
14091
#endif
14092
0
        ret = WOLFSSL_SUCCESS;
14093
0
    }
14094
0
    else {
14095
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL)
14096
        WOLFSSL_MSG("Session is expired but return success for \
14097
                              OpenSSL compatibility");
14098
        ret = WOLFSSL_SUCCESS;
14099
#else
14100
0
        ret = WOLFSSL_FAILURE;  /* session timed out */
14101
0
#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL */
14102
0
    }
14103
0
    return ret;
14104
0
}
14105
14106
14107
#ifdef WOLFSSL_SESSION_STATS
14108
static int get_locked_session_stats(word32* active, word32* total,
14109
                                    word32* peak);
14110
#endif
14111
14112
#ifndef NO_CLIENT_CACHE
14113
ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverID,
14114
                            word16 idLen, const byte* sessionID,
14115
                            word16 useTicket)
14116
0
{
14117
0
    int error = -1;
14118
0
    word32 clientRow = 0, clientIdx = 0, sessionIDHash = 0;
14119
0
    (void)useTicket;
14120
0
    if (side == WOLFSSL_CLIENT_END
14121
0
            && row != INVALID_SESSION_ROW
14122
0
            && (idLen
14123
#ifdef HAVE_SESSION_TICKET
14124
                || useTicket == 1
14125
#endif
14126
0
                || serverID != NULL
14127
0
                )) {
14128
14129
0
        WOLFSSL_MSG("Trying to add client cache entry");
14130
14131
0
        if (idLen) {
14132
0
            clientRow = HashObject(serverID,
14133
0
                    idLen, &error) % CLIENT_SESSION_ROWS;
14134
0
        }
14135
0
        else if (serverID != NULL) {
14136
0
            clientRow = HashObject(sessionID,
14137
0
                    ID_LEN, &error) % CLIENT_SESSION_ROWS;
14138
0
        }
14139
0
        else {
14140
0
            error = -1;
14141
0
        }
14142
0
        if (error == 0 && wc_LockMutex(&clisession_mutex) == 0) {
14143
0
            clientIdx = ClientCache[clientRow].nextIdx;
14144
0
            if (clientIdx < CLIENT_SESSIONS_PER_ROW) {
14145
0
                ClientCache[clientRow].Clients[clientIdx].serverRow =
14146
0
                                                                (word16)row;
14147
0
                ClientCache[clientRow].Clients[clientIdx].serverIdx =
14148
0
                                                                (word16)idx;
14149
0
                if (sessionID != NULL) {
14150
0
                    sessionIDHash = HashObject(sessionID, ID_LEN, &error);
14151
0
                    if (error == 0) {
14152
0
                        ClientCache[clientRow].Clients[clientIdx].sessionIDHash
14153
0
                            = sessionIDHash;
14154
0
                    }
14155
0
                }
14156
0
            }
14157
0
            else {
14158
0
                error = -1;
14159
0
                ClientCache[clientRow].nextIdx = 0; /* reset index as saftey */
14160
0
                WOLFSSL_MSG("Invalid client cache index! "
14161
0
                            "Possible corrupted memory");
14162
0
            }
14163
0
            if (error == 0) {
14164
0
                WOLFSSL_MSG("Adding client cache entry");
14165
0
                if (ClientCache[clientRow].totalCount < CLIENT_SESSIONS_PER_ROW)
14166
0
                    ClientCache[clientRow].totalCount++;
14167
0
                ClientCache[clientRow].nextIdx++;
14168
0
                ClientCache[clientRow].nextIdx %= CLIENT_SESSIONS_PER_ROW;
14169
0
            }
14170
14171
0
            wc_UnLockMutex(&clisession_mutex);
14172
0
        }
14173
0
        else {
14174
0
            WOLFSSL_MSG("Hash session or lock failed");
14175
0
            error = -1;
14176
0
        }
14177
0
    }
14178
0
    else {
14179
0
        WOLFSSL_MSG("Skipping client cache");
14180
0
    }
14181
0
    if (error == 0)
14182
0
        return &ClientCache[clientRow].Clients[clientIdx];
14183
0
    else
14184
0
        return NULL;
14185
0
}
14186
#endif
14187
14188
/**
14189
 * For backwards compatibility, this API needs to be used in *ALL* functions
14190
 * that access the WOLFSSL_SESSION members directly.
14191
 *
14192
 * This API checks if the passed in session is actually a ClientSession object
14193
 * and returns the matching session cache object. Otherwise just return the
14194
 * input. ClientSession objects only occur in the ClientCache. They are not
14195
 * allocated anywhere else.
14196
 */
14197
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
14198
0
{
14199
0
    WOLFSSL_ENTER("ClientSessionToSession");
14200
#ifdef NO_SESSION_CACHE_REF
14201
    return (WOLFSSL_SESSION*)session;
14202
#else
14203
0
#ifndef NO_CLIENT_CACHE
14204
0
    if (session == NULL)
14205
0
        return NULL;
14206
    /* Check if session points into ClientCache */
14207
0
    if ((byte*)session >= (byte*)ClientCache &&
14208
            /* Cast to byte* to make pointer arithmetic work per byte */
14209
0
            (byte*)session < ((byte*)ClientCache) + sizeof(ClientCache)) {
14210
0
        ClientSession* clientSession = (ClientSession*)session;
14211
0
        SessionRow* sessRow = NULL;
14212
0
        WOLFSSL_SESSION* cacheSession = NULL;
14213
0
        word32 sessionIDHash = 0;
14214
0
        int error = 0;
14215
0
        session = NULL; /* Default to NULL for failure case */
14216
0
        if (wc_LockMutex(&clisession_mutex) != 0) {
14217
0
            WOLFSSL_MSG("Client cache mutex lock failed");
14218
0
            return NULL;
14219
0
        }
14220
0
        if (clientSession->serverRow >= SESSION_ROWS ||
14221
0
                clientSession->serverIdx >= SESSIONS_PER_ROW) {
14222
0
            WOLFSSL_MSG("Client cache serverRow or serverIdx invalid");
14223
0
            error = -1;
14224
0
        }
14225
0
        if (error == 0) {
14226
            /* Lock row */
14227
0
            sessRow = &SessionCache[clientSession->serverRow];
14228
0
            error = SESSION_ROW_LOCK(sessRow);
14229
0
            if (error != 0) {
14230
0
                WOLFSSL_MSG("Session cache row lock failure");
14231
0
                sessRow = NULL;
14232
0
            }
14233
0
        }
14234
0
        if (error == 0) {
14235
0
            cacheSession = &sessRow->Sessions[clientSession->serverIdx];
14236
0
            if (cacheSession->sessionIDSz == 0) {
14237
0
                cacheSession = NULL;
14238
0
                WOLFSSL_MSG("Session cache entry not set");
14239
0
                error = -1;
14240
0
            }
14241
0
        }
14242
0
        if (error == 0) {
14243
            /* Calculate the hash of the session ID */
14244
0
            sessionIDHash = HashObject(cacheSession->sessionID, ID_LEN,
14245
0
                    &error);
14246
0
        }
14247
0
        if (error == 0) {
14248
            /* Check the session ID hash matches */
14249
0
            error = clientSession->sessionIDHash != sessionIDHash;
14250
0
        }
14251
0
        if (error == 0) {
14252
            /* Hashes match */
14253
0
            session = cacheSession;
14254
0
            WOLFSSL_MSG("Found session cache matching client session object");
14255
0
        }
14256
0
        if (sessRow != NULL) {
14257
0
            SESSION_ROW_UNLOCK(sessRow);
14258
0
        }
14259
0
        wc_UnLockMutex(&clisession_mutex);
14260
0
        return (WOLFSSL_SESSION*)session;
14261
0
    }
14262
0
    else {
14263
        /* Plain WOLFSSL_SESSION object */
14264
0
        return (WOLFSSL_SESSION*)session;
14265
0
    }
14266
#else
14267
    return (WOLFSSL_SESSION*)session;
14268
#endif
14269
0
#endif
14270
0
}
14271
14272
int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
14273
        const byte* id, byte idSz, int* sessionIndex, int side,
14274
        word16 useTicket, ClientSession** clientCacheEntry)
14275
0
{
14276
0
    WOLFSSL_SESSION* cacheSession = NULL;
14277
0
    SessionRow* sessRow = NULL;
14278
0
    word32 idx = 0;
14279
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
14280
    WOLFSSL_X509* peer = NULL;
14281
#endif
14282
#ifdef HAVE_SESSION_TICKET
14283
    byte*  cacheTicBuff = NULL;
14284
    byte   ticBuffUsed = 0;
14285
    byte*  ticBuff = NULL;
14286
    int    ticLen  = 0;
14287
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&          \
14288
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
14289
    byte *preallocNonce = NULL;
14290
    byte preallocNonceLen = 0;
14291
    byte preallocNonceUsed = 0;
14292
    byte *toFree = NULL;
14293
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC */
14294
#endif /* HAVE_SESSION_TICKET */
14295
0
    int ret = 0;
14296
0
    int row;
14297
0
    int i;
14298
0
    int overwrite = 0;
14299
14300
0
    (void)ctx;
14301
0
    (void)sessionIndex;
14302
0
    (void)useTicket;
14303
0
    (void)clientCacheEntry;
14304
14305
0
    if (idSz == 0) {
14306
0
        WOLFSSL_MSG("AddSessionToCache idSz == 0");
14307
0
        return BAD_FUNC_ARG;
14308
0
    }
14309
14310
0
    addSession = ClientSessionToSession(addSession);
14311
0
    if (addSession == NULL) {
14312
0
        WOLFSSL_MSG("AddSessionToCache is NULL");
14313
0
        return MEMORY_E;
14314
0
    }
14315
14316
#ifdef HAVE_SESSION_TICKET
14317
    ticLen = addSession->ticketLen;
14318
    /* Alloc Memory here to avoid syscalls during lock */
14319
    if (ticLen > SESSION_TICKET_LEN) {
14320
        ticBuff = (byte*)XMALLOC(ticLen, NULL,
14321
                DYNAMIC_TYPE_SESSION_TICK);
14322
        if (ticBuff == NULL) {
14323
            return MEMORY_E;
14324
        }
14325
    }
14326
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&          \
14327
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
14328
    if (addSession->ticketNonce.data != addSession->ticketNonce.dataStatic) {
14329
        /* use the AddSession->heap even if the buffer maybe saved in
14330
         * CachedSession objects. CachedSession heap and AddSession heap should
14331
         * be the same */
14332
        preallocNonce = (byte*)XMALLOC(addSession->ticketNonce.len,
14333
            addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
14334
        if (preallocNonce == NULL) {
14335
            if (ticBuff != NULL)
14336
                XFREE(ticBuff, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
14337
            return MEMORY_E;
14338
        }
14339
        preallocNonceLen = addSession->ticketNonce.len;
14340
    }
14341
#endif /* WOLFSSL_TLS13 && WOLFSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3) */
14342
#endif /* HAVE_SESSION_TICKET */
14343
14344
    /* Find a position for the new session in cache and use that */
14345
    /* Use the session object in the cache for external cache if required */
14346
0
    row = (int)(HashObject(id, ID_LEN, &ret) % SESSION_ROWS);
14347
0
    if (ret != 0) {
14348
0
        WOLFSSL_MSG("Hash session failed");
14349
    #ifdef HAVE_SESSION_TICKET
14350
        XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14351
    #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKE_NONCE_MALLOC)
14352
        if (preallocNonce != NULL)
14353
            XFREE(preallocNonce, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
14354
    #endif
14355
    #endif
14356
0
        return ret;
14357
0
    }
14358
14359
0
    sessRow = &SessionCache[row];
14360
0
    if (SESSION_ROW_LOCK(sessRow) != 0) {
14361
    #ifdef HAVE_SESSION_TICKET
14362
        XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14363
    #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKE_NONCE_MALLOC)
14364
        if (preallocNonce != NULL)
14365
            XFREE(preallocNonce, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
14366
    #endif
14367
    #endif
14368
0
        WOLFSSL_MSG("Session row lock failed");
14369
0
        return BAD_MUTEX_E;
14370
0
    }
14371
14372
0
    for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
14373
0
        if (XMEMCMP(id,
14374
0
                sessRow->Sessions[i].sessionID, ID_LEN) == 0 &&
14375
0
                sessRow->Sessions[i].side == side) {
14376
0
            WOLFSSL_MSG("Session already exists. Overwriting.");
14377
0
            overwrite = 1;
14378
0
            idx = i;
14379
0
            break;
14380
0
        }
14381
0
    }
14382
14383
0
    if (!overwrite)
14384
0
        idx = sessRow->nextIdx;
14385
#ifdef SESSION_INDEX
14386
    if (sessionIndex != NULL)
14387
        *sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
14388
#endif
14389
0
    cacheSession = &sessRow->Sessions[idx];
14390
14391
#ifdef HAVE_EX_DATA
14392
    if (cacheSession->rem_sess_cb && cacheSession->ownExData) {
14393
        cacheSession->rem_sess_cb(NULL, cacheSession);
14394
        /* Make sure not to call remove functions again */
14395
        cacheSession->ownExData = 0;
14396
        cacheSession->rem_sess_cb = NULL;
14397
    }
14398
#endif
14399
14400
0
    cacheSession->type = WOLFSSL_SESSION_TYPE_CACHE;
14401
0
    cacheSession->cacheRow = row;
14402
14403
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
14404
    /* Save the peer field to free after unlocking the row */
14405
    if (cacheSession->peer != NULL)
14406
        peer = cacheSession->peer;
14407
    cacheSession->peer = NULL;
14408
#endif
14409
#ifdef HAVE_SESSION_TICKET
14410
    /* If we can re-use the existing buffer in cacheSession then we won't touch
14411
     * ticBuff at all making it a very cheap malloc/free. The page on a modern
14412
     * OS will most likely not even be allocated to the process. */
14413
    if (ticBuff != NULL && cacheSession->ticketLenAlloc < ticLen) {
14414
        /* Save pointer only if separately allocated */
14415
        if (cacheSession->ticket != cacheSession->staticTicket)
14416
            cacheTicBuff = cacheSession->ticket;
14417
        ticBuffUsed = 1;
14418
        cacheSession->ticket = ticBuff;
14419
        cacheSession->ticketLenAlloc = (word16) ticLen;
14420
    }
14421
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&          \
14422
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
14423
    /* cache entry never used */
14424
    if (cacheSession->ticketNonce.data == NULL)
14425
        cacheSession->ticketNonce.data = cacheSession->ticketNonce.dataStatic;
14426
14427
    if (cacheSession->ticketNonce.data !=
14428
            cacheSession->ticketNonce.dataStatic) {
14429
        toFree = cacheSession->ticketNonce.data;
14430
        cacheSession->ticketNonce.data = cacheSession->ticketNonce.dataStatic;
14431
        cacheSession->ticketNonce.len = 0;
14432
    }
14433
#endif /* WOFLSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
14434
#endif
14435
#ifdef SESSION_CERTS
14436
    if (overwrite &&
14437
            addSession->chain.count == 0 &&
14438
            cacheSession->chain.count > 0) {
14439
        /* Copy in the certs from the session */
14440
        addSession->chain.count = cacheSession->chain.count;
14441
        XMEMCPY(addSession->chain.certs, cacheSession->chain.certs,
14442
                sizeof(x509_buffer) * cacheSession->chain.count);
14443
    }
14444
#endif /* SESSION_CERTS */
14445
0
    cacheSession->heap = NULL;
14446
    /* Copy data into the cache object */
14447
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) &&                  \
14448
    defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                                   \
14449
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
14450
    ret = wolfSSL_DupSessionEx(addSession, cacheSession, 1, preallocNonce,
14451
        &preallocNonceLen, &preallocNonceUsed) == WOLFSSL_FAILURE;
14452
#else
14453
0
    ret = wolfSSL_DupSession(addSession, cacheSession, 1) == WOLFSSL_FAILURE;
14454
0
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC
14455
          && FIPS_VERSION_GE(5,3)*/
14456
14457
0
    if (ret == 0) {
14458
        /* Increment the totalCount and the nextIdx */
14459
0
        if (sessRow->totalCount < SESSIONS_PER_ROW)
14460
0
            sessRow->totalCount++;
14461
0
        sessRow->nextIdx = (sessRow->nextIdx + 1) % SESSIONS_PER_ROW;
14462
0
        if (id != addSession->sessionID) {
14463
            /* ssl->session->sessionID may contain the bogus ID or we want the
14464
             * ID from the arrays object */
14465
0
            XMEMCPY(cacheSession->sessionID, id, ID_LEN);
14466
0
            cacheSession->sessionIDSz = ID_LEN;
14467
0
        }
14468
#ifdef HAVE_EX_DATA
14469
        if (ctx->rem_sess_cb != NULL) {
14470
            addSession->ownExData = 0;
14471
            cacheSession->ownExData = 1;
14472
            cacheSession->rem_sess_cb = ctx->rem_sess_cb;
14473
        }
14474
#endif
14475
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) &&                  \
14476
    defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                                    \
14477
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
14478
        if (preallocNonce != NULL && preallocNonceUsed) {
14479
            cacheSession->ticketNonce.data = preallocNonce;
14480
            cacheSession->ticketNonce.len = preallocNonceLen;
14481
            preallocNonce = NULL;
14482
            preallocNonceLen = 0;
14483
        }
14484
#endif /* HAVE_SESSION_TICKET && WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC
14485
        * && FIPS_VERSION_GE(5,3)*/
14486
0
    }
14487
#ifdef HAVE_SESSION_TICKET
14488
    else if (ticBuffUsed) {
14489
        /* Error occured. Need to clean up the ticket buffer. */
14490
        cacheSession->ticket = cacheSession->staticTicket;
14491
        cacheSession->ticketLenAlloc = 0;
14492
        cacheSession->ticketLen = 0;
14493
    }
14494
#endif
14495
14496
0
    SESSION_ROW_UNLOCK(sessRow);
14497
0
    cacheSession = NULL; /* Can't access after unlocked */
14498
14499
0
#ifndef NO_CLIENT_CACHE
14500
0
    if (ret == 0 && clientCacheEntry != NULL) {
14501
0
        ClientSession* clientCache = AddSessionToClientCache(side, row, idx,
14502
0
                addSession->serverID, addSession->idLen, id, useTicket);
14503
0
        if (clientCache != NULL)
14504
0
            *clientCacheEntry = clientCache;
14505
0
    }
14506
0
#endif
14507
14508
#ifdef HAVE_SESSION_TICKET
14509
    if (ticBuff != NULL && !ticBuffUsed)
14510
        XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14511
    if (cacheTicBuff != NULL)
14512
        XFREE(cacheTicBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14513
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&         \
14514
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
14515
    if (preallocNonce != NULL)
14516
        XFREE(preallocNonce, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
14517
    if (toFree != NULL)
14518
        XFREE(toFree, addSession->heap, DYNAMIC_TYPE_SESSION_TICK);
14519
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
14520
#endif
14521
14522
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
14523
    if (peer != NULL) {
14524
        wolfSSL_X509_free(peer);
14525
        peer = NULL; /* Make sure not use after this point */
14526
    }
14527
#endif
14528
14529
0
    return ret;
14530
0
}
14531
14532
#ifndef NO_CLIENT_CACHE
14533
#endif
14534
14535
void AddSession(WOLFSSL* ssl)
14536
0
{
14537
0
    int    error = 0;
14538
0
    const byte* id = NULL;
14539
0
    byte idSz = 0;
14540
0
    WOLFSSL_SESSION* session = ssl->session;
14541
#ifdef HAVE_EXT_CACHE
14542
    int cbRet = 0;
14543
#endif
14544
14545
0
    (void)error;
14546
14547
0
    WOLFSSL_ENTER("AddSession");
14548
14549
0
    if (SslSessionCacheOff(ssl, session)) {
14550
0
        WOLFSSL_MSG("Cache off");
14551
0
        return;
14552
0
    }
14553
14554
0
    if (ssl->options.haveSessionId == 0) {
14555
0
        WOLFSSL_MSG("Don't have session id");
14556
0
        return;
14557
0
    }
14558
14559
#if defined(HAVE_SESSION_TICKET) && !defined(OPENSSL_EXTRA)
14560
    /* For the compat layer generate a session object to use */
14561
    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1) {
14562
        WOLFSSL_MSG("Using tickets instead of cache");
14563
        return;
14564
    }
14565
#endif
14566
14567
0
    if (session->haveAltSessionID) {
14568
0
        id = session->altSessionID;
14569
0
        idSz = ID_LEN;
14570
0
    }
14571
0
    else {
14572
0
        if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) {
14573
            /* Make sure the session ID is available when the user calls any
14574
             * get_session API */
14575
0
            XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
14576
0
            session->sessionIDSz = ssl->arrays->sessionIDSz;
14577
0
        }
14578
0
        id = session->sessionID;
14579
0
        idSz = session->sessionIDSz;
14580
0
    }
14581
14582
0
    session->timeout = ssl->timeout;
14583
0
    session->side = (byte)ssl->options.side;
14584
0
    if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
14585
0
        XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
14586
0
    session->haveEMS = ssl->options.haveEMS;
14587
#ifdef OPENSSL_EXTRA
14588
    /* If using compatibility layer then check for and copy over session context
14589
     * id. */
14590
    if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
14591
        XMEMCPY(ssl->session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
14592
        session->sessionCtxSz = ssl->sessionCtxSz;
14593
    }
14594
#endif
14595
0
    session->timeout = ssl->timeout;
14596
0
    session->bornOn  = LowResTimer();
14597
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
14598
                               defined(HAVE_SESSION_TICKET))
14599
    session->version = ssl->version;
14600
#endif
14601
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
14602
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
14603
0
    session->cipherSuite0 = ssl->options.cipherSuite0;
14604
0
    session->cipherSuite = ssl->options.cipherSuite;
14605
0
#endif
14606
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14607
    session->peerVerifyRet = (byte)ssl->peerVerifyRet;
14608
#endif
14609
    /* Do this last so that if it fails, the rest of the session is setup. Do
14610
     * this only for the client because if the server doesn't have an ID at
14611
     * this point, it won't on resumption. */
14612
0
    if (idSz == 0 && ssl->options.side == WOLFSSL_CLIENT_END) {
14613
0
        WC_RNG* rng = NULL;
14614
0
        if (ssl->rng != NULL)
14615
0
            rng = ssl->rng;
14616
#if defined(HAVE_GLOBAL_RNG) && defined(OPENSSL_EXTRA)
14617
        else if (initGlobalRNG == 1 || wolfSSL_RAND_Init() == WOLFSSL_SUCCESS) {
14618
            rng = &globalRNG;
14619
        }
14620
#endif
14621
0
        if (wc_RNG_GenerateBlock(rng, ssl->session->altSessionID,
14622
0
                ID_LEN) != 0)
14623
0
            return;
14624
0
        ssl->session->haveAltSessionID = 1;
14625
0
        id = ssl->session->altSessionID;
14626
0
        idSz = ID_LEN;
14627
0
    }
14628
    /* Setup done */
14629
14630
0
    if (ssl->options.side == WOLFSSL_SERVER_END /* No point in adding a
14631
                                                 * client session */
14632
#ifdef HAVE_EXT_CACHE
14633
            && !ssl->options.internalCacheOff
14634
#endif
14635
0
            )
14636
0
    {
14637
        /* Try to add the session to cache. Its ok if we don't succeed. */
14638
0
        (void)AddSessionToCache(ssl->ctx, session, id, idSz,
14639
#ifdef SESSION_INDEX
14640
                &ssl->sessionIndex,
14641
#else
14642
0
                NULL,
14643
0
#endif
14644
0
                ssl->options.side,
14645
#ifdef HAVE_SESSION_TICKET
14646
                ssl->options.useTicket,
14647
#else
14648
0
                0,
14649
0
#endif
14650
0
                NULL
14651
0
                );
14652
0
    }
14653
14654
#ifdef HAVE_EXT_CACHE
14655
    if (error == 0 && ssl->ctx->new_sess_cb != NULL) {
14656
        wolfSSL_SESSION_up_ref(session);
14657
        cbRet = ssl->ctx->new_sess_cb(ssl, session);
14658
        if (cbRet == 0)
14659
            wolfSSL_FreeSession(ssl->ctx, session);
14660
    }
14661
#endif
14662
14663
#if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
14664
    if (error == 0) {
14665
        word32 active = 0;
14666
14667
        error = get_locked_session_stats(&active, NULL, NULL);
14668
        if (error == WOLFSSL_SUCCESS) {
14669
            error = 0;  /* back to this function ok */
14670
14671
            if (PeakSessions < active) {
14672
                PeakSessions = active;
14673
            }
14674
        }
14675
    }
14676
#endif /* WOLFSSL_SESSION_STATS && WOLFSSL_PEAK_SESSIONS */
14677
0
    (void)error;
14678
0
}
14679
14680
14681
#ifdef SESSION_INDEX
14682
14683
int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
14684
{
14685
    WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
14686
    WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
14687
    return ssl->sessionIndex;
14688
}
14689
14690
14691
int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
14692
{
14693
    int row, col, result = WOLFSSL_FAILURE;
14694
    SessionRow* sessRow;
14695
14696
    WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
14697
14698
    session = ClientSessionToSession(session);
14699
14700
    row = idx >> SESSIDX_ROW_SHIFT;
14701
    col = idx & SESSIDX_IDX_MASK;
14702
14703
    if (session == NULL ||
14704
            row < 0 || row >= SESSION_ROWS || col >= SESSIONS_PER_ROW) {
14705
        return WOLFSSL_FAILURE;
14706
    }
14707
14708
    sessRow = &SessionCache[row];
14709
    if (SESSION_ROW_LOCK(sessRow) != 0) {
14710
        return BAD_MUTEX_E;
14711
    }
14712
14713
    XMEMCPY(session, &sessRow->Sessions[col], sizeof(WOLFSSL_SESSION));
14714
    result = WOLFSSL_SUCCESS;
14715
14716
    SESSION_ROW_UNLOCK(sessRow);
14717
14718
    WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
14719
    return result;
14720
}
14721
14722
#endif /* SESSION_INDEX */
14723
14724
#if defined(SESSION_CERTS)
14725
14726
WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
14727
{
14728
    WOLFSSL_X509_CHAIN* chain = NULL;
14729
14730
    WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
14731
14732
    session = ClientSessionToSession(session);
14733
14734
    if (session)
14735
        chain = &session->chain;
14736
14737
    WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
14738
    return chain;
14739
}
14740
14741
14742
#ifdef OPENSSL_EXTRA
14743
/* gets the peer certificate associated with the session passed in
14744
 * returns null on failure, the caller should not free the returned pointer */
14745
WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session)
14746
{
14747
    WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
14748
14749
    session = ClientSessionToSession(session);
14750
    if (session) {
14751
        int count;
14752
14753
        count = wolfSSL_get_chain_count(&session->chain);
14754
        if (count < 1 || count >= MAX_CHAIN_DEPTH) {
14755
            WOLFSSL_MSG("bad count found");
14756
            return NULL;
14757
        }
14758
14759
        if (session->peer == NULL) {
14760
            session->peer = wolfSSL_get_chain_X509(&session->chain, 0);
14761
        }
14762
        return session->peer;
14763
    }
14764
    WOLFSSL_MSG("No session passed in");
14765
14766
    return NULL;
14767
}
14768
#endif /* OPENSSL_EXTRA */
14769
#endif /* SESSION_INDEX && SESSION_CERTS */
14770
14771
14772
#ifdef WOLFSSL_SESSION_STATS
14773
14774
static int get_locked_session_stats(word32* active, word32* total, word32* peak)
14775
{
14776
    int result = WOLFSSL_SUCCESS;
14777
    int i;
14778
    int count;
14779
    int idx;
14780
    word32 now   = 0;
14781
    word32 seen  = 0;
14782
    word32 ticks = LowResTimer();
14783
14784
    WOLFSSL_ENTER("get_locked_session_stats");
14785
14786
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
14787
    wc_LockMutex(&session_mutex);
14788
#endif
14789
    for (i = 0; i < SESSION_ROWS; i++) {
14790
        SessionRow* row = &SessionCache[i];
14791
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
14792
        if (SESSION_ROW_LOCK(row) != 0) {
14793
            WOLFSSL_MSG("Session row cache mutex lock failed");
14794
            return BAD_MUTEX_E;
14795
        }
14796
    #endif
14797
14798
        seen += row->totalCount;
14799
14800
        if (active == NULL) {
14801
            SESSION_ROW_UNLOCK(row);
14802
            continue;
14803
        }
14804
14805
        count = min((word32)row->totalCount, SESSIONS_PER_ROW);
14806
        idx   = row->nextIdx - 1;
14807
        if (idx < 0 || idx >= SESSIONS_PER_ROW) {
14808
            idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
14809
        }
14810
14811
        for (; count > 0; --count) {
14812
            /* if not expired then good */
14813
            if (ticks < (row->Sessions[idx].bornOn +
14814
                            row->Sessions[idx].timeout) ) {
14815
                now++;
14816
            }
14817
14818
            idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
14819
        }
14820
14821
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
14822
        SESSION_ROW_UNLOCK(row);
14823
    #endif
14824
    }
14825
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
14826
    wc_UnLockMutex(&session_mutex);
14827
#endif
14828
14829
    if (active) {
14830
        *active = now;
14831
    }
14832
    if (total) {
14833
        *total = seen;
14834
    }
14835
14836
#ifdef WOLFSSL_PEAK_SESSIONS
14837
    if (peak) {
14838
        *peak = PeakSessions;
14839
    }
14840
#else
14841
    (void)peak;
14842
#endif
14843
14844
    WOLFSSL_LEAVE("get_locked_session_stats", result);
14845
14846
    return result;
14847
}
14848
14849
14850
/* return WOLFSSL_SUCCESS on ok */
14851
int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
14852
                              word32* maxSessions)
14853
{
14854
    int result = WOLFSSL_SUCCESS;
14855
14856
    WOLFSSL_ENTER("wolfSSL_get_session_stats");
14857
14858
    if (maxSessions) {
14859
        *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
14860
14861
        if (active == NULL && total == NULL && peak == NULL)
14862
            return result;  /* we're done */
14863
    }
14864
14865
    /* user must provide at least one query value */
14866
    if (active == NULL && total == NULL && peak == NULL) {
14867
        return BAD_FUNC_ARG;
14868
    }
14869
14870
    result = get_locked_session_stats(active, total, peak);
14871
14872
    WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
14873
14874
    return result;
14875
}
14876
14877
#endif /* WOLFSSL_SESSION_STATS */
14878
14879
14880
    #ifdef PRINT_SESSION_STATS
14881
14882
    /* WOLFSSL_SUCCESS on ok */
14883
    int wolfSSL_PrintSessionStats(void)
14884
    {
14885
        word32 totalSessionsSeen = 0;
14886
        word32 totalSessionsNow = 0;
14887
        word32 peak = 0;
14888
        word32 maxSessions = 0;
14889
        int    i;
14890
        int    ret;
14891
        double E;               /* expected freq */
14892
        double chiSquare = 0;
14893
14894
        ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
14895
                                        &peak, &maxSessions);
14896
        if (ret != WOLFSSL_SUCCESS)
14897
            return ret;
14898
        printf("Total Sessions Seen = %u\n", totalSessionsSeen);
14899
        printf("Total Sessions Now  = %u\n", totalSessionsNow);
14900
#ifdef WOLFSSL_PEAK_SESSIONS
14901
        printf("Peak  Sessions      = %u\n", peak);
14902
#endif
14903
        printf("Max   Sessions      = %u\n", maxSessions);
14904
14905
        E = (double)totalSessionsSeen / SESSION_ROWS;
14906
14907
        for (i = 0; i < SESSION_ROWS; i++) {
14908
            double diff = SessionCache[i].totalCount - E;
14909
            diff *= diff;                /* square    */
14910
            diff /= E;                   /* normalize */
14911
14912
            chiSquare += diff;
14913
        }
14914
        printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
14915
                                                     SESSION_ROWS - 1);
14916
        #if (SESSION_ROWS == 11)
14917
            printf(" .05 p value =  18.3, chi-square should be less\n");
14918
        #elif (SESSION_ROWS == 211)
14919
            printf(".05 p value  = 244.8, chi-square should be less\n");
14920
        #elif (SESSION_ROWS == 5981)
14921
            printf(".05 p value  = 6161.0, chi-square should be less\n");
14922
        #elif (SESSION_ROWS == 3)
14923
            printf(".05 p value  =   6.0, chi-square should be less\n");
14924
        #elif (SESSION_ROWS == 2861)
14925
            printf(".05 p value  = 2985.5, chi-square should be less\n");
14926
        #endif
14927
        printf("\n");
14928
14929
        return ret;
14930
    }
14931
14932
    #endif /* SESSION_STATS */
14933
14934
#else  /* NO_SESSION_CACHE */
14935
14936
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
14937
{
14938
    return (WOLFSSL_SESSION*)session;
14939
}
14940
14941
/* No session cache version */
14942
WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret,
14943
        byte restoreSessionCerts)
14944
{
14945
    (void)ssl;
14946
    (void)masterSecret;
14947
    (void)restoreSessionCerts;
14948
14949
    return NULL;
14950
}
14951
14952
#endif /* NO_SESSION_CACHE */
14953
14954
14955
/* call before SSL_connect, if verifying will add name check to
14956
   date check and signature check */
14957
WOLFSSL_ABI
14958
int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
14959
0
{
14960
0
    WOLFSSL_ENTER("wolfSSL_check_domain_name");
14961
14962
0
    if (ssl == NULL || dn == NULL) {
14963
0
        WOLFSSL_MSG("Bad function argument: NULL");
14964
0
        return WOLFSSL_FAILURE;
14965
0
    }
14966
14967
0
    if (ssl->buffers.domainName.buffer)
14968
0
        XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
14969
14970
0
    ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
14971
0
    ssl->buffers.domainName.buffer = (byte*)XMALLOC(
14972
0
            ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
14973
14974
0
    if (ssl->buffers.domainName.buffer) {
14975
0
        unsigned char* domainName = ssl->buffers.domainName.buffer;
14976
0
        XMEMCPY(domainName, dn, ssl->buffers.domainName.length);
14977
0
        domainName[ssl->buffers.domainName.length] = '\0';
14978
0
        return WOLFSSL_SUCCESS;
14979
0
    }
14980
0
    else {
14981
0
        ssl->error = MEMORY_ERROR;
14982
0
        return WOLFSSL_FAILURE;
14983
0
    }
14984
0
}
14985
14986
14987
/* turn on wolfSSL zlib compression
14988
   returns WOLFSSL_SUCCESS for success, else error (not built in)
14989
*/
14990
int wolfSSL_set_compression(WOLFSSL* ssl)
14991
0
{
14992
0
    WOLFSSL_ENTER("wolfSSL_set_compression");
14993
0
    (void)ssl;
14994
#ifdef HAVE_LIBZ
14995
    ssl->options.usingCompression = 1;
14996
    return WOLFSSL_SUCCESS;
14997
#else
14998
0
    return NOT_COMPILED_IN;
14999
0
#endif
15000
0
}
15001
15002
15003
#ifndef USE_WINDOWS_API
15004
    #ifndef NO_WRITEV
15005
15006
        /* simulate writev semantics, doesn't actually do block at a time though
15007
           because of SSL_write behavior and because front adds may be small */
15008
        int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
15009
0
        {
15010
0
        #ifdef WOLFSSL_SMALL_STACK
15011
0
            byte   staticBuffer[1]; /* force heap usage */
15012
        #else
15013
            byte   staticBuffer[FILE_BUFFER_SIZE];
15014
        #endif
15015
0
            byte* myBuffer  = staticBuffer;
15016
0
            int   dynamic   = 0;
15017
0
            int   sending   = 0;
15018
0
            int   idx       = 0;
15019
0
            int   i;
15020
0
            int   ret;
15021
15022
0
            WOLFSSL_ENTER("wolfSSL_writev");
15023
15024
0
            for (i = 0; i < iovcnt; i++)
15025
0
                sending += (int)iov[i].iov_len;
15026
15027
0
            if (sending > (int)sizeof(staticBuffer)) {
15028
0
                myBuffer = (byte*)XMALLOC(sending, ssl->heap,
15029
0
                                                           DYNAMIC_TYPE_WRITEV);
15030
0
                if (!myBuffer)
15031
0
                    return MEMORY_ERROR;
15032
15033
0
                dynamic = 1;
15034
0
            }
15035
15036
0
            for (i = 0; i < iovcnt; i++) {
15037
0
                XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
15038
0
                idx += (int)iov[i].iov_len;
15039
0
            }
15040
15041
           /* myBuffer may not be initialized fully, but the span up to the
15042
            * sending length will be.
15043
            */
15044
0
            PRAGMA_GCC_DIAG_PUSH;
15045
0
            PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"");
15046
0
            ret = wolfSSL_write(ssl, myBuffer, sending);
15047
0
            PRAGMA_GCC_DIAG_POP;
15048
15049
0
            if (dynamic)
15050
0
                XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
15051
15052
0
            return ret;
15053
0
        }
15054
    #endif
15055
#endif
15056
15057
15058
#ifdef WOLFSSL_CALLBACKS
15059
15060
    typedef struct itimerval Itimerval;
15061
15062
    /* don't keep calling simple functions while setting up timer and signals
15063
       if no inlining these are the next best */
15064
15065
    #define AddTimes(a, b, c)                       \
15066
        do {                                        \
15067
            c.tv_sec  = a.tv_sec  + b.tv_sec;       \
15068
            c.tv_usec = a.tv_usec + b.tv_usec;      \
15069
            if (c.tv_usec >=  1000000) {            \
15070
                c.tv_sec++;                         \
15071
                c.tv_usec -= 1000000;               \
15072
            }                                       \
15073
        } while (0)
15074
15075
15076
    #define SubtractTimes(a, b, c)                  \
15077
        do {                                        \
15078
            c.tv_sec  = a.tv_sec  - b.tv_sec;       \
15079
            c.tv_usec = a.tv_usec - b.tv_usec;      \
15080
            if (c.tv_usec < 0) {                    \
15081
                c.tv_sec--;                         \
15082
                c.tv_usec += 1000000;               \
15083
            }                                       \
15084
        } while (0)
15085
15086
    #define CmpTimes(a, b, cmp)                     \
15087
        ((a.tv_sec  ==  b.tv_sec) ?                 \
15088
            (a.tv_usec cmp b.tv_usec) :             \
15089
            (a.tv_sec  cmp b.tv_sec))               \
15090
15091
15092
    /* do nothing handler */
15093
    static void myHandler(int signo)
15094
    {
15095
        (void)signo;
15096
        return;
15097
    }
15098
15099
15100
    static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
15101
                                 TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
15102
    {
15103
        int       ret        = WOLFSSL_FATAL_ERROR;
15104
        int       oldTimerOn = 0;   /* was timer already on */
15105
        WOLFSSL_TIMEVAL startTime;
15106
        WOLFSSL_TIMEVAL endTime;
15107
        WOLFSSL_TIMEVAL totalTime;
15108
        Itimerval myTimeout;
15109
        Itimerval oldTimeout; /* if old timer adjust from total time to reset */
15110
        struct sigaction act, oact;
15111
15112
        #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
15113
15114
        if (hsCb) {
15115
            ssl->hsInfoOn = 1;
15116
            InitHandShakeInfo(&ssl->handShakeInfo, ssl);
15117
        }
15118
        if (toCb) {
15119
            ssl->toInfoOn = 1;
15120
            InitTimeoutInfo(&ssl->timeoutInfo);
15121
15122
            if (gettimeofday(&startTime, 0) < 0)
15123
                ERR_OUT(GETTIME_ERROR);
15124
15125
            /* use setitimer to simulate getitimer, init 0 myTimeout */
15126
            myTimeout.it_interval.tv_sec  = 0;
15127
            myTimeout.it_interval.tv_usec = 0;
15128
            myTimeout.it_value.tv_sec     = 0;
15129
            myTimeout.it_value.tv_usec    = 0;
15130
            if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
15131
                ERR_OUT(SETITIMER_ERROR);
15132
15133
            if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
15134
                oldTimerOn = 1;
15135
15136
                /* is old timer going to expire before ours */
15137
                if (CmpTimes(oldTimeout.it_value, timeout, <)) {
15138
                    timeout.tv_sec  = oldTimeout.it_value.tv_sec;
15139
                    timeout.tv_usec = oldTimeout.it_value.tv_usec;
15140
                }
15141
            }
15142
            myTimeout.it_value.tv_sec  = timeout.tv_sec;
15143
            myTimeout.it_value.tv_usec = timeout.tv_usec;
15144
15145
            /* set up signal handler, don't restart socket send/recv */
15146
            act.sa_handler = myHandler;
15147
            sigemptyset(&act.sa_mask);
15148
            act.sa_flags = 0;
15149
#ifdef SA_INTERRUPT
15150
            act.sa_flags |= SA_INTERRUPT;
15151
#endif
15152
            if (sigaction(SIGALRM, &act, &oact) < 0)
15153
                ERR_OUT(SIGACT_ERROR);
15154
15155
            if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
15156
                ERR_OUT(SETITIMER_ERROR);
15157
        }
15158
15159
        /* do main work */
15160
#ifndef NO_WOLFSSL_CLIENT
15161
        if (ssl->options.side == WOLFSSL_CLIENT_END)
15162
            ret = wolfSSL_connect(ssl);
15163
#endif
15164
#ifndef NO_WOLFSSL_SERVER
15165
        if (ssl->options.side == WOLFSSL_SERVER_END)
15166
            ret = wolfSSL_accept(ssl);
15167
#endif
15168
15169
        /* do callbacks */
15170
        if (toCb) {
15171
            if (oldTimerOn) {
15172
                gettimeofday(&endTime, 0);
15173
                SubtractTimes(endTime, startTime, totalTime);
15174
                /* adjust old timer for elapsed time */
15175
                if (CmpTimes(totalTime, oldTimeout.it_value, <))
15176
                    SubtractTimes(oldTimeout.it_value, totalTime,
15177
                                  oldTimeout.it_value);
15178
                else {
15179
                    /* reset value to interval, may be off */
15180
                    oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
15181
                    oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
15182
                }
15183
                /* keep iter the same whether there or not */
15184
            }
15185
            /* restore old handler */
15186
            if (sigaction(SIGALRM, &oact, 0) < 0)
15187
                ret = SIGACT_ERROR;    /* more pressing error, stomp */
15188
            else
15189
                /* use old settings which may turn off (expired or not there) */
15190
                if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
15191
                    ret = SETITIMER_ERROR;
15192
15193
            /* if we had a timeout call callback */
15194
            if (ssl->timeoutInfo.timeoutName[0]) {
15195
                ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
15196
                ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
15197
                (toCb)(&ssl->timeoutInfo);
15198
            }
15199
            ssl->toInfoOn = 0;
15200
        }
15201
15202
        /* clean up buffers allocated by AddPacketInfo */
15203
        FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
15204
15205
        if (hsCb) {
15206
            FinishHandShakeInfo(&ssl->handShakeInfo);
15207
            (hsCb)(&ssl->handShakeInfo);
15208
            ssl->hsInfoOn = 0;
15209
        }
15210
        return ret;
15211
    }
15212
15213
15214
#ifndef NO_WOLFSSL_CLIENT
15215
15216
    int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
15217
                          TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
15218
    {
15219
        WOLFSSL_ENTER("wolfSSL_connect_ex");
15220
        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
15221
    }
15222
15223
#endif
15224
15225
15226
#ifndef NO_WOLFSSL_SERVER
15227
15228
    int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
15229
                         TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
15230
    {
15231
        WOLFSSL_ENTER("wolfSSL_accept_ex");
15232
        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
15233
    }
15234
15235
#endif
15236
15237
#endif /* WOLFSSL_CALLBACKS */
15238
15239
15240
#ifndef NO_PSK
15241
15242
    void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
15243
                                         wc_psk_client_callback cb)
15244
    {
15245
        WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
15246
15247
        if (ctx == NULL)
15248
            return;
15249
15250
        ctx->havePSK = 1;
15251
        ctx->client_psk_cb = cb;
15252
    }
15253
15254
    void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
15255
    {
15256
        byte haveRSA = 1;
15257
        int  keySz   = 0;
15258
15259
        WOLFSSL_ENTER("SSL_set_psk_client_callback");
15260
15261
        if (ssl == NULL)
15262
            return;
15263
15264
        ssl->options.havePSK = 1;
15265
        ssl->options.client_psk_cb = cb;
15266
15267
        #ifdef NO_RSA
15268
            haveRSA = 0;
15269
        #endif
15270
        #ifndef NO_CERTS
15271
            keySz = ssl->buffers.keySz;
15272
        #endif
15273
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
15274
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
15275
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
15276
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
15277
                   ssl->options.haveAnon, TRUE, ssl->options.side);
15278
    }
15279
    #ifdef OPENSSL_EXTRA
15280
    /**
15281
     * set call back function for psk session use
15282
     * @param ssl  a pointer to WOLFSSL structure
15283
     * @param cb   a function pointer to wc_psk_use_session_cb
15284
     * @return none
15285
     */
15286
    void wolfSSL_set_psk_use_session_callback(WOLFSSL* ssl,
15287
                                                wc_psk_use_session_cb_func cb)
15288
    {
15289
        WOLFSSL_ENTER("wolfSSL_set_psk_use_session_callback");
15290
15291
        ssl->options.havePSK = 1;
15292
        ssl->options.session_psk_cb = cb;
15293
15294
        WOLFSSL_LEAVE("wolfSSL_set_psk_use_session_callback", WOLFSSL_SUCCESS);
15295
    }
15296
    #endif
15297
15298
    void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
15299
                                         wc_psk_server_callback cb)
15300
    {
15301
        WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
15302
        if (ctx == NULL)
15303
            return;
15304
        ctx->havePSK = 1;
15305
        ctx->server_psk_cb = cb;
15306
    }
15307
15308
    void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
15309
    {
15310
        byte haveRSA = 1;
15311
        int  keySz   = 0;
15312
15313
        WOLFSSL_ENTER("SSL_set_psk_server_callback");
15314
        if (ssl == NULL)
15315
            return;
15316
15317
        ssl->options.havePSK = 1;
15318
        ssl->options.server_psk_cb = cb;
15319
15320
        #ifdef NO_RSA
15321
            haveRSA = 0;
15322
        #endif
15323
        #ifndef NO_CERTS
15324
            keySz = ssl->buffers.keySz;
15325
        #endif
15326
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
15327
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
15328
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
15329
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
15330
                   ssl->options.haveAnon, TRUE, ssl->options.side);
15331
    }
15332
15333
    const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
15334
    {
15335
        WOLFSSL_ENTER("SSL_get_psk_identity_hint");
15336
15337
        if (ssl == NULL || ssl->arrays == NULL)
15338
            return NULL;
15339
15340
        return ssl->arrays->server_hint;
15341
    }
15342
15343
15344
    const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
15345
    {
15346
        WOLFSSL_ENTER("SSL_get_psk_identity");
15347
15348
        if (ssl == NULL || ssl->arrays == NULL)
15349
            return NULL;
15350
15351
        return ssl->arrays->client_identity;
15352
    }
15353
15354
    int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
15355
    {
15356
        WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
15357
        if (hint == 0)
15358
            ctx->server_hint[0] = '\0';
15359
        else {
15360
            /* Qt does not call CTX_set_*_psk_callbacks where havePSK is set */
15361
            #ifdef WOLFSSL_QT
15362
            ctx->havePSK=1;
15363
            #endif
15364
            XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
15365
            ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
15366
        }
15367
        return WOLFSSL_SUCCESS;
15368
    }
15369
15370
    int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
15371
    {
15372
        WOLFSSL_ENTER("SSL_use_psk_identity_hint");
15373
15374
        if (ssl == NULL || ssl->arrays == NULL)
15375
            return WOLFSSL_FAILURE;
15376
15377
        if (hint == 0)
15378
            ssl->arrays->server_hint[0] = 0;
15379
        else {
15380
            XSTRNCPY(ssl->arrays->server_hint, hint,
15381
                                            sizeof(ssl->arrays->server_hint)-1);
15382
            ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
15383
        }
15384
        return WOLFSSL_SUCCESS;
15385
    }
15386
15387
    void* wolfSSL_get_psk_callback_ctx(WOLFSSL* ssl)
15388
    {
15389
        return ssl ? ssl->options.psk_ctx : NULL;
15390
    }
15391
    void* wolfSSL_CTX_get_psk_callback_ctx(WOLFSSL_CTX* ctx)
15392
    {
15393
        return ctx ? ctx->psk_ctx : NULL;
15394
    }
15395
    int wolfSSL_set_psk_callback_ctx(WOLFSSL* ssl, void* psk_ctx)
15396
    {
15397
        if (ssl == NULL)
15398
            return WOLFSSL_FAILURE;
15399
        ssl->options.psk_ctx = psk_ctx;
15400
        return WOLFSSL_SUCCESS;
15401
    }
15402
    int wolfSSL_CTX_set_psk_callback_ctx(WOLFSSL_CTX* ctx, void* psk_ctx)
15403
    {
15404
        if (ctx == NULL)
15405
            return WOLFSSL_FAILURE;
15406
        ctx->psk_ctx = psk_ctx;
15407
        return WOLFSSL_SUCCESS;
15408
    }
15409
#endif /* NO_PSK */
15410
15411
15412
#ifdef HAVE_ANON
15413
15414
    int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
15415
    {
15416
        WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
15417
15418
        if (ctx == NULL)
15419
            return WOLFSSL_FAILURE;
15420
15421
        ctx->haveAnon = 1;
15422
15423
        return WOLFSSL_SUCCESS;
15424
    }
15425
15426
#endif /* HAVE_ANON */
15427
15428
15429
#ifndef NO_CERTS
15430
/* used to be defined on NO_FILESYSTEM only, but are generally useful */
15431
15432
    int wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX* ctx,
15433
                                         const unsigned char* in,
15434
                                         long sz, int format, int userChain,
15435
                                         word32 flags)
15436
0
    {
15437
0
        int verify;
15438
0
        int ret = WOLFSSL_FAILURE;
15439
15440
0
        WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer_ex");
15441
15442
0
        verify = GET_VERIFY_SETTING_CTX(ctx);
15443
0
        if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
15444
0
            verify = VERIFY_SKIP_DATE;
15445
15446
0
        if (format == WOLFSSL_FILETYPE_PEM)
15447
0
            ret = ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL,
15448
0
                                      verify);
15449
0
        else
15450
0
            ret = ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL, NULL,
15451
0
                                 userChain, verify);
15452
#if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
15453
        if (ret == WOLFSSL_SUCCESS)
15454
            ret = wolfSSL_CTX_trust_peer_buffer(ctx, in, sz, format);
15455
#endif
15456
15457
0
        WOLFSSL_LEAVE("wolfSSL_CTX_load_verify_buffer_ex", ret);
15458
0
        return ret;
15459
0
    }
15460
15461
    /* wolfSSL extension allows DER files to be loaded from buffers as well */
15462
    int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
15463
                                       const unsigned char* in,
15464
                                       long sz, int format)
15465
0
    {
15466
0
        return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 0,
15467
0
            WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
15468
0
    }
15469
15470
    int wolfSSL_CTX_load_verify_chain_buffer_format(WOLFSSL_CTX* ctx,
15471
                                       const unsigned char* in,
15472
                                       long sz, int format)
15473
0
    {
15474
0
        return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 1,
15475
0
            WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
15476
0
    }
15477
15478
15479
#ifdef WOLFSSL_TRUST_PEER_CERT
15480
    int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx,
15481
                                       const unsigned char* in,
15482
                                       long sz, int format)
15483
    {
15484
        WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
15485
15486
        /* sanity check on arguments */
15487
        if (sz < 0 || in == NULL || ctx == NULL) {
15488
            return BAD_FUNC_ARG;
15489
        }
15490
15491
        if (format == WOLFSSL_FILETYPE_PEM)
15492
            return ProcessChainBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE,
15493
                                      NULL, GET_VERIFY_SETTING_CTX(ctx));
15494
        else
15495
            return ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE, NULL,
15496
                                 NULL, 0, GET_VERIFY_SETTING_CTX(ctx));
15497
    }
15498
#endif /* WOLFSSL_TRUST_PEER_CERT */
15499
15500
15501
    int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
15502
                                 const unsigned char* in, long sz, int format)
15503
0
    {
15504
0
        int ret = WOLFSSL_FAILURE;
15505
15506
0
        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
15507
0
        ret = ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0,
15508
0
                             GET_VERIFY_SETTING_CTX(ctx));
15509
0
        WOLFSSL_LEAVE("wolfSSL_CTX_use_certificate_buffer", ret);
15510
0
        return ret;
15511
0
    }
15512
15513
15514
    int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
15515
                                 const unsigned char* in, long sz, int format)
15516
0
    {
15517
0
        int ret = WOLFSSL_FAILURE;
15518
15519
0
        WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
15520
0
        ret = ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL, NULL,
15521
0
                             0, GET_VERIFY_SETTING_CTX(ctx));
15522
0
        WOLFSSL_LEAVE("wolfSSL_CTX_use_PrivateKey_buffer", ret);
15523
0
        return ret;
15524
0
    }
15525
15526
#ifdef WOLF_PRIVATE_KEY_ID
15527
    int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
15528
                                      long sz, int devId, long keySz)
15529
0
    {
15530
0
        int ret = wolfSSL_CTX_use_PrivateKey_Id(ctx, id, sz, devId);
15531
15532
0
        if (ret == WOLFSSL_SUCCESS)
15533
0
            ctx->privateKeySz = (word32)keySz;
15534
15535
0
        return ret;
15536
0
    }
15537
15538
    int wolfSSL_CTX_use_PrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
15539
                                      long sz, int devId)
15540
0
    {
15541
0
        int ret = WOLFSSL_FAILURE;
15542
15543
0
        FreeDer(&ctx->privateKey);
15544
0
        if (AllocDer(&ctx->privateKey, (word32)sz, PRIVATEKEY_TYPE,
15545
0
                                                              ctx->heap) == 0) {
15546
0
            XMEMCPY(ctx->privateKey->buffer, id, sz);
15547
0
            ctx->privateKeyId = 1;
15548
0
            if (devId != INVALID_DEVID)
15549
0
                ctx->privateKeyDevId = devId;
15550
0
            else
15551
0
                ctx->privateKeyDevId = ctx->devId;
15552
15553
0
            ret = WOLFSSL_SUCCESS;
15554
0
        }
15555
15556
0
        return ret;
15557
0
    }
15558
15559
    int wolfSSL_CTX_use_PrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
15560
                                         int devId)
15561
0
    {
15562
0
        int ret = WOLFSSL_FAILURE;
15563
0
        word32 sz = (word32)XSTRLEN(label) + 1;
15564
15565
0
        FreeDer(&ctx->privateKey);
15566
0
        if (AllocDer(&ctx->privateKey, (word32)sz, PRIVATEKEY_TYPE,
15567
0
                                                              ctx->heap) == 0) {
15568
0
            XMEMCPY(ctx->privateKey->buffer, label, sz);
15569
0
            ctx->privateKeyLabel = 1;
15570
0
            if (devId != INVALID_DEVID)
15571
0
                ctx->privateKeyDevId = devId;
15572
0
            else
15573
0
                ctx->privateKeyDevId = ctx->devId;
15574
15575
0
            ret = WOLFSSL_SUCCESS;
15576
0
        }
15577
15578
0
        return ret;
15579
0
    }
15580
#endif /* WOLF_PRIVATE_KEY_ID */
15581
15582
    int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
15583
                                 const unsigned char* in, long sz, int format)
15584
0
    {
15585
0
        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
15586
0
        return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1,
15587
0
                             GET_VERIFY_SETTING_CTX(ctx));
15588
0
    }
15589
15590
    int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
15591
                                 const unsigned char* in, long sz)
15592
0
    {
15593
0
        return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
15594
0
                                                            WOLFSSL_FILETYPE_PEM);
15595
0
    }
15596
15597
15598
#ifndef NO_DH
15599
15600
    /* server wrapper for ctx or ssl Diffie-Hellman parameters */
15601
    static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
15602
                                               const unsigned char* buf,
15603
                                               long sz, int format)
15604
0
    {
15605
0
        DerBuffer* der = NULL;
15606
0
        int    ret      = 0;
15607
0
        word32 pSz = MAX_DH_SIZE;
15608
0
        word32 gSz = MAX_DH_SIZE;
15609
0
    #ifdef WOLFSSL_SMALL_STACK
15610
0
        byte*  p = NULL;
15611
0
        byte*  g = NULL;
15612
    #else
15613
        byte   p[MAX_DH_SIZE];
15614
        byte   g[MAX_DH_SIZE];
15615
    #endif
15616
15617
0
        if (ctx == NULL || buf == NULL)
15618
0
            return BAD_FUNC_ARG;
15619
15620
0
        ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap);
15621
0
        if (ret != 0) {
15622
0
            return ret;
15623
0
        }
15624
0
        der->buffer = (byte*)buf;
15625
0
        der->length = (word32)sz;
15626
15627
0
    #ifdef WOLFSSL_SMALL_STACK
15628
0
        p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15629
0
        g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15630
15631
0
        if (p == NULL || g == NULL) {
15632
0
            XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15633
0
            XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15634
0
            return MEMORY_E;
15635
0
        }
15636
0
    #endif
15637
15638
0
        if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
15639
0
            ret = WOLFSSL_BAD_FILETYPE;
15640
0
        else {
15641
0
            if (format == WOLFSSL_FILETYPE_PEM) {
15642
0
#ifdef WOLFSSL_PEM_TO_DER
15643
0
                FreeDer(&der);
15644
0
                ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap,
15645
0
                               NULL, NULL);
15646
0
                if (ret < 0) {
15647
                    /* Also try X9.42 format */
15648
0
                    ret = PemToDer(buf, sz, X942_PARAM_TYPE, &der, ctx->heap,
15649
0
                               NULL, NULL);
15650
0
                }
15651
    #ifdef WOLFSSL_WPAS
15652
        #ifndef NO_DSA
15653
                if (ret < 0) {
15654
                    ret = PemToDer(buf, sz, DSA_PARAM_TYPE, &der, ctx->heap,
15655
                               NULL, NULL);
15656
                }
15657
        #endif
15658
    #endif /* WOLFSSL_WPAS */
15659
#else
15660
                ret = NOT_COMPILED_IN;
15661
#endif /* WOLFSSL_PEM_TO_DER */
15662
0
            }
15663
15664
0
            if (ret == 0) {
15665
0
                if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0)
15666
0
                    ret = WOLFSSL_BAD_FILETYPE;
15667
0
                else if (ssl)
15668
0
                    ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
15669
0
                else
15670
0
                    ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
15671
0
            }
15672
0
        }
15673
15674
0
        FreeDer(&der);
15675
15676
0
    #ifdef WOLFSSL_SMALL_STACK
15677
0
        XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15678
0
        XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15679
0
    #endif
15680
15681
0
        return ret;
15682
0
    }
15683
15684
15685
    /* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
15686
    int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
15687
                               int format)
15688
0
    {
15689
0
        if (ssl == NULL)
15690
0
            return BAD_FUNC_ARG;
15691
15692
0
        return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
15693
0
    }
15694
15695
15696
    /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
15697
    int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
15698
                                   long sz, int format)
15699
0
    {
15700
0
        return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
15701
0
    }
15702
15703
#endif /* NO_DH */
15704
15705
15706
    int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
15707
                                 const unsigned char* in, long sz, int format)
15708
0
    {
15709
0
        WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
15710
0
        if (ssl == NULL)
15711
0
            return BAD_FUNC_ARG;
15712
15713
0
        return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE, ssl, NULL, 0,
15714
0
                             GET_VERIFY_SETTING_SSL(ssl));
15715
0
    }
15716
15717
15718
    int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
15719
                                 const unsigned char* in, long sz, int format)
15720
0
    {
15721
0
        WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
15722
0
        if (ssl == NULL)
15723
0
            return BAD_FUNC_ARG;
15724
15725
0
        return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
15726
0
                             ssl, NULL, 0, GET_VERIFY_SETTING_SSL(ssl));
15727
0
    }
15728
15729
#ifdef WOLF_PRIVATE_KEY_ID
15730
    int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id,
15731
                                  long sz, int devId, long keySz)
15732
0
    {
15733
0
        int ret = wolfSSL_use_PrivateKey_Id(ssl, id, sz, devId);
15734
15735
0
        if (ret == WOLFSSL_SUCCESS)
15736
0
            ssl->buffers.keySz = (word32)keySz;
15737
15738
0
        return ret;
15739
0
    }
15740
15741
    int wolfSSL_use_PrivateKey_Id(WOLFSSL* ssl, const unsigned char* id,
15742
                                  long sz, int devId)
15743
0
    {
15744
0
        int ret = WOLFSSL_FAILURE;
15745
15746
0
        if (ssl->buffers.weOwnKey)
15747
0
            FreeDer(&ssl->buffers.key);
15748
0
        if (AllocDer(&ssl->buffers.key, (word32)sz, PRIVATEKEY_TYPE,
15749
0
                                                            ssl->heap) == 0) {
15750
0
            XMEMCPY(ssl->buffers.key->buffer, id, sz);
15751
0
            ssl->buffers.weOwnKey = 1;
15752
0
            ssl->buffers.keyId = 1;
15753
0
            if (devId != INVALID_DEVID)
15754
0
                ssl->buffers.keyDevId = devId;
15755
0
            else
15756
0
                ssl->buffers.keyDevId = ssl->devId;
15757
15758
0
            ret = WOLFSSL_SUCCESS;
15759
0
        }
15760
15761
0
        return ret;
15762
0
    }
15763
15764
    int wolfSSL_use_PrivateKey_Label(WOLFSSL* ssl, const char* label, int devId)
15765
0
    {
15766
0
        int ret = WOLFSSL_FAILURE;
15767
0
        word32 sz = (word32)XSTRLEN(label) + 1;
15768
15769
0
        if (ssl->buffers.weOwnKey)
15770
0
            FreeDer(&ssl->buffers.key);
15771
0
        if (AllocDer(&ssl->buffers.key, (word32)sz, PRIVATEKEY_TYPE,
15772
0
                                                            ssl->heap) == 0) {
15773
0
            XMEMCPY(ssl->buffers.key->buffer, label, sz);
15774
0
            ssl->buffers.weOwnKey = 1;
15775
0
            ssl->buffers.keyLabel = 1;
15776
0
            if (devId != INVALID_DEVID)
15777
0
                ssl->buffers.keyDevId = devId;
15778
0
            else
15779
0
                ssl->buffers.keyDevId = ssl->devId;
15780
15781
0
            ret = WOLFSSL_SUCCESS;
15782
0
        }
15783
15784
0
        return ret;
15785
0
    }
15786
#endif /* WOLF_PRIVATE_KEY_ID */
15787
15788
    int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
15789
                                 const unsigned char* in, long sz, int format)
15790
0
    {
15791
0
        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
15792
0
        if (ssl == NULL)
15793
0
            return BAD_FUNC_ARG;
15794
15795
0
        return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE,
15796
0
                             ssl, NULL, 1, GET_VERIFY_SETTING_SSL(ssl));
15797
0
    }
15798
15799
    int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
15800
                                 const unsigned char* in, long sz)
15801
0
    {
15802
0
        return wolfSSL_use_certificate_chain_buffer_format(ssl, in, sz,
15803
0
                                                            WOLFSSL_FILETYPE_PEM);
15804
0
    }
15805
15806
15807
    /* unload any certs or keys that SSL owns, leave CTX as is
15808
       WOLFSSL_SUCCESS on ok */
15809
    int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
15810
0
    {
15811
0
        if (ssl == NULL) {
15812
0
            WOLFSSL_MSG("Null function arg");
15813
0
            return BAD_FUNC_ARG;
15814
0
        }
15815
15816
0
        if (ssl->buffers.weOwnCert && !ssl->keepCert) {
15817
0
            WOLFSSL_MSG("Unloading cert");
15818
0
            FreeDer(&ssl->buffers.certificate);
15819
            #ifdef KEEP_OUR_CERT
15820
            wolfSSL_X509_free(ssl->ourCert);
15821
            ssl->ourCert = NULL;
15822
            #endif
15823
0
            ssl->buffers.weOwnCert = 0;
15824
0
        }
15825
15826
0
        if (ssl->buffers.weOwnCertChain) {
15827
0
            WOLFSSL_MSG("Unloading cert chain");
15828
0
            FreeDer(&ssl->buffers.certChain);
15829
0
            ssl->buffers.weOwnCertChain = 0;
15830
0
        }
15831
15832
0
        if (ssl->buffers.weOwnKey) {
15833
0
            WOLFSSL_MSG("Unloading key");
15834
0
            ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
15835
0
            FreeDer(&ssl->buffers.key);
15836
0
            ssl->buffers.weOwnKey = 0;
15837
0
        }
15838
15839
0
        return WOLFSSL_SUCCESS;
15840
0
    }
15841
15842
15843
    int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
15844
0
    {
15845
0
        WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
15846
15847
0
        if (ctx == NULL)
15848
0
            return BAD_FUNC_ARG;
15849
15850
0
        return wolfSSL_CertManagerUnloadCAs(ctx->cm);
15851
0
    }
15852
15853
15854
#ifdef WOLFSSL_TRUST_PEER_CERT
15855
    int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
15856
    {
15857
        WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
15858
15859
        if (ctx == NULL)
15860
            return BAD_FUNC_ARG;
15861
15862
        return wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
15863
    }
15864
15865
#ifdef WOLFSSL_LOCAL_X509_STORE
15866
    int wolfSSL_Unload_trust_peers(WOLFSSL* ssl)
15867
    {
15868
        WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
15869
15870
        if (ssl == NULL)
15871
            return BAD_FUNC_ARG;
15872
15873
        return wolfSSL_CertManagerUnload_trust_peers(SSL_CM(ssl));
15874
    }
15875
#endif /* WOLFSSL_LOCAL_X509_STORE */
15876
#endif /* WOLFSSL_TRUST_PEER_CERT */
15877
/* old NO_FILESYSTEM end */
15878
#endif /* !NO_CERTS */
15879
15880
15881
#ifdef OPENSSL_EXTRA
15882
15883
    int wolfSSL_add_all_algorithms(void)
15884
    {
15885
        WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
15886
        if (initRefCount != 0 || wolfSSL_Init() == WOLFSSL_SUCCESS)
15887
            return WOLFSSL_SUCCESS;
15888
        else
15889
            return WOLFSSL_FATAL_ERROR;
15890
    }
15891
15892
    int wolfSSL_OpenSSL_add_all_algorithms_noconf(void)
15893
    {
15894
        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_noconf");
15895
15896
        if  (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR)
15897
            return WOLFSSL_FATAL_ERROR;
15898
15899
        return  WOLFSSL_SUCCESS;
15900
    }
15901
15902
    int wolfSSL_OpenSSL_add_all_algorithms_conf(void)
15903
    {
15904
        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_conf");
15905
        /* This function is currently the same as
15906
        wolfSSL_OpenSSL_add_all_algorithms_noconf since we do not employ
15907
        the use of a wolfssl.cnf type configuration file and is only used for
15908
        OpenSSL compatability. */
15909
15910
        if (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR) {
15911
            return WOLFSSL_FATAL_ERROR;
15912
        }
15913
        return WOLFSSL_SUCCESS;
15914
    }
15915
15916
   /* returns previous set cache size which stays constant */
15917
    long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
15918
    {
15919
        /* cache size fixed at compile time in wolfSSL */
15920
        (void)ctx;
15921
        (void)sz;
15922
        WOLFSSL_MSG("session cache is set at compile time");
15923
        #ifndef NO_SESSION_CACHE
15924
            return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
15925
        #else
15926
            return 0;
15927
        #endif
15928
    }
15929
15930
#endif
15931
15932
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
15933
    defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
15934
    void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
15935
    {
15936
        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
15937
        if (mode)
15938
            ctx->quietShutdown = 1;
15939
    }
15940
15941
15942
    void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
15943
    {
15944
        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
15945
        if (mode)
15946
            ssl->options.quietShutdown = 1;
15947
    }
15948
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
15949
          WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
15950
15951
#ifdef OPENSSL_EXTRA
15952
#ifndef NO_BIO
15953
    void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
15954
    {
15955
        WOLFSSL_ENTER("wolfSSL_set_bio");
15956
15957
        if (ssl == NULL) {
15958
            WOLFSSL_MSG("Bad argument, ssl was NULL");
15959
            return;
15960
        }
15961
15962
        /* free any existing WOLFSSL_BIOs in use but don't free those in
15963
         * a chain */
15964
        if (ssl->biord != NULL) {
15965
            if (ssl->biord != ssl->biowr) {
15966
                if (ssl->biowr != NULL && ssl->biowr->prev != NULL)
15967
                    wolfSSL_BIO_free(ssl->biowr);
15968
                ssl->biowr = NULL;
15969
            }
15970
            if (ssl->biord->prev != NULL)
15971
                wolfSSL_BIO_free(ssl->biord);
15972
            ssl->biord = NULL;
15973
        }
15974
        /* set flag obviously */
15975
        if (rd && !(rd->flags & WOLFSSL_BIO_FLAG_READ))
15976
            rd->flags |= WOLFSSL_BIO_FLAG_READ;
15977
        if (wr && !(wr->flags & WOLFSSL_BIO_FLAG_WRITE))
15978
            wr->flags |= WOLFSSL_BIO_FLAG_WRITE;
15979
15980
        ssl->biord = rd;
15981
        ssl->biowr = wr;
15982
15983
        /* set SSL to use BIO callbacks instead */
15984
        if (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0)) {
15985
            ssl->CBIORecv = BioReceive;
15986
        }
15987
        if (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0)) {
15988
            ssl->CBIOSend = BioSend;
15989
        }
15990
15991
        /* User programs should always retry reading from these BIOs */
15992
        if (rd) {
15993
            /* User writes to rd */
15994
            BIO_set_retry_write(rd);
15995
        }
15996
        if (wr) {
15997
            /* User reads from wr */
15998
            BIO_set_retry_read(wr);
15999
        }
16000
    }
16001
#endif /* !NO_BIO */
16002
#endif /* OPENSSL_EXTRA */
16003
16004
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
16005
    void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
16006
                                       WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
16007
    {
16008
        WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
16009
        if (ctx != NULL) {
16010
            wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
16011
            ctx->ca_names = names;
16012
        }
16013
    }
16014
16015
    void wolfSSL_set_client_CA_list(WOLFSSL* ssl,
16016
                                       WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
16017
    {
16018
        WOLFSSL_ENTER("wolfSSL_set_client_CA_list");
16019
        if (ssl != NULL) {
16020
            if (ssl->ca_names != ssl->ctx->ca_names)
16021
                wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
16022
            ssl->ca_names = names;
16023
        }
16024
    }
16025
16026
    #ifdef OPENSSL_EXTRA
16027
    /* registers client cert callback, called during handshake if server
16028
       requests client auth but user has not loaded client cert/key */
16029
    void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb)
16030
    {
16031
        WOLFSSL_ENTER("wolfSSL_CTX_set_client_cert_cb");
16032
16033
        if (ctx != NULL) {
16034
            ctx->CBClientCert = cb;
16035
        }
16036
    }
16037
16038
    void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx,
16039
        CertSetupCallback cb, void *arg)
16040
    {
16041
        WOLFSSL_ENTER("wolfSSL_CTX_set_cert_cb");
16042
        if (ctx == NULL)
16043
            return;
16044
16045
        ctx->certSetupCb = cb;
16046
        ctx->certSetupCbArg = arg;
16047
    }
16048
16049
    /**
16050
     * Internal wrapper for calling certSetupCb
16051
     * @param ssl The SSL/TLS Object
16052
     * @return 0 on success
16053
     */
16054
    int CertSetupCbWrapper(WOLFSSL* ssl)
16055
    {
16056
        int ret = 0;
16057
        if (ssl->ctx->certSetupCb != NULL) {
16058
            WOLFSSL_MSG("Calling user cert setup callback");
16059
            ret = ssl->ctx->certSetupCb(ssl, ssl->ctx->certSetupCbArg);
16060
            if (ret == 1) {
16061
                WOLFSSL_MSG("User cert callback returned success");
16062
                ret = 0;
16063
            }
16064
            else if (ret == 0) {
16065
                SendAlert(ssl, alert_fatal, internal_error);
16066
                ret = CLIENT_CERT_CB_ERROR;
16067
            }
16068
            else if (ret < 0) {
16069
                ret = WOLFSSL_ERROR_WANT_X509_LOOKUP;
16070
            }
16071
            else {
16072
                WOLFSSL_MSG("Unexpected user callback return");
16073
                ret = CLIENT_CERT_CB_ERROR;
16074
            }
16075
        }
16076
        return ret;
16077
    }
16078
    #endif /* OPENSSL_EXTRA */
16079
16080
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || HAVE_WEBSERVER */
16081
16082
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
16083
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
16084
            const WOLFSSL_CTX *ctx)
16085
    {
16086
        WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list");
16087
16088
        if (ctx == NULL) {
16089
            WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get_client_CA_list");
16090
            return NULL;
16091
        }
16092
16093
        return ctx->ca_names;
16094
    }
16095
16096
    /* returns the CA's set on server side or the CA's sent from server when
16097
     * on client side */
16098
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list(
16099
            const WOLFSSL* ssl)
16100
    {
16101
        WOLFSSL_ENTER("wolfSSL_get_client_CA_list");
16102
16103
        if (ssl == NULL) {
16104
            WOLFSSL_MSG("Bad argument passed to wolfSSL_get_client_CA_list");
16105
            return NULL;
16106
        }
16107
16108
        return SSL_CA_NAMES(ssl);
16109
    }
16110
16111
    #if !defined(NO_CERTS)
16112
    int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
16113
    {
16114
        WOLFSSL_X509_NAME *nameCopy = NULL;
16115
16116
        WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
16117
16118
        if (ctx == NULL || x509 == NULL){
16119
            WOLFSSL_MSG("Bad argument");
16120
            return WOLFSSL_FAILURE;
16121
        }
16122
16123
        if (ctx->ca_names == NULL) {
16124
            ctx->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
16125
            if (ctx->ca_names == NULL) {
16126
                WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
16127
                return WOLFSSL_FAILURE;
16128
            }
16129
        }
16130
16131
        nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(x509));
16132
        if (nameCopy == NULL) {
16133
            WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
16134
            return WOLFSSL_FAILURE;
16135
        }
16136
16137
        if (wolfSSL_sk_X509_NAME_push(ctx->ca_names, nameCopy) != WOLFSSL_SUCCESS) {
16138
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
16139
            wolfSSL_X509_NAME_free(nameCopy);
16140
            return WOLFSSL_FAILURE;
16141
        }
16142
16143
        return WOLFSSL_SUCCESS;
16144
    }
16145
    #endif
16146
16147
    #ifndef NO_BIO
16148
        #if !defined(NO_RSA) && !defined(NO_CERTS)
16149
        WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
16150
        {
16151
            /* The webserver build is using this to load a CA into the server
16152
             * for client authentication as an option. Have this return NULL in
16153
             * that case. If OPENSSL_EXTRA is enabled, go ahead and include
16154
             * the function. */
16155
        #ifdef OPENSSL_EXTRA
16156
            WOLFSSL_STACK *list = NULL;
16157
            WOLFSSL_BIO* bio = NULL;
16158
            WOLFSSL_X509 *cert = NULL;
16159
            WOLFSSL_X509_NAME *nameCopy = NULL;
16160
            unsigned long err = WOLFSSL_FAILURE;
16161
16162
            WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
16163
16164
            bio = wolfSSL_BIO_new_file(fname, "rb");
16165
            if (bio == NULL) {
16166
                WOLFSSL_MSG("wolfSSL_BIO_new_file error");
16167
                goto cleanup;
16168
            }
16169
16170
            list = wolfSSL_sk_X509_NAME_new(NULL);
16171
            if (list == NULL) {
16172
                WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
16173
                goto cleanup;
16174
            }
16175
16176
            /* Read each certificate in the chain out of the file. */
16177
            while (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
16178
                /* Need a persistent copy of the subject name. */
16179
                nameCopy = wolfSSL_X509_NAME_dup(
16180
                        wolfSSL_X509_get_subject_name(cert));
16181
                if (nameCopy == NULL) {
16182
                    WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
16183
                    goto cleanup;
16184
                }
16185
                /*
16186
                * Original cert will be freed so make sure not to try to access
16187
                * it in the future.
16188
                */
16189
                nameCopy->x509 = NULL;
16190
16191
                if (wolfSSL_sk_X509_NAME_push(list, nameCopy) !=
16192
                        WOLFSSL_SUCCESS) {
16193
                    WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
16194
                    /* Do free in loop because nameCopy is now responsibility
16195
                     * of list to free and adding jumps to cleanup after this
16196
                     * might result in a double free. */
16197
                    wolfSSL_X509_NAME_free(nameCopy);
16198
                    goto cleanup;
16199
                }
16200
16201
                wolfSSL_X509_free(cert);
16202
                cert = NULL;
16203
            }
16204
16205
            CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
16206
16207
            err = WOLFSSL_SUCCESS;
16208
cleanup:
16209
            wolfSSL_X509_free(cert);
16210
            wolfSSL_BIO_free(bio);
16211
            if (err != WOLFSSL_SUCCESS) {
16212
                /* We failed so return NULL */
16213
                wolfSSL_sk_X509_NAME_pop_free(list, NULL);
16214
                list = NULL;
16215
            }
16216
            return list;
16217
        #else
16218
            (void)fname;
16219
            return NULL;
16220
        #endif
16221
        }
16222
        #endif
16223
    #endif /* !NO_BIO */
16224
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA */
16225
16226
#ifdef OPENSSL_EXTRA
16227
16228
    #ifndef NO_FILESYSTEM
16229
    /*
16230
     * This is an OpenSSL compatibility layer function, but it doesn't mirror
16231
     * the exact functionality of its OpenSSL counterpart. We don't support the
16232
     * notion of an "OpenSSL directory," nor do we support the environment
16233
     * variables SSL_CERT_DIR or SSL_CERT_FILE. This function is simply a
16234
     * wrapper around our native wolfSSL_CTX_load_system_CA_certs function. This
16235
     * function does conform to OpenSSL's return value conventions, though.
16236
     */
16237
    int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
16238
    {
16239
        int ret;
16240
16241
        WOLFSSL_ENTER("wolfSSL_CTX_set_default_verify_paths");
16242
16243
        ret = wolfSSL_CTX_load_system_CA_certs(ctx);
16244
        if (ret == WOLFSSL_BAD_PATH) {
16245
            /*
16246
             * OpenSSL doesn't treat the lack of a system CA cert directory as a
16247
             * failure. We do the same here.
16248
             */
16249
            ret = WOLFSSL_SUCCESS;
16250
        }
16251
        else if (ret != WOLFSSL_SUCCESS) {
16252
            /*
16253
             * All other failure types map to WOLFSSL_FAILURE (0), same as
16254
             * OpenSSL.
16255
             */
16256
            ret = WOLFSSL_FAILURE;
16257
        }
16258
16259
        WOLFSSL_LEAVE("wolfSSL_CTX_set_default_verify_paths", ret);
16260
16261
        return ret;
16262
    }
16263
    #endif /* !NO_FILESYSTEM */
16264
16265
    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
16266
        && !defined(WC_NO_RNG)
16267
    static const byte srp_N[] = {
16268
        0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
16269
        0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
16270
        0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
16271
        0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
16272
        0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
16273
        0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
16274
        0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
16275
        0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
16276
        0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
16277
        0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
16278
        0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
16279
        0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
16280
    };
16281
    static const byte srp_g[] = {
16282
        0x02
16283
    };
16284
16285
    int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
16286
    {
16287
        int r = 0;
16288
        SrpSide srp_side = SRP_CLIENT_SIDE;
16289
        byte salt[SRP_SALT_SIZE];
16290
16291
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
16292
        if (ctx == NULL || ctx->srp == NULL || username==NULL)
16293
            return SSL_FAILURE;
16294
16295
        if (ctx->method->side == WOLFSSL_SERVER_END){
16296
            srp_side = SRP_SERVER_SIDE;
16297
        } else if (ctx->method->side == WOLFSSL_CLIENT_END){
16298
            srp_side = SRP_CLIENT_SIDE;
16299
        } else {
16300
            WOLFSSL_MSG("Init CTX failed");
16301
            return SSL_FAILURE;
16302
        }
16303
16304
        if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0) {
16305
            WOLFSSL_MSG("Init SRP CTX failed");
16306
            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
16307
            ctx->srp = NULL;
16308
            return SSL_FAILURE;
16309
        }
16310
        r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
16311
                              (word32)XSTRLEN(username));
16312
        if (r < 0) {
16313
            WOLFSSL_MSG("fail to set srp username.");
16314
            return SSL_FAILURE;
16315
        }
16316
16317
        /* if wolfSSL_CTX_set_srp_password has already been called, */
16318
        /* execute wc_SrpSetPassword here */
16319
        if (ctx->srp_password != NULL) {
16320
            WC_RNG rng;
16321
            if (wc_InitRng(&rng) < 0){
16322
                WOLFSSL_MSG("wc_InitRng failed");
16323
                return SSL_FAILURE;
16324
            }
16325
            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
16326
            r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
16327
            wc_FreeRng(&rng);
16328
            if (r <  0) {
16329
                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
16330
                return SSL_FAILURE;
16331
            }
16332
16333
            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
16334
                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
16335
                                salt, sizeof(salt)/sizeof(salt[0])) < 0) {
16336
                WOLFSSL_MSG("wc_SrpSetParam failed");
16337
                return SSL_FAILURE;
16338
            }
16339
            r = wc_SrpSetPassword(ctx->srp,
16340
                     (const byte*)ctx->srp_password,
16341
                     (word32)XSTRLEN((char *)ctx->srp_password));
16342
            if (r < 0) {
16343
                WOLFSSL_MSG("fail to set srp password.");
16344
                return SSL_FAILURE;
16345
            }
16346
16347
            XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
16348
            ctx->srp_password = NULL;
16349
        }
16350
16351
        return WOLFSSL_SUCCESS;
16352
    }
16353
16354
    int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
16355
    {
16356
        int r;
16357
        byte salt[SRP_SALT_SIZE];
16358
16359
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
16360
        if (ctx == NULL || ctx->srp == NULL || password == NULL)
16361
            return SSL_FAILURE;
16362
16363
        if (ctx->srp->user != NULL) {
16364
            WC_RNG rng;
16365
            if (wc_InitRng(&rng) < 0) {
16366
                WOLFSSL_MSG("wc_InitRng failed");
16367
                return SSL_FAILURE;
16368
            }
16369
            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
16370
            r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
16371
            wc_FreeRng(&rng);
16372
            if (r <  0) {
16373
                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
16374
                return SSL_FAILURE;
16375
            }
16376
            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
16377
                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
16378
                                salt, sizeof(salt)/sizeof(salt[0])) < 0){
16379
                WOLFSSL_MSG("wc_SrpSetParam failed");
16380
                wc_FreeRng(&rng);
16381
                return SSL_FAILURE;
16382
            }
16383
            r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
16384
                                  (word32)XSTRLEN(password));
16385
            if (r < 0) {
16386
                WOLFSSL_MSG("wc_SrpSetPassword failed.");
16387
                wc_FreeRng(&rng);
16388
                return SSL_FAILURE;
16389
            }
16390
            if (ctx->srp_password != NULL){
16391
                XFREE(ctx->srp_password,NULL,
16392
                      DYNAMIC_TYPE_SRP);
16393
                ctx->srp_password = NULL;
16394
            }
16395
            wc_FreeRng(&rng);
16396
        } else {
16397
            /* save password for wolfSSL_set_srp_username */
16398
            if (ctx->srp_password != NULL)
16399
                XFREE(ctx->srp_password,ctx->heap, DYNAMIC_TYPE_SRP);
16400
16401
            ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
16402
                                               DYNAMIC_TYPE_SRP);
16403
            if (ctx->srp_password == NULL){
16404
                WOLFSSL_MSG("memory allocation error");
16405
                return SSL_FAILURE;
16406
            }
16407
            XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
16408
        }
16409
        return WOLFSSL_SUCCESS;
16410
    }
16411
16412
    /**
16413
     * The modulus passed to wc_SrpSetParams in ssl.c is constant so check
16414
     * that the requested strength is less than or equal to the size of the
16415
     * static modulus size.
16416
     * @param ctx Not used
16417
     * @param strength Minimum number of bits for the modulus
16418
     * @return 1 if strength is less than or equal to static modulus
16419
     *         0 if strength is greater than static modulus
16420
     */
16421
    int  wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength)
16422
    {
16423
        (void)ctx;
16424
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_strength");
16425
        if (strength > (int)(sizeof(srp_N)*8)) {
16426
            WOLFSSL_MSG("Bad Parameter");
16427
            return WOLFSSL_FAILURE;
16428
        }
16429
        return WOLFSSL_SUCCESS;
16430
    }
16431
16432
    char* wolfSSL_get_srp_username(WOLFSSL *ssl)
16433
    {
16434
        if (ssl && ssl->ctx && ssl->ctx->srp) {
16435
            return (char*) ssl->ctx->srp->user;
16436
        }
16437
        return NULL;
16438
    }
16439
    #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
16440
16441
    /* keyblock size in bytes or -1 */
16442
    int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
16443
    {
16444
        if (ssl == NULL)
16445
            return WOLFSSL_FATAL_ERROR;
16446
16447
        return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
16448
                    ssl->specs.hash_size);
16449
    }
16450
16451
#endif /* OPENSSL_EXTRA */
16452
16453
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
16454
16455
    /* store keys returns WOLFSSL_SUCCESS or -1 on error */
16456
    int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
16457
                                     unsigned char** sr, unsigned int* srLen,
16458
                                     unsigned char** cr, unsigned int* crLen)
16459
    {
16460
        if (ssl == NULL || ssl->arrays == NULL)
16461
            return WOLFSSL_FATAL_ERROR;
16462
16463
        *ms = ssl->arrays->masterSecret;
16464
        *sr = ssl->arrays->serverRandom;
16465
        *cr = ssl->arrays->clientRandom;
16466
16467
        *msLen = SECRET_LEN;
16468
        *srLen = RAN_LEN;
16469
        *crLen = RAN_LEN;
16470
16471
        return WOLFSSL_SUCCESS;
16472
    }
16473
16474
    void wolfSSL_set_accept_state(WOLFSSL* ssl)
16475
    {
16476
        WOLFSSL_ENTER("wolfSSL_set_accept_state");
16477
16478
        if (ssl == NULL)
16479
            return;
16480
16481
        if (ssl->options.side == WOLFSSL_CLIENT_END) {
16482
    #ifdef HAVE_ECC
16483
        #ifdef WOLFSSL_SMALL_STACK
16484
            ecc_key* key = NULL;
16485
        #else
16486
            ecc_key key[1];
16487
        #endif
16488
            word32 idx = 0;
16489
16490
        #ifdef WOLFSSL_SMALL_STACK
16491
            key = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
16492
                                    DYNAMIC_TYPE_ECC);
16493
            if (key == NULL) {
16494
                WOLFSSL_MSG("Error allocating memory for ecc_key");
16495
            }
16496
        #endif
16497
            if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
16498
                if (wc_ecc_init(key) >= 0) {
16499
                    if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
16500
                            key, ssl->buffers.key->length) != 0) {
16501
                        ssl->options.haveECDSAsig = 0;
16502
                        ssl->options.haveECC = 0;
16503
                        ssl->options.haveStaticECC = 0;
16504
                    }
16505
                    wc_ecc_free(key);
16506
                }
16507
            }
16508
        #ifdef WOLFSSL_SMALL_STACK
16509
            XFREE(key, ssl->heap, DYNAMIC_TYPE_ECC);
16510
        #endif
16511
    #endif
16512
16513
    #ifndef NO_DH
16514
            if (!ssl->options.haveDH && ssl->ctx->haveDH) {
16515
                ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
16516
                ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
16517
                ssl->options.haveDH = 1;
16518
            }
16519
    #endif
16520
        }
16521
16522
        if (InitSSL_Side(ssl, WOLFSSL_SERVER_END) != WOLFSSL_SUCCESS) {
16523
            WOLFSSL_MSG("Error initializing server side");
16524
        }
16525
    }
16526
16527
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
16528
16529
    /* return true if connection established */
16530
    int wolfSSL_is_init_finished(WOLFSSL* ssl)
16531
0
    {
16532
0
        if (ssl == NULL)
16533
0
            return 0;
16534
16535
0
        if (ssl->options.handShakeState == HANDSHAKE_DONE)
16536
0
            return 1;
16537
16538
0
        return 0;
16539
0
    }
16540
16541
#ifdef OPENSSL_EXTRA
16542
    void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
16543
                                      WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
16544
    {
16545
        /* wolfSSL verifies all these internally */
16546
        (void)ctx;
16547
        (void)f;
16548
    }
16549
16550
16551
    void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
16552
    {
16553
        WOLFSSL_ENTER("wolfSSL_set_shutdown");
16554
        if(ssl==NULL) {
16555
            WOLFSSL_MSG("Shutdown not set. ssl is null");
16556
            return;
16557
        }
16558
16559
        ssl->options.sentNotify =  (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
16560
        ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
16561
    }
16562
#endif
16563
16564
    long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
16565
0
    {
16566
0
        WOLFSSL_ENTER("wolfSSL_CTX_get_options");
16567
0
        WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
16568
0
        if(ctx == NULL)
16569
0
            return BAD_FUNC_ARG;
16570
0
        return ctx->mask;
16571
0
    }
16572
16573
    static long wolf_set_options(long old_op, long op);
16574
    long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
16575
0
    {
16576
0
        WOLFSSL_ENTER("SSL_CTX_set_options");
16577
16578
0
        if (ctx == NULL)
16579
0
            return BAD_FUNC_ARG;
16580
16581
0
        ctx->mask = wolf_set_options(ctx->mask, opt);
16582
16583
0
        return ctx->mask;
16584
0
    }
16585
16586
    long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
16587
0
    {
16588
0
        WOLFSSL_ENTER("SSL_CTX_clear_options");
16589
0
        if(ctx == NULL)
16590
0
            return BAD_FUNC_ARG;
16591
0
        ctx->mask &= ~opt;
16592
0
        return ctx->mask;
16593
0
    }
16594
16595
#ifdef OPENSSL_EXTRA
16596
16597
    int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
16598
    {
16599
        WOLFSSL_ENTER("SSL_set_rfd");
16600
        ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
16601
16602
        ssl->IOCB_ReadCtx  = &ssl->rfd;
16603
16604
    #ifdef WOLFSSL_DTLS
16605
        if (ssl->options.dtls) {
16606
            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
16607
            ssl->buffers.dtlsCtx.rfd = rfd;
16608
        }
16609
    #endif
16610
16611
        return WOLFSSL_SUCCESS;
16612
    }
16613
16614
16615
    int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
16616
    {
16617
        WOLFSSL_ENTER("SSL_set_wfd");
16618
        ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
16619
16620
        ssl->IOCB_WriteCtx  = &ssl->wfd;
16621
16622
        return WOLFSSL_SUCCESS;
16623
    }
16624
#endif /* OPENSSL_EXTRA */
16625
16626
#if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
16627
16628
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
16629
    /**
16630
     * Implemented in a similar way that ngx_ssl_ocsp_validate does it when
16631
     * SSL_get0_verified_chain is not available.
16632
     * @param ssl WOLFSSL object to extract certs from
16633
     * @return Stack of verified certs
16634
     */
16635
    WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
16636
    {
16637
        WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
16638
        WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
16639
        WOLFSSL_X509* peerCert = NULL;
16640
16641
        WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
16642
16643
        if (ssl == NULL || ssl->ctx == NULL) {
16644
            WOLFSSL_MSG("Bad parameter");
16645
            return NULL;
16646
        }
16647
16648
        peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl);
16649
        if (peerCert == NULL) {
16650
            WOLFSSL_MSG("wolfSSL_get_peer_certificate error");
16651
            return NULL;
16652
        }
16653
        /* wolfSSL_get_peer_certificate returns a copy. We want the internal
16654
         * member so that we don't have to worry about free'ing it. We call
16655
         * wolfSSL_get_peer_certificate so that we don't have to worry about
16656
         * setting up the internal pointer. */
16657
        wolfSSL_X509_free(peerCert);
16658
        peerCert = (WOLFSSL_X509*)&ssl->peerCert;
16659
        chain = wolfSSL_get_peer_cert_chain(ssl);
16660
        if (chain == NULL) {
16661
            WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
16662
            return NULL;
16663
        }
16664
        storeCtx = wolfSSL_X509_STORE_CTX_new();
16665
        if (storeCtx == NULL) {
16666
            WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
16667
            return NULL;
16668
        }
16669
        if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl),
16670
                peerCert, chain) != WOLFSSL_SUCCESS) {
16671
            WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
16672
            wolfSSL_X509_STORE_CTX_free(storeCtx);
16673
            return NULL;
16674
        }
16675
        if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
16676
            WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
16677
            wolfSSL_X509_STORE_CTX_free(storeCtx);
16678
            return NULL;
16679
        }
16680
        wolfSSL_X509_STORE_CTX_free(storeCtx);
16681
        return chain;
16682
    }
16683
#endif /* SESSION_CERTS && OPENSSL_EXTRA */
16684
16685
    WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx)
16686
    {
16687
        if (ctx == NULL) {
16688
            return NULL;
16689
        }
16690
16691
        if (ctx->x509_store_pt != NULL)
16692
            return ctx->x509_store_pt;
16693
        return &ctx->x509_store;
16694
    }
16695
16696
    void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
16697
    {
16698
        WOLFSSL_ENTER("wolfSSL_CTX_set_cert_store");
16699
        if (ctx == NULL || str == NULL || ctx->cm == str->cm) {
16700
            return;
16701
        }
16702
16703
        if (wolfSSL_CertManager_up_ref(str->cm) != WOLFSSL_SUCCESS) {
16704
            WOLFSSL_MSG("wolfSSL_CertManager_up_ref error");
16705
            return;
16706
        }
16707
        /* free cert manager if have one */
16708
        if (ctx->cm != NULL) {
16709
            wolfSSL_CertManagerFree(ctx->cm);
16710
        }
16711
        ctx->cm               = str->cm;
16712
        ctx->x509_store.cm    = str->cm;
16713
16714
        /* free existing store if it exists */
16715
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
16716
        ctx->x509_store.cache = str->cache;
16717
        ctx->x509_store_pt    = str; /* take ownership of store and free it
16718
                                        with CTX free */
16719
        ctx->cm->x509_store_p = ctx->x509_store_pt;/* CTX has onwership
16720
                                                    and free it with CTX free*/
16721
    }
16722
16723
16724
    int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
16725
    {
16726
        WOLFSSL_ENTER("wolfSSL_set0_verify_cert_store");
16727
16728
        if (ssl == NULL || str == NULL) {
16729
            WOLFSSL_MSG("Bad parameter");
16730
            return WOLFSSL_FAILURE;
16731
        }
16732
16733
        /* NO-OP when setting existing store */
16734
        if (str == SSL_STORE(ssl))
16735
            return WOLFSSL_SUCCESS;
16736
16737
        /* free existing store if it exists */
16738
        wolfSSL_X509_STORE_free(ssl->x509_store_pt);
16739
        if (str == ssl->ctx->x509_store_pt)
16740
            ssl->x509_store_pt = NULL; /* if setting ctx store then just revert
16741
                                          to using that instead */
16742
        else
16743
            ssl->x509_store_pt = str; /* take ownership of store and free it
16744
                                         with SSL free */
16745
        return WOLFSSL_SUCCESS;
16746
    }
16747
16748
16749
    int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
16750
    {
16751
        WOLFSSL_ENTER("wolfSSL_set1_verify_cert_store");
16752
16753
        if (ssl == NULL || str == NULL) {
16754
            WOLFSSL_MSG("Bad parameter");
16755
            return WOLFSSL_FAILURE;
16756
        }
16757
16758
        /* NO-OP when setting existing store */
16759
        if (str == SSL_STORE(ssl))
16760
            return WOLFSSL_SUCCESS;
16761
16762
        if (wolfSSL_X509_STORE_up_ref(str) != WOLFSSL_SUCCESS) {
16763
            WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
16764
            return WOLFSSL_FAILURE;
16765
        }
16766
16767
        /* free existing store if it exists */
16768
        wolfSSL_X509_STORE_free(ssl->x509_store_pt);
16769
        if (str == ssl->ctx->x509_store_pt)
16770
            ssl->x509_store_pt = NULL; /* if setting ctx store then just revert
16771
                                          to using that instead */
16772
        else
16773
            ssl->x509_store_pt = str; /* take ownership of store and free it
16774
                                         with SSL free */
16775
        return WOLFSSL_SUCCESS;
16776
    }
16777
#endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
16778
16779
#ifdef WOLFSSL_ENCRYPTED_KEYS
16780
16781
    void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
16782
                                                   void* userdata)
16783
    {
16784
        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
16785
        if (ctx)
16786
            ctx->passwd_userdata = userdata;
16787
    }
16788
16789
16790
    void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, wc_pem_password_cb*
16791
                                           cb)
16792
    {
16793
        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
16794
        if (ctx)
16795
            ctx->passwd_cb = cb;
16796
    }
16797
16798
    wc_pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
16799
    {
16800
        if (ctx == NULL || ctx->passwd_cb == NULL) {
16801
            return NULL;
16802
        }
16803
16804
        return ctx->passwd_cb;
16805
    }
16806
16807
16808
    void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
16809
    {
16810
        if (ctx == NULL) {
16811
            return NULL;
16812
        }
16813
16814
        return ctx->passwd_userdata;
16815
    }
16816
16817
#endif /* WOLFSSL_ENCRYPTED_KEYS */
16818
16819
16820
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
16821
    int wolfSSL_num_locks(void)
16822
    {
16823
        return 0;
16824
    }
16825
16826
    void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
16827
    {
16828
        WOLFSSL_ENTER("wolfSSL_set_locking_callback");
16829
16830
        if (wc_SetMutexCb(f) != 0) {
16831
            WOLFSSL_MSG("Error when setting mutex call back");
16832
        }
16833
    }
16834
16835
16836
    typedef unsigned long (idCb)(void);
16837
    static idCb* inner_idCb = NULL;
16838
16839
    unsigned long wolfSSL_thread_id(void)
16840
    {
16841
        if (inner_idCb != NULL) {
16842
            return inner_idCb();
16843
        }
16844
        else {
16845
            return 0;
16846
        }
16847
    }
16848
16849
16850
    void wolfSSL_set_id_callback(unsigned long (*f)(void))
16851
    {
16852
        inner_idCb = f;
16853
    }
16854
16855
    unsigned long wolfSSL_ERR_get_error(void)
16856
    {
16857
        int ret;
16858
16859
        WOLFSSL_ENTER("wolfSSL_ERR_get_error");
16860
16861
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
16862
        ret = wc_PullErrorNode(NULL, NULL, NULL);
16863
        if (ret < 0) {
16864
            if (ret == BAD_STATE_E) {
16865
                ret = 0; /* no errors in queue */
16866
            }
16867
            else {
16868
                WOLFSSL_MSG("Error with pulling error node!");
16869
                WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
16870
                ret = 0 - ret; /* return absolute value of error */
16871
                /* panic and try to clear out nodes */
16872
                wc_ClearErrorNodes();
16873
            }
16874
        }
16875
        else {
16876
            wc_RemoveErrorNode(0);
16877
        }
16878
16879
        return ret;
16880
#else
16881
16882
        (void)ret;
16883
16884
        return (unsigned long)(0 - NOT_COMPILED_IN);
16885
#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
16886
    }
16887
16888
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
16889
#ifndef NO_BIO
16890
    /* print out and clear all errors */
16891
    void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
16892
    {
16893
        const char* file = NULL;
16894
        const char* reason = NULL;
16895
        int ret;
16896
        int line = 0;
16897
        char buf[WOLFSSL_MAX_ERROR_SZ * 2];
16898
16899
        WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
16900
16901
        if (bio == NULL) {
16902
            WOLFSSL_MSG("BIO passed in was null");
16903
            return;
16904
        }
16905
16906
        do {
16907
        ret = wc_PeekErrorNode(0, &file, &reason, &line);
16908
        if (ret >= 0) {
16909
            const char* r = wolfSSL_ERR_reason_error_string(0 - ret);
16910
            if (XSNPRINTF(buf, sizeof(buf),
16911
                          "error:%d:wolfSSL library:%s:%s:%d\n",
16912
                          ret, r, file, line)
16913
                >= (int)sizeof(buf))
16914
            {
16915
                WOLFSSL_MSG("Buffer overrun formatting error message");
16916
            }
16917
            wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
16918
            wc_RemoveErrorNode(0);
16919
        }
16920
        } while (ret >= 0);
16921
        if (wolfSSL_BIO_write(bio, "", 1) != 1) {
16922
            WOLFSSL_MSG("Issue writing final string terminator");
16923
        }
16924
    }
16925
#endif /* !NO_BIO */
16926
#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
16927
16928
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
16929
16930
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
16931
    defined(HAVE_SECRET_CALLBACK)
16932
#if !defined(NO_WOLFSSL_SERVER)
16933
/* Return the amount of random bytes copied over or error case.
16934
 * ssl : ssl struct after handshake
16935
 * out : buffer to hold random bytes
16936
 * outSz : either 0 (return max buffer sz) or size of out buffer
16937
 */
16938
size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
16939
                                                                   size_t outSz)
16940
{
16941
    size_t size;
16942
16943
    /* return max size of buffer */
16944
    if (outSz == 0) {
16945
        return RAN_LEN;
16946
    }
16947
16948
    if (ssl == NULL || out == NULL) {
16949
        return 0;
16950
    }
16951
16952
    if (ssl->arrays == NULL) {
16953
        WOLFSSL_MSG("Arrays struct not saved after handshake");
16954
        return 0;
16955
    }
16956
16957
    if (outSz > RAN_LEN) {
16958
        size = RAN_LEN;
16959
    }
16960
    else {
16961
        size = outSz;
16962
    }
16963
16964
    XMEMCPY(out, ssl->arrays->serverRandom, size);
16965
    return size;
16966
}
16967
#endif /* !NO_WOLFSSL_SERVER */
16968
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
16969
16970
#ifdef OPENSSL_EXTRA
16971
#if !defined(NO_WOLFSSL_SERVER)
16972
/* Used to get the peer ephemeral public key sent during the connection
16973
 * NOTE: currently wolfSSL_KeepHandshakeResources(WOLFSSL* ssl) must be called
16974
 *       before the ephemeral key is stored.
16975
 * return WOLFSSL_SUCCESS on success */
16976
int wolfSSL_get_server_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey)
16977
{
16978
    WOLFSSL_EVP_PKEY* ret = NULL;
16979
16980
    WOLFSSL_ENTER("wolfSSL_get_server_tmp_key");
16981
16982
    if (ssl == NULL || pkey == NULL) {
16983
        WOLFSSL_MSG("Bad argument passed in");
16984
        return WOLFSSL_FAILURE;
16985
    }
16986
16987
#ifdef HAVE_ECC
16988
    if (ssl->peerEccKey != NULL) {
16989
        unsigned char* der;
16990
        const unsigned char* pt;
16991
        unsigned int   derSz = 0;
16992
        int sz;
16993
16994
        PRIVATE_KEY_UNLOCK();
16995
        if (wc_ecc_export_x963(ssl->peerEccKey, NULL, &derSz) !=
16996
                LENGTH_ONLY_E) {
16997
            WOLFSSL_MSG("get ecc der size failed");
16998
            PRIVATE_KEY_LOCK();
16999
            return WOLFSSL_FAILURE;
17000
        }
17001
        PRIVATE_KEY_LOCK();
17002
17003
        derSz += MAX_SEQ_SZ + (2 * MAX_ALGO_SZ) + MAX_SEQ_SZ + TRAILING_ZERO;
17004
        der = (unsigned char*)XMALLOC(derSz, ssl->heap, DYNAMIC_TYPE_KEY);
17005
        if (der == NULL) {
17006
            WOLFSSL_MSG("Memory error");
17007
            return WOLFSSL_FAILURE;
17008
        }
17009
17010
        if ((sz = wc_EccPublicKeyToDer(ssl->peerEccKey, der, derSz, 1)) <= 0) {
17011
            WOLFSSL_MSG("get ecc der failed");
17012
            XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
17013
            return WOLFSSL_FAILURE;
17014
        }
17015
        pt = der; /* in case pointer gets advanced */
17016
        ret = wolfSSL_d2i_PUBKEY(NULL, &pt, sz);
17017
        XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
17018
    }
17019
#endif
17020
17021
    *pkey = ret;
17022
#ifdef HAVE_ECC
17023
    if (ret != NULL)
17024
        return WOLFSSL_SUCCESS;
17025
    else
17026
#endif
17027
        return WOLFSSL_FAILURE;
17028
}
17029
17030
#endif /* !NO_WOLFSSL_SERVER */
17031
17032
/**
17033
 * This function checks if any compiled in protocol versions are
17034
 * left enabled after calls to set_min or set_max API.
17035
 * @param major The SSL/TLS major version
17036
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
17037
 *         protocol versions are left enabled.
17038
 */
17039
static int CheckSslMethodVersion(byte major, unsigned long options)
17040
{
17041
    int sanityConfirmed = 0;
17042
17043
    (void)options;
17044
17045
    switch (major) {
17046
    #ifndef NO_TLS
17047
        case SSLv3_MAJOR:
17048
            #ifdef WOLFSSL_ALLOW_SSLV3
17049
                if (!(options & WOLFSSL_OP_NO_SSLv3)) {
17050
                    sanityConfirmed = 1;
17051
                }
17052
            #endif
17053
            #ifndef NO_OLD_TLS
17054
                if (!(options & WOLFSSL_OP_NO_TLSv1))
17055
                    sanityConfirmed = 1;
17056
                if (!(options & WOLFSSL_OP_NO_TLSv1_1))
17057
                    sanityConfirmed = 1;
17058
            #endif
17059
            #ifndef WOLFSSL_NO_TLS12
17060
                if (!(options & WOLFSSL_OP_NO_TLSv1_2))
17061
                    sanityConfirmed = 1;
17062
            #endif
17063
            #ifdef WOLFSSL_TLS13
17064
                if (!(options & WOLFSSL_OP_NO_TLSv1_3))
17065
                    sanityConfirmed = 1;
17066
            #endif
17067
            break;
17068
    #endif
17069
    #ifdef WOLFSSL_DTLS
17070
        case DTLS_MAJOR:
17071
            sanityConfirmed = 1;
17072
            break;
17073
    #endif
17074
        default:
17075
            WOLFSSL_MSG("Invalid major version");
17076
            return WOLFSSL_FAILURE;
17077
    }
17078
    if (!sanityConfirmed) {
17079
        WOLFSSL_MSG("All compiled in TLS versions disabled");
17080
        return WOLFSSL_FAILURE;
17081
    }
17082
    return WOLFSSL_SUCCESS;
17083
}
17084
17085
/**
17086
 * protoVerTbl holds (D)TLS version numbers in ascending order.
17087
 * Except DTLS versions, the newer version is located in the latter part of
17088
 * the table. This table is referred by wolfSSL_CTX_set_min_proto_version and
17089
 * wolfSSL_CTX_set_max_proto_version.
17090
 */
17091
static const int protoVerTbl[] = {
17092
    SSL3_VERSION,
17093
    TLS1_VERSION,
17094
    TLS1_1_VERSION,
17095
    TLS1_2_VERSION,
17096
    TLS1_3_VERSION,
17097
    DTLS1_VERSION,
17098
    DTLS1_2_VERSION
17099
};
17100
/* number of protocol versions listed in protoVerTbl */
17101
#define NUMBER_OF_PROTOCOLS (sizeof(protoVerTbl)/sizeof(int))
17102
17103
/**
17104
 * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol
17105
 * version to use by SSL objects created from this WOLFSSL_CTX.
17106
 * This API guarantees that a version of SSL/TLS lower than specified
17107
 * here will not be allowed. If the version specified is not compiled in
17108
 * then this API sets the lowest compiled in protocol version.
17109
 * This API also accept 0 as version, to set the minimum version automatically.
17110
 * CheckSslMethodVersion() is called to check if any remaining protocol versions
17111
 * are enabled.
17112
 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
17113
 * @param version Any of the following
17114
 *          * 0
17115
 *          * SSL3_VERSION
17116
 *          * TLS1_VERSION
17117
 *          * TLS1_1_VERSION
17118
 *          * TLS1_2_VERSION
17119
 *          * TLS1_3_VERSION
17120
 *          * DTLS1_VERSION
17121
 *          * DTLS1_2_VERSION
17122
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
17123
 *         protocol versions are left enabled.
17124
 */
17125
static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version)
17126
{
17127
    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version_ex");
17128
17129
    if (ctx == NULL) {
17130
        return WOLFSSL_FAILURE;
17131
    }
17132
17133
    switch (version) {
17134
#ifndef NO_TLS
17135
        case SSL3_VERSION:
17136
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
17137
            ctx->minDowngrade = SSLv3_MINOR;
17138
            break;
17139
#endif
17140
        case TLS1_VERSION:
17141
        #ifdef WOLFSSL_ALLOW_TLSV10
17142
            ctx->minDowngrade = TLSv1_MINOR;
17143
            break;
17144
        #endif
17145
        case TLS1_1_VERSION:
17146
        #ifndef NO_OLD_TLS
17147
            ctx->minDowngrade = TLSv1_1_MINOR;
17148
            break;
17149
        #endif
17150
        case TLS1_2_VERSION:
17151
        #ifndef WOLFSSL_NO_TLS12
17152
            ctx->minDowngrade = TLSv1_2_MINOR;
17153
            break;
17154
        #endif
17155
        case TLS1_3_VERSION:
17156
        #ifdef WOLFSSL_TLS13
17157
            ctx->minDowngrade = TLSv1_3_MINOR;
17158
            break;
17159
        #endif
17160
#endif
17161
#ifdef WOLFSSL_DTLS
17162
        case DTLS1_VERSION:
17163
    #ifndef NO_OLD_TLS
17164
            ctx->minDowngrade = DTLS_MINOR;
17165
            break;
17166
    #endif
17167
        case DTLS1_2_VERSION:
17168
            ctx->minDowngrade = DTLSv1_2_MINOR;
17169
            break;
17170
#endif
17171
        default:
17172
            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17173
            return WOLFSSL_FAILURE;
17174
    }
17175
17176
    switch (version) {
17177
#ifndef NO_TLS
17178
    case TLS1_3_VERSION:
17179
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
17180
        FALL_THROUGH;
17181
    case TLS1_2_VERSION:
17182
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
17183
        FALL_THROUGH;
17184
    case TLS1_1_VERSION:
17185
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
17186
        FALL_THROUGH;
17187
    case TLS1_VERSION:
17188
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
17189
        break;
17190
    case SSL3_VERSION:
17191
    case SSL2_VERSION:
17192
        /* Nothing to do here */
17193
        break;
17194
#endif
17195
#ifdef WOLFSSL_DTLS
17196
    case DTLS1_VERSION:
17197
    case DTLS1_2_VERSION:
17198
        break;
17199
#endif
17200
    default:
17201
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17202
        return WOLFSSL_FAILURE;
17203
    }
17204
17205
    return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
17206
}
17207
17208
/* Sets the min protocol version allowed with WOLFSSL_CTX
17209
 * returns WOLFSSL_SUCCESS on success */
17210
int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
17211
{
17212
    int ret;
17213
    int proto    = 0;
17214
    int maxProto = 0;
17215
    int i;
17216
    int idx = 0;
17217
17218
    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version");
17219
17220
    if (ctx == NULL) {
17221
        return WOLFSSL_FAILURE;
17222
    }
17223
    if (version != 0) {
17224
        proto = version;
17225
        ctx->minProto = 0; /* turn min proto flag off */
17226
        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
17227
            if (protoVerTbl[i] == version) {
17228
                break;
17229
            }
17230
        }
17231
    }
17232
    else {
17233
        /* when 0 is specified as version, try to find out the min version */
17234
        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
17235
            ret = Set_CTX_min_proto_version(ctx, protoVerTbl[i]);
17236
            if (ret == WOLFSSL_SUCCESS) {
17237
                proto = protoVerTbl[i];
17238
                ctx->minProto = 1; /* turn min proto flag on */
17239
                break;
17240
            }
17241
        }
17242
    }
17243
17244
    /* check case where max > min , if so then clear the NO_* options
17245
     * i is the index into the table for proto version used, see if the max
17246
     * proto version index found is smaller */
17247
    maxProto = wolfSSL_CTX_get_max_proto_version(ctx);
17248
    for (idx = 0; (unsigned)idx < NUMBER_OF_PROTOCOLS; idx++) {
17249
        if (protoVerTbl[idx] == maxProto) {
17250
            break;
17251
        }
17252
    }
17253
    if (idx < i) {
17254
        wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_TLSv1 |
17255
                WOLFSSL_OP_NO_TLSv1_1 | WOLFSSL_OP_NO_TLSv1_2 |
17256
                WOLFSSL_OP_NO_TLSv1_3);
17257
    }
17258
17259
    ret = Set_CTX_min_proto_version(ctx, proto);
17260
    return ret;
17261
}
17262
17263
/**
17264
 * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol
17265
 * version to use by SSL objects created from this WOLFSSL_CTX.
17266
 * This API guarantees that a version of SSL/TLS higher than specified
17267
 * here will not be allowed. If the version specified is not compiled in
17268
 * then this API sets the highest compiled in protocol version.
17269
 * This API also accept 0 as version, to set the maximum version automatically.
17270
 * CheckSslMethodVersion() is called to check if any remaining protocol versions
17271
 * are enabled.
17272
 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
17273
 * @param ver Any of the following
17274
 *          * 0
17275
 *          * SSL3_VERSION
17276
 *          * TLS1_VERSION
17277
 *          * TLS1_1_VERSION
17278
 *          * TLS1_2_VERSION
17279
 *          * TLS1_3_VERSION
17280
 *          * DTLS1_VERSION
17281
 *          * DTLS1_2_VERSION
17282
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
17283
 *         protocol versions are left enabled.
17284
 */
17285
static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver)
17286
{
17287
    WOLFSSL_ENTER("Set_CTX_max_proto_version");
17288
17289
    if (!ctx || !ctx->method) {
17290
        WOLFSSL_MSG("Bad parameter");
17291
        return WOLFSSL_FAILURE;
17292
    }
17293
17294
    switch (ver) {
17295
    case SSL2_VERSION:
17296
        WOLFSSL_MSG("wolfSSL does not support SSLv2");
17297
        return WOLFSSL_FAILURE;
17298
#ifndef NO_TLS
17299
    case SSL3_VERSION:
17300
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
17301
        FALL_THROUGH;
17302
    case TLS1_VERSION:
17303
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
17304
        FALL_THROUGH;
17305
    case TLS1_1_VERSION:
17306
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
17307
        FALL_THROUGH;
17308
    case TLS1_2_VERSION:
17309
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3);
17310
        FALL_THROUGH;
17311
    case TLS1_3_VERSION:
17312
        /* Nothing to do here */
17313
        break;
17314
#endif
17315
#ifdef WOLFSSL_DTLS
17316
    case DTLS1_VERSION:
17317
    case DTLS1_2_VERSION:
17318
        break;
17319
#endif
17320
    default:
17321
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17322
        return WOLFSSL_FAILURE;
17323
    }
17324
17325
    return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
17326
}
17327
17328
17329
/* Sets the max protocol version allowed with WOLFSSL_CTX
17330
 * returns WOLFSSL_SUCCESS on success */
17331
int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
17332
{
17333
    int i;
17334
    int ret = WOLFSSL_FAILURE;
17335
    int minProto;
17336
17337
    WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version");
17338
17339
    if (ctx == NULL) {
17340
        return ret;
17341
    }
17342
17343
    /* clear out flags and reset min protocol version */
17344
    minProto = wolfSSL_CTX_get_min_proto_version(ctx);
17345
    wolfSSL_CTX_clear_options(ctx,
17346
            WOLFSSL_OP_NO_TLSv1 | WOLFSSL_OP_NO_TLSv1_1 |
17347
            WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3);
17348
    wolfSSL_CTX_set_min_proto_version(ctx, minProto);
17349
    if (version != 0) {
17350
        ctx->maxProto = 0; /* turn max proto flag off */
17351
        return Set_CTX_max_proto_version(ctx, version);
17352
    }
17353
17354
    /* when 0 is specified as version, try to find out the min version from
17355
     * the bottom to top of the protoverTbl.
17356
     */
17357
    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
17358
        ret = Set_CTX_max_proto_version(ctx, protoVerTbl[i]);
17359
        if (ret == WOLFSSL_SUCCESS) {
17360
            ctx->maxProto = 1; /* turn max proto flag on */
17361
            break;
17362
        }
17363
    }
17364
17365
    return ret;
17366
}
17367
17368
17369
static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver)
17370
{
17371
    WOLFSSL_ENTER("Set_SSL_min_proto_version");
17372
17373
    if (ssl == NULL) {
17374
        return WOLFSSL_FAILURE;
17375
    }
17376
17377
    switch (ver) {
17378
#ifndef NO_TLS
17379
        case SSL3_VERSION:
17380
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
17381
            ssl->options.minDowngrade = SSLv3_MINOR;
17382
            break;
17383
#endif
17384
        case TLS1_VERSION:
17385
        #ifdef WOLFSSL_ALLOW_TLSV10
17386
            ssl->options.minDowngrade = TLSv1_MINOR;
17387
            break;
17388
        #endif
17389
        case TLS1_1_VERSION:
17390
        #ifndef NO_OLD_TLS
17391
            ssl->options.minDowngrade = TLSv1_1_MINOR;
17392
            break;
17393
        #endif
17394
        case TLS1_2_VERSION:
17395
        #ifndef WOLFSSL_NO_TLS12
17396
            ssl->options.minDowngrade = TLSv1_2_MINOR;
17397
            break;
17398
        #endif
17399
        case TLS1_3_VERSION:
17400
        #ifdef WOLFSSL_TLS13
17401
            ssl->options.minDowngrade = TLSv1_3_MINOR;
17402
            break;
17403
        #endif
17404
#endif
17405
#ifdef WOLFSSL_DTLS
17406
        case DTLS1_VERSION:
17407
    #ifndef NO_OLD_TLS
17408
            ssl->options.minDowngrade = DTLS_MINOR;
17409
            break;
17410
    #endif
17411
        case DTLS1_2_VERSION:
17412
            ssl->options.minDowngrade = DTLSv1_2_MINOR;
17413
            break;
17414
#endif
17415
        default:
17416
            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17417
            return WOLFSSL_FAILURE;
17418
    }
17419
17420
    switch (ver) {
17421
#ifndef NO_TLS
17422
    case TLS1_3_VERSION:
17423
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
17424
        FALL_THROUGH;
17425
    case TLS1_2_VERSION:
17426
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
17427
        FALL_THROUGH;
17428
    case TLS1_1_VERSION:
17429
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
17430
        FALL_THROUGH;
17431
    case TLS1_VERSION:
17432
        ssl->options.mask |= WOLFSSL_OP_NO_SSLv3;
17433
        break;
17434
    case SSL3_VERSION:
17435
    case SSL2_VERSION:
17436
        /* Nothing to do here */
17437
        break;
17438
#endif
17439
#ifdef WOLFSSL_DTLS
17440
    case DTLS1_VERSION:
17441
    case DTLS1_2_VERSION:
17442
        break;
17443
#endif
17444
    default:
17445
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17446
        return WOLFSSL_FAILURE;
17447
    }
17448
17449
    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
17450
}
17451
17452
int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version)
17453
{
17454
    int i;
17455
    int ret = WOLFSSL_FAILURE;;
17456
17457
    WOLFSSL_ENTER("wolfSSL_set_min_proto_version");
17458
17459
    if (ssl == NULL) {
17460
        return WOLFSSL_FAILURE;
17461
    }
17462
    if (version != 0) {
17463
        return Set_SSL_min_proto_version(ssl, version);
17464
    }
17465
17466
    /* when 0 is specified as version, try to find out the min version */
17467
    for (i= 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
17468
        ret = Set_SSL_min_proto_version(ssl, protoVerTbl[i]);
17469
        if (ret == WOLFSSL_SUCCESS)
17470
            break;
17471
    }
17472
17473
    return ret;
17474
}
17475
17476
static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver)
17477
{
17478
17479
    WOLFSSL_ENTER("Set_SSL_max_proto_version");
17480
17481
    if (!ssl) {
17482
        WOLFSSL_MSG("Bad parameter");
17483
        return WOLFSSL_FAILURE;
17484
    }
17485
17486
    switch (ver) {
17487
    case SSL2_VERSION:
17488
        WOLFSSL_MSG("wolfSSL does not support SSLv2");
17489
        return WOLFSSL_FAILURE;
17490
#ifndef NO_TLS
17491
    case SSL3_VERSION:
17492
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
17493
        FALL_THROUGH;
17494
    case TLS1_VERSION:
17495
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
17496
        FALL_THROUGH;
17497
    case TLS1_1_VERSION:
17498
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
17499
        FALL_THROUGH;
17500
    case TLS1_2_VERSION:
17501
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_3;
17502
        FALL_THROUGH;
17503
    case TLS1_3_VERSION:
17504
        /* Nothing to do here */
17505
        break;
17506
#endif
17507
#ifdef WOLFSSL_DTLS
17508
    case DTLS1_VERSION:
17509
    case DTLS1_2_VERSION:
17510
        break;
17511
#endif
17512
    default:
17513
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17514
        return WOLFSSL_FAILURE;
17515
    }
17516
17517
    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
17518
}
17519
17520
int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version)
17521
{
17522
    int i;
17523
    int ret = WOLFSSL_FAILURE;;
17524
17525
    WOLFSSL_ENTER("wolfSSL_set_max_proto_version");
17526
17527
    if (ssl == NULL) {
17528
        return WOLFSSL_FAILURE;
17529
    }
17530
    if (version != 0) {
17531
        return Set_SSL_max_proto_version(ssl, version);
17532
    }
17533
17534
    /* when 0 is specified as version, try to find out the min version from
17535
     * the bottom to top of the protoverTbl.
17536
     */
17537
    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
17538
        ret = Set_SSL_max_proto_version(ssl, protoVerTbl[i]);
17539
        if (ret == WOLFSSL_SUCCESS)
17540
            break;
17541
    }
17542
17543
    return ret;
17544
}
17545
17546
static int GetMinProtoVersion(int minDowngrade)
17547
{
17548
    int ret;
17549
17550
    switch (minDowngrade) {
17551
#ifndef NO_OLD_TLS
17552
    #ifdef WOLFSSL_ALLOW_SSLV3
17553
        case SSLv3_MINOR:
17554
            ret = SSL3_VERSION;
17555
            break;
17556
    #endif
17557
    #ifdef WOLFSSL_ALLOW_TLSV10
17558
        case TLSv1_MINOR:
17559
            ret = TLS1_VERSION;
17560
            break;
17561
    #endif
17562
        case TLSv1_1_MINOR:
17563
            ret = TLS1_1_VERSION;
17564
            break;
17565
#endif
17566
#ifndef WOLFSSL_NO_TLS12
17567
        case TLSv1_2_MINOR:
17568
            ret = TLS1_2_VERSION;
17569
            break;
17570
#endif
17571
#ifdef WOLFSSL_TLS13
17572
        case TLSv1_3_MINOR:
17573
            ret = TLS1_3_VERSION;
17574
            break;
17575
#endif
17576
        default:
17577
            ret = 0;
17578
            break;
17579
    }
17580
17581
    return ret;
17582
}
17583
17584
WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx)
17585
{
17586
    int ret = 0;
17587
17588
    WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version");
17589
17590
    if (ctx != NULL) {
17591
        if (ctx->minProto) {
17592
            ret = 0;
17593
        }
17594
        else {
17595
            ret = GetMinProtoVersion(ctx->minDowngrade);
17596
        }
17597
    }
17598
    else {
17599
        ret = GetMinProtoVersion(WOLFSSL_MIN_DOWNGRADE);
17600
    }
17601
17602
    WOLFSSL_LEAVE("wolfSSL_CTX_get_min_proto_version", ret);
17603
17604
    return ret;
17605
}
17606
17607
17608
/* returns the maximum allowed protocol version given the 'options' used
17609
 * returns WOLFSSL_FATAL_ERROR on no match */
17610
static int GetMaxProtoVersion(long options)
17611
{
17612
#ifndef NO_TLS
17613
#ifdef WOLFSSL_TLS13
17614
    if (!(options & WOLFSSL_OP_NO_TLSv1_3))
17615
        return TLS1_3_VERSION;
17616
#endif
17617
#ifndef WOLFSSL_NO_TLS12
17618
    if (!(options & WOLFSSL_OP_NO_TLSv1_2))
17619
        return TLS1_2_VERSION;
17620
#endif
17621
#ifndef NO_OLD_TLS
17622
    if (!(options & WOLFSSL_OP_NO_TLSv1_1))
17623
        return TLS1_1_VERSION;
17624
    #ifdef WOLFSSL_ALLOW_TLSV10
17625
    if (!(options & WOLFSSL_OP_NO_TLSv1))
17626
        return TLS1_VERSION;
17627
    #endif
17628
    #ifdef WOLFSSL_ALLOW_SSLV3
17629
    if (!(options & WOLFSSL_OP_NO_SSLv3))
17630
        return SSL3_VERSION;
17631
    #endif
17632
#endif
17633
#else
17634
    (void)options;
17635
#endif /* NO_TLS */
17636
    return WOLFSSL_FATAL_ERROR;
17637
}
17638
17639
17640
/* returns the maximum protocol version for 'ctx' */
17641
int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx)
17642
{
17643
    int ret = 0;
17644
    long options = 0; /* default to nothing set */
17645
17646
    WOLFSSL_ENTER("wolfSSL_CTX_get_max_proto_version");
17647
17648
    if (ctx != NULL) {
17649
        options = wolfSSL_CTX_get_options(ctx);
17650
    }
17651
17652
    if ((ctx != NULL) && ctx->maxProto) {
17653
        ret = 0;
17654
    }
17655
    else {
17656
        ret = GetMaxProtoVersion(options);
17657
    }
17658
17659
    WOLFSSL_LEAVE("wolfSSL_CTX_get_max_proto_version", ret);
17660
17661
    if (ret == WOLFSSL_FATAL_ERROR) {
17662
        WOLFSSL_MSG("Error getting max proto version");
17663
        ret = 0; /* setting ret to 0 to match compat return */
17664
    }
17665
    return ret;
17666
}
17667
#endif /* OPENSSL_EXTRA */
17668
17669
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
17670
    defined(HAVE_SECRET_CALLBACK)
17671
#if !defined(NO_WOLFSSL_CLIENT)
17672
/* Return the amount of random bytes copied over or error case.
17673
 * ssl : ssl struct after handshake
17674
 * out : buffer to hold random bytes
17675
 * outSz : either 0 (return max buffer sz) or size of out buffer
17676
 */
17677
size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
17678
                                                                   size_t outSz)
17679
{
17680
    size_t size;
17681
17682
    /* return max size of buffer */
17683
    if (outSz == 0) {
17684
        return RAN_LEN;
17685
    }
17686
17687
    if (ssl == NULL || out == NULL) {
17688
        return 0;
17689
    }
17690
17691
    if (ssl->arrays == NULL) {
17692
        WOLFSSL_MSG("Arrays struct not saved after handshake");
17693
        return 0;
17694
    }
17695
17696
    if (outSz > RAN_LEN) {
17697
        size = RAN_LEN;
17698
    }
17699
    else {
17700
        size = outSz;
17701
    }
17702
17703
    XMEMCPY(out, ssl->arrays->clientRandom, size);
17704
    return size;
17705
}
17706
#endif /* !NO_WOLFSSL_CLIENT */
17707
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
17708
17709
#ifdef OPENSSL_EXTRA
17710
    unsigned long wolfSSLeay(void)
17711
    {
17712
        return SSLEAY_VERSION_NUMBER;
17713
    }
17714
17715
    unsigned long wolfSSL_OpenSSL_version_num(void)
17716
    {
17717
        return OPENSSL_VERSION_NUMBER;
17718
    }
17719
17720
    const char* wolfSSLeay_version(int type)
17721
    {
17722
        (void)type;
17723
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
17724
        return wolfSSL_OpenSSL_version(type);
17725
#else
17726
        return wolfSSL_OpenSSL_version();
17727
#endif
17728
    }
17729
17730
17731
#ifndef NO_MD5
17732
    int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
17733
    {
17734
        int ret;
17735
        typedef char md5_test[sizeof(MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1];
17736
        (void)sizeof(md5_test);
17737
17738
        WOLFSSL_ENTER("MD5_Init");
17739
        ret = wc_InitMd5((wc_Md5*)md5);
17740
17741
        /* return 1 on success, 0 otherwise */
17742
        if (ret == 0)
17743
            return 1;
17744
17745
        return 0;
17746
    }
17747
17748
17749
    int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
17750
                           unsigned long sz)
17751
    {
17752
        int ret;
17753
17754
        WOLFSSL_ENTER("wolfSSL_MD5_Update");
17755
        ret = wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz);
17756
17757
        /* return 1 on success, 0 otherwise */
17758
        if (ret == 0)
17759
            return 1;
17760
17761
        return 0;
17762
    }
17763
17764
17765
    int wolfSSL_MD5_Final(byte* output, WOLFSSL_MD5_CTX* md5)
17766
    {
17767
        int ret;
17768
17769
        WOLFSSL_ENTER("MD5_Final");
17770
        ret = wc_Md5Final((wc_Md5*)md5, output);
17771
17772
        /* have to actually free the resources (if any) here, because the
17773
         * OpenSSL API doesn't include SHA*_Free().
17774
         */
17775
        wc_Md5Free((wc_Md5*)md5);
17776
17777
        /* return 1 on success, 0 otherwise */
17778
        if (ret == 0)
17779
            return 1;
17780
17781
        return 0;
17782
    }
17783
    /* Apply MD5 transformation to the data */
17784
    int wolfSSL_MD5_Transform(WOLFSSL_MD5_CTX* md5, const unsigned char* data)
17785
    {
17786
        int ret;
17787
17788
       WOLFSSL_ENTER("MD5_Transform");
17789
17790
       /* sanity check */
17791
       if (md5 == NULL || data == NULL) {
17792
            return 0;
17793
       }
17794
       #if defined(BIG_ENDIAN_ORDER)
17795
       {
17796
            ByteReverseWords((word32*)data, (word32*)data, WC_MD5_BLOCK_SIZE);
17797
       }
17798
       #endif
17799
17800
       ret = wc_Md5Transform((wc_Md5*)md5, data);
17801
17802
       /* return 1 on success, 0 otherwise */
17803
        if (ret == 0)
17804
            return 1;
17805
        else
17806
            return 0;
17807
    }
17808
17809
    unsigned char *wolfSSL_MD5(const unsigned char* data, size_t len,
17810
            unsigned char* hash)
17811
    {
17812
        static unsigned char out[WC_MD5_DIGEST_SIZE];
17813
17814
        WOLFSSL_ENTER("wolfSSL_MD5");
17815
17816
        if (hash == NULL)
17817
            hash = out;
17818
        if (wc_Md5Hash(data, (word32)len, hash) != 0) {
17819
            WOLFSSL_MSG("wc_Md5Hash error");
17820
            return NULL;
17821
        }
17822
        return hash;
17823
    }
17824
#endif /* !NO_MD5 */
17825
17826
17827
#ifndef NO_SHA
17828
    int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
17829
    {
17830
        int ret;
17831
17832
        typedef char sha_test[sizeof(SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1];
17833
        (void)sizeof(sha_test);
17834
17835
        WOLFSSL_ENTER("SHA_Init");
17836
        ret = wc_InitSha((wc_Sha*)sha);
17837
17838
        /* return 1 on success, 0 otherwise */
17839
        if (ret == 0)
17840
            return 1;
17841
17842
        return 0;
17843
    }
17844
17845
17846
    int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
17847
                           unsigned long sz)
17848
    {
17849
        int ret;
17850
17851
        WOLFSSL_ENTER("SHA_Update");
17852
        ret = wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz);
17853
17854
        /* return 1 on success, 0 otherwise */
17855
        if (ret == 0)
17856
            return 1;
17857
17858
        return 0;
17859
    }
17860
17861
17862
    int wolfSSL_SHA_Final(byte* output, WOLFSSL_SHA_CTX* sha)
17863
    {
17864
        int ret;
17865
17866
        WOLFSSL_ENTER("SHA_Final");
17867
        ret = wc_ShaFinal((wc_Sha*)sha, output);
17868
17869
        /* have to actually free the resources (if any) here, because the
17870
         * OpenSSL API doesn't include SHA*_Free().
17871
         */
17872
        wc_ShaFree((wc_Sha*)sha);
17873
17874
        /* return 1 on success, 0 otherwise */
17875
        if (ret == 0)
17876
            return 1;
17877
17878
        return 0;
17879
    }
17880
17881
    #if defined(OPENSSL_EXTRA)
17882
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17883
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
17884
    /* Apply SHA1 transformation to the data */
17885
    int wolfSSL_SHA_Transform(WOLFSSL_SHA_CTX* sha,
17886
                                         const unsigned char* data)
17887
    {
17888
       int ret;
17889
17890
       WOLFSSL_ENTER("SHA_Transform");
17891
       /* sanity check */
17892
       if (sha == NULL || data == NULL) {
17893
            return 0;
17894
       }
17895
       #if defined(LITTLE_ENDIAN_ORDER)
17896
       {
17897
            ByteReverseWords((word32*)data, (word32*)data, WC_SHA_BLOCK_SIZE);
17898
       }
17899
       #endif
17900
       ret = wc_ShaTransform((wc_Sha*)sha, data);
17901
17902
       /* return 1 on success, 0 otherwise */
17903
        if (ret == 0)
17904
            return 1;
17905
        else
17906
            return 0;
17907
    }
17908
    #endif
17909
    #endif
17910
17911
    int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
17912
    {
17913
        WOLFSSL_ENTER("SHA1_Init");
17914
        return SHA_Init(sha);
17915
    }
17916
17917
17918
    int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
17919
                            unsigned long sz)
17920
    {
17921
        WOLFSSL_ENTER("SHA1_Update");
17922
        return SHA_Update(sha, input, sz);
17923
    }
17924
17925
17926
    int wolfSSL_SHA1_Final(byte* output, WOLFSSL_SHA_CTX* sha)
17927
    {
17928
        WOLFSSL_ENTER("SHA1_Final");
17929
        return SHA_Final(output, sha);
17930
    }
17931
    #if defined(OPENSSL_EXTRA)
17932
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17933
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
17934
    /* Apply SHA1 transformation to the data */
17935
    int wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX* sha,
17936
                                         const unsigned char* data)
17937
    {
17938
       WOLFSSL_ENTER("SHA1_Transform");
17939
       return (wolfSSL_SHA_Transform(sha, data));
17940
    }
17941
    #endif
17942
    #endif
17943
#endif /* !NO_SHA */
17944
17945
#ifdef WOLFSSL_SHA224
17946
17947
    int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha)
17948
    {
17949
        int ret;
17950
17951
        typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1];
17952
        (void)sizeof(sha_test);
17953
17954
        WOLFSSL_ENTER("SHA224_Init");
17955
        ret = wc_InitSha224((wc_Sha224*)sha);
17956
17957
        /* return 1 on success, 0 otherwise */
17958
        if (ret == 0)
17959
            return 1;
17960
17961
        return 0;
17962
    }
17963
17964
17965
    int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha, const void* input,
17966
                           unsigned long sz)
17967
    {
17968
        int ret;
17969
17970
        WOLFSSL_ENTER("SHA224_Update");
17971
        ret = wc_Sha224Update((wc_Sha224*)sha, (const byte*)input, (word32)sz);
17972
17973
        /* return 1 on success, 0 otherwise */
17974
        if (ret == 0)
17975
            return 1;
17976
17977
        return 0;
17978
    }
17979
17980
17981
    int wolfSSL_SHA224_Final(byte* output, WOLFSSL_SHA224_CTX* sha)
17982
    {
17983
        int ret;
17984
17985
        WOLFSSL_ENTER("SHA224_Final");
17986
        ret = wc_Sha224Final((wc_Sha224*)sha, output);
17987
17988
        /* have to actually free the resources (if any) here, because the
17989
         * OpenSSL API doesn't include SHA*_Free().
17990
         */
17991
        wc_Sha224Free((wc_Sha224*)sha);
17992
17993
        /* return 1 on success, 0 otherwise */
17994
        if (ret == 0)
17995
            return 1;
17996
17997
        return 0;
17998
    }
17999
18000
#endif /* WOLFSSL_SHA224 */
18001
18002
18003
    int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
18004
    {
18005
        int ret;
18006
18007
        typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1];
18008
        (void)sizeof(sha_test);
18009
18010
        WOLFSSL_ENTER("SHA256_Init");
18011
        ret = wc_InitSha256((wc_Sha256*)sha256);
18012
18013
        /* return 1 on success, 0 otherwise */
18014
        if (ret == 0)
18015
            return 1;
18016
18017
        return 0;
18018
    }
18019
18020
18021
    int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
18022
                              unsigned long sz)
18023
    {
18024
        int ret;
18025
18026
        WOLFSSL_ENTER("SHA256_Update");
18027
        ret = wc_Sha256Update((wc_Sha256*)sha, (const byte*)input, (word32)sz);
18028
18029
        /* return 1 on success, 0 otherwise */
18030
        if (ret == 0)
18031
            return 1;
18032
18033
        return 0;
18034
    }
18035
18036
18037
    int wolfSSL_SHA256_Final(byte* output, WOLFSSL_SHA256_CTX* sha)
18038
    {
18039
        int ret;
18040
18041
        WOLFSSL_ENTER("SHA256_Final");
18042
        ret = wc_Sha256Final((wc_Sha256*)sha, output);
18043
18044
        /* have to actually free the resources (if any) here, because the
18045
         * OpenSSL API doesn't include SHA*_Free().
18046
         */
18047
        wc_Sha256Free((wc_Sha256*)sha);
18048
18049
        /* return 1 on success, 0 otherwise */
18050
        if (ret == 0)
18051
            return 1;
18052
18053
        return 0;
18054
    }
18055
18056
    #if defined(OPENSSL_EXTRA)
18057
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
18058
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
18059
        !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH)
18060
    /* Apply SHA256 transformation to the data */
18061
    int wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX* sha256,
18062
                                                const unsigned char* data)
18063
    {
18064
       int ret;
18065
18066
       WOLFSSL_ENTER("SHA256_Transform");
18067
       /* sanity check */
18068
       if (sha256 == NULL || data == NULL) {
18069
            return 0;
18070
       }
18071
       #if defined(LITTLE_ENDIAN_ORDER)
18072
       {
18073
            ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE);
18074
       }
18075
       #endif
18076
       ret = wc_Sha256Transform((wc_Sha256*)sha256, data);
18077
18078
       /* return 1 on success, 0 otherwise */
18079
        if (ret == 0)
18080
            return 1;
18081
        else
18082
            return 0;
18083
    }
18084
    #endif
18085
    #endif
18086
18087
#ifdef WOLFSSL_SHA384
18088
18089
    int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
18090
    {
18091
        int ret;
18092
18093
        typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1];
18094
        (void)sizeof(sha_test);
18095
18096
        WOLFSSL_ENTER("SHA384_Init");
18097
        ret = wc_InitSha384((wc_Sha384*)sha);
18098
18099
        /* return 1 on success, 0 otherwise */
18100
        if (ret == 0)
18101
            return 1;
18102
18103
        return 0;
18104
    }
18105
18106
18107
    int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
18108
                           unsigned long sz)
18109
    {
18110
        int ret;
18111
18112
        WOLFSSL_ENTER("SHA384_Update");
18113
        ret = wc_Sha384Update((wc_Sha384*)sha, (const byte*)input, (word32)sz);
18114
18115
        /* return 1 on success, 0 otherwise */
18116
        if (ret == 0)
18117
            return 1;
18118
18119
        return 0;
18120
    }
18121
18122
18123
    int wolfSSL_SHA384_Final(byte* output, WOLFSSL_SHA384_CTX* sha)
18124
    {
18125
        int ret;
18126
18127
        WOLFSSL_ENTER("SHA384_Final");
18128
        ret = wc_Sha384Final((wc_Sha384*)sha, output);
18129
18130
        /* have to actually free the resources (if any) here, because the
18131
         * OpenSSL API doesn't include SHA*_Free().
18132
         */
18133
        wc_Sha384Free((wc_Sha384*)sha);
18134
18135
        /* return 1 on success, 0 otherwise */
18136
        if (ret == 0)
18137
            return 1;
18138
18139
        return 0;
18140
    }
18141
18142
#endif /* WOLFSSL_SHA384 */
18143
18144
18145
#ifdef WOLFSSL_SHA512
18146
18147
    int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
18148
    {
18149
        int ret;
18150
18151
        typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1];
18152
        (void)sizeof(sha_test);
18153
18154
        WOLFSSL_ENTER("SHA512_Init");
18155
        ret = wc_InitSha512((wc_Sha512*)sha);
18156
18157
        /* return 1 on success, 0 otherwise */
18158
        if (ret == 0)
18159
            return 1;
18160
18161
        return 0;
18162
    }
18163
18164
18165
    int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
18166
                           unsigned long sz)
18167
    {
18168
        int ret;
18169
18170
        WOLFSSL_ENTER("SHA512_Update");
18171
        ret = wc_Sha512Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
18172
18173
        /* return 1 on success, 0 otherwise */
18174
        if (ret == 0)
18175
            return 1;
18176
18177
        return 0;
18178
    }
18179
18180
18181
    int wolfSSL_SHA512_Final(byte* output, WOLFSSL_SHA512_CTX* sha)
18182
    {
18183
        int ret;
18184
18185
        WOLFSSL_ENTER("SHA512_Final");
18186
        ret = wc_Sha512Final((wc_Sha512*)sha, output);
18187
18188
        /* have to actually free the resources (if any) here, because the
18189
         * OpenSSL API doesn't include SHA*_Free().
18190
         */
18191
        wc_Sha512Free((wc_Sha512*)sha);
18192
18193
        /* return 1 on success, 0 otherwise */
18194
        if (ret == 0)
18195
            return 1;
18196
18197
        return 0;
18198
    }
18199
18200
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
18201
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
18202
    /* Apply SHA512 transformation to the data */
18203
    int wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX* sha512,
18204
                                          const unsigned char* data)
18205
    {
18206
       int ret;
18207
18208
       WOLFSSL_ENTER("SHA512_Transform");
18209
       /* sanity check */
18210
       if (sha512 == NULL || data == NULL) {
18211
            return WOLFSSL_FAILURE;
18212
       }
18213
18214
       ret = wc_Sha512Transform((wc_Sha512*)sha512, data);
18215
18216
       /* return 1 on success, 0 otherwise */
18217
        if (ret == 0)
18218
            return WOLFSSL_SUCCESS;
18219
        else
18220
            return WOLFSSL_FAILURE;
18221
    }
18222
    #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
18223
              (HAVE_FIPS_VERSION > 2)) */
18224
18225
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
18226
#if !defined(WOLFSSL_NOSHA512_224)
18227
    int wolfSSL_SHA512_224_Init(WOLFSSL_SHA512_224_CTX* sha)
18228
    {
18229
        int ret;
18230
18231
        WOLFSSL_ENTER("wolfSSL_SHA512_224_Init");
18232
        ret = wc_InitSha512_224((wc_Sha512*)sha);
18233
18234
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
18235
        if (ret == 0)
18236
            return WOLFSSL_SUCCESS;
18237
18238
        return WOLFSSL_FAILURE;
18239
    }
18240
18241
    int wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX* sha,
18242
                                        const void* input, unsigned long sz)
18243
    {
18244
        int ret;
18245
18246
        WOLFSSL_ENTER("wolfSSL_SHA512_224_Update");
18247
        ret = wc_Sha512_224Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
18248
18249
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
18250
        if (ret == 0)
18251
            return WOLFSSL_SUCCESS;
18252
18253
        return WOLFSSL_FAILURE;
18254
    }
18255
18256
    int wolfSSL_SHA512_224_Final(byte* output, WOLFSSL_SHA512_224_CTX* sha)
18257
    {
18258
        int ret;
18259
18260
        WOLFSSL_ENTER("wolfSSL_SHA512_224_Final");
18261
        ret = wc_Sha512_224Final((wc_Sha512*)sha, output);
18262
18263
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
18264
        if (ret == 0)
18265
            return WOLFSSL_SUCCESS;
18266
18267
        return WOLFSSL_FAILURE;
18268
    }
18269
18270
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
18271
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
18272
    /* Apply SHA512 transformation to the data */
18273
    int wolfSSL_SHA512_224_Transform(WOLFSSL_SHA512_CTX* sha512,
18274
                                          const unsigned char* data)
18275
    {
18276
       int ret;
18277
18278
       WOLFSSL_ENTER("SHA512_224_Transform");
18279
       /* sanity check */
18280
       if (sha512 == NULL || data == NULL) {
18281
            return WOLFSSL_FAILURE;
18282
       }
18283
18284
       ret = wc_Sha512_224Transform((wc_Sha512*)sha512, data);
18285
18286
       /* return 1 on success, 0 otherwise */
18287
        if (ret == 0)
18288
            return WOLFSSL_SUCCESS;
18289
        else
18290
            return WOLFSSL_FAILURE;
18291
    }
18292
    #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
18293
              (HAVE_FIPS_VERSION > 2)) */
18294
18295
#endif /* !WOLFSSL_NOSHA512_224 */
18296
#if !defined(WOLFSSL_NOSHA512_256)
18297
    int wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_256_CTX* sha)
18298
    {
18299
        int ret;
18300
18301
        WOLFSSL_ENTER("wolfSSL_SHA512_256_Init");
18302
        ret = wc_InitSha512_256((wc_Sha512*)sha);
18303
18304
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
18305
        if (ret == 0)
18306
            return WOLFSSL_SUCCESS;
18307
18308
        return WOLFSSL_FAILURE;
18309
    }
18310
18311
    int wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX* sha,
18312
                                        const void* input, unsigned long sz)
18313
    {
18314
        int ret;
18315
18316
        WOLFSSL_ENTER("wolfSSL_SHA512_256_Update");
18317
        ret = wc_Sha512_256Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
18318
18319
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
18320
        if (ret == 0)
18321
            return WOLFSSL_SUCCESS;
18322
18323
        return WOLFSSL_FAILURE;
18324
    }
18325
18326
    int wolfSSL_SHA512_256_Final(byte* output, WOLFSSL_SHA512_256_CTX* sha)
18327
    {
18328
        int ret;
18329
18330
        WOLFSSL_ENTER("wolfSSL_SHA512_256_Final");
18331
        ret = wc_Sha512_256Final((wc_Sha512*)sha, output);
18332
18333
        /* return WOLFSSL_SUCCESS on success, 0 otherwise */
18334
        if (ret == 0)
18335
            return WOLFSSL_SUCCESS;
18336
18337
        return WOLFSSL_FAILURE;
18338
    }
18339
18340
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
18341
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
18342
    /* Apply SHA512 transformation to the data */
18343
    int wolfSSL_SHA512_256_Transform(WOLFSSL_SHA512_CTX* sha512,
18344
                                          const unsigned char* data)
18345
    {
18346
       int ret;
18347
18348
       WOLFSSL_ENTER("SHA512_256_Transform");
18349
       /* sanity check */
18350
       if (sha512 == NULL || data == NULL) {
18351
            return WOLFSSL_FAILURE;
18352
       }
18353
18354
       ret = wc_Sha512_256Transform((wc_Sha512*)sha512, data);
18355
18356
       /* return 1 on success, 0 otherwise */
18357
        if (ret == 0)
18358
            return WOLFSSL_SUCCESS;
18359
        else
18360
            return WOLFSSL_FAILURE;
18361
    }
18362
    #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
18363
              (HAVE_FIPS_VERSION > 2)) */
18364
18365
#endif /* !WOLFSSL_NOSHA512_256 */
18366
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
18367
18368
#endif /* WOLFSSL_SHA512 */
18369
18370
#ifdef WOLFSSL_SHA3
18371
#ifndef WOLFSSL_NOSHA3_224
18372
18373
    int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha)
18374
    {
18375
        int ret;
18376
18377
        typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18378
        (void)sizeof(sha_test);
18379
18380
        WOLFSSL_ENTER("SHA3_224_Init");
18381
        ret = wc_InitSha3_224((wc_Sha3*)sha, NULL, INVALID_DEVID);
18382
18383
        /* return 1 on success, 0 otherwise */
18384
        if (ret == 0)
18385
            return 1;
18386
18387
        return 0;
18388
    }
18389
18390
18391
    int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha, const void* input,
18392
                           unsigned long sz)
18393
    {
18394
        int ret;
18395
18396
        WOLFSSL_ENTER("SHA3_224_Update");
18397
        ret = wc_Sha3_224_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18398
18399
        /* return 1 on success, 0 otherwise */
18400
        if (ret == 0)
18401
            return 1;
18402
18403
        return 0;
18404
    }
18405
18406
18407
    int wolfSSL_SHA3_224_Final(byte* output, WOLFSSL_SHA3_224_CTX* sha)
18408
    {
18409
        int ret;
18410
18411
        WOLFSSL_ENTER("SHA3_224_Final");
18412
        ret = wc_Sha3_224_Final((wc_Sha3*)sha, output);
18413
18414
        /* have to actually free the resources (if any) here, because the
18415
         * OpenSSL API doesn't include SHA*_Free().
18416
         */
18417
        wc_Sha3_224_Free((wc_Sha3*)sha);
18418
18419
        /* return 1 on success, 0 otherwise */
18420
        if (ret == 0)
18421
            return 1;
18422
18423
        return 0;
18424
    }
18425
18426
#endif /* WOLFSSL_NOSHA3_224 */
18427
18428
18429
#ifndef WOLFSSL_NOSHA3_256
18430
    int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256)
18431
    {
18432
        int ret;
18433
18434
        typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18435
        (void)sizeof(sha_test);
18436
18437
        WOLFSSL_ENTER("SHA3_256_Init");
18438
        ret = wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, INVALID_DEVID);
18439
18440
        /* return 1 on success, 0 otherwise */
18441
        if (ret == 0)
18442
            return 1;
18443
18444
        return 0;
18445
    }
18446
18447
18448
    int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha, const void* input,
18449
                              unsigned long sz)
18450
    {
18451
        int ret;
18452
18453
        WOLFSSL_ENTER("SHA3_256_Update");
18454
        ret = wc_Sha3_256_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18455
18456
        /* return 1 on success, 0 otherwise */
18457
        if (ret == 0)
18458
            return 1;
18459
18460
        return 0;
18461
    }
18462
18463
18464
    int wolfSSL_SHA3_256_Final(byte* output, WOLFSSL_SHA3_256_CTX* sha)
18465
    {
18466
        int ret;
18467
18468
        WOLFSSL_ENTER("SHA3_256_Final");
18469
        ret = wc_Sha3_256_Final((wc_Sha3*)sha, output);
18470
18471
        /* have to actually free the resources (if any) here, because the
18472
         * OpenSSL API doesn't include SHA*_Free().
18473
         */
18474
        wc_Sha3_256_Free((wc_Sha3*)sha);
18475
18476
        /* return 1 on success, 0 otherwise */
18477
        if (ret == 0)
18478
            return 1;
18479
18480
        return 0;
18481
    }
18482
#endif /* WOLFSSL_NOSHA3_256 */
18483
18484
18485
    int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha)
18486
    {
18487
        int ret;
18488
18489
        typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18490
        (void)sizeof(sha_test);
18491
18492
        WOLFSSL_ENTER("SHA3_384_Init");
18493
        ret = wc_InitSha3_384((wc_Sha3*)sha, NULL, INVALID_DEVID);
18494
18495
        /* return 1 on success, 0 otherwise */
18496
        if (ret == 0)
18497
            return 1;
18498
18499
        return 0;
18500
    }
18501
18502
18503
    int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha, const void* input,
18504
                           unsigned long sz)
18505
    {
18506
        int ret;
18507
18508
        WOLFSSL_ENTER("SHA3_384_Update");
18509
        ret = wc_Sha3_384_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18510
18511
        /* return 1 on success, 0 otherwise */
18512
        if (ret == 0)
18513
            return 1;
18514
18515
        return 0;
18516
    }
18517
18518
18519
    int wolfSSL_SHA3_384_Final(byte* output, WOLFSSL_SHA3_384_CTX* sha)
18520
    {
18521
        int ret;
18522
18523
        WOLFSSL_ENTER("SHA3_384_Final");
18524
        ret = wc_Sha3_384_Final((wc_Sha3*)sha, output);
18525
18526
        /* have to actually free the resources (if any) here, because the
18527
         * OpenSSL API doesn't include SHA*_Free().
18528
         */
18529
        wc_Sha3_384_Free((wc_Sha3*)sha);
18530
18531
        /* return 1 on success, 0 otherwise */
18532
        if (ret == 0)
18533
            return 1;
18534
18535
        return 0;
18536
    }
18537
18538
18539
18540
#ifndef WOLFSSL_NOSHA3_512
18541
18542
    int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha)
18543
    {
18544
        int ret;
18545
18546
        typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18547
        (void)sizeof(sha_test);
18548
18549
        WOLFSSL_ENTER("SHA3_512_Init");
18550
        ret = wc_InitSha3_512((wc_Sha3*)sha, NULL, INVALID_DEVID);
18551
18552
        /* return 1 on success, 0 otherwise */
18553
        if (ret == 0)
18554
            return 1;
18555
18556
        return 0;
18557
    }
18558
18559
18560
    int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha, const void* input,
18561
                           unsigned long sz)
18562
    {
18563
        int ret;
18564
18565
        WOLFSSL_ENTER("SHA3_512_Update");
18566
        ret = wc_Sha3_512_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18567
18568
        /* return 1 on success, 0 otherwise */
18569
        if (ret == 0)
18570
            return 1;
18571
18572
        return 0;
18573
    }
18574
18575
18576
    int wolfSSL_SHA3_512_Final(byte* output, WOLFSSL_SHA3_512_CTX* sha)
18577
    {
18578
        int ret;
18579
18580
        WOLFSSL_ENTER("SHA3_512_Final");
18581
        ret = wc_Sha3_512_Final((wc_Sha3*)sha, output);
18582
18583
        /* have to actually free the resources (if any) here, because the
18584
         * OpenSSL API doesn't include SHA*_Free().
18585
         */
18586
        wc_Sha3_512_Free((wc_Sha3*)sha);
18587
18588
        /* return 1 on success, 0 otherwise */
18589
        if (ret == 0)
18590
            return 1;
18591
18592
        return 0;
18593
    }
18594
18595
#endif /* WOLFSSL_NOSHA3_512 */
18596
#endif /* WOLFSSL_SHA3 */
18597
18598
    unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
18599
                                int key_len, const unsigned char* d, int n,
18600
                                unsigned char* md, unsigned int* md_len)
18601
    {
18602
        int type;
18603
        int mdlen;
18604
        unsigned char* ret = NULL;
18605
#ifdef WOLFSSL_SMALL_STACK
18606
        Hmac* hmac = NULL;
18607
#else
18608
        Hmac  hmac[1];
18609
#endif
18610
        void* heap = NULL;
18611
18612
        WOLFSSL_ENTER("wolfSSL_HMAC");
18613
        if (!md) {
18614
            WOLFSSL_MSG("Static buffer not supported, pass in md buffer");
18615
            return NULL;  /* no static buffer support */
18616
        }
18617
18618
#ifndef NO_MD5
18619
        if (XSTRCMP(evp_md, "MD5") == 0) {
18620
            type = WC_MD5;
18621
            mdlen = WC_MD5_DIGEST_SIZE;
18622
        } else
18623
#endif
18624
#ifdef WOLFSSL_SHA224
18625
        if (XSTRCMP(evp_md, "SHA224") == 0) {
18626
            type = WC_SHA224;
18627
            mdlen = WC_SHA224_DIGEST_SIZE;
18628
        } else
18629
#endif
18630
#ifndef NO_SHA256
18631
        if (XSTRCMP(evp_md, "SHA256") == 0) {
18632
            type = WC_SHA256;
18633
            mdlen = WC_SHA256_DIGEST_SIZE;
18634
        } else
18635
#endif
18636
#ifdef WOLFSSL_SHA384
18637
        if (XSTRCMP(evp_md, "SHA384") == 0) {
18638
            type = WC_SHA384;
18639
            mdlen = WC_SHA384_DIGEST_SIZE;
18640
        } else
18641
#endif
18642
#ifdef WOLFSSL_SHA512
18643
        if (XSTRCMP(evp_md, "SHA512") == 0) {
18644
            type = WC_SHA512;
18645
            mdlen = WC_SHA512_DIGEST_SIZE;
18646
        } else
18647
#endif
18648
#ifdef WOLFSSL_SHA3
18649
    #ifndef WOLFSSL_NOSHA3_224
18650
        if (XSTRCMP(evp_md, "SHA3_224") == 0) {
18651
            type = WC_SHA3_224;
18652
            mdlen = WC_SHA3_224_DIGEST_SIZE;
18653
        } else
18654
    #endif
18655
    #ifndef WOLFSSL_NOSHA3_256
18656
        if (XSTRCMP(evp_md, "SHA3_256") == 0) {
18657
            type = WC_SHA3_256;
18658
            mdlen = WC_SHA3_256_DIGEST_SIZE;
18659
        } else
18660
    #endif
18661
        if (XSTRCMP(evp_md, "SHA3_384") == 0) {
18662
            type = WC_SHA3_384;
18663
            mdlen = WC_SHA3_384_DIGEST_SIZE;
18664
        } else
18665
    #ifndef WOLFSSL_NOSHA3_512
18666
        if (XSTRCMP(evp_md, "SHA3_512") == 0) {
18667
            type = WC_SHA3_512;
18668
            mdlen = WC_SHA3_512_DIGEST_SIZE;
18669
        } else
18670
    #endif
18671
#endif
18672
#ifndef NO_SHA
18673
        if (XSTRCMP(evp_md, "SHA") == 0 || XSTRCMP(evp_md, "SHA1") == 0) {
18674
            type = WC_SHA;
18675
            mdlen = WC_SHA_DIGEST_SIZE;
18676
        }
18677
        else
18678
#endif
18679
        {
18680
            return NULL;
18681
        }
18682
18683
    #ifdef WOLFSSL_SMALL_STACK
18684
        hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
18685
        if (hmac == NULL)
18686
            return NULL;
18687
    #endif
18688
18689
        if (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0) {
18690
            if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) {
18691
                if (wc_HmacUpdate(hmac, d, n) == 0) {
18692
                    if (wc_HmacFinal(hmac, md) == 0) {
18693
                        if (md_len)
18694
                            *md_len = mdlen;
18695
                        ret = md;
18696
                    }
18697
                }
18698
            }
18699
            wc_HmacFree(hmac);
18700
        }
18701
18702
    #ifdef WOLFSSL_SMALL_STACK
18703
        XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
18704
    #endif
18705
18706
        (void)evp_md;
18707
        return ret;
18708
    }
18709
18710
#ifndef NO_DES3
18711
    /* 0 on ok */
18712
    int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
18713
                              WOLFSSL_DES_key_schedule* schedule)
18714
    {
18715
        WOLFSSL_ENTER("wolfSSL_DES_key_sched");
18716
18717
        if (key == NULL || schedule == NULL) {
18718
            WOLFSSL_MSG("Null argument passed in");
18719
        }
18720
        else {
18721
            XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock));
18722
        }
18723
18724
        return 0;
18725
    }
18726
18727
18728
    /* intended to behave similar to Kerberos mit_des_cbc_cksum
18729
     * return the last 4 bytes of cipher text */
18730
    WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in,
18731
            WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc,
18732
            WOLFSSL_const_DES_cblock* iv)
18733
    {
18734
        WOLFSSL_DES_LONG ret;
18735
        unsigned char* tmp;
18736
        unsigned char* data   = (unsigned char*)in;
18737
        long           dataSz = length;
18738
        byte dynamicFlag = 0; /* when padding the buffer created needs free'd */
18739
18740
        WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum");
18741
18742
        if (in == NULL || out == NULL || sc == NULL || iv == NULL) {
18743
            WOLFSSL_MSG("Bad argument passed in");
18744
            return 0;
18745
        }
18746
18747
        /* if input length is not a multiple of DES_BLOCK_SIZE pad with 0s */
18748
        if (dataSz % DES_BLOCK_SIZE) {
18749
            dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE);
18750
            data = (unsigned char*)XMALLOC(dataSz, NULL,
18751
                                           DYNAMIC_TYPE_TMP_BUFFER);
18752
            if (data == NULL) {
18753
                WOLFSSL_MSG("Issue creating temporary buffer");
18754
                return 0;
18755
            }
18756
            dynamicFlag = 1; /* set to free buffer at end */
18757
            XMEMCPY(data, in, length);
18758
            XMEMSET(data + length, 0, dataSz - length); /* padding */
18759
        }
18760
18761
        tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18762
        if (tmp == NULL) {
18763
            WOLFSSL_MSG("Issue creating temporary buffer");
18764
            if (dynamicFlag == 1) {
18765
                XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18766
            }
18767
            return 0;
18768
        }
18769
18770
        wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc,
18771
                (WOLFSSL_DES_cblock*)iv, 1);
18772
        XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE),
18773
                DES_BLOCK_SIZE);
18774
18775
        ret = (((*((unsigned char*)out + 4) & 0xFF) << 24)|
18776
               ((*((unsigned char*)out + 5) & 0xFF) << 16)|
18777
               ((*((unsigned char*)out + 6) & 0xFF) << 8) |
18778
               (*((unsigned char*)out + 7) & 0xFF));
18779
18780
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18781
        if (dynamicFlag == 1) {
18782
            XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18783
        }
18784
18785
        return ret;
18786
    }
18787
18788
18789
    void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
18790
                                 unsigned char* output, long length,
18791
                                 WOLFSSL_DES_key_schedule* schedule,
18792
                                 WOLFSSL_DES_cblock* ivec, int enc)
18793
    {
18794
        Des myDes;
18795
        byte lastblock[DES_BLOCK_SIZE];
18796
        int  lb_sz;
18797
        long  blk;
18798
18799
        WOLFSSL_ENTER("DES_cbc_encrypt");
18800
18801
        /* OpenSSL compat, no ret */
18802
        if (wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec,
18803
                !enc) != 0) {
18804
            WOLFSSL_MSG("wc_Des_SetKey return error.");
18805
            return;
18806
        }
18807
        lb_sz = length%DES_BLOCK_SIZE;
18808
        blk   = length/DES_BLOCK_SIZE;
18809
18810
        if (enc == DES_ENCRYPT){
18811
            wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
18812
            if(lb_sz){
18813
                XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
18814
                XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
18815
                wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE,
18816
                    lastblock, (word32)DES_BLOCK_SIZE);
18817
            }
18818
        }
18819
        else {
18820
            wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
18821
            if(lb_sz){
18822
                wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE);
18823
                XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
18824
            }
18825
        }
18826
    }
18827
18828
18829
    /* WOLFSSL_DES_key_schedule is a unsigned char array of size 8 */
18830
    void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input,
18831
                                      unsigned char* output, long sz,
18832
                                      WOLFSSL_DES_key_schedule* ks1,
18833
                                      WOLFSSL_DES_key_schedule* ks2,
18834
                                      WOLFSSL_DES_key_schedule* ks3,
18835
                                      WOLFSSL_DES_cblock* ivec, int enc)
18836
    {
18837
        int ret;
18838
        Des3 des;
18839
        byte key[24];/* EDE uses 24 size key */
18840
        byte lastblock[DES_BLOCK_SIZE];
18841
        int  lb_sz;
18842
        long  blk;
18843
18844
        WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt");
18845
18846
        XMEMSET(key, 0, sizeof(key));
18847
        XMEMCPY(key, *ks1, DES_BLOCK_SIZE);
18848
        XMEMCPY(&key[DES_BLOCK_SIZE], *ks2, DES_BLOCK_SIZE);
18849
        XMEMCPY(&key[DES_BLOCK_SIZE * 2], *ks3, DES_BLOCK_SIZE);
18850
        lb_sz = sz%DES_BLOCK_SIZE;
18851
        blk   = sz/DES_BLOCK_SIZE;
18852
18853
        /* OpenSSL compat, no ret */
18854
        (void)wc_Des3Init(&des, NULL, INVALID_DEVID);
18855
18856
        if (enc == DES_ENCRYPT) {
18857
            if (wc_Des3_SetKey(&des, key, (const byte*)ivec,
18858
                    DES_ENCRYPTION) == 0) {
18859
                ret = wc_Des3_CbcEncrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
18860
            #if defined(WOLFSSL_ASYNC_CRYPT)
18861
                ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18862
            #endif
18863
                (void)ret; /* ignore return codes for processing */
18864
                if(lb_sz){
18865
                    XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
18866
                    XMEMCPY(lastblock, input+sz-lb_sz, lb_sz);
18867
                    ret = wc_Des3_CbcEncrypt(&des, output+blk*DES_BLOCK_SIZE,
18868
                        lastblock, (word32)DES_BLOCK_SIZE);
18869
                #if defined(WOLFSSL_ASYNC_CRYPT)
18870
                    ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18871
                #endif
18872
                    (void)ret; /* ignore return codes for processing */
18873
                }
18874
            }
18875
        }
18876
        else {
18877
            if (wc_Des3_SetKey(&des, key, (const byte*)ivec,
18878
                    DES_DECRYPTION) == 0) {
18879
                ret = wc_Des3_CbcDecrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
18880
            #if defined(WOLFSSL_ASYNC_CRYPT)
18881
                ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18882
            #endif
18883
                (void)ret; /* ignore return codes for processing */
18884
                if(lb_sz){
18885
                    ret = wc_Des3_CbcDecrypt(&des, lastblock, input+sz-lb_sz, (word32)DES_BLOCK_SIZE);
18886
                #if defined(WOLFSSL_ASYNC_CRYPT)
18887
                    ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18888
                #endif
18889
                    (void)ret; /* ignore return codes for processing */
18890
                    XMEMCPY(output+sz-lb_sz, lastblock, lb_sz);
18891
                }
18892
            }
18893
        }
18894
        wc_Des3Free(&des);
18895
    }
18896
18897
18898
    /* correctly sets ivec for next call */
18899
    void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
18900
                     unsigned char* output, long length,
18901
                     WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
18902
                     int enc)
18903
    {
18904
        Des myDes;
18905
        byte lastblock[DES_BLOCK_SIZE];
18906
        int  lb_sz;
18907
        long idx = length;
18908
        long blk;
18909
18910
        WOLFSSL_ENTER("DES_ncbc_encrypt");
18911
18912
        /* OpenSSL compat, no ret */
18913
        if (wc_Des_SetKey(&myDes, (const byte*)schedule,
18914
                         (const byte*)ivec, !enc) != 0) {
18915
            WOLFSSL_MSG("wc_Des_SetKey return error.");
18916
            return;
18917
        }
18918
18919
        lb_sz = length%DES_BLOCK_SIZE;
18920
        blk   = length/DES_BLOCK_SIZE;
18921
        idx  -= sizeof(DES_cblock);
18922
        if (lb_sz) {
18923
            idx += DES_BLOCK_SIZE - lb_sz;
18924
        }
18925
        if (enc == DES_ENCRYPT){
18926
            wc_Des_CbcEncrypt(&myDes, output, input,
18927
                    (word32)blk * DES_BLOCK_SIZE);
18928
            if (lb_sz){
18929
                XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
18930
                XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
18931
                wc_Des_CbcEncrypt(&myDes, output + blk * DES_BLOCK_SIZE,
18932
                    lastblock, (word32)DES_BLOCK_SIZE);
18933
            }
18934
            XMEMCPY(ivec, output + idx, sizeof(DES_cblock));
18935
        } else {
18936
            WOLFSSL_DES_cblock tmp;
18937
            XMEMCPY(tmp, input + idx, sizeof(DES_cblock));
18938
            wc_Des_CbcDecrypt(&myDes, output, input,
18939
                    (word32)blk * DES_BLOCK_SIZE);
18940
            if (lb_sz){
18941
                wc_Des_CbcDecrypt(&myDes, lastblock, input + length - lb_sz,
18942
                        (word32)DES_BLOCK_SIZE);
18943
                XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
18944
            }
18945
            XMEMCPY(ivec, tmp, sizeof(WOLFSSL_DES_cblock));
18946
        }
18947
18948
    }
18949
18950
#endif /* NO_DES3 */
18951
18952
    void wolfSSL_ERR_free_strings(void)
18953
    {
18954
        /* handled internally */
18955
    }
18956
18957
    void wolfSSL_cleanup_all_ex_data(void)
18958
    {
18959
        /* nothing to do here */
18960
    }
18961
18962
#endif /* OPENSSL_EXTRA */
18963
18964
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
18965
    void wolfSSL_ERR_clear_error(void)
18966
    {
18967
        WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
18968
        wc_ClearErrorNodes();
18969
    }
18970
#endif
18971
18972
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
18973
    int wolfSSL_clear(WOLFSSL* ssl)
18974
    {
18975
        WOLFSSL_ENTER("wolfSSL_clear");
18976
18977
        if (ssl == NULL) {
18978
            return WOLFSSL_FAILURE;
18979
        }
18980
18981
        if (!ssl->options.handShakeDone) {
18982
            /* Only reset the session if we didn't complete a handshake */
18983
            wolfSSL_SESSION_free(ssl->session);
18984
            ssl->session = wolfSSL_NewSession(ssl->heap);
18985
            if (ssl->session == NULL) {
18986
                return WOLFSSL_FAILURE;
18987
            }
18988
        }
18989
18990
        /* reset option bits */
18991
        ssl->options.isClosed = 0;
18992
        ssl->options.connReset = 0;
18993
        ssl->options.sentNotify = 0;
18994
        ssl->options.closeNotify = 0;
18995
        ssl->options.sendVerify = 0;
18996
        ssl->options.serverState = NULL_STATE;
18997
        ssl->options.clientState = NULL_STATE;
18998
        ssl->options.connectState = CONNECT_BEGIN;
18999
        ssl->options.acceptState  = ACCEPT_BEGIN;
19000
        ssl->options.handShakeState  = NULL_STATE;
19001
        ssl->options.handShakeDone = 0;
19002
        ssl->options.processReply = 0; /* doProcessInit */
19003
        ssl->options.havePeerVerify = 0;
19004
        ssl->options.havePeerCert = 0;
19005
        ssl->options.peerAuthGood = 0;
19006
        ssl->options.tls1_3 = 0;
19007
        ssl->options.haveSessionId = 0;
19008
        ssl->options.tls = 0;
19009
        ssl->options.tls1_1 = 0;
19010
        ssl->options.noPskDheKe = 0;
19011
    #ifdef HAVE_SESSION_TICKET
19012
        #ifdef WOLFSSL_TLS13
19013
        ssl->options.ticketsSent = 0;
19014
        #endif
19015
        ssl->options.rejectTicket = 0;
19016
    #endif
19017
    #ifdef WOLFSSL_EARLY_DATA
19018
        ssl->earlyData = no_early_data;
19019
        ssl->earlyDataSz = 0;
19020
    #endif
19021
19022
    #if defined(HAVE_TLS_EXTENSIONS) && !defined(NO_TLS)
19023
        TLSX_FreeAll(ssl->extensions, ssl->heap);
19024
        ssl->extensions = NULL;
19025
    #endif
19026
19027
        ssl->keys.encryptionOn = 0;
19028
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
19029
19030
        if (InitSSL_Suites(ssl) != WOLFSSL_SUCCESS)
19031
            return WOLFSSL_FAILURE;
19032
19033
        if (InitHandshakeHashes(ssl) != 0)
19034
            return WOLFSSL_FAILURE;
19035
19036
#ifdef KEEP_PEER_CERT
19037
        FreeX509(&ssl->peerCert);
19038
        InitX509(&ssl->peerCert, 0, ssl->heap);
19039
#endif
19040
19041
#ifdef WOLFSSL_QUIC
19042
        wolfSSL_quic_clear(ssl);
19043
#endif
19044
19045
        return WOLFSSL_SUCCESS;
19046
    }
19047
19048
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
19049
19050
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
19051
    long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
19052
    {
19053
        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
19054
19055
        WOLFSSL_ENTER("SSL_CTX_set_mode");
19056
        switch(mode) {
19057
            case SSL_MODE_ENABLE_PARTIAL_WRITE:
19058
                ctx->partialWrite = 1;
19059
                break;
19060
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19061
            case SSL_MODE_RELEASE_BUFFERS:
19062
                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
19063
                break;
19064
            #endif
19065
            case SSL_MODE_AUTO_RETRY:
19066
                ctx->autoRetry = 1;
19067
                break;
19068
            default:
19069
                WOLFSSL_MSG("Mode Not Implemented");
19070
        }
19071
19072
        /* SSL_MODE_AUTO_RETRY
19073
         * Should not return -1 with renegotiation on read/write */
19074
19075
        return mode;
19076
    }
19077
19078
    long wolfSSL_CTX_clear_mode(WOLFSSL_CTX* ctx, long mode)
19079
    {
19080
        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
19081
19082
        WOLFSSL_ENTER("SSL_CTX_set_mode");
19083
        switch(mode) {
19084
            case SSL_MODE_ENABLE_PARTIAL_WRITE:
19085
                ctx->partialWrite = 0;
19086
                break;
19087
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19088
            case SSL_MODE_RELEASE_BUFFERS:
19089
                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
19090
                break;
19091
            #endif
19092
            case SSL_MODE_AUTO_RETRY:
19093
                ctx->autoRetry = 0;
19094
                break;
19095
            default:
19096
                WOLFSSL_MSG("Mode Not Implemented");
19097
        }
19098
19099
        /* SSL_MODE_AUTO_RETRY
19100
         * Should not return -1 with renegotiation on read/write */
19101
19102
        return 0;
19103
    }
19104
#endif
19105
19106
#ifdef OPENSSL_EXTRA
19107
19108
    #ifndef NO_WOLFSSL_STUB
19109
    long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
19110
    {
19111
        /* TODO: */
19112
        (void)ssl;
19113
        WOLFSSL_STUB("SSL_get_mode");
19114
        return 0;
19115
    }
19116
    #endif
19117
19118
    #ifndef NO_WOLFSSL_STUB
19119
    long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
19120
    {
19121
        /* TODO: */
19122
        (void)ctx;
19123
        WOLFSSL_STUB("SSL_CTX_get_mode");
19124
        return 0;
19125
    }
19126
    #endif
19127
19128
    #ifndef NO_WOLFSSL_STUB
19129
    void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
19130
    {
19131
        /* TODO: maybe? */
19132
        (void)ctx;
19133
        (void)m;
19134
        WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
19135
    }
19136
    #endif
19137
19138
19139
    /* Storing app session context id, this value is inherited by WOLFSSL
19140
     * objects created from WOLFSSL_CTX. Any session that is imported with a
19141
     * different session context id will be rejected.
19142
     *
19143
     * ctx         structure to set context in
19144
     * sid_ctx     value of context to set
19145
     * sid_ctx_len length of sid_ctx buffer
19146
     *
19147
     * Returns WOLFSSL_SUCCESS in success case and SSL_FAILURE when failing
19148
     */
19149
    int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
19150
                                           const unsigned char* sid_ctx,
19151
                                           unsigned int sid_ctx_len)
19152
    {
19153
        WOLFSSL_ENTER("SSL_CTX_set_session_id_context");
19154
19155
        /* No application specific context needed for wolfSSL */
19156
        if (sid_ctx_len > ID_LEN || ctx == NULL || sid_ctx == NULL) {
19157
            return SSL_FAILURE;
19158
        }
19159
        XMEMCPY(ctx->sessionCtx, sid_ctx, sid_ctx_len);
19160
        ctx->sessionCtxSz = (byte)sid_ctx_len;
19161
19162
        return WOLFSSL_SUCCESS;
19163
    }
19164
19165
19166
19167
    /* Storing app session context id. Any session that is imported with a
19168
     * different session context id will be rejected.
19169
     *
19170
     * ssl  structure to set context in
19171
     * id   value of context to set
19172
     * len  length of sid_ctx buffer
19173
     *
19174
     * Returns WOLFSSL_SUCCESS in success case and SSL_FAILURE when failing
19175
     */
19176
    int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
19177
                                   unsigned int len)
19178
    {
19179
        WOLFSSL_ENTER("wolfSSL_set_session_id_context");
19180
19181
        if (len > ID_LEN || ssl == NULL || id == NULL) {
19182
            return SSL_FAILURE;
19183
        }
19184
        XMEMCPY(ssl->sessionCtx, id, len);
19185
        ssl->sessionCtxSz = (byte)len;
19186
19187
        return WOLFSSL_SUCCESS;
19188
    }
19189
19190
19191
    long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
19192
    {
19193
        (void)ctx;
19194
        #ifndef NO_SESSION_CACHE
19195
            return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
19196
        #else
19197
            return 0;
19198
        #endif
19199
    }
19200
19201
19202
    /* returns the unsigned error value and increments the pointer into the
19203
     * error queue.
19204
     *
19205
     * file  pointer to file name
19206
     * line  gets set to line number of error when not NULL
19207
     */
19208
    unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
19209
    {
19210
    #ifdef WOLFSSL_HAVE_ERROR_QUEUE
19211
        int ret = wc_PullErrorNode(file, NULL, line);
19212
        if (ret < 0) {
19213
            if (ret == BAD_STATE_E) return 0; /* no errors in queue */
19214
            WOLFSSL_MSG("Issue getting error node");
19215
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
19216
            ret = 0 - ret; /* return absolute value of error */
19217
19218
            /* panic and try to clear out nodes */
19219
            wc_ClearErrorNodes();
19220
        }
19221
        return (unsigned long)ret;
19222
    #else
19223
        (void)file;
19224
        (void)line;
19225
19226
        return 0;
19227
    #endif
19228
    }
19229
19230
19231
#if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
19232
    (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
19233
    static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
19234
    static const char WOLFSSL_SYS_BIND_T[]    = "bind";
19235
    static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
19236
    static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
19237
    static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
19238
    static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
19239
    static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
19240
    static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
19241
    static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
19242
    static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
19243
    static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
19244
    static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
19245
    static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
19246
    static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
19247
    static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
19248
    static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
19249
19250
    /* switch with int mapped to function name for compatibility */
19251
    static const char* wolfSSL_ERR_sys_func(int fun)
19252
    {
19253
        switch (fun) {
19254
            case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
19255
            case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
19256
            case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
19257
            case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
19258
            case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
19259
            case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
19260
            case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
19261
            case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
19262
            case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
19263
            case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
19264
            case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
19265
            case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
19266
            case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
19267
            case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
19268
            case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
19269
            case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
19270
            default:
19271
                return "NULL";
19272
        }
19273
    }
19274
#endif /* DEBUG_WOLFSSL */
19275
19276
19277
    void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
19278
            int line)
19279
    {
19280
        WOLFSSL_ENTER("wolfSSL_ERR_put_error");
19281
19282
        #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
19283
        (void)fun;
19284
        (void)err;
19285
        (void)file;
19286
        (void)line;
19287
        WOLFSSL_MSG("Not compiled in debug mode");
19288
        #elif defined(OPENSSL_EXTRA) && \
19289
                (defined(_WIN32) || defined(NO_ERROR_QUEUE))
19290
        (void)fun;
19291
        (void)file;
19292
        (void)line;
19293
        WOLFSSL_ERROR(err);
19294
        #else
19295
        WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
19296
            file, NULL);
19297
        #endif
19298
        (void)lib;
19299
    }
19300
19301
19302
    /* Similar to wolfSSL_ERR_get_error_line but takes in a flags argument for
19303
     * more flexibility.
19304
     *
19305
     * file  output pointer to file where error happened
19306
     * line  output to line number of error
19307
     * data  output data. Is a string if ERR_TXT_STRING flag is used
19308
     * flags output format of output
19309
     *
19310
     * Returns the error value or 0 if no errors are in the queue
19311
     */
19312
    unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
19313
                                                  const char** data, int *flags)
19314
    {
19315
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
19316
        int ret;
19317
19318
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
19319
19320
        if (flags != NULL)
19321
            *flags = ERR_TXT_STRING; /* Clear the flags */
19322
19323
        ret = wc_PullErrorNode(file, data, line);
19324
        if (ret < 0) {
19325
            if (ret == BAD_STATE_E) return 0; /* no errors in queue */
19326
            WOLFSSL_MSG("Error with pulling error node!");
19327
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
19328
            ret = 0 - ret; /* return absolute value of error */
19329
19330
            /* panic and try to clear out nodes */
19331
            wc_ClearErrorNodes();
19332
        }
19333
19334
        return (unsigned long)ret;
19335
#else
19336
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
19337
        WOLFSSL_MSG("Error queue turned off, can not get error line");
19338
        (void)file;
19339
        (void)line;
19340
        (void)data;
19341
        (void)flags;
19342
        return 0;
19343
#endif
19344
    }
19345
19346
#endif /* OPENSSL_EXTRA */
19347
19348
19349
#if (defined(KEEP_PEER_CERT) && defined(SESSION_CERTS)) || \
19350
    (defined(OPENSSL_EXTRA) && defined(SESSION_CERTS))
19351
    /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
19352
     *
19353
     * x509  WOLFSSL_X509 object to decode into.
19354
     * in    X509 DER data.
19355
     * len   Length of the X509 DER data.
19356
     * returns the new certificate on success, otherwise NULL.
19357
     */
19358
    static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
19359
    {
19360
        int          ret;
19361
    #ifdef WOLFSSL_SMALL_STACK
19362
        DecodedCert* cert;
19363
    #else
19364
        DecodedCert  cert[1];
19365
    #endif
19366
        if (x509 == NULL || in == NULL || len <= 0)
19367
            return BAD_FUNC_ARG;
19368
19369
    #ifdef WOLFSSL_SMALL_STACK
19370
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
19371
                                     DYNAMIC_TYPE_DCERT);
19372
        if (cert == NULL)
19373
            return MEMORY_E;
19374
    #endif
19375
19376
        /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
19377
         */
19378
        InitDecodedCert(cert, (byte*)in, len, NULL);
19379
        if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) {
19380
        /* Check if x509 was not previously initialized by wolfSSL_X509_new() */
19381
            if (x509->dynamicMemory != TRUE)
19382
                InitX509(x509, 0, NULL);
19383
            ret = CopyDecodedToX509(x509, cert);
19384
            FreeDecodedCert(cert);
19385
        }
19386
    #ifdef WOLFSSL_SMALL_STACK
19387
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
19388
    #endif
19389
19390
        return ret;
19391
    }
19392
#endif /* (KEEP_PEER_CERT & SESSION_CERTS) || (OPENSSL_EXTRA & SESSION_CERTS) */
19393
19394
19395
#ifdef KEEP_PEER_CERT
19396
    WOLFSSL_ABI
19397
    WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
19398
    {
19399
        WOLFSSL_X509* ret = NULL;
19400
        WOLFSSL_ENTER("SSL_get_peer_certificate");
19401
        if (ssl != NULL) {
19402
            if (ssl->peerCert.issuer.sz)
19403
                ret = wolfSSL_X509_dup(&ssl->peerCert);
19404
#ifdef SESSION_CERTS
19405
            else if (ssl->session->chain.count > 0) {
19406
                if (DecodeToX509(&ssl->peerCert, ssl->session->chain.certs[0].buffer,
19407
                        ssl->session->chain.certs[0].length) == 0) {
19408
                    ret = wolfSSL_X509_dup(&ssl->peerCert);
19409
                }
19410
            }
19411
#endif
19412
        }
19413
        WOLFSSL_LEAVE("SSL_get_peer_certificate", ret != NULL);
19414
        return ret;
19415
    }
19416
19417
#endif /* KEEP_PEER_CERT */
19418
19419
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
19420
/* Return stack of peer certs.
19421
 * Caller does not need to free return. The stack is Free'd when WOLFSSL* ssl is.
19422
 */
19423
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
19424
{
19425
    WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
19426
19427
    if (ssl == NULL)
19428
        return NULL;
19429
19430
    /* Try to populate if NULL or empty */
19431
    if (ssl->peerCertChain == NULL ||
19432
            wolfSSL_sk_X509_num(ssl->peerCertChain) == 0)
19433
        wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl);
19434
    return ssl->peerCertChain;
19435
}
19436
19437
#ifndef WOLFSSL_QT
19438
static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
19439
        WOLFSSL_X509 *x);
19440
/**
19441
 * Recursively push the issuer CA chain onto the stack
19442
 * @param cm The cert manager that is queried for the issuer
19443
 * @param x  This cert's issuer will be queried in cm
19444
 * @param sk The issuer is pushed onto this stack
19445
 * @return WOLFSSL_SUCCESS on success
19446
 *         WOLFSSL_FAILURE on no issuer found
19447
 *         WOLFSSL_FATAL_ERROR on a fatal error
19448
 */
19449
static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm,
19450
        WOLFSSL_X509 *x, WOLFSSL_STACK* sk)
19451
{
19452
    WOLFSSL_X509* issuer[MAX_CHAIN_DEPTH];
19453
    int i;
19454
    int push = 1;
19455
    int ret = WOLFSSL_SUCCESS;
19456
19457
    for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
19458
        if (x509GetIssuerFromCM(&issuer[i], cm, x)
19459
                != WOLFSSL_SUCCESS)
19460
            break;
19461
        x = issuer[i];
19462
    }
19463
    if (i == 0) /* No further chain found */
19464
        return WOLFSSL_FAILURE;
19465
    i--;
19466
    for (; i >= 0; i--) {
19467
        if (push) {
19468
            if (wolfSSL_sk_X509_push(sk, issuer[i]) != WOLFSSL_SUCCESS) {
19469
                wolfSSL_X509_free(issuer[i]);
19470
                ret = WOLFSSL_FATAL_ERROR;
19471
                push = 0; /* Free the rest of the unpushed certs */
19472
            }
19473
        }
19474
        else {
19475
            wolfSSL_X509_free(issuer[i]);
19476
        }
19477
    }
19478
    return ret;
19479
}
19480
#endif /* !WOLFSSL_QT */
19481
19482
/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
19483
    based off of the ssl session chain. Attempts to place CA certificates
19484
    at the bottom of the stack. Returns stack of WOLFSSL_X509 certs or
19485
    NULL on failure */
19486
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
19487
{
19488
    WOLFSSL_STACK* sk;
19489
    WOLFSSL_X509* x509;
19490
    int i = 0;
19491
    int ret;
19492
19493
    WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
19494
    if ((ssl == NULL) || (ssl->session->chain.count == 0))
19495
        return NULL;
19496
19497
    sk = wolfSSL_sk_X509_new_null();
19498
    i = ssl->session->chain.count-1;
19499
    for (; i >= 0; i--) {
19500
        x509 = wolfSSL_X509_new();
19501
        if (x509 == NULL) {
19502
            WOLFSSL_MSG("Error Creating X509");
19503
            wolfSSL_sk_X509_pop_free(sk, NULL);
19504
            return NULL;
19505
        }
19506
        ret = DecodeToX509(x509, ssl->session->chain.certs[i].buffer,
19507
                             ssl->session->chain.certs[i].length);
19508
#if !defined(WOLFSSL_QT)
19509
        if (ret == 0 && i == ssl->session->chain.count-1) {
19510
            /* On the last element in the chain try to add the CA chain
19511
             * first if we have one for this cert */
19512
            if (PushCAx509Chain(SSL_CM(ssl), x509, sk)
19513
                    == WOLFSSL_FATAL_ERROR) {
19514
                ret = WOLFSSL_FATAL_ERROR;
19515
            }
19516
        }
19517
#endif
19518
19519
        if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) {
19520
            WOLFSSL_MSG("Error decoding cert");
19521
            wolfSSL_X509_free(x509);
19522
            wolfSSL_sk_X509_pop_free(sk, NULL);
19523
            return NULL;
19524
        }
19525
    }
19526
19527
    if (sk == NULL) {
19528
        WOLFSSL_MSG("Null session chain");
19529
    }
19530
#if defined(OPENSSL_ALL)
19531
    else if (ssl->options.side == WOLFSSL_SERVER_END) {
19532
        /* to be compliant with openssl
19533
           first element is kept as peer cert on server side.*/
19534
        wolfSSL_sk_X509_pop(sk);
19535
    }
19536
#endif
19537
    if (ssl->peerCertChain != NULL)
19538
        wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
19539
    /* This is Free'd when ssl is Free'd */
19540
    ssl->peerCertChain = sk;
19541
    return sk;
19542
}
19543
#endif /* SESSION_CERTS && OPENSSL_EXTRA */
19544
19545
#ifndef NO_CERTS
19546
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
19547
19548
/* create a generic wolfSSL stack node
19549
 * returns a new WOLFSSL_STACK structure on success */
19550
WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap)
19551
{
19552
    WOLFSSL_STACK* sk;
19553
    WOLFSSL_ENTER("wolfSSL_sk_new_node");
19554
19555
    sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), heap,
19556
                                                          DYNAMIC_TYPE_OPENSSL);
19557
    if (sk != NULL) {
19558
        XMEMSET(sk, 0, sizeof(*sk));
19559
        sk->heap = heap;
19560
    }
19561
19562
    return sk;
19563
}
19564
19565
/* free's node but does not free internal data such as in->data.x509 */
19566
void wolfSSL_sk_free_node(WOLFSSL_STACK* in)
19567
{
19568
    if (in != NULL) {
19569
        XFREE(in, in->heap, DYNAMIC_TYPE_OPENSSL);
19570
    }
19571
}
19572
19573
/* pushes node "in" onto "stack" and returns pointer to the new stack on success
19574
 * also handles internal "num" for number of nodes on stack
19575
 * return WOLFSSL_SUCCESS on success
19576
 */
19577
int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in)
19578
{
19579
    if (stack == NULL || in == NULL) {
19580
        return WOLFSSL_FAILURE;
19581
    }
19582
19583
    if (*stack == NULL) {
19584
        in->num = 1;
19585
        *stack = in;
19586
        return WOLFSSL_SUCCESS;
19587
    }
19588
19589
    in->num  = (*stack)->num + 1;
19590
    in->next = *stack;
19591
    *stack   = in;
19592
    return WOLFSSL_SUCCESS;
19593
}
19594
19595
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19596
static WC_INLINE int compare_WOLFSSL_CIPHER(
19597
    WOLFSSL_CIPHER *a,
19598
    WOLFSSL_CIPHER *b)
19599
{
19600
    if ((a->cipherSuite0 == b->cipherSuite0) &&
19601
        (a->cipherSuite == b->cipherSuite) &&
19602
        (a->ssl == b->ssl) &&
19603
        (XMEMCMP(a->description, b->description, sizeof a->description) == 0) &&
19604
        (a->offset == b->offset) &&
19605
        (a->in_stack == b->in_stack) &&
19606
        (a->bits == b->bits))
19607
        return 0;
19608
    else
19609
        return -1;
19610
}
19611
#endif /* OPENSSL_ALL || WOLFSSL_QT */
19612
19613
19614
/* return 1 on success 0 on fail */
19615
int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data)
19616
{
19617
    WOLFSSL_STACK* node;
19618
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19619
    WOLFSSL_CIPHER ciph;
19620
#endif
19621
    WOLFSSL_ENTER("wolfSSL_sk_push");
19622
19623
    if (!sk) {
19624
        return WOLFSSL_FAILURE;
19625
    }
19626
19627
    /* Check if empty data */
19628
    switch (sk->type) {
19629
        case STACK_TYPE_CIPHER:
19630
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19631
            /* check if entire struct is zero */
19632
            XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER));
19633
            if (compare_WOLFSSL_CIPHER(&sk->data.cipher, &ciph) == 0) {
19634
                sk->data.cipher = *(WOLFSSL_CIPHER*)data;
19635
                sk->num = 1;
19636
                if (sk->hash_fn) {
19637
                    sk->hash = sk->hash_fn(&sk->data.cipher);
19638
                }
19639
                return WOLFSSL_SUCCESS;
19640
            }
19641
            break;
19642
#endif
19643
        case STACK_TYPE_X509:
19644
        case STACK_TYPE_GEN_NAME:
19645
        case STACK_TYPE_BIO:
19646
        case STACK_TYPE_OBJ:
19647
        case STACK_TYPE_STRING:
19648
        case STACK_TYPE_ACCESS_DESCRIPTION:
19649
        case STACK_TYPE_X509_EXT:
19650
        case STACK_TYPE_X509_REQ_ATTR:
19651
        case STACK_TYPE_NULL:
19652
        case STACK_TYPE_X509_NAME:
19653
        case STACK_TYPE_X509_NAME_ENTRY:
19654
        case STACK_TYPE_CONF_VALUE:
19655
        case STACK_TYPE_X509_INFO:
19656
        case STACK_TYPE_BY_DIR_entry:
19657
        case STACK_TYPE_BY_DIR_hash:
19658
        case STACK_TYPE_X509_OBJ:
19659
        case STACK_TYPE_DIST_POINT:
19660
        case STACK_TYPE_X509_CRL:
19661
        default:
19662
            /* All other types are pointers */
19663
            if (!sk->data.generic) {
19664
                sk->data.generic = (void*)data;
19665
                sk->num = 1;
19666
#ifdef OPENSSL_ALL
19667
                if (sk->hash_fn) {
19668
                    sk->hash = sk->hash_fn(sk->data.generic);
19669
                }
19670
#endif
19671
                return WOLFSSL_SUCCESS;
19672
            }
19673
            break;
19674
    }
19675
19676
    /* stack already has value(s) create a new node and add more */
19677
    node = wolfSSL_sk_new_node(sk->heap);
19678
    if (!node) {
19679
        WOLFSSL_MSG("Memory error");
19680
        return WOLFSSL_FAILURE;
19681
    }
19682
19683
    /* push new x509 onto head of stack */
19684
    node->next      = sk->next;
19685
    node->type      = sk->type;
19686
    sk->next        = node;
19687
    sk->num        += 1;
19688
19689
#ifdef OPENSSL_ALL
19690
    node->hash_fn = sk->hash_fn;
19691
    node->hash = sk->hash;
19692
    sk->hash = 0;
19693
#endif
19694
    switch (sk->type) {
19695
        case STACK_TYPE_CIPHER:
19696
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19697
            node->data.cipher = sk->data.cipher;
19698
            sk->data.cipher = *(WOLFSSL_CIPHER*)data;
19699
            if (sk->hash_fn) {
19700
                sk->hash = sk->hash_fn(&sk->data.cipher);
19701
            }
19702
            break;
19703
#endif
19704
        case STACK_TYPE_X509:
19705
        case STACK_TYPE_GEN_NAME:
19706
        case STACK_TYPE_BIO:
19707
        case STACK_TYPE_OBJ:
19708
        case STACK_TYPE_STRING:
19709
        case STACK_TYPE_ACCESS_DESCRIPTION:
19710
        case STACK_TYPE_X509_EXT:
19711
        case STACK_TYPE_X509_REQ_ATTR:
19712
        case STACK_TYPE_NULL:
19713
        case STACK_TYPE_X509_NAME:
19714
        case STACK_TYPE_X509_NAME_ENTRY:
19715
        case STACK_TYPE_CONF_VALUE:
19716
        case STACK_TYPE_X509_INFO:
19717
        case STACK_TYPE_BY_DIR_entry:
19718
        case STACK_TYPE_BY_DIR_hash:
19719
        case STACK_TYPE_X509_OBJ:
19720
        case STACK_TYPE_DIST_POINT:
19721
        case STACK_TYPE_X509_CRL:
19722
        default:
19723
            /* All other types are pointers */
19724
            node->data.generic = sk->data.generic;
19725
            sk->data.generic = (void*)data;
19726
#ifdef OPENSSL_ALL
19727
            if (sk->hash_fn) {
19728
                sk->hash = sk->hash_fn(sk->data.generic);
19729
            }
19730
#endif
19731
            break;
19732
    }
19733
19734
    return WOLFSSL_SUCCESS;
19735
}
19736
19737
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
19738
19739
#ifdef OPENSSL_EXTRA
19740
19741
/* returns the node at index "idx", NULL if not found */
19742
WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx)
19743
{
19744
    int i;
19745
    WOLFSSL_STACK* ret = NULL;
19746
    WOLFSSL_STACK* current;
19747
19748
    current = sk;
19749
    for (i = 0; i <= idx && current != NULL; i++) {
19750
        if (i == idx) {
19751
            ret = current;
19752
            break;
19753
        }
19754
        current = current->next;
19755
    }
19756
    return ret;
19757
}
19758
19759
19760
#endif /* OPENSSL_EXTRA */
19761
19762
#ifdef OPENSSL_EXTRA
19763
19764
#if defined(OPENSSL_ALL)
19765
19766
void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data)
19767
{
19768
    unsigned long hash;
19769
19770
    WOLFSSL_ENTER("wolfSSL_lh_retrieve");
19771
19772
    if (!sk || !data) {
19773
        WOLFSSL_MSG("Bad parameters");
19774
        return NULL;
19775
    }
19776
19777
    if (!sk->hash_fn) {
19778
        WOLFSSL_MSG("No hash function defined");
19779
        return NULL;
19780
    }
19781
19782
    hash = sk->hash_fn(data);
19783
19784
    while (sk) {
19785
        /* Calc hash if not done so yet */
19786
        if (!sk->hash) {
19787
            switch (sk->type) {
19788
                case STACK_TYPE_CIPHER:
19789
                    sk->hash = sk->hash_fn(&sk->data.cipher);
19790
                    break;
19791
                case STACK_TYPE_X509:
19792
                case STACK_TYPE_GEN_NAME:
19793
                case STACK_TYPE_BIO:
19794
                case STACK_TYPE_OBJ:
19795
                case STACK_TYPE_STRING:
19796
                case STACK_TYPE_ACCESS_DESCRIPTION:
19797
                case STACK_TYPE_X509_EXT:
19798
                case STACK_TYPE_X509_REQ_ATTR:
19799
                case STACK_TYPE_NULL:
19800
                case STACK_TYPE_X509_NAME:
19801
                case STACK_TYPE_X509_NAME_ENTRY:
19802
                case STACK_TYPE_CONF_VALUE:
19803
                case STACK_TYPE_X509_INFO:
19804
                case STACK_TYPE_BY_DIR_entry:
19805
                case STACK_TYPE_BY_DIR_hash:
19806
                case STACK_TYPE_X509_OBJ:
19807
                case STACK_TYPE_DIST_POINT:
19808
                case STACK_TYPE_X509_CRL:
19809
                default:
19810
                    sk->hash = sk->hash_fn(sk->data.generic);
19811
                    break;
19812
            }
19813
        }
19814
        if (sk->hash == hash) {
19815
            switch (sk->type) {
19816
                case STACK_TYPE_CIPHER:
19817
                    return &sk->data.cipher;
19818
                case STACK_TYPE_X509:
19819
                case STACK_TYPE_GEN_NAME:
19820
                case STACK_TYPE_BIO:
19821
                case STACK_TYPE_OBJ:
19822
                case STACK_TYPE_STRING:
19823
                case STACK_TYPE_ACCESS_DESCRIPTION:
19824
                case STACK_TYPE_X509_EXT:
19825
                case STACK_TYPE_X509_REQ_ATTR:
19826
                case STACK_TYPE_NULL:
19827
                case STACK_TYPE_X509_NAME:
19828
                case STACK_TYPE_X509_NAME_ENTRY:
19829
                case STACK_TYPE_CONF_VALUE:
19830
                case STACK_TYPE_X509_INFO:
19831
                case STACK_TYPE_BY_DIR_entry:
19832
                case STACK_TYPE_BY_DIR_hash:
19833
                case STACK_TYPE_X509_OBJ:
19834
                case STACK_TYPE_DIST_POINT:
19835
                case STACK_TYPE_X509_CRL:
19836
                default:
19837
                    return sk->data.generic;
19838
            }
19839
        }
19840
        sk = sk->next;
19841
    }
19842
19843
    return NULL;
19844
}
19845
19846
#endif /* OPENSSL_ALL */
19847
19848
#endif /* OPENSSL_EXTRA */
19849
19850
/* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
19851
   KEEP_OUR_CERT is to insure ability for returning ssl certificate */
19852
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
19853
    defined(KEEP_OUR_CERT)
19854
WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
19855
{
19856
    if (ssl == NULL) {
19857
        return NULL;
19858
    }
19859
19860
    if (ssl->buffers.weOwnCert) {
19861
        if (ssl->ourCert == NULL) {
19862
            if (ssl->buffers.certificate == NULL) {
19863
                WOLFSSL_MSG("Certificate buffer not set!");
19864
                return NULL;
19865
            }
19866
            #ifndef WOLFSSL_X509_STORE_CERTS
19867
            ssl->ourCert = wolfSSL_X509_d2i(NULL,
19868
                                              ssl->buffers.certificate->buffer,
19869
                                              ssl->buffers.certificate->length);
19870
            #endif
19871
        }
19872
        return ssl->ourCert;
19873
    }
19874
    else { /* if cert not owned get parent ctx cert or return null */
19875
        if (ssl->ctx) {
19876
            if (ssl->ctx->ourCert == NULL) {
19877
                if (ssl->ctx->certificate == NULL) {
19878
                    WOLFSSL_MSG("Ctx Certificate buffer not set!");
19879
                    return NULL;
19880
                }
19881
                #ifndef WOLFSSL_X509_STORE_CERTS
19882
                ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
19883
                                               ssl->ctx->certificate->buffer,
19884
                                               ssl->ctx->certificate->length);
19885
                #endif
19886
                ssl->ctx->ownOurCert = 1;
19887
            }
19888
            return ssl->ctx->ourCert;
19889
        }
19890
    }
19891
19892
    return NULL;
19893
}
19894
19895
WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx)
19896
{
19897
    if (ctx) {
19898
        if (ctx->ourCert == NULL) {
19899
            if (ctx->certificate == NULL) {
19900
                WOLFSSL_MSG("Ctx Certificate buffer not set!");
19901
                return NULL;
19902
            }
19903
            #ifndef WOLFSSL_X509_STORE_CERTS
19904
            ctx->ourCert = wolfSSL_X509_d2i(NULL,
19905
                                           ctx->certificate->buffer,
19906
                                           ctx->certificate->length);
19907
            #endif
19908
            ctx->ownOurCert = 1;
19909
        }
19910
        return ctx->ourCert;
19911
    }
19912
    return NULL;
19913
}
19914
#endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
19915
#endif /* NO_CERTS */
19916
19917
19918
#if !defined(NO_ASN) && (defined(OPENSSL_EXTRA) || \
19919
        defined(OPENSSL_EXTRA_X509_SMALL))
19920
void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj)
19921
{
19922
    if (obj == NULL) {
19923
        return;
19924
    }
19925
    if ((obj->obj != NULL) && ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0)) {
19926
#ifdef WOLFSSL_DEBUG_OPENSSL
19927
        WOLFSSL_MSG("Freeing ASN1 data");
19928
#endif
19929
        XFREE((void*)obj->obj, obj->heap, DYNAMIC_TYPE_ASN1);
19930
        obj->obj = NULL;
19931
    }
19932
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
19933
    if (obj->pathlen != NULL) {
19934
        wolfSSL_ASN1_INTEGER_free(obj->pathlen);
19935
        obj->pathlen = NULL;
19936
    }
19937
    #endif
19938
    if ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC) != 0) {
19939
#ifdef WOLFSSL_DEBUG_OPENSSL
19940
        WOLFSSL_MSG("Freeing ASN1 OBJECT");
19941
#endif
19942
        XFREE(obj, NULL, DYNAMIC_TYPE_ASN1);
19943
    }
19944
}
19945
19946
WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void)
19947
{
19948
    WOLFSSL_ASN1_OBJECT* obj;
19949
19950
    obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL,
19951
                                        DYNAMIC_TYPE_ASN1);
19952
    if (obj == NULL) {
19953
        return NULL;
19954
    }
19955
19956
    XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT));
19957
    obj->d.ia5 = &(obj->d.ia5_internal);
19958
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
19959
    obj->d.iPAddress = &(obj->d.iPAddress_internal);
19960
#endif
19961
    obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
19962
    return obj;
19963
}
19964
19965
WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_dup(WOLFSSL_ASN1_OBJECT* obj)
19966
{
19967
    WOLFSSL_ASN1_OBJECT* dupl = NULL;
19968
19969
    WOLFSSL_ENTER("wolfSSL_ASN1_OBJECT_dup");
19970
19971
    if (!obj) {
19972
        WOLFSSL_MSG("Bad parameter");
19973
        return NULL;
19974
    }
19975
    dupl = wolfSSL_ASN1_OBJECT_new();
19976
    if (!dupl) {
19977
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error");
19978
        return NULL;
19979
    }
19980
    /* Copy data */
19981
    XMEMCPY(dupl->sName, obj->sName, WOLFSSL_MAX_SNAME);
19982
    dupl->type = obj->type;
19983
    dupl->grp = obj->grp;
19984
    dupl->nid = obj->nid;
19985
    dupl->objSz = obj->objSz;
19986
    if (obj->obj) {
19987
        dupl->obj = (const unsigned char*)XMALLOC(
19988
                obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
19989
        if (!dupl->obj) {
19990
            WOLFSSL_MSG("ASN1 obj malloc error");
19991
            wolfSSL_ASN1_OBJECT_free(dupl);
19992
            return NULL;
19993
        }
19994
        XMEMCPY((byte*)dupl->obj, obj->obj, obj->objSz);
19995
        dupl->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
19996
    }
19997
    return dupl;
19998
}
19999
#endif /* !NO_ASN && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
20000
20001
#ifndef NO_ASN
20002
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
20003
/* Creates and returns a new WOLFSSL_CIPHER stack. */
20004
WOLFSSL_STACK* wolfSSL_sk_new_asn1_obj(void)
20005
{
20006
    WOLFSSL_STACK* sk;
20007
    WOLFSSL_ENTER("wolfSSL_sk_new_asn1_obj");
20008
20009
    sk = wolfSSL_sk_new_null();
20010
    if (sk == NULL)
20011
        return NULL;
20012
    sk->type = STACK_TYPE_OBJ;
20013
20014
    return sk;
20015
}
20016
20017
/* return 1 on success 0 on fail */
20018
int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
20019
                                              WOLFSSL_ASN1_OBJECT* obj)
20020
{
20021
    WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_push");
20022
20023
    if (sk == NULL || obj == NULL) {
20024
        return WOLFSSL_FAILURE;
20025
    }
20026
20027
    return wolfSSL_sk_push(sk, obj);
20028
}
20029
20030
20031
WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop(
20032
                                        WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
20033
{
20034
    WOLFSSL_STACK* node;
20035
    WOLFSSL_ASN1_OBJECT* obj;
20036
20037
    if (sk == NULL) {
20038
        return NULL;
20039
    }
20040
20041
    node = sk->next;
20042
    obj = sk->data.obj;
20043
20044
    if (node != NULL) { /* update sk and remove node from stack */
20045
        sk->data.obj = node->data.obj;
20046
        sk->next = node->next;
20047
        XFREE(node, NULL, DYNAMIC_TYPE_ASN1);
20048
    }
20049
    else { /* last obj in stack */
20050
        sk->data.obj = NULL;
20051
    }
20052
20053
    if (sk->num > 0) {
20054
        sk->num -= 1;
20055
    }
20056
20057
    return obj;
20058
}
20059
20060
20061
/* Free the structure for ASN1_OBJECT stack
20062
 *
20063
 * sk  stack to free nodes in
20064
 */
20065
void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
20066
{
20067
    wolfSSL_sk_free(sk);
20068
}
20069
20070
/* Free's all nodes in ASN1_OBJECT stack.
20071
 * This is different then wolfSSL_ASN1_OBJECT_free in that it allows for
20072
 * choosing the function to use when freeing an ASN1_OBJECT stack.
20073
 *
20074
 * sk  stack to free nodes in
20075
 * f   X509 free function
20076
 */
20077
void wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
20078
                                     void (*f) (WOLFSSL_ASN1_OBJECT*))
20079
{
20080
    WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_pop_free");
20081
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
20082
}
20083
20084
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
20085
#endif /* !NO_ASN */
20086
20087
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
20088
#ifndef NO_ASN
20089
20090
int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in)
20091
{
20092
    /*
20093
       ASN1_STRING_to_UTF8() converts the string in to UTF8 format,
20094
       the converted data is allocated in a buffer in *out.
20095
       The length of out is returned or a negative error code.
20096
       The buffer *out should be free using OPENSSL_free().
20097
       */
20098
    unsigned char* buf;
20099
    unsigned char* inPtr;
20100
    int inLen;
20101
20102
    if (!out || !in) {
20103
        return -1;
20104
    }
20105
20106
    inPtr = wolfSSL_ASN1_STRING_data(in);
20107
    inLen = wolfSSL_ASN1_STRING_length(in);
20108
    if (!inPtr || inLen < 0) {
20109
        return -1;
20110
    }
20111
    buf = (unsigned char*)XMALLOC(inLen + 1, NULL, DYNAMIC_TYPE_OPENSSL);
20112
    if (!buf) {
20113
        return -1;
20114
    }
20115
    XMEMCPY(buf, inPtr, inLen + 1);
20116
    *out = buf;
20117
    return inLen;
20118
}
20119
#endif /* !NO_ASN */
20120
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
20121
20122
#if defined(OPENSSL_EXTRA)
20123
#ifndef NO_ASN
20124
20125
int wolfSSL_ASN1_UNIVERSALSTRING_to_string(WOLFSSL_ASN1_STRING *s)
20126
{
20127
    char *idx;
20128
    char *copy;
20129
    WOLFSSL_ENTER("wolfSSL_ASN1_UNIVERSALSTRING_to_string");
20130
20131
    if (!s) {
20132
        WOLFSSL_MSG("Bad parameter");
20133
        return WOLFSSL_FAILURE;
20134
    }
20135
20136
    if (s->type != V_ASN1_UNIVERSALSTRING) {
20137
        WOLFSSL_MSG("Input is not a universal string");
20138
        return WOLFSSL_FAILURE;
20139
    }
20140
20141
    if ((s->length % 4) != 0) {
20142
        WOLFSSL_MSG("Input string must be divisible by 4");
20143
        return WOLFSSL_FAILURE;
20144
    }
20145
20146
    for (idx = s->data; idx < s->data + s->length; idx += 4)
20147
        if ((idx[0] != '\0') || (idx[1] != '\0') || (idx[2] != '\0'))
20148
            break;
20149
20150
    if (idx != s->data + s->length) {
20151
        WOLFSSL_MSG("Wrong string format");
20152
        return WOLFSSL_FAILURE;
20153
    }
20154
20155
    for (copy = idx = s->data; idx < s->data + s->length; idx += 4)
20156
        *copy++ = idx[3];
20157
    *copy = '\0';
20158
    s->length /= 4;
20159
    s->type = V_ASN1_PRINTABLESTRING;
20160
    return WOLFSSL_SUCCESS;
20161
}
20162
20163
/* Returns string representation of ASN1_STRING */
20164
char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method,
20165
    const WOLFSSL_ASN1_STRING *s)
20166
{
20167
    int i;
20168
    int tmpSz = 100;
20169
    int valSz = 5;
20170
    char* tmp;
20171
    char val[5];
20172
    unsigned char* str;
20173
20174
    WOLFSSL_ENTER("wolfSSL_i2s_ASN1_STRING");
20175
    (void)method;
20176
20177
    if(s == NULL || s->data == NULL) {
20178
        WOLFSSL_MSG("Bad Function Argument");
20179
        return NULL;
20180
    }
20181
    str = (unsigned char*)XMALLOC(s->length, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20182
    if (str == NULL) {
20183
        WOLFSSL_MSG("Memory Error");
20184
        return NULL;
20185
    }
20186
    XMEMCPY(str, (unsigned char*)s->data, s->length);
20187
20188
    tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20189
    if (tmp == NULL) {
20190
        WOLFSSL_MSG("Memory Error");
20191
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20192
        return NULL;
20193
    }
20194
    XMEMSET(tmp, 0, tmpSz);
20195
20196
    for (i = 0; i < tmpSz && i < (s->length - 1); i++) {
20197
        if (XSNPRINTF(val, valSz, "%02X:", str[i])
20198
            >= valSz)
20199
        {
20200
            WOLFSSL_MSG("Buffer overrun");
20201
            XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20202
            return NULL;
20203
        }
20204
        XSTRNCAT(tmp, val, valSz);
20205
    }
20206
    if (XSNPRINTF(val, valSz, "%02X", str[i])
20207
        >= valSz)
20208
    {
20209
        WOLFSSL_MSG("Buffer overrun");
20210
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20211
        return NULL;
20212
    }
20213
20214
    XSTRNCAT(tmp, val, valSz);
20215
    XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
20216
20217
    return tmp;
20218
}
20219
#endif /* NO_ASN */
20220
#endif /* OPENSSL_EXTRA */
20221
20222
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
20223
void wolfSSL_set_connect_state(WOLFSSL* ssl)
20224
{
20225
    WOLFSSL_ENTER("wolfSSL_set_connect_state");
20226
    if (ssl == NULL) {
20227
        WOLFSSL_MSG("WOLFSSL struct pointer passed in was null");
20228
        return;
20229
    }
20230
20231
    #ifndef NO_DH
20232
    /* client creates its own DH parameters on handshake */
20233
    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
20234
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
20235
            DYNAMIC_TYPE_PUBLIC_KEY);
20236
    }
20237
    ssl->buffers.serverDH_P.buffer = NULL;
20238
    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
20239
        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
20240
            DYNAMIC_TYPE_PUBLIC_KEY);
20241
    }
20242
    ssl->buffers.serverDH_G.buffer = NULL;
20243
    #endif
20244
20245
    if (InitSSL_Side(ssl, WOLFSSL_CLIENT_END) != WOLFSSL_SUCCESS) {
20246
        WOLFSSL_MSG("Error initializing client side");
20247
    }
20248
}
20249
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
20250
20251
20252
int wolfSSL_get_shutdown(const WOLFSSL* ssl)
20253
0
{
20254
0
    int isShutdown = 0;
20255
20256
0
    WOLFSSL_ENTER("wolfSSL_get_shutdown");
20257
20258
0
    if (ssl) {
20259
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
20260
        if (ssl->options.handShakeState == NULL_STATE) {
20261
            /* The SSL object was possibly cleared with wolfSSL_clear after
20262
             * a successful shutdown. Simulate a response for a full
20263
             * bidirectional shutdown. */
20264
            isShutdown = WOLFSSL_SENT_SHUTDOWN | WOLFSSL_RECEIVED_SHUTDOWN;
20265
        }
20266
        else
20267
#endif
20268
0
        {
20269
            /* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
20270
             * WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
20271
0
            if (ssl->options.sentNotify)
20272
0
                isShutdown |= WOLFSSL_SENT_SHUTDOWN;
20273
0
            if (ssl->options.closeNotify||ssl->options.connReset)
20274
0
                isShutdown |= WOLFSSL_RECEIVED_SHUTDOWN;
20275
0
        }
20276
20277
0
    }
20278
0
    return isShutdown;
20279
0
}
20280
20281
20282
int wolfSSL_session_reused(WOLFSSL* ssl)
20283
0
{
20284
0
    int resuming = 0;
20285
0
    WOLFSSL_ENTER("wolfSSL_session_reused");
20286
0
    if (ssl)
20287
0
        resuming = ssl->options.resuming;
20288
0
    WOLFSSL_LEAVE("wolfSSL_session_reused", resuming);
20289
0
    return resuming;
20290
0
}
20291
20292
/* return a new malloc'd session with default settings on success */
20293
WOLFSSL_SESSION* wolfSSL_NewSession(void* heap)
20294
0
{
20295
0
    WOLFSSL_SESSION* ret = NULL;
20296
20297
0
    ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), heap,
20298
0
            DYNAMIC_TYPE_SESSION);
20299
0
    if (ret != NULL) {
20300
0
        XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION));
20301
0
    #ifndef SINGLE_THREADED
20302
0
        if (wc_InitMutex(&ret->refMutex) != 0) {
20303
0
            WOLFSSL_MSG("Error setting up session reference mutex");
20304
0
            XFREE(ret, ret->heap, DYNAMIC_TYPE_SESSION);
20305
0
            return NULL;
20306
0
        }
20307
0
    #endif
20308
0
        ret->refCount = 1;
20309
0
#ifndef NO_SESSION_CACHE
20310
0
        ret->cacheRow = INVALID_SESSION_ROW; /* not in cache */
20311
0
#endif
20312
0
        ret->type = WOLFSSL_SESSION_TYPE_HEAP;
20313
0
        ret->heap = heap;
20314
#ifdef WOLFSSL_CHECK_MEM_ZERO
20315
        wc_MemZero_Add("SESSION master secret", ret->masterSecret, SECRET_LEN);
20316
        wc_MemZero_Add("SESSION id", ret->sessionID, ID_LEN);
20317
#endif
20318
    #ifdef HAVE_SESSION_TICKET
20319
        ret->ticket = ret->staticTicket;
20320
        #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&  \
20321
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
20322
        ret->ticketNonce.data = ret->ticketNonce.dataStatic;
20323
        #endif
20324
    #endif
20325
#ifdef HAVE_STUNNEL
20326
        /* stunnel has this funny mechanism of storing the "is_authenticated"
20327
         * session info in the session ex data. This is basically their
20328
         * default so let's just hard code it. */
20329
        if (wolfSSL_SESSION_set_ex_data(ret, 0, (void *)(-1))
20330
                != WOLFSSL_SUCCESS) {
20331
            WOLFSSL_MSG("Error setting up ex data for stunnel");
20332
            XFREE(ret, NULL, DYNAMIC_TYPE_SESSION);
20333
            return NULL;
20334
        }
20335
#endif
20336
#ifdef HAVE_EX_DATA
20337
        ret->ownExData = 1;
20338
#endif
20339
0
    }
20340
0
    return ret;
20341
0
}
20342
20343
20344
WOLFSSL_SESSION* wolfSSL_SESSION_new_ex(void* heap)
20345
0
{
20346
0
    return wolfSSL_NewSession(heap);
20347
0
}
20348
20349
WOLFSSL_SESSION* wolfSSL_SESSION_new(void)
20350
0
{
20351
0
    return wolfSSL_SESSION_new_ex(NULL);
20352
0
}
20353
20354
/* add one to session reference count
20355
 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error */
20356
int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session)
20357
0
{
20358
0
    session = ClientSessionToSession(session);
20359
20360
0
    if (session == NULL || session->type != WOLFSSL_SESSION_TYPE_HEAP)
20361
0
        return WOLFSSL_FAILURE;
20362
20363
0
#ifndef SINGLE_THREADED
20364
0
    if (wc_LockMutex(&session->refMutex) != 0) {
20365
0
        WOLFSSL_MSG("Failed to lock session mutex");
20366
0
        return WOLFSSL_FAILURE;
20367
0
    }
20368
0
#endif
20369
0
    session->refCount++;
20370
0
#ifndef SINGLE_THREADED
20371
0
    wc_UnLockMutex(&session->refMutex);
20372
0
#endif
20373
0
    return WOLFSSL_SUCCESS;
20374
0
}
20375
20376
/**
20377
 * Deep copy the contents from input to output.
20378
 * @param input         The source of the copy.
20379
 * @param output        The destination of the copy.
20380
 * @param avoidSysCalls If true, then system calls will be avoided or an error
20381
 *                      will be returned if it is not possible to proceed
20382
 *                      without a system call. This is useful for fetching
20383
 *                      sessions from cache. When a cache row is locked, we
20384
 *                      don't want to block other threads with long running
20385
 *                      system calls.
20386
 * @param ticketNonceBuf If not null and @avoidSysCalls is true, the copy of the
20387
 *                      ticketNonce will happen in this pre allocated buffer
20388
 * @param ticketNonceLen @ticketNonceBuf len as input, used length on output
20389
 * @param ticketNonceUsed if @ticketNonceBuf was used to copy the ticket noncet
20390
 * @return              WOLFSSL_SUCCESS on success
20391
 *                      WOLFSSL_FAILURE on failure
20392
 */
20393
static int wolfSSL_DupSessionEx(const WOLFSSL_SESSION* input,
20394
    WOLFSSL_SESSION* output, int avoidSysCalls, byte* ticketNonceBuf,
20395
    byte* ticketNonceLen, byte* preallocUsed)
20396
0
{
20397
#ifdef HAVE_SESSION_TICKET
20398
    int   ticLenAlloc = 0;
20399
    byte *ticBuff = NULL;
20400
#endif
20401
0
    const size_t copyOffset = OFFSETOF(WOLFSSL_SESSION, heap) + sizeof(input->heap);
20402
0
    int ret = WOLFSSL_SUCCESS;
20403
20404
0
    (void)avoidSysCalls;
20405
0
    (void)ticketNonceBuf;
20406
0
    (void)ticketNonceLen;
20407
0
    (void)preallocUsed;
20408
20409
0
    input = ClientSessionToSession(input);
20410
0
    output = ClientSessionToSession(output);
20411
20412
0
    if (input == NULL || output == NULL || input == output) {
20413
0
        WOLFSSL_MSG("input or output are null or same");
20414
0
        return WOLFSSL_FAILURE;
20415
0
    }
20416
20417
#ifdef HAVE_SESSION_TICKET
20418
    if (output->ticket != output->staticTicket) {
20419
        ticBuff = output->ticket;
20420
        ticLenAlloc = output->ticketLenAlloc;
20421
    }
20422
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&          \
20423
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
20424
        /* free the data, it would be better to re-use the buffer but this
20425
         * maintain the code simpler. A smart allocator should re-use the free'd
20426
         * buffer in the next malloc without much performance penalties. */
20427
    if (output->ticketNonce.data != output->ticketNonce.dataStatic) {
20428
20429
        /*  Callers that avoid syscall should never calls this with
20430
         * output->tickeNonce.data being a dynamic buffer.*/
20431
        if (avoidSysCalls) {
20432
            WOLFSSL_MSG("can't avoid syscalls with dynamic TicketNonce buffer");
20433
            return WOLFSSL_FAILURE;
20434
        }
20435
20436
        XFREE(output->ticketNonce.data,
20437
            output->heap, DYNAMIC_TYPE_SESSION_TICK);
20438
        output->ticketNonce.data = output->ticketNonce.dataStatic;
20439
        output->ticketNonce.len = 0;
20440
    }
20441
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
20442
#endif /* HAVE_SESSION_TICKET */
20443
20444
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
20445
    if (output->peer != NULL) {
20446
        if (avoidSysCalls) {
20447
            WOLFSSL_MSG("Can't free cert when avoiding syscalls");
20448
            return WOLFSSL_FAILURE;
20449
        }
20450
        wolfSSL_X509_free(output->peer);
20451
        output->peer = NULL;
20452
    }
20453
#endif
20454
20455
0
    XMEMCPY((byte*)output + copyOffset, (byte*)input + copyOffset,
20456
0
            sizeof(WOLFSSL_SESSION) - copyOffset);
20457
20458
#if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_TLS13) &&                  \
20459
    defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                                    \
20460
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
20461
    /* fix pointer to static after the copy  */
20462
    output->ticketNonce.data = output->ticketNonce.dataStatic;
20463
#endif
20464
    /* Set sane values for copy */
20465
0
#ifndef NO_SESSION_CACHE
20466
0
    if (output->type != WOLFSSL_SESSION_TYPE_CACHE)
20467
0
        output->cacheRow = INVALID_SESSION_ROW;
20468
0
#endif
20469
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
20470
    if (input->peer != NULL && input->peer->dynamicMemory) {
20471
        if (wolfSSL_X509_up_ref(input->peer) != WOLFSSL_SUCCESS) {
20472
            WOLFSSL_MSG("Can't increase peer cert ref count");
20473
            output->peer = NULL;
20474
        }
20475
    }
20476
    else if (!avoidSysCalls)
20477
        output->peer = wolfSSL_X509_dup(input->peer);
20478
    else
20479
        /* output->peer is not that important to copy */
20480
        output->peer = NULL;
20481
#endif
20482
#ifdef HAVE_SESSION_TICKET
20483
    if (input->ticketLen > SESSION_TICKET_LEN) {
20484
        /* Need dynamic buffer */
20485
        if (ticBuff == NULL || ticLenAlloc < input->ticketLen) {
20486
            /* allocate new one */
20487
            byte* tmp;
20488
            if (avoidSysCalls) {
20489
                WOLFSSL_MSG("Failed to allocate memory for ticket when avoiding"
20490
                        " syscalls");
20491
                output->ticket = ticBuff;
20492
                output->ticketLenAlloc = (word16) ticLenAlloc;
20493
                output->ticketLen = 0;
20494
                ret = WOLFSSL_FAILURE;
20495
            }
20496
            else {
20497
                tmp = (byte*)XREALLOC(ticBuff, input->ticketLen,
20498
                        output->heap, DYNAMIC_TYPE_SESSION_TICK);
20499
                if (tmp == NULL) {
20500
                    WOLFSSL_MSG("Failed to allocate memory for ticket");
20501
                    XFREE(ticBuff, output->heap, DYNAMIC_TYPE_SESSION_TICK);
20502
                    output->ticket = NULL;
20503
                    output->ticketLen = 0;
20504
                    output->ticketLenAlloc = 0;
20505
                    ret = WOLFSSL_FAILURE;
20506
                }
20507
                else {
20508
                    ticBuff = tmp;
20509
                    ticLenAlloc = input->ticketLen;
20510
                }
20511
            }
20512
        }
20513
        if (ticBuff != NULL && ret == WOLFSSL_SUCCESS) {
20514
            XMEMCPY(ticBuff, input->ticket, input->ticketLen);
20515
            output->ticket = ticBuff;
20516
            output->ticketLenAlloc = (word16) ticLenAlloc;
20517
        }
20518
    }
20519
    else {
20520
        /* Default ticket to non dynamic */
20521
        if (avoidSysCalls) {
20522
            /* Try to use ticBuf if available. Caller can later move it to
20523
             * the static buffer. */
20524
            if (ticBuff != NULL) {
20525
                if (ticLenAlloc >= input->ticketLen) {
20526
                    output->ticket = output->staticTicket;
20527
                    output->ticketLenAlloc = 0;
20528
                }
20529
                else {
20530
                    WOLFSSL_MSG("ticket dynamic buffer too small but we are "
20531
                                "avoiding system calls");
20532
                    ret = WOLFSSL_FAILURE;
20533
                    output->ticket = ticBuff;
20534
                    output->ticketLenAlloc = (word16) ticLenAlloc;
20535
                    output->ticketLen = 0;
20536
                }
20537
            }
20538
            else {
20539
                output->ticket = output->staticTicket;
20540
                output->ticketLenAlloc = 0;
20541
            }
20542
        }
20543
        else {
20544
            if (ticBuff != NULL)
20545
                XFREE(ticBuff, output->heap, DYNAMIC_TYPE_SESSION_TICK);
20546
            output->ticket = output->staticTicket;
20547
            output->ticketLenAlloc = 0;
20548
        }
20549
        if (input->ticketLenAlloc > 0 && ret == WOLFSSL_SUCCESS) {
20550
            /* Shouldn't happen as session should have placed this in
20551
             * the static buffer */
20552
            XMEMCPY(output->ticket, input->ticket,
20553
                    input->ticketLen);
20554
        }
20555
    }
20556
    ticBuff = NULL;
20557
20558
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&          \
20559
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
20560
    if (preallocUsed != NULL)
20561
        *preallocUsed = 0;
20562
20563
    if (input->ticketNonce.len > MAX_TICKET_NONCE_STATIC_SZ &&
20564
        ret == WOLFSSL_SUCCESS) {
20565
        /* TicketNonce does not fit in the static buffer */
20566
        if (!avoidSysCalls) {
20567
            output->ticketNonce.data = (byte*)XMALLOC(input->ticketNonce.len,
20568
                output->heap, DYNAMIC_TYPE_SESSION_TICK);
20569
20570
            if (output->ticketNonce.data == NULL) {
20571
                WOLFSSL_MSG("Failed to allocate space for ticket nonce");
20572
                output->ticketNonce.data = output->ticketNonce.dataStatic;
20573
                output->ticketNonce.len = 0;
20574
                ret = WOLFSSL_FAILURE;
20575
            }
20576
            else {
20577
                output->ticketNonce.len = input->ticketNonce.len;
20578
                XMEMCPY(output->ticketNonce.data, input->ticketNonce.data,
20579
                    input->ticketNonce.len);
20580
                ret = WOLFSSL_SUCCESS;
20581
            }
20582
        }
20583
        /* we can't do syscalls. Use prealloc buffers if provided from the
20584
         * caller. */
20585
        else if (ticketNonceBuf != NULL &&
20586
                 *ticketNonceLen >= input->ticketNonce.len) {
20587
            XMEMCPY(ticketNonceBuf, input->ticketNonce.data,
20588
                input->ticketNonce.len);
20589
            *ticketNonceLen = input->ticketNonce.len;
20590
            if (preallocUsed != NULL)
20591
                *preallocUsed = 1;
20592
            ret = WOLFSSL_SUCCESS;
20593
        }
20594
        else {
20595
            WOLFSSL_MSG("TicketNonce bigger than static buffer, and we can't "
20596
                        "do syscalls");
20597
            ret = WOLFSSL_FAILURE;
20598
        }
20599
    }
20600
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
20601
20602
#endif /* HAVE_SESSION_TICKET */
20603
0
    return ret;
20604
0
}
20605
20606
/**
20607
 * Deep copy the contents from input to output.
20608
 * @param input         The source of the copy.
20609
 * @param output        The destination of the copy.
20610
 * @param avoidSysCalls If true, then system calls will be avoided or an error
20611
 *                      will be returned if it is not possible to proceed
20612
 *                      without a system call. This is useful for fetching
20613
 *                      sessions from cache. When a cache row is locked, we
20614
 *                      don't want to block other threads with long running
20615
 *                      system calls.
20616
 * @return              WOLFSSL_SUCCESS on success
20617
 *                      WOLFSSL_FAILURE on failure
20618
 */
20619
int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
20620
        int avoidSysCalls)
20621
0
{
20622
0
    return wolfSSL_DupSessionEx(input, output, avoidSysCalls, NULL, NULL, NULL);
20623
0
}
20624
20625
WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
20626
0
{
20627
#ifdef HAVE_EXT_CACHE
20628
    WOLFSSL_SESSION* copy;
20629
20630
    WOLFSSL_ENTER("wolfSSL_SESSION_dup");
20631
20632
    session = ClientSessionToSession(session);
20633
    if (session == NULL)
20634
        return NULL;
20635
20636
#ifdef HAVE_SESSION_TICKET
20637
    if (session->ticketLenAlloc > 0 && !session->ticket) {
20638
        WOLFSSL_MSG("Session dynamic flag is set but ticket pointer is null");
20639
        return NULL;
20640
    }
20641
#endif
20642
20643
    copy = wolfSSL_NewSession(session->heap);
20644
    if (copy != NULL &&
20645
            wolfSSL_DupSession(session, copy, 0) != WOLFSSL_SUCCESS) {
20646
        wolfSSL_FreeSession(NULL, copy);
20647
        copy = NULL;
20648
    }
20649
    return copy;
20650
#else
20651
0
    WOLFSSL_MSG("wolfSSL_SESSION_dup feature not compiled in");
20652
0
    (void)session;
20653
0
    return NULL;
20654
0
#endif /* HAVE_EXT_CACHE */
20655
0
}
20656
20657
void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
20658
0
{
20659
0
    session = ClientSessionToSession(session);
20660
0
    if (session == NULL)
20661
0
        return;
20662
20663
0
    (void)ctx;
20664
20665
    /* refCount will always be 1 or more if created externally.
20666
     * Internal cache sessions don't initialize a refMutex. */
20667
0
    if (session->refCount > 0) {
20668
0
#ifndef SINGLE_THREADED
20669
0
        if (wc_LockMutex(&session->refMutex) != 0) {
20670
0
            WOLFSSL_MSG("Failed to lock session mutex");
20671
0
            return;
20672
0
        }
20673
0
#endif
20674
0
        if (session->refCount > 1) {
20675
0
            session->refCount--;
20676
0
#ifndef SINGLE_THREADED
20677
0
            wc_UnLockMutex(&session->refMutex);
20678
0
#endif
20679
0
            return;
20680
0
        }
20681
0
#ifndef SINGLE_THREADED
20682
0
        wc_UnLockMutex(&session->refMutex);
20683
0
        wc_FreeMutex(&session->refMutex);
20684
0
#endif
20685
0
    }
20686
20687
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
20688
    if (ctx != NULL && ctx->rem_sess_cb
20689
#ifdef HAVE_EX_DATA
20690
            && session->ownExData /* This will be true if we are not using the
20691
                                   * internal cache so it will get called for
20692
                                   * externally cached sessions as well. */
20693
#endif
20694
    ) {
20695
        ctx->rem_sess_cb(ctx, session);
20696
    }
20697
#endif
20698
20699
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
20700
    wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
20701
#endif
20702
20703
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
20704
    if (session->peer) {
20705
        wolfSSL_X509_free(session->peer);
20706
        session->peer = NULL;
20707
    }
20708
#endif
20709
20710
#ifdef HAVE_SESSION_TICKET
20711
    if (session->ticketLenAlloc > 0) {
20712
        XFREE(session->ticket, session->heap, DYNAMIC_TYPE_SESSION_TICK);
20713
    }
20714
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TICKET_NONCE_MALLOC) &&          \
20715
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
20716
    if (session->ticketNonce.data != session->ticketNonce.dataStatic) {
20717
        XFREE(session->ticketNonce.data, session->heap,
20718
            DYNAMIC_TYPE_SESSION_TICK);
20719
    }
20720
#endif /* WOLFSSL_TLS13 && WOLFSSL_TICKET_NONCE_MALLOC && FIPS_VERSION_GE(5,3)*/
20721
#endif
20722
20723
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
20724
    wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
20725
#endif
20726
20727
    /* Make sure masterSecret is zeroed. */
20728
0
    ForceZero(session->masterSecret, SECRET_LEN);
20729
    /* Session ID is sensitive information too. */
20730
0
    ForceZero(session->sessionID, ID_LEN);
20731
20732
0
    if (session->type == WOLFSSL_SESSION_TYPE_HEAP) {
20733
0
        XFREE(session, session->heap, DYNAMIC_TYPE_SESSION);
20734
0
    }
20735
0
}
20736
20737
void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
20738
0
{
20739
0
    session = ClientSessionToSession(session);
20740
0
    wolfSSL_FreeSession(NULL, session);
20741
0
}
20742
20743
#ifndef NO_SESSION_CACHE
20744
int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
20745
0
{
20746
0
    int    error = 0;
20747
0
    const byte* id = NULL;
20748
0
    byte idSz = 0;
20749
20750
0
    WOLFSSL_ENTER("wolfSSL_CTX_add_session");
20751
20752
0
    session = ClientSessionToSession(session);
20753
0
    if (session == NULL)
20754
0
        return WOLFSSL_FAILURE;
20755
20756
    /* Session cache is global */
20757
0
    (void)ctx;
20758
20759
0
    id = session->sessionID;
20760
0
    idSz = session->sessionIDSz;
20761
0
    if (session->haveAltSessionID) {
20762
0
        id = session->altSessionID;
20763
0
        idSz = ID_LEN;
20764
0
    }
20765
20766
0
    error = AddSessionToCache(ctx, session, id, idSz,
20767
0
            NULL, session->side,
20768
#ifdef HAVE_SESSION_TICKET
20769
            session->ticketLen > 0,
20770
#else
20771
0
            0,
20772
0
#endif
20773
0
            NULL);
20774
20775
0
    return error == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
20776
0
}
20777
#endif
20778
20779
#if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
20780
20781
/**
20782
* set cipher to WOLFSSL_SESSION from WOLFSSL_CIPHER
20783
* @param session  a pointer to WOLFSSL_SESSION structure
20784
* @param cipher   a function pointer to WOLFSSL_CIPHER
20785
* @return WOLFSSL_SUCCESS on success, otherwise WOLFSSL_FAILURE
20786
*/
20787
int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session,
20788
                                            const WOLFSSL_CIPHER* cipher)
20789
{
20790
    WOLFSSL_ENTER("wolfSSL_SESSION_set_cipher");
20791
20792
    session = ClientSessionToSession(session);
20793
    /* sanity check */
20794
    if (session == NULL || cipher == NULL) {
20795
        WOLFSSL_MSG("bad argument");
20796
        return WOLFSSL_FAILURE;
20797
    }
20798
    session->cipherSuite0 = cipher->cipherSuite0;
20799
    session->cipherSuite  = cipher->cipherSuite;
20800
20801
    WOLFSSL_LEAVE("wolfSSL_SESSION_set_cipher", WOLFSSL_SUCCESS);
20802
    return WOLFSSL_SUCCESS;
20803
}
20804
#endif /* OPENSSL_EXTRA || HAVE_EXT_CACHE */
20805
20806
20807
/* helper function that takes in a protocol version struct and returns string */
20808
static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
20809
0
{
20810
0
    WOLFSSL_ENTER("wolfSSL_get_version");
20811
20812
0
    if (version == NULL) {
20813
0
        return "Bad arg";
20814
0
    }
20815
20816
0
    if (version->major == SSLv3_MAJOR) {
20817
0
        switch (version->minor) {
20818
0
            case SSLv3_MINOR :
20819
0
                return "SSLv3";
20820
0
            case TLSv1_MINOR :
20821
0
                return "TLSv1";
20822
0
            case TLSv1_1_MINOR :
20823
0
                return "TLSv1.1";
20824
0
            case TLSv1_2_MINOR :
20825
0
                return "TLSv1.2";
20826
0
            case TLSv1_3_MINOR :
20827
0
                return "TLSv1.3";
20828
0
            default:
20829
0
                return "unknown";
20830
0
        }
20831
0
    }
20832
#ifdef WOLFSSL_DTLS
20833
    else if (version->major == DTLS_MAJOR) {
20834
        switch (version->minor) {
20835
            case DTLS_MINOR :
20836
                return "DTLS";
20837
            case DTLSv1_2_MINOR :
20838
                return "DTLSv1.2";
20839
            case DTLSv1_3_MINOR :
20840
                return "DTLSv1.3";
20841
            default:
20842
                return "unknown";
20843
        }
20844
    }
20845
#endif /* WOLFSSL_DTLS */
20846
0
    return "unknown";
20847
0
}
20848
20849
20850
const char* wolfSSL_get_version(const WOLFSSL* ssl)
20851
0
{
20852
0
    if (ssl == NULL) {
20853
0
        WOLFSSL_MSG("Bad argument");
20854
0
        return "unknown";
20855
0
    }
20856
20857
0
    return wolfSSL_internal_get_version(&ssl->version);
20858
0
}
20859
20860
20861
/* current library version */
20862
const char* wolfSSL_lib_version(void)
20863
0
{
20864
0
    return LIBWOLFSSL_VERSION_STRING;
20865
0
}
20866
20867
#ifdef OPENSSL_EXTRA
20868
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
20869
const char* wolfSSL_OpenSSL_version(int a)
20870
{
20871
    (void)a;
20872
    return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
20873
}
20874
#else
20875
const char* wolfSSL_OpenSSL_version(void)
20876
{
20877
    return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
20878
}
20879
#endif /* WOLFSSL_QT */
20880
#endif
20881
20882
20883
/* current library version in hex */
20884
word32 wolfSSL_lib_version_hex(void)
20885
0
{
20886
0
    return LIBWOLFSSL_VERSION_HEX;
20887
0
}
20888
20889
20890
int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
20891
0
{
20892
0
    WOLFSSL_ENTER("SSL_get_current_cipher_suite");
20893
0
    if (ssl)
20894
0
        return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
20895
0
    return 0;
20896
0
}
20897
20898
WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
20899
0
{
20900
0
    WOLFSSL_ENTER("SSL_get_current_cipher");
20901
0
    if (ssl) {
20902
0
        ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
20903
0
        ssl->cipher.cipherSuite  = ssl->options.cipherSuite;
20904
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
20905
        ssl->cipher.bits = ssl->specs.key_size * 8;
20906
#endif
20907
0
        return &ssl->cipher;
20908
0
    }
20909
0
    else
20910
0
        return NULL;
20911
0
}
20912
20913
20914
const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
20915
0
{
20916
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_name");
20917
20918
0
    if (cipher == NULL) {
20919
0
        return NULL;
20920
0
    }
20921
20922
0
    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
20923
0
        !defined(WOLFSSL_QT)
20924
0
        return GetCipherNameIana(cipher->cipherSuite0, cipher->cipherSuite);
20925
    #else
20926
        return wolfSSL_get_cipher_name_from_suite(cipher->cipherSuite0,
20927
                cipher->cipherSuite);
20928
    #endif
20929
0
}
20930
20931
const char*  wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
20932
0
{
20933
0
    WOLFSSL_ENTER("SSL_CIPHER_get_version");
20934
20935
0
    if (cipher == NULL || cipher->ssl == NULL) {
20936
0
        return NULL;
20937
0
    }
20938
20939
0
    return wolfSSL_get_version(cipher->ssl);
20940
0
}
20941
20942
const char* wolfSSL_SESSION_CIPHER_get_name(const WOLFSSL_SESSION* session)
20943
0
{
20944
0
    session = ClientSessionToSession(session);
20945
0
    if (session == NULL) {
20946
0
        return NULL;
20947
0
    }
20948
20949
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
20950
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
20951
0
    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS)
20952
0
        return GetCipherNameIana(session->cipherSuite0, session->cipherSuite);
20953
    #else
20954
        return GetCipherNameInternal(session->cipherSuite0, session->cipherSuite);
20955
    #endif
20956
#else
20957
    return NULL;
20958
#endif
20959
0
}
20960
20961
const char* wolfSSL_get_cipher(WOLFSSL* ssl)
20962
0
{
20963
0
    WOLFSSL_ENTER("wolfSSL_get_cipher");
20964
0
    return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
20965
0
}
20966
20967
/* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
20968
const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
20969
0
{
20970
    /* get access to cipher_name_idx in internal.c */
20971
0
    return wolfSSL_get_cipher_name_internal(ssl);
20972
0
}
20973
20974
const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0,
20975
    const byte cipherSuite)
20976
0
{
20977
0
    return GetCipherNameInternal(cipherSuite0, cipherSuite);
20978
0
}
20979
20980
const char* wolfSSL_get_cipher_name_iana_from_suite(const byte cipherSuite0,
20981
        const byte cipherSuite)
20982
0
{
20983
0
    return GetCipherNameIana(cipherSuite0, cipherSuite);
20984
0
}
20985
20986
int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0,
20987
0
                                       byte* cipherSuite, int *flags) {
20988
0
    if ((name == NULL) ||
20989
0
        (cipherSuite0 == NULL) ||
20990
0
        (cipherSuite == NULL) ||
20991
0
        (flags == NULL))
20992
0
        return BAD_FUNC_ARG;
20993
0
    return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, flags);
20994
0
}
20995
20996
20997
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
20998
/* Creates and returns a new WOLFSSL_CIPHER stack. */
20999
WOLFSSL_STACK* wolfSSL_sk_new_cipher(void)
21000
{
21001
    WOLFSSL_STACK* sk;
21002
    WOLFSSL_ENTER("wolfSSL_sk_new_cipher");
21003
21004
    sk = wolfSSL_sk_new_null();
21005
    if (sk == NULL)
21006
        return NULL;
21007
    sk->type = STACK_TYPE_CIPHER;
21008
21009
    return sk;
21010
}
21011
21012
/* return 1 on success 0 on fail */
21013
int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk,
21014
                                                      WOLFSSL_CIPHER* cipher)
21015
{
21016
    return wolfSSL_sk_push(sk, cipher);
21017
}
21018
21019
#ifndef NO_WOLFSSL_STUB
21020
WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
21021
{
21022
    WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop");
21023
    (void)sk;
21024
    return NULL;
21025
}
21026
#endif /* NO_WOLFSSL_STUB */
21027
#endif /* WOLFSSL_QT || OPENSSL_ALL */
21028
21029
word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher)
21030
0
{
21031
0
    word16 cipher_id = 0;
21032
21033
0
    WOLFSSL_ENTER("SSL_CIPHER_get_id");
21034
21035
0
    if (cipher && cipher->ssl) {
21036
0
        cipher_id = (cipher->ssl->options.cipherSuite0 << 8) |
21037
0
                     cipher->ssl->options.cipherSuite;
21038
0
    }
21039
21040
0
    return cipher_id;
21041
0
}
21042
21043
const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
21044
0
{
21045
0
    const WOLFSSL_CIPHER* cipher = NULL;
21046
0
    byte cipherSuite0, cipherSuite;
21047
0
    WOLFSSL_ENTER("SSL_get_cipher_by_value");
21048
21049
    /* extract cipher id information */
21050
0
    cipherSuite =   (value       & 0xFF);
21051
0
    cipherSuite0 = ((value >> 8) & 0xFF);
21052
21053
    /* TODO: lookup by cipherSuite0 / cipherSuite */
21054
0
    (void)cipherSuite0;
21055
0
    (void)cipherSuite;
21056
21057
0
    return cipher;
21058
0
}
21059
21060
21061
#if defined(OPENSSL_EXTRA)
21062
/* Free the structure for WOLFSSL_CIPHER stack
21063
 *
21064
 * sk  stack to free nodes in
21065
 */
21066
void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
21067
{
21068
    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free");
21069
21070
    wolfSSL_sk_free(sk);
21071
}
21072
#endif /* OPENSSL_ALL */
21073
21074
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
21075
                                                                 !defined(NO_DH)
21076
#ifdef HAVE_FFDHE
21077
static const char* wolfssl_ffdhe_name(word16 group)
21078
0
{
21079
0
    const char* str = NULL;
21080
0
    switch (group) {
21081
0
        case WOLFSSL_FFDHE_2048:
21082
0
            str = "FFDHE_2048";
21083
0
            break;
21084
0
        case WOLFSSL_FFDHE_3072:
21085
0
            str = "FFDHE_3072";
21086
0
            break;
21087
0
        case WOLFSSL_FFDHE_4096:
21088
0
            str = "FFDHE_4096";
21089
0
            break;
21090
0
        case WOLFSSL_FFDHE_6144:
21091
0
            str = "FFDHE_6144";
21092
0
            break;
21093
0
        case WOLFSSL_FFDHE_8192:
21094
0
            str = "FFDHE_8192";
21095
0
            break;
21096
0
        default:
21097
0
            break;
21098
0
    }
21099
0
    return str;
21100
0
}
21101
#endif
21102
/* Return the name of the curve used for key exchange as a printable string.
21103
 *
21104
 * ssl  The SSL/TLS object.
21105
 * returns NULL if ECDH was not used, otherwise the name as a string.
21106
 */
21107
const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
21108
0
{
21109
0
    const char* cName = NULL;
21110
21111
0
    if (ssl == NULL)
21112
0
        return NULL;
21113
21114
#if defined(WOLFSSL_TLS13) && defined(HAVE_PQC)
21115
    /* Check for post-quantum groups. Return now because we do not want the ECC
21116
     * check to override this result in the case of a hybrid. */
21117
    if (IsAtLeastTLSv1_3(ssl->version)) {
21118
        switch (ssl->namedGroup) {
21119
#ifdef HAVE_LIBOQS
21120
        case WOLFSSL_KYBER_LEVEL1:
21121
            return "KYBER_LEVEL1";
21122
        case WOLFSSL_KYBER_LEVEL3:
21123
            return "KYBER_LEVEL3";
21124
        case WOLFSSL_KYBER_LEVEL5:
21125
            return "KYBER_LEVEL5";
21126
        case WOLFSSL_NTRU_HPS_LEVEL1:
21127
            return "NTRU_HPS_LEVEL1";
21128
        case WOLFSSL_NTRU_HPS_LEVEL3:
21129
            return "NTRU_HPS_LEVEL3";
21130
        case WOLFSSL_NTRU_HPS_LEVEL5:
21131
            return "NTRU_HPS_LEVEL5";
21132
        case WOLFSSL_NTRU_HRSS_LEVEL3:
21133
            return "NTRU_HRSS_LEVEL3";
21134
        case WOLFSSL_SABER_LEVEL1:
21135
            return "SABER_LEVEL1";
21136
        case WOLFSSL_SABER_LEVEL3:
21137
            return "SABER_LEVEL3";
21138
        case WOLFSSL_SABER_LEVEL5:
21139
            return "SABER_LEVEL5";
21140
        case WOLFSSL_KYBER_90S_LEVEL1:
21141
            return "KYBER_90S_LEVEL1";
21142
        case WOLFSSL_KYBER_90S_LEVEL3:
21143
            return "KYBER_90S_LEVEL3";
21144
        case WOLFSSL_KYBER_90S_LEVEL5:
21145
            return "KYBER_90S_LEVEL5";
21146
        case WOLFSSL_P256_NTRU_HPS_LEVEL1:
21147
            return "P256_NTRU_HPS_LEVEL1";
21148
        case WOLFSSL_P384_NTRU_HPS_LEVEL3:
21149
            return "P384_NTRU_HPS_LEVEL3";
21150
        case WOLFSSL_P521_NTRU_HPS_LEVEL5:
21151
            return "P521_NTRU_HPS_LEVEL5";
21152
        case WOLFSSL_P384_NTRU_HRSS_LEVEL3:
21153
            return "P384_NTRU_HRSS_LEVEL3";
21154
        case WOLFSSL_P256_SABER_LEVEL1:
21155
            return "P256_SABER_LEVEL1";
21156
        case WOLFSSL_P384_SABER_LEVEL3:
21157
            return "P384_SABER_LEVEL3";
21158
        case WOLFSSL_P521_SABER_LEVEL5:
21159
            return "P521_SABER_LEVEL5";
21160
        case WOLFSSL_P256_KYBER_LEVEL1:
21161
            return "P256_KYBER_LEVEL1";
21162
        case WOLFSSL_P384_KYBER_LEVEL3:
21163
            return "P384_KYBER_LEVEL3";
21164
        case WOLFSSL_P521_KYBER_LEVEL5:
21165
            return "P521_KYBER_LEVEL5";
21166
        case WOLFSSL_P256_KYBER_90S_LEVEL1:
21167
            return "P256_KYBER_90S_LEVEL1";
21168
        case WOLFSSL_P384_KYBER_90S_LEVEL3:
21169
            return "P384_KYBER_90S_LEVEL3";
21170
        case WOLFSSL_P521_KYBER_90S_LEVEL5:
21171
            return "P521_KYBER_90S_LEVEL5";
21172
#elif defined(HAVE_PQM4)
21173
        case WOLFSSL_KYBER_LEVEL1:
21174
            return "KYBER_LEVEL1";
21175
#elif defined(WOLFSSL_WC_KYBER)
21176
    #ifdef WOLFSSL_KYBER512
21177
        case WOLFSSL_KYBER_LEVEL1:
21178
            return "KYBER_LEVEL1";
21179
    #endif
21180
    #ifdef WOLFSSL_KYBER768
21181
        case WOLFSSL_KYBER_LEVEL3:
21182
            return "KYBER_LEVEL3";
21183
    #endif
21184
    #ifdef WOLFSSL_KYBER1024
21185
        case WOLFSSL_KYBER_LEVEL5:
21186
            return "KYBER_LEVEL5";
21187
    #endif
21188
#endif
21189
        }
21190
    }
21191
21192
#endif /* WOLFSSL_TLS13 && HAVE_PQC */
21193
0
#ifdef HAVE_FFDHE
21194
0
    if (ssl->namedGroup != 0) {
21195
0
        cName = wolfssl_ffdhe_name(ssl->namedGroup);
21196
0
    }
21197
0
#endif
21198
21199
0
#ifdef HAVE_CURVE25519
21200
0
    if (ssl->ecdhCurveOID == ECC_X25519_OID && cName == NULL) {
21201
0
        cName = "X25519";
21202
0
    }
21203
0
#endif
21204
21205
0
#ifdef HAVE_CURVE448
21206
0
    if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
21207
0
        cName = "X448";
21208
0
    }
21209
0
#endif
21210
21211
0
#ifdef HAVE_ECC
21212
0
    if (ssl->ecdhCurveOID != 0 && cName == NULL) {
21213
0
        cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
21214
0
                                NULL));
21215
0
    }
21216
0
#endif
21217
21218
0
    return cName;
21219
0
}
21220
#endif
21221
21222
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
21223
    defined(OPENSSL_EXTRA_X509_SMALL)
21224
21225
    /* Creates a new WOLFSSL_ASN1_STRING structure.
21226
     *
21227
     * returns a pointer to the new structure created on success or NULL if fail
21228
     */
21229
    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new(void)
21230
    {
21231
        WOLFSSL_ASN1_STRING* asn1;
21232
21233
#ifdef WOLFSSL_DEBUG_OPENSSL
21234
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_new");
21235
#endif
21236
21237
        asn1 = (WOLFSSL_ASN1_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_STRING), NULL,
21238
                DYNAMIC_TYPE_OPENSSL);
21239
        if (asn1 != NULL) {
21240
            XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
21241
        }
21242
21243
        return asn1; /* no check for null because error case is returning null*/
21244
    }
21245
21246
    /**
21247
     * Used to duplicate a passed in WOLFSSL_ASN1_STRING*
21248
     * @param asn1 WOLFSSL_ASN1_STRING* to be duplicated
21249
     * @return WOLFSSL_ASN1_STRING* the duplicate struct or NULL on error
21250
     */
21251
    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_dup(WOLFSSL_ASN1_STRING* asn1)
21252
    {
21253
        WOLFSSL_ASN1_STRING* dupl = NULL;
21254
21255
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_dup");
21256
        if (!asn1) {
21257
            WOLFSSL_MSG("Bad parameter");
21258
            return NULL;
21259
        }
21260
21261
        dupl = wolfSSL_ASN1_STRING_new();
21262
        if (!dupl) {
21263
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_new error");
21264
            return NULL;
21265
        }
21266
21267
        dupl->type = asn1->type;
21268
        dupl->flags = asn1->flags;
21269
21270
        if (wolfSSL_ASN1_STRING_set(dupl, asn1->data, asn1->length)
21271
                != WOLFSSL_SUCCESS) {
21272
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
21273
            wolfSSL_ASN1_STRING_free(dupl);
21274
            return NULL;
21275
        }
21276
21277
        return dupl;
21278
    }
21279
21280
21281
    /* used to free a WOLFSSL_ASN1_STRING structure */
21282
    void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1)
21283
    {
21284
#ifdef WOLFSSL_DEBUG_OPENSSL
21285
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_free");
21286
#endif
21287
21288
        if (asn1 != NULL) {
21289
            if (asn1->length > 0 && asn1->data != NULL && asn1->isDynamic) {
21290
                XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
21291
            }
21292
            XFREE(asn1, NULL, DYNAMIC_TYPE_OPENSSL);
21293
        }
21294
    }
21295
21296
    int wolfSSL_ASN1_STRING_cmp(const WOLFSSL_ASN1_STRING *a, const WOLFSSL_ASN1_STRING *b)
21297
    {
21298
        int i;
21299
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_cmp");
21300
21301
        if (!a || !b) {
21302
            return WOLFSSL_FATAL_ERROR;
21303
        }
21304
21305
        if (a->length != b->length) {
21306
            return a->length - b->length;
21307
        }
21308
21309
        if ((i = XMEMCMP(a->data, b->data, a->length)) != 0) {
21310
            return i;
21311
        }
21312
21313
        return a->type - b->type;
21314
    }
21315
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
21316
21317
#if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \
21318
    defined(OPENSSL_EXTRA_X509_SMALL))
21319
21320
    int wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING* dest,
21321
                            const WOLFSSL_ASN1_STRING* src)
21322
    {
21323
        if (src == NULL || dest == NULL) {
21324
            return WOLFSSL_FAILURE;
21325
        }
21326
        dest->type = src->type;
21327
        if(wolfSSL_ASN1_STRING_set(dest, src->data, src->length)
21328
                    != WOLFSSL_SUCCESS) {
21329
                return WOLFSSL_FAILURE;
21330
        }
21331
        dest->flags = src->flags;
21332
21333
        return WOLFSSL_SUCCESS;
21334
    }
21335
    /* Creates a new WOLFSSL_ASN1_STRING structure given the input type.
21336
     *
21337
     * type is the type of set when WOLFSSL_ASN1_STRING is created
21338
     *
21339
     * returns a pointer to the new structure created on success or NULL if fail
21340
     */
21341
    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type)
21342
    {
21343
        WOLFSSL_ASN1_STRING* asn1;
21344
21345
#ifdef WOLFSSL_DEBUG_OPENSSL
21346
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type_new");
21347
#endif
21348
21349
        asn1 = wolfSSL_ASN1_STRING_new();
21350
        if (asn1 == NULL) {
21351
            return NULL;
21352
        }
21353
        asn1->type = type;
21354
21355
        return asn1;
21356
    }
21357
21358
21359
/******************************************************************************
21360
* wolfSSL_ASN1_STRING_type - returns the type of <asn1>
21361
*
21362
* RETURNS:
21363
* returns the type set for <asn1>. Otherwise, returns WOLFSSL_FAILURE.
21364
*/
21365
    int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1)
21366
    {
21367
21368
#ifdef WOLFSSL_DEBUG_OPENSSL
21369
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type");
21370
#endif
21371
21372
        if (asn1 == NULL) {
21373
            return WOLFSSL_FAILURE;
21374
        }
21375
21376
        return asn1->type;
21377
    }
21378
21379
#endif /* !NO_CERTS && OPENSSL_EXTRA */
21380
21381
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
21382
    defined(OPENSSL_EXTRA_X509_SMALL)
21383
    /* if dataSz is negative then use XSTRLEN to find length of data
21384
     * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
21385
    /* `data` can be NULL and only buffer will be allocated */
21386
    int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data,
21387
            int dataSz)
21388
    {
21389
        int sz;
21390
21391
#ifdef WOLFSSL_DEBUG_OPENSSL
21392
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_set");
21393
#endif
21394
21395
        if (asn1 == NULL || (data == NULL && dataSz < 0)) {
21396
            return WOLFSSL_FAILURE;
21397
        }
21398
21399
        if (dataSz < 0) {
21400
            sz = (int)XSTRLEN((const char*)data);
21401
        }
21402
        else {
21403
            sz = dataSz;
21404
        }
21405
21406
        if (sz < 0) {
21407
            return WOLFSSL_FAILURE;
21408
        }
21409
21410
        /* free any existing data before copying */
21411
        if (asn1->data != NULL && asn1->isDynamic) {
21412
            XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
21413
            asn1->data = NULL;
21414
        }
21415
21416
        if (sz + 1 > CTC_NAME_SIZE) { /* account for null char */
21417
            /* create new data buffer and copy over */
21418
            asn1->data = (char*)XMALLOC(sz + 1, NULL, DYNAMIC_TYPE_OPENSSL);
21419
            if (asn1->data == NULL) {
21420
                return WOLFSSL_FAILURE;
21421
            }
21422
            asn1->isDynamic = 1;
21423
        }
21424
        else {
21425
            XMEMSET(asn1->strData, 0, CTC_NAME_SIZE);
21426
            asn1->data = asn1->strData;
21427
            asn1->isDynamic = 0;
21428
        }
21429
        if (data != NULL) {
21430
            XMEMCPY(asn1->data, data, sz);
21431
            asn1->data[sz] = '\0';
21432
        }
21433
        asn1->length = sz;
21434
21435
        return WOLFSSL_SUCCESS;
21436
    }
21437
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
21438
21439
#ifndef NO_CERTS
21440
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
21441
    const unsigned char* wolfSSL_ASN1_STRING_get0_data(
21442
                                            const WOLFSSL_ASN1_STRING* asn)
21443
    {
21444
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_get0_data");
21445
21446
        if (asn) {
21447
            return (const unsigned char*)asn->data;
21448
        } else {
21449
            return NULL;
21450
        }
21451
    }
21452
    unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn)
21453
    {
21454
#ifdef WOLFSSL_DEBUG_OPENSSL
21455
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_data");
21456
#endif
21457
21458
        if (asn) {
21459
            return (unsigned char*)asn->data;
21460
        }
21461
        else {
21462
            return NULL;
21463
        }
21464
    }
21465
21466
21467
    int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn)
21468
    {
21469
#ifdef WOLFSSL_DEBUG_OPENSSL
21470
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_length");
21471
#endif
21472
21473
        if (asn) {
21474
            return asn->length;
21475
        }
21476
        else {
21477
            return 0;
21478
        }
21479
    }
21480
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
21481
21482
#ifdef OPENSSL_EXTRA
21483
#ifndef NO_WOLFSSL_STUB
21484
    WOLFSSL_ASN1_STRING* wolfSSL_d2i_DISPLAYTEXT(WOLFSSL_ASN1_STRING **asn,
21485
                                             const unsigned char **in, long len)
21486
    {
21487
        WOLFSSL_STUB("d2i_DISPLAYTEXT");
21488
        (void)asn;
21489
        (void)in;
21490
        (void)len;
21491
        return NULL;
21492
    }
21493
#endif
21494
21495
#endif /* OPENSSL_EXTRA */
21496
21497
#endif /* !NO_CERTS */
21498
21499
#ifdef OPENSSL_EXTRA
21500
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21501
/* return authentication NID corresponding to cipher suite
21502
 * @param cipher a pointer to WOLFSSL_CIPHER
21503
 * return NID if found, NID_undef if not found
21504
 */
21505
int wolfSSL_CIPHER_get_auth_nid(const WOLFSSL_CIPHER* cipher)
21506
{
21507
    static const struct authnid {
21508
        const char* alg_name;
21509
        const int  nid;
21510
    } authnid_tbl[] = {
21511
        {"RSA",     NID_auth_rsa},
21512
        {"PSK",     NID_auth_psk},
21513
        {"SRP",     NID_auth_srp},
21514
        {"ECDSA",   NID_auth_ecdsa},
21515
        {"None",    NID_auth_null},
21516
        {NULL,      NID_undef}
21517
    };
21518
21519
    const struct authnid* sa;
21520
    const char* authStr;
21521
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21522
21523
    if (GetCipherSegment(cipher, n) == NULL) {
21524
        WOLFSSL_MSG("no suitable cipher name found");
21525
        return NID_undef;
21526
    }
21527
21528
    authStr = GetCipherAuthStr(n);
21529
21530
    if (authStr != NULL) {
21531
        for(sa = authnid_tbl; sa->alg_name != NULL; sa++) {
21532
            if (XSTRCMP(sa->alg_name, authStr) == 0) {
21533
                return sa->nid;
21534
            }
21535
        }
21536
    }
21537
21538
    return NID_undef;
21539
}
21540
/* return cipher NID corresponding to cipher suite
21541
 * @param cipher a pointer to WOLFSSL_CIPHER
21542
 * return NID if found, NID_undef if not found
21543
 */
21544
int wolfSSL_CIPHER_get_cipher_nid(const WOLFSSL_CIPHER* cipher)
21545
{
21546
    static const struct ciphernid {
21547
        const char* alg_name;
21548
        const int  nid;
21549
    } ciphernid_tbl[] = {
21550
        {"AESGCM(256)",             NID_aes_256_gcm},
21551
        {"AESGCM(128)",             NID_aes_128_gcm},
21552
        {"AESCCM(128)",             NID_aes_128_ccm},
21553
        {"AES(128)",                NID_aes_128_cbc},
21554
        {"AES(256)",                NID_aes_256_cbc},
21555
        {"CAMELLIA(256)",           NID_camellia_256_cbc},
21556
        {"CAMELLIA(128)",           NID_camellia_128_cbc},
21557
        {"RC4",                     NID_rc4},
21558
        {"3DES",                    NID_des_ede3_cbc},
21559
        {"CHACHA20/POLY1305(256)",  NID_chacha20_poly1305},
21560
        {"None",                    NID_undef},
21561
        {NULL,                      NID_undef}
21562
    };
21563
21564
    const struct ciphernid* c;
21565
    const char* encStr;
21566
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21567
21568
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_cipher_nid");
21569
21570
    if (GetCipherSegment(cipher, n) == NULL) {
21571
        WOLFSSL_MSG("no suitable cipher name found");
21572
        return NID_undef;
21573
    }
21574
21575
    encStr = GetCipherEncStr(n);
21576
21577
    if (encStr != NULL) {
21578
        for(c = ciphernid_tbl; c->alg_name != NULL; c++) {
21579
            if (XSTRCMP(c->alg_name, encStr) == 0) {
21580
                return c->nid;
21581
            }
21582
        }
21583
    }
21584
21585
    return NID_undef;
21586
}
21587
/* return digest NID corresponding to cipher suite
21588
 * @param cipher a pointer to WOLFSSL_CIPHER
21589
 * return NID if found, NID_undef if not found
21590
 */
21591
int wolfSSL_CIPHER_get_digest_nid(const WOLFSSL_CIPHER* cipher)
21592
{
21593
    static const struct macnid {
21594
        const char* alg_name;
21595
        const int  nid;
21596
    } macnid_tbl[] = {
21597
        {"SHA1",    NID_sha1},
21598
        {"SHA256",  NID_sha256},
21599
        {"SHA384",  NID_sha384},
21600
        {NULL,      NID_undef}
21601
    };
21602
21603
    const struct macnid* mc;
21604
    const char* name;
21605
    const char* macStr;
21606
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21607
    (void)name;
21608
21609
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_digest_nid");
21610
21611
    if ((name = GetCipherSegment(cipher, n)) == NULL) {
21612
        WOLFSSL_MSG("no suitable cipher name found");
21613
        return NID_undef;
21614
    }
21615
21616
    /* in MD5 case, NID will be NID_md5 */
21617
    if (XSTRSTR(name, "MD5") != NULL) {
21618
        return NID_md5;
21619
    }
21620
21621
    macStr = GetCipherMacStr(n);
21622
21623
    if (macStr != NULL) {
21624
        for(mc = macnid_tbl; mc->alg_name != NULL; mc++) {
21625
            if (XSTRCMP(mc->alg_name, macStr) == 0) {
21626
                return mc->nid;
21627
            }
21628
        }
21629
    }
21630
21631
    return NID_undef;
21632
}
21633
/* return key exchange NID corresponding to cipher suite
21634
 * @param cipher a pointer to WOLFSSL_CIPHER
21635
 * return NID if found, NID_undef if not found
21636
 */
21637
int wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER* cipher)
21638
{
21639
    static const struct kxnid {
21640
        const char* name;
21641
        const int  nid;
21642
    } kxnid_table[] = {
21643
        {"ECDHEPSK",  NID_kx_ecdhe_psk},
21644
        {"ECDH",      NID_kx_ecdhe},
21645
        {"DHEPSK",    NID_kx_dhe_psk},
21646
        {"DH",        NID_kx_dhe},
21647
        {"RSAPSK",    NID_kx_rsa_psk},
21648
        {"SRP",       NID_kx_srp},
21649
        {"EDH",       NID_kx_dhe},
21650
        {"RSA",       NID_kx_rsa},
21651
        {NULL,        NID_undef}
21652
    };
21653
21654
    const struct kxnid* k;
21655
    const char* keaStr;
21656
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21657
21658
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_kx_nid");
21659
21660
    if (GetCipherSegment(cipher, n) == NULL) {
21661
        WOLFSSL_MSG("no suitable cipher name found");
21662
        return NID_undef;
21663
    }
21664
21665
    /* in TLS 1.3 case, NID will be NID_kx_any */
21666
    if (XSTRCMP(n[0], "TLS13") == 0) {
21667
        return NID_kx_any;
21668
    }
21669
21670
    keaStr = GetCipherKeaStr(n);
21671
21672
    if (keaStr != NULL) {
21673
        for(k = kxnid_table; k->name != NULL; k++) {
21674
            if (XSTRCMP(k->name, keaStr) == 0) {
21675
                return k->nid;
21676
            }
21677
        }
21678
    }
21679
21680
    return NID_undef;
21681
}
21682
/* check if cipher suite is AEAD
21683
 * @param cipher a pointer to WOLFSSL_CIPHER
21684
 * return 1 if cipher is AEAD, 0 otherwise
21685
 */
21686
int wolfSSL_CIPHER_is_aead(const WOLFSSL_CIPHER* cipher)
21687
{
21688
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21689
21690
    WOLFSSL_ENTER("wolfSSL_CIPHER_is_aead");
21691
21692
    if (GetCipherSegment(cipher, n) == NULL) {
21693
        WOLFSSL_MSG("no suitable cipher name found");
21694
        return NID_undef;
21695
    }
21696
21697
    return IsCipherAEAD(n);
21698
}
21699
/* Creates cipher->description based on cipher->offset
21700
 * cipher->offset is set in wolfSSL_get_ciphers_compat when it is added
21701
 * to a stack of ciphers.
21702
 * @param [in] cipher: A cipher from a stack of ciphers.
21703
 * return WOLFSSL_SUCCESS if cipher->description is set, else WOLFSSL_FAILURE
21704
 */
21705
int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher)
21706
{
21707
    int strLen;
21708
    unsigned long offset;
21709
    char* dp;
21710
    const char* name;
21711
    const char *keaStr, *authStr, *encStr, *macStr, *protocol;
21712
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21713
    int len = MAX_DESCRIPTION_SZ-1;
21714
    const CipherSuiteInfo* cipher_names;
21715
    ProtocolVersion pv;
21716
    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description");
21717
21718
    if (cipher == NULL)
21719
        return WOLFSSL_FAILURE;
21720
21721
    dp = cipher->description;
21722
    if (dp == NULL)
21723
        return WOLFSSL_FAILURE;
21724
21725
    cipher_names = GetCipherNames();
21726
21727
    offset = cipher->offset;
21728
    if (offset >= (unsigned long)GetCipherNamesSize())
21729
        return WOLFSSL_FAILURE;
21730
    pv.major = cipher_names[offset].major;
21731
    pv.minor = cipher_names[offset].minor;
21732
    protocol = wolfSSL_internal_get_version(&pv);
21733
21734
    if ((name = GetCipherSegment(cipher, n)) == NULL) {
21735
        WOLFSSL_MSG("no suitable cipher name found");
21736
        return WOLFSSL_FAILURE;
21737
    }
21738
21739
    /* keaStr */
21740
    keaStr = GetCipherKeaStr(n);
21741
    /* authStr */
21742
    authStr = GetCipherAuthStr(n);
21743
    /* encStr */
21744
    encStr = GetCipherEncStr(n);
21745
    if ((cipher->bits = SetCipherBits(encStr)) == WOLFSSL_FAILURE) {
21746
       WOLFSSL_MSG("Cipher Bits Not Set.");
21747
    }
21748
    /* macStr */
21749
    macStr = GetCipherMacStr(n);
21750
21751
21752
    /* Build up the string by copying onto the end. */
21753
    XSTRNCPY(dp, name, len);
21754
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21755
    len -= strLen; dp += strLen;
21756
21757
    XSTRNCPY(dp, " ", len);
21758
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21759
    len -= strLen; dp += strLen;
21760
    XSTRNCPY(dp, protocol, len);
21761
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21762
    len -= strLen; dp += strLen;
21763
21764
    XSTRNCPY(dp, " Kx=", len);
21765
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21766
    len -= strLen; dp += strLen;
21767
    XSTRNCPY(dp, keaStr, len);
21768
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21769
    len -= strLen; dp += strLen;
21770
21771
    XSTRNCPY(dp, " Au=", len);
21772
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21773
    len -= strLen; dp += strLen;
21774
    XSTRNCPY(dp, authStr, len);
21775
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21776
    len -= strLen; dp += strLen;
21777
21778
    XSTRNCPY(dp, " Enc=", len);
21779
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21780
    len -= strLen; dp += strLen;
21781
    XSTRNCPY(dp, encStr, len);
21782
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21783
    len -= strLen; dp += strLen;
21784
21785
    XSTRNCPY(dp, " Mac=", len);
21786
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21787
    len -= strLen; dp += strLen;
21788
    XSTRNCPY(dp, macStr, len);
21789
    dp[len-1] = '\0';
21790
21791
    return WOLFSSL_SUCCESS;
21792
}
21793
#endif /* OPENSSL_ALL || WOLFSSL_QT */
21794
21795
static WC_INLINE const char* wolfssl_kea_to_string(int kea)
21796
{
21797
    const char* keaStr;
21798
21799
    switch (kea) {
21800
        case no_kea:
21801
            keaStr = "None";
21802
            break;
21803
#ifndef NO_RSA
21804
        case rsa_kea:
21805
            keaStr = "RSA";
21806
            break;
21807
#endif
21808
#ifndef NO_DH
21809
        case diffie_hellman_kea:
21810
            keaStr = "DHE";
21811
            break;
21812
#endif
21813
        case fortezza_kea:
21814
            keaStr = "FZ";
21815
            break;
21816
#ifndef NO_PSK
21817
        case psk_kea:
21818
            keaStr = "PSK";
21819
            break;
21820
    #ifndef NO_DH
21821
        case dhe_psk_kea:
21822
            keaStr = "DHEPSK";
21823
            break;
21824
    #endif
21825
    #ifdef HAVE_ECC
21826
        case ecdhe_psk_kea:
21827
            keaStr = "ECDHEPSK";
21828
            break;
21829
    #endif
21830
#endif
21831
#ifdef HAVE_ECC
21832
        case ecc_diffie_hellman_kea:
21833
            keaStr = "ECDHE";
21834
            break;
21835
        case ecc_static_diffie_hellman_kea:
21836
            keaStr = "ECDH";
21837
            break;
21838
#endif
21839
        default:
21840
            keaStr = "unknown";
21841
            break;
21842
    }
21843
21844
    return keaStr;
21845
}
21846
21847
static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo)
21848
{
21849
    const char* authStr;
21850
21851
    switch (sig_algo) {
21852
        case anonymous_sa_algo:
21853
            authStr = "None";
21854
            break;
21855
#ifndef NO_RSA
21856
        case rsa_sa_algo:
21857
            authStr = "RSA";
21858
            break;
21859
    #ifdef WC_RSA_PSS
21860
        case rsa_pss_sa_algo:
21861
            authStr = "RSA-PSS";
21862
            break;
21863
    #endif
21864
#endif
21865
#ifndef NO_DSA
21866
        case dsa_sa_algo:
21867
            authStr = "DSA";
21868
            break;
21869
#endif
21870
#ifdef HAVE_ECC
21871
        case ecc_dsa_sa_algo:
21872
            authStr = "ECDSA";
21873
            break;
21874
#endif
21875
#ifdef HAVE_ED25519
21876
        case ed25519_sa_algo:
21877
            authStr = "Ed25519";
21878
            break;
21879
#endif
21880
#ifdef HAVE_ED448
21881
        case ed448_sa_algo:
21882
            authStr = "Ed448";
21883
            break;
21884
#endif
21885
        default:
21886
            authStr = "unknown";
21887
            break;
21888
    }
21889
21890
    return authStr;
21891
}
21892
21893
static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size)
21894
{
21895
    const char* encStr;
21896
21897
    (void)key_size;
21898
21899
    switch (cipher) {
21900
        case wolfssl_cipher_null:
21901
            encStr = "None";
21902
            break;
21903
#ifndef NO_RC4
21904
        case wolfssl_rc4:
21905
            encStr = "RC4(128)";
21906
            break;
21907
#endif
21908
#ifndef NO_DES3
21909
        case wolfssl_triple_des:
21910
            encStr = "3DES(168)";
21911
            break;
21912
#endif
21913
#ifndef NO_AES
21914
        case wolfssl_aes:
21915
            if (key_size == 128)
21916
                encStr = "AES(128)";
21917
            else if (key_size == 256)
21918
                encStr = "AES(256)";
21919
            else
21920
                encStr = "AES(?)";
21921
            break;
21922
    #ifdef HAVE_AESGCM
21923
        case wolfssl_aes_gcm:
21924
            if (key_size == 128)
21925
                encStr = "AESGCM(128)";
21926
            else if (key_size == 256)
21927
                encStr = "AESGCM(256)";
21928
            else
21929
                encStr = "AESGCM(?)";
21930
            break;
21931
    #endif
21932
    #ifdef HAVE_AESCCM
21933
        case wolfssl_aes_ccm:
21934
            if (key_size == 128)
21935
                encStr = "AESCCM(128)";
21936
            else if (key_size == 256)
21937
                encStr = "AESCCM(256)";
21938
            else
21939
                encStr = "AESCCM(?)";
21940
            break;
21941
    #endif
21942
#endif
21943
#ifdef HAVE_CHACHA
21944
        case wolfssl_chacha:
21945
            encStr = "CHACHA20/POLY1305(256)";
21946
            break;
21947
#endif
21948
#ifdef HAVE_CAMELLIA
21949
        case wolfssl_camellia:
21950
            if (key_size == 128)
21951
                encStr = "Camellia(128)";
21952
            else if (key_size == 256)
21953
                encStr = "Camellia(256)";
21954
            else
21955
                encStr = "Camellia(?)";
21956
            break;
21957
#endif
21958
        default:
21959
            encStr = "unknown";
21960
            break;
21961
    }
21962
21963
    return encStr;
21964
}
21965
21966
static WC_INLINE const char* wolfssl_mac_to_string(int mac)
21967
{
21968
    const char* macStr;
21969
21970
    switch (mac) {
21971
        case no_mac:
21972
            macStr = "None";
21973
            break;
21974
#ifndef NO_MD5
21975
        case md5_mac:
21976
            macStr = "MD5";
21977
            break;
21978
#endif
21979
#ifndef NO_SHA
21980
        case sha_mac:
21981
            macStr = "SHA1";
21982
            break;
21983
#endif
21984
#ifdef HAVE_SHA224
21985
        case sha224_mac:
21986
            macStr = "SHA224";
21987
            break;
21988
#endif
21989
#ifndef NO_SHA256
21990
        case sha256_mac:
21991
            macStr = "SHA256";
21992
            break;
21993
#endif
21994
#ifdef HAVE_SHA384
21995
        case sha384_mac:
21996
            macStr = "SHA384";
21997
            break;
21998
#endif
21999
#ifdef HAVE_SHA512
22000
        case sha512_mac:
22001
            macStr = "SHA512";
22002
            break;
22003
#endif
22004
        default:
22005
            macStr = "unknown";
22006
            break;
22007
    }
22008
22009
    return macStr;
22010
}
22011
22012
char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
22013
                                 int len)
22014
{
22015
    char *ret = in;
22016
    const char *keaStr, *authStr, *encStr, *macStr;
22017
    size_t strLen;
22018
    WOLFSSL_ENTER("wolfSSL_CIPHER_description");
22019
22020
    if (cipher == NULL || in == NULL)
22021
        return NULL;
22022
22023
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
22024
    /* if cipher is in the stack from wolfSSL_get_ciphers_compat then
22025
     * Return the description based on cipher_names[cipher->offset]
22026
     */
22027
    if (cipher->in_stack == TRUE) {
22028
        wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher);
22029
        XSTRNCPY(in,cipher->description,len);
22030
        return ret;
22031
    }
22032
#endif
22033
22034
    /* Get the cipher description based on the SSL session cipher */
22035
    keaStr = wolfssl_kea_to_string(cipher->ssl->specs.kea);
22036
    authStr = wolfssl_sigalg_to_string(cipher->ssl->specs.sig_algo);
22037
    encStr = wolfssl_cipher_to_string(cipher->ssl->specs.bulk_cipher_algorithm,
22038
                                      cipher->ssl->specs.key_size);
22039
    macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm);
22040
22041
    /* Build up the string by copying onto the end. */
22042
    XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len);
22043
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22044
22045
    XSTRNCPY(in, " ", len);
22046
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22047
    XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len);
22048
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22049
22050
    XSTRNCPY(in, " Kx=", len);
22051
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22052
    XSTRNCPY(in, keaStr, len);
22053
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22054
22055
    XSTRNCPY(in, " Au=", len);
22056
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22057
    XSTRNCPY(in, authStr, len);
22058
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22059
22060
    XSTRNCPY(in, " Enc=", len);
22061
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22062
    XSTRNCPY(in, encStr, len);
22063
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22064
22065
    XSTRNCPY(in, " Mac=", len);
22066
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
22067
    XSTRNCPY(in, macStr, len);
22068
    in[len-1] = '\0';
22069
22070
    return ret;
22071
}
22072
22073
22074
#ifndef NO_WOLFSSL_STUB
22075
int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
22076
                   int* ssl)
22077
{
22078
    (void)url;
22079
    (void)host;
22080
    (void)port;
22081
    (void)path;
22082
    (void)ssl;
22083
    WOLFSSL_STUB("OCSP_parse_url");
22084
    return 0;
22085
}
22086
#endif
22087
22088
#ifndef NO_MD4
22089
22090
void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
22091
{
22092
    /* make sure we have a big enough buffer */
22093
    typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
22094
    (void) sizeof(ok);
22095
22096
    WOLFSSL_ENTER("MD4_Init");
22097
    wc_InitMd4((Md4*)md4);
22098
}
22099
22100
22101
void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
22102
                       unsigned long len)
22103
{
22104
    WOLFSSL_ENTER("MD4_Update");
22105
    wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
22106
}
22107
22108
22109
void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
22110
{
22111
    WOLFSSL_ENTER("MD4_Final");
22112
    wc_Md4Final((Md4*)md4, digest);
22113
}
22114
22115
#endif /* NO_MD4 */
22116
22117
#ifndef NO_WOLFSSL_STUB
22118
void wolfSSL_RAND_screen(void)
22119
{
22120
    WOLFSSL_STUB("RAND_screen");
22121
}
22122
#endif
22123
22124
22125
22126
int wolfSSL_RAND_load_file(const char* fname, long len)
22127
{
22128
    (void)fname;
22129
    /* wolfCrypt provides enough entropy internally or will report error */
22130
    if (len == -1)
22131
        return 1024;
22132
    else
22133
        return (int)len;
22134
}
22135
22136
22137
#ifndef NO_WOLFSSL_STUB
22138
WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
22139
{
22140
    WOLFSSL_STUB("COMP_zlib");
22141
    return 0;
22142
}
22143
#endif
22144
22145
#ifndef NO_WOLFSSL_STUB
22146
WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
22147
{
22148
    WOLFSSL_STUB("COMP_rle");
22149
    return 0;
22150
}
22151
#endif
22152
22153
#ifndef NO_WOLFSSL_STUB
22154
int wolfSSL_COMP_add_compression_method(int method, void* data)
22155
{
22156
    (void)method;
22157
    (void)data;
22158
    WOLFSSL_STUB("COMP_add_compression_method");
22159
    return 0;
22160
}
22161
#endif
22162
22163
/*  wolfSSL_set_dynlock_create_callback
22164
 *  CRYPTO_set_dynlock_create_callback has been deprecated since openSSL 1.0.1.
22165
 *  This function exists for compatibility purposes because wolfSSL satisfies
22166
 *  thread safety without relying on the callback.
22167
 */
22168
void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
22169
                                                          const char*, int))
22170
{
22171
    WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
22172
    (void)f;
22173
}
22174
/*  wolfSSL_set_dynlock_lock_callback
22175
 *  CRYPTO_set_dynlock_lock_callback has been deprecated since openSSL 1.0.1.
22176
 *  This function exists for compatibility purposes because wolfSSL satisfies
22177
 *  thread safety without relying on the callback.
22178
 */
22179
void wolfSSL_set_dynlock_lock_callback(
22180
             void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
22181
{
22182
    WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
22183
    (void)f;
22184
}
22185
/*  wolfSSL_set_dynlock_destroy_callback
22186
 *  CRYPTO_set_dynlock_destroy_callback has been deprecated since openSSL 1.0.1.
22187
 *  This function exists for compatibility purposes because wolfSSL satisfies
22188
 *  thread safety without relying on the callback.
22189
 */
22190
void wolfSSL_set_dynlock_destroy_callback(
22191
                  void (*f)(WOLFSSL_dynlock_value*, const char*, int))
22192
{
22193
    WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
22194
    (void)f;
22195
}
22196
22197
22198
#endif /* OPENSSL_EXTRA */
22199
22200
#ifdef OPENSSL_EXTRA
22201
#ifndef NO_CERTS
22202
22203
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
22204
/* Copies unencrypted DER key buffer into "der". If "der" is null then the size
22205
 * of buffer needed is returned. If *der == NULL then it allocates a buffer.
22206
 * NOTE: This also advances the "der" pointer to be at the end of buffer.
22207
 *
22208
 * Returns size of key buffer on success
22209
 */
22210
int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der)
22211
{
22212
    return wolfSSL_EVP_PKEY_get_der(key, der);
22213
}
22214
22215
int wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
22216
{
22217
    return wolfSSL_EVP_PKEY_get_der(key, der);
22218
}
22219
#endif /* !NO_ASN && !NO_PWDBASED */
22220
22221
#endif /* !NO_CERTS */
22222
#endif /* OPENSSL_EXTRA */
22223
22224
#ifdef OPENSSL_EXTRA
22225
22226
/******************************************************************************
22227
* wolfSSL_CTX_set1_param - set a pointer to the SSL verification parameters
22228
*
22229
* RETURNS:
22230
*   WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
22231
*   Note: Returns WOLFSSL_SUCCESS, in case either parameter is NULL,
22232
*   same as openssl.
22233
*/
22234
int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm)
22235
{
22236
    if (ctx == NULL || vpm == NULL)
22237
        return WOLFSSL_SUCCESS;
22238
22239
    return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, vpm);
22240
}
22241
22242
/******************************************************************************
22243
* wolfSSL_CTX/_get0_param - return a pointer to the SSL verification parameters
22244
*
22245
* RETURNS:
22246
* returns pointer to the SSL verification parameters on success,
22247
* otherwise returns NULL
22248
*/
22249
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx)
22250
{
22251
    if (ctx == NULL) {
22252
        return NULL;
22253
    }
22254
22255
    return ctx->param;
22256
}
22257
22258
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl)
22259
{
22260
    if (ssl == NULL) {
22261
        return NULL;
22262
    }
22263
    return ssl->param;
22264
}
22265
22266
#endif /* OPENSSL_EXTRA */
22267
22268
#if defined(OPENSSL_EXTRA)
22269
int wolfSSL_i2d_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER* a, unsigned char** out)
22270
{
22271
    int ret = 0;
22272
    word32 idx = 0;
22273
    int len;
22274
    int preAlloc = 1;
22275
22276
    WOLFSSL_ENTER("wolfSSL_i2d_ASN1_INTEGER");
22277
22278
    if (a == NULL || a->data == NULL || a->length <= 0 || out == NULL) {
22279
        WOLFSSL_MSG("Bad parameter.");
22280
        ret = WOLFSSL_FATAL_ERROR;
22281
    }
22282
22283
    if (ret == 0 && *out == NULL) {
22284
        preAlloc = 0;
22285
        *out = (unsigned char*)XMALLOC(a->length, NULL, DYNAMIC_TYPE_ASN1);
22286
        if (*out == NULL) {
22287
            WOLFSSL_MSG("Failed to allocate output buffer.");
22288
            ret = WOLFSSL_FATAL_ERROR;
22289
        }
22290
    }
22291
    if (ret == 0) {
22292
        /*
22293
         * A WOLFSSL_ASN1_INTEGER stores the DER buffer of the integer in its
22294
         * "data" field, but it's only the magnitude of the number (i.e. the
22295
         * sign isn't encoded). The "negative" field is 1 if the value should
22296
         * be interpreted as negative and 0 otherwise. If the value is negative,
22297
         * we need to output the 2's complement of the value in the DER output.
22298
         */
22299
        XMEMCPY(*out, a->data, a->length);
22300
        if (a->negative) {
22301
            if (GetLength(a->data, &idx, &len, a->length) < 0) {
22302
                ret = WOLFSSL_FATAL_ERROR;
22303
            }
22304
            else {
22305
                ++idx;
22306
                for (; (int)idx < a->length; ++idx) {
22307
                    (*out)[idx] = ~(*out)[idx];
22308
                }
22309
                do {
22310
                    --idx;
22311
                    ++(*out)[idx];
22312
                } while ((*out)[idx] == 0);
22313
            }
22314
        }
22315
    }
22316
    if (ret == 0) {
22317
        ret = a->length;
22318
        if (preAlloc) {
22319
            *out += a->length;
22320
        }
22321
    }
22322
22323
    WOLFSSL_LEAVE("wolfSSL_i2d_ASN1_INTEGER", ret);
22324
22325
    return ret;
22326
}
22327
22328
WOLFSSL_ASN1_INTEGER* wolfSSL_d2i_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER** a,
22329
                                               const unsigned char** in,
22330
                                               long inSz)
22331
{
22332
    WOLFSSL_ASN1_INTEGER* ret = NULL;
22333
    int err = 0;
22334
    word32 idx = 0;
22335
    int len;
22336
22337
    WOLFSSL_ENTER("wolfSSL_d2i_ASN1_INTEGER");
22338
22339
    if (in == NULL || *in == NULL || inSz <= 0) {
22340
        WOLFSSL_MSG("Bad parameter");
22341
        err = 1;
22342
    }
22343
22344
    if (err == 0 && (*in)[0] != ASN_INTEGER) {
22345
        WOLFSSL_MSG("Tag doesn't indicate integer type.");
22346
        err = 1;
22347
    }
22348
    if (err == 0) {
22349
        ret = wolfSSL_ASN1_INTEGER_new();
22350
        if (ret == NULL) {
22351
            err = 1;
22352
        }
22353
        else {
22354
            ret->type = V_ASN1_INTEGER;
22355
        }
22356
    }
22357
    if (err == 0 && inSz > (long)sizeof(ret->intData)) {
22358
        ret->data = (unsigned char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_ASN1);
22359
        if (ret->data == NULL) {
22360
            err = 1;
22361
        }
22362
        else {
22363
            ret->isDynamic = 1;
22364
            ret->dataMax = (word32)inSz;
22365
        }
22366
    }
22367
    if (err == 0) {
22368
        XMEMCPY(ret->data, *in, inSz);
22369
        ret->length = (word32)inSz;
22370
        /* Advance to the end of the length field.*/
22371
        if (GetLength(*in, &idx, &len, (word32)inSz) < 0) {
22372
            err = 1;
22373
        }
22374
        else {
22375
            /* See 2's complement comment in wolfSSL_d2i_ASN1_INTEGER. */
22376
            ret->negative = (*in)[idx+1] & 0x80;
22377
            if (ret->negative) {
22378
                ++idx;
22379
                for (; (int)idx < inSz; ++idx) {
22380
                    ret->data[idx] = ~ret->data[idx];
22381
                }
22382
                do {
22383
                    --idx;
22384
                    ++ret->data[idx];
22385
                } while (ret->data[idx] == 0);
22386
                ret->type |= V_ASN1_NEG_INTEGER;
22387
            }
22388
            if (a != NULL) {
22389
                *a = ret;
22390
            }
22391
        }
22392
    }
22393
22394
    if (err != 0) {
22395
        wolfSSL_ASN1_INTEGER_free(ret);
22396
        ret = NULL;
22397
    }
22398
22399
    return ret;
22400
}
22401
#endif /* OPENSSL_EXTRA */
22402
22403
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
22404
/* Used to create a new WOLFSSL_ASN1_INTEGER structure.
22405
 * returns a pointer to new structure on success and NULL on failure
22406
 */
22407
WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void)
22408
{
22409
    WOLFSSL_ASN1_INTEGER* a;
22410
22411
    a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL,
22412
                                       DYNAMIC_TYPE_OPENSSL);
22413
    if (a == NULL) {
22414
        return NULL;
22415
    }
22416
22417
    XMEMSET(a, 0, sizeof(WOLFSSL_ASN1_INTEGER));
22418
    a->data    = a->intData;
22419
    a->isDynamic = 0;
22420
    a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
22421
    a->length  = 0;
22422
    return a;
22423
}
22424
22425
22426
/* free's internal elements of WOLFSSL_ASN1_INTEGER and free's "in" itself */
22427
void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in)
22428
{
22429
    if (in != NULL) {
22430
        if (in->isDynamic) {
22431
            XFREE(in->data, NULL, DYNAMIC_TYPE_OPENSSL);
22432
        }
22433
        XFREE(in, NULL, DYNAMIC_TYPE_OPENSSL);
22434
    }
22435
}
22436
22437
22438
/* Duplicate all WOLFSSL_ASN1_INTEGER members from src to dup
22439
 *  src : WOLFSSL_ASN1_INTEGER to duplicate
22440
 *  Returns pointer to duplicate WOLFSSL_ASN1_INTEGER
22441
 */
22442
WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER* src)
22443
{
22444
    WOLFSSL_ASN1_INTEGER* copy;
22445
    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_dup");
22446
    if (!src)
22447
        return NULL;
22448
22449
    copy = wolfSSL_ASN1_INTEGER_new();
22450
22451
    if (copy == NULL)
22452
        return NULL;
22453
22454
    copy->negative  = src->negative;
22455
    copy->dataMax   = src->dataMax;
22456
    copy->isDynamic = src->isDynamic;
22457
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
22458
    copy->length    = src->length;
22459
#endif
22460
    XSTRNCPY((char*)copy->intData,(const char*)src->intData,WOLFSSL_ASN1_INTEGER_MAX);
22461
22462
    if (copy->isDynamic && src->data && copy->dataMax) {
22463
        copy->data = (unsigned char*)
22464
            XMALLOC(src->dataMax,NULL,DYNAMIC_TYPE_OPENSSL);
22465
        if (copy->data == NULL) {
22466
            wolfSSL_ASN1_INTEGER_free(copy);
22467
            return NULL;
22468
        }
22469
        XMEMCPY(copy->data, src->data, copy->dataMax);
22470
    }
22471
    return copy;
22472
}
22473
22474
22475
/* sets the value of WOLFSSL_ASN1_INTEGER a to the long value v. */
22476
int wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v)
22477
{
22478
    int ret = WOLFSSL_SUCCESS; /* return 1 for success and 0 for failure */
22479
    int j;
22480
    unsigned int i = 0;
22481
    unsigned char tmp[sizeof(long)+1] = {0};
22482
    int pad = 0;
22483
22484
    if (a != NULL) {
22485
        /* dynamically create data buffer, +2 for type and length */
22486
        a->data = (unsigned char*)XMALLOC((sizeof(long)+1) + 2, NULL,
22487
                DYNAMIC_TYPE_OPENSSL);
22488
        if (a->data == NULL) {
22489
            wolfSSL_ASN1_INTEGER_free(a);
22490
            ret = WOLFSSL_FAILURE;
22491
        }
22492
        else {
22493
            a->dataMax   = (int)(sizeof(long)+1) + 2;
22494
            a->isDynamic = 1;
22495
        }
22496
    }
22497
    else {
22498
        /* Invalid parameter */
22499
        ret = WOLFSSL_FAILURE;
22500
    }
22501
22502
22503
    if (ret != WOLFSSL_FAILURE) {
22504
        /* Set type */
22505
        a->data[i++] = ASN_INTEGER;
22506
22507
        /* Check for negative */
22508
        if (v < 0) {
22509
            a->negative = 1;
22510
            v *= -1;
22511
        }
22512
22513
        /* Create char buffer */
22514
        for (j = 0; j < (int)sizeof(long); j++) {
22515
            if (v == 0) {
22516
                break;
22517
            }
22518
            tmp[j] = (unsigned char)(v & 0xff);
22519
            v >>= 8;
22520
        }
22521
22522
        /* 0 pad to indicate positive number when top bit set. */
22523
        if ((!a->negative) && (j > 0) && (tmp[j-1] & 0x80)) {
22524
            pad = 1;
22525
        }
22526
        /* Set length */
22527
        a->data[i++] = (unsigned char)(((j == 0) ? ++j : j) + pad);
22528
        /* +2 for type and length */
22529
        a->length = j + pad + 2;
22530
22531
        /* Add padding if required. */
22532
        if (pad) {
22533
            a->data[i++] = 0;
22534
        }
22535
        /* Copy to data */
22536
        for (; j > 0; j--) {
22537
            a->data[i++] = tmp[j-1];
22538
        }
22539
    }
22540
22541
    return ret;
22542
}
22543
22544
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
22545
22546
#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
22547
    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
22548
#ifndef NO_ASN_TIME
22549
#ifndef NO_BIO
22550
int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
22551
{
22552
    char buf[MAX_TIME_STRING_SZ];
22553
    int  ret = WOLFSSL_SUCCESS;
22554
22555
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_print");
22556
22557
    if (bio == NULL || asnTime == NULL) {
22558
        WOLFSSL_MSG("NULL function argument");
22559
        return WOLFSSL_FAILURE;
22560
    }
22561
22562
    if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)asnTime, buf,
22563
                sizeof(buf)) == NULL) {
22564
        XMEMSET(buf, 0, MAX_TIME_STRING_SZ);
22565
        XSTRNCPY(buf, "Bad time value", sizeof(buf)-1);
22566
        ret = WOLFSSL_FAILURE;
22567
    }
22568
22569
    if (wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf)) <= 0) {
22570
        WOLFSSL_MSG("Unable to write to bio");
22571
        return WOLFSSL_FAILURE;
22572
    }
22573
22574
    return ret;
22575
}
22576
#endif /* !NO_BIO */
22577
22578
char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len)
22579
{
22580
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string");
22581
22582
    if (t == NULL || buf == NULL || len < 5) {
22583
        WOLFSSL_MSG("Bad argument");
22584
        return NULL;
22585
    }
22586
22587
    if (t->length > len) {
22588
        WOLFSSL_MSG("Length of date is longer then buffer");
22589
        return NULL;
22590
    }
22591
22592
    if (!GetTimeString(t->data, t->type, buf, len)) {
22593
        return NULL;
22594
    }
22595
22596
    return buf;
22597
}
22598
22599
/* Converts a WOLFSSL_ASN1_TIME to a struct tm. Returns WOLFSSL_SUCCESS on
22600
 * success and WOLFSSL_FAILURE on failure. */
22601
static int Asn1TimeToTm(WOLFSSL_ASN1_TIME* asnTime, struct tm* tm)
22602
{
22603
    unsigned char* asn1TimeBuf;
22604
    int asn1TimeBufLen;
22605
    int i = 0;
22606
    int bytesNeeded = 11;
22607
22608
    if (asnTime == NULL) {
22609
        WOLFSSL_MSG("asnTime is NULL");
22610
        return WOLFSSL_FAILURE;
22611
    }
22612
    if (tm == NULL) {
22613
        WOLFSSL_MSG("tm is NULL");
22614
        return WOLFSSL_FAILURE;
22615
    }
22616
22617
    asn1TimeBuf = wolfSSL_ASN1_TIME_get_data(asnTime);
22618
    if (asn1TimeBuf == NULL) {
22619
        WOLFSSL_MSG("Failed to get WOLFSSL_ASN1_TIME buffer.");
22620
        return WOLFSSL_FAILURE;
22621
    }
22622
    asn1TimeBufLen = wolfSSL_ASN1_TIME_get_length(asnTime);
22623
    if (asn1TimeBufLen <= 0) {
22624
        WOLFSSL_MSG("Failed to get WOLFSSL_ASN1_TIME buffer length.");
22625
        return WOLFSSL_FAILURE;
22626
    }
22627
    XMEMSET(tm, 0, sizeof(struct tm));
22628
22629
    /* Convert ASN1_time to struct tm */
22630
    /* Check type */
22631
    if (asnTime->type == ASN_UTC_TIME) {
22632
        /* 2-digit year */
22633
        bytesNeeded += 2;
22634
        if (bytesNeeded > asn1TimeBufLen) {
22635
            WOLFSSL_MSG("WOLFSSL_ASN1_TIME buffer length is invalid.");
22636
            return WOLFSSL_FAILURE;
22637
        }
22638
        if (asn1TimeBuf[bytesNeeded-1] != 'Z') {
22639
            WOLFSSL_MSG("Expecting UTC time.");
22640
            return WOLFSSL_FAILURE;
22641
        }
22642
22643
        tm->tm_year = (asn1TimeBuf[i] - '0') * 10; i++;
22644
        tm->tm_year += asn1TimeBuf[i] - '0'; i++;
22645
        if (tm->tm_year < 70) {
22646
            tm->tm_year += 100;
22647
        }
22648
    }
22649
    else if (asnTime->type == ASN_GENERALIZED_TIME) {
22650
        /* 4-digit year */
22651
        bytesNeeded += 4;
22652
        if (bytesNeeded > asn1TimeBufLen) {
22653
            WOLFSSL_MSG("WOLFSSL_ASN1_TIME buffer length is invalid.");
22654
            return WOLFSSL_FAILURE;
22655
        }
22656
        if (asn1TimeBuf[bytesNeeded-1] != 'Z') {
22657
            WOLFSSL_MSG("Expecting UTC time.");
22658
            return WOLFSSL_FAILURE;
22659
        }
22660
22661
        tm->tm_year = (asn1TimeBuf[i] - '0') * 1000; i++;
22662
        tm->tm_year += (asn1TimeBuf[i] - '0') * 100; i++;
22663
        tm->tm_year += (asn1TimeBuf[i] - '0') * 10; i++;
22664
        tm->tm_year += asn1TimeBuf[i] - '0'; i++;
22665
        tm->tm_year -= 1900;
22666
    }
22667
    else {
22668
        WOLFSSL_MSG("asnTime->type is invalid.");
22669
        return WOLFSSL_FAILURE;
22670
    }
22671
22672
    tm->tm_mon = (asn1TimeBuf[i] - '0') * 10; i++;
22673
    tm->tm_mon += (asn1TimeBuf[i] - '0') - 1; i++; /* January is 0 not 1 */
22674
    tm->tm_mday = (asn1TimeBuf[i] - '0') * 10; i++;
22675
    tm->tm_mday += (asn1TimeBuf[i] - '0'); i++;
22676
    tm->tm_hour = (asn1TimeBuf[i] - '0') * 10; i++;
22677
    tm->tm_hour += (asn1TimeBuf[i] - '0'); i++;
22678
    tm->tm_min = (asn1TimeBuf[i] - '0') * 10; i++;
22679
    tm->tm_min += (asn1TimeBuf[i] - '0'); i++;
22680
    tm->tm_sec = (asn1TimeBuf[i] - '0') * 10; i++;
22681
    tm->tm_sec += (asn1TimeBuf[i] - '0');
22682
22683
#ifdef XMKTIME
22684
    /* Call XMKTIME on tm to get the tm_wday and tm_yday fields populated. */
22685
    XMKTIME(tm);
22686
#endif
22687
22688
    return WOLFSSL_SUCCESS;
22689
}
22690
22691
int wolfSSL_ASN1_TIME_to_tm(const WOLFSSL_ASN1_TIME* asnTime, struct tm* tm)
22692
{
22693
    time_t currentTime;
22694
    struct tm *tmpTs;
22695
#if defined(NEED_TMP_TIME)
22696
    /* for use with gmtime_r */
22697
    struct tm tmpTimeStorage;
22698
    tmpTs = &tmpTimeStorage;
22699
#else
22700
    tmpTs = NULL;
22701
#endif
22702
    (void)tmpTs;
22703
22704
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_tm");
22705
22706
    /* If asnTime is NULL, then the current time is converted. */
22707
    if (asnTime == NULL) {
22708
        if (tm == NULL) {
22709
            WOLFSSL_MSG("asnTime and tm are both NULL");
22710
            return WOLFSSL_FAILURE;
22711
        }
22712
22713
        currentTime = wc_Time(0);
22714
        if (currentTime <= 0) {
22715
            WOLFSSL_MSG("Failed to get current time.");
22716
            return WOLFSSL_FAILURE;
22717
        }
22718
22719
        tm = XGMTIME(&currentTime, tmpTs);
22720
        if (tm == NULL) {
22721
            WOLFSSL_MSG("Failed to convert current time to UTC.");
22722
            return WOLFSSL_FAILURE;
22723
        }
22724
22725
        return WOLFSSL_SUCCESS;
22726
    }
22727
22728
    /* If tm is NULL this function performs a format check on asnTime only. */
22729
    if (tm == NULL) {
22730
        return wolfSSL_ASN1_TIME_check(asnTime);
22731
    }
22732
22733
    return Asn1TimeToTm((WOLFSSL_ASN1_TIME*)asnTime, tm);
22734
}
22735
#endif /* !NO_ASN_TIME */
22736
#endif /* WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
22737
    OPENSSL_EXTRA*/
22738
22739
22740
#ifdef OPENSSL_EXTRA
22741
22742
int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
22743
                             const WOLFSSL_ASN1_INTEGER* b)
22744
{
22745
    int ret = 0;
22746
22747
    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_cmp");
22748
22749
    if (a == NULL || b == NULL) {
22750
        WOLFSSL_MSG("Bad parameter.");
22751
        ret = WOLFSSL_FATAL_ERROR;
22752
    }
22753
22754
    if (ret == 0 && ((a->length != b->length) ||
22755
                     ((a->negative == 0) != (b->negative == 0)))) {
22756
        ret = WOLFSSL_FATAL_ERROR;
22757
    }
22758
    if (ret == 0) {
22759
        ret = XMEMCMP(a->data, b->data, a->length);
22760
    }
22761
22762
    WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_cmp", ret);
22763
22764
    return ret;
22765
}
22766
22767
long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* a)
22768
{
22769
    long ret = 1;
22770
    WOLFSSL_BIGNUM* bn = NULL;
22771
22772
    WOLFSSL_ENTER("ASN1_INTEGER_get");
22773
22774
    if (a == NULL) {
22775
        /* OpenSSL returns 0 when a is NULL and -1 if there is an error. Quoting
22776
         * the documentation:
22777
         *
22778
         * "ASN1_INTEGER_get() also returns the value of a but it returns 0 if a
22779
         * is NULL and -1 on error (which is ambiguous because -1 is a
22780
         * legitimate value for an ASN1_INTEGER). New applications should use
22781
         * ASN1_INTEGER_get_int64() instead."
22782
         * */
22783
        ret = 0;
22784
    }
22785
22786
    if (ret > 0) {
22787
        bn = wolfSSL_ASN1_INTEGER_to_BN(a, NULL);
22788
        if (bn == NULL) {
22789
            ret = -1;
22790
        }
22791
    }
22792
    if (ret > 0) {
22793
        ret = wolfSSL_BN_get_word(bn);
22794
        if (a->negative == 1) {
22795
            ret = -ret;
22796
        }
22797
    }
22798
22799
    if (bn != NULL) {
22800
        wolfSSL_BN_free(bn);
22801
    }
22802
22803
    WOLFSSL_LEAVE("ASN1_INTEGER_get", (int)ret);
22804
22805
    return ret;
22806
}
22807
22808
#endif /* OPENSSL_EXTRA */
22809
22810
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
22811
/* Gets an index to store SSL structure at.
22812
 *
22813
 * Returns positive index on success and negative values on failure
22814
 */
22815
int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
22816
{
22817
    WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
22818
22819
    /* store SSL at index 0 */
22820
    return 0;
22821
}
22822
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
22823
22824
#ifdef OPENSSL_EXTRA
22825
/* Sets a function callback that will send information about the state of all
22826
 * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
22827
 * in.
22828
 *
22829
 * ctx WOLFSSL_CTX structure to set callback function in
22830
 * f   callback function to use
22831
 */
22832
void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
22833
       void (*f)(const WOLFSSL* ssl, int type, int val))
22834
{
22835
    WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
22836
    if (ctx == NULL) {
22837
        WOLFSSL_MSG("Bad function argument");
22838
    }
22839
    else {
22840
        ctx->CBIS = f;
22841
    }
22842
}
22843
22844
22845
unsigned long wolfSSL_ERR_peek_error(void)
22846
{
22847
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
22848
22849
    return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
22850
}
22851
22852
int wolfSSL_ERR_GET_LIB(unsigned long err)
22853
{
22854
    unsigned long value;
22855
22856
    value = (err & 0xFFFFFFL);
22857
    switch (value) {
22858
    case -SSL_R_HTTP_REQUEST:
22859
        return ERR_LIB_SSL;
22860
    case PEM_R_NO_START_LINE:
22861
    case PEM_R_PROBLEMS_GETTING_PASSWORD:
22862
    case PEM_R_BAD_PASSWORD_READ:
22863
    case PEM_R_BAD_DECRYPT:
22864
        return ERR_LIB_PEM;
22865
    case EVP_R_BAD_DECRYPT:
22866
    case EVP_R_BN_DECODE_ERROR:
22867
    case EVP_R_DECODE_ERROR:
22868
    case EVP_R_PRIVATE_KEY_DECODE_ERROR:
22869
        return ERR_LIB_EVP;
22870
    case ASN1_R_HEADER_TOO_LONG:
22871
        return ERR_LIB_ASN1;
22872
    default:
22873
        return 0;
22874
    }
22875
}
22876
22877
/* This function is to find global error values that are the same through out
22878
 * all library version. With wolfSSL having only one set of error codes the
22879
 * return value is pretty straight forward. The only thing needed is all wolfSSL
22880
 * error values are typically negative.
22881
 *
22882
 * Returns the error reason
22883
 */
22884
int wolfSSL_ERR_GET_REASON(unsigned long err)
22885
{
22886
    int ret = (int)err;
22887
22888
    WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
22889
22890
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
22891
    /* Nginx looks for this error to know to stop parsing certificates. */
22892
    if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
22893
        return PEM_R_NO_START_LINE;
22894
    if (err == ((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
22895
        return SSL_R_HTTP_REQUEST;
22896
#endif
22897
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
22898
    if (err == ((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
22899
        return ASN1_R_HEADER_TOO_LONG;
22900
#endif
22901
22902
    /* check if error value is in range of wolfSSL errors */
22903
    ret = 0 - ret; /* setting as negative value */
22904
    /* wolfCrypt range is less than MAX (-100)
22905
       wolfSSL range is MIN (-300) and lower */
22906
    if (ret < MAX_CODE_E && ret > MIN_CODE_E) {
22907
        return ret;
22908
    }
22909
    else {
22910
        WOLFSSL_MSG("Not in range of typical error values");
22911
        ret = (int)err;
22912
    }
22913
22914
    return ret;
22915
}
22916
22917
/* returns a string that describes the alert
22918
 *
22919
 * alertID the alert value to look up
22920
 */
22921
const char* wolfSSL_alert_type_string_long(int alertID)
22922
{
22923
    WOLFSSL_ENTER("wolfSSL_alert_type_string_long");
22924
22925
    return AlertTypeToString(alertID);
22926
}
22927
22928
22929
const char* wolfSSL_alert_desc_string_long(int alertID)
22930
{
22931
    WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
22932
22933
    return AlertTypeToString(alertID);
22934
}
22935
22936
#define STATE_STRINGS_PROTO(s) \
22937
    {                          \
22938
        {"SSLv3 " s,           \
22939
         "SSLv3 " s,           \
22940
         "SSLv3 " s},          \
22941
        {"TLSv1 " s,           \
22942
         "TLSv1 " s,           \
22943
         "TLSv1 " s},          \
22944
        {"TLSv1_1 " s,         \
22945
         "TLSv1_1 " s,         \
22946
         "TLSv1_1 " s},        \
22947
        {"TLSv1_2 " s,         \
22948
         "TLSv1_2 " s,         \
22949
         "TLSv1_2 " s},        \
22950
        {"TLSv1_3 " s,         \
22951
         "TLSv1_3 " s,         \
22952
         "TLSv1_3 " s},        \
22953
        {"DTLSv1 " s,          \
22954
         "DTLSv1 " s,          \
22955
         "DTLSv1 " s},         \
22956
        {"DTLSv1_2 " s,        \
22957
         "DTLSv1_2 " s,        \
22958
         "DTLSv1_2 " s},       \
22959
        {"DTLSv1_3 " s,        \
22960
         "DTLSv1_3 " s,        \
22961
         "DTLSv1_3 " s},       \
22962
    }
22963
22964
#define STATE_STRINGS_PROTO_RW(s) \
22965
    {                             \
22966
        {"SSLv3 read " s,         \
22967
         "SSLv3 write " s,        \
22968
         "SSLv3 " s},             \
22969
        {"TLSv1 read " s,         \
22970
         "TLSv1 write " s,        \
22971
         "TLSv1 " s},             \
22972
        {"TLSv1_1 read " s,       \
22973
         "TLSv1_1 write " s,      \
22974
         "TLSv1_1 " s},           \
22975
        {"TLSv1_2 read " s,       \
22976
         "TLSv1_2 write " s,      \
22977
         "TLSv1_2 " s},           \
22978
        {"TLSv1_3 read " s,       \
22979
         "TLSv1_3 write " s,      \
22980
         "TLSv1_3 " s},           \
22981
        {"DTLSv1 read " s,        \
22982
         "DTLSv1 write " s,       \
22983
         "DTLSv1 " s},            \
22984
        {"DTLSv1_2 read " s,      \
22985
         "DTLSv1_2 write " s,     \
22986
         "DTLSv1_2 " s},          \
22987
        {"DTLSv1_3 read " s,      \
22988
         "DTLSv1_3 write " s,     \
22989
         "DTLSv1_3 " s},          \
22990
    }
22991
22992
/* Gets the current state of the WOLFSSL structure
22993
 *
22994
 * ssl WOLFSSL structure to get state of
22995
 *
22996
 * Returns a human readable string of the WOLFSSL structure state
22997
 */
22998
const char* wolfSSL_state_string_long(const WOLFSSL* ssl)
22999
{
23000
23001
    static const char* OUTPUT_STR[24][8][3] = {
23002
        STATE_STRINGS_PROTO("Initialization"),
23003
        STATE_STRINGS_PROTO_RW("Server Hello Request"),
23004
        STATE_STRINGS_PROTO_RW("Server Hello Verify Request"),
23005
        STATE_STRINGS_PROTO_RW("Server Hello Retry Request"),
23006
        STATE_STRINGS_PROTO_RW("Server Hello"),
23007
        STATE_STRINGS_PROTO_RW("Server Certificate Status"),
23008
        STATE_STRINGS_PROTO_RW("Server Encrypted Extensions"),
23009
        STATE_STRINGS_PROTO_RW("Server Session Ticket"),
23010
        STATE_STRINGS_PROTO_RW("Server Certificate Request"),
23011
        STATE_STRINGS_PROTO_RW("Server Cert"),
23012
        STATE_STRINGS_PROTO_RW("Server Key Exchange"),
23013
        STATE_STRINGS_PROTO_RW("Server Hello Done"),
23014
        STATE_STRINGS_PROTO_RW("Server Change CipherSpec"),
23015
        STATE_STRINGS_PROTO_RW("Server Finished"),
23016
        STATE_STRINGS_PROTO_RW("server Key Update"),
23017
        STATE_STRINGS_PROTO_RW("Client Hello"),
23018
        STATE_STRINGS_PROTO_RW("Client Key Exchange"),
23019
        STATE_STRINGS_PROTO_RW("Client Cert"),
23020
        STATE_STRINGS_PROTO_RW("Client Change CipherSpec"),
23021
        STATE_STRINGS_PROTO_RW("Client Certificate Verify"),
23022
        STATE_STRINGS_PROTO_RW("Client End Of Early Data"),
23023
        STATE_STRINGS_PROTO_RW("Client Finished"),
23024
        STATE_STRINGS_PROTO_RW("Client Key Update"),
23025
        STATE_STRINGS_PROTO("Handshake Done"),
23026
    };
23027
    enum ProtocolVer {
23028
        SSL_V3 = 0,
23029
        TLS_V1,
23030
        TLS_V1_1,
23031
        TLS_V1_2,
23032
        TLS_V1_3,
23033
        DTLS_V1,
23034
        DTLS_V1_2,
23035
        DTLS_V1_3,
23036
        UNKNOWN = 100
23037
    };
23038
23039
    enum IOMode {
23040
        SS_READ = 0,
23041
        SS_WRITE,
23042
        SS_NEITHER
23043
    };
23044
23045
    enum SslState {
23046
        ss_null_state = 0,
23047
        ss_server_hellorequest,
23048
        ss_server_helloverify,
23049
        ss_server_helloretryrequest,
23050
        ss_server_hello,
23051
        ss_server_certificatestatus,
23052
        ss_server_encryptedextensions,
23053
        ss_server_sessionticket,
23054
        ss_server_certrequest,
23055
        ss_server_cert,
23056
        ss_server_keyexchange,
23057
        ss_server_hellodone,
23058
        ss_server_changecipherspec,
23059
        ss_server_finished,
23060
        ss_server_keyupdate,
23061
        ss_client_hello,
23062
        ss_client_keyexchange,
23063
        ss_client_cert,
23064
        ss_client_changecipherspec,
23065
        ss_client_certverify,
23066
        ss_client_endofearlydata,
23067
        ss_client_finished,
23068
        ss_client_keyupdate,
23069
        ss_handshake_done
23070
    };
23071
23072
    int protocol = 0;
23073
    int cbmode = 0;
23074
    int state = 0;
23075
23076
    WOLFSSL_ENTER("wolfSSL_state_string_long");
23077
    if (ssl == NULL) {
23078
        WOLFSSL_MSG("Null argument passed in");
23079
        return NULL;
23080
    }
23081
23082
    /* Get state of callback */
23083
    if (ssl->cbmode == SSL_CB_MODE_WRITE) {
23084
        cbmode =  SS_WRITE;
23085
    }
23086
    else if (ssl->cbmode == SSL_CB_MODE_READ) {
23087
        cbmode =  SS_READ;
23088
    }
23089
    else {
23090
        cbmode =  SS_NEITHER;
23091
    }
23092
23093
    /* Get protocol version */
23094
    switch (ssl->version.major) {
23095
        case SSLv3_MAJOR:
23096
            switch (ssl->version.minor) {
23097
                case SSLv3_MINOR:
23098
                    protocol = SSL_V3;
23099
                    break;
23100
                case TLSv1_MINOR:
23101
                    protocol = TLS_V1;
23102
                    break;
23103
                case TLSv1_1_MINOR:
23104
                    protocol = TLS_V1_1;
23105
                    break;
23106
                case TLSv1_2_MINOR:
23107
                    protocol = TLS_V1_2;
23108
                    break;
23109
                case TLSv1_3_MINOR:
23110
                    protocol = TLS_V1_3;
23111
                    break;
23112
                default:
23113
                    protocol = UNKNOWN;
23114
            }
23115
            break;
23116
        case DTLS_MAJOR:
23117
            switch (ssl->version.minor) {
23118
                case DTLS_MINOR:
23119
                    protocol = DTLS_V1;
23120
                    break;
23121
                case DTLSv1_2_MINOR:
23122
                    protocol = DTLS_V1_2;
23123
                    break;
23124
                case DTLSv1_3_MINOR:
23125
                    protocol = DTLS_V1_3;
23126
                    break;
23127
                default:
23128
                    protocol = UNKNOWN;
23129
            }
23130
            break;
23131
    default:
23132
        protocol = UNKNOWN;
23133
    }
23134
23135
    /* accept process */
23136
    if (ssl->cbmode == SSL_CB_MODE_READ) {
23137
        state = ssl->cbtype;
23138
        switch (state) {
23139
            case hello_request:
23140
                state = ss_server_hellorequest;
23141
                break;
23142
            case client_hello:
23143
                state = ss_client_hello;
23144
                break;
23145
            case server_hello:
23146
                state = ss_server_hello;
23147
                break;
23148
            case hello_verify_request:
23149
                state = ss_server_helloverify;
23150
                break;
23151
            case session_ticket:
23152
                state = ss_server_sessionticket;
23153
                break;
23154
            case end_of_early_data:
23155
                state = ss_client_endofearlydata;
23156
                break;
23157
            case hello_retry_request:
23158
                state = ss_server_helloretryrequest;
23159
                break;
23160
            case encrypted_extensions:
23161
                state = ss_server_encryptedextensions;
23162
                break;
23163
            case certificate:
23164
                if (ssl->options.side == WOLFSSL_SERVER_END)
23165
                    state = ss_client_cert;
23166
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
23167
                    state = ss_server_cert;
23168
                else {
23169
                    WOLFSSL_MSG("Unknown State");
23170
                    state = ss_null_state;
23171
                }
23172
                break;
23173
            case server_key_exchange:
23174
                state = ss_server_keyexchange;
23175
                break;
23176
            case certificate_request:
23177
                state = ss_server_certrequest;
23178
                break;
23179
            case server_hello_done:
23180
                state = ss_server_hellodone;
23181
                break;
23182
            case certificate_verify:
23183
                state = ss_client_certverify;
23184
                break;
23185
            case client_key_exchange:
23186
                state = ss_client_keyexchange;
23187
                break;
23188
            case finished:
23189
                if (ssl->options.side == WOLFSSL_SERVER_END)
23190
                    state = ss_client_finished;
23191
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
23192
                    state = ss_server_finished;
23193
                else {
23194
                    WOLFSSL_MSG("Unknown State");
23195
                    state = ss_null_state;
23196
                }
23197
                break;
23198
            case certificate_status:
23199
                state = ss_server_certificatestatus;
23200
                break;
23201
            case key_update:
23202
                if (ssl->options.side == WOLFSSL_SERVER_END)
23203
                    state = ss_client_keyupdate;
23204
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
23205
                    state = ss_server_keyupdate;
23206
                else {
23207
                    WOLFSSL_MSG("Unknown State");
23208
                    state = ss_null_state;
23209
                }
23210
                break;
23211
            case change_cipher_hs:
23212
                if (ssl->options.side == WOLFSSL_SERVER_END)
23213
                    state = ss_client_changecipherspec;
23214
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
23215
                    state = ss_server_changecipherspec;
23216
                else {
23217
                    WOLFSSL_MSG("Unknown State");
23218
                    state = ss_null_state;
23219
                }
23220
                break;
23221
            default:
23222
                WOLFSSL_MSG("Unknown State");
23223
                state = ss_null_state;
23224
        }
23225
    }
23226
    else {
23227
        /* Send process */
23228
        if (ssl->options.side == WOLFSSL_SERVER_END)
23229
            state = ssl->options.serverState;
23230
        else
23231
            state = ssl->options.clientState;
23232
23233
        switch (state) {
23234
            case SERVER_HELLOVERIFYREQUEST_COMPLETE:
23235
                state = ss_server_helloverify;
23236
                break;
23237
            case SERVER_HELLO_RETRY_REQUEST_COMPLETE:
23238
                state = ss_server_helloretryrequest;
23239
                break;
23240
            case SERVER_HELLO_COMPLETE:
23241
                state = ss_server_hello;
23242
                break;
23243
            case SERVER_ENCRYPTED_EXTENSIONS_COMPLETE:
23244
                state = ss_server_encryptedextensions;
23245
                break;
23246
            case SERVER_CERT_COMPLETE:
23247
                state = ss_server_cert;
23248
                break;
23249
            case SERVER_KEYEXCHANGE_COMPLETE:
23250
                state = ss_server_keyexchange;
23251
                break;
23252
            case SERVER_HELLODONE_COMPLETE:
23253
                state = ss_server_hellodone;
23254
                break;
23255
            case SERVER_CHANGECIPHERSPEC_COMPLETE:
23256
                state = ss_server_changecipherspec;
23257
                break;
23258
            case SERVER_FINISHED_COMPLETE:
23259
                state = ss_server_finished;
23260
                break;
23261
            case CLIENT_HELLO_RETRY:
23262
            case CLIENT_HELLO_COMPLETE:
23263
                state = ss_client_hello;
23264
                break;
23265
            case CLIENT_KEYEXCHANGE_COMPLETE:
23266
                state = ss_client_keyexchange;
23267
                break;
23268
            case CLIENT_CHANGECIPHERSPEC_COMPLETE:
23269
                state = ss_client_changecipherspec;
23270
                break;
23271
            case CLIENT_FINISHED_COMPLETE:
23272
                state = ss_client_finished;
23273
                break;
23274
            case HANDSHAKE_DONE:
23275
                state = ss_handshake_done;
23276
                break;
23277
            default:
23278
                WOLFSSL_MSG("Unknown State");
23279
                state = ss_null_state;
23280
        }
23281
    }
23282
23283
    if (protocol == UNKNOWN) {
23284
        WOLFSSL_MSG("Unknown protocol");
23285
        return "";
23286
    }
23287
    else {
23288
        return OUTPUT_STR[state][protocol][cbmode];
23289
    }
23290
}
23291
23292
/*
23293
 * Sets default PEM callback password if null is passed into
23294
 * the callback parameter of a PEM_read_bio_* function.
23295
 *
23296
 * Returns callback phrase size on success or WOLFSSL_FAILURE otherwise.
23297
 */
23298
int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
23299
{
23300
    int sz;
23301
    (void)w;
23302
    WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
23303
23304
    /* We assume that the user passes a default password as userdata */
23305
    if (key) {
23306
        sz = (int)XSTRLEN((const char*)key);
23307
        sz = (sz > num) ? num : sz;
23308
        XMEMCPY(name, key, sz);
23309
        return sz;
23310
    } else {
23311
        WOLFSSL_MSG("Error, default password cannot be created.");
23312
        return WOLFSSL_FAILURE;
23313
    }
23314
}
23315
23316
#endif /* OPENSSL_EXTRA */
23317
23318
static long wolf_set_options(long old_op, long op)
23319
0
{
23320
    /* if SSL_OP_ALL then turn all bug workarounds on */
23321
0
    if ((op & WOLFSSL_OP_ALL) == WOLFSSL_OP_ALL) {
23322
0
        WOLFSSL_MSG("\tSSL_OP_ALL");
23323
0
    }
23324
23325
    /* by default cookie exchange is on with DTLS */
23326
0
    if ((op & WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE) {
23327
0
        WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
23328
0
    }
23329
23330
0
    if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
23331
0
        WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
23332
0
    }
23333
23334
#ifdef SSL_OP_NO_TLSv1_3
23335
    if ((op & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
23336
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
23337
    }
23338
#endif
23339
23340
0
    if ((op & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
23341
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
23342
0
    }
23343
23344
0
    if ((op & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
23345
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
23346
0
    }
23347
23348
0
    if ((op & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
23349
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
23350
0
    }
23351
23352
0
    if ((op & WOLFSSL_OP_NO_SSLv3) == WOLFSSL_OP_NO_SSLv3) {
23353
0
        WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
23354
0
    }
23355
23356
0
    if ((op & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) ==
23357
0
            WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
23358
0
        WOLFSSL_MSG("\tWOLFSSL_OP_CIPHER_SERVER_PREFERENCE");
23359
0
    }
23360
23361
0
    if ((op & WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION) {
23362
    #ifdef HAVE_LIBZ
23363
        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
23364
    #else
23365
0
        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
23366
0
    #endif
23367
0
    }
23368
23369
0
    return old_op | op;
23370
0
}
23371
23372
long wolfSSL_set_options(WOLFSSL* ssl, long op)
23373
0
{
23374
0
    word16 haveRSA = 1;
23375
0
    word16 havePSK = 0;
23376
0
    int    keySz   = 0;
23377
23378
0
    WOLFSSL_ENTER("wolfSSL_set_options");
23379
23380
0
    if (ssl == NULL) {
23381
0
        return 0;
23382
0
    }
23383
23384
0
    ssl->options.mask = wolf_set_options(ssl->options.mask, op);
23385
23386
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
23387
0
        if (ssl->version.minor == TLSv1_3_MINOR)
23388
0
            ssl->version.minor = TLSv1_2_MINOR;
23389
0
    }
23390
23391
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
23392
0
        if (ssl->version.minor == TLSv1_2_MINOR)
23393
0
            ssl->version.minor = TLSv1_1_MINOR;
23394
0
    }
23395
23396
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
23397
0
        if (ssl->version.minor == TLSv1_1_MINOR)
23398
0
            ssl->version.minor = TLSv1_MINOR;
23399
0
    }
23400
23401
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
23402
0
        if (ssl->version.minor == TLSv1_MINOR)
23403
0
            ssl->version.minor = SSLv3_MINOR;
23404
0
    }
23405
23406
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_COMPRESSION)
23407
0
        == WOLFSSL_OP_NO_COMPRESSION) {
23408
    #ifdef HAVE_LIBZ
23409
        ssl->options.usingCompression = 0;
23410
    #endif
23411
0
    }
23412
23413
    /* in the case of a version change the cipher suites should be reset */
23414
#ifndef NO_PSK
23415
    havePSK = ssl->options.havePSK;
23416
#endif
23417
#ifdef NO_RSA
23418
    haveRSA = 0;
23419
#endif
23420
0
#ifndef NO_CERTS
23421
0
    keySz = ssl->buffers.keySz;
23422
0
#endif
23423
23424
0
    if (ssl->suites != NULL && ssl->options.side != WOLFSSL_NEITHER_END)
23425
0
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
23426
0
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
23427
0
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
23428
0
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
23429
0
                   ssl->options.haveAnon, TRUE, ssl->options.side);
23430
23431
0
    return ssl->options.mask;
23432
0
}
23433
23434
23435
long wolfSSL_get_options(const WOLFSSL* ssl)
23436
0
{
23437
0
    WOLFSSL_ENTER("wolfSSL_get_options");
23438
0
    if(ssl == NULL)
23439
0
        return WOLFSSL_FAILURE;
23440
0
    return ssl->options.mask;
23441
0
}
23442
23443
#if defined(HAVE_SECURE_RENEGOTIATION) \
23444
        || defined(HAVE_SERVER_RENEGOTIATION_INFO)
23445
/* clears the counter for number of renegotiations done
23446
 * returns the current count before it is cleared */
23447
long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
23448
0
{
23449
0
    long total;
23450
23451
0
    WOLFSSL_ENTER("wolfSSL_clear_num_renegotiations");
23452
0
    if (s == NULL)
23453
0
        return 0;
23454
23455
0
    total = s->secure_rene_count;
23456
0
    s->secure_rene_count = 0;
23457
0
    return total;
23458
0
}
23459
23460
23461
/* return the number of renegotiations since wolfSSL_new */
23462
long wolfSSL_total_renegotiations(WOLFSSL *s)
23463
0
{
23464
0
    WOLFSSL_ENTER("wolfSSL_total_renegotiations");
23465
0
    return wolfSSL_num_renegotiations(s);
23466
0
}
23467
23468
23469
/* return the number of renegotiations since wolfSSL_new */
23470
long wolfSSL_num_renegotiations(WOLFSSL* s)
23471
0
{
23472
0
    if (s == NULL) {
23473
0
        return 0;
23474
0
    }
23475
23476
0
    return s->secure_rene_count;
23477
0
}
23478
23479
23480
/* Is there a renegotiation currently in progress? */
23481
int  wolfSSL_SSL_renegotiate_pending(WOLFSSL *s)
23482
0
{
23483
0
    return s && s->options.handShakeDone &&
23484
0
            s->options.handShakeState != HANDSHAKE_DONE ? 1 : 0;
23485
0
}
23486
#endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
23487
23488
#ifdef OPENSSL_EXTRA
23489
23490
long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
23491
{
23492
    WOLFSSL_ENTER("SSL_clear_options");
23493
    if(ssl == NULL)
23494
        return WOLFSSL_FAILURE;
23495
    ssl->options.mask &= ~opt;
23496
    return ssl->options.mask;
23497
}
23498
23499
#ifdef HAVE_PK_CALLBACKS
23500
long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
23501
{
23502
    if (ssl == NULL) {
23503
        return WOLFSSL_FAILURE;
23504
    }
23505
23506
    ssl->loggingCtx = arg;
23507
    return WOLFSSL_SUCCESS;
23508
}
23509
#endif /* HAVE_PK_CALLBACKS */
23510
23511
#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
23512
const unsigned char *SSL_SESSION_get0_id_context(const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length)
23513
{
23514
    sess = ClientSessionToSession(sess);
23515
    return wolfSSL_SESSION_get_id((WOLFSSL_SESSION *)sess, sid_ctx_length);
23516
}
23517
#endif
23518
23519
/*** TBD ***/
23520
#ifndef NO_WOLFSSL_STUB
23521
WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st)
23522
{
23523
    (void)st;
23524
    WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero");
23525
    /* wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); */
23526
    return WOLFSSL_FAILURE;
23527
}
23528
#endif
23529
23530
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
23531
long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type)
23532
{
23533
    WOLFSSL_ENTER("wolfSSL_set_tlsext_status_type");
23534
23535
    if (s == NULL){
23536
        return BAD_FUNC_ARG;
23537
    }
23538
23539
    if (type == TLSEXT_STATUSTYPE_ocsp){
23540
        int r = TLSX_UseCertificateStatusRequest(&s->extensions, (byte)type, 0, s,
23541
                                                             s->heap, s->devId);
23542
        return (long)r;
23543
    } else {
23544
        WOLFSSL_MSG(
23545
       "SSL_set_tlsext_status_type only supports TLSEXT_STATUSTYPE_ocsp type.");
23546
        return SSL_FAILURE;
23547
    }
23548
23549
}
23550
23551
long wolfSSL_get_tlsext_status_type(WOLFSSL *s)
23552
{
23553
    TLSX* extension;
23554
23555
    if (s == NULL)
23556
        return WOLFSSL_FATAL_ERROR;
23557
    extension = TLSX_Find(s->extensions, TLSX_STATUS_REQUEST);
23558
    return extension != NULL ? TLSEXT_STATUSTYPE_ocsp : WOLFSSL_FATAL_ERROR;
23559
}
23560
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
23561
23562
#ifndef NO_WOLFSSL_STUB
23563
WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
23564
{
23565
    (void)s;
23566
    (void)arg;
23567
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
23568
    return WOLFSSL_FAILURE;
23569
}
23570
#endif
23571
23572
/*** TBD ***/
23573
#ifndef NO_WOLFSSL_STUB
23574
WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
23575
{
23576
    (void)s;
23577
    (void)arg;
23578
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
23579
    return WOLFSSL_FAILURE;
23580
}
23581
#endif
23582
23583
/*** TBD ***/
23584
#ifndef NO_WOLFSSL_STUB
23585
WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
23586
{
23587
    (void)s;
23588
    (void)arg;
23589
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
23590
    return WOLFSSL_FAILURE;
23591
}
23592
#endif
23593
23594
/*** TBD ***/
23595
#ifndef NO_WOLFSSL_STUB
23596
WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
23597
{
23598
    (void)s;
23599
    (void)arg;
23600
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
23601
    return WOLFSSL_FAILURE;
23602
}
23603
#endif
23604
23605
/*** TBD ***/
23606
#ifndef NO_WOLFSSL_STUB
23607
WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len)
23608
{
23609
    (void)s;
23610
    (void)sid;
23611
    (void)sid_len;
23612
    WOLFSSL_STUB("SSL_SESSION_set1_id");
23613
    return WOLFSSL_FAILURE;
23614
}
23615
#endif
23616
23617
#ifndef NO_WOLFSSL_STUB
23618
/*** TBD ***/
23619
WOLFSSL_API int SSL_SESSION_set1_id_context(WOLFSSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len)
23620
{
23621
    (void)s;
23622
    (void)sid_ctx;
23623
    (void)sid_ctx_len;
23624
    WOLFSSL_STUB("SSL_SESSION_set1_id_context");
23625
    return WOLFSSL_FAILURE;
23626
}
23627
#endif
23628
23629
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
23630
    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
23631
/**
23632
 * Set `a` in a smart way.
23633
 *
23634
 * @param a Object to set
23635
 * @param type The type of object in value
23636
 * @param value Object to set
23637
 */
23638
void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value)
23639
{
23640
    if (!a) {
23641
        return;
23642
    }
23643
    switch (type) {
23644
        case V_ASN1_NULL:
23645
            a->value.ptr = (char *)value;
23646
            break;
23647
        case V_ASN1_SEQUENCE:
23648
            a->value.asn1_string = (WOLFSSL_ASN1_STRING*)value;
23649
            break;
23650
        case V_ASN1_OBJECT:
23651
            a->value.object = (WOLFSSL_ASN1_OBJECT*)value;
23652
            break;
23653
        case V_ASN1_UTCTIME:
23654
            a->value.utctime = (WOLFSSL_ASN1_TIME*)value;
23655
            break;
23656
        case V_ASN1_GENERALIZEDTIME:
23657
            a->value.generalizedtime = (WOLFSSL_ASN1_TIME*)value;
23658
            break;
23659
        default:
23660
            WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
23661
            return;
23662
    }
23663
    a->type = type;
23664
}
23665
23666
#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY || WOLFSSL_WPAS */
23667
23668
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
23669
    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS) \
23670
    || defined(OPENSSL_EXTRA)
23671
/**
23672
 * Allocate a new WOLFSSL_ASN1_TYPE object.
23673
 *
23674
 * @return New zero'ed WOLFSSL_ASN1_TYPE object
23675
 */
23676
WOLFSSL_ASN1_TYPE* wolfSSL_ASN1_TYPE_new(void)
23677
{
23678
    WOLFSSL_ASN1_TYPE* ret = (WOLFSSL_ASN1_TYPE*)XMALLOC(sizeof(WOLFSSL_ASN1_TYPE),
23679
                                                        NULL, DYNAMIC_TYPE_OPENSSL);
23680
    if (!ret)
23681
        return NULL;
23682
    XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TYPE));
23683
    return ret;
23684
}
23685
23686
/**
23687
 * Free WOLFSSL_ASN1_TYPE and all its members.
23688
 *
23689
 * @param at Object to free
23690
 */
23691
void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at)
23692
{
23693
    if (at) {
23694
        switch (at->type) {
23695
            case V_ASN1_OBJECT:
23696
                wolfSSL_ASN1_OBJECT_free(at->value.object);
23697
                break;
23698
            case V_ASN1_UTCTIME:
23699
            #ifndef NO_ASN_TIME
23700
                wolfSSL_ASN1_TIME_free(at->value.utctime);
23701
            #endif
23702
                break;
23703
            case V_ASN1_GENERALIZEDTIME:
23704
            #ifndef NO_ASN_TIME
23705
                wolfSSL_ASN1_TIME_free(at->value.generalizedtime);
23706
            #endif
23707
                break;
23708
            case V_ASN1_UTF8STRING:
23709
            case V_ASN1_PRINTABLESTRING:
23710
            case V_ASN1_T61STRING:
23711
            case V_ASN1_IA5STRING:
23712
            case V_ASN1_UNIVERSALSTRING:
23713
            case V_ASN1_SEQUENCE:
23714
                wolfSSL_ASN1_STRING_free(at->value.asn1_string);
23715
                break;
23716
            default:
23717
                WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
23718
                break;
23719
        }
23720
        XFREE(at, NULL, DYNAMIC_TYPE_OPENSSL);
23721
    }
23722
}
23723
#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY || WOLFSSL_WPAS
23724
        || OPENSSL_EXTRA */
23725
23726
23727
23728
#ifndef NO_WOLFSSL_STUB
23729
/*** TBD ***/
23730
WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
23731
{
23732
    (void)ssl;
23733
    WOLFSSL_STUB("SSL_get_privatekey");
23734
    return NULL;
23735
}
23736
#endif
23737
23738
/**
23739
 * Get a textual representation of given WOLFSSL_ASN1_OBJECT then write it to
23740
 * buf at most buf_len bytes.
23741
 *
23742
 * params
23743
 * - buf: buffer where the textual representation is to be written to
23744
 * - buf_len: buffer size in bytes
23745
 * - a: WOLFSSL_ASN1_OBJECT
23746
 *
23747
 * return the string length written on success, WOLFSSL_FAILURE on failure.
23748
 */
23749
WOLFSSL_API int wolfSSL_i2t_ASN1_OBJECT(char *buf, int buf_len,
23750
                                                WOLFSSL_ASN1_OBJECT *a)
23751
{
23752
    WOLFSSL_ENTER("wolfSSL_i2t_ASN1_OBJECT");
23753
    return wolfSSL_OBJ_obj2txt(buf, buf_len, a, 0);
23754
}
23755
23756
WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
23757
                                             const unsigned char **der,
23758
                                             long length)
23759
{
23760
    const unsigned char *d;
23761
    long len;
23762
    int tag, cls;
23763
    WOLFSSL_ASN1_OBJECT* ret = NULL;
23764
23765
    WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OBJECT");
23766
23767
    if (!der || !*der || length <= 0) {
23768
        WOLFSSL_MSG("Bad parameter");
23769
        return NULL;
23770
    }
23771
23772
    d = *der;
23773
23774
    if (wolfSSL_ASN1_get_object(&d, &len, &tag, &cls, length) & 0x80) {
23775
        WOLFSSL_MSG("wolfSSL_ASN1_get_object error");
23776
        return NULL;
23777
    }
23778
    /* d now points to value */
23779
23780
    if (tag != ASN_OBJECT_ID) {
23781
        WOLFSSL_MSG("Not an ASN object");
23782
        return NULL;
23783
    }
23784
23785
    ret = wolfSSL_c2i_ASN1_OBJECT(a, &d, len);
23786
    if (ret)
23787
        *der = d;
23788
    return ret;
23789
}
23790
23791
/**
23792
 * Parse an ASN1 encoded input and output information about the parsed object
23793
 * @param in    ASN1 encoded data. *in is moved to the value of the ASN1 object
23794
 * @param len   Length of parsed ASN1 object
23795
 * @param tag   Tag value of parsed ASN1 object
23796
 * @param cls   Class of parsed ASN1 object
23797
 * @param inLen Length of *in buffer
23798
 * @return int  Depends on which bits are set in the returned int:
23799
 *              0x80 an error occurred during parsing
23800
 *              0x20 parsed object is constructed
23801
 *              0x01 the parsed object length is infinite
23802
 */
23803
int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag,
23804
                            int *cls, long inLen)
23805
{
23806
    word32 inOutIdx = 0;
23807
    int l;
23808
    byte t;
23809
    int ret = 0x80;
23810
23811
    WOLFSSL_ENTER("wolfSSL_ASN1_get_object");
23812
23813
    if (!in || !*in || !len || !tag || !cls || inLen == 0) {
23814
        WOLFSSL_MSG("Bad parameter");
23815
        return ret;
23816
    }
23817
23818
    if (GetASNTag(*in, &inOutIdx, &t, (word32)inLen) != 0) {
23819
        WOLFSSL_MSG("GetASNTag error");
23820
        return ret;
23821
    }
23822
23823
    if (GetLength(*in, &inOutIdx, &l, (word32)inLen) < 0) {
23824
        WOLFSSL_MSG("GetLength error");
23825
        return ret;
23826
    }
23827
23828
    *tag = t & 0x1F; /* Tag number is 5 lsb */
23829
    *cls = t & 0xC0; /* Class is 2 msb */
23830
    *len = l;
23831
    ret = t & ASN_CONSTRUCTED;
23832
23833
    if (l > (int)(inLen - inOutIdx)) {
23834
        /* Still return other values but indicate error in msb */
23835
        ret |= 0x80;
23836
    }
23837
23838
    *in += inOutIdx;
23839
    return ret;
23840
}
23841
23842
WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
23843
        const unsigned char **pp, long len)
23844
{
23845
    WOLFSSL_ASN1_OBJECT* ret = NULL;
23846
23847
    WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT");
23848
23849
    if (!pp || !*pp || len <= 0) {
23850
        WOLFSSL_MSG("Bad parameter");
23851
        return NULL;
23852
    }
23853
23854
    if (!(ret = wolfSSL_ASN1_OBJECT_new())) {
23855
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error");
23856
        return NULL;
23857
    }
23858
23859
    ret->obj = (const unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
23860
    if (!ret->obj) {
23861
        WOLFSSL_MSG("error allocating asn data memory");
23862
        wolfSSL_ASN1_OBJECT_free(ret);
23863
        return NULL;
23864
    }
23865
23866
    XMEMCPY((byte*)ret->obj, *pp, len);
23867
    ret->objSz = (unsigned int)len;
23868
    ret->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
23869
23870
    *pp += len;
23871
23872
    if (a)
23873
        *a = ret;
23874
    return ret;
23875
}
23876
23877
#ifndef NO_BIO
23878
/* Return number of bytes written to BIO on success. 0 on failure. */
23879
WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp,
23880
                                        WOLFSSL_ASN1_OBJECT *a)
23881
{
23882
    int length = 0;
23883
    word32 idx = 0;
23884
    const char null_str[] = "NULL";
23885
23886
    WOLFSSL_ENTER("wolfSSL_i2a_ASN1_OBJECT");
23887
23888
    if (bp == NULL)
23889
        return WOLFSSL_FAILURE;
23890
23891
    if (a == NULL) {
23892
        /* Write "NULL" */
23893
        if (wolfSSL_BIO_write(bp, null_str, (int)XSTRLEN(null_str)) ==
23894
                (int)XSTRLEN(null_str)) {
23895
            return (int)XSTRLEN(null_str);
23896
        }
23897
        else {
23898
            return WOLFSSL_FAILURE;
23899
        }
23900
    }
23901
23902
23903
    if ((a->obj == NULL) || (a->obj[idx++] != ASN_OBJECT_ID)) {
23904
        WOLFSSL_MSG("Bad ASN1 Object");
23905
        return WOLFSSL_FAILURE;
23906
    }
23907
23908
    if (GetLength((const byte*)a->obj, &idx, &length,
23909
                   a->objSz) < 0 || length < 0) {
23910
        return WOLFSSL_FAILURE;
23911
    }
23912
23913
    if (wolfSSL_BIO_write(bp, a->obj + idx, length) == (int)length) {
23914
        return length;
23915
    }
23916
23917
    return WOLFSSL_FAILURE;
23918
}
23919
#endif /* !NO_BIO */
23920
23921
/* Returns object data for an ASN1_OBJECT */
23922
/* If pp is NULL then only the size is returned */
23923
/* If pp has pointer to pointer then its used directly */
23924
/* If pp has pointer to pointer that is NULL then new variable is allocated */
23925
/* Failure returns WOLFSSL_FAILURE (0) */
23926
int wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT *a, unsigned char **pp)
23927
{
23928
    byte *p;
23929
23930
    WOLFSSL_ENTER("wolfSSL_i2d_ASN1_OBJECT");
23931
23932
    if (!a || !a->obj) {
23933
        WOLFSSL_MSG("Bad parameters");
23934
        return WOLFSSL_FAILURE;
23935
    }
23936
23937
    if (!pp)
23938
        return a->objSz;
23939
23940
    if (*pp)
23941
        p = *pp;
23942
    else {
23943
        p = (byte*)XMALLOC(a->objSz, NULL, DYNAMIC_TYPE_OPENSSL);
23944
        if (!p) {
23945
            WOLFSSL_MSG("Bad malloc");
23946
            return WOLFSSL_FAILURE;
23947
        }
23948
    }
23949
23950
    XMEMCPY(p, a->obj, a->objSz);
23951
    *pp = p + a->objSz;
23952
    return a->objSz;
23953
}
23954
23955
#ifndef NO_WOLFSSL_STUB
23956
/*** TBD ***/
23957
WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
23958
{
23959
    (void)ctx;
23960
    (void)dh;
23961
    WOLFSSL_STUB("SSL_CTX_set_tmp_dh_callback");
23962
}
23963
#endif
23964
23965
#ifndef NO_WOLFSSL_STUB
23966
/*** TBD ***/
23967
WOLFSSL_API WOLF_STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
23968
{
23969
    WOLFSSL_STUB("SSL_COMP_get_compression_methods");
23970
    return NULL;
23971
}
23972
#endif
23973
23974
23975
int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p)
23976
{
23977
    WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_num");
23978
    if (p == NULL) {
23979
        return WOLFSSL_FATAL_ERROR;
23980
    }
23981
    return (int)p->num;
23982
}
23983
23984
WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* sk, int i)
23985
{
23986
    WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value");
23987
    return (WOLFSSL_CIPHER*)wolfSSL_sk_value(sk, i);
23988
}
23989
23990
#if !defined(NETOS)
23991
WOLFSSL_API void ERR_load_SSL_strings(void)
23992
{
23993
23994
}
23995
#endif
23996
23997
#ifdef HAVE_OCSP
23998
WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp)
23999
{
24000
    if (s == NULL || resp == NULL)
24001
        return 0;
24002
24003
    *resp = s->ocspResp;
24004
    return s->ocspRespSz;
24005
}
24006
24007
WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len)
24008
{
24009
    if (s == NULL)
24010
        return WOLFSSL_FAILURE;
24011
24012
    s->ocspResp   = resp;
24013
    s->ocspRespSz = len;
24014
24015
    return WOLFSSL_SUCCESS;
24016
}
24017
#endif /* HAVE_OCSP */
24018
24019
#ifdef HAVE_MAX_FRAGMENT
24020
#ifndef NO_WOLFSSL_CLIENT
24021
/**
24022
 * Set max fragment tls extension
24023
 * @param c a pointer to WOLFSSL_CTX object
24024
 * @param mode maximum fragment length mode
24025
 * @return 1 on success, otherwise 0 or negative error code
24026
 */
24027
WOLFSSL_API int wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX *c,
24028
                                                            unsigned char mode)
24029
{
24030
    if (c == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
24031
        return BAD_FUNC_ARG;
24032
24033
    return wolfSSL_CTX_UseMaxFragment(c, mode);
24034
}
24035
/**
24036
 * Set max fragment tls extension
24037
 * @param c a pointer to WOLFSSL object
24038
 * @param mode maximum fragment length mode
24039
 * @return 1 on success, otherwise 0 or negative error code
24040
 */
24041
WOLFSSL_API int wolfSSL_set_tlsext_max_fragment_length(WOLFSSL *s,
24042
                                                            unsigned char mode)
24043
{
24044
    if (s == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
24045
        return BAD_FUNC_ARG;
24046
24047
    return wolfSSL_UseMaxFragment(s, mode);
24048
}
24049
#endif /* NO_WOLFSSL_CLIENT */
24050
#endif /* HAVE_MAX_FRAGMENT */
24051
24052
#endif /* OPENSSL_EXTRA */
24053
24054
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
24055
WOLFSSL_API size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count)
24056
{
24057
    byte len = 0;
24058
24059
    WOLFSSL_ENTER("SSL_get_finished");
24060
24061
    if (!ssl || !buf || count < TLS_FINISHED_SZ) {
24062
        WOLFSSL_MSG("Bad parameter");
24063
        return WOLFSSL_FAILURE;
24064
    }
24065
24066
    if (ssl->options.side == WOLFSSL_SERVER_END) {
24067
        len = ssl->serverFinished_len;
24068
        XMEMCPY(buf, ssl->serverFinished, len);
24069
    }
24070
    else {
24071
        len = ssl->clientFinished_len;
24072
        XMEMCPY(buf, ssl->clientFinished, len);
24073
    }
24074
    return len;
24075
}
24076
24077
WOLFSSL_API size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count)
24078
{
24079
    byte len = 0;
24080
    WOLFSSL_ENTER("SSL_get_peer_finished");
24081
24082
    if (!ssl || !buf || count < TLS_FINISHED_SZ) {
24083
        WOLFSSL_MSG("Bad parameter");
24084
        return WOLFSSL_FAILURE;
24085
    }
24086
24087
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
24088
        len = ssl->serverFinished_len;
24089
        XMEMCPY(buf, ssl->serverFinished, len);
24090
    }
24091
    else {
24092
        len = ssl->clientFinished_len;
24093
        XMEMCPY(buf, ssl->clientFinished, len);
24094
    }
24095
24096
    return len;
24097
}
24098
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
24099
24100
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
24101
long wolfSSL_get_verify_result(const WOLFSSL *ssl)
24102
{
24103
    if (ssl == NULL) {
24104
        return WOLFSSL_FAILURE;
24105
    }
24106
24107
    return ssl->peerVerifyRet;
24108
}
24109
#endif
24110
24111
#ifdef OPENSSL_EXTRA
24112
24113
#ifndef NO_WOLFSSL_STUB
24114
/* shows the number of accepts attempted by CTX in it's lifetime */
24115
long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
24116
{
24117
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
24118
    (void)ctx;
24119
    return 0;
24120
}
24121
#endif
24122
24123
#ifndef NO_WOLFSSL_STUB
24124
/* shows the number of connects attempted CTX in it's lifetime */
24125
long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
24126
{
24127
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
24128
    (void)ctx;
24129
    return 0;
24130
}
24131
#endif
24132
24133
24134
#ifndef NO_WOLFSSL_STUB
24135
/* shows the number of accepts completed by CTX in it's lifetime */
24136
long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
24137
{
24138
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
24139
    (void)ctx;
24140
    return 0;
24141
}
24142
#endif
24143
24144
24145
#ifndef NO_WOLFSSL_STUB
24146
/* shows the number of connects completed by CTX in it's lifetime */
24147
long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
24148
{
24149
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
24150
    (void)ctx;
24151
    return 0;
24152
}
24153
#endif
24154
24155
24156
#ifndef NO_WOLFSSL_STUB
24157
/* shows the number of renegotiation accepts attempted by CTX */
24158
long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
24159
{
24160
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
24161
    (void)ctx;
24162
    return 0;
24163
}
24164
#endif
24165
24166
24167
#ifndef NO_WOLFSSL_STUB
24168
/* shows the number of renegotiation accepts attempted by CTX */
24169
long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
24170
{
24171
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
24172
    (void)ctx;
24173
    return 0;
24174
}
24175
#endif
24176
24177
24178
#ifndef NO_WOLFSSL_STUB
24179
long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
24180
{
24181
    WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
24182
    (void)ctx;
24183
    return 0;
24184
}
24185
#endif
24186
24187
24188
#ifndef NO_WOLFSSL_STUB
24189
long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
24190
{
24191
    WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
24192
    (void)ctx;
24193
    return 0;
24194
}
24195
#endif
24196
24197
24198
#ifndef NO_WOLFSSL_STUB
24199
long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
24200
{
24201
    WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
24202
    (void)ctx;
24203
    return 0;
24204
}
24205
#endif
24206
24207
24208
#ifndef NO_WOLFSSL_STUB
24209
long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
24210
{
24211
    WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
24212
    (void)ctx;
24213
    return 0;
24214
}
24215
#endif
24216
24217
24218
#ifndef NO_WOLFSSL_STUB
24219
long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
24220
{
24221
    WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
24222
    (void)ctx;
24223
    return 0;
24224
}
24225
#endif
24226
24227
24228
/* Return the total number of sessions */
24229
long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
24230
{
24231
    word32 total = 0;
24232
24233
    WOLFSSL_ENTER("wolfSSL_CTX_sess_number");
24234
    (void)ctx;
24235
24236
#if defined(WOLFSSL_SESSION_STATS) && !defined(NO_SESSION_CACHE)
24237
    if (wolfSSL_get_session_stats(NULL, &total, NULL, NULL) != WOLFSSL_SUCCESS) {
24238
        WOLFSSL_MSG("Error getting session stats");
24239
    }
24240
#else
24241
    WOLFSSL_MSG("Please use macro WOLFSSL_SESSION_STATS for session stats");
24242
#endif
24243
24244
    return (long)total;
24245
}
24246
24247
24248
#ifndef NO_CERTS
24249
long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
24250
{
24251
    byte* chain = NULL;
24252
    long  chainSz = 0;
24253
    int   derSz;
24254
    const byte* der;
24255
    int   ret;
24256
    int   idx = 0;
24257
    DerBuffer *derBuffer = NULL;
24258
24259
    WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
24260
24261
    if (ctx == NULL || x509 == NULL) {
24262
        WOLFSSL_MSG("Bad Argument");
24263
        return WOLFSSL_FAILURE;
24264
    }
24265
24266
    der = wolfSSL_X509_get_der(x509, &derSz);
24267
    if (der == NULL || derSz <= 0) {
24268
        WOLFSSL_MSG("Error getting X509 DER");
24269
        return WOLFSSL_FAILURE;
24270
    }
24271
24272
    if (ctx->certificate == NULL) {
24273
        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
24274
24275
        /* Process buffer makes first certificate the leaf. */
24276
        ret = ProcessBuffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
24277
                            NULL, NULL, 1, GET_VERIFY_SETTING_CTX(ctx));
24278
        if (ret != WOLFSSL_SUCCESS) {
24279
            WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
24280
            return WOLFSSL_FAILURE;
24281
        }
24282
    }
24283
    else {
24284
        /* TODO: Do this elsewhere. */
24285
        ret = AllocDer(&derBuffer, derSz, CERT_TYPE, ctx->heap);
24286
        if (ret != 0) {
24287
            WOLFSSL_MSG("Memory Error");
24288
            return WOLFSSL_FAILURE;
24289
        }
24290
        XMEMCPY(derBuffer->buffer, der, derSz);
24291
        ret = AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA,
24292
            GET_VERIFY_SETTING_CTX(ctx));
24293
        if (ret != WOLFSSL_SUCCESS) {
24294
            WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
24295
            return WOLFSSL_FAILURE;
24296
        }
24297
24298
        /* adding cert to existing chain */
24299
        if (ctx->certChain != NULL && ctx->certChain->length > 0) {
24300
            chainSz += ctx->certChain->length;
24301
        }
24302
        chainSz += OPAQUE24_LEN + derSz;
24303
24304
        chain = (byte*)XMALLOC(chainSz, ctx->heap, DYNAMIC_TYPE_DER);
24305
        if (chain == NULL) {
24306
            WOLFSSL_MSG("Memory Error");
24307
            return WOLFSSL_FAILURE;
24308
        }
24309
24310
        if (ctx->certChain != NULL && ctx->certChain->length > 0) {
24311
            XMEMCPY(chain, ctx->certChain->buffer, ctx->certChain->length);
24312
            idx = ctx->certChain->length;
24313
        }
24314
        c32to24(derSz, chain + idx);
24315
        idx += OPAQUE24_LEN;
24316
        XMEMCPY(chain + idx, der, derSz);
24317
        idx += derSz;
24318
#ifdef WOLFSSL_TLS13
24319
        ctx->certChainCnt++;
24320
#endif
24321
24322
        FreeDer(&ctx->certChain);
24323
        ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap);
24324
        if (ret == 0) {
24325
            XMEMCPY(ctx->certChain->buffer, chain, idx);
24326
        }
24327
    }
24328
24329
    /* on success WOLFSSL_X509 memory is responsibility of ctx */
24330
    wolfSSL_X509_free(x509);
24331
    if (chain != NULL)
24332
        XFREE(chain, ctx->heap, DYNAMIC_TYPE_DER);
24333
24334
    return WOLFSSL_SUCCESS;
24335
}
24336
24337
24338
long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg)
24339
{
24340
    if (ctx == NULL || ctx->cm == NULL) {
24341
        return WOLFSSL_FAILURE;
24342
    }
24343
24344
    ctx->cm->ocspIOCtx = arg;
24345
    return WOLFSSL_SUCCESS;
24346
}
24347
24348
#endif /* NO_CERTS */
24349
24350
24351
/* Get the session cache mode for CTX
24352
 *
24353
 * ctx  WOLFSSL_CTX struct to get cache mode from
24354
 *
24355
 * Returns a bit mask that has the session cache mode */
24356
WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx)
24357
{
24358
    long m = 0;
24359
24360
    WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
24361
24362
    if (ctx == NULL) {
24363
        return m;
24364
    }
24365
24366
    if (ctx->sessionCacheOff != 1) {
24367
        m |= SSL_SESS_CACHE_SERVER;
24368
    }
24369
24370
    if (ctx->sessionCacheFlushOff == 1) {
24371
        m |= SSL_SESS_CACHE_NO_AUTO_CLEAR;
24372
    }
24373
24374
#ifdef HAVE_EXT_CACHE
24375
    if (ctx->internalCacheOff == 1) {
24376
        m |= SSL_SESS_CACHE_NO_INTERNAL_STORE;
24377
    }
24378
    if (ctx->internalCacheLookupOff == 1) {
24379
        m |= SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;
24380
    }
24381
#endif
24382
24383
    return m;
24384
}
24385
24386
24387
int wolfSSL_get_read_ahead(const WOLFSSL* ssl)
24388
{
24389
    if (ssl == NULL) {
24390
        return WOLFSSL_FAILURE;
24391
    }
24392
24393
    return ssl->readAhead;
24394
}
24395
24396
24397
int wolfSSL_set_read_ahead(WOLFSSL* ssl, int v)
24398
{
24399
    if (ssl == NULL) {
24400
        return WOLFSSL_FAILURE;
24401
    }
24402
24403
    ssl->readAhead = (byte)v;
24404
24405
    return WOLFSSL_SUCCESS;
24406
}
24407
24408
24409
int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
24410
{
24411
    if (ctx == NULL) {
24412
        return WOLFSSL_FAILURE;
24413
    }
24414
24415
    return ctx->readAhead;
24416
}
24417
24418
24419
int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
24420
{
24421
    if (ctx == NULL) {
24422
        return WOLFSSL_FAILURE;
24423
    }
24424
24425
    ctx->readAhead = (byte)v;
24426
24427
    return WOLFSSL_SUCCESS;
24428
}
24429
24430
24431
long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
24432
        void* arg)
24433
{
24434
    if (ctx == NULL) {
24435
        return WOLFSSL_FAILURE;
24436
    }
24437
24438
    ctx->userPRFArg = arg;
24439
    return WOLFSSL_SUCCESS;
24440
}
24441
24442
24443
#ifndef NO_DES3
24444
/* 0 on success */
24445
int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes,
24446
                                               WOLFSSL_DES_key_schedule* key)
24447
{
24448
#ifdef WOLFSSL_CHECK_DESKEY
24449
    return wolfSSL_DES_set_key_checked(myDes, key);
24450
#else
24451
    wolfSSL_DES_set_key_unchecked(myDes, key);
24452
    return 0;
24453
#endif
24454
}
24455
24456
24457
24458
/* return true in fail case (1) */
24459
static int DES_check(word32 mask, word32 mask2, unsigned char* key)
24460
{
24461
    word32 value[2];
24462
24463
    /* sanity check on length made in wolfSSL_DES_set_key_checked */
24464
    value[0] = mask;
24465
    value[1] = mask2;
24466
    return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0;
24467
}
24468
24469
24470
/* check that the key is odd parity and is not a weak key
24471
 * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */
24472
int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes,
24473
                                               WOLFSSL_DES_key_schedule* key)
24474
{
24475
    if (myDes == NULL || key == NULL) {
24476
        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked");
24477
        return -2;
24478
    }
24479
    else {
24480
        word32 sz = sizeof(WOLFSSL_DES_key_schedule);
24481
24482
        /* sanity check before call to DES_check */
24483
        if (sz != (sizeof(word32) * 2)) {
24484
            WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size");
24485
            return -2;
24486
        }
24487
24488
        /* check odd parity */
24489
        if (wolfSSL_DES_check_key_parity(myDes) != 1) {
24490
            WOLFSSL_MSG("Odd parity test fail");
24491
            return -1;
24492
        }
24493
24494
        if (wolfSSL_DES_is_weak_key(myDes) == 1) {
24495
            WOLFSSL_MSG("Weak key found");
24496
            return -2;
24497
        }
24498
24499
        /* passed tests, now copy over key */
24500
        XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
24501
24502
        return 0;
24503
    }
24504
}
24505
24506
24507
/* check is not weak. Weak key list from Nist "Recommendation for the Triple
24508
 * Data Encryption Algorithm (TDEA) Block Cipher"
24509
 *
24510
 * returns 1 if is weak 0 if not
24511
 */
24512
int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key)
24513
{
24514
    word32 mask, mask2;
24515
24516
    WOLFSSL_ENTER("wolfSSL_DES_is_weak_key");
24517
24518
    if (key == NULL) {
24519
        WOLFSSL_MSG("NULL key passed in");
24520
        return 1;
24521
    }
24522
24523
    mask = 0x01010101; mask2 = 0x01010101;
24524
    if (DES_check(mask, mask2, *key)) {
24525
        WOLFSSL_MSG("Weak key found");
24526
        return 1;
24527
    }
24528
24529
    mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE;
24530
    if (DES_check(mask, mask2, *key)) {
24531
        WOLFSSL_MSG("Weak key found");
24532
        return 1;
24533
    }
24534
24535
    mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1;
24536
    if (DES_check(mask, mask2, *key)) {
24537
        WOLFSSL_MSG("Weak key found");
24538
        return 1;
24539
    }
24540
24541
    mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E;
24542
    if (DES_check(mask, mask2, *key)) {
24543
        WOLFSSL_MSG("Weak key found");
24544
        return 1;
24545
    }
24546
24547
    /* semi-weak *key check (list from same Nist paper) */
24548
    mask  = 0x011F011F; mask2 = 0x010E010E;
24549
    if (DES_check(mask, mask2, *key) ||
24550
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24551
        WOLFSSL_MSG("Weak key found");
24552
        return 1;
24553
    }
24554
24555
    mask  = 0x01E001E0; mask2 = 0x01F101F1;
24556
    if (DES_check(mask, mask2, *key) ||
24557
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24558
        WOLFSSL_MSG("Weak key found");
24559
        return 1;
24560
    }
24561
24562
    mask  = 0x01FE01FE; mask2 = 0x01FE01FE;
24563
    if (DES_check(mask, mask2, *key) ||
24564
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24565
        WOLFSSL_MSG("Weak key found");
24566
        return 1;
24567
    }
24568
24569
    mask  = 0x1FE01FE0; mask2 = 0x0EF10EF1;
24570
    if (DES_check(mask, mask2, *key) ||
24571
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24572
        WOLFSSL_MSG("Weak key found");
24573
        return 1;
24574
    }
24575
24576
    mask  = 0x1FFE1FFE; mask2 = 0x0EFE0EFE;
24577
    if (DES_check(mask, mask2, *key) ||
24578
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24579
        WOLFSSL_MSG("Weak key found");
24580
        return 1;
24581
    }
24582
24583
    return 0;
24584
}
24585
24586
24587
void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
24588
                                               WOLFSSL_DES_key_schedule* key)
24589
{
24590
    if (myDes != NULL && key != NULL) {
24591
        XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
24592
    }
24593
}
24594
24595
24596
/* Sets the parity of the DES key for use */
24597
void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
24598
{
24599
    word32 i;
24600
    word32 sz = sizeof(WOLFSSL_DES_cblock);
24601
24602
    WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity");
24603
24604
    for (i = 0; i < sz; i++) {
24605
        unsigned char c = (*myDes)[i];
24606
        if ((
24607
            ((c >> 1) & 0x01) ^
24608
            ((c >> 2) & 0x01) ^
24609
            ((c >> 3) & 0x01) ^
24610
            ((c >> 4) & 0x01) ^
24611
            ((c >> 5) & 0x01) ^
24612
            ((c >> 6) & 0x01) ^
24613
            ((c >> 7) & 0x01)) == (c & 0x01)) {
24614
            WOLFSSL_MSG("Flipping parity bit");
24615
            (*myDes)[i] = c ^ 0x01;
24616
        }
24617
    }
24618
}
24619
24620
int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *myDes)
24621
{
24622
    word32 i;
24623
    word32 sz = sizeof(WOLFSSL_DES_cblock);
24624
24625
    WOLFSSL_ENTER("wolfSSL_DES_check_key_parity");
24626
24627
    for (i = 0; i < sz; i++) {
24628
        unsigned char c = (*myDes)[i];
24629
        if ((
24630
            ((c >> 1) & 0x01) ^
24631
            ((c >> 2) & 0x01) ^
24632
            ((c >> 3) & 0x01) ^
24633
            ((c >> 4) & 0x01) ^
24634
            ((c >> 5) & 0x01) ^
24635
            ((c >> 6) & 0x01) ^
24636
            ((c >> 7) & 0x01)) == (c & 0x01)) {
24637
            return 0;
24638
        }
24639
    }
24640
    return 1;
24641
}
24642
24643
#ifdef WOLFSSL_DES_ECB
24644
/* Encrypt or decrypt input message desa with key and get output in desb.
24645
 * if enc is DES_ENCRYPT,input message is encrypted or
24646
 * if enc is DES_DECRYPT,input message is decrypted.
24647
 * */
24648
void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
24649
             WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int enc)
24650
{
24651
    Des myDes;
24652
24653
    WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt");
24654
24655
    if (desa == NULL || key == NULL || desb == NULL ||
24656
        (enc != DES_ENCRYPT && enc != DES_DECRYPT)) {
24657
        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt");
24658
    } else {
24659
        if (wc_Des_SetKey(&myDes, (const byte*) key,
24660
                           (const byte*) NULL, !enc) != 0) {
24661
            WOLFSSL_MSG("wc_Des_SetKey return error.");
24662
            return;
24663
        }
24664
        if (enc == DES_ENCRYPT){
24665
            if (wc_Des_EcbEncrypt(&myDes, (byte*) desb, (const byte*) desa,
24666
                        sizeof(WOLFSSL_DES_cblock)) != 0){
24667
                WOLFSSL_MSG("wc_Des_EcbEncrypt return error.");
24668
            }
24669
        } else {
24670
            if (wc_Des_EcbDecrypt(&myDes, (byte*) desb, (const byte*) desa,
24671
                        sizeof(WOLFSSL_DES_cblock)) != 0){
24672
                WOLFSSL_MSG("wc_Des_EcbDecrpyt return error.");
24673
            }
24674
        }
24675
    }
24676
}
24677
#endif
24678
#endif /* NO_DES3 */
24679
24680
#ifndef NO_RC4
24681
/* Set the key state for Arc4 structure.
24682
 *
24683
 * key  Arc4 structure to use
24684
 * len  length of data buffer
24685
 * data initial state to set Arc4 structure
24686
 */
24687
void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len,
24688
        const unsigned char* data)
24689
{
24690
    typedef char rc4_test[sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4) ? 1 : -1];
24691
    (void)sizeof(rc4_test);
24692
24693
    WOLFSSL_ENTER("wolfSSL_RC4_set_key");
24694
24695
    if (key == NULL || len < 0) {
24696
        WOLFSSL_MSG("bad argument passed in");
24697
        return;
24698
    }
24699
24700
    XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY));
24701
    wc_Arc4SetKey((Arc4*)key, data, (word32)len);
24702
}
24703
24704
24705
/* Encrypt/decrypt with Arc4 structure.
24706
 *
24707
 * len length of buffer to encrypt/decrypt (in/out)
24708
 * in  buffer to encrypt/decrypt
24709
 * out results of encryption/decryption
24710
 */
24711
void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len,
24712
        const unsigned char* in, unsigned char* out)
24713
{
24714
    WOLFSSL_ENTER("wolfSSL_RC4");
24715
24716
    if (key == NULL || in == NULL || out == NULL) {
24717
        WOLFSSL_MSG("Bad argument passed in");
24718
        return;
24719
    }
24720
24721
    wc_Arc4Process((Arc4*)key, out, in, (word32)len);
24722
}
24723
#endif /* NO_RC4 */
24724
24725
#ifndef NO_AES
24726
24727
#ifdef WOLFSSL_AES_DIRECT
24728
/* AES encrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
24729
 *
24730
 * input  Data to encrypt
24731
 * output Encrypted data after done
24732
 * key    AES key to use for encryption
24733
 */
24734
void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output,
24735
        AES_KEY *key)
24736
{
24737
    WOLFSSL_ENTER("wolfSSL_AES_encrypt");
24738
24739
    if (input == NULL || output == NULL || key == NULL) {
24740
        WOLFSSL_MSG("Null argument passed in");
24741
        return;
24742
    }
24743
24744
#if !defined(HAVE_SELFTEST) && \
24745
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
24746
    if (wc_AesEncryptDirect((Aes*)key, output, input) != 0) {
24747
        WOLFSSL_MSG("wc_AesEncryptDirect failed");
24748
        return;
24749
    }
24750
#else
24751
    wc_AesEncryptDirect((Aes*)key, output, input);
24752
#endif
24753
}
24754
24755
24756
/* AES decrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
24757
 *
24758
 * input  Data to decrypt
24759
 * output Decrypted data after done
24760
 * key    AES key to use for encryption
24761
 */
24762
void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output,
24763
        AES_KEY *key)
24764
{
24765
    WOLFSSL_ENTER("wolfSSL_AES_decrypt");
24766
24767
    if (input == NULL || output == NULL || key == NULL) {
24768
        WOLFSSL_MSG("Null argument passed in");
24769
        return;
24770
    }
24771
24772
#if !defined(HAVE_SELFTEST) && \
24773
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
24774
    if (wc_AesDecryptDirect((Aes*)key, output, input) != 0) {
24775
        WOLFSSL_MSG("wc_AesDecryptDirect failed");
24776
        return;
24777
    }
24778
#else
24779
    wc_AesDecryptDirect((Aes*)key, output, input);
24780
#endif
24781
}
24782
#endif /* WOLFSSL_AES_DIRECT */
24783
24784
/* Setup of an AES key to use for encryption.
24785
 *
24786
 * key  key in bytes to use for encryption
24787
 * bits size of key in bits
24788
 * aes  AES structure to initialize
24789
 */
24790
int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits,
24791
        AES_KEY *aes)
24792
{
24793
    typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
24794
    (void)sizeof(aes_test);
24795
24796
    WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key");
24797
24798
    if (key == NULL || aes == NULL) {
24799
        WOLFSSL_MSG("Null argument passed in");
24800
        return -1;
24801
    }
24802
24803
    XMEMSET(aes, 0, sizeof(AES_KEY));
24804
    if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_ENCRYPT) != 0) {
24805
        WOLFSSL_MSG("Error in setting AES key");
24806
        return -1;
24807
    }
24808
    return 0;
24809
}
24810
24811
24812
/* Setup of an AES key to use for decryption.
24813
 *
24814
 * key  key in bytes to use for decryption
24815
 * bits size of key in bits
24816
 * aes  AES structure to initialize
24817
 */
24818
int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits,
24819
        AES_KEY *aes)
24820
{
24821
    typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
24822
    (void)sizeof(aes_test);
24823
24824
    WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key");
24825
24826
    if (key == NULL || aes == NULL) {
24827
        WOLFSSL_MSG("Null argument passed in");
24828
        return -1;
24829
    }
24830
24831
    XMEMSET(aes, 0, sizeof(AES_KEY));
24832
    if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_DECRYPT) != 0) {
24833
        WOLFSSL_MSG("Error in setting AES key");
24834
        return -1;
24835
    }
24836
    return 0;
24837
}
24838
24839
24840
#ifdef HAVE_AES_ECB
24841
/* Encrypt/decrypt a 16 byte block of data using the key passed in.
24842
 *
24843
 * in  buffer to encrypt/decrypt
24844
 * out buffer to hold result of encryption/decryption
24845
 * key AES structure to use with encryption/decryption
24846
 * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
24847
 */
24848
void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out,
24849
                             AES_KEY *key, const int enc)
24850
{
24851
    Aes* aes;
24852
24853
    WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt");
24854
24855
    if (key == NULL || in == NULL || out == NULL) {
24856
        WOLFSSL_MSG("Error, Null argument passed in");
24857
        return;
24858
    }
24859
24860
    aes = (Aes*)key;
24861
    if (enc == AES_ENCRYPT) {
24862
        if (wc_AesEcbEncrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
24863
            WOLFSSL_MSG("Error with AES CBC encrypt");
24864
        }
24865
    }
24866
    else {
24867
    #ifdef HAVE_AES_DECRYPT
24868
        if (wc_AesEcbDecrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
24869
            WOLFSSL_MSG("Error with AES CBC decrypt");
24870
        }
24871
    #else
24872
        WOLFSSL_MSG("AES decryption not compiled in");
24873
    #endif
24874
    }
24875
}
24876
#endif /* HAVE_AES_ECB */
24877
24878
#ifdef HAVE_AES_CBC
24879
/* Encrypt data using key and iv passed in. iv gets updated to most recent iv
24880
 * state after encryption/decryption.
24881
 *
24882
 * in  buffer to encrypt/decrypt
24883
 * out buffer to hold result of encryption/decryption
24884
 * len length of input buffer
24885
 * key AES structure to use with encryption/decryption
24886
 * iv  iv to use with operation
24887
 * enc 1 for encryption and 0 for decryption
24888
 */
24889
void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out,
24890
        size_t len, AES_KEY *key, unsigned char* iv, const int enc)
24891
{
24892
    Aes* aes;
24893
24894
    WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
24895
24896
    if (key == NULL || in == NULL || out == NULL || iv == NULL || len == 0) {
24897
        WOLFSSL_MSG("Error, Null argument passed in");
24898
        return;
24899
    }
24900
24901
    aes = (Aes*)key;
24902
    if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
24903
        WOLFSSL_MSG("Error with setting iv");
24904
        return;
24905
    }
24906
24907
    if (enc == AES_ENCRYPT) {
24908
        if (wc_AesCbcEncrypt(aes, out, in, (word32)len) != 0) {
24909
            WOLFSSL_MSG("Error with AES CBC encrypt");
24910
            return;
24911
        }
24912
    }
24913
    else {
24914
        if (wc_AesCbcDecrypt(aes, out, in, (word32)len) != 0) {
24915
            WOLFSSL_MSG("Error with AES CBC decrypt");
24916
            return;
24917
        }
24918
    }
24919
24920
    /* to be compatible copy iv to iv buffer after completing operation */
24921
    XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
24922
}
24923
#endif /* HAVE_AES_CBC */
24924
24925
24926
/* Encrypt data using CFB mode with key and iv passed in. iv gets updated to
24927
 * most recent iv state after encryption/decryption.
24928
 *
24929
 * in  buffer to encrypt/decrypt
24930
 * out buffer to hold result of encryption/decryption
24931
 * len length of input buffer
24932
 * key AES structure to use with encryption/decryption
24933
 * iv  iv to use with operation
24934
 * num contains the amount of block used
24935
 * enc AES_ENCRYPT for encryption and AES_DECRYPT for decryption
24936
 */
24937
void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out,
24938
        size_t len, AES_KEY *key, unsigned char* iv, int* num,
24939
        const int enc)
24940
{
24941
#ifndef WOLFSSL_AES_CFB
24942
    WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB");
24943
    (void)in;
24944
    (void)out;
24945
    (void)len;
24946
    (void)key;
24947
    (void)iv;
24948
    (void)num;
24949
    (void)enc;
24950
24951
    return;
24952
#else
24953
    Aes* aes;
24954
24955
    WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
24956
    if (key == NULL || in == NULL || out == NULL || iv == NULL) {
24957
        WOLFSSL_MSG("Error, Null argument passed in");
24958
        return;
24959
    }
24960
24961
    aes = (Aes*)key;
24962
24963
    /*
24964
     * We copy the IV directly into reg here because using wc_AesSetIV will
24965
     * clear the leftover bytes field "left", and this function relies on the
24966
     * leftover bytes being preserved between calls.
24967
     */
24968
    XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
24969
24970
    if (enc == AES_ENCRYPT) {
24971
        if (wc_AesCfbEncrypt(aes, out, in, (word32)len) != 0) {
24972
            WOLFSSL_MSG("Error with AES CBC encrypt");
24973
            return;
24974
        }
24975
    }
24976
    else {
24977
        if (wc_AesCfbDecrypt(aes, out, in, (word32)len) != 0) {
24978
            WOLFSSL_MSG("Error with AES CBC decrypt");
24979
            return;
24980
        }
24981
    }
24982
24983
    /* to be compatible copy iv to iv buffer after completing operation */
24984
    XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
24985
24986
    /* store number of left over bytes to num */
24987
    *num = (aes->left)? AES_BLOCK_SIZE - aes->left : 0;
24988
#endif /* WOLFSSL_AES_CFB */
24989
}
24990
24991
/* wc_AesKey*Wrap_ex API not available in FIPS and SELFTEST */
24992
#if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
24993
int wolfSSL_AES_wrap_key(AES_KEY *key, const unsigned char *iv,
24994
                 unsigned char *out,
24995
                 const unsigned char *in, unsigned int inlen)
24996
{
24997
    int ret;
24998
24999
    WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
25000
25001
    if (out == NULL || in == NULL) {
25002
        WOLFSSL_MSG("Error, Null argument passed in");
25003
        return WOLFSSL_FAILURE;
25004
    }
25005
25006
    ret = wc_AesKeyWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv);
25007
25008
    return ret < 0 ? WOLFSSL_FAILURE : ret;
25009
}
25010
25011
int wolfSSL_AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
25012
                   unsigned char *out,
25013
                   const unsigned char *in, unsigned int inlen)
25014
{
25015
    int ret;
25016
25017
    WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
25018
25019
    if (out == NULL || in == NULL) {
25020
        WOLFSSL_MSG("Error, Null argument passed in");
25021
        return WOLFSSL_FAILURE;
25022
    }
25023
25024
    ret = wc_AesKeyUnWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv);
25025
25026
    return ret < 0 ? WOLFSSL_FAILURE : ret;
25027
}
25028
#endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */
25029
25030
#ifdef HAVE_CTS
25031
/*
25032
 * Ciphertext stealing interface compatible with RFC2040 and RFC3962.
25033
 */
25034
size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in,
25035
        unsigned char *out, size_t len, const void *key,
25036
        unsigned char *iv, WOLFSSL_CBC128_CB cbc)
25037
{
25038
    byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
25039
    int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
25040
    WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_encrypt");
25041
25042
    if (in == NULL || out == NULL || len < WOLFSSL_CTS128_BLOCK_SZ ||
25043
            cbc == NULL) {
25044
        WOLFSSL_MSG("Bad parameter");
25045
        return WOLFSSL_FAILURE;
25046
    }
25047
25048
    if (lastBlkLen == 0)
25049
        lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
25050
25051
    /* Encrypt data up to last block */
25052
    (*cbc)(in, out, len - lastBlkLen, key, iv, AES_ENCRYPT);
25053
25054
    /* Move to last block */
25055
    in += len - lastBlkLen;
25056
    out += len - lastBlkLen;
25057
25058
    /* RFC2040: Pad Pn with zeros at the end to create P of length BB. */
25059
    XMEMCPY(lastBlk, in, lastBlkLen);
25060
    XMEMSET(lastBlk + lastBlkLen, 0, WOLFSSL_CTS128_BLOCK_SZ - lastBlkLen);
25061
    /* RFC2040: Select the first Ln bytes of En-1 to create Cn */
25062
    XMEMCPY(out, out - WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
25063
    (*cbc)(lastBlk, out - WOLFSSL_CTS128_BLOCK_SZ, WOLFSSL_CTS128_BLOCK_SZ,
25064
            key, iv, AES_ENCRYPT);
25065
25066
    return len;
25067
}
25068
25069
size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in,
25070
        unsigned char *out, size_t len, const void *key,
25071
        unsigned char *iv, WOLFSSL_CBC128_CB cbc)
25072
{
25073
    byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
25074
    byte prevBlk[WOLFSSL_CTS128_BLOCK_SZ];
25075
    int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
25076
    WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_decrypt");
25077
25078
    if (in == NULL || out == NULL || len <= WOLFSSL_CTS128_BLOCK_SZ ||
25079
            cbc == NULL) {
25080
        WOLFSSL_MSG("Bad parameter");
25081
        return WOLFSSL_FAILURE;
25082
    }
25083
25084
    if (lastBlkLen == 0)
25085
        lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
25086
25087
    /* Decrypt up to last two blocks */
25088
    (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv,
25089
            AES_DECRYPTION);
25090
25091
    /* Move to last two blocks */
25092
    in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
25093
    out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
25094
25095
    /* RFC2040: Decrypt Cn-1 to create Dn.
25096
     * Use 0 buffer as IV to do straight decryption.
25097
     * This places the Cn-1 block at lastBlk */
25098
    XMEMSET(lastBlk, 0, WOLFSSL_CTS128_BLOCK_SZ);
25099
    (*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, AES_DECRYPT);
25100
    /* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn
25101
     *          to create En. */
25102
    XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
25103
    /* Cn and Cn-1 can now be decrypted */
25104
    (*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT);
25105
    (*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT);
25106
    XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen);
25107
    return len;
25108
}
25109
#endif /* HAVE_CTS */
25110
#endif /* NO_AES */
25111
25112
#ifndef NO_ASN_TIME
25113
#ifndef NO_BIO
25114
int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
25115
{
25116
    WOLFSSL_ENTER("ASN1_UTCTIME_print");
25117
    if (bio == NULL || a == NULL) {
25118
        return WOLFSSL_FAILURE;
25119
    }
25120
    if (a->type != ASN_UTC_TIME) {
25121
        WOLFSSL_MSG("Error, not UTC_TIME");
25122
        return WOLFSSL_FAILURE;
25123
    }
25124
25125
    return wolfSSL_ASN1_TIME_print(bio, a);
25126
}
25127
25128
#endif /* !NO_BIO */
25129
25130
/* Checks the ASN1 syntax of "a"
25131
 * returns WOLFSSL_SUCCESS (1)  if correct otherwise WOLFSSL_FAILURE (0) */
25132
int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a)
25133
{
25134
    char buf[MAX_TIME_STRING_SZ];
25135
25136
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_check");
25137
25138
    /* if can parse the WOLFSSL_ASN1_TIME passed in then consider syntax good */
25139
    if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)a, buf,
25140
                MAX_TIME_STRING_SZ) == NULL) {
25141
        return WOLFSSL_FAILURE;
25142
    }
25143
    return WOLFSSL_SUCCESS;
25144
}
25145
25146
/*
25147
 * Convert time to Unix time (GMT).
25148
 */
25149
static long long TimeToUnixTime(int sec, int min, int hour, int mday, int mon,
25150
                                int year)
25151
{
25152
    /* Number of cumulative days from the previous months, starting from
25153
     * beginning of January. */
25154
    static const int monthDaysCumulative [12] = {
25155
        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
25156
    };
25157
    int leapDays = year;
25158
25159
    if (mon <= 1) {
25160
        --leapDays;
25161
    }
25162
    leapDays = leapDays / 4 - leapDays / 100 + leapDays / 400 - 1969 / 4 +
25163
               1969 / 100 - 1969 / 400;
25164
25165
    return ((((long long) (year - 1970) * 365 + leapDays +
25166
           monthDaysCumulative[mon] + mday - 1) * 24 + hour) * 60 + min) * 60 +
25167
           sec;
25168
}
25169
25170
int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from,
25171
    const WOLFSSL_ASN1_TIME *to)
25172
{
25173
    const int SECS_PER_DAY = 24 * 60 * 60;
25174
    struct tm fromTm_s, *fromTmGmt = &fromTm_s;
25175
    struct tm toTm_s, *toTmGmt = &toTm_s;
25176
    time_t currTime;
25177
    long long fromSecs;
25178
    long long toSecs;
25179
    double diffSecs;
25180
    struct tm *tmpTs;
25181
#if defined(NEED_TMP_TIME)
25182
    /* for use with gmtime_r */
25183
    struct tm tmpTimeStorage;
25184
    tmpTs = &tmpTimeStorage;
25185
#else
25186
    tmpTs = NULL;
25187
#endif
25188
    (void)tmpTs;
25189
25190
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_diff");
25191
25192
    if (days == NULL) {
25193
        WOLFSSL_MSG("days is NULL");
25194
        return WOLFSSL_FAILURE;
25195
    }
25196
    if (secs == NULL) {
25197
        WOLFSSL_MSG("secs is NULL");
25198
        return WOLFSSL_FAILURE;
25199
    }
25200
25201
    if (from == NULL && to == NULL) {
25202
        *days = 0;
25203
        *secs = 0;
25204
        return WOLFSSL_SUCCESS;
25205
    }
25206
25207
    if (from == NULL) {
25208
        currTime = wc_Time(0);
25209
        fromTmGmt = XGMTIME(&currTime, tmpTs);
25210
        if (fromTmGmt == NULL) {
25211
            WOLFSSL_MSG("XGMTIME for from time failed.");
25212
            return WOLFSSL_FAILURE;
25213
        }
25214
    }
25215
    else if (wolfSSL_ASN1_TIME_to_tm(from, fromTmGmt) != WOLFSSL_SUCCESS) {
25216
        WOLFSSL_MSG("Failed to convert from time to struct tm.");
25217
        return WOLFSSL_FAILURE;
25218
    }
25219
25220
    /* We use TimeToUnixTime here instead of XMKTIME to avoid the Year 2038
25221
     * Problem on platforms where time_t is 32 bits. struct tm stores the year
25222
     * as years since 1900, so we add 1900 to the year. */
25223
    fromSecs = TimeToUnixTime(fromTmGmt->tm_sec, fromTmGmt->tm_min,
25224
                          fromTmGmt->tm_hour, fromTmGmt->tm_mday,
25225
                          fromTmGmt->tm_mon, fromTmGmt->tm_year + 1900);
25226
25227
    if (to == NULL) {
25228
        currTime = wc_Time(0);
25229
        toTmGmt = XGMTIME(&currTime, tmpTs);
25230
        if (toTmGmt == NULL) {
25231
            WOLFSSL_MSG("XGMTIME for to time failed.");
25232
            return WOLFSSL_FAILURE;
25233
        }
25234
    }
25235
    else if (wolfSSL_ASN1_TIME_to_tm(to, toTmGmt) != WOLFSSL_SUCCESS) {
25236
        WOLFSSL_MSG("Failed to convert to time to struct tm.");
25237
        return WOLFSSL_FAILURE;
25238
    }
25239
25240
    toSecs = TimeToUnixTime(toTmGmt->tm_sec, toTmGmt->tm_min, toTmGmt->tm_hour,
25241
                        toTmGmt->tm_mday, toTmGmt->tm_mon,
25242
                        toTmGmt->tm_year + 1900);
25243
25244
    diffSecs = (double)(toSecs - fromSecs);
25245
    *days = (int) (diffSecs / SECS_PER_DAY);
25246
    *secs = (int) (diffSecs - (((double)*days) * SECS_PER_DAY));
25247
25248
    return WOLFSSL_SUCCESS;
25249
}
25250
25251
int wolfSSL_ASN1_TIME_compare(const WOLFSSL_ASN1_TIME *a,
25252
                              const WOLFSSL_ASN1_TIME *b)
25253
{
25254
    int ret;
25255
    int days;
25256
    int secs;
25257
25258
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_compare");
25259
25260
    if (wolfSSL_ASN1_TIME_diff(&days, &secs, a, b) != WOLFSSL_SUCCESS) {
25261
        WOLFSSL_MSG("Failed to get time difference.");
25262
        ret = -2;
25263
    }
25264
    else {
25265
        if (days == 0 && secs == 0) {
25266
            /* a and b are the same time. */
25267
            ret = 0;
25268
        }
25269
        else if (days >= 0 && secs >= 0) {
25270
            /* a is before b. */
25271
            ret = -1;
25272
        }
25273
        else if (days <= 0 && secs <= 0) {
25274
            /* a is after b. */
25275
            ret = 1;
25276
        }
25277
        else {
25278
            WOLFSSL_MSG("Incoherent time difference.");
25279
            ret = -2;
25280
        }
25281
    }
25282
25283
    WOLFSSL_LEAVE("wolfSSL_ASN1_TIME_compare", ret);
25284
25285
    return ret;
25286
}
25287
#endif /* !NO_ASN_TIME */
25288
25289
#ifndef NO_WOLFSSL_STUB
25290
WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t)
25291
{
25292
    WOLFSSL_STUB("wolfSSL_ASN1_TIME_set");
25293
    (void)s;
25294
    (void)t;
25295
    return s;
25296
}
25297
#endif /* !NO_WOLFSSL_STUB */
25298
25299
int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str)
25300
{
25301
    int slen;
25302
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_set_string");
25303
25304
    if (!str) {
25305
        WOLFSSL_MSG("Bad parameter");
25306
        return WOLFSSL_FAILURE;
25307
    }
25308
    slen = (int)XSTRLEN(str)+1;
25309
    if (slen > CTC_DATE_SIZE) {
25310
        WOLFSSL_MSG("Date string too long");
25311
        return WOLFSSL_FAILURE;
25312
    }
25313
    if (s) {
25314
        XMEMCPY(s->data, str, slen);
25315
        s->length = slen - 1; /* do not include null terminator in length */
25316
        s->type = slen == ASN_UTC_TIME_SIZE ? V_ASN1_UTCTIME :
25317
            V_ASN1_GENERALIZEDTIME;
25318
    }
25319
    return WOLFSSL_SUCCESS;
25320
}
25321
25322
#ifndef NO_BIO
25323
25324
/* Return the month as a string.
25325
 *
25326
 * n  The number of the month as a two characters (1 based).
25327
 * returns the month as a string.
25328
 */
25329
static WC_INLINE const char* MonthStr(const char* n)
25330
{
25331
    static const char monthStr[12][4] = {
25332
            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
25333
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
25334
    return monthStr[(n[0] - '0') * 10 + (n[1] - '0') - 1];
25335
}
25336
25337
int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO* bio,
25338
    const WOLFSSL_ASN1_GENERALIZEDTIME* asnTime)
25339
{
25340
    const char* p;
25341
    WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_print");
25342
25343
    if (bio == NULL || asnTime == NULL)
25344
        return BAD_FUNC_ARG;
25345
25346
    if (asnTime->type != ASN_GENERALIZED_TIME) {
25347
        WOLFSSL_MSG("Error, not GENERALIZED_TIME");
25348
        return WOLFSSL_FAILURE;
25349
    }
25350
    p = (const char *)(asnTime->data);
25351
    /* GetTimeString not always available. */
25352
    if (wolfSSL_BIO_write(bio, MonthStr(p + 4), 3) <= 0)
25353
        return WOLFSSL_FAILURE;
25354
    if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
25355
        return WOLFSSL_FAILURE;
25356
25357
    /* Day */
25358
    if (wolfSSL_BIO_write(bio, p + 6, 2) <= 0)
25359
        return WOLFSSL_FAILURE;
25360
    if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
25361
        return WOLFSSL_FAILURE;
25362
25363
    /* Hour */
25364
    if (wolfSSL_BIO_write(bio, p + 8, 2) <= 0)
25365
        return WOLFSSL_FAILURE;
25366
    if (wolfSSL_BIO_write(bio, ":", 1) <= 0)
25367
        return WOLFSSL_FAILURE;
25368
25369
    /* Min */
25370
    if (wolfSSL_BIO_write(bio, p + 10, 2) <= 0)
25371
        return WOLFSSL_FAILURE;
25372
    if (wolfSSL_BIO_write(bio, ":", 1) <= 0)
25373
        return WOLFSSL_FAILURE;
25374
25375
    /* Secs */
25376
    if (wolfSSL_BIO_write(bio, p + 12, 2) <= 0)
25377
        return WOLFSSL_FAILURE;
25378
    if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
25379
        return WOLFSSL_FAILURE;
25380
    if (wolfSSL_BIO_write(bio, p, 4) <= 0)
25381
        return WOLFSSL_FAILURE;
25382
25383
    return 0;
25384
}
25385
#endif /* !NO_BIO */
25386
25387
void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME* asn1Time)
25388
{
25389
    WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_free");
25390
    if (asn1Time == NULL)
25391
        return;
25392
    XMEMSET(asn1Time->data, 0, sizeof(asn1Time->data));
25393
}
25394
25395
#endif /* OPENSSL_EXTRA */
25396
25397
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
25398
int wolfSSL_sk_num(const WOLFSSL_STACK* sk)
25399
{
25400
    WOLFSSL_ENTER("wolfSSL_sk_num");
25401
    if (sk == NULL)
25402
        return 0;
25403
    return (int)sk->num;
25404
}
25405
25406
void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i)
25407
{
25408
    WOLFSSL_ENTER("wolfSSL_sk_value");
25409
25410
    for (; sk != NULL && i > 0; i--)
25411
        sk = sk->next;
25412
    if (sk == NULL)
25413
        return NULL;
25414
25415
    switch (sk->type) {
25416
        case STACK_TYPE_X509:
25417
            return (void*)sk->data.x509;
25418
        case STACK_TYPE_GEN_NAME:
25419
            return (void*)sk->data.gn;
25420
        case STACK_TYPE_BIO:
25421
            return (void*)sk->data.bio;
25422
        case STACK_TYPE_OBJ:
25423
            return (void*)sk->data.obj;
25424
        case STACK_TYPE_STRING:
25425
            return (void*)sk->data.string;
25426
        case STACK_TYPE_CIPHER:
25427
            return (void*)&sk->data.cipher;
25428
        case STACK_TYPE_ACCESS_DESCRIPTION:
25429
            return (void*)sk->data.access;
25430
        case STACK_TYPE_X509_EXT:
25431
            return (void*)sk->data.ext;
25432
        case STACK_TYPE_X509_REQ_ATTR:
25433
            return (void*)sk->data.generic;
25434
        case STACK_TYPE_NULL:
25435
            return (void*)sk->data.generic;
25436
        case STACK_TYPE_X509_NAME:
25437
            return (void*)sk->data.name;
25438
        case STACK_TYPE_X509_NAME_ENTRY:
25439
            return (void*)sk->data.name_entry;
25440
        case STACK_TYPE_CONF_VALUE:
25441
    #ifdef OPENSSL_EXTRA
25442
            return (void*)sk->data.conf;
25443
    #else
25444
            return NULL;
25445
    #endif
25446
        case STACK_TYPE_X509_INFO:
25447
            return (void*)sk->data.info;
25448
        case STACK_TYPE_BY_DIR_entry:
25449
            return (void*)sk->data.dir_entry;
25450
        case STACK_TYPE_BY_DIR_hash:
25451
            return (void*)sk->data.dir_hash;
25452
        case STACK_TYPE_X509_OBJ:
25453
            return (void*)sk->data.x509_obj;
25454
        case STACK_TYPE_DIST_POINT:
25455
            return (void*)sk->data.dp;
25456
        case STACK_TYPE_X509_CRL:
25457
            return (void*)sk->data.crl;
25458
        default:
25459
            return (void*)sk->data.generic;
25460
    }
25461
}
25462
25463
/* copies over data of "in" to "out" */
25464
static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out)
25465
{
25466
    if (in == NULL || out == NULL)
25467
        return;
25468
25469
    *out = *in;
25470
}
25471
25472
WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk)
25473
{
25474
25475
    WOLFSSL_STACK* ret = NULL;
25476
    WOLFSSL_STACK* last = NULL;
25477
25478
    WOLFSSL_ENTER("wolfSSL_sk_dup");
25479
25480
    while (sk) {
25481
        WOLFSSL_STACK* cur = wolfSSL_sk_new_node(sk->heap);
25482
25483
        if (!cur) {
25484
            WOLFSSL_MSG("wolfSSL_sk_new_node error");
25485
            goto error;
25486
        }
25487
25488
        if (!ret) {
25489
            /* Set first node */
25490
            ret = cur;
25491
        }
25492
25493
        if (last) {
25494
            last->next = cur;
25495
        }
25496
25497
        XMEMCPY(cur, sk, sizeof(WOLFSSL_STACK));
25498
25499
        /* We will allocate new memory for this */
25500
        XMEMSET(&cur->data, 0, sizeof(cur->data));
25501
        cur->next = NULL;
25502
25503
        switch (sk->type) {
25504
            case STACK_TYPE_X509:
25505
                if (!sk->data.x509)
25506
                    break;
25507
                cur->data.x509 = wolfSSL_X509_dup(sk->data.x509);
25508
                if (!cur->data.x509) {
25509
                    WOLFSSL_MSG("wolfSSL_X509_dup error");
25510
                    goto error;
25511
                }
25512
                break;
25513
            case STACK_TYPE_CIPHER:
25514
                wolfSSL_CIPHER_copy(&sk->data.cipher, &cur->data.cipher);
25515
                break;
25516
            case STACK_TYPE_GEN_NAME:
25517
                if (!sk->data.gn)
25518
                    break;
25519
                cur->data.gn = wolfSSL_GENERAL_NAME_dup(sk->data.gn);
25520
                if (!cur->data.gn) {
25521
                    WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
25522
                    goto error;
25523
                }
25524
                break;
25525
            case STACK_TYPE_OBJ:
25526
                if (!sk->data.obj)
25527
                    break;
25528
                cur->data.obj = wolfSSL_ASN1_OBJECT_dup(sk->data.obj);
25529
                if (!cur->data.obj) {
25530
                    WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup error");
25531
                    goto error;
25532
                }
25533
                break;
25534
            case STACK_TYPE_BIO:
25535
            case STACK_TYPE_STRING:
25536
            case STACK_TYPE_ACCESS_DESCRIPTION:
25537
            case STACK_TYPE_X509_EXT:
25538
            case STACK_TYPE_X509_REQ_ATTR:
25539
            case STACK_TYPE_NULL:
25540
            case STACK_TYPE_X509_NAME:
25541
            case STACK_TYPE_X509_NAME_ENTRY:
25542
            case STACK_TYPE_CONF_VALUE:
25543
            case STACK_TYPE_X509_INFO:
25544
            case STACK_TYPE_BY_DIR_entry:
25545
            case STACK_TYPE_BY_DIR_hash:
25546
            case STACK_TYPE_X509_OBJ:
25547
            case STACK_TYPE_DIST_POINT:
25548
            case STACK_TYPE_X509_CRL:
25549
            default:
25550
                WOLFSSL_MSG("Unsupported stack type");
25551
                goto error;
25552
        }
25553
25554
        sk = sk->next;
25555
        last = cur;
25556
    }
25557
    return ret;
25558
25559
error:
25560
    if (ret) {
25561
        wolfSSL_sk_GENERAL_NAME_free(ret);
25562
    }
25563
    return NULL;
25564
}
25565
25566
/* Free the just the stack structure */
25567
void wolfSSL_sk_free(WOLFSSL_STACK* sk)
25568
{
25569
    WOLFSSL_ENTER("wolfSSL_sk_free");
25570
25571
    while (sk != NULL) {
25572
        WOLFSSL_STACK* next = sk->next;
25573
        XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
25574
        sk = next;
25575
    }
25576
}
25577
25578
/* Frees each node in the stack and frees the stack.
25579
 */
25580
void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk,
25581
    void (*f) (void*))
25582
{
25583
    WOLFSSL_ENTER("wolfSSL_sk_GENERIC_pop_free");
25584
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
25585
}
25586
25587
/* return 1 on success 0 on fail */
25588
int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic)
25589
{
25590
    WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push");
25591
25592
    return wolfSSL_sk_push(sk, generic);
25593
}
25594
void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk)
25595
{
25596
    wolfSSL_sk_free(sk);
25597
}
25598
25599
/* Free all nodes in a stack including the pushed objects */
25600
void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
25601
                                                       wolfSSL_sk_freefunc func)
25602
{
25603
    WOLFSSL_ENTER("wolfSSL_sk_pop_free");
25604
25605
    if (sk == NULL) {
25606
        /* pop_free can be called with NULL, do not print bad argument */
25607
        return;
25608
    }
25609
    #if defined(WOLFSSL_QT)
25610
    /* In Qt v15.5, it calls OPENSSL_sk_free(xxx, OPENSSL_sk_free).
25611
    *  By using OPENSSL_sk_free for free causes access violation.
25612
    *  Therefore, switching free func to wolfSSL_ACCESS_DESCRIPTION_free
25613
    *  is needed even the func isn't NULL.
25614
    */
25615
    if (sk->type == STACK_TYPE_ACCESS_DESCRIPTION) {
25616
        func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free;
25617
    }
25618
    #endif
25619
    if (func == NULL) {
25620
        switch(sk->type) {
25621
            case STACK_TYPE_ACCESS_DESCRIPTION:
25622
            #if defined(OPENSSL_ALL)
25623
                func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free;
25624
            #endif
25625
                break;
25626
            case STACK_TYPE_X509:
25627
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_free;
25628
                break;
25629
            case STACK_TYPE_X509_OBJ:
25630
            #ifdef OPENSSL_ALL
25631
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_OBJECT_free;
25632
            #endif
25633
                break;
25634
            case STACK_TYPE_OBJ:
25635
                func = (wolfSSL_sk_freefunc)wolfSSL_ASN1_OBJECT_free;
25636
                break;
25637
            case STACK_TYPE_DIST_POINT:
25638
            #ifdef OPENSSL_EXTRA
25639
                func = (wolfSSL_sk_freefunc)wolfSSL_DIST_POINT_free;
25640
            #endif
25641
                break;
25642
            case STACK_TYPE_GEN_NAME:
25643
                func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_NAME_free;
25644
                break;
25645
            case STACK_TYPE_STRING:
25646
            #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
25647
                defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
25648
                func = (wolfSSL_sk_freefunc)wolfSSL_WOLFSSL_STRING_free;
25649
            #endif
25650
                break;
25651
            case STACK_TYPE_X509_NAME:
25652
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
25653
                && !defined(WOLFCRYPT_ONLY)
25654
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_free;
25655
            #endif
25656
                break;
25657
            case STACK_TYPE_X509_NAME_ENTRY:
25658
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
25659
                && !defined(WOLFCRYPT_ONLY)
25660
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_ENTRY_free;
25661
            #endif
25662
                break;
25663
            case STACK_TYPE_X509_EXT:
25664
            #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
25665
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_EXTENSION_free;
25666
            #endif
25667
                break;
25668
            case STACK_TYPE_X509_REQ_ATTR:
25669
            #if defined(OPENSSL_ALL) && \
25670
                (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
25671
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_ATTRIBUTE_free;
25672
            #endif
25673
                break;
25674
            case STACK_TYPE_CONF_VALUE:
25675
            #if defined(OPENSSL_ALL)
25676
                func = (wolfSSL_sk_freefunc)wolfSSL_X509V3_conf_free;
25677
            #endif
25678
                break;
25679
            case STACK_TYPE_X509_INFO:
25680
            #if defined(OPENSSL_ALL)
25681
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_INFO_free;
25682
            #endif
25683
                break;
25684
            case STACK_TYPE_BIO:
25685
#if !defined(NO_BIO) && defined(OPENSSL_EXTRA)
25686
                func = (wolfSSL_sk_freefunc)wolfSSL_BIO_vfree;
25687
#endif
25688
                break;
25689
            case STACK_TYPE_BY_DIR_entry:
25690
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
25691
                func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_entry_free;
25692
#endif
25693
                break;
25694
            case STACK_TYPE_BY_DIR_hash:
25695
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
25696
                func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_HASH_free;
25697
#endif
25698
                break;
25699
            case STACK_TYPE_X509_CRL:
25700
#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
25701
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_CRL_free;
25702
#endif
25703
                break;
25704
            case STACK_TYPE_CIPHER:
25705
            case STACK_TYPE_NULL:
25706
            default:
25707
                break;
25708
        }
25709
    }
25710
25711
    while (sk != NULL) {
25712
        WOLFSSL_STACK* next = sk->next;
25713
25714
        if (func != NULL) {
25715
            if (sk->type != STACK_TYPE_CIPHER)
25716
                func(sk->data.generic);
25717
        }
25718
        XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
25719
        sk = next;
25720
    }
25721
}
25722
25723
/* Creates and returns a new null stack. */
25724
WOLFSSL_STACK* wolfSSL_sk_new_null(void)
25725
{
25726
    WOLFSSL_STACK* sk;
25727
    WOLFSSL_ENTER("wolfSSL_sk_new_null");
25728
25729
    sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
25730
                                 DYNAMIC_TYPE_OPENSSL);
25731
    if (sk == NULL) {
25732
        WOLFSSL_MSG("WOLFSSL_STACK memory error");
25733
        return NULL;
25734
    }
25735
25736
    XMEMSET(sk, 0, sizeof(WOLFSSL_STACK));
25737
    sk->type = STACK_TYPE_NULL;
25738
25739
    return sk;
25740
}
25741
25742
int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk)
25743
{
25744
    if (sk == NULL)
25745
        return 0;
25746
    return (int)sk->num;
25747
}
25748
25749
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
25750
25751
#if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
25752
        defined(HAVE_EXT_CACHE))
25753
/* stunnel 4.28 needs
25754
 *
25755
 * Callback that is called if a session tries to resume but could not find
25756
 * the session to resume it.
25757
 */
25758
void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
25759
                    WOLFSSL_SESSION*(*f)(WOLFSSL*, const unsigned char*, int, int*))
25760
{
25761
    if (ctx == NULL)
25762
        return;
25763
25764
#ifdef HAVE_EXT_CACHE
25765
    ctx->get_sess_cb = f;
25766
#else
25767
    (void)f;
25768
#endif
25769
}
25770
25771
void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
25772
                             int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
25773
{
25774
    if (ctx == NULL)
25775
        return;
25776
25777
#ifdef HAVE_EXT_CACHE
25778
    ctx->new_sess_cb = f;
25779
#else
25780
    (void)f;
25781
#endif
25782
}
25783
25784
void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
25785
                                                        WOLFSSL_SESSION*))
25786
{
25787
    if (ctx == NULL)
25788
        return;
25789
25790
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
25791
    ctx->rem_sess_cb = f;
25792
#else
25793
    (void)f;
25794
#endif
25795
}
25796
25797
25798
/*
25799
 *
25800
 * Note: It is expected that the importing and exporting function have been
25801
 *       built with the same settings. For example if session tickets was
25802
 *       enabled with the wolfSSL library exporting a session then it is
25803
 *       expected to be turned on with the wolfSSL library importing the session.
25804
 */
25805
int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
25806
{
25807
    int size = 0;
25808
#ifdef HAVE_EXT_CACHE
25809
    int idx = 0;
25810
#ifdef SESSION_CERTS
25811
    int i;
25812
#endif
25813
    unsigned char *data;
25814
25815
    WOLFSSL_ENTER("wolfSSL_i2d_SSL_SESSION");
25816
25817
    sess = ClientSessionToSession(sess);
25818
    if (sess == NULL) {
25819
        return BAD_FUNC_ARG;
25820
    }
25821
25822
    /* side | bornOn | timeout | sessionID len | sessionID | masterSecret |
25823
     * haveEMS  */
25824
    size += OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN +
25825
            sess->sessionIDSz + SECRET_LEN + OPAQUE8_LEN;
25826
    /* altSessionID */
25827
    size += OPAQUE8_LEN + (sess->haveAltSessionID ? ID_LEN : 0);
25828
#ifdef SESSION_CERTS
25829
    /* Peer chain */
25830
    size += OPAQUE8_LEN;
25831
    for (i = 0; i < sess->chain.count; i++)
25832
        size += OPAQUE16_LEN + sess->chain.certs[i].length;
25833
#endif
25834
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
25835
                               defined(HAVE_SESSION_TICKET))
25836
    /* Protocol version */
25837
    size += OPAQUE16_LEN;
25838
#endif
25839
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
25840
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
25841
    /* cipher suite */
25842
    size += OPAQUE16_LEN;
25843
#endif
25844
#ifndef NO_CLIENT_CACHE
25845
    /* ServerID len | ServerID */
25846
    size += OPAQUE16_LEN + sess->idLen;
25847
#endif
25848
#ifdef OPENSSL_EXTRA
25849
    /* session context ID len | session context ID */
25850
    size += OPAQUE8_LEN + sess->sessionCtxSz;
25851
#endif
25852
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
25853
    /* peerVerifyRet */
25854
    size += OPAQUE8_LEN;
25855
#endif
25856
#ifdef WOLFSSL_TLS13
25857
    /* namedGroup */
25858
    size += OPAQUE16_LEN;
25859
#endif
25860
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
25861
#ifdef WOLFSSL_TLS13
25862
#ifdef WOLFSSL_32BIT_MILLI_TIME
25863
    /* ticketSeen | ticketAdd */
25864
    size += OPAQUE32_LEN + OPAQUE32_LEN;
25865
#else
25866
    /* ticketSeen Hi 32 bits | ticketSeen Lo 32 bits | ticketAdd */
25867
    size += OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE32_LEN;
25868
#endif
25869
    /* ticketNonce */
25870
    size += OPAQUE8_LEN + sess->ticketNonce.len;
25871
#endif
25872
#ifdef WOLFSSL_EARLY_DATA
25873
    size += OPAQUE32_LEN;
25874
#endif
25875
#endif
25876
#ifdef HAVE_SESSION_TICKET
25877
    /* ticket len | ticket */
25878
    size += OPAQUE16_LEN + sess->ticketLen;
25879
#endif
25880
25881
    if (p != NULL) {
25882
        if (*p == NULL)
25883
            *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL);
25884
        if (*p == NULL)
25885
            return 0;
25886
        data = *p;
25887
25888
        data[idx++] = sess->side;
25889
        c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN;
25890
        c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN;
25891
        data[idx++] = sess->sessionIDSz;
25892
        XMEMCPY(data + idx, sess->sessionID, sess->sessionIDSz);
25893
        idx += sess->sessionIDSz;
25894
        XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN;
25895
        data[idx++] = (byte)sess->haveEMS;
25896
        data[idx++] = sess->haveAltSessionID ? ID_LEN : 0;
25897
        if (sess->haveAltSessionID) {
25898
            XMEMCPY(data + idx, sess->altSessionID, ID_LEN);
25899
            idx += ID_LEN;
25900
        }
25901
#ifdef SESSION_CERTS
25902
        data[idx++] = (byte)sess->chain.count;
25903
        for (i = 0; i < sess->chain.count; i++) {
25904
            c16toa((word16)sess->chain.certs[i].length, data + idx);
25905
            idx += OPAQUE16_LEN;
25906
            XMEMCPY(data + idx, sess->chain.certs[i].buffer,
25907
                    sess->chain.certs[i].length);
25908
            idx += sess->chain.certs[i].length;
25909
        }
25910
#endif
25911
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
25912
                               defined(HAVE_SESSION_TICKET))
25913
        data[idx++] = sess->version.major;
25914
        data[idx++] = sess->version.minor;
25915
#endif
25916
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
25917
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
25918
        data[idx++] = sess->cipherSuite0;
25919
        data[idx++] = sess->cipherSuite;
25920
#endif
25921
#ifndef NO_CLIENT_CACHE
25922
        c16toa(sess->idLen, data + idx); idx += OPAQUE16_LEN;
25923
        XMEMCPY(data + idx, sess->serverID, sess->idLen);
25924
        idx += sess->idLen;
25925
#endif
25926
#ifdef OPENSSL_EXTRA
25927
        data[idx++] = sess->sessionCtxSz;
25928
        XMEMCPY(data + idx, sess->sessionCtx, sess->sessionCtxSz);
25929
        idx += sess->sessionCtxSz;
25930
#endif
25931
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
25932
        data[idx++] = sess->peerVerifyRet;
25933
#endif
25934
#ifdef WOLFSSL_TLS13
25935
        c16toa(sess->namedGroup, data + idx);
25936
        idx += OPAQUE16_LEN;
25937
#endif
25938
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
25939
#ifdef WOLFSSL_TLS13
25940
#ifdef WOLFSSL_32BIT_MILLI_TIME
25941
        c32toa(sess->ticketSeen, data + idx);
25942
        idx += OPAQUE32_LEN;
25943
#else
25944
        c32toa((word32)(sess->ticketSeen >> 32), data + idx);
25945
        idx += OPAQUE32_LEN;
25946
        c32toa((word32)sess->ticketSeen, data + idx);
25947
        idx += OPAQUE32_LEN;
25948
#endif
25949
        c32toa(sess->ticketAdd, data + idx);
25950
        idx += OPAQUE32_LEN;
25951
        data[idx++] = sess->ticketNonce.len;
25952
        XMEMCPY(data + idx, sess->ticketNonce.data, sess->ticketNonce.len);
25953
        idx += sess->ticketNonce.len;
25954
#endif
25955
#ifdef WOLFSSL_EARLY_DATA
25956
        c32toa(sess->maxEarlyDataSz, data + idx);
25957
        idx += OPAQUE32_LEN;
25958
#endif
25959
#endif
25960
#ifdef HAVE_SESSION_TICKET
25961
        c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
25962
        XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
25963
        idx += sess->ticketLen;
25964
#endif
25965
    }
25966
#endif
25967
25968
    (void)sess;
25969
    (void)p;
25970
#ifdef HAVE_EXT_CACHE
25971
    (void)idx;
25972
#endif
25973
25974
    return size;
25975
}
25976
25977
25978
/* TODO: no function to free new session.
25979
 *
25980
 * Note: It is expected that the importing and exporting function have been
25981
 *       built with the same settings. For example if session tickets was
25982
 *       enabled with the wolfSSL library exporting a session then it is
25983
 *       expected to be turned on with the wolfSSL library importing the session.
25984
 */
25985
WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
25986
                                const unsigned char** p, long i)
25987
{
25988
    WOLFSSL_SESSION* s = NULL;
25989
    int ret = 0;
25990
#if defined(HAVE_EXT_CACHE)
25991
    int idx;
25992
    byte* data;
25993
#ifdef SESSION_CERTS
25994
    int j;
25995
    word16 length;
25996
#endif
25997
#endif /* HAVE_EXT_CACHE */
25998
25999
    (void)p;
26000
    (void)i;
26001
    (void)ret;
26002
    (void)sess;
26003
26004
#ifdef HAVE_EXT_CACHE
26005
    if (p == NULL || *p == NULL)
26006
        return NULL;
26007
26008
    s = wolfSSL_SESSION_new();
26009
    if (s == NULL)
26010
        return NULL;
26011
26012
    idx = 0;
26013
    data = (byte*)*p;
26014
26015
    /* side | bornOn | timeout | sessionID len */
26016
    if (i < OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) {
26017
        ret = BUFFER_ERROR;
26018
        goto end;
26019
    }
26020
    s->side = data[idx++];
26021
    ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN;
26022
    ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN;
26023
    s->sessionIDSz = data[idx++];
26024
26025
    /* sessionID | secret | haveEMS | haveAltSessionID */
26026
    if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN + OPAQUE8_LEN) {
26027
        ret = BUFFER_ERROR;
26028
        goto end;
26029
    }
26030
    XMEMCPY(s->sessionID, data + idx, s->sessionIDSz);
26031
    idx  += s->sessionIDSz;
26032
    XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN;
26033
    s->haveEMS = data[idx++];
26034
    if (data[idx] != ID_LEN && data[idx] != 0) {
26035
        ret = BUFFER_ERROR;
26036
        goto end;
26037
    }
26038
    s->haveAltSessionID = data[idx++] == ID_LEN;
26039
26040
    /* altSessionID */
26041
    if (s->haveAltSessionID) {
26042
        if (i - idx < ID_LEN) {
26043
            ret = BUFFER_ERROR;
26044
            goto end;
26045
        }
26046
        XMEMCPY(s->altSessionID, data + idx, ID_LEN); idx += ID_LEN;
26047
    }
26048
26049
#ifdef SESSION_CERTS
26050
    /* Certificate chain */
26051
    if (i - idx == 0) {
26052
        ret = BUFFER_ERROR;
26053
        goto end;
26054
    }
26055
    s->chain.count = data[idx++];
26056
    for (j = 0; j < s->chain.count; j++) {
26057
        if (i - idx < OPAQUE16_LEN) {
26058
            ret = BUFFER_ERROR;
26059
            goto end;
26060
        }
26061
        ato16(data + idx, &length); idx += OPAQUE16_LEN;
26062
        s->chain.certs[j].length = length;
26063
        if (i - idx < length) {
26064
            ret = BUFFER_ERROR;
26065
            goto end;
26066
        }
26067
        XMEMCPY(s->chain.certs[j].buffer, data + idx, length);
26068
        idx += length;
26069
    }
26070
#endif
26071
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
26072
                               defined(HAVE_SESSION_TICKET))
26073
    /* Protocol Version */
26074
    if (i - idx < OPAQUE16_LEN) {
26075
        ret = BUFFER_ERROR;
26076
        goto end;
26077
    }
26078
    s->version.major = data[idx++];
26079
    s->version.minor = data[idx++];
26080
#endif
26081
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
26082
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
26083
    /* Cipher suite */
26084
    if (i - idx < OPAQUE16_LEN) {
26085
        ret = BUFFER_ERROR;
26086
        goto end;
26087
    }
26088
    s->cipherSuite0 = data[idx++];
26089
    s->cipherSuite = data[idx++];
26090
#endif
26091
#ifndef NO_CLIENT_CACHE
26092
    /* ServerID len */
26093
    if (i - idx < OPAQUE16_LEN) {
26094
        ret = BUFFER_ERROR;
26095
        goto end;
26096
    }
26097
    ato16(data + idx, &s->idLen); idx += OPAQUE16_LEN;
26098
26099
    /* ServerID */
26100
    if (i - idx < s->idLen) {
26101
        ret = BUFFER_ERROR;
26102
        goto end;
26103
    }
26104
    XMEMCPY(s->serverID, data + idx, s->idLen); idx += s->idLen;
26105
#endif
26106
#ifdef OPENSSL_EXTRA
26107
    /* byte for length of session context ID */
26108
    if (i - idx < OPAQUE8_LEN) {
26109
        ret = BUFFER_ERROR;
26110
        goto end;
26111
    }
26112
    s->sessionCtxSz = data[idx++];
26113
26114
    /* app session context ID */
26115
    if (i - idx < s->sessionCtxSz) {
26116
        ret = BUFFER_ERROR;
26117
        goto end;
26118
    }
26119
    XMEMCPY(s->sessionCtx, data + idx, s->sessionCtxSz); idx += s->sessionCtxSz;
26120
#endif
26121
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
26122
    /* byte for peerVerifyRet */
26123
    if (i - idx < OPAQUE8_LEN) {
26124
        ret = BUFFER_ERROR;
26125
        goto end;
26126
    }
26127
    s->peerVerifyRet = data[idx++];
26128
#endif
26129
#ifdef WOLFSSL_TLS13
26130
    if (i - idx < OPAQUE16_LEN) {
26131
        ret = BUFFER_ERROR;
26132
        goto end;
26133
    }
26134
    ato16(data + idx, &s->namedGroup);
26135
    idx += OPAQUE16_LEN;
26136
#endif
26137
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
26138
#ifdef WOLFSSL_TLS13
26139
    if (i - idx < (OPAQUE32_LEN * 2)) {
26140
        ret = BUFFER_ERROR;
26141
        goto end;
26142
    }
26143
#ifdef WOLFSSL_32BIT_MILLI_TIME
26144
    ato32(data + idx, &s->ticketSeen);
26145
    idx += OPAQUE32_LEN;
26146
#else
26147
    {
26148
        word32 seenHi, seenLo;
26149
26150
        ato32(data + idx, &seenHi);
26151
        idx += OPAQUE32_LEN;
26152
        ato32(data + idx, &seenLo);
26153
        idx += OPAQUE32_LEN;
26154
        s->ticketSeen = ((sword64)seenHi << 32) + seenLo;
26155
    }
26156
#endif
26157
    ato32(data + idx, &s->ticketAdd);
26158
    idx += OPAQUE32_LEN;
26159
    if (i - idx < OPAQUE8_LEN) {
26160
        ret = BUFFER_ERROR;
26161
        goto end;
26162
    }
26163
    s->ticketNonce.len = data[idx++];
26164
26165
    if (i - idx < s->ticketNonce.len) {
26166
        ret = BUFFER_ERROR;
26167
        goto end;
26168
    }
26169
#if defined(WOLFSSL_TICKET_NONCE_MALLOC) &&                     \
26170
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
26171
    ret = SessionTicketNoncePopulate(s, data + idx, s->ticketNonce.len);
26172
    if (ret != 0)
26173
        goto end;
26174
#else
26175
    if (s->ticketNonce.len > MAX_TICKET_NONCE_STATIC_SZ) {
26176
        ret = BUFFER_ERROR;
26177
        goto end;
26178
    }
26179
    XMEMCPY(s->ticketNonce.data, data + idx, s->ticketNonce.len);
26180
#endif /* defined(WOLFSSL_TICKET_NONCE_MALLOC) && FIPS_VERSION_GE(5,3) */
26181
26182
    idx += s->ticketNonce.len;
26183
#endif
26184
#ifdef WOLFSSL_EARLY_DATA
26185
    if (i - idx < OPAQUE32_LEN) {
26186
        ret = BUFFER_ERROR;
26187
        goto end;
26188
    }
26189
    ato32(data + idx, &s->maxEarlyDataSz);
26190
    idx += OPAQUE32_LEN;
26191
#endif
26192
#endif
26193
#ifdef HAVE_SESSION_TICKET
26194
    /* ticket len */
26195
    if (i - idx < OPAQUE16_LEN) {
26196
        ret = BUFFER_ERROR;
26197
        goto end;
26198
    }
26199
    ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
26200
26201
    /* Dispose of ol dynamic ticket and ensure space for new ticket. */
26202
    if (s->ticketLenAlloc > 0) {
26203
        XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
26204
    }
26205
    if (s->ticketLen <= SESSION_TICKET_LEN)
26206
        s->ticket = s->staticTicket;
26207
    else {
26208
        s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
26209
                                   DYNAMIC_TYPE_SESSION_TICK);
26210
        if (s->ticket == NULL) {
26211
            ret = MEMORY_ERROR;
26212
            goto end;
26213
        }
26214
        s->ticketLenAlloc = (word16)s->ticketLen;
26215
    }
26216
26217
    /* ticket */
26218
    if (i - idx < s->ticketLen) {
26219
        ret = BUFFER_ERROR;
26220
        goto end;
26221
    }
26222
    XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
26223
#endif
26224
    (void)idx;
26225
26226
    if (sess != NULL) {
26227
        *sess = s;
26228
    }
26229
26230
    *p += idx;
26231
26232
end:
26233
    if (ret != 0 && (sess == NULL || *sess != s)) {
26234
        wolfSSL_SESSION_free(s);
26235
        s = NULL;
26236
    }
26237
#endif /* HAVE_EXT_CACHE */
26238
    return s;
26239
}
26240
26241
/* Check if there is a session ticket associated with this WOLFSSL_SESSION.
26242
 *
26243
 * sess - pointer to WOLFSSL_SESSION struct
26244
 *
26245
 * Returns 1 if has session ticket, otherwise 0 */
26246
int wolfSSL_SESSION_has_ticket(const WOLFSSL_SESSION* sess)
26247
{
26248
    WOLFSSL_ENTER("wolfSSL_SESSION_has_ticket");
26249
#ifdef HAVE_SESSION_TICKET
26250
    sess = ClientSessionToSession(sess);
26251
    if (sess) {
26252
        if ((sess->ticketLen > 0) && (sess->ticket != NULL)) {
26253
            return WOLFSSL_SUCCESS;
26254
        }
26255
    }
26256
#else
26257
    (void)sess;
26258
#endif
26259
    return WOLFSSL_FAILURE;
26260
}
26261
26262
unsigned long wolfSSL_SESSION_get_ticket_lifetime_hint(
26263
                  const WOLFSSL_SESSION* sess)
26264
{
26265
    WOLFSSL_ENTER("wolfSSL_SESSION_get_ticket_lifetime_hint");
26266
    sess = ClientSessionToSession(sess);
26267
    if (sess) {
26268
        return sess->timeout;
26269
    }
26270
    return 0;
26271
}
26272
26273
long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
26274
{
26275
    long timeout = 0;
26276
    WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
26277
    sess = ClientSessionToSession(sess);
26278
    if (sess)
26279
        timeout = sess->timeout;
26280
    return timeout;
26281
}
26282
26283
26284
long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
26285
{
26286
    long bornOn = 0;
26287
    WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
26288
    sess = ClientSessionToSession(sess);
26289
    if (sess)
26290
        bornOn = sess->bornOn;
26291
    return bornOn;
26292
}
26293
26294
long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
26295
{
26296
    word32 tmptime;
26297
26298
    ses = ClientSessionToSession(ses);
26299
    if (ses == NULL || t < 0) {
26300
        return BAD_FUNC_ARG;
26301
    }
26302
26303
    tmptime = t & 0xFFFFFFFF;
26304
    ses->timeout = tmptime;
26305
26306
    return WOLFSSL_SUCCESS;
26307
}
26308
26309
#endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
26310
26311
#ifdef OPENSSL_EXTRA
26312
26313
#if defined(HAVE_EX_DATA) && !defined(NO_FILESYSTEM)
26314
int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
26315
{
26316
    int ret = WOLFSSL_FATAL_ERROR;
26317
26318
    WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
26319
    if (ssl != NULL && fname != NULL)
26320
    {
26321
    #ifdef WOLFSSL_SMALL_STACK
26322
        byte           staticBuffer[1]; /* force heap usage */
26323
    #else
26324
        byte           staticBuffer[FILE_BUFFER_SIZE];
26325
    #endif
26326
        byte*          myBuffer  = staticBuffer;
26327
        int            dynamic   = 0;
26328
        XFILE          file;
26329
        long           sz        = 0;
26330
        WOLFSSL_CTX*   ctx       = ssl->ctx;
26331
        WOLFSSL_X509*  peer_cert = &ssl->peerCert;
26332
        DerBuffer*     fileDer = NULL;
26333
26334
        file = XFOPEN(fname, "rb");
26335
        if (file == XBADFILE)
26336
            return WOLFSSL_BAD_FILE;
26337
26338
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
26339
            XFCLOSE(file);
26340
            return WOLFSSL_BAD_FILE;
26341
        }
26342
        sz = XFTELL(file);
26343
        XREWIND(file);
26344
26345
        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
26346
            WOLFSSL_MSG("cmp_peer_cert_to_file size error");
26347
            XFCLOSE(file);
26348
            return WOLFSSL_BAD_FILE;
26349
        }
26350
26351
        if (sz > (long)sizeof(staticBuffer)) {
26352
            WOLFSSL_MSG("Getting dynamic buffer");
26353
            myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
26354
            dynamic = 1;
26355
        }
26356
26357
        if ((myBuffer != NULL) &&
26358
            (sz > 0) &&
26359
            (XFREAD(myBuffer, 1, sz, file) == (size_t)sz) &&
26360
            (PemToDer(myBuffer, (long)sz, CERT_TYPE,
26361
                      &fileDer, ctx->heap, NULL, NULL) == 0) &&
26362
            (fileDer->length != 0) &&
26363
            (fileDer->length == peer_cert->derCert->length) &&
26364
            (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
26365
                                                fileDer->length) == 0))
26366
        {
26367
            ret = 0;
26368
        }
26369
26370
        FreeDer(&fileDer);
26371
26372
        if (dynamic)
26373
            XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
26374
26375
        XFCLOSE(file);
26376
    }
26377
26378
    return ret;
26379
}
26380
#endif
26381
#endif /* OPENSSL_EXTRA */
26382
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
26383
const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
26384
#ifndef NO_CERTS
26385
    /* oidCertExtType */
26386
    { NID_basic_constraints, BASIC_CA_OID, oidCertExtType, "basicConstraints",
26387
                                                "X509v3 Basic Constraints"},
26388
    { NID_subject_alt_name, ALT_NAMES_OID, oidCertExtType, "subjectAltName",
26389
                                         "X509v3 Subject Alternative Name"},
26390
    { NID_crl_distribution_points, CRL_DIST_OID, oidCertExtType, "crlDistributionPoints",
26391
                                          "X509v3 CRL Distribution Points"},
26392
    { NID_info_access, AUTH_INFO_OID, oidCertExtType, "authorityInfoAccess",
26393
                                            "Authority Information Access"},
26394
    { NID_authority_key_identifier, AUTH_KEY_OID, oidCertExtType,
26395
               "authorityKeyIdentifier", "X509v3 Authority Key Identifier"},
26396
    { NID_subject_key_identifier, SUBJ_KEY_OID, oidCertExtType,
26397
                   "subjectKeyIdentifier", "X509v3 Subject Key Identifier"},
26398
    { NID_key_usage, KEY_USAGE_OID, oidCertExtType, "keyUsage",
26399
                                                        "X509v3 Key Usage"},
26400
    { NID_inhibit_any_policy, INHIBIT_ANY_OID, oidCertExtType,
26401
                           "inhibitAnyPolicy", "X509v3 Inhibit Any Policy"},
26402
    { NID_ext_key_usage, EXT_KEY_USAGE_OID, oidCertExtType,
26403
                           "extendedKeyUsage", "X509v3 Extended Key Usage"},
26404
    { NID_name_constraints, NAME_CONS_OID, oidCertExtType,
26405
                              "nameConstraints", "X509v3 Name Constraints"},
26406
    { NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
26407
                      "certificatePolicies", "X509v3 Certificate Policies"},
26408
26409
    /* oidCertAuthInfoType */
26410
    { NID_ad_OCSP, AIA_OCSP_OID, oidCertAuthInfoType, "OCSP",
26411
                                            "OCSP"},
26412
    { NID_ad_ca_issuers, AIA_CA_ISSUER_OID, oidCertAuthInfoType,
26413
                                                 "caIssuers", "CA Issuers"},
26414
26415
    /* oidCertPolicyType */
26416
    { NID_any_policy, CP_ANY_OID, oidCertPolicyType, "anyPolicy",
26417
                                                       "X509v3 Any Policy"},
26418
26419
    /* oidCertAltNameType */
26420
    { NID_hw_name_oid, HW_NAME_OID, oidCertAltNameType, "Hardware name",""},
26421
26422
    /* oidCertKeyUseType */
26423
    { NID_anyExtendedKeyUsage, EKU_ANY_OID, oidCertKeyUseType,
26424
                           "anyExtendedKeyUsage", "Any Extended Key Usage"},
26425
    { EKU_SERVER_AUTH_OID, EKU_SERVER_AUTH_OID, oidCertKeyUseType,
26426
                             "serverAuth", "TLS Web Server Authentication"},
26427
    { EKU_CLIENT_AUTH_OID, EKU_CLIENT_AUTH_OID, oidCertKeyUseType,
26428
                             "clientAuth", "TLS Web Client Authentication"},
26429
    { EKU_OCSP_SIGN_OID, EKU_OCSP_SIGN_OID, oidCertKeyUseType,
26430
                                             "OCSPSigning", "OCSP Signing"},
26431
26432
    /* oidCertNameType */
26433
    { NID_commonName, NID_commonName, oidCertNameType, "CN", "commonName"},
26434
    { NID_surname, NID_surname, oidCertNameType, "SN", "surname"},
26435
    { NID_serialNumber, NID_serialNumber, oidCertNameType, "serialNumber",
26436
                                                            "serialNumber"},
26437
    { NID_userId, NID_userId, oidCertNameType, "UID", "userid"},
26438
    { NID_countryName, NID_countryName, oidCertNameType, "C", "countryName"},
26439
    { NID_localityName, NID_localityName, oidCertNameType, "L", "localityName"},
26440
    { NID_stateOrProvinceName, NID_stateOrProvinceName, oidCertNameType, "ST",
26441
                                                        "stateOrProvinceName"},
26442
    { NID_streetAddress, NID_streetAddress, oidCertNameType, "street",
26443
                                                        "streetAddress"},
26444
    { NID_organizationName, NID_organizationName, oidCertNameType, "O",
26445
                                                        "organizationName"},
26446
    { NID_organizationalUnitName, NID_organizationalUnitName, oidCertNameType,
26447
                                                "OU", "organizationalUnitName"},
26448
    { NID_emailAddress, NID_emailAddress, oidCertNameType, "emailAddress",
26449
                                                            "emailAddress"},
26450
    { NID_domainComponent, NID_domainComponent, oidCertNameType, "DC",
26451
                                                            "domainComponent"},
26452
    { NID_favouriteDrink, NID_favouriteDrink, oidCertNameType, "favouriteDrink",
26453
                                                            "favouriteDrink"},
26454
    { NID_businessCategory, NID_businessCategory, oidCertNameType, "businessCategory",
26455
                                                            "businessCategory"},
26456
    { NID_jurisdictionCountryName, NID_jurisdictionCountryName, oidCertNameType, "jurisdictionC",
26457
                                                            "jurisdictionCountryName"},
26458
    { NID_jurisdictionStateOrProvinceName, NID_jurisdictionStateOrProvinceName,
26459
            oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"},
26460
    { NID_postalCode, NID_postalCode, oidCertNameType, "postalCode", "postalCode"},
26461
    { NID_userId, NID_userId, oidCertNameType, "UID", "userId"},
26462
26463
#ifdef WOLFSSL_CERT_REQ
26464
    { NID_pkcs9_challengePassword, CHALLENGE_PASSWORD_OID,
26465
            oidCsrAttrType, "challengePassword", "challengePassword"},
26466
    { NID_pkcs9_contentType, PKCS9_CONTENT_TYPE_OID,
26467
        oidCsrAttrType, "contentType", "contentType" },
26468
    { NID_pkcs9_unstructuredName, UNSTRUCTURED_NAME_OID,
26469
        oidCsrAttrType, "unstructuredName", "unstructuredName" },
26470
    { NID_name, NAME_OID, oidCsrAttrType, "name", "name" },
26471
    { NID_surname, SURNAME_OID,
26472
        oidCsrAttrType, "surname", "surname" },
26473
    { NID_givenName, GIVEN_NAME_OID,
26474
        oidCsrAttrType, "givenName", "givenName" },
26475
    { NID_initials, INITIALS_OID,
26476
        oidCsrAttrType, "initials", "initials" },
26477
    { NID_dnQualifier, DNQUALIFIER_OID,
26478
        oidCsrAttrType, "dnQualifer", "dnQualifier" },
26479
#endif
26480
#endif
26481
#ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */
26482
        /* oidHashType */
26483
    #ifdef WOLFSSL_MD2
26484
        { NID_md2, MD2h, oidHashType, "MD2", "md2"},
26485
    #endif
26486
    #ifdef WOLFSSL_MD5
26487
        { NID_md5, MD5h, oidHashType, "MD5", "md5"},
26488
    #endif
26489
    #ifndef NO_SHA
26490
        { NID_sha1, SHAh, oidHashType, "SHA1", "sha1"},
26491
    #endif
26492
    #ifdef WOLFSSL_SHA224
26493
        { NID_sha224, SHA224h, oidHashType, "SHA224", "sha224"},
26494
    #endif
26495
    #ifndef NO_SHA256
26496
        { NID_sha256, SHA256h, oidHashType, "SHA256", "sha256"},
26497
    #endif
26498
    #ifdef WOLFSSL_SHA384
26499
        { NID_sha384, SHA384h, oidHashType, "SHA384", "sha384"},
26500
    #endif
26501
    #ifdef WOLFSSL_SHA512
26502
        { NID_sha512, SHA512h, oidHashType, "SHA512", "sha512"},
26503
    #endif
26504
    #ifdef WOLFSSL_SHA3
26505
        #ifndef WOLFSSL_NOSHA3_224
26506
        { NID_sha3_224, SHA3_224h, oidHashType, "SHA3-224", "sha3-224"},
26507
        #endif
26508
        #ifndef WOLFSSL_NOSHA3_256
26509
        { NID_sha3_256, SHA3_256h, oidHashType, "SHA3-256", "sha3-256"},
26510
        #endif
26511
        #ifndef WOLFSSL_NOSHA3_384
26512
        { NID_sha3_384, SHA3_384h, oidHashType, "SHA3-384", "sha3-384"},
26513
        #endif
26514
        #ifndef WOLFSSL_NOSHA3_512
26515
        { NID_sha3_512, SHA3_512h, oidHashType, "SHA3-512", "sha3-512"},
26516
        #endif
26517
    #endif /* WOLFSSL_SHA3 */
26518
        /* oidSigType */
26519
    #ifndef NO_DSA
26520
        #ifndef NO_SHA
26521
        { NID_dsaWithSHA1, CTC_SHAwDSA, oidSigType, "DSA-SHA1", "dsaWithSHA1"},
26522
        { NID_dsa_with_SHA256, CTC_SHA256wDSA, oidSigType, "dsa_with_SHA256",
26523
                                                        "dsa_with_SHA256"},
26524
        #endif
26525
    #endif /* NO_DSA */
26526
    #ifndef NO_RSA
26527
        #ifdef WOLFSSL_MD2
26528
        { NID_md2WithRSAEncryption, CTC_MD2wRSA, oidSigType, "RSA-MD2",
26529
                                                        "md2WithRSAEncryption"},
26530
        #endif
26531
        #ifndef NO_MD5
26532
        { NID_md5WithRSAEncryption, CTC_MD5wRSA, oidSigType, "RSA-MD5",
26533
                                                        "md5WithRSAEncryption"},
26534
        #endif
26535
        #ifndef NO_SHA
26536
        { NID_sha1WithRSAEncryption, CTC_SHAwRSA, oidSigType, "RSA-SHA1",
26537
                                                       "sha1WithRSAEncryption"},
26538
        #endif
26539
        #ifdef WOLFSSL_SHA224
26540
        { NID_sha224WithRSAEncryption, CTC_SHA224wRSA, oidSigType, "RSA-SHA224",
26541
                                                     "sha224WithRSAEncryption"},
26542
        #endif
26543
        #ifndef NO_SHA256
26544
        { NID_sha256WithRSAEncryption, CTC_SHA256wRSA, oidSigType, "RSA-SHA256",
26545
                                                     "sha256WithRSAEncryption"},
26546
        #endif
26547
        #ifdef WOLFSSL_SHA384
26548
        { NID_sha384WithRSAEncryption, CTC_SHA384wRSA, oidSigType, "RSA-SHA384",
26549
                                                     "sha384WithRSAEncryption"},
26550
        #endif
26551
        #ifdef WOLFSSL_SHA512
26552
        { NID_sha512WithRSAEncryption, CTC_SHA512wRSA, oidSigType, "RSA-SHA512",
26553
                                                     "sha512WithRSAEncryption"},
26554
        #endif
26555
        #ifdef WOLFSSL_SHA3
26556
        #ifndef WOLFSSL_NOSHA3_224
26557
        { NID_RSA_SHA3_224, CTC_SHA3_224wRSA, oidSigType, "RSA-SHA3-224",
26558
                                                     "sha3-224WithRSAEncryption"},
26559
        #endif
26560
        #ifndef WOLFSSL_NOSHA3_256
26561
        { NID_RSA_SHA3_256, CTC_SHA3_256wRSA, oidSigType, "RSA-SHA3-256",
26562
                                                     "sha3-256WithRSAEncryption"},
26563
        #endif
26564
        #ifndef WOLFSSL_NOSHA3_384
26565
        { NID_RSA_SHA3_384, CTC_SHA3_384wRSA, oidSigType, "RSA-SHA3-384",
26566
                                                     "sha3-384WithRSAEncryption"},
26567
        #endif
26568
        #ifndef WOLFSSL_NOSHA3_512
26569
        { NID_RSA_SHA3_512, CTC_SHA3_512wRSA, oidSigType, "RSA-SHA3-512",
26570
                                                     "sha3-512WithRSAEncryption"},
26571
        #endif
26572
        #endif
26573
    #endif /* NO_RSA */
26574
    #ifdef HAVE_ECC
26575
        #ifndef NO_SHA
26576
        { NID_ecdsa_with_SHA1, CTC_SHAwECDSA, oidSigType, "ecdsa-with-SHA1", "shaWithECDSA"},
26577
        #endif
26578
        #ifdef WOLFSSL_SHA224
26579
        { NID_ecdsa_with_SHA224, CTC_SHA224wECDSA, oidSigType, "ecdsa-with-SHA224","sha224WithECDSA"},
26580
        #endif
26581
        #ifndef NO_SHA256
26582
        { NID_ecdsa_with_SHA256, CTC_SHA256wECDSA, oidSigType, "ecdsa-with-SHA256","sha256WithECDSA"},
26583
        #endif
26584
        #ifdef WOLFSSL_SHA384
26585
        { NID_ecdsa_with_SHA384, CTC_SHA384wECDSA, oidSigType, "ecdsa-with-SHA384","sha384WithECDSA"},
26586
        #endif
26587
        #ifdef WOLFSSL_SHA512
26588
        { NID_ecdsa_with_SHA512, CTC_SHA512wECDSA, oidSigType, "ecdsa-with-SHA512","sha512WithECDSA"},
26589
        #endif
26590
        #ifdef WOLFSSL_SHA3
26591
        #ifndef WOLFSSL_NOSHA3_224
26592
        { NID_ecdsa_with_SHA3_224, CTC_SHA3_224wECDSA, oidSigType, "id-ecdsa-with-SHA3-224",
26593
                "ecdsa_with_SHA3-224"},
26594
        #endif
26595
        #ifndef WOLFSSL_NOSHA3_256
26596
        { NID_ecdsa_with_SHA3_256, CTC_SHA3_256wECDSA, oidSigType, "id-ecdsa-with-SHA3-256",
26597
                "ecdsa_with_SHA3-256"},
26598
        #endif
26599
        #ifndef WOLFSSL_NOSHA3_384
26600
        { NID_ecdsa_with_SHA3_384, CTC_SHA3_384wECDSA, oidSigType, "id-ecdsa-with-SHA3-384",
26601
                "ecdsa_with_SHA3-384"},
26602
        #endif
26603
        #ifndef WOLFSSL_NOSHA3_512
26604
        { NID_ecdsa_with_SHA3_512, CTC_SHA3_512wECDSA, oidSigType, "id-ecdsa-with-SHA3-512",
26605
                "ecdsa_with_SHA3-512"},
26606
        #endif
26607
        #endif
26608
    #endif /* HAVE_ECC */
26609
26610
        /* oidKeyType */
26611
    #ifndef NO_DSA
26612
        { NID_dsa, DSAk, oidKeyType, "DSA", "dsaEncryption"},
26613
    #endif /* NO_DSA */
26614
    #ifndef NO_RSA
26615
        { NID_rsaEncryption, RSAk, oidKeyType, "rsaEncryption", "rsaEncryption"},
26616
    #endif /* NO_RSA */
26617
    #ifdef HAVE_ECC
26618
        { NID_X9_62_id_ecPublicKey, ECDSAk, oidKeyType, "id-ecPublicKey",
26619
                                                        "id-ecPublicKey"},
26620
    #endif /* HAVE_ECC */
26621
    #ifndef NO_DH
26622
        { NID_dhKeyAgreement, DHk, oidKeyType, "dhKeyAgreement", "dhKeyAgreement"},
26623
    #endif
26624
    #ifdef HAVE_ED448
26625
        { NID_ED448, ED448k,  oidKeyType, "ED448", "ED448"},
26626
    #endif
26627
    #ifdef HAVE_ED25519
26628
        { NID_ED25519, ED25519k,  oidKeyType, "ED25519", "ED25519"},
26629
    #endif
26630
    #ifdef HAVE_PQC
26631
    #ifdef HAVE_FALCON
26632
        { CTC_FALCON_LEVEL1, FALCON_LEVEL1k,  oidKeyType, "Falcon Level 1",
26633
                                                          "Falcon Level 1"},
26634
        { CTC_FALCON_LEVEL5, FALCON_LEVEL5k,  oidKeyType, "Falcon Level 5",
26635
                                                          "Falcon Level 5"},
26636
    #endif /* HAVE_FALCON */
26637
    #ifdef HAVE_DILITHIUM
26638
        { CTC_DILITHIUM_LEVEL2, DILITHIUM_LEVEL2k,  oidKeyType,
26639
          "Dilithium Level 2", "Dilithium Level 2"},
26640
        { CTC_DILITHIUM_LEVEL3, DILITHIUM_LEVEL3k,  oidKeyType,
26641
          "Dilithium Level 3", "Dilithium Level 3"},
26642
        { CTC_DILITHIUM_LEVEL5, DILITHIUM_LEVEL5k,  oidKeyType,
26643
          "Dilithium Level 5", "Dilithium Level 5"},
26644
        { CTC_DILITHIUM_AES_LEVEL2, DILITHIUM_AES_LEVEL2k,  oidKeyType,
26645
          "Dilithium AES Level 2", "Dilithium AES Level 2"},
26646
        { CTC_DILITHIUM_AES_LEVEL3, DILITHIUM_AES_LEVEL3k,  oidKeyType,
26647
          "Dilithium AES Level 3", "Dilithium AES Level 3"},
26648
        { CTC_DILITHIUM_AES_LEVEL5, DILITHIUM_AES_LEVEL5k,  oidKeyType,
26649
          "Dilithium AES Level 5", "Dilithium AES Level 5"},
26650
    #endif /* HAVE_DILITHIUM */
26651
    #endif /* HAVE_PQC */
26652
26653
        /* oidCurveType */
26654
    #ifdef HAVE_ECC
26655
        { NID_X9_62_prime192v1, ECC_SECP192R1_OID, oidCurveType, "prime192v1", "prime192v1"},
26656
        { NID_X9_62_prime192v2, ECC_PRIME192V2_OID, oidCurveType, "prime192v2", "prime192v2"},
26657
        { NID_X9_62_prime192v3, ECC_PRIME192V3_OID, oidCurveType, "prime192v3", "prime192v3"},
26658
26659
        { NID_X9_62_prime239v1, ECC_PRIME239V1_OID, oidCurveType, "prime239v1", "prime239v1"},
26660
        { NID_X9_62_prime239v2, ECC_PRIME239V2_OID, oidCurveType, "prime239v2", "prime239v2"},
26661
        { NID_X9_62_prime239v3, ECC_PRIME239V3_OID, oidCurveType, "prime239v3", "prime239v3"},
26662
26663
        { NID_X9_62_prime256v1, ECC_SECP256R1_OID, oidCurveType, "prime256v1", "prime256v1"},
26664
26665
        { NID_secp112r1, ECC_SECP112R1_OID,  oidCurveType, "secp112r1", "secp112r1"},
26666
        { NID_secp112r2, ECC_SECP112R2_OID,  oidCurveType, "secp112r2", "secp112r2"},
26667
26668
        { NID_secp128r1, ECC_SECP128R1_OID,  oidCurveType, "secp128r1", "secp128r1"},
26669
        { NID_secp128r2, ECC_SECP128R2_OID,  oidCurveType, "secp128r2", "secp128r2"},
26670
26671
        { NID_secp160r1, ECC_SECP160R1_OID,  oidCurveType, "secp160r1", "secp160r1"},
26672
        { NID_secp160r2, ECC_SECP160R2_OID,  oidCurveType, "secp160r2", "secp160r2"},
26673
26674
        { NID_secp224r1, ECC_SECP224R1_OID,  oidCurveType, "secp224r1", "secp224r1"},
26675
        { NID_secp384r1, ECC_SECP384R1_OID,  oidCurveType, "secp384r1", "secp384r1"},
26676
        { NID_secp521r1, ECC_SECP521R1_OID,  oidCurveType, "secp521r1", "secp521r1"},
26677
26678
        { NID_secp160k1, ECC_SECP160K1_OID,  oidCurveType, "secp160k1", "secp160k1"},
26679
        { NID_secp192k1, ECC_SECP192K1_OID,  oidCurveType, "secp192k1", "secp192k1"},
26680
        { NID_secp224k1, ECC_SECP224K1_OID,  oidCurveType, "secp224k1", "secp224k1"},
26681
        { NID_secp256k1, ECC_SECP256K1_OID,  oidCurveType, "secp256k1", "secp256k1"},
26682
26683
        { NID_brainpoolP160r1, ECC_BRAINPOOLP160R1_OID,  oidCurveType, "brainpoolP160r1", "brainpoolP160r1"},
26684
        { NID_brainpoolP192r1, ECC_BRAINPOOLP192R1_OID,  oidCurveType, "brainpoolP192r1", "brainpoolP192r1"},
26685
        { NID_brainpoolP224r1, ECC_BRAINPOOLP224R1_OID,  oidCurveType, "brainpoolP224r1", "brainpoolP224r1"},
26686
        { NID_brainpoolP256r1, ECC_BRAINPOOLP256R1_OID,  oidCurveType, "brainpoolP256r1", "brainpoolP256r1"},
26687
        { NID_brainpoolP320r1, ECC_BRAINPOOLP320R1_OID,  oidCurveType, "brainpoolP320r1", "brainpoolP320r1"},
26688
        { NID_brainpoolP384r1, ECC_BRAINPOOLP384R1_OID,  oidCurveType, "brainpoolP384r1", "brainpoolP384r1"},
26689
        { NID_brainpoolP512r1, ECC_BRAINPOOLP512R1_OID,  oidCurveType, "brainpoolP512r1", "brainpoolP512r1"},
26690
    #endif /* HAVE_ECC */
26691
26692
        /* oidBlkType */
26693
    #ifdef WOLFSSL_AES_128
26694
        { AES128CBCb, AES128CBCb, oidBlkType, "AES-128-CBC", "aes-128-cbc"},
26695
    #endif
26696
    #ifdef WOLFSSL_AES_192
26697
        { AES192CBCb, AES192CBCb, oidBlkType, "AES-192-CBC", "aes-192-cbc"},
26698
    #endif
26699
    #ifdef WOLFSSL_AES_256
26700
        { AES256CBCb, AES256CBCb, oidBlkType, "AES-256-CBC", "aes-256-cbc"},
26701
    #endif
26702
    #ifndef NO_DES3
26703
        { NID_des, DESb, oidBlkType, "DES-CBC", "des-cbc"},
26704
        { NID_des3, DES3b, oidBlkType, "DES-EDE3-CBC", "des-ede3-cbc"},
26705
    #endif /* !NO_DES3 */
26706
    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
26707
        { NID_chacha20_poly1305, NID_chacha20_poly1305, oidBlkType, "ChaCha20-Poly1305", "chacha20-poly1305"},
26708
    #endif
26709
26710
        /* oidOcspType */
26711
    #ifdef HAVE_OCSP
26712
        { NID_id_pkix_OCSP_basic, OCSP_BASIC_OID, oidOcspType, "basicOCSPResponse",
26713
                                                         "Basic OCSP Response"},
26714
        { OCSP_NONCE_OID, OCSP_NONCE_OID, oidOcspType, "Nonce",
26715
                                                                  "OCSP Nonce"},
26716
    #endif /* HAVE_OCSP */
26717
26718
    #ifndef NO_PWDBASED
26719
        /* oidKdfType */
26720
        { PBKDF2_OID, PBKDF2_OID, oidKdfType, "PBKDFv2", "PBKDF2"},
26721
26722
        /* oidPBEType */
26723
        { PBE_SHA1_RC4_128, PBE_SHA1_RC4_128, oidPBEType,
26724
                                 "PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4"},
26725
        { PBE_SHA1_DES, PBE_SHA1_DES, oidPBEType, "PBE-SHA1-DES",
26726
                                                       "pbeWithSHA1AndDES-CBC"},
26727
        { PBE_SHA1_DES3, PBE_SHA1_DES3, oidPBEType, "PBE-SHA1-3DES",
26728
                                            "pbeWithSHA1And3-KeyTripleDES-CBC"},
26729
    #endif
26730
26731
        /* oidKeyWrapType */
26732
    #ifdef WOLFSSL_AES_128
26733
        { AES128_WRAP, AES128_WRAP, oidKeyWrapType, "AES-128 wrap", "aes128-wrap"},
26734
    #endif
26735
    #ifdef WOLFSSL_AES_192
26736
        { AES192_WRAP, AES192_WRAP, oidKeyWrapType, "AES-192 wrap", "aes192-wrap"},
26737
    #endif
26738
    #ifdef WOLFSSL_AES_256
26739
        { AES256_WRAP, AES256_WRAP, oidKeyWrapType, "AES-256 wrap", "aes256-wrap"},
26740
    #endif
26741
26742
    #ifndef NO_PKCS7
26743
        #ifndef NO_DH
26744
        /* oidCmsKeyAgreeType */
26745
            #ifndef NO_SHA
26746
        { dhSinglePass_stdDH_sha1kdf_scheme, dhSinglePass_stdDH_sha1kdf_scheme,
26747
                oidCmsKeyAgreeType, "dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme"},
26748
            #endif
26749
            #ifdef WOLFSSL_SHA224
26750
        { dhSinglePass_stdDH_sha224kdf_scheme,
26751
                dhSinglePass_stdDH_sha224kdf_scheme, oidCmsKeyAgreeType,
26752
                "dhSinglePass-stdDH-sha224kdf-scheme", "dhSinglePass-stdDH-sha224kdf-scheme"},
26753
            #endif
26754
            #ifndef NO_SHA256
26755
        { dhSinglePass_stdDH_sha256kdf_scheme,
26756
                        dhSinglePass_stdDH_sha256kdf_scheme, oidCmsKeyAgreeType,
26757
                        "dhSinglePass-stdDH-sha256kdf-scheme", "dhSinglePass-stdDH-sha256kdf-scheme"},
26758
            #endif
26759
            #ifdef WOLFSSL_SHA384
26760
        { dhSinglePass_stdDH_sha384kdf_scheme,
26761
                        dhSinglePass_stdDH_sha384kdf_scheme, oidCmsKeyAgreeType,
26762
                        "dhSinglePass-stdDH-sha384kdf-scheme", "dhSinglePass-stdDH-sha384kdf-scheme"},
26763
            #endif
26764
            #ifdef WOLFSSL_SHA512
26765
        { dhSinglePass_stdDH_sha512kdf_scheme,
26766
                        dhSinglePass_stdDH_sha512kdf_scheme, oidCmsKeyAgreeType,
26767
                        "dhSinglePass-stdDH-sha512kdf-scheme", "dhSinglePass-stdDH-sha512kdf-scheme"},
26768
            #endif
26769
        #endif
26770
    #endif
26771
    #if defined(WOLFSSL_APACHE_HTTPD)
26772
        /* "1.3.6.1.5.5.7.8.7" */
26773
        { NID_id_on_dnsSRV, NID_id_on_dnsSRV, oidCertNameType,
26774
            WOLFSSL_SN_DNS_SRV, WOLFSSL_LN_DNS_SRV },
26775
26776
        /* "1.3.6.1.4.1.311.20.2.3" */
26777
        { NID_ms_upn, WOLFSSL_MS_UPN_SUM, oidCertExtType, WOLFSSL_SN_MS_UPN,
26778
            WOLFSSL_LN_MS_UPN },
26779
26780
        /* "1.3.6.1.5.5.7.1.24" */
26781
        { NID_tlsfeature, WOLFSSL_TLS_FEATURE_SUM, oidTlsExtType,
26782
            WOLFSSL_SN_TLS_FEATURE, WOLFSSL_LN_TLS_FEATURE },
26783
    #endif
26784
#endif /* OPENSSL_EXTRA */
26785
};
26786
26787
#define WOLFSSL_OBJECT_INFO_SZ \
26788
                (sizeof(wolfssl_object_info) / sizeof(*wolfssl_object_info))
26789
const size_t wolfssl_object_info_sz = WOLFSSL_OBJECT_INFO_SZ;
26790
#endif
26791
26792
#ifdef OPENSSL_EXTRA
26793
26794
WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFSSL_ASN1_INTEGER *ai)
26795
{
26796
    WOLFSSL_ASN1_INTEGER* a;
26797
    int len;
26798
    const int extraTagSz = MAX_LENGTH_SZ + 1;
26799
    byte intTag[MAX_LENGTH_SZ + 1];
26800
    int idx = 0;
26801
    WOLFSSL_ENTER("wolfSSL_BN_to_ASN1_INTEGER");
26802
26803
    if (ai == NULL) {
26804
        a = wolfSSL_ASN1_INTEGER_new();
26805
26806
        if (a == NULL)
26807
            return NULL;
26808
26809
        a->type = V_ASN1_INTEGER;
26810
    }
26811
    else {
26812
        a = ai;
26813
    }
26814
    if (a) {
26815
        if (wolfSSL_BN_is_negative(bn) && !wolfSSL_BN_is_zero(bn)) {
26816
            a->type |= V_ASN1_NEG_INTEGER;
26817
            a->negative = 1;
26818
        }
26819
26820
        len = wolfSSL_BN_num_bytes(bn);
26821
        if (len == 0)
26822
            len = 1;
26823
26824
        /* allocate buffer */
26825
        if (len + extraTagSz > (int)sizeof(a->intData)) {
26826
            /* create new data buffer and copy over */
26827
            a->data = (byte*)XMALLOC(len + extraTagSz, NULL,
26828
                    DYNAMIC_TYPE_OPENSSL);
26829
            if (a->data == NULL) {
26830
                if (a != ai)
26831
                    wolfSSL_ASN1_INTEGER_free(a);
26832
                return NULL;
26833
            }
26834
            a->isDynamic = 1;
26835
        }
26836
        else {
26837
            XMEMSET(a->intData, 0, sizeof(a->intData));
26838
            a->data = a->intData;
26839
            a->isDynamic = 0;
26840
        }
26841
26842
        /* populate data */
26843
        if (wolfSSL_BN_is_zero(bn)) {
26844
            a->data[0] = 0;
26845
        }
26846
        else {
26847
            len = wolfSSL_BN_bn2bin(bn, a->data);
26848
            if (len < 0) {
26849
                wolfSSL_ASN1_INTEGER_free(a);
26850
                return NULL;
26851
            }
26852
        }
26853
        a->length = len;
26854
26855
        /* Write ASN tag */
26856
        idx = SetASNInt(a->length, a->data[0], intTag);
26857
        XMEMMOVE(a->data + idx, a->data, a->length);
26858
        XMEMCPY(a->data, intTag, idx);
26859
        a->dataMax = a->length += idx;
26860
    }
26861
26862
    return a;
26863
}
26864
26865
#ifdef OPENSSL_ALL
26866
void *wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM *tpl)
26867
{
26868
    void *ret = NULL;
26869
    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
26870
    size_t i;
26871
    WOLFSSL_ENTER("wolfSSL_ASN1_item_new");
26872
    if (!tpl) {
26873
        return NULL;
26874
    }
26875
    if (!(ret = (void *)XMALLOC(tpl->size, NULL, DYNAMIC_TYPE_OPENSSL))) {
26876
        return NULL;
26877
    }
26878
    XMEMSET(ret, 0, tpl->size);
26879
    for (member = tpl->members, i = 0; i < tpl->mcount;
26880
            member++, i++) {
26881
        switch (member->type) {
26882
            case WOLFSSL_X509_ALGOR_ASN1:
26883
            {
26884
                WOLFSSL_X509_ALGOR* algor = wolfSSL_X509_ALGOR_new();
26885
                if (!algor) {
26886
                    goto error;
26887
                }
26888
                *(WOLFSSL_X509_ALGOR**)(((byte*)ret) + member->offset) = algor;
26889
                break;
26890
            }
26891
            case WOLFSSL_ASN1_BIT_STRING_ASN1:
26892
            {
26893
                WOLFSSL_ASN1_BIT_STRING* bit_str = wolfSSL_ASN1_BIT_STRING_new();
26894
                if (!bit_str) {
26895
                    goto error;
26896
                }
26897
                *(WOLFSSL_ASN1_BIT_STRING**)(((byte*)ret) + member->offset) = bit_str;
26898
                break;
26899
            }
26900
            default:
26901
                WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_new");
26902
                goto error;
26903
        }
26904
    }
26905
    return ret;
26906
error:
26907
    wolfSSL_ASN1_item_free(ret, tpl);
26908
    return NULL;
26909
}
26910
26911
void wolfSSL_ASN1_item_free(void *val, const WOLFSSL_ASN1_ITEM *tpl)
26912
{
26913
    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
26914
    size_t i;
26915
    WOLFSSL_ENTER("wolfSSL_ASN1_item_free");
26916
    if (val) {
26917
        for (member = tpl->members, i = 0; i < tpl->mcount;
26918
                member++, i++) {
26919
            switch (member->type) {
26920
                case WOLFSSL_X509_ALGOR_ASN1:
26921
                {
26922
                    WOLFSSL_X509_ALGOR* algor = *(WOLFSSL_X509_ALGOR**)
26923
                                                 (((byte*)val) + member->offset);
26924
                    if (algor) {
26925
                        wolfSSL_X509_ALGOR_free(algor);
26926
                    }
26927
                    break;
26928
                }
26929
                case WOLFSSL_ASN1_BIT_STRING_ASN1:
26930
                {
26931
                    WOLFSSL_ASN1_BIT_STRING* bit_str = *(WOLFSSL_ASN1_BIT_STRING**)
26932
                                                        (((byte*)val) + member->offset);
26933
                    if (bit_str) {
26934
                        wolfSSL_ASN1_BIT_STRING_free(bit_str);
26935
                    }
26936
                    break;
26937
                }
26938
                default:
26939
                    WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_free");
26940
            }
26941
        }
26942
        XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL);
26943
    }
26944
}
26945
26946
#define bufLenOrNull(buf, len) ((buf) ? (buf) + (len) : NULL)
26947
26948
static int i2dProcessMembers(const void *src, byte *buf,
26949
                          const WOLFSSL_ASN1_TEMPLATE *members, size_t mcount)
26950
{
26951
    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
26952
    int len = 0, ret;
26953
    size_t i;
26954
    WOLFSSL_ENTER("processMembers");
26955
    for (member = members, i = 0; i < mcount; member++, i++) {
26956
        switch (member->type) {
26957
            case WOLFSSL_X509_ALGOR_ASN1:
26958
            {
26959
                word32 oid = 0;
26960
                word32 idx = 0;
26961
                const WOLFSSL_X509_ALGOR* algor = *(const WOLFSSL_X509_ALGOR**)
26962
                                                   (((byte*)src) + member->offset);
26963
                if (!algor->algorithm) {
26964
                    WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
26965
                    return WOLFSSL_FAILURE;
26966
                }
26967
26968
                if (GetObjectId(algor->algorithm->obj, &idx, &oid,
26969
                        algor->algorithm->grp, algor->algorithm->objSz) < 0) {
26970
                    WOLFSSL_MSG("Issue getting OID of object");
26971
                    return -1;
26972
                }
26973
26974
                ret = SetAlgoID(oid, bufLenOrNull(buf, len),
26975
                                algor->algorithm->grp, 0);
26976
                if (!ret) {
26977
                    return WOLFSSL_FAILURE;
26978
                }
26979
                len += ret;
26980
                break;
26981
            }
26982
            case WOLFSSL_ASN1_BIT_STRING_ASN1:
26983
            {
26984
                const WOLFSSL_ASN1_BIT_STRING* bit_str;
26985
                bit_str = *(const WOLFSSL_ASN1_BIT_STRING**)
26986
                           (((byte*)src) + member->offset);
26987
                len += SetBitString(bit_str->length, 0, bufLenOrNull(buf, len));
26988
                if (buf && bit_str->data) {
26989
                    XMEMCPY(buf + len, bit_str->data, bit_str->length);
26990
                }
26991
                len += bit_str->length;
26992
                break;
26993
            }
26994
            default:
26995
                WOLFSSL_MSG("Type not support in processMembers");
26996
                WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
26997
                return WOLFSSL_FAILURE;
26998
        }
26999
    }
27000
    WOLFSSL_LEAVE("processMembers", len);
27001
    return len;
27002
}
27003
27004
static int wolfSSL_ASN1_item_i2d_1(const void *src, byte *buf,
27005
                                       const WOLFSSL_ASN1_ITEM *tpl, int *len)
27006
{
27007
    *len = 0;
27008
27009
    switch (tpl->type) {
27010
        case ASN_SEQUENCE:
27011
        {
27012
            int seq_len = i2dProcessMembers(src, NULL, tpl->members,
27013
                                         tpl->mcount);
27014
            if (seq_len == WOLFSSL_FAILURE)
27015
                return WOLFSSL_FAILURE;
27016
            *len += SetSequence(seq_len, bufLenOrNull(buf, *len));
27017
            if (buf) {
27018
                if (i2dProcessMembers(src, bufLenOrNull(buf, *len), tpl->members,
27019
                                      tpl->mcount) != seq_len) {
27020
                    WOLFSSL_MSG("Inconsistent sequence length");
27021
                    return WOLFSSL_FAILURE;
27022
                }
27023
            }
27024
            *len += seq_len;
27025
            break;
27026
        }
27027
        default:
27028
            WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_i2d");
27029
            return WOLFSSL_FAILURE;
27030
    }
27031
27032
    return WOLFSSL_SUCCESS;
27033
}
27034
27035
int wolfSSL_ASN1_item_i2d(const void *src, byte **dest,
27036
                          const WOLFSSL_ASN1_ITEM *tpl)
27037
{
27038
    int len;
27039
    byte *buf = NULL;
27040
27041
    WOLFSSL_ENTER("wolfSSL_ASN1_item_i2d");
27042
27043
    if ((src == NULL) || (tpl == NULL))
27044
        goto error;
27045
27046
    if (wolfSSL_ASN1_item_i2d_1(src, NULL, tpl, &len) != WOLFSSL_SUCCESS)
27047
        goto error;
27048
27049
    if (dest == NULL) {
27050
        WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_SUCCESS);
27051
        return len;
27052
    }
27053
27054
    if (*dest == NULL) {
27055
        buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
27056
        if (buf == NULL)
27057
            goto error;
27058
    } else
27059
        buf = *dest;
27060
27061
    if (wolfSSL_ASN1_item_i2d_1(src, buf, tpl, &len) != WOLFSSL_SUCCESS)
27062
        goto error;
27063
27064
    if (*dest == NULL)
27065
        *dest = buf;
27066
    else {
27067
        /* XXX *dest length is not checked because the user is responsible
27068
         * for providing a long enough buffer
27069
         */
27070
        XMEMCPY(*dest, buf, len);
27071
    }
27072
27073
    WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", len);
27074
    return len;
27075
error:
27076
    if (buf) {
27077
        XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
27078
    }
27079
    WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_FAILURE);
27080
    return WOLFSSL_FAILURE;
27081
}
27082
27083
#endif /* OPENSSL_ALL */
27084
27085
#endif /* OPENSSL_EXTRA */
27086
27087
#ifdef OPENSSL_EXTRA
27088
WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void)
27089
{
27090
    WOLFSSL_HMAC_CTX* hmac_ctx = (WOLFSSL_HMAC_CTX*)XMALLOC(
27091
        sizeof(WOLFSSL_HMAC_CTX), NULL, DYNAMIC_TYPE_OPENSSL);
27092
    if (hmac_ctx != NULL) {
27093
        XMEMSET(hmac_ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
27094
    }
27095
    return hmac_ctx;
27096
}
27097
27098
int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx)
27099
{
27100
    WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init");
27101
27102
    if (ctx != NULL) {
27103
        /* wc_HmacSetKey sets up ctx->hmac */
27104
        XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
27105
    }
27106
27107
    return WOLFSSL_SUCCESS;
27108
}
27109
27110
27111
int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key,
27112
                             int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e)
27113
{
27114
    WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex");
27115
27116
    /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */
27117
    (void)e;
27118
    return wolfSSL_HMAC_Init(ctx, key, keylen, type);
27119
}
27120
27121
27122
/* helper function for Deep copy of internal wolfSSL hmac structure
27123
 * returns WOLFSSL_SUCCESS on success */
27124
int wolfSSL_HmacCopy(Hmac* des, Hmac* src)
27125
{
27126
    void* heap;
27127
    int ret;
27128
27129
#ifndef HAVE_FIPS
27130
    heap = src->heap;
27131
#else
27132
    heap = NULL;
27133
#endif
27134
    if (wc_HmacInit(des, heap, 0) != 0) {
27135
        return WOLFSSL_FAILURE;
27136
    }
27137
27138
    /* requires that hash structures have no dynamic parts to them */
27139
    switch (src->macType) {
27140
    #ifndef NO_MD5
27141
        case WC_MD5:
27142
            ret = wc_Md5Copy(&src->hash.md5, &des->hash.md5);
27143
            break;
27144
    #endif /* !NO_MD5 */
27145
27146
    #ifndef NO_SHA
27147
        case WC_SHA:
27148
            ret = wc_ShaCopy(&src->hash.sha, &des->hash.sha);
27149
            break;
27150
    #endif /* !NO_SHA */
27151
27152
    #ifdef WOLFSSL_SHA224
27153
        case WC_SHA224:
27154
            ret = wc_Sha224Copy(&src->hash.sha224, &des->hash.sha224);
27155
            break;
27156
    #endif /* WOLFSSL_SHA224 */
27157
27158
    #ifndef NO_SHA256
27159
        case WC_SHA256:
27160
            ret = wc_Sha256Copy(&src->hash.sha256, &des->hash.sha256);
27161
            break;
27162
    #endif /* !NO_SHA256 */
27163
27164
    #ifdef WOLFSSL_SHA384
27165
        case WC_SHA384:
27166
            ret = wc_Sha384Copy(&src->hash.sha384, &des->hash.sha384);
27167
            break;
27168
    #endif /* WOLFSSL_SHA384 */
27169
    #ifdef WOLFSSL_SHA512
27170
        case WC_SHA512:
27171
            ret = wc_Sha512Copy(&src->hash.sha512, &des->hash.sha512);
27172
            break;
27173
    #endif /* WOLFSSL_SHA512 */
27174
#ifdef WOLFSSL_SHA3
27175
    #ifndef WOLFSSL_NOSHA3_224
27176
        case WC_SHA3_224:
27177
            ret = wc_Sha3_224_Copy(&src->hash.sha3, &des->hash.sha3);
27178
            break;
27179
    #endif /* WOLFSSL_NO_SHA3_224 */
27180
    #ifndef WOLFSSL_NOSHA3_256
27181
        case WC_SHA3_256:
27182
            ret = wc_Sha3_256_Copy(&src->hash.sha3, &des->hash.sha3);
27183
            break;
27184
    #endif /* WOLFSSL_NO_SHA3_256 */
27185
    #ifndef WOLFSSL_NOSHA3_384
27186
        case WC_SHA3_384:
27187
            ret = wc_Sha3_384_Copy(&src->hash.sha3, &des->hash.sha3);
27188
            break;
27189
    #endif /* WOLFSSL_NO_SHA3_384 */
27190
    #ifndef WOLFSSL_NOSHA3_512
27191
        case WC_SHA3_512:
27192
            ret = wc_Sha3_512_Copy(&src->hash.sha3, &des->hash.sha3);
27193
            break;
27194
    #endif /* WOLFSSL_NO_SHA3_512 */
27195
#endif /* WOLFSSL_SHA3 */
27196
27197
        default:
27198
            return WOLFSSL_FAILURE;
27199
    }
27200
27201
    if (ret != 0)
27202
        return WOLFSSL_FAILURE;
27203
27204
    XMEMCPY((byte*)des->ipad, (byte*)src->ipad, WC_HMAC_BLOCK_SIZE);
27205
    XMEMCPY((byte*)des->opad, (byte*)src->opad, WC_HMAC_BLOCK_SIZE);
27206
    XMEMCPY((byte*)des->innerHash, (byte*)src->innerHash, WC_MAX_DIGEST_SIZE);
27207
#ifndef HAVE_FIPS
27208
    des->heap    = heap;
27209
#endif
27210
    des->macType = src->macType;
27211
    des->innerHashKeyed = src->innerHashKeyed;
27212
27213
#ifdef WOLFSSL_ASYNC_CRYPT
27214
    XMEMCPY(&des->asyncDev, &src->asyncDev, sizeof(WC_ASYNC_DEV));
27215
    des->keyLen = src->keyLen;
27216
    #ifdef HAVE_CAVIUM
27217
        des->data = (byte*)XMALLOC(src->dataLen, des->heap,
27218
                DYNAMIC_TYPE_HMAC);
27219
        if (des->data == NULL) {
27220
            return BUFFER_E;
27221
        }
27222
        XMEMCPY(des->data, src->data, src->dataLen);
27223
        des->dataLen = src->dataLen;
27224
    #endif /* HAVE_CAVIUM */
27225
#endif /* WOLFSSL_ASYNC_CRYPT */
27226
        return WOLFSSL_SUCCESS;
27227
}
27228
27229
27230
/* Deep copy of information from src to des structure
27231
 *
27232
 * des destination to copy information to
27233
 * src structure to get information from
27234
 *
27235
 * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
27236
 */
27237
int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src)
27238
{
27239
    WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy");
27240
27241
    if (des == NULL || src == NULL) {
27242
        return WOLFSSL_FAILURE;
27243
    }
27244
27245
    des->type = src->type;
27246
    XMEMCPY((byte *)&des->save_ipad, (byte *)&src->hmac.ipad,
27247
                                        WC_HMAC_BLOCK_SIZE);
27248
    XMEMCPY((byte *)&des->save_opad, (byte *)&src->hmac.opad,
27249
                                        WC_HMAC_BLOCK_SIZE);
27250
27251
    return wolfSSL_HmacCopy(&des->hmac, &src->hmac);
27252
}
27253
27254
27255
#if defined(HAVE_FIPS) && \
27256
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
27257
27258
static int _HMAC_Init(Hmac* hmac, int type, void* heap)
27259
{
27260
    int ret = 0;
27261
27262
    switch (type) {
27263
    #ifndef NO_MD5
27264
        case WC_MD5:
27265
            ret = wc_InitMd5(&hmac->hash.md5);
27266
            break;
27267
    #endif /* !NO_MD5 */
27268
27269
    #ifndef NO_SHA
27270
        case WC_SHA:
27271
            ret = wc_InitSha(&hmac->hash.sha);
27272
            break;
27273
    #endif /* !NO_SHA */
27274
27275
    #ifdef WOLFSSL_SHA224
27276
        case WC_SHA224:
27277
            ret = wc_InitSha224(&hmac->hash.sha224);
27278
            break;
27279
    #endif /* WOLFSSL_SHA224 */
27280
27281
    #ifndef NO_SHA256
27282
        case WC_SHA256:
27283
            ret = wc_InitSha256(&hmac->hash.sha256);
27284
            break;
27285
    #endif /* !NO_SHA256 */
27286
27287
    #ifdef WOLFSSL_SHA384
27288
        case WC_SHA384:
27289
            ret = wc_InitSha384(&hmac->hash.sha384);
27290
            break;
27291
    #endif /* WOLFSSL_SHA384 */
27292
    #ifdef WOLFSSL_SHA512
27293
        case WC_SHA512:
27294
            ret = wc_InitSha512(&hmac->hash.sha512);
27295
            break;
27296
    #endif /* WOLFSSL_SHA512 */
27297
27298
    #ifdef WOLFSSL_SHA3
27299
        case WC_SHA3_224:
27300
            ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);
27301
            break;
27302
        case WC_SHA3_256:
27303
            ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);
27304
            break;
27305
        case WC_SHA3_384:
27306
            ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);
27307
            break;
27308
        case WC_SHA3_512:
27309
            ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);
27310
            break;
27311
    #endif
27312
27313
        default:
27314
            ret = BAD_FUNC_ARG;
27315
            break;
27316
    }
27317
27318
    (void)heap;
27319
27320
    return ret;
27321
}
27322
27323
#else
27324
    #define _HMAC_Init _InitHmac
27325
#endif
27326
27327
27328
int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
27329
                  const EVP_MD* type)
27330
{
27331
    int hmac_error = 0;
27332
    void* heap = NULL;
27333
    int inited;
27334
27335
    WOLFSSL_MSG("wolfSSL_HMAC_Init");
27336
27337
    if (ctx == NULL) {
27338
        WOLFSSL_MSG("no ctx on init");
27339
        return WOLFSSL_FAILURE;
27340
    }
27341
27342
#ifndef HAVE_FIPS
27343
    heap = ctx->hmac.heap;
27344
#endif
27345
27346
    if (type) {
27347
        WOLFSSL_MSG("init has type");
27348
27349
#ifndef NO_MD5
27350
        if (XSTRNCMP(type, "MD5", 3) == 0) {
27351
            WOLFSSL_MSG("md5 hmac");
27352
            ctx->type = WC_MD5;
27353
        }
27354
        else
27355
#endif
27356
#ifdef WOLFSSL_SHA224
27357
        if (XSTRNCMP(type, "SHA224", 6) == 0) {
27358
            WOLFSSL_MSG("sha224 hmac");
27359
            ctx->type = WC_SHA224;
27360
        }
27361
        else
27362
#endif
27363
#ifndef NO_SHA256
27364
        if (XSTRNCMP(type, "SHA256", 6) == 0) {
27365
            WOLFSSL_MSG("sha256 hmac");
27366
            ctx->type = WC_SHA256;
27367
        }
27368
        else
27369
#endif
27370
#ifdef WOLFSSL_SHA384
27371
        if (XSTRNCMP(type, "SHA384", 6) == 0) {
27372
            WOLFSSL_MSG("sha384 hmac");
27373
            ctx->type = WC_SHA384;
27374
        }
27375
        else
27376
#endif
27377
#ifdef WOLFSSL_SHA512
27378
        if (XSTRNCMP(type, "SHA512", 6) == 0) {
27379
            WOLFSSL_MSG("sha512 hmac");
27380
            ctx->type = WC_SHA512;
27381
        }
27382
        else
27383
#endif
27384
#ifdef WOLFSSL_SHA3
27385
    #ifndef WOLFSSL_NOSHA3_224
27386
        if (XSTRNCMP(type, "SHA3_224", 8) == 0) {
27387
            WOLFSSL_MSG("sha3_224 hmac");
27388
            ctx->type = WC_SHA3_224;
27389
        }
27390
        else
27391
    #endif
27392
    #ifndef WOLFSSL_NOSHA3_256
27393
        if (XSTRNCMP(type, "SHA3_256", 8) == 0) {
27394
            WOLFSSL_MSG("sha3_256 hmac");
27395
            ctx->type = WC_SHA3_256;
27396
        }
27397
        else
27398
    #endif
27399
        if (XSTRNCMP(type, "SHA3_384", 8) == 0) {
27400
            WOLFSSL_MSG("sha3_384 hmac");
27401
            ctx->type = WC_SHA3_384;
27402
        }
27403
        else
27404
    #ifndef WOLFSSL_NOSHA3_512
27405
        if (XSTRNCMP(type, "SHA3_512", 8) == 0) {
27406
            WOLFSSL_MSG("sha3_512 hmac");
27407
            ctx->type = WC_SHA3_512;
27408
        }
27409
        else
27410
    #endif
27411
#endif
27412
27413
#ifndef NO_SHA
27414
        /* has to be last since would pick or 256, 384, or 512 too */
27415
        if (XSTRNCMP(type, "SHA", 3) == 0) {
27416
            WOLFSSL_MSG("sha hmac");
27417
            ctx->type = WC_SHA;
27418
        }
27419
        else
27420
#endif
27421
        {
27422
            WOLFSSL_MSG("bad init type");
27423
            return WOLFSSL_FAILURE;
27424
        }
27425
    }
27426
27427
    /* Check if init has been called before */
27428
    inited = (ctx->hmac.macType != WC_HASH_TYPE_NONE);
27429
    /* Free if needed */
27430
    if (inited) {
27431
        wc_HmacFree(&ctx->hmac);
27432
    }
27433
    if (key != NULL) {
27434
        WOLFSSL_MSG("keying hmac");
27435
27436
        if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
27437
            hmac_error = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key,
27438
                                       (word32)keylen);
27439
            if (hmac_error < 0){
27440
                /* in FIPS mode a key < 14 characters will fail here */
27441
                WOLFSSL_MSG("hmac set key error");
27442
                WOLFSSL_ERROR(hmac_error);
27443
                wc_HmacFree(&ctx->hmac);
27444
                return WOLFSSL_FAILURE;
27445
            }
27446
            XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad,
27447
                                        WC_HMAC_BLOCK_SIZE);
27448
            XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad,
27449
                                        WC_HMAC_BLOCK_SIZE);
27450
        }
27451
        /* OpenSSL compat, no error */
27452
    }
27453
    else if (!inited) {
27454
        return WOLFSSL_FAILURE;
27455
    }
27456
    else if (ctx->type >= 0) { /* MD5 == 0 */
27457
        WOLFSSL_MSG("recover hmac");
27458
        if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
27459
            ctx->hmac.macType = (byte)ctx->type;
27460
            ctx->hmac.innerHashKeyed = 0;
27461
            XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad,
27462
                                       WC_HMAC_BLOCK_SIZE);
27463
            XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad,
27464
                                       WC_HMAC_BLOCK_SIZE);
27465
            if ((hmac_error = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap))
27466
                    !=0) {
27467
                WOLFSSL_MSG("hmac init error");
27468
                WOLFSSL_ERROR(hmac_error);
27469
                return WOLFSSL_FAILURE;
27470
            }
27471
        }
27472
    }
27473
27474
    (void)hmac_error;
27475
27476
    return WOLFSSL_SUCCESS;
27477
}
27478
27479
27480
int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
27481
                    int len)
27482
{
27483
    int hmac_error = 0;
27484
27485
    WOLFSSL_MSG("wolfSSL_HMAC_Update");
27486
27487
    if (ctx == NULL) {
27488
        WOLFSSL_MSG("no ctx");
27489
        return WOLFSSL_FAILURE;
27490
    }
27491
27492
    if (data) {
27493
        WOLFSSL_MSG("updating hmac");
27494
        hmac_error = wc_HmacUpdate(&ctx->hmac, data, (word32)len);
27495
        if (hmac_error < 0){
27496
            WOLFSSL_MSG("hmac update error");
27497
            return WOLFSSL_FAILURE;
27498
        }
27499
    }
27500
27501
    return WOLFSSL_SUCCESS;
27502
}
27503
27504
27505
int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
27506
                   unsigned int* len)
27507
{
27508
    int hmac_error;
27509
27510
    WOLFSSL_MSG("wolfSSL_HMAC_Final");
27511
27512
    /* "len" parameter is optional. */
27513
    if (ctx == NULL || hash == NULL) {
27514
        WOLFSSL_MSG("invalid parameter");
27515
        return WOLFSSL_FAILURE;
27516
    }
27517
27518
    WOLFSSL_MSG("final hmac");
27519
    hmac_error = wc_HmacFinal(&ctx->hmac, hash);
27520
    if (hmac_error < 0){
27521
        WOLFSSL_MSG("final hmac error");
27522
        return WOLFSSL_FAILURE;
27523
    }
27524
27525
    if (len) {
27526
        WOLFSSL_MSG("setting output len");
27527
        switch (ctx->type) {
27528
            #ifndef NO_MD5
27529
            case WC_MD5:
27530
                *len = WC_MD5_DIGEST_SIZE;
27531
                break;
27532
            #endif
27533
27534
            #ifndef NO_SHA
27535
            case WC_SHA:
27536
                *len = WC_SHA_DIGEST_SIZE;
27537
                break;
27538
            #endif
27539
27540
            #ifdef WOLFSSL_SHA224
27541
            case WC_SHA224:
27542
                *len = WC_SHA224_DIGEST_SIZE;
27543
                break;
27544
            #endif
27545
27546
            #ifndef NO_SHA256
27547
            case WC_SHA256:
27548
                *len = WC_SHA256_DIGEST_SIZE;
27549
                break;
27550
            #endif
27551
27552
            #ifdef WOLFSSL_SHA384
27553
            case WC_SHA384:
27554
                *len = WC_SHA384_DIGEST_SIZE;
27555
                break;
27556
            #endif
27557
27558
            #ifdef WOLFSSL_SHA512
27559
            case WC_SHA512:
27560
                *len = WC_SHA512_DIGEST_SIZE;
27561
                break;
27562
            #endif
27563
27564
        #ifdef WOLFSSL_SHA3
27565
            #ifndef WOLFSSL_NOSHA3_224
27566
            case WC_SHA3_224:
27567
                *len = WC_SHA3_224_DIGEST_SIZE;
27568
                break;
27569
            #endif
27570
            #ifndef WOLFSSL_NOSHA3_256
27571
            case WC_SHA3_256:
27572
                *len = WC_SHA3_256_DIGEST_SIZE;
27573
                break;
27574
            #endif
27575
            #ifndef WOLFSSL_NOSHA3_384
27576
            case WC_SHA3_384:
27577
                *len = WC_SHA3_384_DIGEST_SIZE;
27578
                break;
27579
            #endif
27580
            #ifndef WOLFSSL_NOSHA3_512
27581
            case WC_SHA3_512:
27582
                *len = WC_SHA3_512_DIGEST_SIZE;
27583
                break;
27584
            #endif
27585
        #endif
27586
27587
            default:
27588
                WOLFSSL_MSG("bad hmac type");
27589
                return WOLFSSL_FAILURE;
27590
        }
27591
    }
27592
27593
    return WOLFSSL_SUCCESS;
27594
}
27595
27596
27597
int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
27598
{
27599
    WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
27600
27601
    if (ctx) {
27602
        wc_HmacFree(&ctx->hmac);
27603
    }
27604
27605
    return WOLFSSL_SUCCESS;
27606
}
27607
27608
void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx)
27609
{
27610
    if (ctx) {
27611
        wolfSSL_HMAC_cleanup(ctx);
27612
    }
27613
}
27614
27615
void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx)
27616
{
27617
    if (ctx) {
27618
        wolfSSL_HMAC_CTX_cleanup(ctx);
27619
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27620
    }
27621
}
27622
27623
size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx)
27624
{
27625
    if (!ctx) {
27626
        return 0;
27627
    }
27628
27629
    return (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType);
27630
}
27631
27632
const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx)
27633
{
27634
    if (!ctx) {
27635
        return NULL;
27636
    }
27637
27638
    return wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type);
27639
}
27640
27641
#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \
27642
    defined(WOLFSSL_AES_DIRECT)
27643
WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void)
27644
{
27645
    WOLFSSL_CMAC_CTX* ctx = NULL;
27646
27647
    ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL,
27648
                                     DYNAMIC_TYPE_OPENSSL);
27649
    if (ctx != NULL) {
27650
        ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC);
27651
        if (ctx->internal == NULL) {
27652
            XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27653
            ctx = NULL;
27654
        }
27655
    }
27656
    if (ctx != NULL) {
27657
        ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new();
27658
        if (ctx->cctx == NULL) {
27659
            XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
27660
            XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27661
            ctx = NULL;
27662
        }
27663
    }
27664
27665
    return ctx;
27666
}
27667
27668
void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx)
27669
{
27670
    if (ctx != NULL) {
27671
        if (ctx->internal != NULL) {
27672
            XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
27673
        }
27674
        if (ctx->cctx != NULL) {
27675
            wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx);
27676
        }
27677
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27678
    }
27679
}
27680
27681
WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX* ctx)
27682
{
27683
    WOLFSSL_EVP_CIPHER_CTX* cctx = NULL;
27684
27685
    if (ctx != NULL) {
27686
        cctx = ctx->cctx;
27687
    }
27688
27689
    return cctx;
27690
}
27691
27692
int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keyLen,
27693
                      const WOLFSSL_EVP_CIPHER* cipher, WOLFSSL_ENGINE* engine)
27694
{
27695
    int ret = WOLFSSL_SUCCESS;
27696
27697
    (void)engine;
27698
27699
    WOLFSSL_ENTER("wolfSSL_CMAC_Init");
27700
27701
    if (ctx == NULL || cipher == NULL || (
27702
            cipher != EVP_AES_128_CBC &&
27703
            cipher != EVP_AES_192_CBC &&
27704
            cipher != EVP_AES_256_CBC)) {
27705
        ret = WOLFSSL_FAILURE;
27706
    }
27707
27708
    if (ret == WOLFSSL_SUCCESS) {
27709
        ret = wc_InitCmac((Cmac*)ctx->internal, (const byte*)key,
27710
                          (word32)keyLen, WC_CMAC_AES, NULL);
27711
        if (ret != 0) {
27712
            ret = WOLFSSL_FAILURE;
27713
        }
27714
        else {
27715
            ret = WOLFSSL_SUCCESS;
27716
        }
27717
    }
27718
    if (ret == WOLFSSL_SUCCESS) {
27719
        ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL,
27720
                                     1);
27721
    }
27722
27723
    WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret);
27724
27725
    return ret;
27726
}
27727
27728
int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len)
27729
{
27730
    int ret = WOLFSSL_SUCCESS;
27731
27732
    WOLFSSL_ENTER("wolfSSL_CMAC_Update");
27733
27734
    if (ctx == NULL || ctx->internal == NULL) {
27735
        ret = WOLFSSL_FAILURE;
27736
    }
27737
27738
    if (ret == WOLFSSL_SUCCESS) {
27739
        if (data) {
27740
            ret = wc_CmacUpdate((Cmac*)ctx->internal, (const byte*)data,
27741
                                (word32)len);
27742
            if (ret != 0){
27743
                ret = WOLFSSL_FAILURE;
27744
            }
27745
            else {
27746
                ret = WOLFSSL_SUCCESS;
27747
            }
27748
        }
27749
    }
27750
27751
    WOLFSSL_LEAVE("wolfSSL_CMAC_Update", ret);
27752
27753
    return ret;
27754
}
27755
27756
int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out,
27757
                       size_t* len)
27758
{
27759
    int ret = WOLFSSL_SUCCESS;
27760
    int blockSize;
27761
27762
    WOLFSSL_ENTER("wolfSSL_CMAC_Final");
27763
27764
    if (ctx == NULL || ctx->cctx == NULL || ctx->internal == NULL ||
27765
                                                                  len == NULL) {
27766
        ret = WOLFSSL_FAILURE;
27767
    }
27768
27769
    if (ret == WOLFSSL_SUCCESS) {
27770
        blockSize = EVP_CIPHER_CTX_block_size(ctx->cctx);
27771
        if (blockSize <= 0) {
27772
            ret = WOLFSSL_FAILURE;
27773
        }
27774
        else {
27775
            *len = blockSize;
27776
        }
27777
    }
27778
    if (ret == WOLFSSL_SUCCESS) {
27779
        word32 len32 = (word32)*len;
27780
27781
        ret = wc_CmacFinal((Cmac*)ctx->internal, out, &len32);
27782
        *len = (size_t)len32;
27783
        if (ret != 0) {
27784
            ret = WOLFSSL_FAILURE;
27785
        }
27786
        else {
27787
            ret = WOLFSSL_SUCCESS;
27788
        }
27789
    }
27790
27791
    WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret);
27792
27793
    return ret;
27794
}
27795
#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */
27796
#endif /* OPENSSL_EXTRA */
27797
27798
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
27799
/* Free the dynamically allocated data.
27800
 *
27801
 * p  Pointer to dynamically allocated memory.
27802
 */
27803
void wolfSSL_OPENSSL_free(void* p)
27804
{
27805
    WOLFSSL_MSG("wolfSSL_OPENSSL_free");
27806
27807
    XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
27808
}
27809
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
27810
27811
#ifdef OPENSSL_EXTRA
27812
27813
void *wolfSSL_OPENSSL_malloc(size_t a)
27814
{
27815
    return (void *)XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
27816
}
27817
27818
int wolfSSL_OPENSSL_hexchar2int(unsigned char c)
27819
{
27820
    /* 'char' is unsigned on some platforms. */
27821
    return (int)(signed char)HexCharToByte((char)c);
27822
}
27823
27824
unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len)
27825
{
27826
    unsigned char* targetBuf;
27827
    int srcDigitHigh = 0;
27828
    int srcDigitLow = 0;
27829
    size_t srcLen;
27830
    size_t srcIdx = 0;
27831
    long targetIdx = 0;
27832
27833
    srcLen = XSTRLEN(str);
27834
    targetBuf = (unsigned char*)XMALLOC(srcLen / 2, NULL, DYNAMIC_TYPE_OPENSSL);
27835
    if (targetBuf == NULL) {
27836
        return NULL;
27837
    }
27838
27839
    while (srcIdx < srcLen) {
27840
        if (str[srcIdx] == ':') {
27841
            srcIdx++;
27842
            continue;
27843
        }
27844
27845
        srcDigitHigh = wolfSSL_OPENSSL_hexchar2int(str[srcIdx++]);
27846
        srcDigitLow = wolfSSL_OPENSSL_hexchar2int(str[srcIdx++]);
27847
        if (srcDigitHigh < 0 || srcDigitLow < 0) {
27848
            WOLFSSL_MSG("Invalid hex character.");
27849
            XFREE(targetBuf, NULL, DYNAMIC_TYPE_OPENSSL);
27850
            return NULL;
27851
        }
27852
27853
        targetBuf[targetIdx++] = (unsigned char)((srcDigitHigh << 4) | srcDigitLow);
27854
    }
27855
27856
    if (len != NULL)
27857
        *len = targetIdx;
27858
27859
    return targetBuf;
27860
}
27861
27862
int wolfSSL_OPENSSL_init_ssl(word64 opts, const OPENSSL_INIT_SETTINGS *settings)
27863
{
27864
    (void)opts;
27865
    (void)settings;
27866
    return wolfSSL_library_init();
27867
}
27868
27869
int wolfSSL_OPENSSL_init_crypto(word64 opts, const OPENSSL_INIT_SETTINGS* settings)
27870
{
27871
    (void)opts;
27872
    (void)settings;
27873
    return wolfSSL_library_init();
27874
}
27875
27876
#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER)
27877
27878
int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
27879
                  unsigned char* passwd, int passwdSz, byte **cipherInfo,
27880
                  int maxDerSz)
27881
{
27882
    int ret, paddingSz;
27883
    word32 idx, cipherInfoSz;
27884
#ifdef WOLFSSL_SMALL_STACK
27885
    EncryptedInfo* info = NULL;
27886
#else
27887
    EncryptedInfo  info[1];
27888
#endif
27889
27890
    WOLFSSL_ENTER("EncryptDerKey");
27891
27892
    if (der == NULL || derSz == NULL || cipher == NULL ||
27893
        passwd == NULL || cipherInfo == NULL)
27894
        return BAD_FUNC_ARG;
27895
27896
#ifdef WOLFSSL_SMALL_STACK
27897
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
27898
                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
27899
    if (info == NULL) {
27900
        WOLFSSL_MSG("malloc failed");
27901
        return WOLFSSL_FAILURE;
27902
    }
27903
#endif
27904
27905
    XMEMSET(info, 0, sizeof(EncryptedInfo));
27906
27907
    /* set the cipher name on info */
27908
    XSTRNCPY(info->name, cipher, NAME_SZ-1);
27909
    info->name[NAME_SZ-1] = '\0'; /* null term */
27910
27911
    ret = wc_EncryptedInfoGet(info, info->name);
27912
    if (ret != 0) {
27913
        WOLFSSL_MSG("unsupported cipher");
27914
    #ifdef WOLFSSL_SMALL_STACK
27915
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27916
    #endif
27917
        return WOLFSSL_FAILURE;
27918
    }
27919
27920
    /* Generate a random salt */
27921
    if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != WOLFSSL_SUCCESS) {
27922
        WOLFSSL_MSG("generate iv failed");
27923
#ifdef WOLFSSL_SMALL_STACK
27924
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27925
#endif
27926
        return WOLFSSL_FAILURE;
27927
    }
27928
27929
    /* add the padding before encryption */
27930
    paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
27931
    if (paddingSz == 0)
27932
        paddingSz = info->ivSz;
27933
    if (maxDerSz < *derSz + paddingSz) {
27934
        WOLFSSL_MSG("not enough DER buffer allocated");
27935
#ifdef WOLFSSL_SMALL_STACK
27936
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27937
#endif
27938
        return WOLFSSL_FAILURE;
27939
    }
27940
    XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
27941
    (*derSz) += paddingSz;
27942
27943
    /* encrypt buffer */
27944
    if (wc_BufferKeyEncrypt(info, der, *derSz, passwd, passwdSz, WC_MD5) != 0) {
27945
        WOLFSSL_MSG("encrypt key failed");
27946
#ifdef WOLFSSL_SMALL_STACK
27947
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27948
#endif
27949
        return WOLFSSL_FAILURE;
27950
    }
27951
27952
    /* create cipher info : 'cipher_name,Salt(hex)' */
27953
    cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
27954
    *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
27955
                                DYNAMIC_TYPE_STRING);
27956
    if (*cipherInfo == NULL) {
27957
        WOLFSSL_MSG("malloc failed");
27958
#ifdef WOLFSSL_SMALL_STACK
27959
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27960
#endif
27961
        return WOLFSSL_FAILURE;
27962
    }
27963
    XSTRLCPY((char*)*cipherInfo, info->name, cipherInfoSz);
27964
    XSTRLCAT((char*)*cipherInfo, ",", cipherInfoSz);
27965
27966
    idx = (word32)XSTRLEN((char*)*cipherInfo);
27967
    cipherInfoSz -= idx;
27968
    ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
27969
27970
#ifdef WOLFSSL_SMALL_STACK
27971
    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27972
#endif
27973
    if (ret != 0) {
27974
        WOLFSSL_MSG("Base16_Encode failed");
27975
        XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27976
        return WOLFSSL_FAILURE;
27977
    }
27978
27979
    return WOLFSSL_SUCCESS;
27980
}
27981
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
27982
27983
#ifndef NO_BIO
27984
static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
27985
{
27986
    int ret;
27987
    int pemSz;
27988
    byte* pemBuf;
27989
    int derSz = 0;
27990
    byte* derBuf = NULL;
27991
27992
    if (bio == NULL || key == NULL) {
27993
        WOLFSSL_MSG("Bad parameters");
27994
        return WOLFSSL_FAILURE;
27995
    }
27996
27997
    switch (key->type) {
27998
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
27999
        case EVP_PKEY_RSA:
28000
            if ((derSz = wolfSSL_RSA_To_Der(key->rsa, &derBuf, 1, bio->heap))
28001
                    < 0) {
28002
                WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
28003
                break;
28004
            }
28005
            break;
28006
#endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
28007
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
28008
        defined(WOLFSSL_CERT_GEN))
28009
        case EVP_PKEY_DSA:
28010
            if (key->dsa == NULL) {
28011
                WOLFSSL_MSG("key->dsa is null");
28012
                break;
28013
            }
28014
            derSz = MAX_DSA_PUBKEY_SZ;
28015
            derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
28016
            if (derBuf == NULL) {
28017
                WOLFSSL_MSG("malloc failed");
28018
                break;
28019
            }
28020
            /* Key to DER */
28021
            derSz = wc_DsaKeyToPublicDer((DsaKey*)key->dsa->internal, derBuf,
28022
                    derSz);
28023
            if (derSz < 0) {
28024
                WOLFSSL_MSG("wc_DsaKeyToDer failed");
28025
                break;
28026
            }
28027
            break;
28028
#endif /* !NO_DSA && !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
28029
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
28030
        case EVP_PKEY_EC:
28031
        {
28032
            if (key->ecc == NULL) {
28033
                WOLFSSL_MSG("key->ecc is null");
28034
                break;
28035
            }
28036
            derSz = wc_EccPublicKeyDerSize((ecc_key*)key->ecc->internal, 1);
28037
            if (derSz <= 0) {
28038
                WOLFSSL_MSG("wc_EccPublicKeyDerSize failed");
28039
                break;
28040
            }
28041
            derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
28042
            if (derBuf == NULL) {
28043
                WOLFSSL_MSG("malloc failed");
28044
                break;
28045
            }
28046
            derSz = wc_EccPublicKeyToDer((ecc_key*)key->ecc->internal, derBuf,
28047
                    derSz, 1);
28048
            if (derSz < 0) {
28049
                WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
28050
                break;
28051
            }
28052
            break;
28053
        }
28054
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
28055
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
28056
        case EVP_PKEY_DH:
28057
            WOLFSSL_MSG("Writing DH PUBKEY not supported!");
28058
            break;
28059
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
28060
        default:
28061
            WOLFSSL_MSG("Unknown Key type!");
28062
            break;
28063
    }
28064
28065
    if (derBuf == NULL || derSz <= 0) {
28066
        if (derBuf != NULL)
28067
            XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
28068
        return WOLFSSL_FAILURE;
28069
    }
28070
28071
    pemSz = wc_DerToPem(derBuf, derSz, NULL, 0, PUBLICKEY_TYPE);
28072
    if (pemSz < 0) {
28073
        WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz);
28074
        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
28075
        return WOLFSSL_FAILURE;
28076
    }
28077
28078
    pemBuf = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
28079
    if (pemBuf == NULL) {
28080
        WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz);
28081
        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
28082
        return WOLFSSL_FAILURE;
28083
    }
28084
28085
    ret = wc_DerToPem(derBuf, derSz, pemBuf, pemSz, PUBLICKEY_TYPE);
28086
    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
28087
    if (ret < 0) {
28088
        WOLFSSL_LEAVE("pem_write_bio_pubkey", ret);
28089
        XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
28090
        return WOLFSSL_FAILURE;
28091
    }
28092
28093
    ret = wolfSSL_BIO_write(bio, pemBuf, pemSz);
28094
    XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
28095
    if (ret != pemSz) {
28096
        WOLFSSL_MSG("Unable to write full PEM to BIO");
28097
        return WOLFSSL_FAILURE;
28098
    }
28099
28100
    return WOLFSSL_SUCCESS;
28101
}
28102
28103
/* Takes a public key and writes it out to a WOLFSSL_BIO
28104
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
28105
 */
28106
int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
28107
{
28108
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
28109
28110
    return pem_write_bio_pubkey(bio, key);
28111
}
28112
28113
/* Takes a private key and writes it out to a WOLFSSL_BIO
28114
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
28115
 */
28116
int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
28117
                                     const WOLFSSL_EVP_CIPHER* cipher,
28118
                                     unsigned char* passwd, int len,
28119
                                     wc_pem_password_cb* cb, void* arg)
28120
{
28121
    byte* keyDer;
28122
    int pemSz;
28123
    int type;
28124
    int ret;
28125
    byte* tmp;
28126
28127
    (void)cipher;
28128
    (void)passwd;
28129
    (void)len;
28130
    (void)cb;
28131
    (void)arg;
28132
28133
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
28134
28135
    if (bio == NULL || key == NULL) {
28136
        WOLFSSL_MSG("Bad Function Arguments");
28137
        return WOLFSSL_FAILURE;
28138
    }
28139
28140
    keyDer = (byte*)key->pkey.ptr;
28141
28142
    switch (key->type) {
28143
#ifndef NO_RSA
28144
        case EVP_PKEY_RSA:
28145
            type = PRIVATEKEY_TYPE;
28146
            break;
28147
#endif
28148
28149
#ifndef NO_DSA
28150
        case EVP_PKEY_DSA:
28151
            type = DSA_PRIVATEKEY_TYPE;
28152
            break;
28153
#endif
28154
28155
#ifdef HAVE_ECC
28156
        case EVP_PKEY_EC:
28157
            type = ECC_PRIVATEKEY_TYPE;
28158
            break;
28159
#endif
28160
28161
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
28162
        case EVP_PKEY_DH:
28163
            type = DH_PRIVATEKEY_TYPE;
28164
            break;
28165
#endif
28166
28167
        default:
28168
            WOLFSSL_MSG("Unknown Key type!");
28169
            type = PRIVATEKEY_TYPE;
28170
    }
28171
28172
    pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type);
28173
    if (pemSz < 0) {
28174
        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz);
28175
        return WOLFSSL_FAILURE;
28176
    }
28177
    tmp = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
28178
    if (tmp == NULL) {
28179
        return MEMORY_E;
28180
    }
28181
28182
    ret = wc_DerToPem(keyDer, key->pkey_sz, tmp, pemSz, type);
28183
    if (ret < 0) {
28184
        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret);
28185
        XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
28186
        return WOLFSSL_FAILURE;
28187
    }
28188
28189
    ret = wolfSSL_BIO_write(bio, tmp, pemSz);
28190
    XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
28191
    if (ret != pemSz) {
28192
        WOLFSSL_MSG("Unable to write full PEM to BIO");
28193
        return WOLFSSL_FAILURE;
28194
    }
28195
28196
    return WOLFSSL_SUCCESS;
28197
}
28198
#endif /* !NO_BIO */
28199
28200
/* Colon separated list of <public key>+<digest> algorithms.
28201
 * Replaces list in context.
28202
 */
28203
int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list)
28204
{
28205
    WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list");
28206
28207
    if (ctx == NULL || list == NULL) {
28208
        WOLFSSL_MSG("Bad function arguments");
28209
        return WOLFSSL_FAILURE;
28210
    }
28211
28212
    /* alloc/init on demand only */
28213
    if (ctx->suites == NULL) {
28214
        ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
28215
                                       DYNAMIC_TYPE_SUITES);
28216
        if (ctx->suites == NULL) {
28217
            WOLFSSL_MSG("Memory alloc for Suites failed");
28218
            return WOLFSSL_FAILURE;
28219
        }
28220
        XMEMSET(ctx->suites, 0, sizeof(Suites));
28221
    }
28222
28223
    return SetSuitesHashSigAlgo(ctx->suites, list);
28224
}
28225
28226
/* Colon separated list of <public key>+<digest> algorithms.
28227
 * Replaces list in SSL.
28228
 */
28229
int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list)
28230
{
28231
    WOLFSSL_MSG("wolfSSL_set1_sigalg_list");
28232
28233
    if (ssl == NULL) {
28234
        WOLFSSL_MSG("Bad function arguments");
28235
        return WOLFSSL_FAILURE;
28236
    }
28237
28238
#ifdef SINGLE_THREADED
28239
    if (ssl->ctx->suites == ssl->suites) {
28240
        ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
28241
                                       DYNAMIC_TYPE_SUITES);
28242
        if (ssl->suites == NULL) {
28243
            WOLFSSL_MSG("Suites Memory error");
28244
            return MEMORY_E;
28245
        }
28246
        *ssl->suites = *ssl->ctx->suites;
28247
        ssl->options.ownSuites = 1;
28248
    }
28249
#endif
28250
    if (ssl == NULL || list == NULL) {
28251
        WOLFSSL_MSG("Bad function arguments");
28252
        return WOLFSSL_FAILURE;
28253
    }
28254
28255
    return SetSuitesHashSigAlgo(ssl->suites, list);
28256
}
28257
28258
struct WOLFSSL_HashSigInfo {
28259
    int hashAlgo;
28260
    int sigAlgo;
28261
    int nid;
28262
}  wolfssl_hash_sig_info[] =
28263
{
28264
#ifndef NO_RSA
28265
    #ifndef NO_SHA256
28266
        { sha256_mac, rsa_sa_algo, CTC_SHA256wRSA },
28267
    #endif
28268
    #ifdef WOLFSSL_SHA384
28269
        { sha384_mac, rsa_sa_algo, CTC_SHA384wRSA },
28270
    #endif
28271
    #ifdef WOLFSSL_SHA512
28272
        { sha512_mac, rsa_sa_algo, CTC_SHA512wRSA },
28273
    #endif
28274
    #ifdef WOLFSSL_SHA224
28275
        { sha224_mac, rsa_sa_algo, CTC_SHA224wRSA },
28276
    #endif
28277
    #ifndef NO_SHA
28278
        { sha_mac,    rsa_sa_algo, CTC_SHAwRSA },
28279
    #endif
28280
    #ifdef WC_RSA_PSS
28281
        #ifndef NO_SHA256
28282
            { sha256_mac, rsa_pss_sa_algo, CTC_SHA256wRSA },
28283
        #endif
28284
        #ifdef WOLFSSL_SHA384
28285
            { sha384_mac, rsa_pss_sa_algo, CTC_SHA384wRSA },
28286
        #endif
28287
        #ifdef WOLFSSL_SHA512
28288
            { sha512_mac, rsa_pss_sa_algo, CTC_SHA512wRSA },
28289
        #endif
28290
        #ifdef WOLFSSL_SHA224
28291
            { sha224_mac, rsa_pss_sa_algo, CTC_SHA224wRSA },
28292
        #endif
28293
    #endif
28294
#endif
28295
#ifdef HAVE_ECC
28296
    #ifndef NO_SHA256
28297
        { sha256_mac, ecc_dsa_sa_algo, CTC_SHA256wECDSA },
28298
    #endif
28299
    #ifdef WOLFSSL_SHA384
28300
        { sha384_mac, ecc_dsa_sa_algo, CTC_SHA384wECDSA },
28301
    #endif
28302
    #ifdef WOLFSSL_SHA512
28303
        { sha512_mac, ecc_dsa_sa_algo, CTC_SHA512wECDSA },
28304
    #endif
28305
    #ifdef WOLFSSL_SHA224
28306
        { sha224_mac, ecc_dsa_sa_algo, CTC_SHA224wECDSA },
28307
    #endif
28308
    #ifndef NO_SHA
28309
        { sha_mac,    ecc_dsa_sa_algo, CTC_SHAwECDSA },
28310
    #endif
28311
#endif
28312
#ifdef HAVE_ED25519
28313
    { no_mac, ed25519_sa_algo, CTC_ED25519 },
28314
#endif
28315
#ifdef HAVE_ED448
28316
    { no_mac, ed448_sa_algo, CTC_ED448 },
28317
#endif
28318
#ifdef HAVE_PQC
28319
#ifdef HAVE_FALCON
28320
    { no_mac, falcon_level1_sa_algo, CTC_FALCON_LEVEL1 },
28321
    { no_mac, falcon_level5_sa_algo, CTC_FALCON_LEVEL5 },
28322
#endif /* HAVE_FALCON */
28323
#ifdef HAVE_DILITHIUM
28324
    { no_mac, dilithium_level2_sa_algo, CTC_DILITHIUM_LEVEL2 },
28325
    { no_mac, dilithium_level3_sa_algo, CTC_DILITHIUM_LEVEL3 },
28326
    { no_mac, dilithium_level5_sa_algo, CTC_DILITHIUM_LEVEL5 },
28327
    { no_mac, dilithium_aes_level2_sa_algo, CTC_DILITHIUM_AES_LEVEL2 },
28328
    { no_mac, dilithium_aes_level3_sa_algo, CTC_DILITHIUM_AES_LEVEL3 },
28329
    { no_mac, dilithium_aes_level5_sa_algo, CTC_DILITHIUM_AES_LEVEL5 },
28330
#endif /* HAVE_DILITHIUM */
28331
#endif /* HAVE_PQC */
28332
#ifndef NO_DSA
28333
    #ifndef NO_SHA
28334
        { sha_mac,    dsa_sa_algo, CTC_SHAwDSA },
28335
    #endif
28336
#endif
28337
};
28338
#define WOLFSSL_HASH_SIG_INFO_SZ \
28339
    (int)(sizeof(wolfssl_hash_sig_info)/sizeof(*wolfssl_hash_sig_info))
28340
28341
int wolfSSL_get_signature_nid(WOLFSSL *ssl, int* nid)
28342
{
28343
    int i;
28344
    int ret = WOLFSSL_FAILURE;
28345
28346
    WOLFSSL_MSG("wolfSSL_get_signature_nid");
28347
28348
    if (ssl == NULL) {
28349
        WOLFSSL_MSG("Bad function arguments");
28350
        return WOLFSSL_FAILURE;
28351
    }
28352
28353
    for (i = 0; i < WOLFSSL_HASH_SIG_INFO_SZ; i++) {
28354
        if (ssl->suites->hashAlgo == wolfssl_hash_sig_info[i].hashAlgo &&
28355
                     ssl->suites->sigAlgo == wolfssl_hash_sig_info[i].sigAlgo) {
28356
            *nid = wolfssl_hash_sig_info[i].nid;
28357
            ret = WOLFSSL_SUCCESS;
28358
            break;
28359
        }
28360
    }
28361
28362
    return ret;
28363
}
28364
28365
#ifdef HAVE_ECC
28366
28367
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
28368
static int populate_groups(int* groups, int max_count, char *list)
28369
{
28370
    char *end;
28371
    int len;
28372
    int count = 0;
28373
    const WOLF_EC_NIST_NAME* nist_name;
28374
28375
    if (!groups || !list) {
28376
        return -1;
28377
    }
28378
28379
    for (end = list; ; list = ++end) {
28380
        if (count > max_count) {
28381
            WOLFSSL_MSG("Too many curves in list");
28382
            return -1;
28383
        }
28384
        while (*end != ':' && *end != '\0') end++;
28385
        len = (int)(end - list); /* end points to char after end
28386
                                  * of curve name so no need for -1 */
28387
        if ((len < kNistCurves_MIN_NAME_LEN) ||
28388
                (len > kNistCurves_MAX_NAME_LEN)) {
28389
            WOLFSSL_MSG("Unrecognized curve name in list");
28390
            return -1;
28391
        }
28392
        for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
28393
            if (len == nist_name->name_len &&
28394
                    XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) {
28395
                break;
28396
            }
28397
        }
28398
        if (!nist_name->name) {
28399
            WOLFSSL_MSG("Unrecognized curve name in list");
28400
            return -1;
28401
        }
28402
        groups[count++] = nist_name->nid;
28403
        if (*end == '\0') break;
28404
    }
28405
28406
    return count;
28407
}
28408
28409
int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list)
28410
{
28411
    int groups[WOLFSSL_MAX_GROUP_COUNT];
28412
    int count;
28413
28414
    if (!ctx || !list) {
28415
        return WOLFSSL_FAILURE;
28416
    }
28417
28418
    if ((count = populate_groups(groups,
28419
            WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
28420
        return WOLFSSL_FAILURE;
28421
    }
28422
28423
    return wolfSSL_CTX_set1_groups(ctx, groups, count);
28424
}
28425
28426
int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list)
28427
{
28428
    int groups[WOLFSSL_MAX_GROUP_COUNT];
28429
    int count;
28430
28431
    if (!ssl || !list) {
28432
        return WOLFSSL_FAILURE;
28433
    }
28434
28435
    if ((count = populate_groups(groups,
28436
            WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
28437
        return WOLFSSL_FAILURE;
28438
    }
28439
28440
    return wolfSSL_set1_groups(ssl, groups, count);
28441
}
28442
#endif /* WOLFSSL_TLS13 */
28443
28444
#endif /* HAVE_ECC */
28445
28446
#ifndef NO_BIO
28447
/* Number of bytes to read from a file at a time. */
28448
#define PEM_READ_FILE_CHUNK_SZ  100
28449
28450
static int pem_read_bio_file(WOLFSSL_BIO* bio, char** pem)
28451
{
28452
    int ret   = 0;
28453
    int idx   = 0;
28454
    int sz    = PEM_READ_FILE_CHUNK_SZ; /* read from file by chunks */
28455
    int memSz = 0;
28456
    char* mem = NULL;
28457
    char* tmp;
28458
28459
    /* Allocate a chunk to read into. */
28460
    tmp = (char*)XMALLOC(sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
28461
    if (tmp == NULL) {
28462
        WOLFSSL_MSG("Memory error");
28463
        ret = MEMORY_E;
28464
    }
28465
28466
    while (ret == 0 && (sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) {
28467
        char* newMem;
28468
28469
        /* sanity check for signed overflow */
28470
        if (memSz + sz < 0) {
28471
            break;
28472
        }
28473
28474
        /* Reallocate to make space for read data. */
28475
        newMem = (char*)XREALLOC(mem, memSz + sz, bio->heap,
28476
                DYNAMIC_TYPE_OPENSSL);
28477
        if (newMem == NULL) {
28478
            WOLFSSL_MSG("Memory error");
28479
            ret = MEMORY_E;
28480
            break;
28481
        }
28482
        mem = newMem;
28483
28484
        /* Copy in new data. */
28485
        XMEMCPY(mem + idx, tmp, sz);
28486
        memSz += sz;
28487
        idx   += sz;
28488
        sz = PEM_READ_FILE_CHUNK_SZ; /* read another chunk from file */
28489
    }
28490
28491
    XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
28492
    tmp = NULL;
28493
28494
    if (ret == 0) {
28495
        /* Check data was read. */
28496
        if (memSz <= 0) {
28497
            WOLFSSL_MSG("No data to read from bio");
28498
            ret = BUFFER_E;
28499
        }
28500
        else {
28501
            /* Return size of data read. */
28502
            ret = memSz;
28503
        }
28504
    }
28505
    /* Dispose of any allocated memory on error. */
28506
    if (ret < 0) {
28507
        XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
28508
        mem = NULL;
28509
    }
28510
28511
    *pem = mem;
28512
    return ret;
28513
}
28514
28515
static int pem_read_bio_pending(WOLFSSL_BIO* bio, int pendingSz, char** pem)
28516
{
28517
    int ret = 0;
28518
    char* mem;
28519
28520
    /* Allocate buffer to hold pending data. */
28521
    mem = (char*)XMALLOC(pendingSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
28522
    if (mem == NULL) {
28523
        WOLFSSL_MSG("Memory error");
28524
        ret = MEMORY_E;
28525
    }
28526
    else if ((ret = wolfSSL_BIO_read(bio, mem, pendingSz)) <= 0) {
28527
        /* Pending data not read. */
28528
        XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
28529
        mem = NULL;
28530
        ret = MEMORY_E;
28531
    }
28532
28533
    *pem = mem;
28534
    return ret;
28535
}
28536
28537
static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
28538
                            void* pass, int keyType, int* eccFlag,
28539
                            DerBuffer** der)
28540
{
28541
#ifdef WOLFSSL_SMALL_STACK
28542
    EncryptedInfo* info = NULL;
28543
#else
28544
    EncryptedInfo info[1];
28545
#endif /* WOLFSSL_SMALL_STACK */
28546
    wc_pem_password_cb* localCb = NULL;
28547
    char* mem = NULL;
28548
    int ret;
28549
28550
    if (cb != NULL) {
28551
        localCb = cb;
28552
    }
28553
    else if (pass != NULL) {
28554
        localCb = wolfSSL_PEM_def_callback;
28555
    }
28556
28557
    if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
28558
        ret = pem_read_bio_pending(bio, ret, &mem);
28559
    }
28560
    else if (bio->type == WOLFSSL_BIO_FILE) {
28561
        ret = pem_read_bio_file(bio, &mem);
28562
    }
28563
    else {
28564
        WOLFSSL_MSG("No data to read from bio");
28565
        ret = NOT_COMPILED_IN;
28566
    }
28567
28568
#ifdef WOLFSSL_SMALL_STACK
28569
    if (ret >= 0) {
28570
        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
28571
                                       DYNAMIC_TYPE_TMP_BUFFER);
28572
        if (info == NULL) {
28573
            WOLFSSL_MSG("Error getting memory for EncryptedInfo structure");
28574
            XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
28575
            mem = NULL;
28576
            ret = MEMORY_E;
28577
        }
28578
    }
28579
#endif /* WOLFSSL_SMALL_STACK */
28580
28581
    if (ret >= 0) {
28582
        int memSz = ret;
28583
28584
        XMEMSET(info, 0, sizeof(EncryptedInfo));
28585
        info->passwd_cb       = localCb;
28586
        info->passwd_userdata = pass;
28587
28588
        /* Do not strip PKCS8 header */
28589
        ret = PemToDer((const unsigned char*)mem, memSz, keyType, der, NULL,
28590
            info, eccFlag);
28591
        if (ret < 0) {
28592
            WOLFSSL_MSG("Bad PEM To DER");
28593
        }
28594
        /* Write left over data back to BIO if not a file BIO */
28595
        else if ((memSz - (int)info->consumed) > 0 &&
28596
                 bio->type != WOLFSSL_BIO_FILE) {
28597
            if (wolfSSL_BIO_write(bio, mem + (int)info->consumed,
28598
                                  memSz - (int)info->consumed) <= 0) {
28599
                WOLFSSL_MSG("Unable to advance bio read pointer");
28600
            }
28601
        }
28602
    }
28603
28604
#ifdef WOLFSSL_SMALL_STACK
28605
    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28606
#endif
28607
    XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
28608
28609
    return ret;
28610
}
28611
28612
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
28613
                                                  WOLFSSL_EVP_PKEY** key,
28614
                                                  wc_pem_password_cb* cb,
28615
                                                  void* pass)
28616
{
28617
    WOLFSSL_EVP_PKEY* pkey = NULL;
28618
    DerBuffer*         der = NULL;
28619
    int             keyFormat = 0;
28620
    int                 type = -1;
28621
28622
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
28623
28624
    if (bio == NULL)
28625
        return pkey;
28626
28627
    if (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE, &keyFormat,
28628
                                                                   &der) >= 0) {
28629
        const unsigned char* ptr = der->buffer;
28630
28631
        if (keyFormat) {
28632
            /* keyFormat is Key_Sum enum */
28633
            if (keyFormat == RSAk)
28634
                type = EVP_PKEY_RSA;
28635
            else if (keyFormat == ECDSAk)
28636
                type = EVP_PKEY_EC;
28637
            else if (keyFormat == DSAk)
28638
                type = EVP_PKEY_DSA;
28639
            else if (keyFormat == DHk)
28640
                type = EVP_PKEY_DH;
28641
        }
28642
        else {
28643
            /* Default to RSA if format is not set */
28644
            type = EVP_PKEY_RSA;
28645
        }
28646
28647
        /* handle case where reuse is attempted */
28648
        if (key != NULL && *key != NULL)
28649
            pkey = *key;
28650
28651
        wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length);
28652
        if (pkey == NULL) {
28653
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
28654
        }
28655
    }
28656
28657
    FreeDer(&der);
28658
28659
    if (key != NULL && pkey != NULL)
28660
        *key = pkey;
28661
28662
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", 0);
28663
28664
    return pkey;
28665
}
28666
28667
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
28668
                                              WOLFSSL_EVP_PKEY **key,
28669
                                              wc_pem_password_cb *cb,
28670
                                              void *pass)
28671
{
28672
    WOLFSSL_EVP_PKEY* pkey = NULL;
28673
    DerBuffer*        der = NULL;
28674
    int               keyFormat = 0;
28675
28676
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
28677
28678
    if (bio == NULL)
28679
        return pkey;
28680
28681
    if (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE, &keyFormat, &der) >= 0) {
28682
        const unsigned char* ptr = der->buffer;
28683
28684
        /* handle case where reuse is attempted */
28685
        if (key != NULL && *key != NULL)
28686
            pkey = *key;
28687
28688
        wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length);
28689
        if (pkey == NULL) {
28690
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
28691
        }
28692
    }
28693
28694
    FreeDer(&der);
28695
28696
    if (key != NULL && pkey != NULL)
28697
        *key = pkey;
28698
28699
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
28700
28701
    return pkey;
28702
}
28703
28704
#if !defined(NO_FILESYSTEM)
28705
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **x,
28706
                                          wc_pem_password_cb *cb, void *u)
28707
{
28708
    int err = 0;
28709
    WOLFSSL_EVP_PKEY* ret = NULL;
28710
    WOLFSSL_BIO* bio = NULL;
28711
28712
    WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
28713
28714
    if (fp == XBADFILE) {
28715
        err = 1;
28716
    }
28717
    if (err == 0) {
28718
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
28719
        err = bio == NULL;
28720
    }
28721
    if (err == 0) {
28722
        err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS;
28723
    }
28724
    if (err == 0) {
28725
        ret = wolfSSL_PEM_read_bio_PUBKEY(bio, x, cb, u);
28726
    }
28727
28728
    if (bio != NULL) {
28729
        wolfSSL_BIO_free(bio);
28730
    }
28731
28732
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
28733
28734
    return ret;
28735
}
28736
#endif /* NO_FILESYSTEM */
28737
#endif /* !NO_BIO */
28738
#endif /* OPENSSL_EXTRA */
28739
28740
#ifdef WOLFSSL_ALT_CERT_CHAINS
28741
int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
28742
{
28743
    int isUsing = 0;
28744
    if (ssl)
28745
        isUsing = ssl->options.usingAltCertChain;
28746
    return isUsing;
28747
}
28748
#endif /* WOLFSSL_ALT_CERT_CHAINS */
28749
28750
28751
#ifdef SESSION_CERTS
28752
28753
#ifdef WOLFSSL_ALT_CERT_CHAINS
28754
/* Get peer's alternate certificate chain */
28755
WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
28756
{
28757
    WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
28758
    if (ssl)
28759
        return &ssl->session->altChain;
28760
28761
    return 0;
28762
}
28763
#endif /* WOLFSSL_ALT_CERT_CHAINS */
28764
28765
28766
/* Get peer's certificate chain */
28767
WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
28768
{
28769
    WOLFSSL_ENTER("wolfSSL_get_peer_chain");
28770
    if (ssl)
28771
        return &ssl->session->chain;
28772
28773
    return 0;
28774
}
28775
28776
28777
/* Get peer's certificate chain total count */
28778
int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
28779
{
28780
    WOLFSSL_ENTER("wolfSSL_get_chain_count");
28781
    if (chain)
28782
        return chain->count;
28783
28784
    return 0;
28785
}
28786
28787
28788
/* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
28789
int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
28790
{
28791
    WOLFSSL_ENTER("wolfSSL_get_chain_length");
28792
    if (chain)
28793
        return chain->certs[idx].length;
28794
28795
    return 0;
28796
}
28797
28798
28799
/* Get peer's ASN.1 DER certificate at index (idx) */
28800
byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
28801
{
28802
    WOLFSSL_ENTER("wolfSSL_get_chain_cert");
28803
    if (chain)
28804
        return chain->certs[idx].buffer;
28805
28806
    return 0;
28807
}
28808
28809
28810
/* Get peer's wolfSSL X509 certificate at index (idx) */
28811
WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
28812
{
28813
    int          ret;
28814
    WOLFSSL_X509* x509 = NULL;
28815
#ifdef WOLFSSL_SMALL_STACK
28816
    DecodedCert* cert = NULL;
28817
#else
28818
    DecodedCert  cert[1];
28819
#endif
28820
28821
    WOLFSSL_ENTER("wolfSSL_get_chain_X509");
28822
    if (chain != NULL) {
28823
    #ifdef WOLFSSL_SMALL_STACK
28824
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
28825
                                                       DYNAMIC_TYPE_DCERT);
28826
        if (cert != NULL)
28827
    #endif
28828
        {
28829
            InitDecodedCert(cert, chain->certs[idx].buffer,
28830
                                  chain->certs[idx].length, NULL);
28831
28832
            if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0) {
28833
                WOLFSSL_MSG("Failed to parse cert");
28834
            }
28835
            else {
28836
                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
28837
                                                             DYNAMIC_TYPE_X509);
28838
                if (x509 == NULL) {
28839
                    WOLFSSL_MSG("Failed alloc X509");
28840
                }
28841
                else {
28842
                    InitX509(x509, 1, NULL);
28843
28844
                    if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
28845
                        WOLFSSL_MSG("Failed to copy decoded");
28846
                        wolfSSL_X509_free(x509);
28847
                        x509 = NULL;
28848
                    }
28849
                }
28850
            }
28851
28852
            FreeDecodedCert(cert);
28853
        #ifdef WOLFSSL_SMALL_STACK
28854
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
28855
        #endif
28856
        }
28857
    }
28858
    (void)ret;
28859
28860
    return x509;
28861
}
28862
28863
28864
/* Get peer's PEM certificate at index (idx), output to buffer if inLen big
28865
   enough else return error (-1). If buffer is NULL only calculate
28866
   outLen. Output length is in *outLen WOLFSSL_SUCCESS on ok */
28867
int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
28868
                               unsigned char* buf, int inLen, int* outLen)
28869
{
28870
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
28871
    const char* header = NULL;
28872
    const char* footer = NULL;
28873
    int headerLen;
28874
    int footerLen;
28875
    int i;
28876
    int err;
28877
    word32 szNeeded = 0;
28878
28879
    WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
28880
    if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
28881
        return BAD_FUNC_ARG;
28882
28883
    err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer);
28884
    if (err != 0)
28885
        return err;
28886
28887
    headerLen = (int)XSTRLEN(header);
28888
    footerLen = (int)XSTRLEN(footer);
28889
28890
    /* Null output buffer return size needed in outLen */
28891
    if(!buf) {
28892
        if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
28893
                    NULL, &szNeeded) != LENGTH_ONLY_E)
28894
            return WOLFSSL_FAILURE;
28895
        *outLen = szNeeded + headerLen + footerLen;
28896
        return LENGTH_ONLY_E;
28897
    }
28898
28899
    /* don't even try if inLen too short */
28900
    if (inLen < headerLen + footerLen + chain->certs[idx].length)
28901
        return BAD_FUNC_ARG;
28902
28903
    /* header */
28904
    if (XMEMCPY(buf, header, headerLen) == NULL)
28905
        return WOLFSSL_FATAL_ERROR;
28906
28907
    i = headerLen;
28908
28909
    /* body */
28910
    *outLen = inLen;  /* input to Base64_Encode */
28911
    if ( (err = Base64_Encode(chain->certs[idx].buffer,
28912
                       chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
28913
        return err;
28914
    i += *outLen;
28915
28916
    /* footer */
28917
    if ( (i + footerLen) > inLen)
28918
        return BAD_FUNC_ARG;
28919
    if (XMEMCPY(buf + i, footer, footerLen) == NULL)
28920
        return WOLFSSL_FATAL_ERROR;
28921
    *outLen += headerLen + footerLen;
28922
28923
    return WOLFSSL_SUCCESS;
28924
#else
28925
    (void)chain;
28926
    (void)idx;
28927
    (void)buf;
28928
    (void)inLen;
28929
    (void)outLen;
28930
    return WOLFSSL_FAILURE;
28931
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
28932
}
28933
28934
28935
/* get session ID */
28936
WOLFSSL_ABI
28937
const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
28938
{
28939
    WOLFSSL_ENTER("wolfSSL_get_sessionID");
28940
    session = ClientSessionToSession(session);
28941
    if (session)
28942
        return session->sessionID;
28943
28944
    return NULL;
28945
}
28946
28947
28948
#endif /* SESSION_CERTS */
28949
28950
#ifdef HAVE_FUZZER
28951
void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
28952
{
28953
    if (ssl) {
28954
        ssl->fuzzerCb  = cbf;
28955
        ssl->fuzzerCtx = fCtx;
28956
    }
28957
}
28958
#endif
28959
28960
#ifndef NO_CERTS
28961
#ifdef  HAVE_PK_CALLBACKS
28962
28963
#ifdef HAVE_ECC
28964
void  wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX* ctx, CallbackEccKeyGen cb)
28965
{
28966
    if (ctx)
28967
        ctx->EccKeyGenCb = cb;
28968
}
28969
void  wolfSSL_SetEccKeyGenCtx(WOLFSSL* ssl, void *ctx)
28970
{
28971
    if (ssl)
28972
        ssl->EccKeyGenCtx = ctx;
28973
}
28974
void* wolfSSL_GetEccKeyGenCtx(WOLFSSL* ssl)
28975
{
28976
    if (ssl)
28977
        return ssl->EccKeyGenCtx;
28978
28979
    return NULL;
28980
}
28981
void  wolfSSL_CTX_SetEccSignCtx(WOLFSSL_CTX* ctx, void *userCtx)
28982
{
28983
    if (ctx)
28984
        ctx->EccSignCtx = userCtx;
28985
}
28986
void* wolfSSL_CTX_GetEccSignCtx(WOLFSSL_CTX* ctx)
28987
{
28988
    if (ctx)
28989
        return ctx->EccSignCtx;
28990
28991
    return NULL;
28992
}
28993
28994
WOLFSSL_ABI
28995
void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
28996
{
28997
    if (ctx)
28998
        ctx->EccSignCb = cb;
28999
}
29000
void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
29001
{
29002
    if (ssl)
29003
        ssl->EccSignCtx = ctx;
29004
}
29005
void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
29006
{
29007
    if (ssl)
29008
        return ssl->EccSignCtx;
29009
29010
    return NULL;
29011
}
29012
29013
void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
29014
{
29015
    if (ctx)
29016
        ctx->EccVerifyCb = cb;
29017
}
29018
void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
29019
{
29020
    if (ssl)
29021
        ssl->EccVerifyCtx = ctx;
29022
}
29023
void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
29024
{
29025
    if (ssl)
29026
        return ssl->EccVerifyCtx;
29027
29028
    return NULL;
29029
}
29030
29031
void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb)
29032
{
29033
    if (ctx)
29034
        ctx->EccSharedSecretCb = cb;
29035
}
29036
void  wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
29037
{
29038
    if (ssl)
29039
        ssl->EccSharedSecretCtx = ctx;
29040
}
29041
void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
29042
{
29043
    if (ssl)
29044
        return ssl->EccSharedSecretCtx;
29045
29046
    return NULL;
29047
}
29048
#endif /* HAVE_ECC */
29049
29050
#ifdef HAVE_ED25519
29051
void  wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX* ctx, CallbackEd25519Sign cb)
29052
{
29053
    if (ctx)
29054
        ctx->Ed25519SignCb = cb;
29055
}
29056
void  wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx)
29057
{
29058
    if (ssl)
29059
        ssl->Ed25519SignCtx = ctx;
29060
}
29061
void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl)
29062
{
29063
    if (ssl)
29064
        return ssl->Ed25519SignCtx;
29065
29066
    return NULL;
29067
}
29068
29069
void  wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX* ctx, CallbackEd25519Verify cb)
29070
{
29071
    if (ctx)
29072
        ctx->Ed25519VerifyCb = cb;
29073
}
29074
void  wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx)
29075
{
29076
    if (ssl)
29077
        ssl->Ed25519VerifyCtx = ctx;
29078
}
29079
void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl)
29080
{
29081
    if (ssl)
29082
        return ssl->Ed25519VerifyCtx;
29083
29084
    return NULL;
29085
}
29086
#endif /* HAVE_ED25519 */
29087
29088
#ifdef HAVE_CURVE25519
29089
void wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX* ctx,
29090
        CallbackX25519KeyGen cb)
29091
{
29092
    if (ctx)
29093
        ctx->X25519KeyGenCb = cb;
29094
}
29095
void  wolfSSL_SetX25519KeyGenCtx(WOLFSSL* ssl, void *ctx)
29096
{
29097
    if (ssl)
29098
        ssl->X25519KeyGenCtx = ctx;
29099
}
29100
void* wolfSSL_GetX25519KeyGenCtx(WOLFSSL* ssl)
29101
{
29102
    if (ssl)
29103
        return ssl->X25519KeyGenCtx;
29104
29105
    return NULL;
29106
}
29107
29108
void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX* ctx,
29109
        CallbackX25519SharedSecret cb)
29110
{
29111
    if (ctx)
29112
        ctx->X25519SharedSecretCb = cb;
29113
}
29114
void  wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx)
29115
{
29116
    if (ssl)
29117
        ssl->X25519SharedSecretCtx = ctx;
29118
}
29119
void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
29120
{
29121
    if (ssl)
29122
        return ssl->X25519SharedSecretCtx;
29123
29124
    return NULL;
29125
}
29126
#endif /* HAVE_CURVE25519 */
29127
29128
#ifdef HAVE_ED448
29129
void  wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX* ctx, CallbackEd448Sign cb)
29130
{
29131
    if (ctx)
29132
        ctx->Ed448SignCb = cb;
29133
}
29134
void  wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx)
29135
{
29136
    if (ssl)
29137
        ssl->Ed448SignCtx = ctx;
29138
}
29139
void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl)
29140
{
29141
    if (ssl)
29142
        return ssl->Ed448SignCtx;
29143
29144
    return NULL;
29145
}
29146
29147
void  wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX* ctx, CallbackEd448Verify cb)
29148
{
29149
    if (ctx)
29150
        ctx->Ed448VerifyCb = cb;
29151
}
29152
void  wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx)
29153
{
29154
    if (ssl)
29155
        ssl->Ed448VerifyCtx = ctx;
29156
}
29157
void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl)
29158
{
29159
    if (ssl)
29160
        return ssl->Ed448VerifyCtx;
29161
29162
    return NULL;
29163
}
29164
#endif /* HAVE_ED448 */
29165
29166
#ifdef HAVE_CURVE448
29167
void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX* ctx,
29168
        CallbackX448KeyGen cb)
29169
{
29170
    if (ctx)
29171
        ctx->X448KeyGenCb = cb;
29172
}
29173
void  wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx)
29174
{
29175
    if (ssl)
29176
        ssl->X448KeyGenCtx = ctx;
29177
}
29178
void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl)
29179
{
29180
    if (ssl)
29181
        return ssl->X448KeyGenCtx;
29182
29183
    return NULL;
29184
}
29185
29186
void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX* ctx,
29187
        CallbackX448SharedSecret cb)
29188
{
29189
    if (ctx)
29190
        ctx->X448SharedSecretCb = cb;
29191
}
29192
void  wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx)
29193
{
29194
    if (ssl)
29195
        ssl->X448SharedSecretCtx = ctx;
29196
}
29197
void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl)
29198
{
29199
    if (ssl)
29200
        return ssl->X448SharedSecretCtx;
29201
29202
    return NULL;
29203
}
29204
#endif /* HAVE_CURVE448 */
29205
29206
#ifndef NO_RSA
29207
void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
29208
{
29209
    if (ctx)
29210
        ctx->RsaSignCb = cb;
29211
}
29212
void  wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
29213
{
29214
    if (ctx)
29215
        ctx->RsaSignCheckCb = cb;
29216
}
29217
void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
29218
{
29219
    if (ssl)
29220
        ssl->RsaSignCtx = ctx;
29221
}
29222
void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
29223
{
29224
    if (ssl)
29225
        return ssl->RsaSignCtx;
29226
29227
    return NULL;
29228
}
29229
29230
29231
void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
29232
{
29233
    if (ctx)
29234
        ctx->RsaVerifyCb = cb;
29235
}
29236
void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
29237
{
29238
    if (ssl)
29239
        ssl->RsaVerifyCtx = ctx;
29240
}
29241
void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
29242
{
29243
    if (ssl)
29244
        return ssl->RsaVerifyCtx;
29245
29246
    return NULL;
29247
}
29248
29249
#ifdef WC_RSA_PSS
29250
void  wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX* ctx, CallbackRsaPssSign cb)
29251
{
29252
    if (ctx)
29253
        ctx->RsaPssSignCb = cb;
29254
}
29255
void  wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
29256
{
29257
    if (ctx)
29258
        ctx->RsaPssSignCheckCb = cb;
29259
}
29260
void  wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx)
29261
{
29262
    if (ssl)
29263
        ssl->RsaPssSignCtx = ctx;
29264
}
29265
void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl)
29266
{
29267
    if (ssl)
29268
        return ssl->RsaPssSignCtx;
29269
29270
    return NULL;
29271
}
29272
29273
void  wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
29274
{
29275
    if (ctx)
29276
        ctx->RsaPssVerifyCb = cb;
29277
}
29278
void  wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx)
29279
{
29280
    if (ssl)
29281
        ssl->RsaPssVerifyCtx = ctx;
29282
}
29283
void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl)
29284
{
29285
    if (ssl)
29286
        return ssl->RsaPssVerifyCtx;
29287
29288
    return NULL;
29289
}
29290
#endif /* WC_RSA_PSS */
29291
29292
void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
29293
{
29294
    if (ctx)
29295
        ctx->RsaEncCb = cb;
29296
}
29297
void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
29298
{
29299
    if (ssl)
29300
        ssl->RsaEncCtx = ctx;
29301
}
29302
void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
29303
{
29304
    if (ssl)
29305
        return ssl->RsaEncCtx;
29306
29307
    return NULL;
29308
}
29309
29310
void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
29311
{
29312
    if (ctx)
29313
        ctx->RsaDecCb = cb;
29314
}
29315
void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
29316
{
29317
    if (ssl)
29318
        ssl->RsaDecCtx = ctx;
29319
}
29320
void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
29321
{
29322
    if (ssl)
29323
        return ssl->RsaDecCtx;
29324
29325
    return NULL;
29326
}
29327
#endif /* NO_RSA */
29328
29329
/* callback for premaster secret generation */
29330
void  wolfSSL_CTX_SetGenPreMasterCb(WOLFSSL_CTX* ctx, CallbackGenPreMaster cb)
29331
{
29332
    if (ctx)
29333
        ctx->GenPreMasterCb = cb;
29334
}
29335
/* Set premaster secret generation callback context */
29336
void  wolfSSL_SetGenPreMasterCtx(WOLFSSL* ssl, void *ctx)
29337
{
29338
    if (ssl)
29339
        ssl->GenPreMasterCtx = ctx;
29340
}
29341
/* Get premaster secret generation callback context */
29342
void* wolfSSL_GetGenPreMasterCtx(WOLFSSL* ssl)
29343
{
29344
    if (ssl)
29345
        return ssl->GenPreMasterCtx;
29346
29347
    return NULL;
29348
}
29349
29350
/* callback for master secret generation */
29351
void  wolfSSL_CTX_SetGenMasterSecretCb(WOLFSSL_CTX* ctx, CallbackGenMasterSecret cb)
29352
{
29353
    if (ctx)
29354
        ctx->GenMasterCb = cb;
29355
}
29356
/* Set master secret generation callback context */
29357
void  wolfSSL_SetGenMasterSecretCtx(WOLFSSL* ssl, void *ctx)
29358
{
29359
    if (ssl)
29360
        ssl->GenMasterCtx = ctx;
29361
}
29362
/* Get master secret generation callback context */
29363
void* wolfSSL_GetGenMasterSecretCtx(WOLFSSL* ssl)
29364
{
29365
    if (ssl)
29366
        return ssl->GenMasterCtx;
29367
29368
    return NULL;
29369
}
29370
29371
/* callback for session key generation */
29372
void  wolfSSL_CTX_SetGenSessionKeyCb(WOLFSSL_CTX* ctx, CallbackGenSessionKey cb)
29373
{
29374
    if (ctx)
29375
        ctx->GenSessionKeyCb = cb;
29376
}
29377
/* Set session key generation callback context */
29378
void  wolfSSL_SetGenSessionKeyCtx(WOLFSSL* ssl, void *ctx)
29379
{
29380
    if (ssl)
29381
        ssl->GenSessionKeyCtx = ctx;
29382
}
29383
/* Get session key generation callback context */
29384
void* wolfSSL_GetGenSessionKeyCtx(WOLFSSL* ssl)
29385
{
29386
    if (ssl)
29387
        return ssl->GenSessionKeyCtx;
29388
29389
    return NULL;
29390
}
29391
29392
/* callback for setting encryption keys */
29393
void  wolfSSL_CTX_SetEncryptKeysCb(WOLFSSL_CTX* ctx, CallbackEncryptKeys cb)
29394
{
29395
    if (ctx)
29396
        ctx->EncryptKeysCb = cb;
29397
}
29398
/* Set encryption keys callback context */
29399
void  wolfSSL_SetEncryptKeysCtx(WOLFSSL* ssl, void *ctx)
29400
{
29401
    if (ssl)
29402
        ssl->EncryptKeysCtx = ctx;
29403
}
29404
/* Get encryption keys callback context */
29405
void* wolfSSL_GetEncryptKeysCtx(WOLFSSL* ssl)
29406
{
29407
    if (ssl)
29408
        return ssl->EncryptKeysCtx;
29409
29410
    return NULL;
29411
}
29412
29413
/* callback for Tls finished */
29414
/* the callback can be used to build TLS Finished message if enabled */
29415
void  wolfSSL_CTX_SetTlsFinishedCb(WOLFSSL_CTX* ctx, CallbackTlsFinished cb)
29416
{
29417
    if (ctx)
29418
        ctx->TlsFinishedCb = cb;
29419
}
29420
/* Set Tls finished callback context */
29421
void  wolfSSL_SetTlsFinishedCtx(WOLFSSL* ssl, void *ctx)
29422
{
29423
    if (ssl)
29424
        ssl->TlsFinishedCtx = ctx;
29425
}
29426
/* Get Tls finished callback context */
29427
void* wolfSSL_GetTlsFinishedCtx(WOLFSSL* ssl)
29428
{
29429
    if (ssl)
29430
        return ssl->TlsFinishedCtx;
29431
29432
    return NULL;
29433
}
29434
#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
29435
/* callback for verify data */
29436
void  wolfSSL_CTX_SetVerifyMacCb(WOLFSSL_CTX* ctx, CallbackVerifyMac cb)
29437
{
29438
    if (ctx)
29439
        ctx->VerifyMacCb = cb;
29440
}
29441
29442
/* Set set keys callback context */
29443
void  wolfSSL_SetVerifyMacCtx(WOLFSSL* ssl, void *ctx)
29444
{
29445
    if (ssl)
29446
        ssl->VerifyMacCtx = ctx;
29447
}
29448
/* Get set  keys callback context */
29449
void* wolfSSL_GetVerifyMacCtx(WOLFSSL* ssl)
29450
{
29451
    if (ssl)
29452
        return ssl->VerifyMacCtx;
29453
29454
    return NULL;
29455
}
29456
#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
29457
29458
#endif /* HAVE_PK_CALLBACKS */
29459
#endif /* NO_CERTS */
29460
29461
#if defined(HAVE_PK_CALLBACKS) && !defined(NO_DH)
29462
void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb)
29463
{
29464
    if (ctx)
29465
        ctx->DhAgreeCb = cb;
29466
}
29467
void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx)
29468
{
29469
    if (ssl)
29470
        ssl->DhAgreeCtx = ctx;
29471
}
29472
void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
29473
{
29474
    if (ssl)
29475
        return ssl->DhAgreeCtx;
29476
29477
    return NULL;
29478
}
29479
#endif /* HAVE_PK_CALLBACKS && !NO_DH */
29480
29481
#if defined(HAVE_PK_CALLBACKS) && defined(HAVE_HKDF)
29482
29483
void wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX* ctx, CallbackHKDFExtract cb)
29484
{
29485
    if (ctx)
29486
        ctx->HkdfExtractCb = cb;
29487
}
29488
29489
void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx)
29490
{
29491
    if (ssl)
29492
        ssl->HkdfExtractCtx = ctx;
29493
}
29494
29495
void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl)
29496
{
29497
    if (ssl)
29498
        return ssl->HkdfExtractCtx;
29499
29500
    return NULL;
29501
}
29502
#endif /* HAVE_PK_CALLBACKS && HAVE_HKDF */
29503
29504
#ifdef WOLFSSL_HAVE_WOLFSCEP
29505
    /* Used by autoconf to see if wolfSCEP is available */
29506
    void wolfSSL_wolfSCEP(void) {}
29507
#endif
29508
29509
29510
#ifdef WOLFSSL_HAVE_CERT_SERVICE
29511
    /* Used by autoconf to see if cert service is available */
29512
    void wolfSSL_cert_service(void) {}
29513
#endif
29514
29515
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
29516
    !defined(WOLFCRYPT_ONLY)
29517
#ifndef NO_CERTS
29518
29519
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
29520
/* Convert ASN1 input string into canonical ASN1 string                     */
29521
/*  , which has the following rules:                                        */
29522
/*   convert to UTF8                                                        */
29523
/*   convert to lower case                                                  */
29524
/*   multi-spaces collapsed                                                 */
29525
/* @param  asn_out a pointer to ASN1_STRING to be converted                 */
29526
/* @param  asn_in  a pointer to input ASN1_STRING                           */
29527
/* @return WOLFSSL_SUCCESS on successful converted, otherwise <=0 error code*/
29528
int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out,
29529
                              const WOLFSSL_ASN1_STRING* asn_in)
29530
{
29531
    char* dst;
29532
    char* src;
29533
    int i, len;
29534
29535
    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_canon");
29536
29537
    /* sanity check */
29538
    if (asn_out == NULL || asn_in == NULL) {
29539
        WOLFSSL_MSG("invalid function arguments");
29540
        return BAD_FUNC_ARG;
29541
    }
29542
29543
    switch (asn_in->type) {
29544
        case MBSTRING_UTF8:
29545
        case V_ASN1_PRINTABLESTRING:
29546
             break;
29547
        default:
29548
           WOLFSSL_MSG("just copy string");
29549
           return wolfSSL_ASN1_STRING_copy(asn_out, asn_in);
29550
    }
29551
    /* type is set as UTF8 */
29552
    asn_out->type = MBSTRING_UTF8;
29553
    asn_out->length = wolfSSL_ASN1_STRING_to_UTF8(
29554
        (unsigned char**)&asn_out->data, (WOLFSSL_ASN1_STRING*)asn_in);
29555
29556
    if (asn_out->length < 0) {
29557
        return WOLFSSL_FAILURE;
29558
    }
29559
    /* point to the last */
29560
    dst = asn_out->data + asn_out->length;
29561
    /* point to the start */
29562
    src = asn_out->data;
29563
29564
    len = asn_out->length;
29565
29566
    /* trimming spaces at the head and tail */
29567
    dst--;
29568
    for (; (len > 0 && XISSPACE(*dst)); len--) {
29569
        dst--;
29570
    }
29571
    for (; (len > 0 && XISSPACE(*src)); len--) {
29572
        src++;
29573
    }
29574
29575
    /* point to the start */
29576
    dst = asn_out->data;
29577
29578
    for (i = 0; i < len; dst++, i++) {
29579
        if (!XISASCII(*src)) {
29580
            /* keep non-ascii code */
29581
            *dst = *src++;
29582
        } else if (XISSPACE(*src)) {
29583
            *dst = 0x20; /* space */
29584
            /* remove the rest of spaces */
29585
            while (XISSPACE(*++src) && i++ < len);
29586
        } else {
29587
            *dst = (char)XTOLOWER((unsigned char)*src++);
29588
        }
29589
    }
29590
    /* put actual length */
29591
    asn_out->length = (int)(dst - asn_out->data);
29592
    return WOLFSSL_SUCCESS;
29593
}
29594
29595
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
29596
#if !defined(NO_FILESYSTEM)
29597
#ifndef NO_BIO
29598
    WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp,
29599
        WOLFSSL_EVP_PKEY **x, wc_pem_password_cb *cb, void *u)
29600
    {
29601
        int err = 0;
29602
        WOLFSSL_EVP_PKEY* ret = NULL;
29603
        WOLFSSL_BIO* bio = NULL;
29604
29605
        WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
29606
29607
        if (fp == XBADFILE) {
29608
            err = 1;
29609
        }
29610
        if (err == 0) {
29611
            bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
29612
            err = bio == NULL;
29613
        }
29614
        if (err == 0) {
29615
            err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS;
29616
        }
29617
        if (err == 0) {
29618
            ret = wolfSSL_PEM_read_bio_PrivateKey(bio, x, cb, u);
29619
        }
29620
29621
        if (bio != NULL) {
29622
            wolfSSL_BIO_free(bio);
29623
        }
29624
29625
        return ret;
29626
    }
29627
#endif
29628
#endif
29629
#endif
29630
29631
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL*/
29632
29633
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
29634
29635
    #define PEM_BEGIN              "-----BEGIN "
29636
    #define PEM_BEGIN_SZ           11
29637
    #define PEM_END                "-----END "
29638
    #define PEM_END_SZ             9
29639
    #define PEM_HDR_FIN            "-----"
29640
    #define PEM_HDR_FIN_SZ         5
29641
    #define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
29642
    #define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
29643
    #define PEM_HDR_FIN_EOL_SZ     6
29644
29645
#ifndef NO_BIO
29646
29647
    int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
29648
                             unsigned char **data, long *len)
29649
    {
29650
        int ret = WOLFSSL_SUCCESS;
29651
        char pem[256];
29652
        int pemLen;
29653
        char* p;
29654
        char* nameStr = NULL;
29655
        int nameLen = 0;
29656
        char* headerStr = NULL;
29657
        int headerLen;
29658
        int headerFound = 0;
29659
        unsigned char* der = NULL;
29660
        word32 derLen = 0;
29661
29662
        if (bio == NULL || name == NULL || header == NULL || data == NULL ||
29663
                                                                  len == NULL) {
29664
            return WOLFSSL_FAILURE;
29665
        }
29666
29667
        /* Find header line. */
29668
        pem[sizeof(pem) - 1] = '\0';
29669
        while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
29670
            if (XSTRNCMP(pem, PEM_BEGIN, PEM_BEGIN_SZ) == 0)
29671
                break;
29672
        }
29673
        if (pemLen <= 0)
29674
            ret = WOLFSSL_FAILURE;
29675
        /* Have a header line. */
29676
        if (ret == WOLFSSL_SUCCESS) {
29677
            while (pem[pemLen - 1] == '\r' || pem[pemLen - 1] == '\n')
29678
                pemLen--;
29679
            pem[pemLen] = '\0';
29680
            if (XSTRNCMP(pem + pemLen - PEM_HDR_FIN_SZ, PEM_HDR_FIN,
29681
                                                         PEM_HDR_FIN_SZ) != 0) {
29682
                ret = WOLFSSL_FAILURE;
29683
            }
29684
        }
29685
29686
        /* Get out name. */
29687
        if (ret == WOLFSSL_SUCCESS) {
29688
            nameLen = pemLen - PEM_BEGIN_SZ - PEM_HDR_FIN_SZ;
29689
            nameStr = (char*)XMALLOC(nameLen + 1, NULL,
29690
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29691
            if (nameStr == NULL)
29692
                ret = WOLFSSL_FAILURE;
29693
        }
29694
        if (ret == WOLFSSL_SUCCESS) {
29695
            XSTRNCPY(nameStr, pem + PEM_BEGIN_SZ, nameLen);
29696
            nameStr[nameLen] = '\0';
29697
29698
            /* Get header of PEM - encryption header. */
29699
            headerLen = 0;
29700
            while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
29701
                while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
29702
                                                     pem[pemLen - 1] == '\n')) {
29703
                    pemLen--;
29704
                }
29705
                pem[pemLen++] = '\n';
29706
                pem[pemLen] = '\0';
29707
29708
                /* Header separator is a blank line. */
29709
                if (pem[0] == '\n') {
29710
                    headerFound = 1;
29711
                    break;
29712
                }
29713
29714
                /* Didn't find a blank line - no header. */
29715
                if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0) {
29716
                    der = (unsigned char*)headerStr;
29717
                    derLen = headerLen;
29718
                    /* Empty header - empty string. */
29719
                    headerStr = (char*)XMALLOC(1, NULL,
29720
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29721
                    if (headerStr == NULL)
29722
                        ret = WOLFSSL_FAILURE;
29723
                    else
29724
                        headerStr[0] = '\0';
29725
                    break;
29726
                }
29727
29728
                p = (char*)XREALLOC(headerStr, headerLen + pemLen + 1, NULL,
29729
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29730
                if (p == NULL) {
29731
                    ret = WOLFSSL_FAILURE;
29732
                    break;
29733
                }
29734
29735
                headerStr = p;
29736
                XMEMCPY(headerStr + headerLen, pem, pemLen + 1);
29737
                headerLen += pemLen;
29738
            }
29739
            if (pemLen <= 0)
29740
                ret = WOLFSSL_FAILURE;
29741
        }
29742
29743
        /* Get body of PEM - if there was a header */
29744
        if (ret == WOLFSSL_SUCCESS && headerFound) {
29745
            derLen = 0;
29746
            while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
29747
                while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
29748
                                                     pem[pemLen - 1] == '\n')) {
29749
                    pemLen--;
29750
                }
29751
                pem[pemLen++] = '\n';
29752
                pem[pemLen] = '\0';
29753
29754
                if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0)
29755
                    break;
29756
29757
                p = (char*)XREALLOC(der, derLen + pemLen + 1, NULL,
29758
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29759
                if (p == NULL) {
29760
                    ret = WOLFSSL_FAILURE;
29761
                    break;
29762
                }
29763
29764
                der = (unsigned char*)p;
29765
                XMEMCPY(der + derLen, pem, pemLen + 1);
29766
                derLen += pemLen;
29767
            }
29768
            if (pemLen <= 0)
29769
                ret = WOLFSSL_FAILURE;
29770
        }
29771
29772
        /* Check trailer. */
29773
        if (ret == WOLFSSL_SUCCESS) {
29774
            if (XSTRNCMP(pem + PEM_END_SZ, nameStr, nameLen) != 0)
29775
                ret = WOLFSSL_FAILURE;
29776
        }
29777
        if (ret == WOLFSSL_SUCCESS) {
29778
            if (XSTRNCMP(pem + PEM_END_SZ + nameLen,
29779
                    PEM_HDR_FIN_EOL_NEWLINE,
29780
                    PEM_HDR_FIN_EOL_SZ) != 0 &&
29781
                XSTRNCMP(pem + PEM_END_SZ + nameLen,
29782
                        PEM_HDR_FIN_EOL_NULL_TERM,
29783
                        PEM_HDR_FIN_EOL_SZ) != 0) {
29784
                ret = WOLFSSL_FAILURE;
29785
            }
29786
        }
29787
29788
        /* Base64 decode body. */
29789
        if (ret == WOLFSSL_SUCCESS) {
29790
            if (Base64_Decode(der, derLen, der, &derLen) != 0)
29791
                ret = WOLFSSL_FAILURE;
29792
        }
29793
29794
        if (ret == WOLFSSL_SUCCESS) {
29795
            *name = nameStr;
29796
            *header = headerStr;
29797
            *data = der;
29798
            *len = derLen;
29799
            nameStr = NULL;
29800
            headerStr = NULL;
29801
            der = NULL;
29802
        }
29803
29804
        if (nameStr != NULL)
29805
            XFREE(nameStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29806
        if (headerStr != NULL)
29807
            XFREE(headerStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29808
        if (der != NULL)
29809
            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29810
29811
        return ret;
29812
    }
29813
29814
    int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
29815
                              const char *header, const unsigned char *data,
29816
                              long len)
29817
    {
29818
        int err = 0;
29819
        int outSz = 0;
29820
        int nameLen;
29821
        int headerLen;
29822
        byte* pem = NULL;
29823
        word32 pemLen;
29824
        word32 derLen = (word32)len;
29825
29826
        if (bio == NULL || name == NULL || header == NULL || data == NULL)
29827
            return 0;
29828
29829
        nameLen = (int)XSTRLEN(name);
29830
        headerLen = (int)XSTRLEN(header);
29831
29832
        pemLen = (derLen + 2) / 3 * 4;
29833
        pemLen += (pemLen + 63) / 64;
29834
29835
        pem = (byte*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29836
        err = pem == NULL;
29837
        if (!err)
29838
            err = Base64_Encode(data, derLen, pem, &pemLen) != 0;
29839
29840
        if (!err) {
29841
            err = wolfSSL_BIO_write(bio, PEM_BEGIN, PEM_BEGIN_SZ) !=
29842
                                                              (int)PEM_BEGIN_SZ;
29843
        }
29844
        if (!err)
29845
            err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
29846
        if (!err) {
29847
            err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
29848
                    PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
29849
        }
29850
        if (!err && headerLen > 0) {
29851
            err = wolfSSL_BIO_write(bio, header, headerLen) != headerLen;
29852
            /* Blank line after a header and before body. */
29853
            if (!err)
29854
                err = wolfSSL_BIO_write(bio, "\n", 1) != 1;
29855
            headerLen++;
29856
        }
29857
        if (!err)
29858
            err = wolfSSL_BIO_write(bio, pem, pemLen) != (int)pemLen;
29859
        if (!err)
29860
            err = wolfSSL_BIO_write(bio, PEM_END, PEM_END_SZ) !=
29861
                                                                (int)PEM_END_SZ;
29862
        if (!err)
29863
            err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
29864
        if (!err) {
29865
            err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
29866
                    PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
29867
        }
29868
29869
        if (!err) {
29870
            outSz = PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ + headerLen +
29871
                             pemLen + PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ;
29872
        }
29873
29874
        if (pem != NULL)
29875
            XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29876
29877
        return outSz;
29878
    }
29879
29880
#if !defined(NO_FILESYSTEM)
29881
    int wolfSSL_PEM_read(XFILE fp, char **name, char **header,
29882
                         unsigned char **data, long *len)
29883
    {
29884
        int ret;
29885
        WOLFSSL_BIO* bio;
29886
29887
        if (name == NULL || header == NULL || data == NULL || len == NULL)
29888
            return WOLFSSL_FAILURE;
29889
29890
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
29891
        if (bio == NULL)
29892
            return 0;
29893
29894
        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
29895
            wolfSSL_BIO_free(bio);
29896
            bio = NULL;
29897
        }
29898
29899
        ret = wolfSSL_PEM_read_bio(bio, name, header, data, len);
29900
29901
        if (bio != NULL)
29902
            wolfSSL_BIO_free(bio);
29903
29904
        return ret;
29905
    }
29906
29907
    int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
29908
                          const unsigned char *data, long len)
29909
    {
29910
        int ret;
29911
        WOLFSSL_BIO* bio;
29912
29913
        if (name == NULL || header == NULL || data == NULL)
29914
            return 0;
29915
29916
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
29917
        if (bio == NULL)
29918
            return 0;
29919
29920
        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
29921
            wolfSSL_BIO_free(bio);
29922
            bio = NULL;
29923
        }
29924
29925
        ret = wolfSSL_PEM_write_bio(bio, name, header, data, len);
29926
29927
        if (bio != NULL)
29928
            wolfSSL_BIO_free(bio);
29929
29930
        return ret;
29931
    }
29932
#endif
29933
#endif /* !NO_BIO */
29934
29935
    int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header,
29936
                                        EncryptedInfo* cipher)
29937
    {
29938
        if (header == NULL || cipher == NULL)
29939
            return WOLFSSL_FAILURE;
29940
29941
        XMEMSET(cipher, 0, sizeof(*cipher));
29942
29943
        if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0)
29944
            return WOLFSSL_FAILURE;
29945
29946
        return WOLFSSL_SUCCESS;
29947
    }
29948
29949
    int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data,
29950
                              long* len, wc_pem_password_cb* callback,
29951
                              void* ctx)
29952
    {
29953
        int ret = WOLFSSL_SUCCESS;
29954
        char password[NAME_SZ];
29955
        int passwordSz;
29956
29957
        if (cipher == NULL || data == NULL || len == NULL || callback == NULL)
29958
            return WOLFSSL_FAILURE;
29959
29960
        passwordSz = callback(password, sizeof(password), PEM_PASS_READ, ctx);
29961
        if (passwordSz < 0)
29962
            ret = WOLFSSL_FAILURE;
29963
29964
        if (ret == WOLFSSL_SUCCESS) {
29965
            if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
29966
                                                     passwordSz, WC_MD5) != 0) {
29967
                ret = WOLFSSL_FAILURE;
29968
            }
29969
        }
29970
29971
        if (passwordSz > 0)
29972
            XMEMSET(password, 0, passwordSz);
29973
29974
        return ret;
29975
    }
29976
29977
#ifndef NO_BIO
29978
    /*
29979
     * bp : bio to read X509 from
29980
     * x  : x509 to write to
29981
     * cb : password call back for reading PEM
29982
     * u  : password
29983
     * _AUX is for working with a trusted X509 certificate
29984
     */
29985
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
29986
                               WOLFSSL_X509 **x, wc_pem_password_cb *cb,
29987
                               void *u)
29988
    {
29989
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
29990
29991
        /* AUX info is; trusted/rejected uses, friendly name, private key id,
29992
         * and potentially a stack of "other" info. wolfSSL does not store
29993
         * friendly name or private key id yet in WOLFSSL_X509 for human
29994
         * readability and does not support extra trusted/rejected uses for
29995
         * root CA. */
29996
        return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
29997
    }
29998
#endif /* !NO_BIO */
29999
30000
30001
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
30002
#endif /* !NO_CERTS */
30003
30004
    /* NID variables are dependent on compatibility header files currently
30005
     *
30006
     * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL
30007
     *         on fail
30008
     */
30009
30010
    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int id)
30011
    {
30012
        return wolfSSL_OBJ_nid2obj_ex(id, NULL);
30013
    }
30014
30015
30016
    WOLFSSL_LOCAL WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj_ex(int id,
30017
                                                WOLFSSL_ASN1_OBJECT* arg_obj)
30018
    {
30019
        word32 oidSz = 0;
30020
        int nid = 0;
30021
        const byte* oid;
30022
        word32 type = 0;
30023
        WOLFSSL_ASN1_OBJECT* obj = arg_obj;
30024
        byte objBuf[MAX_OID_SZ + MAX_LENGTH_SZ + 1]; /* +1 for object tag */
30025
        word32 objSz = 0;
30026
        const char* sName = NULL;
30027
        int i;
30028
30029
#ifdef WOLFSSL_DEBUG_OPENSSL
30030
        WOLFSSL_ENTER("wolfSSL_OBJ_nid2obj()");
30031
#endif
30032
30033
        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
30034
            if (wolfssl_object_info[i].nid == id) {
30035
                nid = id;
30036
                id = wolfssl_object_info[i].id;
30037
                sName = wolfssl_object_info[i].sName;
30038
                type = wolfssl_object_info[i].type;
30039
                break;
30040
            }
30041
        }
30042
        if (i == (int)WOLFSSL_OBJECT_INFO_SZ) {
30043
            WOLFSSL_MSG("NID not in table");
30044
        #ifdef WOLFSSL_QT
30045
            sName = NULL;
30046
            type = id;
30047
        #else
30048
            return NULL;
30049
        #endif
30050
        }
30051
30052
    #ifdef HAVE_ECC
30053
         if (type == 0 && wc_ecc_get_oid(id, &oid, &oidSz) > 0) {
30054
             type = oidCurveType;
30055
         }
30056
    #endif /* HAVE_ECC */
30057
30058
        if (sName != NULL) {
30059
            if (XSTRLEN(sName) > WOLFSSL_MAX_SNAME - 1) {
30060
                WOLFSSL_MSG("Attempted short name is too large");
30061
                return NULL;
30062
            }
30063
        }
30064
30065
        oid = OidFromId(id, type, &oidSz);
30066
30067
        /* set object ID to buffer */
30068
        if (obj == NULL){
30069
            obj = wolfSSL_ASN1_OBJECT_new();
30070
            if (obj == NULL) {
30071
                WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
30072
                return NULL;
30073
            }
30074
        }
30075
        obj->nid     = nid;
30076
        obj->type    = id;
30077
        obj->grp     = type;
30078
30079
        obj->sName[0] = '\0';
30080
        if (sName != NULL) {
30081
            XMEMCPY(obj->sName, (char*)sName, XSTRLEN((char*)sName));
30082
        }
30083
30084
        objBuf[0] = ASN_OBJECT_ID; objSz++;
30085
        objSz += SetLength(oidSz, objBuf + 1);
30086
        if (oidSz) {
30087
            XMEMCPY(objBuf + objSz, oid, oidSz);
30088
            objSz     += oidSz;
30089
        }
30090
30091
        if (obj->objSz == 0 || objSz != obj->objSz) {
30092
            obj->objSz = objSz;
30093
            if(((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
30094
                                                           (obj->obj == NULL)) {
30095
                if (obj->obj != NULL)
30096
                    XFREE((byte*)obj->obj, NULL, DYNAMIC_TYPE_ASN1);
30097
                obj->obj = (byte*)XMALLOC(obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
30098
                if (obj->obj == NULL) {
30099
                    wolfSSL_ASN1_OBJECT_free(obj);
30100
                    return NULL;
30101
                }
30102
                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ;
30103
            }
30104
            else {
30105
                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA ;
30106
            }
30107
        }
30108
        XMEMCPY((byte*)obj->obj, objBuf, obj->objSz);
30109
30110
        (void)type;
30111
30112
        return obj;
30113
    }
30114
30115
    static const char* oid_translate_num_to_str(const char* oid)
30116
    {
30117
        const struct oid_dict {
30118
            const char* num;
30119
            const char* desc;
30120
        } oid_dict[] = {
30121
            { "2.5.29.37.0",       "Any Extended Key Usage" },
30122
            { "1.3.6.1.5.5.7.3.1", "TLS Web Server Authentication" },
30123
            { "1.3.6.1.5.5.7.3.2", "TLS Web Client Authentication" },
30124
            { "1.3.6.1.5.5.7.3.3", "Code Signing" },
30125
            { "1.3.6.1.5.5.7.3.4", "E-mail Protection" },
30126
            { "1.3.6.1.5.5.7.3.8", "Time Stamping" },
30127
            { "1.3.6.1.5.5.7.3.9", "OCSP Signing" },
30128
            { NULL, NULL }
30129
        };
30130
        const struct oid_dict* idx;
30131
30132
        for (idx = oid_dict; idx->num != NULL; idx++) {
30133
            if (!XSTRCMP(oid, idx->num)) {
30134
                return idx->desc;
30135
            }
30136
        }
30137
        return NULL;
30138
    }
30139
30140
    static int wolfssl_obj2txt_numeric(char *buf, int bufLen,
30141
                                       const WOLFSSL_ASN1_OBJECT *a)
30142
    {
30143
        int bufSz;
30144
        int    length;
30145
        word32 idx = 0;
30146
        byte   tag;
30147
30148
        if (GetASNTag(a->obj, &idx, &tag, a->objSz) != 0) {
30149
            return WOLFSSL_FAILURE;
30150
        }
30151
30152
        if (tag != ASN_OBJECT_ID) {
30153
            WOLFSSL_MSG("Bad ASN1 Object");
30154
            return WOLFSSL_FAILURE;
30155
        }
30156
30157
        if (GetLength((const byte*)a->obj, &idx, &length,
30158
                       a->objSz) < 0 || length < 0) {
30159
            return ASN_PARSE_E;
30160
        }
30161
30162
        if (bufLen < MAX_OID_STRING_SZ) {
30163
            bufSz = bufLen - 1;
30164
        }
30165
        else {
30166
            bufSz = MAX_OID_STRING_SZ;
30167
        }
30168
30169
        if ((bufSz = DecodePolicyOID(buf, (word32)bufSz, a->obj + idx,
30170
                    (word32)length)) <= 0) {
30171
            WOLFSSL_MSG("Error decoding OID");
30172
            return WOLFSSL_FAILURE;
30173
        }
30174
30175
        buf[bufSz] = '\0';
30176
30177
        return bufSz;
30178
    }
30179
30180
    /* If no_name is one then use numerical form, otherwise short name.
30181
     *
30182
     * Returns the buffer size on success, WOLFSSL_FAILURE on error
30183
     */
30184
    int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, const WOLFSSL_ASN1_OBJECT *a,
30185
                            int no_name)
30186
    {
30187
        int bufSz;
30188
        const char* desc;
30189
        const char* name;
30190
30191
        WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt()");
30192
30193
        if (buf == NULL || bufLen <= 1 || a == NULL) {
30194
            WOLFSSL_MSG("Bad input argument");
30195
            return WOLFSSL_FAILURE;
30196
        }
30197
30198
        if (no_name == 1) {
30199
            return wolfssl_obj2txt_numeric(buf, bufLen, a);
30200
        }
30201
30202
        /* return long name unless using x509small, then return short name */
30203
#if defined(OPENSSL_EXTRA_X509_SMALL) && !defined(OPENSSL_EXTRA)
30204
        name = a->sName;
30205
#else
30206
        name = wolfSSL_OBJ_nid2ln(wolfSSL_OBJ_obj2nid(a));
30207
#endif
30208
30209
        if (name == NULL) {
30210
            WOLFSSL_MSG("Name not found");
30211
            bufSz = 0;
30212
        }
30213
        else if (XSTRLEN(name) + 1 < (word32)bufLen - 1) {
30214
            bufSz = (int)XSTRLEN(name);
30215
        }
30216
        else {
30217
            bufSz = bufLen - 1;
30218
        }
30219
        if (bufSz) {
30220
            XMEMCPY(buf, name, bufSz);
30221
        }
30222
        else if (a->type == GEN_DNS || a->type == GEN_EMAIL ||
30223
                 a->type == GEN_URI) {
30224
            bufSz = (int)XSTRLEN((const char*)a->obj);
30225
            XMEMCPY(buf, a->obj, min(bufSz, bufLen));
30226
        }
30227
        else if ((bufSz = wolfssl_obj2txt_numeric(buf, bufLen, a)) > 0) {
30228
            if ((desc = oid_translate_num_to_str(buf))) {
30229
                bufSz = (int)XSTRLEN(desc);
30230
                bufSz = min(bufSz, bufLen - 1);
30231
                XMEMCPY(buf, desc, bufSz);
30232
            }
30233
        }
30234
30235
        buf[bufSz] = '\0';
30236
30237
        return bufSz;
30238
    }
30239
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
30240
30241
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
30242
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
30243
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
30244
    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS_SMALL)
30245
    /* Returns the long name that corresponds with an ASN1_OBJECT nid value.
30246
     *  n : NID value of ASN1_OBJECT to search */
30247
    const char* wolfSSL_OBJ_nid2ln(int n)
30248
    {
30249
        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
30250
        size_t i;
30251
        WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
30252
        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
30253
            if (obj_info->nid == n) {
30254
                return obj_info->lName;
30255
            }
30256
        }
30257
        WOLFSSL_MSG("NID not found in table");
30258
        return NULL;
30259
    }
30260
#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
30261
          WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY, WOLFSSL_WPAS_SMALL */
30262
30263
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
30264
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
30265
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
30266
    defined(WOLFSSL_HAPROXY)
30267
    char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
30268
    {
30269
        int ret;
30270
30271
        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
30272
        if (!ctx || !x || !x->derCert) {
30273
            WOLFSSL_MSG("Bad parameter");
30274
            return WOLFSSL_FAILURE;
30275
        }
30276
30277
        FreeDer(&ctx->certificate); /* Make sure previous is free'd */
30278
        ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE,
30279
                       ctx->heap);
30280
        if (ret != 0)
30281
            return WOLFSSL_FAILURE;
30282
30283
        XMEMCPY(ctx->certificate->buffer, x->derCert->buffer,
30284
                x->derCert->length);
30285
#ifdef KEEP_OUR_CERT
30286
        if (ctx->ourCert != NULL && ctx->ownOurCert) {
30287
            wolfSSL_X509_free(ctx->ourCert);
30288
        }
30289
        #ifndef WOLFSSL_X509_STORE_CERTS
30290
        ctx->ourCert = x;
30291
        if (wolfSSL_X509_up_ref(x) != 1) {
30292
            return WOLFSSL_FAILURE;
30293
        }
30294
        #else
30295
        ctx->ourCert = wolfSSL_X509_d2i(NULL, x->derCert->buffer,x->derCert->length);
30296
        if(ctx->ourCert == NULL){
30297
            return WOLFSSL_FAILURE;
30298
        }
30299
        #endif
30300
30301
        /* We own the cert because either we up its reference counter
30302
         * or we create our own copy of the cert object. */
30303
        ctx->ownOurCert = 1;
30304
#endif
30305
30306
        /* Update the available options with public keys. */
30307
        switch (x->pubKeyOID) {
30308
    #ifndef NO_RSA
30309
        #ifdef WC_RSA_PSS
30310
            case RSAPSSk:
30311
        #endif
30312
            case RSAk:
30313
                ctx->haveRSA = 1;
30314
                break;
30315
    #endif
30316
        #ifdef HAVE_ED25519
30317
            case ED25519k:
30318
        #endif
30319
        #ifdef HAVE_ED448
30320
            case ED448k:
30321
        #endif
30322
            case ECDSAk:
30323
                ctx->haveECC = 1;
30324
        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
30325
                ctx->pkCurveOID = x->pkCurveOID;
30326
        #endif
30327
                break;
30328
        }
30329
30330
        return WOLFSSL_SUCCESS;
30331
    }
30332
30333
    static int PushCertToDerBuffer(DerBuffer** inOutDer, int weOwn,
30334
            byte* cert, word32 certSz, void* heap)
30335
    {
30336
        int ret;
30337
        DerBuffer* inChain = NULL;
30338
        DerBuffer* der = NULL;
30339
        word32 len = 0;
30340
        if (inOutDer == NULL)
30341
            return BAD_FUNC_ARG;
30342
        inChain = *inOutDer;
30343
        if (inChain != NULL)
30344
            len = inChain->length;
30345
        ret = AllocDer(&der, len + CERT_HEADER_SZ + certSz, CERT_TYPE,
30346
                heap);
30347
        if (ret != 0) {
30348
            WOLFSSL_MSG("AllocDer error");
30349
            return ret;
30350
        }
30351
        if (inChain != NULL)
30352
            XMEMCPY(der->buffer, inChain->buffer, len);
30353
        c32to24(certSz, der->buffer + len);
30354
        XMEMCPY(der->buffer + len + CERT_HEADER_SZ, cert, certSz);
30355
        if (weOwn)
30356
            FreeDer(inOutDer);
30357
        *inOutDer = der;
30358
        return WOLFSSL_SUCCESS;
30359
    }
30360
30361
    /**
30362
     * wolfSSL_CTX_add1_chain_cert makes a copy of the cert so we free it
30363
     * on success
30364
     */
30365
    int wolfSSL_CTX_add0_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
30366
    {
30367
        WOLFSSL_ENTER("wolfSSL_CTX_add0_chain_cert");
30368
        if (wolfSSL_CTX_add1_chain_cert(ctx, x509) != WOLFSSL_SUCCESS) {
30369
            return WOLFSSL_FAILURE;
30370
        }
30371
        wolfSSL_X509_free(x509);
30372
        return WOLFSSL_SUCCESS;
30373
    }
30374
30375
    int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
30376
    {
30377
        int ret;
30378
        WOLFSSL_ENTER("wolfSSL_CTX_add1_chain_cert");
30379
        if (ctx == NULL || x509 == NULL || x509->derCert == NULL) {
30380
            return WOLFSSL_FAILURE;
30381
        }
30382
30383
        if (ctx->certificate == NULL)
30384
            ret = (int)wolfSSL_CTX_use_certificate(ctx, x509);
30385
        else {
30386
            if (wolfSSL_X509_up_ref(x509) != WOLFSSL_SUCCESS) {
30387
                WOLFSSL_MSG("wolfSSL_X509_up_ref error");
30388
                return WOLFSSL_FAILURE;
30389
            }
30390
            ret = wolfSSL_CTX_load_verify_buffer(ctx, x509->derCert->buffer,
30391
                x509->derCert->length, WOLFSSL_FILETYPE_ASN1);
30392
            if (ret == WOLFSSL_SUCCESS) {
30393
                /* push to ctx->certChain */
30394
                ret = PushCertToDerBuffer(&ctx->certChain, 1,
30395
                    x509->derCert->buffer, x509->derCert->length, ctx->heap);
30396
            }
30397
            /* Store cert to free it later */
30398
            if (ret == WOLFSSL_SUCCESS && ctx->x509Chain == NULL) {
30399
                ctx->x509Chain = wolfSSL_sk_X509_new_null();
30400
                if (ctx->x509Chain == NULL) {
30401
                    WOLFSSL_MSG("wolfSSL_sk_X509_new_null error");
30402
                    ret =  WOLFSSL_FAILURE;
30403
                }
30404
            }
30405
            if (ret == WOLFSSL_SUCCESS &&
30406
                    wolfSSL_sk_X509_push(ctx->x509Chain, x509)
30407
                        != WOLFSSL_SUCCESS) {
30408
                WOLFSSL_MSG("wolfSSL_sk_X509_push error");
30409
                ret = WOLFSSL_FAILURE;
30410
            }
30411
            if (ret != WOLFSSL_SUCCESS)
30412
                wolfSSL_X509_free(x509); /* Decrease ref counter */
30413
        }
30414
30415
        return (ret == WOLFSSL_SUCCESS) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
30416
    }
30417
30418
#ifdef KEEP_OUR_CERT
30419
    int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
30420
    {
30421
        int ret;
30422
30423
        WOLFSSL_ENTER("wolfSSL_add0_chain_cert");
30424
30425
        if (ssl == NULL || ssl->ctx == NULL || x509 == NULL ||
30426
                x509->derCert == NULL)
30427
            return WOLFSSL_FAILURE;
30428
30429
        if (ssl->buffers.certificate == NULL) {
30430
            ret = wolfSSL_use_certificate(ssl, x509);
30431
            /* Store cert to free it later */
30432
            if (ret == WOLFSSL_SUCCESS) {
30433
                if (ssl->buffers.weOwnCert)
30434
                    wolfSSL_X509_free(ssl->ourCert);
30435
                ssl->ourCert = x509;
30436
                ssl->buffers.weOwnCert = 1;
30437
            }
30438
        }
30439
        else {
30440
            ret = PushCertToDerBuffer(&ssl->buffers.certChain,
30441
                    ssl->buffers.weOwnCertChain, x509->derCert->buffer,
30442
                    x509->derCert->length, ssl->heap);
30443
            if (ret == WOLFSSL_SUCCESS) {
30444
                ssl->buffers.weOwnCertChain = 1;
30445
                /* Store cert to free it later */
30446
                if (ssl->ourCertChain == NULL) {
30447
                    ssl->ourCertChain = wolfSSL_sk_X509_new_null();
30448
                    if (ssl->ourCertChain == NULL) {
30449
                        WOLFSSL_MSG("wolfSSL_sk_X509_new_null error");
30450
                        return WOLFSSL_FAILURE;
30451
                    }
30452
                }
30453
                if (wolfSSL_sk_X509_push(ssl->ourCertChain, x509)
30454
                        != WOLFSSL_SUCCESS) {
30455
                    WOLFSSL_MSG("wolfSSL_sk_X509_push error");
30456
                    return WOLFSSL_FAILURE;
30457
                }
30458
            }
30459
        }
30460
        return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
30461
    }
30462
30463
    int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
30464
    {
30465
        int ret;
30466
30467
        WOLFSSL_ENTER("wolfSSL_add1_chain_cert");
30468
        if (ssl == NULL || ssl->ctx == NULL || x509 == NULL ||
30469
                x509->derCert == NULL)
30470
            return WOLFSSL_FAILURE;
30471
30472
        if (wolfSSL_X509_up_ref(x509) != WOLFSSL_SUCCESS) {
30473
            WOLFSSL_MSG("wolfSSL_X509_up_ref error");
30474
            return WOLFSSL_FAILURE;
30475
        }
30476
        ret = wolfSSL_add0_chain_cert(ssl, x509);
30477
        /* Decrease ref counter on error */
30478
        if (ret != WOLFSSL_SUCCESS)
30479
            wolfSSL_X509_free(x509);
30480
        return ret;
30481
    }
30482
#endif
30483
30484
    /* Return the corresponding short name for the nid <n>.
30485
     * or NULL if short name can't be found.
30486
     */
30487
    const char * wolfSSL_OBJ_nid2sn(int n) {
30488
        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
30489
        size_t i;
30490
        WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
30491
30492
        if (n == NID_md5) {
30493
            /* NID_surname == NID_md5 and NID_surname comes before NID_md5 in
30494
             * wolfssl_object_info. As a result, the loop below will incorrectly
30495
             * return "SN" instead of "MD5." NID_surname isn't the true OpenSSL
30496
             * NID, but other functions rely on this table and modifying it to
30497
             * conform with OpenSSL's NIDs isn't trivial. */
30498
             return "MD5";
30499
        }
30500
        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
30501
            if (obj_info->nid == n) {
30502
                return obj_info->sName;
30503
            }
30504
        }
30505
        WOLFSSL_MSG("SN not found");
30506
        return NULL;
30507
    }
30508
30509
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
30510
    int wolfSSL_OBJ_sn2nid(const char *sn) {
30511
        WOLFSSL_ENTER("wolfSSL_OBJ_sn2nid");
30512
        if (sn == NULL)
30513
            return NID_undef;
30514
        return wc_OBJ_sn2nid(sn);
30515
    }
30516
#endif
30517
30518
    size_t wolfSSL_OBJ_length(const WOLFSSL_ASN1_OBJECT* o)
30519
    {
30520
        size_t ret = 0;
30521
        int err = 0;
30522
        word32 idx = 0;
30523
        int len = 0;
30524
30525
        WOLFSSL_ENTER("wolfSSL_OBJ_length");
30526
30527
        if (o == NULL || o->obj == NULL) {
30528
            WOLFSSL_MSG("Bad argument.");
30529
            err = 1;
30530
        }
30531
30532
        if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
30533
            WOLFSSL_MSG("Error parsing ASN.1 header.");
30534
            err = 1;
30535
        }
30536
        if (err == 0) {
30537
            ret = len;
30538
        }
30539
30540
        WOLFSSL_LEAVE("wolfSSL_OBJ_length", (int)ret);
30541
30542
        return ret;
30543
    }
30544
30545
    const unsigned char* wolfSSL_OBJ_get0_data(const WOLFSSL_ASN1_OBJECT* o)
30546
    {
30547
        const unsigned char* ret = NULL;
30548
        int err = 0;
30549
        word32 idx = 0;
30550
        int len = 0;
30551
30552
        WOLFSSL_ENTER("wolfSSL_OBJ_get0_data");
30553
30554
        if (o == NULL || o->obj == NULL) {
30555
            WOLFSSL_MSG("Bad argument.");
30556
            err = 1;
30557
        }
30558
30559
        if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
30560
            WOLFSSL_MSG("Error parsing ASN.1 header.");
30561
            err = 1;
30562
        }
30563
        if (err == 0) {
30564
            ret = o->obj + idx;
30565
        }
30566
30567
        return ret;
30568
    }
30569
30570
30571
    /* Gets the NID value that corresponds with the ASN1 object.
30572
     *
30573
     * o ASN1 object to get NID of
30574
     *
30575
     * Return NID on success and a negative value on failure
30576
     */
30577
    int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o)
30578
    {
30579
        word32 oid = 0;
30580
        word32 idx = 0;
30581
        int ret;
30582
30583
#ifdef WOLFSSL_DEBUG_OPENSSL
30584
        WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
30585
#endif
30586
30587
        if (o == NULL) {
30588
            return -1;
30589
        }
30590
30591
        #ifdef WOLFSSL_QT
30592
        if (o->grp == oidCertExtType) {
30593
            /* If nid is an unknown extension, return NID_undef */
30594
            if (wolfSSL_OBJ_nid2sn(o->nid) == NULL)
30595
                return NID_undef;
30596
        }
30597
        #endif
30598
30599
        if (o->nid > 0)
30600
            return o->nid;
30601
        if ((ret = GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz)) < 0) {
30602
            if (ret == ASN_OBJECT_ID_E) {
30603
                /* Put ASN object tag in front and try again */
30604
                int len = SetObjectId(o->objSz, NULL) + o->objSz;
30605
                byte* buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30606
                if (!buf) {
30607
                    WOLFSSL_MSG("malloc error");
30608
                    return -1;
30609
                }
30610
                idx = SetObjectId(o->objSz, buf);
30611
                XMEMCPY(buf + idx, o->obj, o->objSz);
30612
                idx = 0;
30613
                ret = GetObjectId(buf, &idx, &oid, o->grp, len);
30614
                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30615
                if (ret < 0) {
30616
                    WOLFSSL_MSG("Issue getting OID of object");
30617
                    return -1;
30618
                }
30619
            }
30620
            else {
30621
                WOLFSSL_MSG("Issue getting OID of object");
30622
                return -1;
30623
            }
30624
        }
30625
30626
        return oid2nid(oid, o->grp);
30627
    }
30628
30629
    /* Return the corresponding NID for the long name <ln>
30630
     * or NID_undef if NID can't be found.
30631
     */
30632
    int wolfSSL_OBJ_ln2nid(const char *ln)
30633
    {
30634
        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
30635
        size_t i, lnlen;
30636
        WOLFSSL_ENTER("wolfSSL_OBJ_ln2nid");
30637
        if (ln && (lnlen = XSTRLEN(ln)) > 0) {
30638
            /* Accept input like "/commonName=" */
30639
            if (ln[0] == '/') {
30640
                ln++;
30641
                lnlen--;
30642
            }
30643
            if (lnlen) {
30644
                if (ln[lnlen-1] == '=') {
30645
                    lnlen--;
30646
                }
30647
                for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
30648
                    if (lnlen == XSTRLEN(obj_info->lName) &&
30649
                            XSTRNCMP(ln, obj_info->lName, lnlen) == 0) {
30650
                        return obj_info->nid;
30651
                    }
30652
                }
30653
            }
30654
        }
30655
        return NID_undef;
30656
    }
30657
30658
    /* compares two objects, return 0 if equal */
30659
    int wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT* a,
30660
                        const WOLFSSL_ASN1_OBJECT* b)
30661
    {
30662
        WOLFSSL_ENTER("wolfSSL_OBJ_cmp");
30663
30664
        if (a && b && a->obj && b->obj) {
30665
            if (a->objSz == b->objSz) {
30666
                return XMEMCMP(a->obj, b->obj, a->objSz);
30667
            }
30668
            else if (a->type == EXT_KEY_USAGE_OID ||
30669
                     b->type == EXT_KEY_USAGE_OID) {
30670
                /* Special case for EXT_KEY_USAGE_OID so that
30671
                 * cmp will be treated as a substring search */
30672
                /* Used in libest to check for id-kp-cmcRA in
30673
                 * EXT_KEY_USAGE extension */
30674
                unsigned int idx;
30675
                const byte* s; /* shorter */
30676
                unsigned int sLen;
30677
                const byte* l; /* longer */
30678
                unsigned int lLen;
30679
                if (a->objSz > b->objSz) {
30680
                    s = b->obj; sLen = b->objSz;
30681
                    l = a->obj; lLen = a->objSz;
30682
                }
30683
                else {
30684
                    s = a->obj; sLen = a->objSz;
30685
                    l = b->obj; lLen = b->objSz;
30686
                }
30687
                for (idx = 0; idx <= lLen - sLen; idx++) {
30688
                    if (XMEMCMP(l + idx, s, sLen) == 0) {
30689
                        /* Found substring */
30690
                        return 0;
30691
                    }
30692
                }
30693
            }
30694
        }
30695
30696
        return WOLFSSL_FATAL_ERROR;
30697
    }
30698
#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
30699
          WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY */
30700
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
30701
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
30702
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
30703
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
30704
    /* Gets the NID value that is related to the OID string passed in. Example
30705
     * string would be "2.5.29.14" for subject key ID.
30706
     *
30707
     * returns NID value on success and NID_undef on error
30708
     */
30709
    int wolfSSL_OBJ_txt2nid(const char* s)
30710
    {
30711
        unsigned int i;
30712
    #ifdef WOLFSSL_CERT_EXT
30713
        int ret;
30714
        unsigned int sum = 0;
30715
        unsigned int outSz = MAX_OID_SZ;
30716
        unsigned char out[MAX_OID_SZ];
30717
    #endif
30718
30719
        WOLFSSL_ENTER("OBJ_txt2nid");
30720
30721
        if (s == NULL) {
30722
            return NID_undef;
30723
        }
30724
30725
    #ifdef WOLFSSL_CERT_EXT
30726
        ret = EncodePolicyOID(out, &outSz, s, NULL);
30727
        if (ret == 0) {
30728
            /* sum OID */
30729
            for (i = 0; i < outSz; i++) {
30730
                sum += out[i];
30731
            }
30732
        }
30733
    #endif /* WOLFSSL_CERT_EXT */
30734
30735
        /* get the group that the OID's sum is in
30736
         * @TODO possible conflict with multiples */
30737
        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
30738
            int len;
30739
        #ifdef WOLFSSL_CERT_EXT
30740
            if (ret == 0) {
30741
                if (wolfssl_object_info[i].id == (int)sum) {
30742
                    return wolfssl_object_info[i].nid;
30743
                }
30744
            }
30745
        #endif
30746
30747
            /* try as a short name */
30748
            len = (int)XSTRLEN(s);
30749
            if ((int)XSTRLEN(wolfssl_object_info[i].sName) == len &&
30750
                XSTRNCMP(wolfssl_object_info[i].sName, s, len) == 0) {
30751
                return wolfssl_object_info[i].nid;
30752
            }
30753
30754
            /* try as a long name */
30755
            if ((int)XSTRLEN(wolfssl_object_info[i].lName) == len &&
30756
                XSTRNCMP(wolfssl_object_info[i].lName, s, len) == 0) {
30757
                return wolfssl_object_info[i].nid;
30758
            }
30759
        }
30760
30761
        return NID_undef;
30762
    }
30763
#endif
30764
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
30765
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
30766
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
30767
    defined(WOLFSSL_HAPROXY)
30768
30769
    /* Creates new ASN1_OBJECT from short name, long name, or text
30770
     * representation of oid. If no_name is 0, then short name, long name, and
30771
     * numerical value of oid are interpreted. If no_name is 1, then only the
30772
     * numerical value of the oid is interpreted.
30773
     *
30774
     * Returns pointer to ASN1_OBJECT on success, or NULL on error.
30775
     */
30776
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
30777
    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_txt2obj(const char* s, int no_name)
30778
    {
30779
        int i, ret;
30780
        int nid = NID_undef;
30781
        unsigned int outSz = MAX_OID_SZ;
30782
        unsigned char out[MAX_OID_SZ];
30783
        WOLFSSL_ASN1_OBJECT* obj;
30784
30785
        WOLFSSL_ENTER("wolfSSL_OBJ_txt2obj");
30786
30787
        if (s == NULL)
30788
            return NULL;
30789
30790
        /* If s is numerical value, try to sum oid */
30791
        ret = EncodePolicyOID(out, &outSz, s, NULL);
30792
        if (ret == 0 && outSz > 0) {
30793
            /* If numerical encode succeeded then just
30794
             * create object from that because sums are
30795
             * not unique and can cause confusion. */
30796
            obj = wolfSSL_ASN1_OBJECT_new();
30797
            if (obj == NULL) {
30798
                WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
30799
                return NULL;
30800
            }
30801
            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
30802
            obj->obj = (byte*)XMALLOC(1 + MAX_LENGTH_SZ + outSz, NULL,
30803
                    DYNAMIC_TYPE_ASN1);
30804
            if (obj->obj == NULL) {
30805
                wolfSSL_ASN1_OBJECT_free(obj);
30806
                return NULL;
30807
            }
30808
            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ;
30809
            i = SetObjectId(outSz, (byte*)obj->obj);
30810
            XMEMCPY((byte*)obj->obj + i, out, outSz);
30811
            obj->objSz = i + outSz;
30812
            return obj;
30813
        }
30814
30815
        /* TODO: update short names in wolfssl_object_info and check OID sums
30816
           are correct */
30817
        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
30818
            /* Short name, long name, and numerical value are interpreted */
30819
            if (no_name == 0 &&
30820
                ((XSTRCMP(s, wolfssl_object_info[i].sName) == 0) ||
30821
                 (XSTRCMP(s, wolfssl_object_info[i].lName) == 0)))
30822
            {
30823
                    nid = wolfssl_object_info[i].nid;
30824
            }
30825
        }
30826
30827
        if (nid != NID_undef)
30828
            return wolfSSL_OBJ_nid2obj(nid);
30829
30830
        return NULL;
30831
    }
30832
#endif
30833
30834
    /* compatibility function. Its intended use is to remove OID's from an
30835
     * internal table that have been added with OBJ_create. wolfSSL manages its
30836
     * own internal OID values and does not currently support OBJ_create. */
30837
    void wolfSSL_OBJ_cleanup(void)
30838
    {
30839
        WOLFSSL_ENTER("wolfSSL_OBJ_cleanup()");
30840
    }
30841
30842
    #ifndef NO_WOLFSSL_STUB
30843
    int wolfSSL_OBJ_create(const char *oid, const char *sn, const char *ln)
30844
    {
30845
        (void)oid;
30846
        (void)sn;
30847
        (void)ln;
30848
        WOLFSSL_STUB("wolfSSL_OBJ_create");
30849
        return WOLFSSL_FAILURE;
30850
    }
30851
    #endif
30852
30853
    void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth)
30854
    {
30855
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
30856
        WOLFSSL_ENTER("wolfSSL_set_verify_depth");
30857
        ssl->options.verifyDepth = (byte)depth;
30858
    #endif
30859
    }
30860
30861
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
30862
    HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
30863
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
30864
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
30865
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
30866
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
30867
    WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne)
30868
    {
30869
        WOLFSSL_ASN1_OBJECT* obj = NULL;
30870
30871
#ifdef WOLFSSL_DEBUG_OPENSSL
30872
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
30873
#endif
30874
        if (ne == NULL) return NULL;
30875
        obj = wolfSSL_OBJ_nid2obj_ex(ne->nid, ne->object);
30876
        if (obj != NULL) {
30877
            obj->nid = ne->nid;
30878
            return obj;
30879
        }
30880
        return NULL;
30881
    }
30882
30883
30884
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
30885
    HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
30886
30887
#ifdef OPENSSL_EXTRA
30888
30889
/* wolfSSL uses negative values for error states. This function returns an
30890
 * unsigned type so the value returned is the absolute value of the error.
30891
 */
30892
unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
30893
{
30894
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
30895
30896
    (void)line;
30897
    (void)file;
30898
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
30899
    {
30900
        int ret;
30901
30902
        if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
30903
            WOLFSSL_MSG("Issue peeking at error node in queue");
30904
            return 0;
30905
        }
30906
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
30907
        if (ret == -ASN_NO_PEM_HEADER)
30908
            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
30909
    #endif
30910
    #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
30911
        if (ret == ASN1_R_HEADER_TOO_LONG) {
30912
            return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
30913
        }
30914
    #endif
30915
        return (unsigned long)ret;
30916
    }
30917
#else
30918
    return (unsigned long)(0 - NOT_COMPILED_IN);
30919
#endif
30920
}
30921
30922
30923
#ifndef NO_CERTS
30924
int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
30925
{
30926
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
30927
30928
    if (ctx == NULL || pkey == NULL) {
30929
        return WOLFSSL_FAILURE;
30930
    }
30931
30932
    switch (pkey->type) {
30933
#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && !defined(NO_RSA)
30934
    case EVP_PKEY_RSA:
30935
        WOLFSSL_MSG("populating RSA key");
30936
        if (PopulateRSAEvpPkeyDer(pkey) != WOLFSSL_SUCCESS)
30937
            return WOLFSSL_FAILURE;
30938
        break;
30939
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
30940
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
30941
        defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
30942
    case EVP_PKEY_DSA:
30943
        break;
30944
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
30945
#ifdef HAVE_ECC
30946
    case EVP_PKEY_EC:
30947
        WOLFSSL_MSG("populating ECC key");
30948
        if (ECC_populate_EVP_PKEY(pkey, pkey->ecc)
30949
                != WOLFSSL_SUCCESS)
30950
            return WOLFSSL_FAILURE;
30951
        break;
30952
#endif
30953
    default:
30954
        return WOLFSSL_FAILURE;
30955
    }
30956
30957
    if (pkey->pkey.ptr != NULL) {
30958
        /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */
30959
        return wolfSSL_CTX_use_PrivateKey_buffer(ctx,
30960
                                       (const unsigned char*)pkey->pkey.ptr,
30961
                                       pkey->pkey_sz, SSL_FILETYPE_ASN1);
30962
    }
30963
30964
    WOLFSSL_MSG("wolfSSL private key not set");
30965
    return BAD_FUNC_ARG;
30966
}
30967
#endif /* !NO_CERTS */
30968
30969
#endif /* OPENSSL_EXTRA */
30970
30971
#if defined(HAVE_EX_DATA) && \
30972
   (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
30973
    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \
30974
    defined(HAVE_LIGHTY)) || defined(HAVE_EX_DATA) || \
30975
    defined(WOLFSSL_WPAS_SMALL)
30976
/**
30977
 * get_ex_new_index is a helper function for the following
30978
 * xx_get_ex_new_index functions:
30979
 *  - wolfSSL_CRYPTO_get_ex_new_index
30980
 *  - wolfSSL_CTX_get_ex_new_index
30981
 *  - wolfSSL_get_ex_new_index
30982
 * Issues a unique index number for the specified class-index.
30983
 * Returns an index number greater or equal to zero on success,
30984
 * -1 on failure.
30985
 */
30986
int wolfssl_get_ex_new_index(int class_index)
30987
{
30988
    /* index counter for each class index*/
30989
    static int ctx_idx = 0;
30990
    static int ssl_idx = 0;
30991
    static int ssl_session_idx = 0;
30992
    static int x509_idx = 0;
30993
30994
    int idx = -1;
30995
30996
    switch(class_index) {
30997
        case WOLF_CRYPTO_EX_INDEX_SSL:
30998
            idx = ssl_idx++;
30999
            break;
31000
        case WOLF_CRYPTO_EX_INDEX_SSL_CTX:
31001
            idx = ctx_idx++;
31002
            break;
31003
        case WOLF_CRYPTO_EX_INDEX_X509:
31004
            idx = x509_idx++;
31005
            break;
31006
        case WOLF_CRYPTO_EX_INDEX_SSL_SESSION:
31007
            idx = ssl_session_idx++;
31008
            break;
31009
31010
        /* following class indexes are not supoprted */
31011
        case WOLF_CRYPTO_EX_INDEX_X509_STORE:
31012
        case WOLF_CRYPTO_EX_INDEX_X509_STORE_CTX:
31013
        case WOLF_CRYPTO_EX_INDEX_DH:
31014
        case WOLF_CRYPTO_EX_INDEX_DSA:
31015
        case WOLF_CRYPTO_EX_INDEX_EC_KEY:
31016
        case WOLF_CRYPTO_EX_INDEX_RSA:
31017
        case WOLF_CRYPTO_EX_INDEX_ENGINE:
31018
        case WOLF_CRYPTO_EX_INDEX_UI:
31019
        case WOLF_CRYPTO_EX_INDEX_BIO:
31020
        case WOLF_CRYPTO_EX_INDEX_APP:
31021
        case WOLF_CRYPTO_EX_INDEX_UI_METHOD:
31022
        case WOLF_CRYPTO_EX_INDEX_DRBG:
31023
        default:
31024
            break;
31025
    }
31026
    return idx;
31027
}
31028
#endif /* HAVE_EX_DATA || WOLFSSL_WPAS_SMALL */
31029
31030
#if defined(HAVE_EX_DATA) || defined(WOLFSSL_WPAS_SMALL)
31031
void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
31032
{
31033
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
31034
#ifdef HAVE_EX_DATA
31035
    if(ctx != NULL) {
31036
        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
31037
    }
31038
#else
31039
    (void)ctx;
31040
    (void)idx;
31041
#endif
31042
    return NULL;
31043
}
31044
31045
int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
31046
                                void* c)
31047
{
31048
31049
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
31050
31051
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(idx, arg, a, b, c);
31052
31053
    return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX);
31054
}
31055
31056
/* Return the index that can be used for the WOLFSSL structure to store
31057
 * application data.
31058
 *
31059
 */
31060
int wolfSSL_get_ex_new_index(long argValue, void* arg,
31061
        WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
31062
        WOLFSSL_CRYPTO_EX_free* cb3)
31063
{
31064
    WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
31065
31066
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(argValue, arg, cb1, cb2, cb3);
31067
31068
    return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL);
31069
}
31070
31071
31072
int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
31073
{
31074
    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
31075
    #ifdef HAVE_EX_DATA
31076
    if (ctx != NULL)
31077
    {
31078
        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
31079
    }
31080
    #else
31081
    (void)ctx;
31082
    (void)idx;
31083
    (void)data;
31084
    #endif
31085
    return WOLFSSL_FAILURE;
31086
}
31087
31088
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
31089
int wolfSSL_CTX_set_ex_data_with_cleanup(
31090
    WOLFSSL_CTX* ctx,
31091
    int idx,
31092
    void* data,
31093
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
31094
{
31095
    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data_with_cleanup");
31096
    if (ctx != NULL)
31097
    {
31098
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx, data,
31099
                                                       cleanup_routine);
31100
    }
31101
    return WOLFSSL_FAILURE;
31102
}
31103
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
31104
31105
#endif /* defined(HAVE_EX_DATA) || defined(WOLFSSL_WPAS_SMALL) */
31106
31107
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
31108
31109
/* Returns char* to app data stored in ex[0].
31110
 *
31111
 * ssl WOLFSSL structure to get app data from
31112
 */
31113
void* wolfSSL_get_app_data(const WOLFSSL *ssl)
31114
{
31115
    /* checkout exdata stuff... */
31116
    WOLFSSL_ENTER("wolfSSL_get_app_data");
31117
31118
    return wolfSSL_get_ex_data(ssl, 0);
31119
}
31120
31121
31122
/* Set ex array 0 to have app data
31123
 *
31124
 * ssl WOLFSSL struct to set app data in
31125
 * arg data to be stored
31126
 *
31127
 * Returns WOLFSSL_SUCCESS on success and SSL_FAILURE on failure
31128
 */
31129
int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
31130
    WOLFSSL_ENTER("wolfSSL_set_app_data");
31131
31132
    return wolfSSL_set_ex_data(ssl, 0, arg);
31133
}
31134
31135
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
31136
31137
#if defined(HAVE_EX_DATA) || defined(OPENSSL_EXTRA) || \
31138
    defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
31139
31140
int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
31141
{
31142
    WOLFSSL_ENTER("wolfSSL_set_ex_data");
31143
#ifdef HAVE_EX_DATA
31144
    if (ssl != NULL)
31145
    {
31146
        return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data);
31147
    }
31148
#else
31149
    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
31150
    (void)ssl;
31151
    (void)idx;
31152
    (void)data;
31153
#endif
31154
    return WOLFSSL_FAILURE;
31155
}
31156
31157
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
31158
int wolfSSL_set_ex_data_with_cleanup(
31159
    WOLFSSL* ssl,
31160
    int idx,
31161
    void* data,
31162
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
31163
{
31164
    WOLFSSL_ENTER("wolfSSL_set_ex_data_with_cleanup");
31165
    if (ssl != NULL)
31166
    {
31167
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ssl->ex_data, idx, data,
31168
                                                       cleanup_routine);
31169
    }
31170
    return WOLFSSL_FAILURE;
31171
}
31172
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
31173
31174
void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
31175
{
31176
    WOLFSSL_ENTER("wolfSSL_get_ex_data");
31177
#ifdef HAVE_EX_DATA
31178
    if (ssl != NULL) {
31179
        return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx);
31180
    }
31181
#else
31182
    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
31183
    (void)ssl;
31184
    (void)idx;
31185
#endif
31186
    return 0;
31187
}
31188
31189
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL */
31190
31191
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
31192
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
31193
31194
#if defined(OPENSSL_EXTRA) && !defined(NO_DH)
31195
/* Initialize ctx->dh with dh's params. Return WOLFSSL_SUCCESS on ok */
31196
long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
31197
{
31198
    int pSz, gSz;
31199
    byte *p, *g;
31200
    int ret=0;
31201
31202
    WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
31203
31204
    if(!ctx || !dh)
31205
        return BAD_FUNC_ARG;
31206
31207
    /* Get needed size for p and g */
31208
    pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
31209
    gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
31210
31211
    if(pSz <= 0 || gSz <= 0)
31212
        return WOLFSSL_FATAL_ERROR;
31213
31214
    p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31215
    if(!p)
31216
        return MEMORY_E;
31217
31218
    g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31219
    if(!g) {
31220
        XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31221
        return MEMORY_E;
31222
    }
31223
31224
    pSz = wolfSSL_BN_bn2bin(dh->p, p);
31225
    gSz = wolfSSL_BN_bn2bin(dh->g, g);
31226
31227
    if(pSz >= 0 && gSz >= 0) /* Conversion successful */
31228
        ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
31229
31230
    XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31231
    XFREE(g, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
31232
31233
    return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
31234
}
31235
#endif /* OPENSSL_EXTRA && !NO_DH */
31236
31237
31238
/* returns the enum value associated with handshake state
31239
 *
31240
 * ssl the WOLFSSL structure to get state of
31241
 */
31242
int wolfSSL_get_state(const WOLFSSL* ssl)
31243
{
31244
    WOLFSSL_ENTER("wolfSSL_get_state");
31245
31246
    if (ssl == NULL) {
31247
        WOLFSSL_MSG("Null argument passed in");
31248
        return SSL_FAILURE;
31249
    }
31250
31251
    return ssl->options.handShakeState;
31252
}
31253
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
31254
31255
#ifdef OPENSSL_EXTRA
31256
void wolfSSL_certs_clear(WOLFSSL* ssl)
31257
{
31258
    WOLFSSL_ENTER("wolfSSL_certs_clear()");
31259
31260
    if (ssl == NULL)
31261
        return;
31262
31263
    /* ctx still owns certificate, certChain, key, dh, and cm */
31264
    if (ssl->buffers.weOwnCert)
31265
        FreeDer(&ssl->buffers.certificate);
31266
    ssl->buffers.certificate = NULL;
31267
    if (ssl->buffers.weOwnCertChain)
31268
        FreeDer(&ssl->buffers.certChain);
31269
    ssl->buffers.certChain = NULL;
31270
#ifdef WOLFSSL_TLS13
31271
    ssl->buffers.certChainCnt = 0;
31272
#endif
31273
    if (ssl->buffers.weOwnKey)
31274
        FreeDer(&ssl->buffers.key);
31275
    ssl->buffers.key      = NULL;
31276
    ssl->buffers.keyType  = 0;
31277
    ssl->buffers.keyId    = 0;
31278
    ssl->buffers.keyLabel = 0;
31279
    ssl->buffers.keySz    = 0;
31280
    ssl->buffers.keyDevId = 0;
31281
}
31282
#endif
31283
31284
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
31285
    || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
31286
31287
long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
31288
{
31289
    WOLFSSL_ENTER("wolfSSL_ctrl");
31290
    if (ssl == NULL)
31291
        return BAD_FUNC_ARG;
31292
31293
    switch (cmd) {
31294
        #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
31295
        #ifdef HAVE_SNI
31296
        case SSL_CTRL_SET_TLSEXT_HOSTNAME:
31297
            WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TLSEXT_HOSTNAME.");
31298
            if (pt == NULL) {
31299
                WOLFSSL_MSG("Passed in NULL Host Name.");
31300
                break;
31301
            }
31302
            return wolfSSL_set_tlsext_host_name(ssl, (const char*) pt);
31303
        #endif /* HAVE_SNI */
31304
        #endif /* WOLFSSL_NGINX || WOLFSSL_QT || OPENSSL_ALL */
31305
        default:
31306
            WOLFSSL_MSG("Case not implemented.");
31307
    }
31308
    (void)opt;
31309
    (void)pt;
31310
    return WOLFSSL_FAILURE;
31311
}
31312
31313
long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
31314
{
31315
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
31316
    long ctrl_opt;
31317
#endif
31318
    long ret = WOLFSSL_SUCCESS;
31319
31320
    WOLFSSL_ENTER("wolfSSL_CTX_ctrl");
31321
    if (ctx == NULL)
31322
        return WOLFSSL_FAILURE;
31323
31324
    switch (cmd) {
31325
    case SSL_CTRL_CHAIN:
31326
#ifdef SESSION_CERTS
31327
    {
31328
        /*
31329
         * We don't care about opt here because a copy of the certificate is
31330
         * stored anyway so increasing the reference counter is not necessary.
31331
         * Just check to make sure that it is set to one of the correct values.
31332
         */
31333
        WOLF_STACK_OF(WOLFSSL_X509)* sk = (WOLF_STACK_OF(WOLFSSL_X509)*) pt;
31334
        WOLFSSL_X509* x509;
31335
        int i;
31336
        if (opt != 0 && opt != 1) {
31337
            ret = WOLFSSL_FAILURE;
31338
            break;
31339
        }
31340
        /* Clear certificate chain */
31341
        FreeDer(&ctx->certChain);
31342
        if (sk) {
31343
            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
31344
                x509 = wolfSSL_sk_X509_value(sk, i);
31345
                /* Prevent wolfSSL_CTX_add_extra_chain_cert from freeing cert */
31346
                if (wolfSSL_X509_up_ref(x509) != 1) {
31347
                    WOLFSSL_MSG("Error increasing reference count");
31348
                    continue;
31349
                }
31350
                if (wolfSSL_CTX_add_extra_chain_cert(ctx, x509) !=
31351
                        WOLFSSL_SUCCESS) {
31352
                    WOLFSSL_MSG("Error adding certificate to context");
31353
                    /* Decrease reference count on failure */
31354
                    wolfSSL_X509_free(x509);
31355
                }
31356
            }
31357
        }
31358
        /* Free previous chain */
31359
        wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
31360
        ctx->x509Chain = sk;
31361
        if (sk && opt == 1) {
31362
            /* up all refs when opt == 1 */
31363
            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
31364
                x509 = wolfSSL_sk_X509_value(sk, i);
31365
                if (wolfSSL_X509_up_ref(x509) != 1) {
31366
                    WOLFSSL_MSG("Error increasing reference count");
31367
                    continue;
31368
                }
31369
            }
31370
        }
31371
    }
31372
#else
31373
        WOLFSSL_MSG("Session certificates not compiled in");
31374
        ret = WOLFSSL_FAILURE;
31375
#endif
31376
        break;
31377
31378
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
31379
    case SSL_CTRL_OPTIONS:
31380
        WOLFSSL_MSG("Entering Case: SSL_CTRL_OPTIONS.");
31381
        ctrl_opt = wolfSSL_CTX_set_options(ctx, opt);
31382
31383
        #ifdef WOLFSSL_QT
31384
        /* Set whether to use client or server cipher preference */
31385
        if ((ctrl_opt & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE)
31386
                     == WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
31387
            WOLFSSL_MSG("Using Server's Cipher Preference.");
31388
            ctx->useClientOrder = FALSE;
31389
        } else {
31390
            WOLFSSL_MSG("Using Client's Cipher Preference.");
31391
            ctx->useClientOrder = TRUE;
31392
        }
31393
        #endif /* WOLFSSL_QT */
31394
31395
        return ctrl_opt;
31396
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
31397
    case SSL_CTRL_EXTRA_CHAIN_CERT:
31398
        WOLFSSL_MSG("Entering Case: SSL_CTRL_EXTRA_CHAIN_CERT.");
31399
        if (pt == NULL) {
31400
            WOLFSSL_MSG("Passed in x509 pointer NULL.");
31401
            ret = WOLFSSL_FAILURE;
31402
            break;
31403
        }
31404
        return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
31405
31406
#ifndef NO_DH
31407
    case SSL_CTRL_SET_TMP_DH:
31408
        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_DH.");
31409
        if (pt == NULL) {
31410
            WOLFSSL_MSG("Passed in DH pointer NULL.");
31411
            ret = WOLFSSL_FAILURE;
31412
            break;
31413
        }
31414
        return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
31415
#endif
31416
31417
#ifdef HAVE_ECC
31418
    case SSL_CTRL_SET_TMP_ECDH:
31419
        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_ECDH.");
31420
        if (pt == NULL) {
31421
            WOLFSSL_MSG("Passed in ECDH pointer NULL.");
31422
            ret = WOLFSSL_FAILURE;
31423
            break;
31424
        }
31425
        return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
31426
#endif
31427
    case SSL_CTRL_MODE:
31428
        wolfSSL_CTX_set_mode(ctx,opt);
31429
        break;
31430
    case SSL_CTRL_SET_MIN_PROTO_VERSION:
31431
        WOLFSSL_MSG("set min proto version");
31432
        return wolfSSL_CTX_set_min_proto_version(ctx, (int)opt);
31433
    case SSL_CTRL_SET_MAX_PROTO_VERSION:
31434
        WOLFSSL_MSG("set max proto version");
31435
        return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt);
31436
    case SSL_CTRL_GET_MIN_PROTO_VERSION:
31437
        WOLFSSL_MSG("get min proto version");
31438
        return wolfSSL_CTX_get_min_proto_version(ctx);
31439
    case SSL_CTRL_GET_MAX_PROTO_VERSION:
31440
        WOLFSSL_MSG("get max proto version");
31441
        return wolfSSL_CTX_get_max_proto_version(ctx);
31442
    default:
31443
        WOLFSSL_MSG("CTX_ctrl cmd not implemented");
31444
        ret = WOLFSSL_FAILURE;
31445
        break;
31446
    }
31447
31448
    (void)ctx;
31449
    (void)cmd;
31450
    (void)opt;
31451
    (void)pt;
31452
    WOLFSSL_LEAVE("wolfSSL_CTX_ctrl", (int)ret);
31453
    return ret;
31454
}
31455
31456
#ifndef WOLFSSL_NO_STUB
31457
long wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX* ctx, int cmd, void (*fp)(void))
31458
{
31459
    (void) ctx;
31460
    (void) cmd;
31461
    (void) fp;
31462
    WOLFSSL_STUB("wolfSSL_CTX_callback_ctrl");
31463
    return WOLFSSL_FAILURE;
31464
31465
}
31466
#endif /* WOLFSSL_NO_STUB */
31467
31468
#ifndef NO_WOLFSSL_STUB
31469
long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx)
31470
{
31471
    return wolfSSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0L, NULL);
31472
}
31473
#endif
31474
31475
/* Returns the verifyCallback from the ssl structure if successful.
31476
Returns NULL otherwise. */
31477
VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
31478
{
31479
    WOLFSSL_ENTER("wolfSSL_get_verify_callback()");
31480
    if (ssl) {
31481
        return ssl->verifyCallback;
31482
    }
31483
    return NULL;
31484
}
31485
31486
/* Adds the ASN1 certificate to the user ctx.
31487
Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
31488
int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz,
31489
                                                       const unsigned char *der)
31490
{
31491
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ASN1()");
31492
    if (der != NULL && ctx != NULL) {
31493
        if (wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
31494
                                      WOLFSSL_FILETYPE_ASN1) == WOLFSSL_SUCCESS) {
31495
            return WOLFSSL_SUCCESS;
31496
        }
31497
31498
    }
31499
    return WOLFSSL_FAILURE;
31500
}
31501
31502
31503
#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
31504
    !defined(NO_RSA) && !defined(HAVE_USER_RSA)
31505
/* Adds the rsa private key to the user ctx.
31506
Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
31507
int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
31508
{
31509
    int ret;
31510
    int derSize;
31511
    unsigned char *maxDerBuf;
31512
    unsigned char* key = NULL;
31513
31514
    WOLFSSL_ENTER("wolfSSL_CTX_use_RSAPrivateKey()");
31515
31516
    if (ctx == NULL || rsa == NULL) {
31517
        WOLFSSL_MSG("one or more inputs were NULL");
31518
        return BAD_FUNC_ARG;
31519
    }
31520
    maxDerBuf = (unsigned char*)XMALLOC(4096, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31521
    if (maxDerBuf == NULL) {
31522
        WOLFSSL_MSG("Malloc failure");
31523
        return MEMORY_E;
31524
    }
31525
    key = maxDerBuf;
31526
    /* convert RSA struct to der encoded buffer and get the size */
31527
    if ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, &key)) <= 0) {
31528
        WOLFSSL_MSG("wolfSSL_i2d_RSAPrivateKey() failure");
31529
        XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31530
        return WOLFSSL_FAILURE;
31531
    }
31532
    ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, (const unsigned char*)maxDerBuf,
31533
                                                    derSize, SSL_FILETYPE_ASN1);
31534
    if (ret != WOLFSSL_SUCCESS) {
31535
        WOLFSSL_MSG("wolfSSL_CTX_USE_PrivateKey_buffer() failure");
31536
        XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31537
        return WOLFSSL_FAILURE;
31538
    }
31539
    XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31540
    return ret;
31541
}
31542
#endif /* NO_RSA && !HAVE_FAST_RSA */
31543
31544
31545
#ifndef NO_BIO
31546
/* Converts EVP_PKEY data from a bio buffer to a WOLFSSL_EVP_PKEY structure.
31547
Returns pointer to private EVP_PKEY struct upon success, NULL if there
31548
is a failure.*/
31549
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio,
31550
                                                         WOLFSSL_EVP_PKEY** out)
31551
{
31552
    unsigned char* mem = NULL;
31553
    int memSz = 0;
31554
    WOLFSSL_EVP_PKEY* key = NULL;
31555
    int i = 0, j = 0;
31556
    unsigned char* extraBioMem = NULL;
31557
    int extraBioMemSz = 0;
31558
    int derLength = 0;
31559
31560
    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_bio()");
31561
31562
    if (bio == NULL) {
31563
        return NULL;
31564
    }
31565
    (void)out;
31566
31567
    memSz = wolfSSL_BIO_get_len(bio);
31568
    if (memSz <= 0) {
31569
        WOLFSSL_MSG("wolfSSL_BIO_get_len() failure");
31570
        return NULL;
31571
    }
31572
31573
    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31574
    if (mem == NULL) {
31575
        WOLFSSL_MSG("Malloc failure");
31576
        return NULL;
31577
    }
31578
31579
    if (wolfSSL_BIO_read(bio, (unsigned char*)mem, memSz) == memSz) {
31580
        /* Determines key type and returns the new private EVP_PKEY object */
31581
        if ((key = wolfSSL_d2i_PrivateKey_EVP(NULL, &mem, (long)memSz)) == NULL) {
31582
            WOLFSSL_MSG("wolfSSL_d2i_PrivateKey_EVP() failure");
31583
            XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31584
            return NULL;
31585
        }
31586
31587
        /* Write extra data back into bio object if necessary. */
31588
        derLength = key->pkey_sz;
31589
        extraBioMemSz = (memSz - derLength);
31590
        if (extraBioMemSz > 0) {
31591
            extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
31592
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31593
            if (extraBioMem == NULL) {
31594
                WOLFSSL_MSG("Malloc failure");
31595
                XFREE((unsigned char*)extraBioMem, bio->heap,
31596
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31597
                XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31598
                return NULL;
31599
            }
31600
31601
            for (i = derLength; i < memSz; i++) {
31602
                *(extraBioMem + j) = *(mem + i);
31603
                j++;
31604
            }
31605
31606
            wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
31607
            if (wolfSSL_BIO_get_len(bio) <= 0) {
31608
                WOLFSSL_MSG("Failed to write memory to bio");
31609
                XFREE((unsigned char*)extraBioMem, bio->heap,
31610
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31611
                XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31612
                return NULL;
31613
            }
31614
            XFREE((unsigned char*)extraBioMem, bio->heap,
31615
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31616
        }
31617
31618
        if (out != NULL) {
31619
            *out = key;
31620
        }
31621
    }
31622
    XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31623
    return key;
31624
}
31625
#endif /* !NO_BIO */
31626
31627
#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
31628
31629
31630
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) || \
31631
    defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || defined(WOLFSSL_WPAS_SMALL)
31632
31633
/* Converts a DER encoded private key to a WOLFSSL_EVP_PKEY structure.
31634
 * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
31635
 * on fail */
31636
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out,
31637
                                                  unsigned char** in, long inSz)
31638
{
31639
    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_EVP");
31640
    return d2iGenericKey(out, (const unsigned char**)in, inSz, 1);
31641
}
31642
31643
#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT || WOLFSSL_WPAS_SMALL*/
31644
31645
31646
/* stunnel compatibility functions*/
31647
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
31648
                             defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
31649
                             defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
31650
void wolfSSL_ERR_remove_thread_state(void* pid)
31651
{
31652
    (void) pid;
31653
    return;
31654
}
31655
31656
#ifndef NO_FILESYSTEM
31657
/***TBD ***/
31658
void wolfSSL_print_all_errors_fp(XFILE fp)
31659
{
31660
    (void)fp;
31661
}
31662
#endif /* !NO_FILESYSTEM */
31663
31664
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
31665
    HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH */
31666
31667
31668
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
31669
    defined(HAVE_EX_DATA)
31670
31671
#if defined(HAVE_EX_DATA) && !defined(NO_SESSION_CACHE)
31672
static void SESSION_ex_data_cache_update(WOLFSSL_SESSION* session, int idx,
31673
        void* data, byte get, void** getRet, int* setRet)
31674
{
31675
    int row;
31676
    int i;
31677
    int error = 0;
31678
    SessionRow* sessRow = NULL;
31679
    const byte* id;
31680
    byte foundCache = 0;
31681
31682
    if (getRet != NULL)
31683
        *getRet = NULL;
31684
    if (setRet != NULL)
31685
        *setRet = WOLFSSL_FAILURE;
31686
31687
    id = session->sessionID;
31688
    if (session->haveAltSessionID)
31689
        id = session->altSessionID;
31690
31691
    row = (int)(HashObject(id, ID_LEN, &error) % SESSION_ROWS);
31692
    if (error != 0) {
31693
        WOLFSSL_MSG("Hash session failed");
31694
        return;
31695
    }
31696
31697
    sessRow = &SessionCache[row];
31698
    if (SESSION_ROW_LOCK(sessRow) != 0) {
31699
        WOLFSSL_MSG("Session row lock failed");
31700
        return;
31701
    }
31702
31703
    for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
31704
        if (XMEMCMP(id, sessRow->Sessions[i].sessionID, ID_LEN) == 0
31705
                && session->side == sessRow->Sessions[i].side) {
31706
            if (get) {
31707
                *getRet = wolfSSL_CRYPTO_get_ex_data(
31708
                        &sessRow->Sessions[i].ex_data, idx);
31709
            }
31710
            else {
31711
                *setRet = wolfSSL_CRYPTO_set_ex_data(
31712
                        &sessRow->Sessions[i].ex_data, idx, data);
31713
            }
31714
            foundCache = 1;
31715
            break;
31716
        }
31717
    }
31718
    SESSION_ROW_UNLOCK(sessRow);
31719
    /* If we don't have a session in cache then clear the ex_data and
31720
     * own it */
31721
    if (!foundCache) {
31722
        XMEMSET(&session->ex_data, 0, sizeof(WOLFSSL_CRYPTO_EX_DATA));
31723
        session->ownExData = 1;
31724
        if (!get) {
31725
            *setRet = wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx,
31726
                    data);
31727
        }
31728
    }
31729
31730
}
31731
#endif
31732
31733
int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
31734
{
31735
    int ret = WOLFSSL_FAILURE;
31736
    WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
31737
#ifdef HAVE_EX_DATA
31738
    session = ClientSessionToSession(session);
31739
    if (session != NULL) {
31740
#ifndef NO_SESSION_CACHE
31741
        if (!session->ownExData) {
31742
            /* Need to update in cache */
31743
            SESSION_ex_data_cache_update(session, idx, data, 0, NULL, &ret);
31744
        }
31745
        else
31746
#endif
31747
        {
31748
            ret = wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data);
31749
        }
31750
    }
31751
#else
31752
    (void)session;
31753
    (void)idx;
31754
    (void)data;
31755
#endif
31756
    return ret;
31757
}
31758
31759
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
31760
int wolfSSL_SESSION_set_ex_data_with_cleanup(
31761
    WOLFSSL_SESSION* session,
31762
    int idx,
31763
    void* data,
31764
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
31765
{
31766
    WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data_with_cleanup");
31767
    session = ClientSessionToSession(session);
31768
    if(session != NULL) {
31769
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&session->ex_data, idx,
31770
                                                       data, cleanup_routine);
31771
    }
31772
    return WOLFSSL_FAILURE;
31773
}
31774
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
31775
31776
void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
31777
{
31778
    void* ret = NULL;
31779
    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
31780
#ifdef HAVE_EX_DATA
31781
    session = ClientSessionToSession(session);
31782
    if (session != NULL) {
31783
#ifndef NO_SESSION_CACHE
31784
        if (!session->ownExData) {
31785
            /* Need to retrieve the data from the session cache */
31786
            SESSION_ex_data_cache_update((WOLFSSL_SESSION*)session, idx, NULL,
31787
                                         1, &ret, NULL);
31788
        }
31789
        else
31790
#endif
31791
        {
31792
            ret = wolfSSL_CRYPTO_get_ex_data(&session->ex_data, idx);
31793
        }
31794
    }
31795
#else
31796
    (void)session;
31797
    (void)idx;
31798
#endif
31799
    return ret;
31800
}
31801
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_EX_DATA */
31802
31803
/* Note: This is a huge section of API's - through
31804
 *       wolfSSL_X509_OBJECT_get0_X509_CRL */
31805
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
31806
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
31807
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
31808
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
31809
#ifdef HAVE_EX_DATA
31810
int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
31811
       void* cb2, CRYPTO_free_func* cb3)
31812
{
31813
    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
31814
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(idx, data, cb1, cb2, cb3);
31815
    return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION);
31816
}
31817
#endif
31818
31819
#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_DEBUG_MEMORY)
31820
static wolfSSL_OSSL_Malloc_cb  ossl_malloc  = NULL;
31821
static wolfSSL_OSSL_Free_cb    ossl_free    = NULL;
31822
static wolfSSL_OSSL_Realloc_cb ossl_realloc = NULL;
31823
31824
static void* OSSL_Malloc(size_t size)
31825
{
31826
    if (ossl_malloc != NULL)
31827
        return ossl_malloc(size, NULL, 0);
31828
    else
31829
        return NULL;
31830
}
31831
31832
static void  OSSL_Free(void *ptr)
31833
{
31834
    if (ossl_free != NULL)
31835
        ossl_free(ptr, NULL, 0);
31836
}
31837
31838
static void* OSSL_Realloc(void *ptr, size_t size)
31839
{
31840
    if (ossl_realloc != NULL)
31841
        return ossl_realloc(ptr, size, NULL, 0);
31842
    else
31843
        return NULL;
31844
}
31845
#endif /* USE_WOLFSSL_MEMORY && !WOLFSSL_DEBUG_MEMORY */
31846
31847
int wolfSSL_CRYPTO_set_mem_functions(
31848
        wolfSSL_OSSL_Malloc_cb  m,
31849
        wolfSSL_OSSL_Realloc_cb r,
31850
        wolfSSL_OSSL_Free_cb    f)
31851
{
31852
#ifdef USE_WOLFSSL_MEMORY
31853
#ifdef WOLFSSL_DEBUG_MEMORY
31854
    WOLFSSL_MSG("mem functions will receive function name instead of "
31855
                "file name");
31856
    if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)m, (wolfSSL_Free_cb)f,
31857
            (wolfSSL_Realloc_cb)r) == 0)
31858
        return WOLFSSL_SUCCESS;
31859
#else
31860
    WOLFSSL_MSG("wolfSSL was compiled without WOLFSSL_DEBUG_MEMORY. mem "
31861
                "functions will receive a NULL file name and 0 for the "
31862
                "line number.");
31863
    if (wolfSSL_SetAllocators(OSSL_Malloc, OSSL_Free, OSSL_Realloc) == 0) {
31864
        ossl_malloc = m;
31865
        ossl_free = f;
31866
        ossl_realloc = r;
31867
        return WOLFSSL_SUCCESS;
31868
    }
31869
#endif
31870
    else
31871
        return WOLFSSL_FAILURE;
31872
#else
31873
    (void)m;
31874
    (void)r;
31875
    (void)f;
31876
    WOLFSSL_MSG("wolfSSL allocator callback functions not compiled in");
31877
    return WOLFSSL_FAILURE;
31878
#endif
31879
}
31880
31881
int wolfSSL_ERR_load_ERR_strings(void)
31882
{
31883
    return WOLFSSL_SUCCESS;
31884
}
31885
31886
void wolfSSL_ERR_load_crypto_strings(void)
31887
{
31888
    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
31889
    /* Do nothing */
31890
    return;
31891
}
31892
31893
int wolfSSL_FIPS_mode(void)
31894
{
31895
#ifdef HAVE_FIPS
31896
    return 1;
31897
#else
31898
    return 0;
31899
#endif
31900
}
31901
31902
int wolfSSL_FIPS_mode_set(int r)
31903
{
31904
#ifdef HAVE_FIPS
31905
    if (r == 0) {
31906
        WOLFSSL_MSG("Cannot disable FIPS at runtime.");
31907
        return WOLFSSL_FAILURE;
31908
    }
31909
    return WOLFSSL_SUCCESS;
31910
#else
31911
    if (r == 0) {
31912
        return WOLFSSL_SUCCESS;
31913
    }
31914
    WOLFSSL_MSG("Cannot enable FIPS. This isn't the wolfSSL FIPS code.");
31915
    return WOLFSSL_FAILURE;
31916
#endif
31917
}
31918
31919
int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
31920
{
31921
    int ret = WOLFSSL_FAILURE;
31922
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
31923
31924
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
31925
    (void)alg_bits;
31926
    if (c!= NULL)
31927
        ret = c->bits;
31928
    #else
31929
    if (c != NULL && c->ssl != NULL) {
31930
        ret = 8 * c->ssl->specs.key_size;
31931
        if (alg_bits != NULL) {
31932
            *alg_bits = ret;
31933
        }
31934
    }
31935
    #endif
31936
    return ret;
31937
}
31938
31939
/* returns value less than 0 on fail to match
31940
 * On a successful match the priority level found is returned
31941
 */
31942
int wolfSSL_sk_SSL_CIPHER_find(
31943
        WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, const WOLFSSL_CIPHER* toFind)
31944
{
31945
    WOLFSSL_STACK* next;
31946
    int i, sz;
31947
31948
    if (sk == NULL || toFind == NULL) {
31949
        return WOLFSSL_FATAL_ERROR;
31950
    }
31951
31952
    sz   = wolfSSL_sk_SSL_CIPHER_num(sk);
31953
    next = sk;
31954
    for (i = 0; i < sz && next != NULL; i++) {
31955
        if (next->data.cipher.cipherSuite0 == toFind->cipherSuite0 &&
31956
                next->data.cipher.cipherSuite == toFind->cipherSuite) {
31957
            return sz - i; /* reverse because stack pushed highest on first */
31958
        }
31959
        next = next->next;
31960
    }
31961
    return WOLFSSL_FATAL_ERROR;
31962
}
31963
31964
/* free's all nodes in the stack and there data */
31965
void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
31966
{
31967
    WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free");
31968
    wolfSSL_sk_free(sk);
31969
}
31970
31971
#ifdef HAVE_SNI
31972
int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
31973
{
31974
    int ret;
31975
    WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
31976
    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
31977
            host_name, (word16)XSTRLEN(host_name));
31978
    WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
31979
    return ret;
31980
}
31981
31982
31983
#ifndef NO_WOLFSSL_SERVER
31984
const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
31985
{
31986
    void * serverName = NULL;
31987
    if (ssl == NULL)
31988
        return NULL;
31989
    TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
31990
    return (const char *)serverName;
31991
}
31992
#endif /* NO_WOLFSSL_SERVER */
31993
#endif /* HAVE_SNI */
31994
31995
WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
31996
{
31997
    if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == WOLFSSL_SUCCESS)
31998
        return ssl->ctx;
31999
    return NULL;
32000
}
32001
32002
32003
VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
32004
{
32005
    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
32006
    if(ctx)
32007
        return ctx->verifyCallback;
32008
    return NULL;
32009
}
32010
32011
32012
#ifdef HAVE_SNI
32013
32014
void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
32015
{
32016
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
32017
    if (ctx)
32018
        ctx->sniRecvCb = cb;
32019
}
32020
32021
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
32022
                                               CallbackSniRecv cb)
32023
{
32024
    WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
32025
    if (ctx) {
32026
        ctx->sniRecvCb = cb;
32027
        return WOLFSSL_SUCCESS;
32028
    }
32029
    return WOLFSSL_FAILURE;
32030
}
32031
32032
int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
32033
{
32034
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
32035
    if (ctx) {
32036
        ctx->sniRecvCbArg = arg;
32037
        return WOLFSSL_SUCCESS;
32038
    }
32039
    return WOLFSSL_FAILURE;
32040
}
32041
32042
#endif /* HAVE_SNI */
32043
32044
32045
#ifndef NO_BIO
32046
void wolfSSL_ERR_load_BIO_strings(void) {
32047
    WOLFSSL_ENTER("ERR_load_BIO_strings");
32048
    /* do nothing */
32049
}
32050
#endif
32051
32052
#ifndef NO_WOLFSSL_STUB
32053
/* Set THREADID callback, return 1 on success, 0 on error */
32054
int wolfSSL_THREADID_set_callback(
32055
        void(*threadid_func)(WOLFSSL_CRYPTO_THREADID*))
32056
{
32057
    WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
32058
    WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
32059
    (void)threadid_func;
32060
    return 1;
32061
}
32062
#endif
32063
32064
#ifndef NO_WOLFSSL_STUB
32065
void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
32066
{
32067
    WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
32068
    WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
32069
    (void)id;
32070
    (void)val;
32071
    return;
32072
}
32073
#endif
32074
32075
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
32076
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
32077
        * HAVE_SBLIM_SFCB)) */
32078
32079
32080
#if defined(OPENSSL_EXTRA)
32081
32082
int wolfSSL_CRYPTO_memcmp(const void *a, const void *b, size_t size)
32083
{
32084
    if (!a || !b)
32085
        return 0;
32086
    return ConstantCompare((const byte*)a, (const byte*)b, (int)size);
32087
}
32088
32089
unsigned long wolfSSL_ERR_peek_last_error(void)
32090
{
32091
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
32092
32093
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
32094
    {
32095
        int ret;
32096
32097
        if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
32098
            WOLFSSL_MSG("Issue peeking at error node in queue");
32099
            return 0;
32100
        }
32101
        if (ret == -ASN_NO_PEM_HEADER)
32102
            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
32103
    #if defined(WOLFSSL_PYTHON)
32104
        if (ret == ASN1_R_HEADER_TOO_LONG)
32105
            return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
32106
    #endif
32107
        return (unsigned long)ret;
32108
    }
32109
#else
32110
    return (unsigned long)(0 - NOT_COMPILED_IN);
32111
#endif
32112
}
32113
32114
#endif /* OPENSSL_EXTRA */
32115
32116
int wolfSSL_version(WOLFSSL* ssl)
32117
0
{
32118
0
    WOLFSSL_ENTER("wolfSSL_version");
32119
0
    if (ssl->version.major == SSLv3_MAJOR) {
32120
0
        switch (ssl->version.minor) {
32121
0
            case SSLv3_MINOR :
32122
0
                return SSL3_VERSION;
32123
0
            case TLSv1_MINOR :
32124
0
                return TLS1_VERSION;
32125
0
            case TLSv1_1_MINOR :
32126
0
                return TLS1_1_VERSION;
32127
0
            case TLSv1_2_MINOR :
32128
0
                return TLS1_2_VERSION;
32129
0
            case TLSv1_3_MINOR :
32130
0
                return TLS1_3_VERSION;
32131
0
            default:
32132
0
                return WOLFSSL_FAILURE;
32133
0
        }
32134
0
    }
32135
0
    else if (ssl->version.major == DTLS_MAJOR) {
32136
0
        switch (ssl->version.minor) {
32137
0
            case DTLS_MINOR :
32138
0
                return DTLS1_VERSION;
32139
0
            case DTLSv1_2_MINOR :
32140
0
                return DTLS1_2_VERSION;
32141
0
            default:
32142
0
                return WOLFSSL_FAILURE;
32143
0
        }
32144
0
    }
32145
0
    return WOLFSSL_FAILURE;
32146
0
}
32147
32148
WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
32149
0
{
32150
0
    WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
32151
0
    return ssl->ctx;
32152
0
}
32153
32154
#if defined(OPENSSL_ALL) || \
32155
    defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
32156
    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
32157
32158
const byte* wolfSSL_SESSION_get_id(const WOLFSSL_SESSION* sess,
32159
        unsigned int* idLen)
32160
{
32161
    WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
32162
    sess = ClientSessionToSession(sess);
32163
    if (sess == NULL || idLen == NULL) {
32164
        WOLFSSL_MSG("Bad func args. Please provide idLen");
32165
        return NULL;
32166
    }
32167
    *idLen = sess->sessionIDSz;
32168
    return sess->sessionID;
32169
}
32170
32171
#if (defined(HAVE_SESSION_TICKET) || defined(SESSION_CERTS)) && \
32172
    !defined(NO_FILESYSTEM)
32173
32174
#ifndef NO_BIO
32175
32176
#if defined(SESSION_CERTS) || \
32177
   (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
32178
/* returns a pointer to the protocol used by the session */
32179
static const char* wolfSSL_SESSION_get_protocol(const WOLFSSL_SESSION* in)
32180
{
32181
    in = ClientSessionToSession(in);
32182
    return wolfSSL_internal_get_version((ProtocolVersion*)&in->version);
32183
}
32184
#endif
32185
32186
/* returns true (non 0) if the session has EMS (extended master secret) */
32187
static int wolfSSL_SESSION_haveEMS(const WOLFSSL_SESSION* in)
32188
{
32189
    in = ClientSessionToSession(in);
32190
    if (in == NULL)
32191
        return 0;
32192
    return in->haveEMS;
32193
}
32194
32195
#if defined(HAVE_SESSION_TICKET)
32196
/* prints out the ticket to bio passed in
32197
 * return WOLFSSL_SUCCESS on success
32198
 */
32199
static int wolfSSL_SESSION_print_ticket(WOLFSSL_BIO* bio,
32200
        const WOLFSSL_SESSION* in, const char* tab)
32201
{
32202
    unsigned short i, j, z, sz;
32203
    short tag = 0;
32204
    byte* pt;
32205
32206
32207
    in = ClientSessionToSession(in);
32208
    if (in == NULL || bio == NULL) {
32209
        return BAD_FUNC_ARG;
32210
    }
32211
32212
    sz = in->ticketLen;
32213
    pt = in->ticket;
32214
32215
    if (wolfSSL_BIO_printf(bio, "%s\n", (sz == 0)? " NONE": "") <= 0)
32216
        return WOLFSSL_FAILURE;
32217
32218
    for (i = 0; i < sz;) {
32219
        char asc[16];
32220
32221
        if (sz - i < 16) {
32222
            if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag + (sz - i)) <= 0)
32223
                return WOLFSSL_FAILURE;
32224
        }
32225
        else {
32226
            if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag) <= 0)
32227
                return WOLFSSL_FAILURE;
32228
        }
32229
        for (j = 0; i < sz && j < 8; j++,i++) {
32230
            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
32231
            if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
32232
                return WOLFSSL_FAILURE;
32233
        }
32234
32235
        if (i < sz) {
32236
            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
32237
            if (wolfSSL_BIO_printf(bio, "-%02X", pt[i]) <= 0)
32238
                return WOLFSSL_FAILURE;
32239
            j++;
32240
            i++;
32241
        }
32242
32243
        for (; i < sz && j < 16; j++,i++) {
32244
            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
32245
            if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
32246
                return WOLFSSL_FAILURE;
32247
        }
32248
32249
        /* pad out spacing */
32250
        for (z = j; z < 17; z++) {
32251
            if (wolfSSL_BIO_printf(bio, "   ") <= 0)
32252
                return WOLFSSL_FAILURE;
32253
        }
32254
32255
        for (z = 0; z < j; z++) {
32256
            if (wolfSSL_BIO_printf(bio, "%c", asc[z]) <= 0)
32257
                return WOLFSSL_FAILURE;
32258
        }
32259
        if (wolfSSL_BIO_printf(bio, "\n") <= 0)
32260
            return WOLFSSL_FAILURE;
32261
32262
        tag += 16;
32263
    }
32264
    return WOLFSSL_SUCCESS;
32265
}
32266
#endif /* HAVE_SESSION_TICKET */
32267
32268
32269
/* prints out the session information in human readable form
32270
 * return WOLFSSL_SUCCESS on success
32271
 */
32272
int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *session)
32273
{
32274
    const unsigned char* pt;
32275
    unsigned char buf[SECRET_LEN];
32276
    unsigned int sz = 0, i;
32277
    int ret;
32278
32279
    session = ClientSessionToSession(session);
32280
    if (session == NULL) {
32281
        return WOLFSSL_FAILURE;
32282
    }
32283
32284
    if (wolfSSL_BIO_printf(bp, "%s\n", "SSL-Session:") <= 0)
32285
        return WOLFSSL_FAILURE;
32286
32287
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
32288
                               defined(HAVE_SESSION_TICKET))
32289
    if (wolfSSL_BIO_printf(bp, "    Protocol  : %s\n",
32290
            wolfSSL_SESSION_get_protocol(session)) <= 0)
32291
        return WOLFSSL_FAILURE;
32292
#endif
32293
32294
    if (wolfSSL_BIO_printf(bp, "    Cipher    : %s\n",
32295
            wolfSSL_SESSION_CIPHER_get_name(session)) <= 0)
32296
        return WOLFSSL_FAILURE;
32297
32298
    pt = wolfSSL_SESSION_get_id(session, &sz);
32299
    if (wolfSSL_BIO_printf(bp, "    Session-ID: ") <= 0)
32300
        return WOLFSSL_FAILURE;
32301
32302
    for (i = 0; i < sz; i++) {
32303
        if (wolfSSL_BIO_printf(bp, "%02X", pt[i]) <= 0)
32304
            return WOLFSSL_FAILURE;
32305
    }
32306
    if (wolfSSL_BIO_printf(bp, "\n") <= 0)
32307
        return WOLFSSL_FAILURE;
32308
32309
    if (wolfSSL_BIO_printf(bp, "    Session-ID-ctx: \n") <= 0)
32310
        return WOLFSSL_FAILURE;
32311
32312
    ret = wolfSSL_SESSION_get_master_key(session, buf, sizeof(buf));
32313
    if (wolfSSL_BIO_printf(bp, "    Master-Key: ") <= 0)
32314
        return WOLFSSL_FAILURE;
32315
32316
    if (ret > 0) {
32317
        sz = (unsigned int)ret;
32318
        for (i = 0; i < sz; i++) {
32319
            if (wolfSSL_BIO_printf(bp, "%02X", buf[i]) <= 0)
32320
                return WOLFSSL_FAILURE;
32321
        }
32322
    }
32323
    if (wolfSSL_BIO_printf(bp, "\n") <= 0)
32324
        return WOLFSSL_FAILURE;
32325
32326
    /* @TODO PSK identity hint and SRP */
32327
32328
    if (wolfSSL_BIO_printf(bp, "    TLS session ticket:") <= 0)
32329
        return WOLFSSL_FAILURE;
32330
32331
#ifdef HAVE_SESSION_TICKET
32332
    if (wolfSSL_SESSION_print_ticket(bp, session, "    ") != WOLFSSL_SUCCESS)
32333
        return WOLFSSL_FAILURE;
32334
#endif
32335
32336
#if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
32337
        defined(HAVE_EXT_CACHE))
32338
    if (wolfSSL_BIO_printf(bp, "    Start Time: %ld\n",
32339
                wolfSSL_SESSION_get_time(session)) <= 0)
32340
        return WOLFSSL_FAILURE;
32341
32342
    if (wolfSSL_BIO_printf(bp, "    Timeout   : %ld (sec)\n",
32343
            wolfSSL_SESSION_get_timeout(session)) <= 0)
32344
        return WOLFSSL_FAILURE;
32345
#endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
32346
32347
    /* @TODO verify return code print */
32348
32349
    if (wolfSSL_BIO_printf(bp, "    Extended master secret: %s\n",
32350
            (wolfSSL_SESSION_haveEMS(session) == 0)? "no" : "yes") <= 0)
32351
        return WOLFSSL_FAILURE;
32352
32353
    return WOLFSSL_SUCCESS;
32354
}
32355
32356
#endif /* !NO_BIO */
32357
#endif /* (HAVE_SESSION_TICKET || SESSION_CERTS) && !NO_FILESYSTEM */
32358
32359
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
32360
32361
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
32362
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
32363
32364
/* TODO: Doesn't currently track SSL_VERIFY_CLIENT_ONCE */
32365
int wolfSSL_get_verify_mode(const WOLFSSL* ssl) {
32366
    int mode = 0;
32367
    WOLFSSL_ENTER("wolfSSL_get_verify_mode");
32368
32369
    if (!ssl) {
32370
        return WOLFSSL_FAILURE;
32371
    }
32372
32373
    if (ssl->options.verifyNone) {
32374
        mode = WOLFSSL_VERIFY_NONE;
32375
    }
32376
    else {
32377
        if (ssl->options.verifyPeer) {
32378
            mode |= WOLFSSL_VERIFY_PEER;
32379
        }
32380
        if (ssl->options.failNoCert) {
32381
            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
32382
        }
32383
        if (ssl->options.failNoCertxPSK) {
32384
            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
32385
        }
32386
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
32387
        if (ssl->options.verifyPostHandshake) {
32388
            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
32389
        }
32390
#endif
32391
    }
32392
32393
    WOLFSSL_LEAVE("wolfSSL_get_verify_mode", mode);
32394
    return mode;
32395
}
32396
32397
int wolfSSL_CTX_get_verify_mode(const WOLFSSL_CTX* ctx)
32398
{
32399
    int mode = 0;
32400
    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
32401
32402
    if (!ctx) {
32403
        return WOLFSSL_FAILURE;
32404
    }
32405
32406
    if (ctx->verifyNone) {
32407
        mode = WOLFSSL_VERIFY_NONE;
32408
    }
32409
    else {
32410
        if (ctx->verifyPeer) {
32411
            mode |= WOLFSSL_VERIFY_PEER;
32412
        }
32413
        if (ctx->failNoCert) {
32414
            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
32415
        }
32416
        if (ctx->failNoCertxPSK) {
32417
            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
32418
        }
32419
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
32420
        if (ctx->verifyPostHandshake) {
32421
            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
32422
        }
32423
#endif
32424
    }
32425
32426
    WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
32427
    return mode;
32428
}
32429
32430
#endif
32431
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
32432
/* return 1 if success, 0 if error
32433
 * output keys are little endian format
32434
 */
32435
int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
32436
                                 unsigned char *pub, unsigned int *pubSz)
32437
{
32438
#ifndef WOLFSSL_KEY_GEN
32439
    WOLFSSL_MSG("No Key Gen built in");
32440
    (void) priv;
32441
    (void) privSz;
32442
    (void) pub;
32443
    (void) pubSz;
32444
    return WOLFSSL_FAILURE;
32445
#else /* WOLFSSL_KEY_GEN */
32446
    int ret = WOLFSSL_FAILURE;
32447
    int initTmpRng = 0;
32448
    WC_RNG *rng = NULL;
32449
#ifdef WOLFSSL_SMALL_STACK
32450
    WC_RNG *tmpRNG = NULL;
32451
#else
32452
    WC_RNG tmpRNG[1];
32453
#endif
32454
32455
    WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
32456
32457
    if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
32458
        pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
32459
        WOLFSSL_MSG("Bad arguments");
32460
        return WOLFSSL_FAILURE;
32461
    }
32462
32463
#ifdef WOLFSSL_SMALL_STACK
32464
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32465
    if (tmpRNG == NULL)
32466
        return WOLFSSL_FAILURE;
32467
#endif
32468
    if (wc_InitRng(tmpRNG) == 0) {
32469
        rng = tmpRNG;
32470
        initTmpRng = 1;
32471
    }
32472
    else {
32473
        WOLFSSL_MSG("Bad RNG Init, trying global");
32474
        if (initGlobalRNG == 0)
32475
            WOLFSSL_MSG("Global RNG no Init");
32476
        else
32477
            rng = &globalRNG;
32478
    }
32479
32480
    if (rng) {
32481
        curve25519_key key;
32482
32483
        if (wc_curve25519_init(&key) != MP_OKAY)
32484
            WOLFSSL_MSG("wc_curve25519_init failed");
32485
        else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
32486
            WOLFSSL_MSG("wc_curve25519_make_key failed");
32487
        /* export key pair */
32488
        else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
32489
                                                 pubSz, EC25519_LITTLE_ENDIAN)
32490
                 != MP_OKAY)
32491
            WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
32492
        else
32493
            ret = WOLFSSL_SUCCESS;
32494
32495
        wc_curve25519_free(&key);
32496
    }
32497
32498
    if (initTmpRng)
32499
        wc_FreeRng(tmpRNG);
32500
32501
#ifdef WOLFSSL_SMALL_STACK
32502
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32503
#endif
32504
32505
    return ret;
32506
#endif /* WOLFSSL_KEY_GEN */
32507
}
32508
32509
/* return 1 if success, 0 if error
32510
 * input and output keys are little endian format
32511
 */
32512
int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
32513
                               const unsigned char *priv, unsigned int privSz,
32514
                               const unsigned char *pub, unsigned int pubSz)
32515
{
32516
#ifndef WOLFSSL_KEY_GEN
32517
    WOLFSSL_MSG("No Key Gen built in");
32518
    (void) shared;
32519
    (void) sharedSz;
32520
    (void) priv;
32521
    (void) privSz;
32522
    (void) pub;
32523
    (void) pubSz;
32524
    return WOLFSSL_FAILURE;
32525
#else /* WOLFSSL_KEY_GEN */
32526
    int ret = WOLFSSL_FAILURE;
32527
    curve25519_key privkey, pubkey;
32528
32529
    WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
32530
32531
    if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
32532
        priv == NULL || privSz < CURVE25519_KEYSIZE ||
32533
        pub == NULL || pubSz < CURVE25519_KEYSIZE) {
32534
        WOLFSSL_MSG("Bad arguments");
32535
        return WOLFSSL_FAILURE;
32536
    }
32537
32538
    /* import private key */
32539
    if (wc_curve25519_init(&privkey) != MP_OKAY) {
32540
        WOLFSSL_MSG("wc_curve25519_init privkey failed");
32541
        return ret;
32542
    }
32543
    if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
32544
                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
32545
        WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
32546
        wc_curve25519_free(&privkey);
32547
        return ret;
32548
    }
32549
32550
    /* import public key */
32551
    if (wc_curve25519_init(&pubkey) != MP_OKAY) {
32552
        WOLFSSL_MSG("wc_curve25519_init pubkey failed");
32553
        wc_curve25519_free(&privkey);
32554
        return ret;
32555
    }
32556
    if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
32557
                                       EC25519_LITTLE_ENDIAN) != MP_OKAY) {
32558
        WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
32559
        wc_curve25519_free(&privkey);
32560
        wc_curve25519_free(&pubkey);
32561
        return ret;
32562
    }
32563
32564
    if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
32565
                                       shared, sharedSz,
32566
                                       EC25519_LITTLE_ENDIAN) != MP_OKAY)
32567
        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
32568
    else
32569
        ret = WOLFSSL_SUCCESS;
32570
32571
    wc_curve25519_free(&privkey);
32572
    wc_curve25519_free(&pubkey);
32573
32574
    return ret;
32575
#endif /* WOLFSSL_KEY_GEN */
32576
}
32577
#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
32578
32579
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
32580
/* return 1 if success, 0 if error
32581
 * output keys are little endian format
32582
 */
32583
int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
32584
                                 unsigned char *pub, unsigned int *pubSz)
32585
{
32586
#ifndef WOLFSSL_KEY_GEN
32587
    WOLFSSL_MSG("No Key Gen built in");
32588
    (void) priv;
32589
    (void) privSz;
32590
    (void) pub;
32591
    (void) pubSz;
32592
    return WOLFSSL_FAILURE;
32593
#elif !defined(HAVE_ED25519_KEY_EXPORT)
32594
    WOLFSSL_MSG("No ED25519 key export built in");
32595
    (void) priv;
32596
    (void) privSz;
32597
    (void) pub;
32598
    (void) pubSz;
32599
    return WOLFSSL_FAILURE;
32600
#else /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
32601
    int ret = WOLFSSL_FAILURE;
32602
    int initTmpRng = 0;
32603
    WC_RNG *rng = NULL;
32604
#ifdef WOLFSSL_SMALL_STACK
32605
    WC_RNG *tmpRNG = NULL;
32606
#else
32607
    WC_RNG tmpRNG[1];
32608
#endif
32609
32610
    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
32611
32612
    if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
32613
        pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
32614
        WOLFSSL_MSG("Bad arguments");
32615
        return WOLFSSL_FAILURE;
32616
    }
32617
32618
#ifdef WOLFSSL_SMALL_STACK
32619
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32620
    if (tmpRNG == NULL)
32621
        return WOLFSSL_FATAL_ERROR;
32622
#endif
32623
    if (wc_InitRng(tmpRNG) == 0) {
32624
        rng = tmpRNG;
32625
        initTmpRng = 1;
32626
    }
32627
    else {
32628
        WOLFSSL_MSG("Bad RNG Init, trying global");
32629
        if (initGlobalRNG == 0)
32630
            WOLFSSL_MSG("Global RNG no Init");
32631
        else
32632
            rng = &globalRNG;
32633
    }
32634
32635
    if (rng) {
32636
        ed25519_key key;
32637
32638
        if (wc_ed25519_init(&key) != MP_OKAY)
32639
            WOLFSSL_MSG("wc_ed25519_init failed");
32640
        else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
32641
            WOLFSSL_MSG("wc_ed25519_make_key failed");
32642
        /* export private key */
32643
        else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
32644
            WOLFSSL_MSG("wc_ed25519_export_key failed");
32645
        else
32646
            ret = WOLFSSL_SUCCESS;
32647
32648
        wc_ed25519_free(&key);
32649
    }
32650
32651
    if (initTmpRng)
32652
        wc_FreeRng(tmpRNG);
32653
32654
#ifdef WOLFSSL_SMALL_STACK
32655
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32656
#endif
32657
32658
    return ret;
32659
#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
32660
}
32661
32662
/* return 1 if success, 0 if error
32663
 * input and output keys are little endian format
32664
 * priv is a buffer containing private and public part of key
32665
 */
32666
int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
32667
                         const unsigned char *priv, unsigned int privSz,
32668
                         unsigned char *sig, unsigned int *sigSz)
32669
{
32670
#if !defined(HAVE_ED25519_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT)
32671
#if !defined(HAVE_ED25519_SIGN)
32672
    WOLFSSL_MSG("No ED25519 sign built in");
32673
#elif !defined(WOLFSSL_KEY_GEN)
32674
     WOLFSSL_MSG("No Key Gen built in");
32675
#elif !defined(HAVE_ED25519_KEY_IMPORT)
32676
     WOLFSSL_MSG("No ED25519 Key import built in");
32677
#endif
32678
    (void) msg;
32679
    (void) msgSz;
32680
    (void) priv;
32681
    (void) privSz;
32682
    (void) sig;
32683
    (void) sigSz;
32684
    return WOLFSSL_FAILURE;
32685
#else /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32686
    ed25519_key key;
32687
    int ret = WOLFSSL_FAILURE;
32688
32689
    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
32690
32691
    if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
32692
        msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
32693
        WOLFSSL_MSG("Bad arguments");
32694
        return WOLFSSL_FAILURE;
32695
    }
32696
32697
    /* import key */
32698
    if (wc_ed25519_init(&key) != MP_OKAY) {
32699
        WOLFSSL_MSG("wc_curve25519_init failed");
32700
        return ret;
32701
    }
32702
    if (wc_ed25519_import_private_key(priv, privSz/2,
32703
                                      priv+(privSz/2), ED25519_PUB_KEY_SIZE,
32704
                                      &key) != MP_OKAY){
32705
        WOLFSSL_MSG("wc_ed25519_import_private failed");
32706
        wc_ed25519_free(&key);
32707
        return ret;
32708
    }
32709
32710
    if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
32711
        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
32712
    else
32713
        ret = WOLFSSL_SUCCESS;
32714
32715
    wc_ed25519_free(&key);
32716
32717
    return ret;
32718
#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32719
}
32720
32721
/* return 1 if success, 0 if error
32722
 * input and output keys are little endian format
32723
 * pub is a buffer containing public part of key
32724
 */
32725
int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
32726
                           const unsigned char *pub, unsigned int pubSz,
32727
                           const unsigned char *sig, unsigned int sigSz)
32728
{
32729
#if !defined(HAVE_ED25519_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT)
32730
#if !defined(HAVE_ED25519_VERIFY)
32731
    WOLFSSL_MSG("No ED25519 verify built in");
32732
#elif !defined(WOLFSSL_KEY_GEN)
32733
     WOLFSSL_MSG("No Key Gen built in");
32734
#elif !defined(HAVE_ED25519_KEY_IMPORT)
32735
     WOLFSSL_MSG("No ED25519 Key import built in");
32736
#endif
32737
    (void) msg;
32738
    (void) msgSz;
32739
    (void) pub;
32740
    (void) pubSz;
32741
    (void) sig;
32742
    (void) sigSz;
32743
    return WOLFSSL_FAILURE;
32744
#else /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32745
    ed25519_key key;
32746
    int ret = WOLFSSL_FAILURE, check = 0;
32747
32748
    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
32749
32750
    if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
32751
        msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
32752
        WOLFSSL_MSG("Bad arguments");
32753
        return WOLFSSL_FAILURE;
32754
    }
32755
32756
    /* import key */
32757
    if (wc_ed25519_init(&key) != MP_OKAY) {
32758
        WOLFSSL_MSG("wc_curve25519_init failed");
32759
        return ret;
32760
    }
32761
    if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
32762
        WOLFSSL_MSG("wc_ed25519_import_public failed");
32763
        wc_ed25519_free(&key);
32764
        return ret;
32765
    }
32766
32767
    if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
32768
                                     &check, &key)) != MP_OKAY) {
32769
        WOLFSSL_MSG("wc_ed25519_verify_msg failed");
32770
    }
32771
    else if (!check)
32772
        WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
32773
    else
32774
        ret = WOLFSSL_SUCCESS;
32775
32776
    wc_ed25519_free(&key);
32777
32778
    return ret;
32779
#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32780
}
32781
32782
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
32783
32784
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
32785
/* return 1 if success, 0 if error
32786
 * output keys are little endian format
32787
 */
32788
int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
32789
                               unsigned char *pub, unsigned int *pubSz)
32790
{
32791
#ifndef WOLFSSL_KEY_GEN
32792
    WOLFSSL_MSG("No Key Gen built in");
32793
    (void) priv;
32794
    (void) privSz;
32795
    (void) pub;
32796
    (void) pubSz;
32797
    return WOLFSSL_FAILURE;
32798
#else /* WOLFSSL_KEY_GEN */
32799
    int ret = WOLFSSL_FAILURE;
32800
    int initTmpRng = 0;
32801
    WC_RNG *rng = NULL;
32802
#ifdef WOLFSSL_SMALL_STACK
32803
    WC_RNG *tmpRNG = NULL;
32804
#else
32805
    WC_RNG tmpRNG[1];
32806
#endif
32807
32808
    WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
32809
32810
    if (priv == NULL || privSz == NULL || *privSz < CURVE448_KEY_SIZE ||
32811
        pub == NULL || pubSz == NULL || *pubSz < CURVE448_KEY_SIZE) {
32812
        WOLFSSL_MSG("Bad arguments");
32813
        return WOLFSSL_FAILURE;
32814
    }
32815
32816
#ifdef WOLFSSL_SMALL_STACK
32817
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32818
    if (tmpRNG == NULL)
32819
        return WOLFSSL_FAILURE;
32820
#endif
32821
    if (wc_InitRng(tmpRNG) == 0) {
32822
        rng = tmpRNG;
32823
        initTmpRng = 1;
32824
    }
32825
    else {
32826
        WOLFSSL_MSG("Bad RNG Init, trying global");
32827
        if (initGlobalRNG == 0)
32828
            WOLFSSL_MSG("Global RNG no Init");
32829
        else
32830
            rng = &globalRNG;
32831
    }
32832
32833
    if (rng) {
32834
        curve448_key key;
32835
32836
        if (wc_curve448_init(&key) != MP_OKAY)
32837
            WOLFSSL_MSG("wc_curve448_init failed");
32838
        else if (wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key)!=MP_OKAY)
32839
            WOLFSSL_MSG("wc_curve448_make_key failed");
32840
        /* export key pair */
32841
        else if (wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
32842
                                               EC448_LITTLE_ENDIAN)
32843
                 != MP_OKAY)
32844
            WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
32845
        else
32846
            ret = WOLFSSL_SUCCESS;
32847
32848
        wc_curve448_free(&key);
32849
    }
32850
32851
    if (initTmpRng)
32852
        wc_FreeRng(tmpRNG);
32853
32854
#ifdef WOLFSSL_SMALL_STACK
32855
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32856
#endif
32857
32858
    return ret;
32859
#endif /* WOLFSSL_KEY_GEN */
32860
}
32861
32862
/* return 1 if success, 0 if error
32863
 * input and output keys are little endian format
32864
 */
32865
int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
32866
                             const unsigned char *priv, unsigned int privSz,
32867
                             const unsigned char *pub, unsigned int pubSz)
32868
{
32869
#ifndef WOLFSSL_KEY_GEN
32870
    WOLFSSL_MSG("No Key Gen built in");
32871
    (void) shared;
32872
    (void) sharedSz;
32873
    (void) priv;
32874
    (void) privSz;
32875
    (void) pub;
32876
    (void) pubSz;
32877
    return WOLFSSL_FAILURE;
32878
#else /* WOLFSSL_KEY_GEN */
32879
    int ret = WOLFSSL_FAILURE;
32880
    curve448_key privkey, pubkey;
32881
32882
    WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
32883
32884
    if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE448_KEY_SIZE ||
32885
            priv == NULL || privSz < CURVE448_KEY_SIZE ||
32886
            pub == NULL || pubSz < CURVE448_KEY_SIZE) {
32887
        WOLFSSL_MSG("Bad arguments");
32888
        return WOLFSSL_FAILURE;
32889
    }
32890
32891
    /* import private key */
32892
    if (wc_curve448_init(&privkey) != MP_OKAY) {
32893
        WOLFSSL_MSG("wc_curve448_init privkey failed");
32894
        return ret;
32895
    }
32896
    if (wc_curve448_import_private_ex(priv, privSz, &privkey,
32897
                                      EC448_LITTLE_ENDIAN) != MP_OKAY) {
32898
        WOLFSSL_MSG("wc_curve448_import_private_ex failed");
32899
        wc_curve448_free(&privkey);
32900
        return ret;
32901
    }
32902
32903
    /* import public key */
32904
    if (wc_curve448_init(&pubkey) != MP_OKAY) {
32905
        WOLFSSL_MSG("wc_curve448_init pubkey failed");
32906
        wc_curve448_free(&privkey);
32907
        return ret;
32908
    }
32909
    if (wc_curve448_import_public_ex(pub, pubSz, &pubkey,
32910
                                     EC448_LITTLE_ENDIAN) != MP_OKAY) {
32911
        WOLFSSL_MSG("wc_curve448_import_public_ex failed");
32912
        wc_curve448_free(&privkey);
32913
        wc_curve448_free(&pubkey);
32914
        return ret;
32915
    }
32916
32917
    if (wc_curve448_shared_secret_ex(&privkey, &pubkey, shared, sharedSz,
32918
                                     EC448_LITTLE_ENDIAN) != MP_OKAY)
32919
        WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
32920
    else
32921
        ret = WOLFSSL_SUCCESS;
32922
32923
    wc_curve448_free(&privkey);
32924
    wc_curve448_free(&pubkey);
32925
32926
    return ret;
32927
#endif /* WOLFSSL_KEY_GEN */
32928
}
32929
#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
32930
32931
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
32932
/* return 1 if success, 0 if error
32933
 * output keys are little endian format
32934
 */
32935
int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
32936
                               unsigned char *pub, unsigned int *pubSz)
32937
{
32938
#ifndef WOLFSSL_KEY_GEN
32939
    WOLFSSL_MSG("No Key Gen built in");
32940
    (void) priv;
32941
    (void) privSz;
32942
    (void) pub;
32943
    (void) pubSz;
32944
    return WOLFSSL_FAILURE;
32945
#elif !defined(HAVE_ED448_KEY_EXPORT)
32946
    WOLFSSL_MSG("No ED448 key export built in");
32947
    (void) priv;
32948
    (void) privSz;
32949
    (void) pub;
32950
    (void) pubSz;
32951
    return WOLFSSL_FAILURE;
32952
#else /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
32953
    int ret = WOLFSSL_FAILURE;
32954
    int initTmpRng = 0;
32955
    WC_RNG *rng = NULL;
32956
#ifdef WOLFSSL_SMALL_STACK
32957
    WC_RNG *tmpRNG = NULL;
32958
#else
32959
    WC_RNG tmpRNG[1];
32960
#endif
32961
32962
    WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
32963
32964
    if (priv == NULL || privSz == NULL || *privSz < ED448_PRV_KEY_SIZE ||
32965
            pub == NULL || pubSz == NULL || *pubSz < ED448_PUB_KEY_SIZE) {
32966
        WOLFSSL_MSG("Bad arguments");
32967
        return WOLFSSL_FAILURE;
32968
    }
32969
32970
#ifdef WOLFSSL_SMALL_STACK
32971
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32972
    if (tmpRNG == NULL)
32973
        return WOLFSSL_FATAL_ERROR;
32974
#endif
32975
    if (wc_InitRng(tmpRNG) == 0) {
32976
        rng = tmpRNG;
32977
        initTmpRng = 1;
32978
    }
32979
    else {
32980
        WOLFSSL_MSG("Bad RNG Init, trying global");
32981
        if (initGlobalRNG == 0)
32982
            WOLFSSL_MSG("Global RNG no Init");
32983
        else
32984
            rng = &globalRNG;
32985
    }
32986
32987
    if (rng) {
32988
        ed448_key key;
32989
32990
        if (wc_ed448_init(&key) != MP_OKAY)
32991
            WOLFSSL_MSG("wc_ed448_init failed");
32992
        else if (wc_ed448_make_key(rng, ED448_KEY_SIZE, &key) != MP_OKAY)
32993
            WOLFSSL_MSG("wc_ed448_make_key failed");
32994
        /* export private key */
32995
        else if (wc_ed448_export_key(&key, priv, privSz, pub, pubSz) != MP_OKAY)
32996
            WOLFSSL_MSG("wc_ed448_export_key failed");
32997
        else
32998
            ret = WOLFSSL_SUCCESS;
32999
33000
        wc_ed448_free(&key);
33001
    }
33002
33003
    if (initTmpRng)
33004
        wc_FreeRng(tmpRNG);
33005
33006
#ifdef WOLFSSL_SMALL_STACK
33007
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
33008
#endif
33009
33010
    return ret;
33011
#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
33012
}
33013
33014
/* return 1 if success, 0 if error
33015
 * input and output keys are little endian format
33016
 * priv is a buffer containing private and public part of key
33017
 */
33018
int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
33019
                       const unsigned char *priv, unsigned int privSz,
33020
                       unsigned char *sig, unsigned int *sigSz)
33021
{
33022
#if !defined(HAVE_ED448_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT)
33023
#if !defined(HAVE_ED448_SIGN)
33024
    WOLFSSL_MSG("No ED448 sign built in");
33025
#elif !defined(WOLFSSL_KEY_GEN)
33026
    WOLFSSL_MSG("No Key Gen built in");
33027
#elif !defined(HAVE_ED448_KEY_IMPORT)
33028
    WOLFSSL_MSG("No ED448 Key import built in");
33029
#endif
33030
    (void) msg;
33031
    (void) msgSz;
33032
    (void) priv;
33033
    (void) privSz;
33034
    (void) sig;
33035
    (void) sigSz;
33036
    return WOLFSSL_FAILURE;
33037
#else /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
33038
    ed448_key key;
33039
    int ret = WOLFSSL_FAILURE;
33040
33041
    WOLFSSL_ENTER("wolfSSL_ED448_sign");
33042
33043
    if (priv == NULL || privSz != ED448_PRV_KEY_SIZE || msg == NULL ||
33044
            sig == NULL || *sigSz < ED448_SIG_SIZE) {
33045
        WOLFSSL_MSG("Bad arguments");
33046
        return WOLFSSL_FAILURE;
33047
    }
33048
33049
    /* import key */
33050
    if (wc_ed448_init(&key) != MP_OKAY) {
33051
        WOLFSSL_MSG("wc_curve448_init failed");
33052
        return ret;
33053
    }
33054
    if (wc_ed448_import_private_key(priv, privSz/2, priv+(privSz/2),
33055
                                    ED448_PUB_KEY_SIZE, &key) != MP_OKAY){
33056
        WOLFSSL_MSG("wc_ed448_import_private failed");
33057
        wc_ed448_free(&key);
33058
        return ret;
33059
    }
33060
33061
    if (wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0) != MP_OKAY)
33062
        WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
33063
    else
33064
        ret = WOLFSSL_SUCCESS;
33065
33066
    wc_ed448_free(&key);
33067
33068
    return ret;
33069
#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
33070
}
33071
33072
/* return 1 if success, 0 if error
33073
 * input and output keys are little endian format
33074
 * pub is a buffer containing public part of key
33075
 */
33076
int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
33077
                         const unsigned char *pub, unsigned int pubSz,
33078
                         const unsigned char *sig, unsigned int sigSz)
33079
{
33080
#if !defined(HAVE_ED448_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT)
33081
#if !defined(HAVE_ED448_VERIFY)
33082
    WOLFSSL_MSG("No ED448 verify built in");
33083
#elif !defined(WOLFSSL_KEY_GEN)
33084
    WOLFSSL_MSG("No Key Gen built in");
33085
#elif !defined(HAVE_ED448_KEY_IMPORT)
33086
    WOLFSSL_MSG("No ED448 Key import built in");
33087
#endif
33088
    (void) msg;
33089
    (void) msgSz;
33090
    (void) pub;
33091
    (void) pubSz;
33092
    (void) sig;
33093
    (void) sigSz;
33094
    return WOLFSSL_FAILURE;
33095
#else /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
33096
    ed448_key key;
33097
    int ret = WOLFSSL_FAILURE, check = 0;
33098
33099
    WOLFSSL_ENTER("wolfSSL_ED448_verify");
33100
33101
    if (pub == NULL || pubSz != ED448_PUB_KEY_SIZE || msg == NULL ||
33102
            sig == NULL || sigSz != ED448_SIG_SIZE) {
33103
        WOLFSSL_MSG("Bad arguments");
33104
        return WOLFSSL_FAILURE;
33105
    }
33106
33107
    /* import key */
33108
    if (wc_ed448_init(&key) != MP_OKAY) {
33109
        WOLFSSL_MSG("wc_curve448_init failed");
33110
        return ret;
33111
    }
33112
    if (wc_ed448_import_public(pub, pubSz, &key) != MP_OKAY){
33113
        WOLFSSL_MSG("wc_ed448_import_public failed");
33114
        wc_ed448_free(&key);
33115
        return ret;
33116
    }
33117
33118
    if ((ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
33119
                                   &key, NULL, 0)) != MP_OKAY) {
33120
        WOLFSSL_MSG("wc_ed448_verify_msg failed");
33121
    }
33122
    else if (!check)
33123
        WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
33124
    else
33125
        ret = WOLFSSL_SUCCESS;
33126
33127
    wc_ed448_free(&key);
33128
33129
    return ret;
33130
#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN */
33131
}
33132
33133
#endif /* OPENSSL_EXTRA && HAVE_ED448 */
33134
33135
#ifdef WOLFSSL_JNI
33136
33137
int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
33138
{
33139
    WOLFSSL_ENTER("wolfSSL_set_jobject");
33140
    if (ssl != NULL)
33141
    {
33142
        ssl->jObjectRef = objPtr;
33143
        return WOLFSSL_SUCCESS;
33144
    }
33145
    return WOLFSSL_FAILURE;
33146
}
33147
33148
void* wolfSSL_get_jobject(WOLFSSL* ssl)
33149
{
33150
    WOLFSSL_ENTER("wolfSSL_get_jobject");
33151
    if (ssl != NULL)
33152
        return ssl->jObjectRef;
33153
    return NULL;
33154
}
33155
33156
#endif /* WOLFSSL_JNI */
33157
33158
33159
#ifdef WOLFSSL_ASYNC_CRYPT
33160
int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
33161
    WOLF_EVENT_FLAG flags, int* eventCount)
33162
{
33163
    if (ctx == NULL) {
33164
        return BAD_FUNC_ARG;
33165
    }
33166
33167
    return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
33168
                                        events, maxEvents, flags, eventCount);
33169
}
33170
33171
int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
33172
{
33173
    int ret, eventCount = 0;
33174
    WOLF_EVENT* events[1];
33175
33176
    if (ssl == NULL) {
33177
        return BAD_FUNC_ARG;
33178
    }
33179
33180
    ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
33181
        events, sizeof(events)/sizeof(events[0]), flags, &eventCount);
33182
    if (ret == 0) {
33183
        ret = eventCount;
33184
    }
33185
33186
    return ret;
33187
}
33188
#endif /* WOLFSSL_ASYNC_CRYPT */
33189
33190
#ifdef OPENSSL_EXTRA
33191
unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
33192
                                               const char **data, int *flags)
33193
{
33194
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
33195
33196
    (void)line;
33197
    (void)file;
33198
33199
    /* No data or flags stored - error display only in Nginx. */
33200
    if (data != NULL) {
33201
        *data = "";
33202
    }
33203
    if (flags != NULL) {
33204
        *flags = 0;
33205
    }
33206
33207
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
33208
    {
33209
        int ret = 0;
33210
33211
        while (1) {
33212
            ret = wc_PeekErrorNode(0, file, NULL, line);
33213
            if (ret == BAD_MUTEX_E || ret == BAD_FUNC_ARG || ret == BAD_STATE_E) {
33214
                WOLFSSL_MSG("Issue peeking at error node in queue");
33215
                return 0;
33216
            }
33217
            /* OpenSSL uses positive error codes */
33218
            if (ret < 0) {
33219
                ret = -ret;
33220
            }
33221
33222
            if (ret == -ASN_NO_PEM_HEADER)
33223
                return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
33224
        #ifdef OPENSSL_ALL
33225
            /* PARSE_ERROR is returned if an HTTP request is detected. */
33226
            if (ret == -SSL_R_HTTP_REQUEST)
33227
                return (ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST;
33228
        #endif
33229
        #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
33230
            if (ret == ASN1_R_HEADER_TOO_LONG) {
33231
                return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
33232
            }
33233
        #endif
33234
            if (ret != -WANT_READ && ret != -WANT_WRITE &&
33235
                    ret != -ZERO_RETURN && ret != -WOLFSSL_ERROR_ZERO_RETURN &&
33236
                    ret != -SOCKET_PEER_CLOSED_E && ret != -SOCKET_ERROR_E)
33237
                break;
33238
33239
            wc_RemoveErrorNode(0);
33240
        }
33241
33242
        return (unsigned long)ret;
33243
    }
33244
#else
33245
    return (unsigned long)(0 - NOT_COMPILED_IN);
33246
#endif
33247
}
33248
#endif
33249
33250
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
33251
33252
#if !defined(WOLFSSL_USER_IO)
33253
/* converts an IPv6 or IPv4 address into an octet string for use with rfc3280
33254
 * example input would be "127.0.0.1" and the returned value would be 7F000001
33255
 */
33256
WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa)
33257
{
33258
    int ipaSz = WOLFSSL_IP4_ADDR_LEN;
33259
    char buf[WOLFSSL_IP6_ADDR_LEN + 1]; /* plus 1 for terminator */
33260
    int  af = WOLFSSL_IP4;
33261
    WOLFSSL_ASN1_STRING *ret = NULL;
33262
33263
    if (ipa == NULL)
33264
        return NULL;
33265
33266
    if (XSTRSTR(ipa, ":") != NULL) {
33267
        af = WOLFSSL_IP6;
33268
        ipaSz = WOLFSSL_IP6_ADDR_LEN;
33269
    }
33270
33271
    buf[WOLFSSL_IP6_ADDR_LEN] = '\0';
33272
    if (XINET_PTON(af, ipa, (void*)buf) != 1) {
33273
        WOLFSSL_MSG("Error parsing IP address");
33274
        return NULL;
33275
    }
33276
33277
    ret = wolfSSL_ASN1_STRING_new();
33278
    if (ret != NULL) {
33279
        if (wolfSSL_ASN1_STRING_set(ret, buf, ipaSz) != WOLFSSL_SUCCESS) {
33280
            WOLFSSL_MSG("Error setting the string");
33281
            wolfSSL_ASN1_STRING_free(ret);
33282
            ret = NULL;
33283
        }
33284
    }
33285
33286
    return ret;
33287
}
33288
#endif /* !WOLFSSL_USER_IO */
33289
33290
/* Is the specified cipher suite a fake one used an an extension proxy? */
33291
static WC_INLINE int SCSV_Check(byte suite0, byte suite)
33292
{
33293
    (void)suite0;
33294
    (void)suite;
33295
#ifdef HAVE_RENEGOTIATION_INDICATION
33296
    if (suite0 == CIPHER_BYTE && suite == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
33297
        return 1;
33298
#endif
33299
    return 0;
33300
}
33301
33302
static WC_INLINE int sslCipherMinMaxCheck(const WOLFSSL *ssl, byte suite0,
33303
        byte suite)
33304
{
33305
    const CipherSuiteInfo* cipher_names = GetCipherNames();
33306
    int cipherSz = GetCipherNamesSize();
33307
    int i;
33308
    for (i = 0; i < cipherSz; i++)
33309
        if (cipher_names[i].cipherSuite0 == suite0 &&
33310
                cipher_names[i].cipherSuite == suite)
33311
            break;
33312
    if (i == cipherSz)
33313
        return 1;
33314
    /* Check min version */
33315
    if (cipher_names[i].minor < ssl->options.minDowngrade) {
33316
        if (ssl->options.minDowngrade <= TLSv1_2_MINOR &&
33317
                cipher_names[i].minor >= TLSv1_MINOR)
33318
            /* 1.0 ciphersuites are in general available in 1.1 and
33319
             * 1.1 ciphersuites are in general available in 1.2 */
33320
            return 0;
33321
        return 1;
33322
    }
33323
    /* Check max version */
33324
    switch (cipher_names[i].minor) {
33325
    case SSLv3_MINOR :
33326
        return ssl->options.mask & WOLFSSL_OP_NO_SSLv3;
33327
    case TLSv1_MINOR :
33328
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1;
33329
    case TLSv1_1_MINOR :
33330
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1;
33331
    case TLSv1_2_MINOR :
33332
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2;
33333
    case TLSv1_3_MINOR :
33334
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3;
33335
    default:
33336
        WOLFSSL_MSG("Unrecognized minor version");
33337
        return 1;
33338
    }
33339
}
33340
33341
/* returns a pointer to internal cipher suite list. Should not be free'd by
33342
 * caller.
33343
 */
33344
WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
33345
{
33346
    WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
33347
    Suites* suites;
33348
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
33349
    const CipherSuiteInfo* cipher_names = GetCipherNames();
33350
    int cipherSz = GetCipherNamesSize();
33351
#endif
33352
33353
    WOLFSSL_ENTER("wolfSSL_get_ciphers_compat");
33354
    if (ssl == NULL || (ssl->suites == NULL && ssl->ctx->suites == NULL)) {
33355
        return NULL;
33356
    }
33357
33358
    if (ssl->suites != NULL) {
33359
        if (ssl->suites->suiteSz == 0 &&
33360
                InitSSL_Suites((WOLFSSL*)ssl) != WOLFSSL_SUCCESS) {
33361
            WOLFSSL_MSG("Suite initialization failure");
33362
            return NULL;
33363
        }
33364
        suites = ssl->suites;
33365
    }
33366
    else {
33367
        suites = ssl->ctx->suites;
33368
    }
33369
33370
    /* check if stack needs populated */
33371
    if (suites->stack == NULL) {
33372
        int i;
33373
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
33374
        int j;
33375
33376
        /* higher priority of cipher suite will be on top of stack */
33377
        for (i = suites->suiteSz - 2; i >=0; i-=2) {
33378
#else
33379
        for (i = 0; i < suites->suiteSz; i+=2) {
33380
#endif
33381
            WOLFSSL_STACK* add;
33382
33383
            /* A couple of suites are placeholders for special options,
33384
             * skip those. */
33385
            if (SCSV_Check(suites->suites[i], suites->suites[i+1])
33386
                    || sslCipherMinMaxCheck(ssl, suites->suites[i],
33387
                                            suites->suites[i+1])) {
33388
                continue;
33389
            }
33390
33391
            add = wolfSSL_sk_new_node(ssl->heap);
33392
            if (add != NULL) {
33393
                add->type = STACK_TYPE_CIPHER;
33394
                add->data.cipher.cipherSuite0 = suites->suites[i];
33395
                add->data.cipher.cipherSuite  = suites->suites[i+1];
33396
                add->data.cipher.ssl          = ssl;
33397
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
33398
                for (j = 0; j < cipherSz; j++) {
33399
                    if (cipher_names[j].cipherSuite0 ==
33400
                            add->data.cipher.cipherSuite0 &&
33401
                            cipher_names[j].cipherSuite ==
33402
                                    add->data.cipher.cipherSuite) {
33403
                        add->data.cipher.offset = j;
33404
                        break;
33405
                    }
33406
                }
33407
#endif
33408
                #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
33409
                /* in_stack is checked in wolfSSL_CIPHER_description */
33410
                add->data.cipher.in_stack     = 1;
33411
                #endif
33412
33413
                add->next = ret;
33414
                if (ret != NULL) {
33415
                    add->num = ret->num + 1;
33416
                }
33417
                else {
33418
                    add->num = 1;
33419
                }
33420
                ret = add;
33421
            }
33422
        }
33423
        suites->stack = ret;
33424
    }
33425
    return suites->stack;
33426
}
33427
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
33428
33429
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
33430
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || defined(HAVE_SECRET_CALLBACK)
33431
long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
33432
{
33433
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
33434
33435
    if (ctx == NULL)
33436
        return 0;
33437
33438
    return ctx->timeout;
33439
}
33440
33441
33442
/* returns the time in seconds of the current timeout */
33443
long wolfSSL_get_timeout(WOLFSSL* ssl)
33444
{
33445
    WOLFSSL_ENTER("wolfSSL_get_timeout");
33446
33447
    if (ssl == NULL)
33448
        return 0;
33449
    return ssl->timeout;
33450
}
33451
#endif
33452
33453
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
33454
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
33455
33456
#ifdef HAVE_ECC
33457
int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
33458
{
33459
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
33460
33461
    if (ctx == NULL || ecdh == NULL)
33462
        return BAD_FUNC_ARG;
33463
33464
    ctx->ecdhCurveOID = ecdh->group->curve_oid;
33465
33466
    return WOLFSSL_SUCCESS;
33467
}
33468
#endif
33469
33470
/* Assumes that the session passed in is from the cache. */
33471
int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
33472
{
33473
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
33474
33475
    s = ClientSessionToSession(s);
33476
    if (ctx == NULL || s == NULL)
33477
        return BAD_FUNC_ARG;
33478
33479
#ifdef HAVE_EXT_CACHE
33480
    if (!ctx->internalCacheOff)
33481
#endif
33482
    {
33483
        /* Don't remove session just timeout session. */
33484
        s->timeout = 0;
33485
#ifndef NO_SESSION_CACHE
33486
        /* Clear the timeout in the cache */
33487
        {
33488
            int row;
33489
            int i;
33490
            SessionRow* sessRow = NULL;
33491
            WOLFSSL_SESSION *cacheSession;
33492
            const byte* id;
33493
            int ret = 0;
33494
33495
            id = s->sessionID;
33496
            if (s->haveAltSessionID)
33497
                id = s->altSessionID;
33498
33499
            row = (int)(HashObject(id, ID_LEN, &ret) % SESSION_ROWS);
33500
            if (ret != 0) {
33501
                WOLFSSL_MSG("Hash session failed");
33502
                return ret;
33503
            }
33504
33505
            sessRow = &SessionCache[row];
33506
            if (SESSION_ROW_LOCK(sessRow) != 0) {
33507
                WOLFSSL_MSG("Session row lock failed");
33508
                return BAD_MUTEX_E;
33509
            }
33510
33511
            for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
33512
                cacheSession = &sessRow->Sessions[i];
33513
                if (XMEMCMP(id, cacheSession->sessionID, ID_LEN) == 0) {
33514
                    if (ctx->method->side != cacheSession->side)
33515
                        continue;
33516
                    cacheSession->timeout = 0;
33517
#ifdef HAVE_EX_DATA
33518
                    if (cacheSession->ownExData) {
33519
                        /* Most recent version of ex data is in cache. Copy it
33520
                         * over so the user can free it. */
33521
                        XMEMCPY(&s->ex_data, &cacheSession->ex_data,
33522
                                sizeof(WOLFSSL_CRYPTO_EX_DATA));
33523
                    }
33524
                    cacheSession->ownExData = 0; /* We clear below */
33525
                    s->ownExData = 1;
33526
#endif
33527
                    break;
33528
                }
33529
            }
33530
            SESSION_ROW_UNLOCK(sessRow);
33531
        }
33532
#endif
33533
    }
33534
33535
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
33536
    if (ctx->rem_sess_cb != NULL) {
33537
        ctx->rem_sess_cb(ctx, s);
33538
    }
33539
#endif
33540
33541
    return 0;
33542
}
33543
33544
#ifndef NO_BIO
33545
BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
33546
{
33547
    WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
33548
    /* Nginx sets the buffer size if the read BIO is different to write BIO.
33549
     * The setting buffer size doesn't do anything so return NULL for both.
33550
     */
33551
    if (s == NULL)
33552
        return NULL;
33553
33554
    return s->biord;
33555
}
33556
BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
33557
{
33558
    WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
33559
    (void)s;
33560
    /* Nginx sets the buffer size if the read BIO is different to write BIO.
33561
     * The setting buffer size doesn't do anything so return NULL for both.
33562
     */
33563
    if (s == NULL)
33564
        return NULL;
33565
33566
    return s->biowr;
33567
}
33568
#endif /* !NO_BIO */
33569
33570
int wolfSSL_SSL_do_handshake(WOLFSSL *s)
33571
{
33572
    WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
33573
33574
    if (s == NULL)
33575
        return WOLFSSL_FAILURE;
33576
33577
    if (s->options.side == WOLFSSL_CLIENT_END) {
33578
    #ifndef NO_WOLFSSL_CLIENT
33579
        return wolfSSL_connect(s);
33580
    #else
33581
        WOLFSSL_MSG("Client not compiled in");
33582
        return WOLFSSL_FAILURE;
33583
    #endif
33584
    }
33585
33586
#ifndef NO_WOLFSSL_SERVER
33587
    return wolfSSL_accept(s);
33588
#else
33589
    WOLFSSL_MSG("Server not compiled in");
33590
    return WOLFSSL_FAILURE;
33591
#endif
33592
}
33593
33594
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
33595
int wolfSSL_SSL_in_init(const WOLFSSL *ssl)
33596
#else
33597
int wolfSSL_SSL_in_init(WOLFSSL *ssl)
33598
#endif
33599
{
33600
    WOLFSSL_ENTER("SSL_in_init");
33601
33602
    if (ssl == NULL)
33603
        return WOLFSSL_FAILURE;
33604
33605
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
33606
        return ssl->options.connectState < SECOND_REPLY_DONE;
33607
    }
33608
    return ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
33609
}
33610
33611
int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)
33612
{
33613
    WOLFSSL_ENTER("SSL_connect_init");
33614
33615
    if (ssl == NULL)
33616
        return WOLFSSL_FAILURE;
33617
33618
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
33619
        return ssl->options.connectState > CONNECT_BEGIN &&
33620
            ssl->options.connectState < SECOND_REPLY_DONE;
33621
    }
33622
33623
    return ssl->options.acceptState > ACCEPT_BEGIN &&
33624
        ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
33625
}
33626
33627
#ifndef NO_SESSION_CACHE
33628
33629
WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
33630
{
33631
    WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
33632
33633
    return ssl->session;
33634
}
33635
33636
#endif /* NO_SESSION_CACHE */
33637
33638
#ifndef NO_BIO
33639
int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1,
33640
        char *buf, int size)
33641
{
33642
    int readNextLine;
33643
    int lineLen;
33644
    int len;
33645
    byte isNumCheck;
33646
    word32 outLen;
33647
    const int extraTagSz = MAX_LENGTH_SZ + 1;
33648
    byte intTag[MAX_LENGTH_SZ + 1];
33649
    int idx = 0;
33650
33651
    WOLFSSL_ENTER("wolfSSL_a2i_ASN1_INTEGER");
33652
33653
    if (!bio || !asn1 || !buf || size <= 0) {
33654
        WOLFSSL_MSG("Bad parameter");
33655
        return WOLFSSL_FAILURE;
33656
    }
33657
33658
    /* Reset asn1 */
33659
    if (asn1->isDynamic && asn1->data) {
33660
        XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
33661
    }
33662
    XMEMSET(asn1->intData, 0, WOLFSSL_ASN1_INTEGER_MAX);
33663
    asn1->data = asn1->intData;
33664
    asn1->isDynamic = 0;
33665
    asn1->length = 0;
33666
    asn1->negative = 0;
33667
    asn1->type = V_ASN1_INTEGER;
33668
33669
    lineLen = wolfSSL_BIO_gets(bio, buf, size);
33670
    do {
33671
        readNextLine = 0;
33672
        if (lineLen <= 0) {
33673
            WOLFSSL_MSG("wolfSSL_BIO_gets error");
33674
            return WOLFSSL_FAILURE;
33675
        }
33676
        while (lineLen && (buf[lineLen-1] == '\n' || buf[lineLen-1] == '\r'))
33677
            lineLen--;
33678
        if (buf[lineLen-1] == '\\')
33679
            readNextLine = 1;
33680
        /* Ignore none-hex chars at the end of the line */
33681
        outLen = 1;
33682
        while (lineLen && Base16_Decode((byte*)buf + lineLen - 1, 1,
33683
                &isNumCheck, &outLen) == ASN_INPUT_E)
33684
            lineLen--;
33685
        if (!lineLen || lineLen % 2) {
33686
            WOLFSSL_MSG("Invalid line length");
33687
            return WOLFSSL_FAILURE;
33688
        }
33689
        len = asn1->length + (lineLen/2);
33690
        /* Check if it will fit in static memory and
33691
         * save space for the ASN tag in front */
33692
        if (len > (int)(WOLFSSL_ASN1_INTEGER_MAX - extraTagSz)) {
33693
            /* Allocate mem for data */
33694
            if (asn1->isDynamic) {
33695
                byte* tmp = (byte*)XREALLOC(asn1->data, len + extraTagSz, NULL,
33696
                        DYNAMIC_TYPE_OPENSSL);
33697
                if (!tmp) {
33698
                    WOLFSSL_MSG("realloc error");
33699
                    return WOLFSSL_FAILURE;
33700
                }
33701
                asn1->data = tmp;
33702
            }
33703
            else {
33704
                /* Up to this point asn1->data pointed to asn1->intData.
33705
                 * Now that the size has grown larger than intData can handle
33706
                 * the asn1 structure moves to a dynamic type with isDynamic
33707
                 * flag being set and asn1->data being malloc'd. */
33708
                asn1->data = (byte*)XMALLOC(len + extraTagSz, NULL,
33709
                        DYNAMIC_TYPE_OPENSSL);
33710
                if (!asn1->data) {
33711
                    WOLFSSL_MSG("malloc error");
33712
                    return WOLFSSL_FAILURE;
33713
                }
33714
                asn1->isDynamic = 1;
33715
                XMEMCPY(asn1->data, asn1->intData, asn1->length);
33716
            }
33717
        }
33718
        len = lineLen/2;
33719
        if (Base16_Decode((byte*)buf, lineLen, asn1->data + asn1->length,
33720
                (word32*)&len) != 0) {
33721
            WOLFSSL_MSG("Base16_Decode error");
33722
            return WOLFSSL_FAILURE;
33723
        }
33724
        asn1->length += len;
33725
    } while (readNextLine);
33726
33727
    /* Write ASN tag */
33728
    idx = SetASNInt(asn1->length, asn1->data[0], intTag);
33729
    XMEMMOVE(asn1->data + idx, asn1->data, asn1->length);
33730
    XMEMCPY(asn1->data, intTag, idx);
33731
    asn1->dataMax = asn1->length += idx;
33732
33733
    return WOLFSSL_SUCCESS;
33734
}
33735
33736
int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a)
33737
{
33738
    word32 idx = 1;
33739
    int len = 0;
33740
    byte buf[512];
33741
    word32 bufLen = 512;
33742
33743
    WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER");
33744
33745
    if (bp == NULL || a == NULL)
33746
        return WOLFSSL_FAILURE;
33747
33748
    /* Skip ASN.1 INTEGER (type) byte. */
33749
    if (a->data[idx] == 0x80 || /* Indefinite length, can't determine length */
33750
            GetLength(a->data, &idx, &len, a->length) < 0) {
33751
        return 0;
33752
    }
33753
33754
    /* Zero length integer is the value zero. */
33755
    if (len == 0) {
33756
        return wolfSSL_BIO_write(bp, "00", 2);
33757
    }
33758
33759
    if (Base16_Encode(a->data + idx, len, buf, &bufLen) != 0 ||
33760
            bufLen == 0) {
33761
        return 0;
33762
    }
33763
33764
    return wolfSSL_BIO_write(bp, buf, bufLen - 1); /* Don't write out NULL char */
33765
}
33766
#endif /* !NO_BIO */
33767
33768
33769
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
33770
/* Expected return values from implementations of OpenSSL ticket key callback.
33771
 */
33772
#define TICKET_KEY_CB_RET_FAILURE    (-1)
33773
#define TICKET_KEY_CB_RET_NOT_FOUND   0
33774
#define TICKET_KEY_CB_RET_OK          1
33775
#define TICKET_KEY_CB_RET_RENEW       2
33776
33777
/* Implementation of session ticket encryption/decryption using OpenSSL
33778
 * callback to initialize the cipher and HMAC.
33779
 *
33780
 * ssl           The SSL/TLS object.
33781
 * keyName       The key name - used to identify the key to be used.
33782
 * iv            The IV to use.
33783
 * mac           The MAC of the encrypted data.
33784
 * enc           Encrypt ticket.
33785
 * encTicket     The ticket data.
33786
 * encTicketLen  The length of the ticket data.
33787
 * encLen        The encrypted/decrypted ticket length - output length.
33788
 * ctx           Ignored. Application specific data.
33789
 * returns WOLFSSL_TICKET_RET_OK to indicate success,
33790
 *         WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
33791
 *         WOLFSSL_TICKET_RET_FATAL on error.
33792
 */
33793
static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
33794
        unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
33795
        unsigned char iv[WOLFSSL_TICKET_IV_SZ],
33796
        unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
33797
        int enc, unsigned char* encTicket,
33798
        int encTicketLen, int* encLen, void* ctx)
33799
{
33800
    byte                    digest[WC_MAX_DIGEST_SIZE];
33801
#ifdef WOLFSSL_SMALL_STACK
33802
    WOLFSSL_EVP_CIPHER_CTX  *evpCtx;
33803
#else
33804
    WOLFSSL_EVP_CIPHER_CTX  evpCtx[1];
33805
#endif
33806
    WOLFSSL_HMAC_CTX        hmacCtx;
33807
    unsigned int            mdSz = 0;
33808
    int                     len = 0;
33809
    int                     ret = WOLFSSL_TICKET_RET_FATAL;
33810
    int                     res;
33811
    int                     totalSz = 0;
33812
33813
    (void)ctx;
33814
33815
    WOLFSSL_ENTER("wolfSSL_TicketKeyCb");
33816
33817
    if (ssl == NULL || ssl->ctx == NULL || ssl->ctx->ticketEncWrapCb == NULL) {
33818
        WOLFSSL_MSG("Bad parameter");
33819
        return WOLFSSL_TICKET_RET_FATAL;
33820
    }
33821
33822
#ifdef WOLFSSL_SMALL_STACK
33823
    evpCtx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(sizeof(*evpCtx), ssl->heap,
33824
                                               DYNAMIC_TYPE_TMP_BUFFER);
33825
    if (evpCtx == NULL) {
33826
        WOLFSSL_MSG("out of memory");
33827
        return WOLFSSL_TICKET_RET_FATAL;
33828
    }
33829
#endif
33830
33831
    /* Initialize the cipher and HMAC. */
33832
    wolfSSL_EVP_CIPHER_CTX_init(evpCtx);
33833
    if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
33834
        WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
33835
#ifdef WOLFSSL_SMALL_STACK
33836
        XFREE(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
33837
#endif
33838
        return WOLFSSL_TICKET_RET_FATAL;
33839
    }
33840
    res = ssl->ctx->ticketEncWrapCb(ssl, keyName,
33841
            iv, evpCtx, &hmacCtx, enc);
33842
    if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW) {
33843
        WOLFSSL_MSG("Ticket callback error");
33844
        ret = WOLFSSL_TICKET_RET_FATAL;
33845
        goto end;
33846
    }
33847
33848
    if (wolfSSL_HMAC_size(&hmacCtx) > WOLFSSL_TICKET_MAC_SZ) {
33849
        WOLFSSL_MSG("Ticket cipher MAC size error");
33850
        goto end;
33851
    }
33852
33853
    if (enc)
33854
    {
33855
        /* Encrypt in place. */
33856
        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
33857
                                      encTicket, encTicketLen))
33858
            goto end;
33859
        totalSz = len;
33860
        if (totalSz > *encLen)
33861
            goto end;
33862
        if (!wolfSSL_EVP_EncryptFinal(evpCtx, &encTicket[len], &len))
33863
            goto end;
33864
        /* Total length of encrypted data. */
33865
        totalSz += len;
33866
        if (totalSz > *encLen)
33867
            goto end;
33868
33869
        /* HMAC the encrypted data into the parameter 'mac'. */
33870
        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, totalSz))
33871
            goto end;
33872
        if (!wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz))
33873
            goto end;
33874
    }
33875
    else
33876
    {
33877
        /* HMAC the encrypted data and compare it to the passed in data. */
33878
        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
33879
            goto end;
33880
        if (!wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz))
33881
            goto end;
33882
        if (XMEMCMP(mac, digest, mdSz) != 0)
33883
            goto end;
33884
33885
        /* Decrypt the ticket data in place. */
33886
        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
33887
                                      encTicket, encTicketLen))
33888
            goto end;
33889
        totalSz = len;
33890
        if (totalSz > encTicketLen)
33891
            goto end;
33892
        if (!wolfSSL_EVP_DecryptFinal(evpCtx, &encTicket[len], &len))
33893
            goto end;
33894
        /* Total length of decrypted data. */
33895
        totalSz += len;
33896
        if (totalSz > encTicketLen)
33897
            goto end;
33898
    }
33899
    *encLen = totalSz;
33900
33901
    if (res == TICKET_KEY_CB_RET_RENEW && !IsAtLeastTLSv1_3(ssl->version)
33902
            && !enc)
33903
        ret = WOLFSSL_TICKET_RET_CREATE;
33904
    else
33905
        ret = WOLFSSL_TICKET_RET_OK;
33906
end:
33907
33908
    (void)wc_HmacFree(&hmacCtx.hmac);
33909
#ifdef WOLFSSL_SMALL_STACK
33910
    XFREE(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
33911
#endif
33912
33913
    return ret;
33914
}
33915
33916
/* Set the callback to use when encrypting/decrypting tickets.
33917
 *
33918
 * ctx  The SSL/TLS context object.
33919
 * cb   The OpenSSL session ticket callback.
33920
 * returns WOLFSSL_SUCCESS to indicate success.
33921
 */
33922
int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, ticketCompatCb cb)
33923
{
33924
33925
    /* Set the ticket encryption callback to be a wrapper around OpenSSL
33926
     * callback.
33927
     */
33928
    ctx->ticketEncCb = wolfSSL_TicketKeyCb;
33929
    ctx->ticketEncWrapCb = cb;
33930
33931
    return WOLFSSL_SUCCESS;
33932
}
33933
33934
#endif /* HAVE_SESSION_TICKET */
33935
33936
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
33937
    OPENSSL_EXTRA || HAVE_LIGHTY */
33938
33939
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
33940
    !defined(NO_WOLFSSL_SERVER)
33941
/* Serialize the session ticket encryption keys.
33942
 *
33943
 * @param [in]  ctx     SSL/TLS context object.
33944
 * @param [in]  keys    Buffer to hold session ticket keys.
33945
 * @param [in]  keylen  Length of buffer.
33946
 * @return  WOLFSSL_SUCCESS on success.
33947
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
33948
 *          correct length.
33949
 */
33950
long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
33951
     unsigned char *keys, int keylen)
33952
{
33953
    if (ctx == NULL || keys == NULL) {
33954
        return WOLFSSL_FAILURE;
33955
    }
33956
    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
33957
        return WOLFSSL_FAILURE;
33958
    }
33959
33960
    XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
33961
    keys += WOLFSSL_TICKET_NAME_SZ;
33962
    XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
33963
    keys += WOLFSSL_TICKET_KEY_SZ;
33964
    XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
33965
    keys += WOLFSSL_TICKET_KEY_SZ;
33966
    c32toa(ctx->ticketKeyCtx.expirary[0], keys);
33967
    keys += OPAQUE32_LEN;
33968
    c32toa(ctx->ticketKeyCtx.expirary[1], keys);
33969
33970
    return WOLFSSL_SUCCESS;
33971
}
33972
33973
/* Deserialize the session ticket encryption keys.
33974
 *
33975
 * @param [in]  ctx     SSL/TLS context object.
33976
 * @param [in]  keys    Session ticket keys.
33977
 * @param [in]  keylen  Length of data.
33978
 * @return  WOLFSSL_SUCCESS on success.
33979
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
33980
 *          correct length.
33981
 */
33982
long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
33983
     unsigned char *keys, int keylen)
33984
{
33985
    if (ctx == NULL || keys == NULL) {
33986
        return WOLFSSL_FAILURE;
33987
    }
33988
    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
33989
        return WOLFSSL_FAILURE;
33990
    }
33991
33992
    XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
33993
    keys += WOLFSSL_TICKET_NAME_SZ;
33994
    XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
33995
    keys += WOLFSSL_TICKET_KEY_SZ;
33996
    XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
33997
    keys += WOLFSSL_TICKET_KEY_SZ;
33998
    ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
33999
    keys += OPAQUE32_LEN;
34000
    ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
34001
34002
    return WOLFSSL_SUCCESS;
34003
}
34004
#endif
34005
34006
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
34007
#ifdef HAVE_OCSP
34008
/* Not an OpenSSL API. */
34009
int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
34010
{
34011
    *response = ssl->ocspResp;
34012
    return ssl->ocspRespSz;
34013
}
34014
34015
/* Not an OpenSSL API. */
34016
char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
34017
{
34018
    return ssl->url;
34019
}
34020
34021
/* Not an OpenSSL API. */
34022
int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
34023
{
34024
    if (ssl == NULL)
34025
        return WOLFSSL_FAILURE;
34026
34027
    ssl->url = url;
34028
    return WOLFSSL_SUCCESS;
34029
}
34030
#endif /* OCSP */
34031
#endif /* OPENSSL_ALL || WOLFSSL_NGINX  || WOLFSSL_HAPROXY */
34032
34033
#if defined(HAVE_OCSP) && !defined(NO_ASN_TIME)
34034
int wolfSSL_get_ocsp_producedDate(
34035
    WOLFSSL *ssl,
34036
    byte *producedDate,
34037
    size_t producedDate_space,
34038
    int *producedDateFormat)
34039
{
34040
    if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
34041
        (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
34042
        return BAD_FUNC_ARG;
34043
34044
    if ((producedDate == NULL) || (producedDateFormat == NULL))
34045
        return BAD_FUNC_ARG;
34046
34047
    if (XSTRLEN((char *)ssl->ocspProducedDate) >= producedDate_space)
34048
        return BUFFER_E;
34049
34050
    XSTRNCPY((char *)producedDate, (const char *)ssl->ocspProducedDate, producedDate_space);
34051
    *producedDateFormat = ssl->ocspProducedDateFormat;
34052
34053
    return 0;
34054
}
34055
34056
int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, struct tm *produced_tm) {
34057
    int idx = 0;
34058
34059
    if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
34060
        (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
34061
        return BAD_FUNC_ARG;
34062
34063
    if (produced_tm == NULL)
34064
        return BAD_FUNC_ARG;
34065
34066
    if (ExtractDate(ssl->ocspProducedDate,
34067
            (unsigned char)ssl->ocspProducedDateFormat, produced_tm, &idx))
34068
        return 0;
34069
    else
34070
        return ASN_PARSE_E;
34071
}
34072
#endif
34073
34074
34075
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
34076
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
34077
int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain)
34078
{
34079
    word32         idx;
34080
    word32         length;
34081
    WOLFSSL_STACK* node;
34082
    WOLFSSL_STACK* last = NULL;
34083
34084
    if (ctx == NULL || chain == NULL) {
34085
        chain = NULL;
34086
        return WOLFSSL_FAILURE;
34087
    }
34088
    if (ctx->x509Chain != NULL) {
34089
        *chain = ctx->x509Chain;
34090
        return WOLFSSL_SUCCESS;
34091
    }
34092
34093
    /* If there are no chains then success! */
34094
    *chain = NULL;
34095
    if (ctx->certChain == NULL || ctx->certChain->length == 0) {
34096
        return WOLFSSL_SUCCESS;
34097
    }
34098
34099
    /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
34100
    for (idx = 0; idx < ctx->certChain->length; ) {
34101
        node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
34102
                                       DYNAMIC_TYPE_OPENSSL);
34103
        if (node == NULL)
34104
            return WOLFSSL_FAILURE;
34105
        node->next = NULL;
34106
34107
        /* 3 byte length | X509 DER data */
34108
        ato24(ctx->certChain->buffer + idx, &length);
34109
        idx += 3;
34110
34111
        /* Create a new X509 from DER encoded data. */
34112
        node->data.x509 = wolfSSL_X509_d2i(NULL, ctx->certChain->buffer + idx,
34113
            length);
34114
        if (node->data.x509 == NULL) {
34115
            XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
34116
            /* Return as much of the chain as we created. */
34117
            ctx->x509Chain = *chain;
34118
            return WOLFSSL_FAILURE;
34119
        }
34120
        idx += length;
34121
34122
        /* Add object to the end of the stack. */
34123
        if (last == NULL) {
34124
            node->num = 1;
34125
            *chain = node;
34126
        }
34127
        else {
34128
            (*chain)->num++;
34129
            last->next = node;
34130
        }
34131
34132
        last = node;
34133
    }
34134
34135
    ctx->x509Chain = *chain;
34136
34137
    return WOLFSSL_SUCCESS;
34138
}
34139
34140
int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb)
34141
{
34142
    if (ctx == NULL || ctx->cm == NULL || cb == NULL)
34143
        return WOLFSSL_FAILURE;
34144
34145
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
34146
                               ||  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
34147
    if (ctx->cm->ocsp_stapling == NULL)
34148
        return WOLFSSL_FAILURE;
34149
34150
    *cb = ctx->cm->ocsp_stapling->statusCb;
34151
#else
34152
    (void)cb;
34153
    *cb = NULL;
34154
#endif
34155
34156
    return WOLFSSL_SUCCESS;
34157
34158
}
34159
34160
int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb)
34161
{
34162
    if (ctx == NULL || ctx->cm == NULL)
34163
        return WOLFSSL_FAILURE;
34164
34165
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
34166
                               ||  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
34167
    /* Ensure stapling is on for callback to be used. */
34168
    wolfSSL_CTX_EnableOCSPStapling(ctx);
34169
34170
    if (ctx->cm->ocsp_stapling == NULL)
34171
        return WOLFSSL_FAILURE;
34172
34173
    ctx->cm->ocsp_stapling->statusCb = cb;
34174
#else
34175
    (void)cb;
34176
#endif
34177
34178
    return WOLFSSL_SUCCESS;
34179
}
34180
34181
int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx,
34182
        WOLF_STACK_OF(WOLFSSL_X509) **sk)
34183
{
34184
    WOLFSSL_ENTER("wolfSSL_CTX_get0_chain_certs");
34185
    if (ctx == NULL || sk == NULL) {
34186
        WOLFSSL_MSG("Bad parameter");
34187
        return WOLFSSL_FAILURE;
34188
    }
34189
    *sk = ctx->x509Chain;
34190
    return WOLFSSL_SUCCESS;
34191
}
34192
34193
#ifdef KEEP_OUR_CERT
34194
int wolfSSL_get0_chain_certs(WOLFSSL *ssl,
34195
        WOLF_STACK_OF(WOLFSSL_X509) **sk)
34196
{
34197
    WOLFSSL_ENTER("wolfSSL_get0_chain_certs");
34198
    if (ssl == NULL || sk == NULL) {
34199
        WOLFSSL_MSG("Bad parameter");
34200
        return WOLFSSL_FAILURE;
34201
    }
34202
    *sk = ssl->ourCertChain;
34203
    return WOLFSSL_SUCCESS;
34204
}
34205
#endif
34206
34207
WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void)
34208
{
34209
    WOLF_STACK_OF(WOLFSSL_STRING)* ret = wolfSSL_sk_new_node(NULL);
34210
34211
    if (ret) {
34212
        ret->type = STACK_TYPE_STRING;
34213
    }
34214
34215
    return ret;
34216
}
34217
34218
void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s)
34219
{
34220
    WOLFSSL_ENTER("wolfSSL_WOLFSSL_STRING_free");
34221
34222
    if (s != NULL)
34223
        XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
34224
}
34225
34226
void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* sk)
34227
{
34228
    WOLFSSL_STACK* tmp;
34229
    WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_STRING_free");
34230
34231
    if (sk == NULL)
34232
        return;
34233
34234
    /* parse through stack freeing each node */
34235
    while (sk) {
34236
        tmp = sk->next;
34237
        XFREE(sk->data.string, NULL, DYNAMIC_TYPE_OPENSSL);
34238
        XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
34239
        sk = tmp;
34240
    }
34241
}
34242
34243
WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings,
34244
    int idx)
34245
{
34246
    for (; idx > 0 && strings != NULL; idx--)
34247
        strings = strings->next;
34248
    if (strings == NULL)
34249
        return NULL;
34250
    return strings->data.string;
34251
}
34252
34253
int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings)
34254
{
34255
    if (strings)
34256
        return (int)strings->num;
34257
    return 0;
34258
}
34259
34260
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
34261
34262
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
34263
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) || \
34264
    defined(WOLFSSL_QUIC)
34265
#ifdef HAVE_ALPN
34266
void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
34267
                                unsigned int *len)
34268
{
34269
    word16 nameLen;
34270
34271
    if (ssl != NULL && data != NULL && len != NULL) {
34272
        TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
34273
        *len = nameLen;
34274
    }
34275
}
34276
34277
int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
34278
                              const unsigned char *in, unsigned int inLen,
34279
                              const unsigned char *clientNames,
34280
                              unsigned int clientLen)
34281
{
34282
    unsigned int i, j;
34283
    byte lenIn, lenClient;
34284
34285
    if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
34286
        return OPENSSL_NPN_UNSUPPORTED;
34287
34288
    for (i = 0; i < inLen; i += lenIn) {
34289
        lenIn = in[i++];
34290
        for (j = 0; j < clientLen; j += lenClient) {
34291
            lenClient = clientNames[j++];
34292
34293
            if (lenIn != lenClient)
34294
                continue;
34295
34296
            if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
34297
                *out = (unsigned char *)(in + i);
34298
                *outLen = lenIn;
34299
                return OPENSSL_NPN_NEGOTIATED;
34300
            }
34301
        }
34302
    }
34303
34304
    *out = (unsigned char *)clientNames + 1;
34305
    *outLen = clientNames[0];
34306
    return OPENSSL_NPN_NO_OVERLAP;
34307
}
34308
34309
void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
34310
                                    int (*cb) (WOLFSSL *ssl,
34311
                                               const unsigned char **out,
34312
                                               unsigned char *outlen,
34313
                                               const unsigned char *in,
34314
                                               unsigned int inlen,
34315
                                               void *arg), void *arg)
34316
{
34317
    if (ctx != NULL) {
34318
        ctx->alpnSelect = cb;
34319
        ctx->alpnSelectArg = arg;
34320
    }
34321
}
34322
34323
void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
34324
                                           int (*cb) (WOLFSSL *ssl,
34325
                                                      const unsigned char
34326
                                                      **out,
34327
                                                      unsigned int *outlen,
34328
                                                      void *arg), void *arg)
34329
{
34330
    (void)s;
34331
    (void)cb;
34332
    (void)arg;
34333
    WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
34334
}
34335
34336
void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
34337
                                      int (*cb) (WOLFSSL *ssl,
34338
                                                 unsigned char **out,
34339
                                                 unsigned char *outlen,
34340
                                                 const unsigned char *in,
34341
                                                 unsigned int inlen,
34342
                                                 void *arg), void *arg)
34343
{
34344
    (void)s;
34345
    (void)cb;
34346
    (void)arg;
34347
    WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
34348
}
34349
34350
void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **data,
34351
                                    unsigned *len)
34352
{
34353
    (void)s;
34354
    (void)data;
34355
    (void)len;
34356
    WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
34357
}
34358
#endif /* HAVE_ALPN */
34359
34360
#endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
34361
34362
#ifdef OPENSSL_EXTRA
34363
int wolfSSL_curve_is_disabled(WOLFSSL* ssl, word16 curve_id)
34364
{
34365
    return (curve_id <= WOLFSSL_ECC_MAX &&
34366
            ssl->disabledCurves &&
34367
            ssl->disabledCurves & (1 << curve_id));
34368
}
34369
#endif
34370
34371
#if defined(OPENSSL_EXTRA) && (defined(HAVE_ECC) || \
34372
    defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
34373
static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
34374
{
34375
    int idx, start = 0, len, i, ret = WOLFSSL_FAILURE;
34376
    word16 curve;
34377
    word32 disabled;
34378
    char name[MAX_CURVE_NAME_SZ];
34379
    byte groups_len = 0;
34380
#ifdef WOLFSSL_SMALL_STACK
34381
    void *heap = ssl? ssl->heap : ctx->heap;
34382
    int *groups;
34383
#else
34384
    int groups[WOLFSSL_MAX_GROUP_COUNT];
34385
#endif
34386
34387
#ifdef WOLFSSL_SMALL_STACK
34388
    groups = (int*)XMALLOC(sizeof(int)*WOLFSSL_MAX_GROUP_COUNT,
34389
                           heap, DYNAMIC_TYPE_TMP_BUFFER);
34390
    if (groups == NULL) {
34391
        ret = MEMORY_E;
34392
        goto leave;
34393
    }
34394
#endif
34395
34396
    for (idx = 1; names[idx-1] != '\0'; idx++) {
34397
        if (names[idx] != ':' && names[idx] != '\0')
34398
            continue;
34399
34400
        len = idx - start;
34401
        if (len > MAX_CURVE_NAME_SZ - 1)
34402
            goto leave;
34403
34404
        XMEMCPY(name, names + start, len);
34405
        name[len] = 0;
34406
34407
        if ((XSTRCMP(name, "prime256v1") == 0) ||
34408
            (XSTRCMP(name, "secp256r1") == 0) ||
34409
            (XSTRCMP(name, "P-256") == 0))
34410
        {
34411
            curve = WOLFSSL_ECC_SECP256R1;
34412
        }
34413
        else if ((XSTRCMP(name, "secp384r1") == 0) ||
34414
                 (XSTRCMP(name, "P-384") == 0))
34415
        {
34416
            curve = WOLFSSL_ECC_SECP384R1;
34417
        }
34418
        else if ((XSTRCMP(name, "secp521r1") == 0) ||
34419
                 (XSTRCMP(name, "P-521") == 0))
34420
        {
34421
            curve = WOLFSSL_ECC_SECP521R1;
34422
        }
34423
    #ifdef HAVE_CURVE25519
34424
        else if (XSTRCMP(name, "X25519") == 0)
34425
        {
34426
            curve = WOLFSSL_ECC_X25519;
34427
        }
34428
    #endif
34429
    #ifdef HAVE_CURVE448
34430
        else if (XSTRCMP(name, "X448") == 0)
34431
        {
34432
            curve = WOLFSSL_ECC_X448;
34433
        }
34434
    #endif
34435
        else {
34436
        #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
34437
            int   nret;
34438
            const ecc_set_type *eccSet;
34439
34440
            nret = wc_ecc_get_curve_idx_from_name(name);
34441
            if (nret < 0) {
34442
                WOLFSSL_MSG("Could not find name in set");
34443
                goto leave;
34444
            }
34445
34446
            eccSet = wc_ecc_get_curve_params(ret);
34447
            if (eccSet == NULL) {
34448
                WOLFSSL_MSG("NULL set returned");
34449
                goto leave;
34450
            }
34451
34452
            curve = GetCurveByOID(eccSet->oidSum);
34453
        #else
34454
            WOLFSSL_MSG("API not present to search farther using name");
34455
            goto leave;
34456
        #endif
34457
        }
34458
34459
        if (curve >= (sizeof(word32) * WOLFSSL_BIT_SIZE)) {
34460
            /* shift left more than size of ctx->disabledCurves causes static
34461
             * analysis report */
34462
            WOLFSSL_MSG("curve value is too large for upcoming shift");
34463
            goto leave;
34464
        }
34465
34466
        for (i = 0; i < groups_len; ++i) {
34467
            if (groups[i] == curve) {
34468
                /* silently drop duplicates */
34469
                break;
34470
            }
34471
        }
34472
        if (i >= groups_len) {
34473
            if (groups_len >= WOLFSSL_MAX_GROUP_COUNT) {
34474
                WOLFSSL_MSG_EX("setting %d or more supported "
34475
                               "curves is not permitted", groups_len);
34476
                goto leave;
34477
            }
34478
            groups[groups_len++] = (int)curve;
34479
        }
34480
34481
        start = idx + 1;
34482
    }
34483
34484
    /* Disable all curves so that only the ones the user wants are enabled. */
34485
    disabled = 0xFFFFFFFFUL;
34486
    for (i = 0; i < groups_len; ++i) {
34487
        /* Switch the bit to off and therefore is enabled. */
34488
        curve = (word16)groups[i];
34489
        disabled &= ~(1U << curve);
34490
    #ifdef HAVE_SUPPORTED_CURVES
34491
    #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_OLD_SET_CURVES_LIST)
34492
        /* using the wolfSSL API to set the groups, this will populate
34493
         * (ssl|ctx)->groups and reset any TLSX_SUPPORTED_GROUPS.
34494
         * The order in (ssl|ctx)->groups will then be respected
34495
         * when TLSX_KEY_SHARE needs to be established */
34496
        if ((ssl && wolfSSL_set_groups(ssl, groups, groups_len)
34497
                        != WOLFSSL_SUCCESS)
34498
            || (ctx && wolfSSL_CTX_set_groups(ctx, groups, groups_len)
34499
                           != WOLFSSL_SUCCESS)) {
34500
            WOLFSSL_MSG("Unable to set supported curve");
34501
            goto leave;
34502
        }
34503
    #elif !defined(NO_WOLFSSL_CLIENT)
34504
        /* set the supported curve so client TLS extension contains only the
34505
         * desired curves */
34506
        if ((ssl && wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
34507
            || (ctx && wolfSSL_CTX_UseSupportedCurve(ctx, curve)
34508
                           != WOLFSSL_SUCCESS)) {
34509
            WOLFSSL_MSG("Unable to set supported curve");
34510
            goto leave;
34511
        }
34512
    #endif
34513
    #endif /* HAVE_SUPPORTED_CURVES */
34514
    }
34515
34516
    if (ssl)
34517
        ssl->disabledCurves = disabled;
34518
    else
34519
        ctx->disabledCurves = disabled;
34520
    ret = WOLFSSL_SUCCESS;
34521
34522
leave:
34523
#ifdef WOLFSSL_SMALL_STACK
34524
    if (groups)
34525
        XFREE((void*)groups, heap, DYNAMIC_TYPE_TMP_BUFFER);
34526
#endif
34527
    return ret;
34528
}
34529
34530
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
34531
{
34532
    if (ctx == NULL || names == NULL) {
34533
        WOLFSSL_MSG("ctx or names was NULL");
34534
        return WOLFSSL_FAILURE;
34535
    }
34536
    return set_curves_list(NULL, ctx, names);
34537
}
34538
34539
int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
34540
{
34541
    if (ssl == NULL || names == NULL) {
34542
        WOLFSSL_MSG("ssl or names was NULL");
34543
        return WOLFSSL_FAILURE;
34544
    }
34545
    return set_curves_list(ssl, NULL, names);
34546
}
34547
#endif /* OPENSSL_EXTRA && (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) */
34548
34549
#ifdef OPENSSL_EXTRA
34550
/* Sets a callback for when sending and receiving protocol messages.
34551
 * This callback is copied to all WOLFSSL objects created from the ctx.
34552
 *
34553
 * ctx WOLFSSL_CTX structure to set callback in
34554
 * cb  callback to use
34555
 *
34556
 * return WOLFSSL_SUCCESS on success and SSL_FAILURE with error case
34557
 */
34558
int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
34559
{
34560
    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback");
34561
    if (ctx == NULL) {
34562
        WOLFSSL_MSG("Null ctx passed in");
34563
        return WOLFSSL_FAILURE;
34564
    }
34565
34566
    ctx->protoMsgCb = cb;
34567
    return WOLFSSL_SUCCESS;
34568
}
34569
34570
34571
/* Sets a callback for when sending and receiving protocol messages.
34572
 *
34573
 * ssl WOLFSSL structure to set callback in
34574
 * cb  callback to use
34575
 *
34576
 * return WOLFSSL_SUCCESS on success and SSL_FAILURE with error case
34577
 */
34578
int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
34579
{
34580
    WOLFSSL_ENTER("wolfSSL_set_msg_callback");
34581
34582
    if (ssl == NULL) {
34583
        return SSL_FAILURE;
34584
    }
34585
34586
    if (cb != NULL) {
34587
        ssl->toInfoOn = 1;
34588
    }
34589
34590
    ssl->protoMsgCb = cb;
34591
    return WOLFSSL_SUCCESS;
34592
}
34593
34594
34595
/* set the user argument to pass to the msg callback when called
34596
 * return WOLFSSL_SUCCESS on success */
34597
int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
34598
{
34599
    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback_arg");
34600
    if (ctx == NULL) {
34601
        WOLFSSL_MSG("Null WOLFSSL_CTX passed in");
34602
        return WOLFSSL_FAILURE;
34603
    }
34604
34605
    ctx->protoMsgCtx = arg;
34606
    return WOLFSSL_SUCCESS;
34607
}
34608
34609
34610
int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
34611
{
34612
    WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
34613
    if (ssl == NULL)
34614
        return WOLFSSL_FAILURE;
34615
34616
    ssl->protoMsgCtx = arg;
34617
    return WOLFSSL_SUCCESS;
34618
}
34619
34620
void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int line)
34621
{
34622
    void *ret;
34623
    (void)file;
34624
    (void)line;
34625
34626
    if (data == NULL || siz >= INT_MAX)
34627
        return NULL;
34628
34629
    ret = OPENSSL_malloc(siz);
34630
    if (ret == NULL) {
34631
        return NULL;
34632
    }
34633
    return XMEMCPY(ret, data, siz);
34634
}
34635
34636
void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len)
34637
{
34638
    if (ptr)
34639
        ForceZero(ptr, (word32)len);
34640
}
34641
34642
int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
34643
                            unsigned int p_len)
34644
{
34645
    WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
34646
    if (ctx == NULL)
34647
        return BAD_FUNC_ARG;
34648
    if (ctx->alpn_cli_protos != NULL) {
34649
        XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL);
34650
    }
34651
34652
    ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len,
34653
        ctx->heap, DYNAMIC_TYPE_OPENSSL);
34654
    if (ctx->alpn_cli_protos == NULL) {
34655
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34656
        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34657
         * the function reverses the return value convention.
34658
         */
34659
        return 1;
34660
#else
34661
        return WOLFSSL_FAILURE;
34662
#endif
34663
    }
34664
    XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len);
34665
    ctx->alpn_cli_protos_len = p_len;
34666
34667
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34668
    /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34669
     * the function reverses the return value convention.
34670
     */
34671
    return 0;
34672
#else
34673
    return WOLFSSL_SUCCESS;
34674
#endif
34675
}
34676
34677
34678
#ifdef HAVE_ALPN
34679
#ifndef NO_BIO
34680
/* Sets the ALPN extension protos
34681
 *
34682
 * example format is
34683
 * unsigned char p[] = {
34684
 *      8, 'h', 't', 't', 'p', '/', '1', '.', '1'
34685
 * };
34686
 *
34687
 * returns WOLFSSL_SUCCESS on success */
34688
int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
34689
        const unsigned char* p, unsigned int p_len)
34690
{
34691
    WOLFSSL_BIO* bio;
34692
    char* pt;
34693
34694
    unsigned int sz;
34695
    unsigned int idx = 0;
34696
    int alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
34697
    WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
34698
34699
    if (ssl == NULL || p_len <= 1) {
34700
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34701
        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34702
         * the function reverses the return value convention.
34703
         */
34704
        return 1;
34705
#else
34706
        return WOLFSSL_FAILURE;
34707
#endif
34708
    }
34709
34710
    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
34711
    if (bio == NULL) {
34712
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34713
        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34714
         * the function reverses the return value convention.
34715
         */
34716
        return 1;
34717
#else
34718
        return WOLFSSL_FAILURE;
34719
#endif
34720
    }
34721
34722
    /* convert into comma separated list */
34723
    while (idx < p_len - 1) {
34724
        unsigned int i;
34725
34726
        sz = p[idx++];
34727
        if (idx + sz > p_len) {
34728
            WOLFSSL_MSG("Bad list format");
34729
            wolfSSL_BIO_free(bio);
34730
    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34731
            /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34732
             * the function reverses the return value convention.
34733
             */
34734
            return 1;
34735
    #else
34736
            return WOLFSSL_FAILURE;
34737
    #endif
34738
        }
34739
        if (sz > 0) {
34740
            for (i = 0; i < sz; i++) {
34741
                wolfSSL_BIO_write(bio, &p[idx++], 1);
34742
            }
34743
            if (idx < p_len - 1)
34744
                wolfSSL_BIO_write(bio, ",", 1);
34745
        }
34746
    }
34747
    wolfSSL_BIO_write(bio, "\0", 1);
34748
34749
    /* clears out all current ALPN extensions set */
34750
    TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap);
34751
34752
    if ((sz = wolfSSL_BIO_get_mem_data(bio, &pt)) > 0) {
34753
        wolfSSL_UseALPN(ssl, pt, sz, (byte) alpn_opt);
34754
    }
34755
    wolfSSL_BIO_free(bio);
34756
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34757
    /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34758
     * the function reverses the return value convention.
34759
     */
34760
    return 0;
34761
#else
34762
    return WOLFSSL_SUCCESS;
34763
#endif
34764
}
34765
#endif /* !NO_BIO */
34766
#endif /* HAVE_ALPN */
34767
#endif /* OPENSSL_EXTRA */
34768
34769
#if defined(OPENSSL_EXTRA)
34770
34771
#ifndef NO_BIO
34772
#define WOLFSSL_BIO_INCLUDED
34773
#include "src/bio.c"
34774
#endif
34775
34776
word32 nid2oid(int nid, int grp)
34777
{
34778
    /* get OID type */
34779
    switch (grp) {
34780
        /* oidHashType */
34781
        case oidHashType:
34782
            switch (nid) {
34783
            #ifdef WOLFSSL_MD2
34784
                case NID_md2:
34785
                    return MD2h;
34786
            #endif
34787
            #ifndef NO_MD5
34788
                case NID_md5:
34789
                    return MD5h;
34790
            #endif
34791
            #ifndef NO_SHA
34792
                case NID_sha1:
34793
                    return SHAh;
34794
            #endif
34795
                case NID_sha224:
34796
                    return SHA224h;
34797
            #ifndef NO_SHA256
34798
                case NID_sha256:
34799
                    return SHA256h;
34800
            #endif
34801
            #ifdef WOLFSSL_SHA384
34802
                case NID_sha384:
34803
                    return SHA384h;
34804
            #endif
34805
            #ifdef WOLFSSL_SHA512
34806
                case NID_sha512:
34807
                    return SHA512h;
34808
            #endif
34809
            #ifndef WOLFSSL_NOSHA3_224
34810
                case NID_sha3_224:
34811
                    return SHA3_224h;
34812
            #endif
34813
            #ifndef WOLFSSL_NOSHA3_256
34814
                case NID_sha3_256:
34815
                    return SHA3_256h;
34816
            #endif
34817
            #ifndef WOLFSSL_NOSHA3_384
34818
                case NID_sha3_384:
34819
                    return SHA3_384h;
34820
            #endif
34821
            #ifndef WOLFSSL_NOSHA3_512
34822
                case NID_sha3_512:
34823
                    return SHA3_512h;
34824
            #endif
34825
            }
34826
            break;
34827
34828
        /*  oidSigType */
34829
        case oidSigType:
34830
            switch (nid) {
34831
            #ifndef NO_DSA
34832
                case NID_dsaWithSHA1:
34833
                    return CTC_SHAwDSA;
34834
                case NID_dsa_with_SHA256:
34835
                    return CTC_SHA256wDSA;
34836
            #endif /* NO_DSA */
34837
            #ifndef NO_RSA
34838
                case NID_md2WithRSAEncryption:
34839
                    return CTC_MD2wRSA;
34840
                case NID_md5WithRSAEncryption:
34841
                    return CTC_MD5wRSA;
34842
                case NID_sha1WithRSAEncryption:
34843
                    return CTC_SHAwRSA;
34844
                case NID_sha224WithRSAEncryption:
34845
                    return CTC_SHA224wRSA;
34846
                case NID_sha256WithRSAEncryption:
34847
                    return CTC_SHA256wRSA;
34848
                case NID_sha384WithRSAEncryption:
34849
                    return CTC_SHA384wRSA;
34850
                case NID_sha512WithRSAEncryption:
34851
                    return CTC_SHA512wRSA;
34852
                #ifdef WOLFSSL_SHA3
34853
                case NID_RSA_SHA3_224:
34854
                    return CTC_SHA3_224wRSA;
34855
                case NID_RSA_SHA3_256:
34856
                    return CTC_SHA3_256wRSA;
34857
                case NID_RSA_SHA3_384:
34858
                    return CTC_SHA3_384wRSA;
34859
                case NID_RSA_SHA3_512:
34860
                    return CTC_SHA3_512wRSA;
34861
                #endif
34862
            #endif /* NO_RSA */
34863
            #ifdef HAVE_ECC
34864
                case NID_ecdsa_with_SHA1:
34865
                    return CTC_SHAwECDSA;
34866
                case NID_ecdsa_with_SHA224:
34867
                    return CTC_SHA224wECDSA;
34868
                case NID_ecdsa_with_SHA256:
34869
                    return CTC_SHA256wECDSA;
34870
                case NID_ecdsa_with_SHA384:
34871
                    return CTC_SHA384wECDSA;
34872
                case NID_ecdsa_with_SHA512:
34873
                    return CTC_SHA512wECDSA;
34874
                #ifdef WOLFSSL_SHA3
34875
                case NID_ecdsa_with_SHA3_224:
34876
                    return CTC_SHA3_224wECDSA;
34877
                case NID_ecdsa_with_SHA3_256:
34878
                    return CTC_SHA3_256wECDSA;
34879
                case NID_ecdsa_with_SHA3_384:
34880
                    return CTC_SHA3_384wECDSA;
34881
                case NID_ecdsa_with_SHA3_512:
34882
                    return CTC_SHA3_512wECDSA;
34883
                #endif
34884
            #endif /* HAVE_ECC */
34885
            }
34886
            break;
34887
34888
        /* oidKeyType */
34889
        case oidKeyType:
34890
            switch (nid) {
34891
            #ifndef NO_DSA
34892
                case NID_dsa:
34893
                    return DSAk;
34894
            #endif /* NO_DSA */
34895
            #ifndef NO_RSA
34896
                case NID_rsaEncryption:
34897
                    return RSAk;
34898
            #endif /* NO_RSA */
34899
            #ifdef HAVE_ECC
34900
                case NID_X9_62_id_ecPublicKey:
34901
                    return ECDSAk;
34902
            #endif /* HAVE_ECC */
34903
            }
34904
            break;
34905
34906
34907
    #ifdef HAVE_ECC
34908
        case oidCurveType:
34909
            switch (nid) {
34910
            case NID_X9_62_prime192v1:
34911
                return ECC_SECP192R1_OID;
34912
            case NID_X9_62_prime192v2:
34913
                return ECC_PRIME192V2_OID;
34914
            case NID_X9_62_prime192v3:
34915
                return ECC_PRIME192V3_OID;
34916
            case NID_X9_62_prime239v1:
34917
                return ECC_PRIME239V1_OID;
34918
            case NID_X9_62_prime239v2:
34919
                return ECC_PRIME239V2_OID;
34920
            case NID_X9_62_prime239v3:
34921
                return ECC_PRIME239V3_OID;
34922
            case NID_X9_62_prime256v1:
34923
                return ECC_SECP256R1_OID;
34924
            case NID_secp112r1:
34925
                return ECC_SECP112R1_OID;
34926
            case NID_secp112r2:
34927
                return ECC_SECP112R2_OID;
34928
            case NID_secp128r1:
34929
                return ECC_SECP128R1_OID;
34930
            case NID_secp128r2:
34931
                return ECC_SECP128R2_OID;
34932
            case NID_secp160r1:
34933
                return ECC_SECP160R1_OID;
34934
            case NID_secp160r2:
34935
                return ECC_SECP160R2_OID;
34936
            case NID_secp224r1:
34937
                return ECC_SECP224R1_OID;
34938
            case NID_secp384r1:
34939
                return ECC_SECP384R1_OID;
34940
            case NID_secp521r1:
34941
                return ECC_SECP521R1_OID;
34942
            case NID_secp160k1:
34943
                return ECC_SECP160K1_OID;
34944
            case NID_secp192k1:
34945
                return ECC_SECP192K1_OID;
34946
            case NID_secp224k1:
34947
                return ECC_SECP224K1_OID;
34948
            case NID_secp256k1:
34949
                return ECC_SECP256K1_OID;
34950
            case NID_brainpoolP160r1:
34951
                return ECC_BRAINPOOLP160R1_OID;
34952
            case NID_brainpoolP192r1:
34953
                return ECC_BRAINPOOLP192R1_OID;
34954
            case NID_brainpoolP224r1:
34955
                return ECC_BRAINPOOLP224R1_OID;
34956
            case NID_brainpoolP256r1:
34957
                return ECC_BRAINPOOLP256R1_OID;
34958
            case NID_brainpoolP320r1:
34959
                return ECC_BRAINPOOLP320R1_OID;
34960
            case NID_brainpoolP384r1:
34961
                return ECC_BRAINPOOLP384R1_OID;
34962
            case NID_brainpoolP512r1:
34963
                return ECC_BRAINPOOLP512R1_OID;
34964
            }
34965
            break;
34966
    #endif /* HAVE_ECC */
34967
34968
        /* oidBlkType */
34969
        case oidBlkType:
34970
            switch (nid) {
34971
            #ifdef WOLFSSL_AES_128
34972
                case AES128CBCb:
34973
                    return AES128CBCb;
34974
            #endif
34975
            #ifdef WOLFSSL_AES_192
34976
                case AES192CBCb:
34977
                    return AES192CBCb;
34978
            #endif
34979
            #ifdef WOLFSSL_AES_256
34980
                case AES256CBCb:
34981
                    return AES256CBCb;
34982
            #endif
34983
            #ifndef NO_DES3
34984
                case NID_des:
34985
                    return DESb;
34986
                case NID_des3:
34987
                    return DES3b;
34988
            #endif
34989
            }
34990
            break;
34991
34992
    #ifdef HAVE_OCSP
34993
        case oidOcspType:
34994
            switch (nid) {
34995
                case NID_id_pkix_OCSP_basic:
34996
                    return OCSP_BASIC_OID;
34997
                case OCSP_NONCE_OID:
34998
                    return OCSP_NONCE_OID;
34999
            }
35000
            break;
35001
    #endif /* HAVE_OCSP */
35002
35003
        /* oidCertExtType */
35004
        case oidCertExtType:
35005
            switch (nid) {
35006
                case NID_basic_constraints:
35007
                    return BASIC_CA_OID;
35008
                case NID_subject_alt_name:
35009
                    return ALT_NAMES_OID;
35010
                case NID_crl_distribution_points:
35011
                    return CRL_DIST_OID;
35012
                case NID_info_access:
35013
                    return AUTH_INFO_OID;
35014
                case NID_authority_key_identifier:
35015
                    return AUTH_KEY_OID;
35016
                case NID_subject_key_identifier:
35017
                    return SUBJ_KEY_OID;
35018
                case NID_inhibit_any_policy:
35019
                    return INHIBIT_ANY_OID;
35020
                case NID_key_usage:
35021
                    return KEY_USAGE_OID;
35022
                case NID_name_constraints:
35023
                    return NAME_CONS_OID;
35024
                case NID_certificate_policies:
35025
                    return CERT_POLICY_OID;
35026
                case NID_ext_key_usage:
35027
                    return EXT_KEY_USAGE_OID;
35028
            }
35029
            break;
35030
35031
        /* oidCertAuthInfoType */
35032
        case oidCertAuthInfoType:
35033
            switch (nid) {
35034
                case NID_ad_OCSP:
35035
                    return AIA_OCSP_OID;
35036
                case NID_ad_ca_issuers:
35037
                    return AIA_CA_ISSUER_OID;
35038
            }
35039
            break;
35040
35041
        /* oidCertPolicyType */
35042
        case oidCertPolicyType:
35043
            switch (nid) {
35044
                case NID_any_policy:
35045
                    return CP_ANY_OID;
35046
            }
35047
            break;
35048
35049
        /* oidCertAltNameType */
35050
        case oidCertAltNameType:
35051
            switch (nid) {
35052
                case NID_hw_name_oid:
35053
                    return HW_NAME_OID;
35054
            }
35055
            break;
35056
35057
        /* oidCertKeyUseType */
35058
        case oidCertKeyUseType:
35059
            switch (nid) {
35060
                case NID_anyExtendedKeyUsage:
35061
                    return EKU_ANY_OID;
35062
                case EKU_SERVER_AUTH_OID:
35063
                    return EKU_SERVER_AUTH_OID;
35064
                case EKU_CLIENT_AUTH_OID:
35065
                    return EKU_CLIENT_AUTH_OID;
35066
                case EKU_OCSP_SIGN_OID:
35067
                    return EKU_OCSP_SIGN_OID;
35068
            }
35069
            break;
35070
35071
        /* oidKdfType */
35072
        case oidKdfType:
35073
            switch (nid) {
35074
                case PBKDF2_OID:
35075
                    return PBKDF2_OID;
35076
            }
35077
            break;
35078
35079
        /* oidPBEType */
35080
        case oidPBEType:
35081
            switch (nid) {
35082
                case PBE_SHA1_RC4_128:
35083
                    return PBE_SHA1_RC4_128;
35084
                case PBE_SHA1_DES:
35085
                    return PBE_SHA1_DES;
35086
                case PBE_SHA1_DES3:
35087
                    return PBE_SHA1_DES3;
35088
            }
35089
            break;
35090
35091
        /* oidKeyWrapType */
35092
        case oidKeyWrapType:
35093
            switch (nid) {
35094
            #ifdef WOLFSSL_AES_128
35095
                case AES128_WRAP:
35096
                    return AES128_WRAP;
35097
            #endif
35098
            #ifdef WOLFSSL_AES_192
35099
                case AES192_WRAP:
35100
                    return AES192_WRAP;
35101
            #endif
35102
            #ifdef WOLFSSL_AES_256
35103
                case AES256_WRAP:
35104
                    return AES256_WRAP;
35105
            #endif
35106
            }
35107
            break;
35108
35109
        /* oidCmsKeyAgreeType */
35110
        case oidCmsKeyAgreeType:
35111
            switch (nid) {
35112
                #ifndef NO_SHA
35113
                case dhSinglePass_stdDH_sha1kdf_scheme:
35114
                    return dhSinglePass_stdDH_sha1kdf_scheme;
35115
                #endif
35116
                #ifdef WOLFSSL_SHA224
35117
                case dhSinglePass_stdDH_sha224kdf_scheme:
35118
                    return dhSinglePass_stdDH_sha224kdf_scheme;
35119
                #endif
35120
                #ifndef NO_SHA256
35121
                case dhSinglePass_stdDH_sha256kdf_scheme:
35122
                    return dhSinglePass_stdDH_sha256kdf_scheme;
35123
                #endif
35124
                #ifdef WOLFSSL_SHA384
35125
                case dhSinglePass_stdDH_sha384kdf_scheme:
35126
                    return dhSinglePass_stdDH_sha384kdf_scheme;
35127
                #endif
35128
                #ifdef WOLFSSL_SHA512
35129
                case dhSinglePass_stdDH_sha512kdf_scheme:
35130
                    return dhSinglePass_stdDH_sha512kdf_scheme;
35131
                #endif
35132
            }
35133
            break;
35134
35135
        default:
35136
            WOLFSSL_MSG("NID not in table");
35137
            /* MSVC warns without the cast */
35138
            return (word32)-1;
35139
    }
35140
35141
    /* MSVC warns without the cast */
35142
    return (word32)-1;
35143
}
35144
35145
int oid2nid(word32 oid, int grp)
35146
{
35147
    size_t i;
35148
    /* get OID type */
35149
    switch (grp) {
35150
        /* oidHashType */
35151
        case oidHashType:
35152
            switch (oid) {
35153
            #ifdef WOLFSSL_MD2
35154
                case MD2h:
35155
                    return NID_md2;
35156
            #endif
35157
            #ifndef NO_MD5
35158
                case MD5h:
35159
                    return NID_md5;
35160
            #endif
35161
            #ifndef NO_SHA
35162
                case SHAh:
35163
                    return NID_sha1;
35164
            #endif
35165
                case SHA224h:
35166
                    return NID_sha224;
35167
            #ifndef NO_SHA256
35168
                case SHA256h:
35169
                    return NID_sha256;
35170
            #endif
35171
            #ifdef WOLFSSL_SHA384
35172
                case SHA384h:
35173
                    return NID_sha384;
35174
            #endif
35175
            #ifdef WOLFSSL_SHA512
35176
                case SHA512h:
35177
                    return NID_sha512;
35178
            #endif
35179
            }
35180
            break;
35181
35182
        /*  oidSigType */
35183
        case oidSigType:
35184
            switch (oid) {
35185
            #ifndef NO_DSA
35186
                case CTC_SHAwDSA:
35187
                    return NID_dsaWithSHA1;
35188
                case CTC_SHA256wDSA:
35189
                    return NID_dsa_with_SHA256;
35190
            #endif /* NO_DSA */
35191
            #ifndef NO_RSA
35192
                case CTC_MD2wRSA:
35193
                    return NID_md2WithRSAEncryption;
35194
                case CTC_MD5wRSA:
35195
                    return NID_md5WithRSAEncryption;
35196
                case CTC_SHAwRSA:
35197
                    return NID_sha1WithRSAEncryption;
35198
                case CTC_SHA224wRSA:
35199
                    return NID_sha224WithRSAEncryption;
35200
                case CTC_SHA256wRSA:
35201
                    return NID_sha256WithRSAEncryption;
35202
                case CTC_SHA384wRSA:
35203
                    return NID_sha384WithRSAEncryption;
35204
                case CTC_SHA512wRSA:
35205
                    return NID_sha512WithRSAEncryption;
35206
                #ifdef WOLFSSL_SHA3
35207
                case CTC_SHA3_224wRSA:
35208
                    return NID_RSA_SHA3_224;
35209
                case CTC_SHA3_256wRSA:
35210
                    return NID_RSA_SHA3_256;
35211
                case CTC_SHA3_384wRSA:
35212
                    return NID_RSA_SHA3_384;
35213
                case CTC_SHA3_512wRSA:
35214
                    return NID_RSA_SHA3_512;
35215
                #endif
35216
            #endif /* NO_RSA */
35217
            #ifdef HAVE_ECC
35218
                case CTC_SHAwECDSA:
35219
                    return NID_ecdsa_with_SHA1;
35220
                case CTC_SHA224wECDSA:
35221
                    return NID_ecdsa_with_SHA224;
35222
                case CTC_SHA256wECDSA:
35223
                    return NID_ecdsa_with_SHA256;
35224
                case CTC_SHA384wECDSA:
35225
                    return NID_ecdsa_with_SHA384;
35226
                case CTC_SHA512wECDSA:
35227
                    return NID_ecdsa_with_SHA512;
35228
                #ifdef WOLFSSL_SHA3
35229
                case CTC_SHA3_224wECDSA:
35230
                    return NID_ecdsa_with_SHA3_224;
35231
                case CTC_SHA3_256wECDSA:
35232
                    return NID_ecdsa_with_SHA3_256;
35233
                case CTC_SHA3_384wECDSA:
35234
                    return NID_ecdsa_with_SHA3_384;
35235
                case CTC_SHA3_512wECDSA:
35236
                    return NID_ecdsa_with_SHA3_512;
35237
                #endif
35238
            #endif /* HAVE_ECC */
35239
            }
35240
            break;
35241
35242
        /* oidKeyType */
35243
        case oidKeyType:
35244
            switch (oid) {
35245
            #ifndef NO_DSA
35246
                case DSAk:
35247
                    return NID_dsa;
35248
            #endif /* NO_DSA */
35249
            #ifndef NO_RSA
35250
                case RSAk:
35251
                    return NID_rsaEncryption;
35252
            #endif /* NO_RSA */
35253
            #ifdef HAVE_ECC
35254
                case ECDSAk:
35255
                    return NID_X9_62_id_ecPublicKey;
35256
            #endif /* HAVE_ECC */
35257
            }
35258
            break;
35259
35260
35261
    #ifdef HAVE_ECC
35262
        case oidCurveType:
35263
            switch (oid) {
35264
            case ECC_SECP192R1_OID:
35265
                return NID_X9_62_prime192v1;
35266
            case ECC_PRIME192V2_OID:
35267
                return NID_X9_62_prime192v2;
35268
            case ECC_PRIME192V3_OID:
35269
                return NID_X9_62_prime192v3;
35270
            case ECC_PRIME239V1_OID:
35271
                return NID_X9_62_prime239v1;
35272
            case ECC_PRIME239V2_OID:
35273
                return NID_X9_62_prime239v2;
35274
            case ECC_PRIME239V3_OID:
35275
                return NID_X9_62_prime239v3;
35276
            case ECC_SECP256R1_OID:
35277
                return NID_X9_62_prime256v1;
35278
            case ECC_SECP112R1_OID:
35279
                return NID_secp112r1;
35280
            case ECC_SECP112R2_OID:
35281
                return NID_secp112r2;
35282
            case ECC_SECP128R1_OID:
35283
                return NID_secp128r1;
35284
            case ECC_SECP128R2_OID:
35285
                return NID_secp128r2;
35286
            case ECC_SECP160R1_OID:
35287
                return NID_secp160r1;
35288
            case ECC_SECP160R2_OID:
35289
                return NID_secp160r2;
35290
            case ECC_SECP224R1_OID:
35291
                return NID_secp224r1;
35292
            case ECC_SECP384R1_OID:
35293
                return NID_secp384r1;
35294
            case ECC_SECP521R1_OID:
35295
                return NID_secp521r1;
35296
            case ECC_SECP160K1_OID:
35297
                return NID_secp160k1;
35298
            case ECC_SECP192K1_OID:
35299
                return NID_secp192k1;
35300
            case ECC_SECP224K1_OID:
35301
                return NID_secp224k1;
35302
            case ECC_SECP256K1_OID:
35303
                return NID_secp256k1;
35304
            case ECC_BRAINPOOLP160R1_OID:
35305
                return NID_brainpoolP160r1;
35306
            case ECC_BRAINPOOLP192R1_OID:
35307
                return NID_brainpoolP192r1;
35308
            case ECC_BRAINPOOLP224R1_OID:
35309
                return NID_brainpoolP224r1;
35310
            case ECC_BRAINPOOLP256R1_OID:
35311
                return NID_brainpoolP256r1;
35312
            case ECC_BRAINPOOLP320R1_OID:
35313
                return NID_brainpoolP320r1;
35314
            case ECC_BRAINPOOLP384R1_OID:
35315
                return NID_brainpoolP384r1;
35316
            case ECC_BRAINPOOLP512R1_OID:
35317
                return NID_brainpoolP512r1;
35318
            }
35319
            break;
35320
    #endif /* HAVE_ECC */
35321
35322
        /* oidBlkType */
35323
        case oidBlkType:
35324
            switch (oid) {
35325
            #ifdef WOLFSSL_AES_128
35326
                case AES128CBCb:
35327
                    return AES128CBCb;
35328
            #endif
35329
            #ifdef WOLFSSL_AES_192
35330
                case AES192CBCb:
35331
                    return AES192CBCb;
35332
            #endif
35333
            #ifdef WOLFSSL_AES_256
35334
                case AES256CBCb:
35335
                    return AES256CBCb;
35336
            #endif
35337
            #ifndef NO_DES3
35338
                case DESb:
35339
                    return NID_des;
35340
                case DES3b:
35341
                    return NID_des3;
35342
            #endif
35343
            }
35344
            break;
35345
35346
    #ifdef HAVE_OCSP
35347
        case oidOcspType:
35348
            switch (oid) {
35349
                case OCSP_BASIC_OID:
35350
                    return NID_id_pkix_OCSP_basic;
35351
                case OCSP_NONCE_OID:
35352
                    return OCSP_NONCE_OID;
35353
            }
35354
            break;
35355
    #endif /* HAVE_OCSP */
35356
35357
        /* oidCertExtType */
35358
        case oidCertExtType:
35359
            switch (oid) {
35360
                case BASIC_CA_OID:
35361
                    return NID_basic_constraints;
35362
                case ALT_NAMES_OID:
35363
                    return NID_subject_alt_name;
35364
                case CRL_DIST_OID:
35365
                    return NID_crl_distribution_points;
35366
                case AUTH_INFO_OID:
35367
                    return NID_info_access;
35368
                case AUTH_KEY_OID:
35369
                    return NID_authority_key_identifier;
35370
                case SUBJ_KEY_OID:
35371
                    return NID_subject_key_identifier;
35372
                case INHIBIT_ANY_OID:
35373
                    return NID_inhibit_any_policy;
35374
                case KEY_USAGE_OID:
35375
                    return NID_key_usage;
35376
                case NAME_CONS_OID:
35377
                    return NID_name_constraints;
35378
                case CERT_POLICY_OID:
35379
                    return NID_certificate_policies;
35380
                case EXT_KEY_USAGE_OID:
35381
                    return NID_ext_key_usage;
35382
            }
35383
            break;
35384
35385
        /* oidCertAuthInfoType */
35386
        case oidCertAuthInfoType:
35387
            switch (oid) {
35388
                case AIA_OCSP_OID:
35389
                    return NID_ad_OCSP;
35390
                case AIA_CA_ISSUER_OID:
35391
                    return NID_ad_ca_issuers;
35392
            }
35393
            break;
35394
35395
        /* oidCertPolicyType */
35396
        case oidCertPolicyType:
35397
            switch (oid) {
35398
                case CP_ANY_OID:
35399
                    return NID_any_policy;
35400
            }
35401
            break;
35402
35403
        /* oidCertAltNameType */
35404
        case oidCertAltNameType:
35405
            switch (oid) {
35406
                case HW_NAME_OID:
35407
                    return NID_hw_name_oid;
35408
            }
35409
            break;
35410
35411
        /* oidCertKeyUseType */
35412
        case oidCertKeyUseType:
35413
            switch (oid) {
35414
                case EKU_ANY_OID:
35415
                    return NID_anyExtendedKeyUsage;
35416
                case EKU_SERVER_AUTH_OID:
35417
                    return EKU_SERVER_AUTH_OID;
35418
                case EKU_CLIENT_AUTH_OID:
35419
                    return EKU_CLIENT_AUTH_OID;
35420
                case EKU_OCSP_SIGN_OID:
35421
                    return EKU_OCSP_SIGN_OID;
35422
            }
35423
            break;
35424
35425
        /* oidKdfType */
35426
        case oidKdfType:
35427
            switch (oid) {
35428
                case PBKDF2_OID:
35429
                    return PBKDF2_OID;
35430
            }
35431
            break;
35432
35433
        /* oidPBEType */
35434
        case oidPBEType:
35435
            switch (oid) {
35436
                case PBE_SHA1_RC4_128:
35437
                    return PBE_SHA1_RC4_128;
35438
                case PBE_SHA1_DES:
35439
                    return PBE_SHA1_DES;
35440
                case PBE_SHA1_DES3:
35441
                    return PBE_SHA1_DES3;
35442
            }
35443
            break;
35444
35445
        /* oidKeyWrapType */
35446
        case oidKeyWrapType:
35447
            switch (oid) {
35448
            #ifdef WOLFSSL_AES_128
35449
                case AES128_WRAP:
35450
                    return AES128_WRAP;
35451
            #endif
35452
            #ifdef WOLFSSL_AES_192
35453
                case AES192_WRAP:
35454
                    return AES192_WRAP;
35455
            #endif
35456
            #ifdef WOLFSSL_AES_256
35457
                case AES256_WRAP:
35458
                    return AES256_WRAP;
35459
            #endif
35460
            }
35461
            break;
35462
35463
        /* oidCmsKeyAgreeType */
35464
        case oidCmsKeyAgreeType:
35465
            switch (oid) {
35466
                #ifndef NO_SHA
35467
                case dhSinglePass_stdDH_sha1kdf_scheme:
35468
                    return dhSinglePass_stdDH_sha1kdf_scheme;
35469
                #endif
35470
                #ifdef WOLFSSL_SHA224
35471
                case dhSinglePass_stdDH_sha224kdf_scheme:
35472
                    return dhSinglePass_stdDH_sha224kdf_scheme;
35473
                #endif
35474
                #ifndef NO_SHA256
35475
                case dhSinglePass_stdDH_sha256kdf_scheme:
35476
                    return dhSinglePass_stdDH_sha256kdf_scheme;
35477
                #endif
35478
                #ifdef WOLFSSL_SHA384
35479
                case dhSinglePass_stdDH_sha384kdf_scheme:
35480
                    return dhSinglePass_stdDH_sha384kdf_scheme;
35481
                #endif
35482
                #ifdef WOLFSSL_SHA512
35483
                case dhSinglePass_stdDH_sha512kdf_scheme:
35484
                    return dhSinglePass_stdDH_sha512kdf_scheme;
35485
                #endif
35486
            }
35487
            break;
35488
35489
#ifdef WOLFSSL_CERT_REQ
35490
        case oidCsrAttrType:
35491
            switch (oid) {
35492
                case PKCS9_CONTENT_TYPE_OID:
35493
                    return NID_pkcs9_contentType;
35494
                case CHALLENGE_PASSWORD_OID:
35495
                    return NID_pkcs9_challengePassword;
35496
                case SERIAL_NUMBER_OID:
35497
                    return NID_serialNumber;
35498
                case USER_ID_OID:
35499
                    return NID_userId;
35500
            }
35501
            break;
35502
#endif
35503
35504
        default:
35505
            WOLFSSL_MSG("NID not in table");
35506
    }
35507
    /* If not found in above switch then try the table */
35508
    for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
35509
        if (wolfssl_object_info[i].id == (int)oid) {
35510
            return wolfssl_object_info[i].nid;
35511
        }
35512
    }
35513
35514
    return -1;
35515
}
35516
35517
/* when calling SetIndividualInternal, mpi should be cleared by caller if no
35518
 * longer used. ie mp_free(mpi). This is to free data when fastmath is
35519
 * disabled since a copy of mpi is made by this function and placed into bn.
35520
 */
35521
int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
35522
{
35523
    WOLFSSL_MSG("Entering SetIndividualInternal");
35524
35525
    if (bn == NULL || bn->internal == NULL) {
35526
        WOLFSSL_MSG("bn NULL error");
35527
        return WOLFSSL_FATAL_ERROR;
35528
    }
35529
35530
    if (mpi == NULL) {
35531
        WOLFSSL_MSG("mpi NULL error");
35532
        return WOLFSSL_FATAL_ERROR;
35533
    }
35534
35535
    if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
35536
        WOLFSSL_MSG("mp_copy error");
35537
        return WOLFSSL_FATAL_ERROR;
35538
    }
35539
35540
    return WOLFSSL_SUCCESS;
35541
}
35542
35543
35544
#ifndef NO_ASN
35545
WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai,
35546
                                       WOLFSSL_BIGNUM *bn)
35547
{
35548
#ifdef WOLFSSL_SMALL_STACK
35549
    mp_int* mpi = NULL;
35550
#else
35551
    mp_int mpi[1];
35552
#endif
35553
    word32 idx = 0;
35554
    int ret;
35555
35556
    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_to_BN");
35557
35558
    if (ai == NULL) {
35559
        return NULL;
35560
    }
35561
35562
#ifdef WOLFSSL_SMALL_STACK
35563
    mpi = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
35564
    if (mpi == NULL) {
35565
        return NULL;
35566
    }
35567
#endif
35568
35569
    ret = GetInt(mpi, ai->data, &idx, ai->dataMax);
35570
    if (ret != 0) {
35571
    #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
35572
        ret = mp_init(mpi); /* must init mpi */
35573
        if (ret != MP_OKAY) {
35574
        #ifdef WOLFSSL_SMALL_STACK
35575
            XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
35576
        #endif
35577
            return NULL;
35578
        }
35579
        /* Serial number in QT starts at index 0 of data */
35580
        if (mp_read_unsigned_bin(mpi, (byte*)ai->data, ai->length) != 0) {
35581
                mp_clear(mpi);
35582
            #ifdef WOLFSSL_SMALL_STACK
35583
                XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
35584
            #endif
35585
                return NULL;
35586
            }
35587
    #else
35588
        /* expecting ASN1 format for INTEGER */
35589
        WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret);
35590
    #ifdef WOLFSSL_SMALL_STACK
35591
        XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
35592
    #endif
35593
        return NULL;
35594
    #endif
35595
    }
35596
35597
    /* mp_clear needs called because mpi is copied and causes memory leak with
35598
     * --disable-fastmath */
35599
    ret = SetIndividualExternal(&bn, mpi);
35600
    mp_clear(mpi);
35601
35602
#ifdef WOLFSSL_SMALL_STACK
35603
    XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
35604
#endif
35605
35606
    if (ret != WOLFSSL_SUCCESS) {
35607
        return NULL;
35608
    }
35609
    return bn;
35610
}
35611
#endif /* !NO_ASN */
35612
35613
/* frees all nodes in the current threads error queue
35614
 *
35615
 * id  thread id. ERR_remove_state is depreciated and id is ignored. The
35616
 *     current threads queue will be free'd.
35617
 */
35618
void wolfSSL_ERR_remove_state(unsigned long id)
35619
{
35620
    WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
35621
    (void)id;
35622
    if (wc_ERR_remove_state() != 0) {
35623
        WOLFSSL_MSG("Error with removing the state");
35624
    }
35625
}
35626
35627
35628
WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
35629
{
35630
    static int ctx;  /* wolfcrypt doesn't now need ctx */
35631
35632
    WOLFSSL_MSG("wolfSSL_BN_CTX_new");
35633
    return (WOLFSSL_BN_CTX*)&ctx;
35634
35635
}
35636
35637
void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
35638
{
35639
    (void)ctx;
35640
    WOLFSSL_MSG("wolfSSL_BN_CTX_init");
35641
}
35642
35643
35644
void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
35645
{
35646
    (void)ctx;
35647
    WOLFSSL_MSG("wolfSSL_BN_CTX_free");
35648
    /* do free since static ctx that does nothing */
35649
}
35650
35651
/* WOLFSSL_SUCCESS on ok */
35652
int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
35653
                  const WOLFSSL_BIGNUM* b)
35654
{
35655
    WOLFSSL_MSG("wolfSSL_BN_sub");
35656
35657
    if (r == NULL || a == NULL || b == NULL)
35658
        return 0;
35659
35660
    if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
35661
               (mp_int*)r->internal) == MP_OKAY)
35662
        return WOLFSSL_SUCCESS;
35663
35664
    WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
35665
    return 0;
35666
}
35667
35668
WOLFSSL_API int wolfSSL_BN_mul(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b,
35669
    WOLFSSL_BN_CTX *ctx)
35670
{
35671
    int ret = WOLFSSL_SUCCESS;
35672
35673
    (void)ctx;
35674
35675
    WOLFSSL_ENTER("wolfSSL_BN_mul");
35676
35677
    if (r == NULL || a == NULL || b == NULL || r->internal == NULL ||
35678
        a->internal == NULL || b->internal == NULL) {
35679
        ret = WOLFSSL_FAILURE;
35680
    }
35681
35682
    if (ret == WOLFSSL_SUCCESS) {
35683
        ret = mp_mul((mp_int*)a->internal, (mp_int*)b->internal,
35684
                     (mp_int*)r->internal);
35685
        if (ret == MP_OKAY) {
35686
            ret = WOLFSSL_SUCCESS;
35687
        }
35688
        else {
35689
            ret = WOLFSSL_FAILURE;
35690
        }
35691
    }
35692
35693
    WOLFSSL_LEAVE("wolfSSL_BN_mul", ret);
35694
35695
    return ret;
35696
}
35697
35698
#ifndef WOLFSSL_SP_MATH
35699
int wolfSSL_BN_div(WOLFSSL_BIGNUM* dv, WOLFSSL_BIGNUM* rem,
35700
                   const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* d,
35701
                   WOLFSSL_BN_CTX* ctx)
35702
{
35703
    int ret = WOLFSSL_SUCCESS;
35704
35705
    (void)ctx;
35706
35707
    WOLFSSL_ENTER("wolfSSL_BN_div");
35708
35709
    if (dv == NULL || rem == NULL || a == NULL || d == NULL ||
35710
        dv->internal == NULL || rem->internal == NULL || a->internal == NULL ||
35711
        d->internal == NULL) {
35712
        ret = WOLFSSL_FAILURE;
35713
    }
35714
35715
    if (ret == WOLFSSL_SUCCESS) {
35716
        ret = mp_div((mp_int*)a->internal, (mp_int*)d->internal,
35717
                     (mp_int*)dv->internal, (mp_int*)rem->internal);
35718
        if (ret == MP_OKAY) {
35719
            ret = WOLFSSL_SUCCESS;
35720
        }
35721
        else {
35722
            ret = WOLFSSL_FAILURE;
35723
        }
35724
    }
35725
35726
    WOLFSSL_LEAVE("wolfSSL_BN_div", ret);
35727
35728
    return ret;
35729
}
35730
#endif
35731
35732
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) /* Needed to get mp_gcd. */
35733
int wolfSSL_BN_gcd(WOLFSSL_BIGNUM* r, WOLFSSL_BIGNUM* a, WOLFSSL_BIGNUM* b,
35734
                   WOLFSSL_BN_CTX* ctx)
35735
{
35736
    int ret = WOLFSSL_SUCCESS;
35737
35738
    (void)ctx;
35739
35740
    WOLFSSL_ENTER("wolfSSL_BN_gcd");
35741
35742
    if (r == NULL || a == NULL || b == NULL || r->internal == NULL ||
35743
        a->internal == NULL || b->internal == NULL) {
35744
        ret = WOLFSSL_FAILURE;
35745
    }
35746
35747
    if (ret == WOLFSSL_SUCCESS) {
35748
        ret = mp_gcd((mp_int*)a->internal, (mp_int*)b->internal,
35749
                     (mp_int*)r->internal);
35750
        if (ret == MP_OKAY) {
35751
            ret = WOLFSSL_SUCCESS;
35752
        }
35753
        else {
35754
            ret = WOLFSSL_FAILURE;
35755
        }
35756
    }
35757
35758
    WOLFSSL_LEAVE("wolfSSL_BN_gcd", ret);
35759
35760
    return ret;
35761
}
35762
#endif /* !NO_RSA && WOLFSSL_KEY_GEN */
35763
35764
/* WOLFSSL_SUCCESS on ok */
35765
int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
35766
                  const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
35767
{
35768
    (void)c;
35769
    WOLFSSL_MSG("wolfSSL_BN_mod");
35770
35771
    if (r == NULL || a == NULL || b == NULL)
35772
        return 0;
35773
35774
    if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
35775
               (mp_int*)r->internal) == MP_OKAY)
35776
        return WOLFSSL_SUCCESS;
35777
35778
    WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
35779
    return 0;
35780
}
35781
35782
35783
/* r = (a^p) % m */
35784
int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
35785
      const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
35786
{
35787
    int ret;
35788
35789
    WOLFSSL_ENTER("wolfSSL_BN_mod_exp");
35790
35791
    (void) ctx;
35792
    if (r == NULL || a == NULL || p == NULL || m == NULL) {
35793
        WOLFSSL_MSG("Bad Argument");
35794
        return WOLFSSL_FAILURE;
35795
    }
35796
35797
    if ((ret = mp_exptmod((mp_int*)a->internal,(mp_int*)p->internal,
35798
               (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
35799
        return WOLFSSL_SUCCESS;
35800
    }
35801
35802
    WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret);
35803
    (void)ret;
35804
35805
    return WOLFSSL_FAILURE;
35806
}
35807
35808
/* r = (a * p) % m */
35809
int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
35810
        const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
35811
{
35812
    int ret;
35813
35814
    WOLFSSL_ENTER("wolfSSL_BN_mod_mul");
35815
35816
    (void) ctx;
35817
    if (r == NULL || a == NULL || p == NULL || m == NULL) {
35818
        WOLFSSL_MSG("Bad Argument");
35819
        return SSL_FAILURE;
35820
    }
35821
35822
    if ((ret = mp_mulmod((mp_int*)a->internal,(mp_int*)p->internal,
35823
               (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
35824
        return WOLFSSL_SUCCESS;
35825
    }
35826
35827
    WOLFSSL_LEAVE("wolfSSL_BN_mod_mul", ret);
35828
    (void)ret;
35829
35830
    return SSL_FAILURE;
35831
}
35832
35833
const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
35834
{
35835
    WOLFSSL_MSG("wolfSSL_BN_value_one");
35836
35837
    if (bn_one == NULL) {
35838
        bn_one = wolfSSL_BN_new();
35839
        if (bn_one) {
35840
            if (mp_set_int((mp_int*)bn_one->internal, 1) != MP_OKAY) {
35841
                /* handle error by freeing BN and returning NULL */
35842
                wolfSSL_BN_free(bn_one);
35843
                bn_one = NULL;
35844
            }
35845
        }
35846
    }
35847
35848
    return bn_one;
35849
}
35850
35851
/* return compliant with OpenSSL
35852
 *   size of BIGNUM in bytes, 0 if error */
35853
int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
35854
{
35855
    WOLFSSL_ENTER("wolfSSL_BN_num_bytes");
35856
35857
    if (bn == NULL || bn->internal == NULL)
35858
        return WOLFSSL_FAILURE;
35859
35860
    return mp_unsigned_bin_size((mp_int*)bn->internal);
35861
}
35862
35863
/* return compliant with OpenSSL
35864
 *   size of BIGNUM in bits, 0 if error */
35865
int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
35866
{
35867
    WOLFSSL_ENTER("wolfSSL_BN_num_bits");
35868
35869
    if (bn == NULL || bn->internal == NULL)
35870
        return WOLFSSL_FAILURE;
35871
35872
    return mp_count_bits((mp_int*)bn->internal);
35873
}
35874
35875
int wolfSSL_BN_is_negative(const WOLFSSL_BIGNUM* bn)
35876
{
35877
    if (bn == NULL)
35878
        return WOLFSSL_FAILURE;
35879
35880
    return mp_isneg((mp_int*)bn->internal);
35881
}
35882
35883
WOLFSSL_API void wolfSSL_BN_zero(WOLFSSL_BIGNUM* bn)
35884
{
35885
    if (bn == NULL || bn->internal == NULL) {
35886
        return;
35887
    }
35888
35889
    mp_zero((mp_int*)bn->internal);
35890
}
35891
35892
WOLFSSL_API int wolfSSL_BN_one(WOLFSSL_BIGNUM* bn)
35893
{
35894
    int ret = WOLFSSL_SUCCESS;
35895
35896
    if (bn == NULL || bn->internal == NULL) {
35897
        return WOLFSSL_FAILURE;
35898
    }
35899
35900
    if (ret == WOLFSSL_SUCCESS) {
35901
        ret = wolfSSL_BN_set_word(bn, 1);
35902
    }
35903
35904
    return ret;
35905
}
35906
35907
/* return compliant with OpenSSL
35908
 *   1 if BIGNUM is zero, 0 else */
35909
int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
35910
{
35911
    WOLFSSL_MSG("wolfSSL_BN_is_zero");
35912
35913
    if (bn == NULL || bn->internal == NULL)
35914
        return WOLFSSL_FAILURE;
35915
35916
    if (mp_iszero((mp_int*)bn->internal) == MP_YES)
35917
        return WOLFSSL_SUCCESS;
35918
35919
    return WOLFSSL_FAILURE;
35920
}
35921
35922
/* return compliant with OpenSSL
35923
 *   1 if BIGNUM is one, 0 else */
35924
int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
35925
{
35926
    WOLFSSL_MSG("wolfSSL_BN_is_one");
35927
35928
    if (bn == NULL || bn->internal == NULL)
35929
        return WOLFSSL_FAILURE;
35930
35931
    if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
35932
        return WOLFSSL_SUCCESS;
35933
35934
    return WOLFSSL_FAILURE;
35935
}
35936
35937
/* return compliant with OpenSSL
35938
 *   1 if BIGNUM is odd, 0 else */
35939
int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
35940
{
35941
    WOLFSSL_MSG("wolfSSL_BN_is_odd");
35942
35943
    if (bn == NULL || bn->internal == NULL)
35944
        return WOLFSSL_FAILURE;
35945
35946
    if (mp_isodd((mp_int*)bn->internal) == MP_YES)
35947
        return WOLFSSL_SUCCESS;
35948
35949
    return WOLFSSL_FAILURE;
35950
}
35951
35952
/* return compliant with OpenSSL
35953
 *   1 if BIGNUM is word, 0 else */
35954
int wolfSSL_BN_is_word(const WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
35955
{
35956
    WOLFSSL_MSG("wolfSSL_BN_is_word");
35957
35958
    if (bn == NULL || bn->internal == NULL) {
35959
        WOLFSSL_MSG("bn NULL error");
35960
        return WOLFSSL_FAILURE;
35961
    }
35962
35963
    if (w <= (WOLFSSL_BN_ULONG)MP_MASK) {
35964
        if (mp_isword((mp_int*)bn->internal, (mp_digit)w) == MP_YES) {
35965
            return WOLFSSL_SUCCESS;
35966
        }
35967
    } else {
35968
        int ret;
35969
        mp_int w_mp;
35970
        if (mp_init(&w_mp) != MP_OKAY)
35971
            return WOLFSSL_FAILURE;
35972
        if (mp_set_int(&w_mp, w) != MP_OKAY)
35973
            return WOLFSSL_FAILURE;
35974
        ret = mp_cmp((mp_int *)bn->internal, &w_mp);
35975
        mp_free(&w_mp);
35976
        if (ret == MP_EQ)
35977
            return WOLFSSL_SUCCESS;
35978
    }
35979
35980
    return WOLFSSL_FAILURE;
35981
}
35982
35983
/* return compliant with OpenSSL
35984
 *   -1 if a < b, 0 if a == b and 1 if a > b
35985
 */
35986
int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
35987
{
35988
    int ret;
35989
35990
    WOLFSSL_MSG("wolfSSL_BN_cmp");
35991
35992
    if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
35993
        return WOLFSSL_FATAL_ERROR;
35994
35995
    ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
35996
35997
    return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
35998
}
35999
36000
/* return compliant with OpenSSL
36001
 *   length of BIGNUM in bytes, -1 if error */
36002
int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
36003
{
36004
    WOLFSSL_MSG("wolfSSL_BN_bn2bin");
36005
36006
    if (bn == NULL || bn->internal == NULL) {
36007
        WOLFSSL_MSG("NULL bn error");
36008
        return WOLFSSL_FATAL_ERROR;
36009
    }
36010
36011
    if (r == NULL)
36012
        return mp_unsigned_bin_size((mp_int*)bn->internal);
36013
36014
    if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
36015
        WOLFSSL_MSG("mp_to_unsigned_bin error");
36016
        return WOLFSSL_FATAL_ERROR;
36017
    }
36018
36019
    return mp_unsigned_bin_size((mp_int*)bn->internal);
36020
}
36021
36022
36023
WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
36024
                            WOLFSSL_BIGNUM* ret)
36025
{
36026
    int weOwn = 0;
36027
36028
    WOLFSSL_MSG("wolfSSL_BN_bin2bn");
36029
36030
    /* if ret is null create a BN */
36031
    if (ret == NULL) {
36032
        ret = wolfSSL_BN_new();
36033
        weOwn = 1;
36034
        if (ret == NULL)
36035
            return NULL;
36036
    }
36037
36038
    /* check ret and ret->internal then read in value */
36039
    if (ret && ret->internal) {
36040
        if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
36041
            WOLFSSL_MSG("mp_read_unsigned_bin failure");
36042
            if (weOwn)
36043
                wolfSSL_BN_free(ret);
36044
            return NULL;
36045
        }
36046
    } else {
36047
        /* This may be overly defensive */
36048
        if (weOwn)
36049
            wolfSSL_BN_free(ret);
36050
        return NULL;
36051
    }
36052
36053
    return ret;
36054
}
36055
36056
/* return compliant with OpenSSL
36057
 *   1 if success, 0 if error */
36058
#ifndef NO_WOLFSSL_STUB
36059
int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
36060
{
36061
    (void)bn;
36062
    (void)n;
36063
    WOLFSSL_ENTER("wolfSSL_BN_mask_bits");
36064
    WOLFSSL_STUB("BN_mask_bits");
36065
    return SSL_FAILURE;
36066
}
36067
#endif
36068
36069
/* WOLFSSL_SUCCESS on ok */
36070
int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
36071
{
36072
    int ret = WOLFSSL_SUCCESS;
36073
    int len = (bits + 7) / 8;
36074
    WC_RNG* rng = &globalRNG;
36075
    byte* buff = NULL;
36076
36077
    WOLFSSL_ENTER("wolfSSL_BN_rand");
36078
36079
    if ((bn == NULL || bn->internal == NULL) || bits < 0 ||
36080
        (bits == 0 && (bottom != 0 || top != -1)) || (bits == 1 && top > 0)) {
36081
        WOLFSSL_MSG("Bad argument");
36082
        ret = WOLFSSL_FAILURE;
36083
    }
36084
36085
    if (ret == WOLFSSL_SUCCESS) {
36086
        if (len == 0) {
36087
            mp_zero((mp_int*)bn->internal);
36088
        }
36089
        else {
36090
            buff = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36091
            if (buff == NULL) {
36092
                WOLFSSL_MSG("Failed to allocate buffer.");
36093
                XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36094
                ret = WOLFSSL_FAILURE;
36095
            }
36096
36097
            if (ret == WOLFSSL_SUCCESS && initGlobalRNG == 0 &&
36098
                wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
36099
                WOLFSSL_MSG("Failed to use global RNG.");
36100
                ret = WOLFSSL_FAILURE;
36101
            }
36102
36103
            if (ret == WOLFSSL_SUCCESS &&
36104
                wc_RNG_GenerateBlock(rng, buff, len) != 0) {
36105
                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
36106
                ret = WOLFSSL_FAILURE;
36107
            }
36108
            if (ret == WOLFSSL_SUCCESS &&
36109
                mp_read_unsigned_bin((mp_int*)bn->internal,buff,len)
36110
                != MP_OKAY) {
36111
                    WOLFSSL_MSG("mp_read_unsigned_bin failed");
36112
                    ret = WOLFSSL_FAILURE;
36113
            }
36114
            if (ret == WOLFSSL_SUCCESS) {
36115
                /* Truncate to requested bit length. */
36116
                mp_rshb((mp_int*)bn->internal, 8 - (bits % 8));
36117
36118
                if (top == 0) {
36119
                    if (mp_set_bit((mp_int*)bn->internal, bits - 1)
36120
                        != MP_OKAY) {
36121
                        WOLFSSL_MSG("Failed to set top bit");
36122
                        ret = WOLFSSL_FAILURE;
36123
                    }
36124
                }
36125
                else if (top > 0) {
36126
                    if (mp_set_bit((mp_int*)bn->internal, bits - 1)
36127
                        != MP_OKAY ||
36128
                        mp_set_bit((mp_int*)bn->internal, bits - 2)
36129
                        != MP_OKAY) {
36130
                        WOLFSSL_MSG("Failed to set top 2 bits");
36131
                        ret = WOLFSSL_FAILURE;
36132
                    }
36133
                }
36134
            }
36135
            if (ret == WOLFSSL_SUCCESS && bottom &&
36136
                mp_set_bit((mp_int*)bn->internal, 0) != MP_OKAY) {
36137
                WOLFSSL_MSG("Failed to set 0th bit");
36138
                ret = WOLFSSL_FAILURE;
36139
            }
36140
36141
            if (buff != NULL) {
36142
                XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36143
            }
36144
        }
36145
    }
36146
36147
    WOLFSSL_LEAVE("wolfSSL_BN_rand", ret);
36148
36149
    return ret;
36150
}
36151
36152
/**
36153
 * N = length of range input var
36154
 * Generate N-bit length numbers until generated number is less than range
36155
 * @param r     Output number
36156
 * @param range The upper limit of generated output
36157
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
36158
 */
36159
int wolfSSL_BN_rand_range(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *range)
36160
{
36161
    int n;
36162
    int iter = 0;
36163
    WOLFSSL_MSG("wolfSSL_BN_rand_range");
36164
36165
    if (r == NULL || range == NULL) {
36166
        WOLFSSL_MSG("Bad parameter");
36167
        return WOLFSSL_FAILURE;
36168
    }
36169
36170
    n = wolfSSL_BN_num_bits(range);
36171
36172
    if (n <= 1) {
36173
        wolfSSL_BN_zero(r);
36174
    }
36175
    else {
36176
        do {
36177
            if (iter >= 100) {
36178
                WOLFSSL_MSG("wolfSSL_BN_rand_range too many iterations");
36179
                return WOLFSSL_FAILURE;
36180
            }
36181
            iter++;
36182
            if (wolfSSL_BN_pseudo_rand(r, n, -1, 0) == WOLFSSL_FAILURE) {
36183
                WOLFSSL_MSG("wolfSSL_BN_rand error");
36184
                return WOLFSSL_FAILURE;
36185
            }
36186
        } while(wolfSSL_BN_cmp(r, range) >= 0);
36187
    }
36188
    return WOLFSSL_SUCCESS;
36189
}
36190
36191
/* WOLFSSL_SUCCESS on ok
36192
 * code is same as wolfSSL_BN_rand except for how top and bottom is handled.
36193
 * top -1 then leave most sig bit alone
36194
 * top 0 then most sig is set to 1
36195
 * top is 1 then first two most sig bits are 1
36196
 *
36197
 * bottom is hot then odd number */
36198
int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
36199
{
36200
    int           ret    = 0;
36201
    int           len;
36202
    int           initTmpRng = 0;
36203
    WC_RNG*       rng    = NULL;
36204
#ifdef WOLFSSL_SMALL_STACK
36205
    WC_RNG*       tmpRNG = NULL;
36206
    byte*         buff   = NULL;
36207
#else
36208
    WC_RNG        tmpRNG[1];
36209
    byte          buff[1024];
36210
#endif
36211
36212
    WOLFSSL_ENTER("wolfSSL_BN_pseudo_rand");
36213
36214
    if (bits <= 0) {
36215
        return WOLFSSL_FAILURE;
36216
    }
36217
36218
    len = bits / 8;
36219
    if (bits % 8)
36220
        len++;
36221
36222
    /* has to be a length of at least 1 since we set buf[0] and buf[len-1] */
36223
    if (top == 1 || top == 0 || bottom == 1) {
36224
        if (len < 1) {
36225
            return WOLFSSL_FAILURE;
36226
        }
36227
    }
36228
36229
#ifdef WOLFSSL_SMALL_STACK
36230
    buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
36231
    tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
36232
    if (buff == NULL || tmpRNG == NULL) {
36233
        XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
36234
        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36235
        return ret;
36236
    }
36237
#endif
36238
36239
    if (bn == NULL || bn->internal == NULL)
36240
        WOLFSSL_MSG("Bad function arguments");
36241
    else if (wc_InitRng(tmpRNG) == 0) {
36242
        rng = tmpRNG;
36243
        initTmpRng = 1;
36244
    }
36245
    else if (initGlobalRNG)
36246
        rng = &globalRNG;
36247
36248
    if (rng) {
36249
        if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
36250
            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
36251
        else {
36252
            switch (top) {
36253
                case -1:
36254
                    break;
36255
36256
                case 0:
36257
                    buff[0] |= 0x80;
36258
                    break;
36259
36260
                case 1:
36261
                    buff[0] |= 0x80 | 0x40;
36262
                    break;
36263
            }
36264
36265
            if (bottom == 1) {
36266
                buff[len-1] |= 0x01;
36267
            }
36268
36269
            if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
36270
                WOLFSSL_MSG("mp read bin failed");
36271
            else
36272
                ret = WOLFSSL_SUCCESS;
36273
        }
36274
    }
36275
36276
    if (initTmpRng)
36277
        wc_FreeRng(tmpRNG);
36278
36279
#ifdef WOLFSSL_SMALL_STACK
36280
    XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
36281
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36282
#endif
36283
36284
    return ret;
36285
}
36286
36287
/* return code compliant with OpenSSL :
36288
 *   1 if bit set, 0 else
36289
 */
36290
int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
36291
{
36292
    if (bn == NULL || bn->internal == NULL) {
36293
        WOLFSSL_MSG("bn NULL error");
36294
        return WOLFSSL_FAILURE;
36295
    }
36296
36297
    return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
36298
}
36299
36300
/* return code compliant with OpenSSL :
36301
 *   1 if success, 0 else
36302
 */
36303
int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
36304
{
36305
    if (bn == NULL || bn->internal == NULL) {
36306
        WOLFSSL_MSG("bn NULL error");
36307
        return WOLFSSL_FAILURE;
36308
    }
36309
36310
    if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
36311
        WOLFSSL_MSG("mp_set_bit error");
36312
        return WOLFSSL_FAILURE;
36313
    }
36314
36315
    return WOLFSSL_SUCCESS;
36316
}
36317
36318
36319
int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n)
36320
{
36321
    int ret = WOLFSSL_FAILURE;
36322
#ifndef WOLFSSL_SMALL_STACK
36323
    mp_int tmp[1];
36324
#else
36325
    mp_int* tmp = NULL;
36326
#endif
36327
36328
    if (bn == NULL || bn->internal == NULL) {
36329
        WOLFSSL_MSG("bn NULL error");
36330
        goto end;
36331
    }
36332
    if (mp_is_bit_set((mp_int*)bn->internal, n)) {
36333
#ifdef WOLFSSL_SMALL_STACK
36334
       tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
36335
       if (tmp == NULL) {
36336
           goto end;
36337
       }
36338
#endif
36339
        if (mp_init(tmp) != MP_OKAY) {
36340
            goto end;
36341
        }
36342
        if (mp_set_bit(tmp, n) != MP_OKAY) {
36343
            goto cleanup;
36344
        }
36345
        if (mp_sub((mp_int*)bn->internal, tmp, (mp_int*)bn->internal) != MP_OKAY) {
36346
            goto cleanup;
36347
        }
36348
    } else {
36349
        goto end;
36350
    }
36351
36352
    ret = WOLFSSL_SUCCESS;
36353
cleanup:
36354
    mp_clear(tmp);
36355
36356
end:
36357
#ifdef WOLFSSL_SMALL_STACK
36358
    if (tmp)
36359
        XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
36360
#endif
36361
    return ret;
36362
}
36363
36364
36365
/* WOLFSSL_SUCCESS on ok */
36366
/* Note on use: this function expects str to be an even length. It is
36367
 * converting pairs of bytes into 8-bit values. As an example, the RSA
36368
 * public exponent is commonly 0x010001. To get it to convert, you need
36369
 * to pass in the string "010001", it will fail if you use "10001". This
36370
 * is an affect of how Base16_Decode() works.
36371
 */
36372
int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
36373
{
36374
    int     ret     = 0;
36375
    word32  decSz   = 1024;
36376
#ifdef WOLFSSL_SMALL_STACK
36377
    byte*   decoded;
36378
#else
36379
    byte    decoded[1024];
36380
#endif
36381
    int     weOwn = 0;
36382
    int     strLen;
36383
36384
    WOLFSSL_MSG("wolfSSL_BN_hex2bn");
36385
36386
#ifdef WOLFSSL_SMALL_STACK
36387
    decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_DER);
36388
    if (decoded == NULL)
36389
        return ret;
36390
#endif
36391
36392
    if (str == NULL || str[0] == '\0') {
36393
        WOLFSSL_MSG("Bad function argument");
36394
        ret = WOLFSSL_FAILURE;
36395
    } else {
36396
        strLen = (int)XSTRLEN(str);
36397
        /* ignore trailing new lines */
36398
        while (str[strLen-1] == '\n' && strLen > 0) strLen--;
36399
36400
        if (Base16_Decode((byte*)str, strLen, decoded, &decSz) < 0)
36401
            WOLFSSL_MSG("Bad Base16_Decode error");
36402
        else if (bn == NULL)
36403
            ret = decSz;
36404
        else {
36405
            if (*bn == NULL) {
36406
                *bn = wolfSSL_BN_new();
36407
                if (*bn != NULL) {
36408
                    weOwn = 1;
36409
                }
36410
            }
36411
36412
            if (*bn == NULL)
36413
                WOLFSSL_MSG("BN new failed");
36414
            else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) {
36415
                WOLFSSL_MSG("Bad bin2bn error");
36416
                if (weOwn == 1) {
36417
                    wolfSSL_BN_free(*bn); /* Free new BN */
36418
                }
36419
            }
36420
            else
36421
                ret = WOLFSSL_SUCCESS;
36422
        }
36423
    }
36424
36425
#ifdef WOLFSSL_SMALL_STACK
36426
    XFREE(decoded, NULL, DYNAMIC_TYPE_DER);
36427
#endif
36428
36429
    return ret;
36430
}
36431
36432
36433
WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
36434
{
36435
    WOLFSSL_BIGNUM* ret;
36436
36437
    WOLFSSL_MSG("wolfSSL_BN_dup");
36438
36439
    if (bn == NULL || bn->internal == NULL) {
36440
        WOLFSSL_MSG("bn NULL error");
36441
        return NULL;
36442
    }
36443
36444
    ret = wolfSSL_BN_new();
36445
    if (ret == NULL) {
36446
        WOLFSSL_MSG("bn new error");
36447
        return NULL;
36448
    }
36449
36450
    if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
36451
        WOLFSSL_MSG("mp_copy error");
36452
        wolfSSL_BN_free(ret);
36453
        return NULL;
36454
    }
36455
36456
    ret->neg = bn->neg;
36457
36458
    return ret;
36459
}
36460
36461
36462
WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
36463
{
36464
    WOLFSSL_MSG("wolfSSL_BN_copy");
36465
36466
    if (r == NULL || bn == NULL) {
36467
        WOLFSSL_MSG("r or bn NULL error");
36468
        return NULL;
36469
    }
36470
36471
    if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
36472
        WOLFSSL_MSG("mp_copy error");
36473
        return NULL;
36474
    }
36475
36476
    r->neg = bn->neg;
36477
36478
    return r;
36479
}
36480
36481
/* return code compliant with OpenSSL :
36482
 *   1 if success, 0 else
36483
 */
36484
int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, unsigned long w)
36485
{
36486
    WOLFSSL_MSG("wolfSSL_BN_set_word");
36487
36488
    if (bn == NULL) {
36489
        WOLFSSL_MSG("bn NULL error");
36490
        return WOLFSSL_FAILURE;
36491
    }
36492
36493
    if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
36494
        WOLFSSL_MSG("mp_init_set_int error");
36495
        return WOLFSSL_FAILURE;
36496
    }
36497
36498
    return WOLFSSL_SUCCESS;
36499
}
36500
36501
static WOLFSSL_BN_ULONG wolfSSL_BN_get_word_1(mp_int *mp) {
36502
#if DIGIT_BIT >= (SIZEOF_LONG * CHAR_BIT)
36503
    return (WOLFSSL_BN_ULONG)mp->dp[0];
36504
#else
36505
    WOLFSSL_BN_ULONG ret = 0UL;
36506
    int digit_i;
36507
36508
    for (digit_i = 0; digit_i < mp->used; ++digit_i)
36509
        ret |= ((WOLFSSL_BN_ULONG)mp->dp[digit_i]) << (DIGIT_BIT * digit_i);
36510
36511
    return ret;
36512
#endif
36513
}
36514
36515
/* Returns the big number as an unsigned long if possible.
36516
 *
36517
 * bn  big number structure to get value from
36518
 *
36519
 * Returns value or 0xFFFFFFFFL if bigger than unsigned long.
36520
 */
36521
WOLFSSL_BN_ULONG wolfSSL_BN_get_word(const WOLFSSL_BIGNUM* bn)
36522
{
36523
    WOLFSSL_MSG("wolfSSL_BN_get_word");
36524
36525
    if (bn == NULL) {
36526
        WOLFSSL_MSG("Invalid argument");
36527
        return 0;
36528
    }
36529
36530
    if (wolfSSL_BN_num_bytes(bn) > (int)sizeof(unsigned long)) {
36531
        WOLFSSL_MSG("bignum is larger than unsigned long");
36532
        return 0xFFFFFFFFL;
36533
    }
36534
36535
    return wolfSSL_BN_get_word_1((mp_int*)bn->internal);
36536
}
36537
36538
/* return code compliant with OpenSSL :
36539
 *   number length in decimal if success, 0 if error
36540
 */
36541
#ifndef NO_WOLFSSL_STUB
36542
int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
36543
{
36544
    (void)bn;
36545
    (void)str;
36546
36547
    WOLFSSL_MSG("wolfSSL_BN_dec2bn");
36548
    WOLFSSL_STUB("BN_dec2bn");
36549
    return SSL_FAILURE;
36550
}
36551
#endif
36552
36553
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
36554
char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
36555
{
36556
    int len = 0;
36557
    char *buf;
36558
36559
    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
36560
36561
    if (bn == NULL || bn->internal == NULL) {
36562
        WOLFSSL_MSG("bn NULL error");
36563
        return NULL;
36564
    }
36565
36566
    if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_DEC, &len) != MP_OKAY) {
36567
        WOLFSSL_MSG("mp_radix_size failure");
36568
        return NULL;
36569
    }
36570
36571
    buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
36572
    if (buf == NULL) {
36573
        WOLFSSL_MSG("BN_bn2dec malloc buffer failure");
36574
        return NULL;
36575
    }
36576
36577
    if (mp_todecimal((mp_int*)bn->internal, buf) != MP_OKAY) {
36578
        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
36579
        return NULL;
36580
    }
36581
36582
    return buf;
36583
}
36584
#else
36585
char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
36586
{
36587
    (void)bn;
36588
36589
    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
36590
36591
    return NULL;
36592
}
36593
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
36594
36595
/* Internal function for adding/subtracting an unsigned long from a
36596
 * WOLFSSL_BIGNUM. To add, pass "sub" as 0. To subtract, pass it as 1.
36597
 * Returns 1 (WOLFSSL_SUCCESS) on success and 0 (WOLFSSL_FAILURE) on failure.
36598
 */
36599
static int wolfSSL_BN_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
36600
                                   int sub)
36601
{
36602
    int ret = WOLFSSL_SUCCESS;
36603
    int rc = 0;
36604
#ifdef WOLFSSL_SMALL_STACK
36605
    mp_int *w_mp = (mp_int *)XMALLOC(sizeof(*w_mp), NULL,
36606
                                     DYNAMIC_TYPE_TMP_BUFFER);
36607
    if (w_mp == NULL)
36608
        return WOLFSSL_FAILURE;
36609
#else
36610
    mp_int w_mp[1];
36611
#endif
36612
36613
    XMEMSET(w_mp, 0, sizeof(*w_mp));
36614
36615
    if (bn == NULL || bn->internal == NULL) {
36616
        WOLFSSL_MSG("bn NULL error");
36617
        ret = WOLFSSL_FAILURE;
36618
    }
36619
36620
    if (ret == WOLFSSL_SUCCESS) {
36621
        if (w <= (WOLFSSL_BN_ULONG)MP_MASK) {
36622
            if (sub == 1) {
36623
                rc = mp_sub_d((mp_int*)bn->internal, (mp_digit)w,
36624
                              (mp_int*)bn->internal);
36625
            }
36626
            else {
36627
                rc = mp_add_d((mp_int*)bn->internal, (mp_digit)w,
36628
                              (mp_int*)bn->internal);
36629
            }
36630
            if (rc != MP_OKAY) {
36631
                WOLFSSL_MSG("mp_add/sub_d error");
36632
                ret = WOLFSSL_FAILURE;
36633
            }
36634
        }
36635
        else {
36636
            if (mp_init(w_mp) != MP_OKAY) {
36637
                ret = WOLFSSL_FAILURE;
36638
            }
36639
            if (ret == WOLFSSL_SUCCESS) {
36640
                if (mp_set_int(w_mp, w) != MP_OKAY) {
36641
                    ret = WOLFSSL_FAILURE;
36642
                }
36643
            }
36644
            if (ret == WOLFSSL_SUCCESS) {
36645
                if (sub == 1) {
36646
                    rc = mp_sub((mp_int *)bn->internal, w_mp,
36647
                                (mp_int *)bn->internal);
36648
                }
36649
                else {
36650
                    rc = mp_add((mp_int *)bn->internal, w_mp,
36651
                                (mp_int *)bn->internal);
36652
                }
36653
                if (rc != MP_OKAY) {
36654
                    WOLFSSL_MSG("mp_add/sub error");
36655
                    ret = WOLFSSL_FAILURE;
36656
                }
36657
            }
36658
        }
36659
    }
36660
36661
    mp_free(w_mp);
36662
36663
#ifdef WOLFSSL_SMALL_STACK
36664
    XFREE(w_mp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36665
#endif
36666
36667
    return ret;
36668
}
36669
36670
/* return code compliant with OpenSSL :
36671
 *   1 if success, 0 else
36672
 */
36673
int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
36674
{
36675
    int ret;
36676
36677
    WOLFSSL_ENTER("wolfSSL_BN_add_word");
36678
36679
    ret = wolfSSL_BN_add_word_int(bn, w, 0);
36680
36681
    WOLFSSL_LEAVE("wolfSSL_BN_add_word", ret);
36682
36683
    return ret;
36684
}
36685
36686
/* return code compliant with OpenSSL :
36687
 *   1 if success, 0 else
36688
 */
36689
WOLFSSL_API int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
36690
{
36691
    int ret;
36692
36693
    WOLFSSL_ENTER("wolfSSL_BN_sub_word");
36694
36695
    ret = wolfSSL_BN_add_word_int(bn, w, 1);
36696
36697
    WOLFSSL_LEAVE("wolfSSL_BN_sub_word", ret);
36698
36699
    return ret;
36700
}
36701
36702
#ifndef WOLFSSL_SP_MATH
36703
/* return code compliant with OpenSSL :
36704
 *   1 if success, 0 else
36705
 */
36706
int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
36707
{
36708
    WOLFSSL_MSG("wolfSSL_BN_lshift");
36709
36710
    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
36711
        WOLFSSL_MSG("bn NULL error");
36712
        return WOLFSSL_FAILURE;
36713
    }
36714
36715
    if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
36716
        WOLFSSL_MSG("mp_mul_2d error");
36717
        return WOLFSSL_FAILURE;
36718
    }
36719
36720
    return WOLFSSL_SUCCESS;
36721
}
36722
36723
/* return code compliant with OpenSSL :
36724
 *   1 if success, 0 else
36725
 */
36726
int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
36727
{
36728
    WOLFSSL_MSG("wolfSSL_BN_rshift");
36729
36730
    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
36731
        WOLFSSL_MSG("bn NULL error");
36732
        return WOLFSSL_FAILURE;
36733
    }
36734
36735
    if (mp_div_2d((mp_int*)bn->internal, n,
36736
                  (mp_int*)r->internal, NULL) != MP_OKAY) {
36737
        WOLFSSL_MSG("mp_mul_2d error");
36738
        return WOLFSSL_FAILURE;
36739
    }
36740
36741
    return WOLFSSL_SUCCESS;
36742
}
36743
#endif
36744
36745
/* return code compliant with OpenSSL :
36746
 *   1 if success, 0 else
36747
 */
36748
int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
36749
{
36750
    WOLFSSL_MSG("wolfSSL_BN_add");
36751
36752
    if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
36753
        b == NULL || b->internal == NULL) {
36754
        WOLFSSL_MSG("bn NULL error");
36755
        return WOLFSSL_FAILURE;
36756
    }
36757
36758
    if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
36759
               (mp_int*)r->internal) != MP_OKAY) {
36760
        WOLFSSL_MSG("mp_add_d error");
36761
        return WOLFSSL_FAILURE;
36762
    }
36763
36764
    return WOLFSSL_SUCCESS;
36765
}
36766
36767
#ifndef WOLFSSL_SP_MATH
36768
/* r = a + b (mod m) */
36769
int wolfSSL_BN_mod_add(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
36770
                       const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m,
36771
                       WOLFSSL_BN_CTX *ctx)
36772
{
36773
    (void)ctx;
36774
    WOLFSSL_MSG("wolfSSL_BN_add");
36775
36776
    if (r == NULL || r->internal == NULL ||
36777
            a == NULL || a->internal == NULL ||
36778
            b == NULL || b->internal == NULL ||
36779
            m == NULL || m->internal == NULL) {
36780
        WOLFSSL_MSG("bn NULL error");
36781
        return WOLFSSL_FAILURE;
36782
    }
36783
36784
    if (mp_addmod((mp_int*)a->internal, (mp_int*)b->internal,
36785
                  (mp_int*)m->internal, (mp_int*)r->internal) != MP_OKAY) {
36786
        WOLFSSL_MSG("mp_add_d error");
36787
        return WOLFSSL_FAILURE;
36788
    }
36789
36790
    return WOLFSSL_SUCCESS;
36791
}
36792
#endif
36793
36794
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA))
36795
36796
int wolfSSL_BN_generate_prime_ex(WOLFSSL_BIGNUM* prime, int bits,
36797
    int safe, const WOLFSSL_BIGNUM* add, const WOLFSSL_BIGNUM* rem,
36798
    WOLFSSL_BN_GENCB* cb)
36799
{
36800
    int ret = WOLFSSL_SUCCESS;
36801
#ifdef WOLFSSL_SMALL_STACK
36802
    WC_RNG* rng = NULL;
36803
#else
36804
    WC_RNG rng[1];
36805
#endif
36806
36807
    (void)cb;
36808
36809
    WOLFSSL_ENTER("wolfSSL_BN_generate_prime_ex");
36810
36811
    if (safe == 1 || add != NULL || rem != NULL) {
36812
        /* These parameters aren't supported, yet. */
36813
        ret = WOLFSSL_FAILURE;
36814
    }
36815
36816
    if (prime == NULL || prime->internal == NULL) {
36817
        ret = WOLFSSL_FAILURE;
36818
    }
36819
36820
#ifdef WOLFSSL_SMALL_STACK
36821
    if (ret == WOLFSSL_SUCCESS) {
36822
        rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
36823
        if (rng == NULL) {
36824
            ret = WOLFSSL_FAILURE;
36825
        }
36826
    }
36827
#endif
36828
    if (ret == WOLFSSL_SUCCESS) {
36829
        XMEMSET(rng, 0, sizeof(WC_RNG));
36830
        if (wc_InitRng(rng) != 0) {
36831
            ret = WOLFSSL_FAILURE;
36832
        }
36833
    }
36834
36835
    if (ret == WOLFSSL_SUCCESS) {
36836
        if (mp_rand_prime((mp_int*)prime->internal, (bits + 7) / 8, rng, NULL)
36837
                != MP_OKAY) {
36838
            ret = WOLFSSL_FAILURE;
36839
        }
36840
    }
36841
36842
    wc_FreeRng(rng);
36843
#ifdef WOLFSSL_SMALL_STACK
36844
    if (rng != NULL)
36845
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
36846
#endif
36847
36848
    WOLFSSL_LEAVE("wolfSSL_BN_generate_prime_ex", ret);
36849
36850
    return ret;
36851
}
36852
36853
/* return code compliant with OpenSSL :
36854
 *   1 if prime, 0 if not, -1 if error
36855
 */
36856
int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
36857
                           WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
36858
{
36859
    WC_RNG*        rng    = NULL;
36860
#ifdef WOLFSSL_SMALL_STACK
36861
    WC_RNG*        tmpRNG = NULL;
36862
#else
36863
    WC_RNG         tmpRNG[1];
36864
#endif
36865
    int            initTmpRng = 0;
36866
    int            res = MP_NO;
36867
36868
    (void)ctx;
36869
    (void)cb;
36870
36871
    WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
36872
36873
    if (bn == NULL || bn->internal == NULL) {
36874
        WOLFSSL_MSG("bn NULL error");
36875
        return WOLFSSL_FATAL_ERROR;
36876
    }
36877
36878
#ifdef WOLFSSL_SMALL_STACK
36879
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
36880
    if (tmpRNG == NULL)
36881
        return WOLFSSL_FAILURE;
36882
#endif
36883
    if (wc_InitRng(tmpRNG) == 0) {
36884
        rng = tmpRNG;
36885
        initTmpRng = 1;
36886
    }
36887
    else {
36888
        WOLFSSL_MSG("Bad RNG Init, trying global");
36889
        if (initGlobalRNG == 0) {
36890
            WOLFSSL_MSG("Global RNG no Init");
36891
        }
36892
        else
36893
            rng = &globalRNG;
36894
    }
36895
36896
    if (rng) {
36897
        if (mp_prime_is_prime_ex((mp_int*)bn->internal,
36898
                                 nbchecks, &res, rng) != MP_OKAY) {
36899
            WOLFSSL_MSG("mp_prime_is_prime_ex error");
36900
            res = MP_NO;
36901
        }
36902
    }
36903
36904
    if (initTmpRng)
36905
        wc_FreeRng(tmpRNG);
36906
#ifdef WOLFSSL_SMALL_STACK
36907
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
36908
#endif
36909
36910
    if (res != MP_YES) {
36911
        WOLFSSL_MSG("mp_prime_is_prime_ex not prime");
36912
        return WOLFSSL_FAILURE;
36913
    }
36914
36915
    return WOLFSSL_SUCCESS;
36916
}
36917
36918
/* return code compliant with OpenSSL :
36919
 *   (bn mod w) if success, -1 if error
36920
 */
36921
WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
36922
                                     WOLFSSL_BN_ULONG w)
36923
{
36924
    WOLFSSL_BN_ULONG ret = 0;
36925
36926
    WOLFSSL_MSG("wolfSSL_BN_mod_word");
36927
36928
    if (bn == NULL || bn->internal == NULL) {
36929
        WOLFSSL_MSG("bn NULL error");
36930
        return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
36931
    }
36932
36933
    if (w <= (WOLFSSL_BN_ULONG)MP_MASK) {
36934
        mp_digit bn_ret;
36935
        if (mp_mod_d((mp_int*)bn->internal, (mp_digit)w, &bn_ret) != MP_OKAY) {
36936
            WOLFSSL_MSG("mp_add_d error");
36937
            return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
36938
        }
36939
        ret = (WOLFSSL_BN_ULONG)bn_ret;
36940
    } else {
36941
        int mp_ret;
36942
        mp_int w_mp, r_mp;
36943
        if (mp_init(&w_mp) != MP_OKAY)
36944
            return (unsigned long)WOLFSSL_FAILURE;
36945
        if (mp_init(&r_mp) != MP_OKAY)
36946
            return (unsigned long)WOLFSSL_FAILURE;
36947
        if (mp_set_int(&w_mp, w) != MP_OKAY)
36948
            return (unsigned long)WOLFSSL_FAILURE;
36949
        mp_ret = mp_mod((mp_int *)bn->internal, &w_mp, &r_mp);
36950
        ret = wolfSSL_BN_get_word_1(&r_mp);
36951
        mp_free(&r_mp);
36952
        mp_free(&w_mp);
36953
        if (mp_ret != MP_OKAY) {
36954
            WOLFSSL_MSG("mp_mod error");
36955
            return (WOLFSSL_BN_ULONG)WOLFSSL_FAILURE;
36956
        }
36957
    }
36958
36959
    return ret;
36960
}
36961
#endif /* WOLFSSL_KEY_GEN && (!NO_RSA || !NO_DH || !NO_DSA) */
36962
36963
char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
36964
{
36965
    int len = 0;
36966
    char *buf;
36967
36968
    WOLFSSL_ENTER("wolfSSL_BN_bn2hex");
36969
36970
    if (bn == NULL || bn->internal == NULL) {
36971
        WOLFSSL_MSG("bn NULL error");
36972
        return NULL;
36973
    }
36974
36975
    if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_HEX, &len) != MP_OKAY) {
36976
        WOLFSSL_MSG("mp_radix_size failure");
36977
        return NULL;
36978
    }
36979
36980
    buf = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
36981
    if (buf == NULL) {
36982
        WOLFSSL_MSG("BN_bn2hex malloc buffer failure");
36983
        return NULL;
36984
    }
36985
36986
    if (mp_tohex((mp_int*)bn->internal, buf) != MP_OKAY) {
36987
        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
36988
        return NULL;
36989
    }
36990
36991
    return buf;
36992
}
36993
36994
#ifndef NO_FILESYSTEM
36995
/* return code compliant with OpenSSL :
36996
 *   1 if success, 0 if error
36997
 */
36998
int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
36999
{
37000
    char *buf;
37001
    int ret;
37002
37003
    WOLFSSL_ENTER("wolfSSL_BN_print_fp");
37004
37005
    if (fp == XBADFILE || bn == NULL || bn->internal == NULL) {
37006
        WOLFSSL_MSG("bn NULL error");
37007
        return WOLFSSL_FAILURE;
37008
    }
37009
37010
    buf = wolfSSL_BN_bn2hex(bn);
37011
    if (buf == NULL) {
37012
        WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
37013
        return WOLFSSL_FAILURE;
37014
    }
37015
37016
    if (XFPRINTF(fp, "%s", buf) < 0)
37017
        ret = WOLFSSL_FAILURE;
37018
    else
37019
        ret = WOLFSSL_SUCCESS;
37020
37021
    XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
37022
37023
    return ret;
37024
}
37025
#endif /* !NO_FILESYSTEM */
37026
37027
37028
WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
37029
{
37030
    /* ctx is not used, return new Bignum */
37031
    (void)ctx;
37032
37033
    WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
37034
37035
    return wolfSSL_BN_new();
37036
}
37037
37038
#ifndef NO_WOLFSSL_STUB
37039
void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
37040
{
37041
    (void)ctx;
37042
37043
    WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
37044
    WOLFSSL_STUB("BN_CTX_start");
37045
    WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
37046
}
37047
#endif
37048
37049
37050
WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r,
37051
                                       WOLFSSL_BIGNUM *a,
37052
                                       const WOLFSSL_BIGNUM *n,
37053
                                       WOLFSSL_BN_CTX *ctx)
37054
{
37055
    int dynamic = 0;
37056
37057
    /* ctx is not used */
37058
    (void)ctx;
37059
37060
    WOLFSSL_ENTER("wolfSSL_BN_mod_inverse");
37061
37062
    /* check parameter */
37063
    if (r == NULL) {
37064
        r = wolfSSL_BN_new();
37065
        if (r == NULL){
37066
            WOLFSSL_MSG("WolfSSL_BN_new() failed");
37067
            return NULL;
37068
        }
37069
        dynamic = 1;
37070
    }
37071
37072
    if (a == NULL) {
37073
        WOLFSSL_MSG("a NULL error");
37074
        if (dynamic == 1) {
37075
            wolfSSL_BN_free(r);
37076
        }
37077
        return NULL;
37078
    }
37079
37080
    if (n == NULL) {
37081
        WOLFSSL_MSG("n NULL error");
37082
        if (dynamic == 1) {
37083
            wolfSSL_BN_free(r);
37084
        }
37085
        return NULL;
37086
    }
37087
37088
    /* Compute inverse of a modulo n and return r */
37089
    if (mp_invmod((mp_int *)a->internal,(mp_int *)n->internal,
37090
                  (mp_int*)r->internal) == MP_VAL){
37091
        WOLFSSL_MSG("mp_invmod() error");
37092
        if (dynamic == 1) {
37093
            wolfSSL_BN_free(r);
37094
        }
37095
        return NULL;
37096
    }
37097
37098
    return  r;
37099
}
37100
#endif  /* OPENSSL_EXTRA */
37101
#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
37102
    !defined(NO_ASN)
37103
#ifndef NO_BIO
37104
static int unprintable_char(char c)
37105
{
37106
    const unsigned char last_unprintable = 31;
37107
    const unsigned char LF = 10;
37108
    const unsigned char CR = 13;
37109
37110
    if (c <= last_unprintable && c != LF && c != CR) {
37111
        return 1;
37112
    }
37113
    return 0;
37114
}
37115
37116
int wolfSSL_ASN1_STRING_print(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str)
37117
{
37118
    int i;
37119
37120
    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_print");
37121
    if (out == NULL || str == NULL)
37122
           return WOLFSSL_FAILURE;
37123
37124
    for (i=0; i < str->length; i++) {
37125
        if (unprintable_char(str->data[i])) {
37126
            str->data[i] = '.';
37127
        }
37128
    }
37129
37130
    if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
37131
        return WOLFSSL_FAILURE;
37132
    }
37133
37134
    return str->length;
37135
}
37136
#endif /* !NO_BIO */
37137
#endif /* (WOLFSSL_QT || OPENSSL_ALL || OPENSSL_EXTRA) && !NO_ASN */
37138
37139
#if defined(OPENSSL_EXTRA)
37140
37141
const char *wolfSSL_ASN1_tag2str(int tag)
37142
{
37143
    static const char *const tag_label[31] = {
37144
        "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL",
37145
        "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", "ENUMERATED",
37146
        "<ASN1 11>", "UTF8STRING", "<ASN1 13>", "<ASN1 14>", "<ASN1 15>",
37147
        "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
37148
        "VIDEOTEXTSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
37149
        "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "UNIVERSALSTRING",
37150
        "<ASN1 29>", "BMPSTRING"
37151
    };
37152
37153
    if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
37154
        tag &= ~0x100;
37155
    if (tag < 0 || tag > 30)
37156
        return "(unknown)";
37157
    return tag_label[tag];
37158
}
37159
37160
#ifndef NO_BIO
37161
static int check_esc_char(char c, char *esc)
37162
{
37163
    char *ptr;
37164
37165
    ptr = esc;
37166
    while(*ptr != 0){
37167
        if (c == *ptr)
37168
            return 1;
37169
        ptr++;
37170
    }
37171
    return 0;
37172
}
37173
37174
int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str,
37175
                                 unsigned long flags)
37176
{
37177
    size_t str_len = 0, type_len = 0;
37178
    unsigned char *typebuf = NULL;
37179
    const char *hash="#";
37180
37181
    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_PRINT_ex");
37182
    if (out == NULL || str == NULL)
37183
        return WOLFSSL_FAILURE;
37184
37185
    /* add ASN1 type tag */
37186
    if (flags & ASN1_STRFLGS_SHOW_TYPE){
37187
        const char *tag = wolfSSL_ASN1_tag2str(str->type);
37188
        /* colon len + tag len + null*/
37189
        type_len = XSTRLEN(tag) + 2;
37190
        typebuf = (unsigned char *)XMALLOC(type_len , NULL, DYNAMIC_TYPE_TMP_BUFFER);
37191
        if (typebuf == NULL){
37192
            WOLFSSL_MSG("memory alloc failed.");
37193
            return WOLFSSL_FAILURE;
37194
        }
37195
        XMEMSET(typebuf, 0, type_len);
37196
        if (XSNPRINTF((char*)typebuf, (size_t)type_len , "%s:", tag)
37197
            >= (int)type_len)
37198
        {
37199
            WOLFSSL_MSG("Buffer overrun.");
37200
            return WOLFSSL_FAILURE;
37201
        }
37202
        type_len--;
37203
    }
37204
37205
    /* dump hex */
37206
    if (flags & ASN1_STRFLGS_DUMP_ALL){
37207
        char hex_tmp[4];
37208
        char *str_ptr, *str_end;
37209
37210
        if (type_len > 0){
37211
            if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
37212
                XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37213
                return WOLFSSL_FAILURE;
37214
            }
37215
            str_len += type_len;
37216
        }
37217
        if (wolfSSL_BIO_write(out, hash, 1) != 1){
37218
            goto err_exit;
37219
        }
37220
        str_len++;
37221
        if (flags & ASN1_STRFLGS_DUMP_DER){
37222
            ByteToHexStr((byte)str->type, &hex_tmp[0]);
37223
            ByteToHexStr((byte)str->length, &hex_tmp[2]);
37224
            if (wolfSSL_BIO_write(out, hex_tmp, 4) != 4){
37225
                goto err_exit;
37226
            }
37227
            str_len += 4;
37228
            XMEMSET(hex_tmp, 0, 4);
37229
        }
37230
37231
        str_ptr = str->data;
37232
        str_end = str->data + str->length;
37233
        while (str_ptr < str_end){
37234
            ByteToHexStr((byte)*str_ptr, &hex_tmp[0]);
37235
            if (wolfSSL_BIO_write(out, hex_tmp, 2) != 2){
37236
                goto err_exit;
37237
            }
37238
            str_ptr++;
37239
            str_len += 2;
37240
        }
37241
        if (type_len > 0)
37242
            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37243
37244
        return (int)str_len;
37245
    }
37246
37247
    if (type_len > 0){
37248
        if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
37249
            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37250
            return WOLFSSL_FAILURE;
37251
        }
37252
        str_len += type_len;
37253
    }
37254
37255
    if (flags & ASN1_STRFLGS_ESC_2253){
37256
        char esc_ch[] = "+;<>\\";
37257
        char* esc_ptr;
37258
37259
        esc_ptr = str->data;
37260
        while (*esc_ptr != 0){
37261
            if (check_esc_char(*esc_ptr, esc_ch)){
37262
                if (wolfSSL_BIO_write(out,"\\", 1) != 1)
37263
                    goto err_exit;
37264
                str_len++;
37265
            }
37266
            if (wolfSSL_BIO_write(out, esc_ptr, 1) != 1)
37267
                goto err_exit;
37268
            str_len++;
37269
            esc_ptr++;
37270
        }
37271
        if (type_len > 0)
37272
            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37273
        return (int)str_len;
37274
    }
37275
37276
    if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
37277
        goto err_exit;
37278
    }
37279
    str_len += str->length;
37280
    if (type_len > 0)
37281
        XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37282
37283
    return (int)str_len;
37284
37285
err_exit:
37286
    if (type_len > 0)
37287
        XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37288
    return WOLFSSL_FAILURE;
37289
}
37290
#endif /* !NO_BIO */
37291
37292
#if !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
37293
37294
37295
WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t,
37296
                                    int offset_day, long offset_sec)
37297
{
37298
    const time_t sec_per_day = 24*60*60;
37299
    time_t t_adj = 0;
37300
    time_t offset_day_sec = 0;
37301
    char time_str[MAX_TIME_STRING_SZ];
37302
    int time_get;
37303
37304
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_adj");
37305
37306
    if (s == NULL) {
37307
        s = wolfSSL_ASN1_TIME_new();
37308
        if (s == NULL) {
37309
            return NULL;
37310
        }
37311
    }
37312
37313
    /* compute GMT time with offset */
37314
    offset_day_sec = offset_day * sec_per_day;
37315
    t_adj          = t + offset_day_sec + offset_sec;
37316
37317
    /* Get time string as either UTC or GeneralizedTime */
37318
    time_get = GetFormattedTime(&t_adj, (byte*)time_str,
37319
        (word32)sizeof(time_str));
37320
    if (time_get <= 0) {
37321
        wolfSSL_ASN1_TIME_free(s);
37322
        return NULL;
37323
    }
37324
37325
    if (wolfSSL_ASN1_TIME_set_string(s, time_str) != WOLFSSL_SUCCESS) {
37326
        wolfSSL_ASN1_TIME_free(s);
37327
        return NULL;
37328
    }
37329
37330
    return s;
37331
}
37332
#endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES */
37333
37334
#ifndef NO_ASN_TIME
37335
37336
WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_new(void)
37337
{
37338
    WOLFSSL_ASN1_TIME* ret = (WOLFSSL_ASN1_TIME*)
37339
            XMALLOC(sizeof(WOLFSSL_ASN1_TIME), NULL, DYNAMIC_TYPE_OPENSSL);
37340
    if (!ret)
37341
        return NULL;
37342
    XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TIME));
37343
    return ret;
37344
}
37345
37346
void wolfSSL_ASN1_TIME_free(WOLFSSL_ASN1_TIME* t)
37347
{
37348
    if (t) {
37349
        XFREE(t, NULL, DYNAMIC_TYPE_OPENSSL);
37350
    }
37351
}
37352
/* not a compatibility function - length getter for opaque type */
37353
int wolfSSL_ASN1_TIME_get_length(WOLFSSL_ASN1_TIME *t)
37354
{
37355
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_length");
37356
    if (t == NULL)
37357
        return WOLFSSL_FAILURE;
37358
    return t->length;
37359
}
37360
/* not a compatibility function - data getter for opaque type */
37361
unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME *t)
37362
{
37363
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_data");
37364
    if (t == NULL)
37365
        return NULL;
37366
    return t->data;
37367
}
37368
37369
WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t,
37370
                                                        WOLFSSL_ASN1_TIME **out)
37371
{
37372
    int time_type = 0;
37373
    WOLFSSL_ASN1_TIME *ret = NULL;
37374
37375
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_generalizedtime");
37376
    if (t == NULL) {
37377
        WOLFSSL_MSG("Invalid ASN_TIME value");
37378
    } else {
37379
        time_type = t->type;
37380
        if (time_type != ASN_UTC_TIME && time_type != ASN_GENERALIZED_TIME){
37381
            WOLFSSL_MSG("Invalid ASN_TIME type.");
37382
        } else {
37383
            if (out == NULL || *out == NULL) {
37384
                ret = wolfSSL_ASN1_TIME_new();
37385
                if (ret == NULL){
37386
                    WOLFSSL_MSG("memory alloc failed.");
37387
                }
37388
            } else {
37389
                ret = *out;
37390
            }
37391
        }
37392
    }
37393
37394
    if (ret != NULL) {
37395
        if (time_type == ASN_GENERALIZED_TIME){
37396
            XMEMCPY(ret->data, t->data, ASN_GENERALIZED_TIME_SIZE);
37397
        } else { /* ASN_UTC_TIME */
37398
            /* convert UTC to generalized time */
37399
            ret->type = ASN_GENERALIZED_TIME;
37400
            ret->length = ASN_GENERALIZED_TIME_SIZE;
37401
            if (t->data[0] >= '5') {
37402
                ret->data[0] = '1'; ret->data[1] = '9';
37403
            } else {
37404
                ret->data[0] = '2'; ret->data[1] = '0';
37405
            }
37406
            XMEMCPY(&ret->data[2], t->data, ASN_UTC_TIME_SIZE);
37407
        }
37408
    }
37409
37410
    return ret;
37411
}
37412
#endif /* !NO_ASN_TIME */
37413
37414
#ifndef NO_ASN
37415
int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp)
37416
{
37417
    unsigned char *pptr = NULL;
37418
    char pad = 0 ;
37419
    unsigned char pad_val = 0;
37420
    int ret_size = 0;
37421
    unsigned char data1 = 0;
37422
    unsigned char neg = 0;
37423
    int i = 0;
37424
37425
    WOLFSSL_ENTER("wolfSSL_i2c_ASN1_INTEGER");
37426
    if (a == NULL)
37427
        return WOLFSSL_FAILURE;
37428
37429
    ret_size = a->intData[1];
37430
    if (ret_size == 0)
37431
        ret_size = 1;
37432
    else{
37433
        ret_size = (int)a->intData[1];
37434
        neg = a->negative;
37435
        data1 = a->intData[2];
37436
        if (ret_size == 1 && data1 == 0)
37437
            neg = 0;
37438
        /* 0x80 or greater positive number in first byte */
37439
        if (!neg && (data1 > 127)){
37440
            pad = 1;
37441
            pad_val = 0;
37442
        } else if (neg){
37443
            /* negative number */
37444
            if (data1 > 128){
37445
                pad = 1;
37446
                pad_val = 0xff;
37447
            } else if (data1 == 128){
37448
                for (i = 3; i < a->intData[1] + 2; i++){
37449
                    if (a->intData[i]){
37450
                        pad = 1;
37451
                        pad_val = 0xff;
37452
                        break;
37453
                    }
37454
                }
37455
            }
37456
        }
37457
        ret_size += (int)pad;
37458
    }
37459
    if (pp == NULL)
37460
        return ret_size;
37461
37462
    pptr = *pp;
37463
    if (pad)
37464
        *(pptr++) = pad_val;
37465
    if (a->intData[1] == 0)
37466
        *(pptr++) = 0;
37467
    else if (!neg){
37468
        /* positive number */
37469
        for (i=0; i < a->intData[1]; i++){
37470
            *pptr = a->intData[i+2];
37471
            pptr++;
37472
        }
37473
    } else {
37474
        /* negative number */
37475
        int str_len = 0;
37476
37477
        /* 0 padding from end of buffer */
37478
        str_len = (int)a->intData[1];
37479
        pptr += a->intData[1] - 1;
37480
        while (!a->intData[str_len + 2] && str_len > 1){
37481
            *(pptr--) = 0;
37482
            str_len--;
37483
        }
37484
        /* 2's complement next octet */
37485
        *(pptr--) = ((a->intData[str_len + 1]) ^ 0xff) + 1;
37486
        str_len--;
37487
        /* Complement any octets left */
37488
        while (str_len > 0){
37489
            *(pptr--) = a->intData[str_len + 1] ^ 0xff;
37490
            str_len--;
37491
        }
37492
    }
37493
    *pp += ret_size;
37494
    return ret_size;
37495
}
37496
#endif /* !NO_ASN */
37497
#endif /* OPENSSL_EXTRA */
37498
37499
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
37500
/* when calling SetIndividualExternal, mpi should be cleared by caller if no
37501
 * longer used. ie mp_free(mpi). This is to free data when fastmath is
37502
 * disabled since a copy of mpi is made by this function and placed into bn.
37503
 */
37504
int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
37505
{
37506
    byte dynamic = 0;
37507
37508
#ifdef WOLFSSL_DEBUG_OPENSSL
37509
    WOLFSSL_MSG("Entering SetIndividualExternal");
37510
#endif
37511
37512
    if (mpi == NULL || bn == NULL) {
37513
        WOLFSSL_MSG("mpi NULL error");
37514
        return WOLFSSL_FATAL_ERROR;
37515
    }
37516
37517
    if (*bn == NULL) {
37518
        *bn = wolfSSL_BN_new();
37519
        if (*bn == NULL) {
37520
            WOLFSSL_MSG("SetIndividualExternal alloc failed");
37521
            return WOLFSSL_FATAL_ERROR;
37522
        }
37523
        dynamic = 1;
37524
    }
37525
37526
    if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
37527
        WOLFSSL_MSG("mp_copy error");
37528
        if (dynamic == 1) {
37529
            wolfSSL_BN_free(*bn);
37530
        }
37531
        return WOLFSSL_FATAL_ERROR;
37532
    }
37533
37534
    return WOLFSSL_SUCCESS;
37535
}
37536
37537
37538
static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
37539
{
37540
    if (bn)
37541
        XMEMSET(bn, 0, sizeof(WOLFSSL_BIGNUM));
37542
}
37543
37544
37545
WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
37546
{
37547
    WOLFSSL_BIGNUM* external;
37548
    mp_int*        mpi;
37549
37550
#ifdef WOLFSSL_DEBUG_OPENSSL
37551
    WOLFSSL_MSG("wolfSSL_BN_new");
37552
#endif
37553
37554
#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
37555
    mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
37556
    if (mpi == NULL) {
37557
        WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
37558
        return NULL;
37559
    }
37560
#endif
37561
37562
    external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
37563
                                        DYNAMIC_TYPE_BIGINT);
37564
    if (external == NULL) {
37565
        WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
37566
#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
37567
        XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
37568
#endif
37569
        return NULL;
37570
    }
37571
37572
#if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
37573
    mpi = &external->fp;
37574
#endif
37575
37576
    InitwolfSSL_BigNum(external);
37577
    if (mp_init(mpi) != MP_OKAY) {
37578
        wolfSSL_BN_free(external);
37579
        return NULL;
37580
    }
37581
    external->internal = mpi;
37582
37583
    return external;
37584
}
37585
37586
37587
#if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
37588
/* This function works without BN_free only with TFM */
37589
void wolfSSL_BN_init(WOLFSSL_BIGNUM* bn)
37590
{
37591
    if(bn == NULL)return;
37592
#ifdef WOLFSSL_DEBUG_OPENSSL
37593
    WOLFSSL_MSG("wolfSSL_BN_init");
37594
#endif
37595
    InitwolfSSL_BigNum(bn);
37596
    if (mp_init(&bn->fp) != MP_OKAY)
37597
        return;
37598
    bn->internal = (void *)&bn->fp;
37599
}
37600
#endif
37601
37602
void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
37603
{
37604
#ifdef WOLFSSL_DEBUG_OPENSSL
37605
    WOLFSSL_MSG("wolfSSL_BN_free");
37606
#endif
37607
    if (bn) {
37608
        if (bn->internal) {
37609
            mp_int* bni = (mp_int*)bn->internal;
37610
            mp_free(bni);
37611
#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
37612
            XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
37613
#endif
37614
            bn->internal = NULL;
37615
        }
37616
        XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
37617
        /* bn = NULL, don't try to access or double free it */
37618
    }
37619
37620
}
37621
37622
void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
37623
{
37624
#ifdef WOLFSSL_DEBUG_OPENSSL
37625
    WOLFSSL_MSG("wolfSSL_BN_clear_free");
37626
#endif
37627
    if (bn) {
37628
        if (bn->internal) {
37629
            mp_int* bni = (mp_int*)bn->internal;
37630
            mp_forcezero(bni);
37631
        }
37632
        wolfSSL_BN_free(bn);
37633
    }
37634
}
37635
37636
void wolfSSL_BN_clear(WOLFSSL_BIGNUM* bn)
37637
{
37638
#ifdef WOLFSSL_DEBUG_OPENSSL
37639
    WOLFSSL_MSG("wolfSSL_BN_clear");
37640
#endif
37641
    if (bn && bn->internal) {
37642
        mp_forcezero((mp_int*)bn->internal);
37643
    }
37644
}
37645
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
37646
37647
#ifdef OPENSSL_ALL
37648
37649
#if !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
37650
int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
37651
                                          WOLFSSL_EVP_PKEY* pkey,
37652
                                          const WOLFSSL_EVP_CIPHER* enc,
37653
                                          char* passwd, int passwdSz,
37654
                                          wc_pem_password_cb* cb, void* ctx)
37655
{
37656
    int ret = 0;
37657
    char password[NAME_SZ];
37658
    byte* key = NULL;
37659
    word32 keySz;
37660
    byte* pem = NULL;
37661
    int pemSz;
37662
    int type = PKCS8_PRIVATEKEY_TYPE;
37663
    int algId;
37664
    const byte* curveOid;
37665
    word32 oidSz;
37666
    int encAlgId = 0;
37667
37668
    if (bio == NULL || pkey == NULL)
37669
        return -1;
37670
37671
    keySz = pkey->pkey_sz + 128;
37672
    key = (byte*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37673
    if (key == NULL)
37674
        ret = MEMORY_E;
37675
37676
    if (ret == 0 && enc != NULL && passwd == NULL) {
37677
        passwdSz = cb(password, sizeof(password), 1, ctx);
37678
        if (passwdSz < 0)
37679
            ret = WOLFSSL_FAILURE;
37680
        passwd = password;
37681
    }
37682
37683
    if (ret == 0 && enc != NULL) {
37684
        WC_RNG rng;
37685
        ret = wc_InitRng(&rng);
37686
        if (ret == 0) {
37687
        #ifndef NO_DES3
37688
            if (enc == EVP_DES_CBC)
37689
                encAlgId = DESb;
37690
            else if (enc == EVP_DES_EDE3_CBC)
37691
                encAlgId = DES3b;
37692
            else
37693
        #endif
37694
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
37695
            #ifdef WOLFSSL_AES_256
37696
            if (enc == EVP_AES_256_CBC)
37697
                encAlgId = AES256CBCb;
37698
            else
37699
            #endif
37700
        #endif
37701
                ret = -1;
37702
            if (ret == 0) {
37703
                ret = TraditionalEnc((byte*)pkey->pkey.ptr, pkey->pkey_sz, key,
37704
                                       &keySz, passwd, passwdSz, PKCS5, PBES2,
37705
                                       encAlgId, NULL, 0, WC_PKCS12_ITT_DEFAULT,
37706
                                       &rng, NULL);
37707
                if (ret > 0) {
37708
                    keySz = ret;
37709
                    ret = 0;
37710
                }
37711
            }
37712
            wc_FreeRng(&rng);
37713
        }
37714
        type = PKCS8_ENC_PRIVATEKEY_TYPE;
37715
    }
37716
    if (ret == 0 && enc == NULL) {
37717
        type = PKCS8_PRIVATEKEY_TYPE;
37718
    #ifdef HAVE_ECC
37719
        if (pkey->type == EVP_PKEY_EC) {
37720
            algId = ECDSAk;
37721
            ret = wc_ecc_get_oid(pkey->ecc->group->curve_oid, &curveOid,
37722
                                                                        &oidSz);
37723
        }
37724
        else
37725
    #endif
37726
        {
37727
            algId = RSAk;
37728
            curveOid = NULL;
37729
            oidSz = 0;
37730
        }
37731
37732
    #ifdef HAVE_ECC
37733
        if (ret >= 0)
37734
    #endif
37735
        {
37736
            ret = wc_CreatePKCS8Key(key, &keySz, (byte*)pkey->pkey.ptr,
37737
                                         pkey->pkey_sz, algId, curveOid, oidSz);
37738
            keySz = ret;
37739
        }
37740
    }
37741
37742
    if (password == passwd)
37743
        XMEMSET(password, 0, passwdSz);
37744
37745
    if (ret >= 0) {
37746
        pemSz = 2 * keySz + 2 * 64;
37747
        pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37748
        if (pem == NULL)
37749
            ret = MEMORY_E;
37750
    }
37751
37752
    if (ret >= 0)
37753
        ret = wc_DerToPemEx(key, keySz, pem, pemSz, NULL, type);
37754
37755
    if (key != NULL)
37756
        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37757
37758
    if (ret >= 0) {
37759
        if (wolfSSL_BIO_write(bio, pem, ret) != ret)
37760
            ret = -1;
37761
    }
37762
37763
    if (pem != NULL)
37764
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37765
37766
    return ret < 0 ? 0 : ret;
37767
37768
}
37769
37770
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
37771
int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
37772
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
37773
    wc_pem_password_cb* cb, void* ctx)
37774
{
37775
    int ret = WOLFSSL_SUCCESS;
37776
    BIO *b;
37777
37778
    WOLFSSL_ENTER("wolfSSL_PEM_write_PKCS8PrivateKey");
37779
37780
    b = wolfSSL_BIO_new_fp(f, BIO_NOCLOSE);
37781
    if (b == NULL) {
37782
        ret = WOLFSSL_FAILURE;
37783
    }
37784
    if (ret == WOLFSSL_SUCCESS) {
37785
        ret = wolfSSL_PEM_write_bio_PKCS8PrivateKey(b, pkey, enc, passwd,
37786
                passwdSz, cb, ctx);
37787
    }
37788
37789
    wolfSSL_BIO_free(b);
37790
37791
    return ret;
37792
}
37793
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
37794
37795
static int bio_get_data(WOLFSSL_BIO* bio, byte** data)
37796
{
37797
    int ret = 0;
37798
    byte* mem = NULL;
37799
#ifndef NO_FILESYSTEM
37800
    long memSz;
37801
    XFILE file;
37802
    long curr;
37803
#endif
37804
37805
    if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
37806
    }
37807
#ifndef NO_FILESYSTEM
37808
    else if (bio->type == WOLFSSL_BIO_FILE) {
37809
        if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
37810
            ret = BAD_FUNC_ARG;
37811
        if (ret == 0) {
37812
            curr = XFTELL(file);
37813
            if (curr < 0) {
37814
                ret = WOLFSSL_BAD_FILE;
37815
            }
37816
            if (XFSEEK(file, 0, XSEEK_END) != 0)
37817
                ret = WOLFSSL_BAD_FILE;
37818
        }
37819
        if (ret == 0) {
37820
            memSz = XFTELL(file);
37821
            if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0) {
37822
                ret = WOLFSSL_BAD_FILE;
37823
            }
37824
        }
37825
        if (ret == 0) {
37826
            memSz -= curr;
37827
            ret = (int)memSz;
37828
            if (XFSEEK(file, curr, SEEK_SET) != 0)
37829
                ret = WOLFSSL_BAD_FILE;
37830
        }
37831
    }
37832
#endif
37833
37834
    if (ret > 0) {
37835
        mem = (byte*)XMALLOC(ret, bio->heap, DYNAMIC_TYPE_OPENSSL);
37836
        if (mem == NULL) {
37837
            WOLFSSL_MSG("Memory error");
37838
            ret = MEMORY_E;
37839
        }
37840
        if (ret >= 0) {
37841
            if ((ret = wolfSSL_BIO_read(bio, mem, ret)) <= 0) {
37842
                XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
37843
                ret = MEMORY_E;
37844
                mem = NULL;
37845
            }
37846
        }
37847
    }
37848
37849
    *data = mem;
37850
37851
    return ret;
37852
}
37853
37854
/* DER data is PKCS#8 encrypted. */
37855
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio,
37856
                                                  WOLFSSL_EVP_PKEY** pkey,
37857
                                                  wc_pem_password_cb* cb,
37858
                                                  void* ctx)
37859
{
37860
    int ret;
37861
    byte* der;
37862
    int len;
37863
    byte* p;
37864
    word32 algId;
37865
    WOLFSSL_EVP_PKEY* key;
37866
37867
    if ((len = bio_get_data(bio, &der)) < 0)
37868
        return NULL;
37869
37870
    if (cb != NULL) {
37871
        char password[NAME_SZ];
37872
        int passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
37873
        if (passwordSz < 0) {
37874
            XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
37875
            return NULL;
37876
        }
37877
    #ifdef WOLFSSL_CHECK_MEM_ZERO
37878
        wc_MemZero_Add("wolfSSL_d2i_PKCS8PrivateKey_bio password", password,
37879
            passwordSz);
37880
    #endif
37881
37882
        ret = ToTraditionalEnc(der, len, password, passwordSz, &algId);
37883
        if (ret < 0) {
37884
            XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
37885
            return NULL;
37886
        }
37887
37888
        ForceZero(password, passwordSz);
37889
    #ifdef WOLFSSL_CHECK_MEM_ZERO
37890
        wc_MemZero_Check(password, passwordSz);
37891
    #endif
37892
    }
37893
37894
    p = der;
37895
    key = wolfSSL_d2i_PrivateKey_EVP(pkey, &p, len);
37896
    XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
37897
    return key;
37898
}
37899
37900
#endif /* !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
37901
37902
/* Detect which type of key it is before decoding. */
37903
WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey,
37904
                                             const unsigned char** pp,
37905
                                             long length)
37906
{
37907
    int ret;
37908
    WOLFSSL_EVP_PKEY* key = NULL;
37909
    const byte* der = *pp;
37910
    word32 idx = 0;
37911
    int len = 0;
37912
    word32 end = 0;
37913
    int cnt = 0;
37914
    int type;
37915
    word32 algId;
37916
    word32 keyLen = (word32)length;
37917
37918
    /* Take off PKCS#8 wrapper if found. */
37919
    if ((len = ToTraditionalInline_ex(der, &idx, keyLen, &algId)) >= 0) {
37920
        der += idx;
37921
        keyLen = len;
37922
    }
37923
    idx = 0;
37924
    len = 0;
37925
37926
    /* Use the number of elements in the outer sequence to determine key type.
37927
     */
37928
    ret = GetSequence(der, &idx, &len, keyLen);
37929
    if (ret >= 0) {
37930
        end = idx + len;
37931
        while (ret >= 0 && idx < end) {
37932
            /* Skip type */
37933
            idx++;
37934
            /* Get length and skip over - keeping count */
37935
            len = 0;
37936
            ret = GetLength(der, &idx, &len, keyLen);
37937
            if (ret >= 0) {
37938
                if (idx + len > end)
37939
                    ret = ASN_PARSE_E;
37940
                else {
37941
                    idx += len;
37942
                    cnt++;
37943
                }
37944
            }
37945
        }
37946
    }
37947
37948
    if (ret >= 0) {
37949
        /* ECC includes version, private[, curve][, public key] */
37950
        if (cnt >= 2 && cnt <= 4)
37951
            type = EVP_PKEY_EC;
37952
        else
37953
            type = EVP_PKEY_RSA;
37954
37955
        key = wolfSSL_d2i_PrivateKey(type, pkey, &der, keyLen);
37956
        *pp = der;
37957
    }
37958
37959
    return key;
37960
}
37961
#endif /* OPENSSL_ALL */
37962
37963
#ifdef WOLFSSL_STATIC_EPHEMERAL
37964
int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr)
37965
{
37966
    int ret;
37967
    word32 idx = 0;
37968
    DerBuffer* der = NULL;
37969
37970
    if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) {
37971
        return BAD_FUNC_ARG;
37972
    }
37973
37974
#ifndef SINGLE_THREADED
37975
    if (!ssl->ctx->staticKELockInit) {
37976
        return BUFFER_E; /* no keys set */
37977
    }
37978
    ret = wc_LockMutex(&ssl->ctx->staticKELock);
37979
    if (ret != 0) {
37980
        return ret;
37981
    }
37982
#endif
37983
37984
    ret = BUFFER_E; /* set default error */
37985
    switch (keyAlgo) {
37986
    #ifndef NO_DH
37987
        case WC_PK_TYPE_DH:
37988
            if (ssl != NULL)
37989
                der = ssl->staticKE.dhKey;
37990
            if (der == NULL)
37991
                der = ssl->ctx->staticKE.dhKey;
37992
            if (der != NULL) {
37993
                DhKey* key = (DhKey*)keyPtr;
37994
                WOLFSSL_MSG("Using static DH key");
37995
                ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length);
37996
            }
37997
            break;
37998
    #endif
37999
    #ifdef HAVE_ECC
38000
        case WC_PK_TYPE_ECDH:
38001
            if (ssl != NULL)
38002
                der = ssl->staticKE.ecKey;
38003
            if (der == NULL)
38004
                der = ssl->ctx->staticKE.ecKey;
38005
            if (der != NULL) {
38006
                ecc_key* key = (ecc_key*)keyPtr;
38007
                WOLFSSL_MSG("Using static ECDH key");
38008
                ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key, der->length);
38009
            }
38010
            break;
38011
    #endif
38012
    #ifdef HAVE_CURVE25519
38013
        case WC_PK_TYPE_CURVE25519:
38014
            if (ssl != NULL)
38015
                der = ssl->staticKE.x25519Key;
38016
            if (der == NULL)
38017
                der = ssl->ctx->staticKE.x25519Key;
38018
            if (der != NULL) {
38019
                curve25519_key* key = (curve25519_key*)keyPtr;
38020
                WOLFSSL_MSG("Using static X25519 key");
38021
                ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key,
38022
                    der->length);
38023
            }
38024
            break;
38025
    #endif
38026
    #ifdef HAVE_CURVE448
38027
        case WC_PK_TYPE_CURVE448:
38028
            if (ssl != NULL)
38029
                der = ssl->staticKE.x448Key;
38030
            if (der == NULL)
38031
                der = ssl->ctx->staticKE.x448Key;
38032
            if (der != NULL) {
38033
                curve448_key* key = (curve448_key*)keyPtr;
38034
                WOLFSSL_MSG("Using static X448 key");
38035
                ret = wc_Curve448PrivateKeyDecode(der->buffer, &idx, key,
38036
                    der->length);
38037
            }
38038
            break;
38039
    #endif
38040
        default:
38041
            /* not supported */
38042
            ret = NOT_COMPILED_IN;
38043
            break;
38044
    }
38045
38046
#ifndef SINGLE_THREADED
38047
    wc_UnLockMutex(&ssl->ctx->staticKELock);
38048
#endif
38049
    return ret;
38050
}
38051
38052
static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx,
38053
    StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key,
38054
    unsigned int keySz, int format, void* heap)
38055
{
38056
    int ret = 0;
38057
    DerBuffer* der = NULL;
38058
    byte* keyBuf = NULL;
38059
#ifndef NO_FILESYSTEM
38060
    const char* keyFile = NULL;
38061
#endif
38062
38063
    /* allow empty key to free buffer */
38064
    if (staticKE == NULL || (key == NULL && keySz > 0)) {
38065
        return BAD_FUNC_ARG;
38066
    }
38067
38068
    WOLFSSL_ENTER("SetStaticEphemeralKey");
38069
38070
    /* if just free'ing key then skip loading */
38071
    if (key != NULL) {
38072
    #ifndef NO_FILESYSTEM
38073
        /* load file from filesystem */
38074
        if (key != NULL && keySz == 0) {
38075
            size_t keyBufSz = 0;
38076
            keyFile = (const char*)key;
38077
            ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap);
38078
            if (ret != 0) {
38079
                return ret;
38080
            }
38081
            keySz = (unsigned int)keyBufSz;
38082
        }
38083
        else
38084
    #endif
38085
        {
38086
            /* use as key buffer directly */
38087
            keyBuf = (byte*)key;
38088
        }
38089
38090
        if (format == WOLFSSL_FILETYPE_PEM) {
38091
        #ifdef WOLFSSL_PEM_TO_DER
38092
            int keyFormat = 0;
38093
            ret = PemToDer(keyBuf, keySz, PRIVATEKEY_TYPE, &der,
38094
                heap, NULL, &keyFormat);
38095
            /* auto detect key type */
38096
            if (ret == 0 && keyAlgo == WC_PK_TYPE_NONE) {
38097
                if (keyFormat == ECDSAk)
38098
                    keyAlgo = WC_PK_TYPE_ECDH;
38099
                else if (keyFormat == X25519k)
38100
                    keyAlgo = WC_PK_TYPE_CURVE25519;
38101
                else
38102
                    keyAlgo = WC_PK_TYPE_DH;
38103
            }
38104
        #else
38105
            ret = NOT_COMPILED_IN;
38106
        #endif
38107
        }
38108
        else {
38109
            /* Detect PK type (if required) */
38110
        #ifdef HAVE_ECC
38111
            if (keyAlgo == WC_PK_TYPE_NONE) {
38112
                word32 idx = 0;
38113
                ecc_key eccKey;
38114
                ret = wc_ecc_init_ex(&eccKey, heap, INVALID_DEVID);
38115
                if (ret == 0) {
38116
                    ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &eccKey, keySz);
38117
                    if (ret == 0)
38118
                        keyAlgo = WC_PK_TYPE_ECDH;
38119
                    wc_ecc_free(&eccKey);
38120
                }
38121
            }
38122
        #endif
38123
        #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
38124
            if (keyAlgo == WC_PK_TYPE_NONE) {
38125
                word32 idx = 0;
38126
                DhKey dhKey;
38127
                ret = wc_InitDhKey_ex(&dhKey, heap, INVALID_DEVID);
38128
                if (ret == 0) {
38129
                    ret = wc_DhKeyDecode(keyBuf, &idx, &dhKey, keySz);
38130
                    if (ret == 0)
38131
                        keyAlgo = WC_PK_TYPE_DH;
38132
                    wc_FreeDhKey(&dhKey);
38133
                }
38134
            }
38135
        #endif
38136
        #ifdef HAVE_CURVE25519
38137
            if (keyAlgo == WC_PK_TYPE_NONE) {
38138
                word32 idx = 0;
38139
                curve25519_key x25519Key;
38140
                ret = wc_curve25519_init_ex(&x25519Key, heap, INVALID_DEVID);
38141
                if (ret == 0) {
38142
                    ret = wc_Curve25519PrivateKeyDecode(keyBuf, &idx, &x25519Key,
38143
                        keySz);
38144
                    if (ret == 0)
38145
                        keyAlgo = WC_PK_TYPE_CURVE25519;
38146
                    wc_curve25519_free(&x25519Key);
38147
                }
38148
            }
38149
        #endif
38150
        #ifdef HAVE_CURVE448
38151
            if (keyAlgo == WC_PK_TYPE_NONE) {
38152
                word32 idx = 0;
38153
                curve448_key x448Key;
38154
                ret = wc_curve448_init(&x448Key);
38155
                if (ret == 0) {
38156
                    ret = wc_Curve448PrivateKeyDecode(keyBuf, &idx, &x448Key,
38157
                        keySz);
38158
                    if (ret == 0)
38159
                        keyAlgo = WC_PK_TYPE_CURVE448;
38160
                    wc_curve448_free(&x448Key);
38161
                }
38162
            }
38163
        #endif
38164
38165
            if (keyAlgo != WC_PK_TYPE_NONE) {
38166
                ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap);
38167
                if (ret == 0) {
38168
                    XMEMCPY(der->buffer, keyBuf, keySz);
38169
                }
38170
            }
38171
        }
38172
    }
38173
38174
#ifndef NO_FILESYSTEM
38175
    /* done with keyFile buffer */
38176
    if (keyFile && keyBuf) {
38177
        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
38178
    }
38179
#endif
38180
38181
#ifndef SINGLE_THREADED
38182
    if (ret == 0 && !ctx->staticKELockInit) {
38183
        ret = wc_InitMutex(&ctx->staticKELock);
38184
        if (ret == 0) {
38185
            ctx->staticKELockInit = 1;
38186
        }
38187
    }
38188
#endif
38189
    if (ret == 0
38190
    #ifndef SINGLE_THREADED
38191
        && (ret = wc_LockMutex(&ctx->staticKELock)) == 0
38192
    #endif
38193
    ) {
38194
        switch (keyAlgo) {
38195
        #ifndef NO_DH
38196
            case WC_PK_TYPE_DH:
38197
                FreeDer(&staticKE->dhKey);
38198
                staticKE->dhKey = der; der = NULL;
38199
                break;
38200
        #endif
38201
        #ifdef HAVE_ECC
38202
            case WC_PK_TYPE_ECDH:
38203
                FreeDer(&staticKE->ecKey);
38204
                staticKE->ecKey = der; der = NULL;
38205
                break;
38206
        #endif
38207
        #ifdef HAVE_CURVE25519
38208
            case WC_PK_TYPE_CURVE25519:
38209
                FreeDer(&staticKE->x25519Key);
38210
                staticKE->x25519Key = der; der = NULL;
38211
                break;
38212
        #endif
38213
        #ifdef HAVE_CURVE448
38214
            case WC_PK_TYPE_CURVE448:
38215
                FreeDer(&staticKE->x448Key);
38216
                staticKE->x448Key = der; der = NULL;
38217
                break;
38218
        #endif
38219
            default:
38220
                /* not supported */
38221
                ret = NOT_COMPILED_IN;
38222
                break;
38223
        }
38224
38225
    #ifndef SINGLE_THREADED
38226
        wc_UnLockMutex(&ctx->staticKELock);
38227
    #endif
38228
    }
38229
38230
    if (ret != 0) {
38231
        FreeDer(&der);
38232
    }
38233
38234
    (void)ctx; /* not used for single threaded */
38235
38236
    WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
38237
38238
    return ret;
38239
}
38240
38241
int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
38242
    const char* key, unsigned int keySz, int format)
38243
{
38244
    if (ctx == NULL) {
38245
        return BAD_FUNC_ARG;
38246
    }
38247
    return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo,
38248
        key, keySz, format, ctx->heap);
38249
}
38250
int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
38251
    const char* key, unsigned int keySz, int format)
38252
{
38253
    if (ssl == NULL || ssl->ctx == NULL) {
38254
        return BAD_FUNC_ARG;
38255
    }
38256
    return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo,
38257
        key, keySz, format, ssl->heap);
38258
}
38259
38260
static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
38261
    int keyAlgo, const unsigned char** key, unsigned int* keySz)
38262
{
38263
    int ret = 0;
38264
    DerBuffer* der = NULL;
38265
38266
    if (key)   *key = NULL;
38267
    if (keySz) *keySz = 0;
38268
38269
#ifndef SINGLE_THREADED
38270
    if (ctx->staticKELockInit &&
38271
        (ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
38272
        return ret;
38273
    }
38274
#endif
38275
38276
    switch (keyAlgo) {
38277
    #ifndef NO_DH
38278
        case WC_PK_TYPE_DH:
38279
            if (ssl != NULL)
38280
                der = ssl->staticKE.dhKey;
38281
            if (der == NULL)
38282
                der = ctx->staticKE.dhKey;
38283
            break;
38284
    #endif
38285
    #ifdef HAVE_ECC
38286
        case WC_PK_TYPE_ECDH:
38287
            if (ssl != NULL)
38288
                der = ssl->staticKE.ecKey;
38289
            if (der == NULL)
38290
                der = ctx->staticKE.ecKey;
38291
            break;
38292
    #endif
38293
    #ifdef HAVE_CURVE25519
38294
        case WC_PK_TYPE_CURVE25519:
38295
            if (ssl != NULL)
38296
                der = ssl->staticKE.x25519Key;
38297
            if (der == NULL)
38298
                der = ctx->staticKE.x25519Key;
38299
            break;
38300
    #endif
38301
    #ifdef HAVE_CURVE448
38302
        case WC_PK_TYPE_CURVE448:
38303
            if (ssl != NULL)
38304
                der = ssl->staticKE.x448Key;
38305
            if (der == NULL)
38306
                der = ctx->staticKE.x448Key;
38307
            break;
38308
    #endif
38309
        default:
38310
            /* not supported */
38311
            ret = NOT_COMPILED_IN;
38312
            break;
38313
    }
38314
38315
    if (der) {
38316
        if (key)
38317
            *key = der->buffer;
38318
        if (keySz)
38319
            *keySz = der->length;
38320
    }
38321
38322
#ifndef SINGLE_THREADED
38323
    wc_UnLockMutex(&ctx->staticKELock);
38324
#endif
38325
38326
    return ret;
38327
}
38328
38329
/* returns pointer to currently loaded static ephemeral as ASN.1 */
38330
/* this can be converted to PEM using wc_DerToPem */
38331
int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
38332
    const unsigned char** key, unsigned int* keySz)
38333
{
38334
    if (ctx == NULL) {
38335
        return BAD_FUNC_ARG;
38336
    }
38337
38338
    return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz);
38339
}
38340
int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
38341
    const unsigned char** key, unsigned int* keySz)
38342
{
38343
    if (ssl == NULL || ssl->ctx == NULL) {
38344
        return BAD_FUNC_ARG;
38345
    }
38346
38347
    return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz);
38348
}
38349
38350
#endif /* WOLFSSL_STATIC_EPHEMERAL */
38351
38352
#if defined(OPENSSL_EXTRA)
38353
/* wolfSSL_THREADID_current is provided as a compat API with
38354
 * CRYPTO_THREADID_current to register current thread id into given id object.
38355
 * However, CRYPTO_THREADID_current API has been deprecated and no longer
38356
 * exists in the OpenSSL 1.0.0 or later.This API only works as a stub
38357
 * like as existing wolfSSL_THREADID_set_numeric.
38358
 */
38359
void wolfSSL_THREADID_current(WOLFSSL_CRYPTO_THREADID* id)
38360
{
38361
    (void)id;
38362
    return;
38363
}
38364
/* wolfSSL_THREADID_hash is provided as a compatible API with
38365
 * CRYPTO_THREADID_hash which returns a hash value calcurated from the
38366
 * specified thread id. However, CRYPTO_THREADID_hash API has been
38367
 * deprecated and no longer exists in the OpenSSL 1.0.0 or later.
38368
 * This API only works as a stub to returns 0. This behavior is
38369
 * equivalent to the latest OpenSSL CRYPTO_THREADID_hash.
38370
 */
38371
unsigned long wolfSSL_THREADID_hash(const WOLFSSL_CRYPTO_THREADID* id)
38372
{
38373
    (void)id;
38374
    return 0UL;
38375
}
38376
/* wolfSSL_CTX_set_ecdh_auto is provided as compatible API with
38377
 * SSL_CTX_set_ecdh_auto to enable auto ecdh curve selection functionality.
38378
 * Since this functionality is enabled by default in wolfSSL,
38379
 * this API exists as a stub.
38380
 */
38381
int wolfSSL_CTX_set_ecdh_auto(WOLFSSL_CTX* ctx, int onoff)
38382
{
38383
    (void)ctx;
38384
    (void)onoff;
38385
    return WOLFSSL_SUCCESS;
38386
}
38387
38388
/**
38389
 * set security level (wolfSSL doesn't support security level)
38390
 * @param ctx  a pointer to WOLFSSL_EVP_PKEY_CTX structure
38391
 * @param level security level
38392
 */
38393
void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level)
38394
{
38395
    WOLFSSL_ENTER("wolfSSL_CTX_set_security_level");
38396
    (void)ctx;
38397
    (void)level;
38398
}
38399
/**
38400
 * get security level (wolfSSL doesn't support security level)
38401
 * @param ctx  a pointer to WOLFSSL_EVP_PKEY_CTX structure
38402
 * @return always 0(level 0)
38403
 */
38404
int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx)
38405
{
38406
    WOLFSSL_ENTER("wolfSSL_CTX_get_security_level");
38407
    (void)ctx;
38408
    return 0;
38409
}
38410
38411
38412
/**
38413
 * Determine whether a WOLFSSL_SESSION object can be used for resumption
38414
 * @param s  a pointer to WOLFSSL_SESSION structure
38415
 * @return return 1 if session is resumable, otherwise 0.
38416
 */
38417
int wolfSSL_SESSION_is_resumable(const WOLFSSL_SESSION *s)
38418
{
38419
    s = ClientSessionToSession(s);
38420
    if (s == NULL)
38421
        return 0;
38422
38423
#ifdef HAVE_SESSION_TICKET
38424
    if (s->ticketLen > 0)
38425
        return 1;
38426
#endif
38427
38428
    if (s->sessionIDSz > 0)
38429
        return 1;
38430
38431
    return 0;
38432
}
38433
38434
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
38435
/*
38436
 * This API accepts a user callback which puts key-log records into
38437
 * a KEY LOGFILE. The callback is stored into a CTX and propagated to
38438
 * each SSL object on its creation timing.
38439
 */
38440
void wolfSSL_CTX_set_keylog_callback(WOLFSSL_CTX* ctx, wolfSSL_CTX_keylog_cb_func cb)
38441
{
38442
    WOLFSSL_ENTER("wolfSSL_CTX_set_keylog_callback");
38443
  /* stores the callback into WOLFSSL_CTX */
38444
    if (ctx != NULL) {
38445
        ctx->keyLogCb = cb;
38446
    }
38447
}
38448
wolfSSL_CTX_keylog_cb_func wolfSSL_CTX_get_keylog_callback(
38449
    const WOLFSSL_CTX* ctx)
38450
{
38451
    WOLFSSL_ENTER("wolfSSL_CTX_get_keylog_callback");
38452
    if (ctx != NULL)
38453
        return ctx->keyLogCb;
38454
    else
38455
        return NULL;
38456
}
38457
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
38458
38459
#endif /* OPENSSL_EXTRA */
38460
38461
#ifndef NO_CERT
38462
#define WOLFSSL_X509_INCLUDED
38463
#include "src/x509.c"
38464
#endif
38465
38466
/*******************************************************************************
38467
 * START OF standard C library wrapping APIs
38468
 ******************************************************************************/
38469
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
38470
                             defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
38471
                             defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
38472
#ifndef NO_WOLFSSL_STUB
38473
int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
38474
                                void *(*r) (void *, size_t, const char *,
38475
                                            int), void (*f) (void *))
38476
{
38477
    (void) m;
38478
    (void) r;
38479
    (void) f;
38480
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
38481
    WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
38482
38483
    return WOLFSSL_FAILURE;
38484
}
38485
#endif
38486
#endif
38487
38488
#if defined(OPENSSL_EXTRA)
38489
38490
/**
38491
 * free allocated memory resouce
38492
 * @param str  a pointer to resource to be freed
38493
 * @param file dummy argument
38494
 * @param line dummy argument
38495
 */
38496
void wolfSSL_CRYPTO_free(void *str, const char *file, int line)
38497
{
38498
    (void)file;
38499
    (void)line;
38500
    XFREE(str, 0, DYNAMIC_TYPE_TMP_BUFFER);
38501
}
38502
/**
38503
 * allocate memory with size of num
38504
 * @param num  size of memory allocation to be malloced
38505
 * @param file dummy argument
38506
 * @param line dummy argument
38507
 * @return a pointer to allocated memory on succssesful, otherwise NULL
38508
 */
38509
void *wolfSSL_CRYPTO_malloc(size_t num, const char *file, int line)
38510
{
38511
    (void)file;
38512
    (void)line;
38513
    return XMALLOC(num, 0, DYNAMIC_TYPE_TMP_BUFFER);
38514
}
38515
38516
#endif
38517
38518
/*******************************************************************************
38519
 * END OF standard C library wrapping APIs
38520
 ******************************************************************************/
38521
38522
/*******************************************************************************
38523
 * START OF EX_DATA APIs
38524
 ******************************************************************************/
38525
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
38526
                             defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
38527
                             defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
38528
void wolfSSL_CRYPTO_cleanup_all_ex_data(void){
38529
    WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data");
38530
}
38531
#endif
38532
38533
#ifdef HAVE_EX_DATA
38534
void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx)
38535
{
38536
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
38537
#ifdef MAX_EX_DATA
38538
    if(ex_data && idx < MAX_EX_DATA && idx >= 0) {
38539
        return ex_data->ex_data[idx];
38540
    }
38541
#else
38542
    (void)ex_data;
38543
    (void)idx;
38544
#endif
38545
    return NULL;
38546
}
38547
38548
int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx, void *data)
38549
{
38550
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data");
38551
#ifdef MAX_EX_DATA
38552
    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
38553
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
38554
        if (ex_data->ex_data_cleanup_routines[idx]) {
38555
            if (ex_data->ex_data[idx])
38556
                ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
38557
            ex_data->ex_data_cleanup_routines[idx] = NULL;
38558
        }
38559
#endif
38560
        ex_data->ex_data[idx] = data;
38561
        return WOLFSSL_SUCCESS;
38562
    }
38563
#else
38564
    (void)ex_data;
38565
    (void)idx;
38566
    (void)data;
38567
#endif
38568
    return WOLFSSL_FAILURE;
38569
}
38570
38571
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
38572
int wolfSSL_CRYPTO_set_ex_data_with_cleanup(
38573
    WOLFSSL_CRYPTO_EX_DATA* ex_data,
38574
    int idx,
38575
    void *data,
38576
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
38577
{
38578
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data_with_cleanup");
38579
    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
38580
        if (ex_data->ex_data_cleanup_routines[idx] && ex_data->ex_data[idx])
38581
            ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
38582
        ex_data->ex_data[idx] = data;
38583
        ex_data->ex_data_cleanup_routines[idx] = cleanup_routine;
38584
        return WOLFSSL_SUCCESS;
38585
    }
38586
    return WOLFSSL_FAILURE;
38587
}
38588
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
38589
38590
/**
38591
 * Issues unique index for the class specified by class_index.
38592
 * Other parameter except class_index are ignored.
38593
 * Currently, following class_index are accepted:
38594
 *  - WOLF_CRYPTO_EX_INDEX_SSL
38595
 *  - WOLF_CRYPTO_EX_INDEX_SSL_CTX
38596
 *  - WOLF_CRYPTO_EX_INDEX_X509
38597
 * @param class_index index one of CRYPTO_EX_INDEX_xxx
38598
 * @param argp  parameters to be saved
38599
 * @param argl  parameters to be saved
38600
 * @param new_func a pointer to WOLFSSL_CRYPTO_EX_new
38601
 * @param dup_func a pointer to WOLFSSL_CRYPTO_EX_dup
38602
 * @param free_func a pointer to WOLFSSL_CRYPTO_EX_free
38603
 * @return index value grater or equal to zero on success, -1 on failure.
38604
 */
38605
int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
38606
                                           WOLFSSL_CRYPTO_EX_new* new_func,
38607
                                           WOLFSSL_CRYPTO_EX_dup* dup_func,
38608
                                           WOLFSSL_CRYPTO_EX_free* free_func)
38609
{
38610
    WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_new_index");
38611
38612
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(argl, argp, new_func, dup_func,
38613
                                         free_func);
38614
38615
    return wolfssl_get_ex_new_index(class_index);
38616
}
38617
#endif /* HAVE_EX_DATA */
38618
38619
/*******************************************************************************
38620
 * END OF EX_DATA APIs
38621
 ******************************************************************************/
38622
38623
/*******************************************************************************
38624
 * START OF BUF_MEM API
38625
 ******************************************************************************/
38626
38627
#if defined(OPENSSL_EXTRA)
38628
38629
/* Begin functions for openssl/buffer.h */
38630
WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
38631
{
38632
    WOLFSSL_BUF_MEM* buf;
38633
    buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
38634
                                                        DYNAMIC_TYPE_OPENSSL);
38635
    if (buf) {
38636
        XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
38637
    }
38638
    return buf;
38639
}
38640
38641
/* non-compat API returns length of buffer on success */
38642
int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len,
38643
        char zeroFill)
38644
{
38645
38646
    int len_int = (int)len;
38647
    int mx;
38648
    char* tmp;
38649
38650
    /* verify provided arguments */
38651
    if (buf == NULL || len_int < 0) {
38652
        return 0; /* BAD_FUNC_ARG; */
38653
    }
38654
38655
    /* check to see if fits in existing length */
38656
    if (buf->length > len) {
38657
        buf->length = len;
38658
        return len_int;
38659
    }
38660
38661
    /* check to see if fits in max buffer */
38662
    if (buf->max >= len) {
38663
        if (buf->data != NULL && zeroFill) {
38664
            XMEMSET(&buf->data[buf->length], 0, len - buf->length);
38665
        }
38666
        buf->length = len;
38667
        return len_int;
38668
    }
38669
38670
    /* expand size, to handle growth */
38671
    mx = (len_int + 3) / 3 * 4;
38672
38673
    /* use realloc */
38674
    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
38675
    if (tmp == NULL) {
38676
        return 0; /* ERR_R_MALLOC_FAILURE; */
38677
    }
38678
    buf->data = tmp;
38679
38680
    buf->max = mx;
38681
    if (zeroFill)
38682
        XMEMSET(&buf->data[buf->length], 0, len - buf->length);
38683
    buf->length = len;
38684
38685
    return len_int;
38686
38687
}
38688
38689
/* returns length of buffer on success */
38690
int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
38691
{
38692
    return wolfSSL_BUF_MEM_grow_ex(buf, len, 1);
38693
}
38694
38695
/* non-compat API returns length of buffer on success */
38696
int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len)
38697
{
38698
    char* tmp;
38699
    int mx;
38700
38701
    /* verify provided arguments */
38702
    if (buf == NULL || len == 0 || (int)len <= 0) {
38703
        return 0; /* BAD_FUNC_ARG; */
38704
    }
38705
38706
    if (len == buf->length)
38707
        return (int)len;
38708
38709
    if (len > buf->length)
38710
        return wolfSSL_BUF_MEM_grow_ex(buf, len, 0);
38711
38712
    /* expand size, to handle growth */
38713
    mx = ((int)len + 3) / 3 * 4;
38714
38715
    /* We want to shrink the internal buffer */
38716
    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
38717
    if (tmp == NULL)
38718
        return 0;
38719
38720
    buf->data = tmp;
38721
    buf->length = len;
38722
    buf->max = mx;
38723
38724
    return (int)len;
38725
}
38726
38727
void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
38728
{
38729
    if (buf) {
38730
        if (buf->data) {
38731
            XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
38732
            buf->data = NULL;
38733
        }
38734
        buf->max = 0;
38735
        buf->length = 0;
38736
        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
38737
    }
38738
}
38739
/* End Functions for openssl/buffer.h */
38740
38741
#endif /* OPENSSL_EXTRA */
38742
38743
/*******************************************************************************
38744
 * END OF BUF_MEM API
38745
 ******************************************************************************/
38746
38747
#define WOLFSSL_CONF_INCLUDED
38748
#include <src/conf.c>
38749
38750
/*******************************************************************************
38751
 * START OF RAND API
38752
 ******************************************************************************/
38753
38754
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
38755
static int wolfSSL_RAND_InitMutex(void)
38756
{
38757
    if (gRandMethodsInit == 0) {
38758
        if (wc_InitMutex(&gRandMethodMutex) != 0) {
38759
            WOLFSSL_MSG("Bad Init Mutex rand methods");
38760
            return BAD_MUTEX_E;
38761
        }
38762
        gRandMethodsInit = 1;
38763
    }
38764
    return 0;
38765
}
38766
#endif
38767
38768
#ifdef OPENSSL_EXTRA
38769
38770
/* Checks if the global RNG has been created. If not then one is created.
38771
 *
38772
 * Returns WOLFSSL_SUCCESS when no error is encountered.
38773
 */
38774
int wolfSSL_RAND_Init(void)
38775
{
38776
    int ret = WOLFSSL_FAILURE;
38777
#ifdef HAVE_GLOBAL_RNG
38778
    if (wc_LockMutex(&globalRNGMutex) == 0) {
38779
        if (initGlobalRNG == 0) {
38780
            ret = wc_InitRng(&globalRNG);
38781
            if (ret == 0) {
38782
                initGlobalRNG = 1;
38783
                ret = WOLFSSL_SUCCESS;
38784
            }
38785
        }
38786
        wc_UnLockMutex(&globalRNGMutex);
38787
    }
38788
#endif
38789
    return ret;
38790
}
38791
38792
38793
/* WOLFSSL_SUCCESS on ok */
38794
int wolfSSL_RAND_seed(const void* seed, int len)
38795
{
38796
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38797
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38798
        if (gRandMethods && gRandMethods->seed) {
38799
            int ret = gRandMethods->seed(seed, len);
38800
            wc_UnLockMutex(&gRandMethodMutex);
38801
            return ret;
38802
        }
38803
        wc_UnLockMutex(&gRandMethodMutex);
38804
    }
38805
#else
38806
    (void)seed;
38807
    (void)len;
38808
#endif
38809
38810
    /* Make sure global shared RNG (globalRNG) is initialized */
38811
    return wolfSSL_RAND_Init();
38812
}
38813
38814
38815
/* Returns the path for reading seed data from.
38816
 * Uses the env variable $RANDFILE first if set, if not then used $HOME/.rnd
38817
 *
38818
 * Note uses stdlib by default unless XGETENV macro is overwritten
38819
 *
38820
 * fname buffer to hold path
38821
 * len   length of fname buffer
38822
 *
38823
 * Returns a pointer to fname on success and NULL on failure
38824
 */
38825
const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
38826
{
38827
#ifndef NO_FILESYSTEM
38828
    char* rt;
38829
    char ap[] = "/.rnd";
38830
38831
    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
38832
38833
    if (fname == NULL) {
38834
        return NULL;
38835
    }
38836
38837
    XMEMSET(fname, 0, len);
38838
    /* if access to stdlib.h */
38839
    if ((rt = XGETENV("RANDFILE")) != NULL) {
38840
        if (len > XSTRLEN(rt)) {
38841
            XMEMCPY(fname, rt, XSTRLEN(rt));
38842
        }
38843
        else {
38844
            WOLFSSL_MSG("RANDFILE too large for buffer");
38845
            rt = NULL;
38846
        }
38847
    }
38848
38849
    /* $RANDFILE was not set or is too large, check $HOME */
38850
    if (rt == NULL) {
38851
        WOLFSSL_MSG("Environment variable RANDFILE not set");
38852
        if ((rt = XGETENV("HOME")) == NULL) {
38853
            WOLFSSL_MSG("Environment variable HOME not set");
38854
            return NULL;
38855
        }
38856
38857
        if (len > XSTRLEN(rt) +  XSTRLEN(ap)) {
38858
            fname[0] = '\0';
38859
            XSTRNCAT(fname, rt, len);
38860
            XSTRNCAT(fname, ap, len - XSTRLEN(rt));
38861
            return fname;
38862
        }
38863
        else {
38864
            WOLFSSL_MSG("HOME too large for buffer");
38865
            return NULL;
38866
        }
38867
    }
38868
38869
    return fname;
38870
#else
38871
    /* no filesystem defined */
38872
    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
38873
    WOLFSSL_MSG("No filesystem feature enabled, not compiled in");
38874
    (void)fname;
38875
    (void)len;
38876
    return NULL;
38877
#endif
38878
}
38879
38880
38881
/* Writes 1024 bytes from the RNG to the given file name.
38882
 *
38883
 * fname name of file to write to
38884
 *
38885
 * Returns the number of bytes written
38886
 */
38887
int wolfSSL_RAND_write_file(const char* fname)
38888
{
38889
    int bytes = 0;
38890
38891
    WOLFSSL_ENTER("RAND_write_file");
38892
38893
    if (fname == NULL) {
38894
        return SSL_FAILURE;
38895
    }
38896
38897
#ifndef NO_FILESYSTEM
38898
    {
38899
    #ifndef WOLFSSL_SMALL_STACK
38900
        unsigned char buf[1024];
38901
    #else
38902
        unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
38903
                                                       DYNAMIC_TYPE_TMP_BUFFER);
38904
        if (buf == NULL) {
38905
            WOLFSSL_MSG("malloc failed");
38906
            return SSL_FAILURE;
38907
        }
38908
    #endif
38909
        bytes = 1024; /* default size of buf */
38910
38911
        if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
38912
            WOLFSSL_MSG("No RNG to use");
38913
        #ifdef WOLFSSL_SMALL_STACK
38914
            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38915
        #endif
38916
            return 0;
38917
        }
38918
38919
        if (wc_RNG_GenerateBlock(&globalRNG, buf, bytes) != 0) {
38920
            WOLFSSL_MSG("Error generating random buffer");
38921
            bytes = 0;
38922
        }
38923
        else {
38924
            XFILE f;
38925
38926
        #ifdef WOLFSSL_CHECK_MEM_ZERO
38927
            wc_MemZero_Add("wolfSSL_RAND_write_file buf", buf, bytes);
38928
        #endif
38929
38930
            f = XFOPEN(fname, "wb");
38931
            if (f == XBADFILE) {
38932
                WOLFSSL_MSG("Error opening the file");
38933
                bytes = 0;
38934
            }
38935
            else {
38936
                size_t bytes_written = XFWRITE(buf, 1, bytes, f);
38937
                bytes = (int)bytes_written;
38938
                XFCLOSE(f);
38939
            }
38940
        }
38941
        ForceZero(buf, bytes);
38942
    #ifdef WOLFSSL_SMALL_STACK
38943
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38944
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
38945
        wc_MemZero_Check(buf, sizeof(buf));
38946
    #endif
38947
    }
38948
#endif
38949
38950
    return bytes;
38951
}
38952
38953
#ifndef FREERTOS_TCP
38954
38955
/* These constant values are protocol values made by egd */
38956
#if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && !defined(HAVE_FIPS) && \
38957
    defined(HAVE_HASHDRBG) && !defined(NETOS) && defined(HAVE_SYS_UN_H)
38958
    #define WOLFSSL_EGD_NBLOCK 0x01
38959
    #include <sys/un.h>
38960
#endif
38961
38962
/* This collects entropy from the path nm and seeds the global PRNG with it.
38963
 *
38964
 * nm is the file path to the egd server
38965
 *
38966
 * Returns the number of bytes read.
38967
 */
38968
int wolfSSL_RAND_egd(const char* nm)
38969
{
38970
#ifdef WOLFSSL_EGD_NBLOCK
38971
    struct sockaddr_un rem;
38972
    int fd;
38973
    int ret = WOLFSSL_SUCCESS;
38974
    word32 bytes = 0;
38975
    word32 idx   = 0;
38976
#ifndef WOLFSSL_SMALL_STACK
38977
    unsigned char buf[256];
38978
#else
38979
    unsigned char* buf;
38980
    buf = (unsigned char*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38981
    if (buf == NULL) {
38982
        WOLFSSL_MSG("Not enough memory");
38983
        return WOLFSSL_FATAL_ERROR;
38984
    }
38985
#endif
38986
38987
    XMEMSET(&rem, 0, sizeof(struct sockaddr_un));
38988
    if (nm == NULL) {
38989
    #ifdef WOLFSSL_SMALL_STACK
38990
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38991
    #endif
38992
        return WOLFSSL_FATAL_ERROR;
38993
    }
38994
38995
    fd = socket(AF_UNIX, SOCK_STREAM, 0);
38996
    if (fd < 0) {
38997
        WOLFSSL_MSG("Error creating socket");
38998
    #ifdef WOLFSSL_SMALL_STACK
38999
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
39000
    #endif
39001
        return WOLFSSL_FATAL_ERROR;
39002
    }
39003
    rem.sun_family = AF_UNIX;
39004
    XSTRNCPY(rem.sun_path, nm, sizeof(rem.sun_path) - 1);
39005
    rem.sun_path[sizeof(rem.sun_path)-1] = '\0';
39006
39007
    /* connect to egd server */
39008
    if (connect(fd, (struct sockaddr*)&rem, sizeof(struct sockaddr_un)) == -1) {
39009
        WOLFSSL_MSG("error connecting to egd server");
39010
        ret = WOLFSSL_FATAL_ERROR;
39011
    }
39012
39013
#ifdef WOLFSSL_CHECK_MEM_ZERO
39014
    if (ret == WOLFSSL_SUCCESS) {
39015
        wc_MemZero_Add("wolfSSL_RAND_egd buf", buf, 256);
39016
    }
39017
#endif
39018
    while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) {
39019
        buf[idx]     = WOLFSSL_EGD_NBLOCK;
39020
        buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */
39021
        ret = (int)write(fd, buf + idx, 2);
39022
        if (ret != 2) {
39023
            if (errno == EAGAIN) {
39024
                ret = WOLFSSL_SUCCESS;
39025
                continue;
39026
            }
39027
            WOLFSSL_MSG("error requesting entropy from egd server");
39028
            ret = WOLFSSL_FATAL_ERROR;
39029
            break;
39030
        }
39031
39032
        /* attempting to read */
39033
        buf[idx] = 0;
39034
        ret = (int)read(fd, buf + idx, 256 - bytes);
39035
        if (ret == 0) {
39036
            WOLFSSL_MSG("error reading entropy from egd server");
39037
            ret = WOLFSSL_FATAL_ERROR;
39038
            break;
39039
        }
39040
        if (ret > 0 && buf[idx] > 0) {
39041
            bytes += buf[idx]; /* egd stores amount sent in first byte */
39042
            if (bytes + idx > 255 || buf[idx] > ret) {
39043
                WOLFSSL_MSG("Buffer error");
39044
                ret = WOLFSSL_FATAL_ERROR;
39045
                break;
39046
            }
39047
            XMEMMOVE(buf + idx, buf + idx + 1, buf[idx]);
39048
            idx = bytes;
39049
            ret = WOLFSSL_SUCCESS;
39050
            if (bytes >= 255) {
39051
                break;
39052
            }
39053
        }
39054
        else {
39055
            if (errno == EAGAIN || errno == EINTR) {
39056
                WOLFSSL_MSG("EGD would read");
39057
                ret = WOLFSSL_SUCCESS; /* try again */
39058
            }
39059
            else if (buf[idx] == 0) {
39060
                /* if egd returned 0 then there is no more entropy to be had.
39061
                   Do not try more reads. */
39062
                ret = WOLFSSL_SUCCESS;
39063
                break;
39064
            }
39065
            else {
39066
                WOLFSSL_MSG("Error with read");
39067
                ret = WOLFSSL_FATAL_ERROR;
39068
            }
39069
        }
39070
    }
39071
39072
    if (bytes > 0 && ret == WOLFSSL_SUCCESS) {
39073
        /* call to check global RNG is created */
39074
        if (wolfSSL_RAND_Init() != SSL_SUCCESS) {
39075
            WOLFSSL_MSG("Error with initializing global RNG structure");
39076
            ret = WOLFSSL_FATAL_ERROR;
39077
        }
39078
        else if (wc_RNG_DRBG_Reseed(&globalRNG, (const byte*) buf, bytes)
39079
                != 0) {
39080
            WOLFSSL_MSG("Error with reseeding DRBG structure");
39081
            ret = WOLFSSL_FATAL_ERROR;
39082
        }
39083
        #ifdef SHOW_SECRETS
39084
        else { /* print out entropy found only when no error occured */
39085
            word32 i;
39086
            printf("EGD Entropy = ");
39087
            for (i = 0; i < bytes; i++) {
39088
                printf("%02X", buf[i]);
39089
            }
39090
            printf("\n");
39091
        }
39092
        #endif
39093
    }
39094
39095
    ForceZero(buf, bytes);
39096
#ifdef WOLFSSL_SMALL_STACK
39097
    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
39098
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
39099
    wc_MemZero_Check(buf, 256);
39100
#endif
39101
    close(fd);
39102
39103
    if (ret == WOLFSSL_SUCCESS) {
39104
        return bytes;
39105
    }
39106
    else {
39107
        return ret;
39108
    }
39109
#else
39110
    WOLFSSL_MSG("Type of socket needed is not available");
39111
    WOLFSSL_MSG("\tor using mode where DRBG API is not available");
39112
    (void)nm;
39113
39114
    return WOLFSSL_FATAL_ERROR;
39115
#endif /* WOLFSSL_EGD_NBLOCK */
39116
}
39117
39118
#endif /* !FREERTOS_TCP */
39119
39120
void wolfSSL_RAND_Cleanup(void)
39121
{
39122
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
39123
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
39124
        if (gRandMethods && gRandMethods->cleanup)
39125
            gRandMethods->cleanup();
39126
        wc_UnLockMutex(&gRandMethodMutex);
39127
    }
39128
39129
    if (wc_FreeMutex(&gRandMethodMutex) == 0)
39130
        gRandMethodsInit = 0;
39131
#endif
39132
#ifdef HAVE_GLOBAL_RNG
39133
    if (wc_LockMutex(&globalRNGMutex) == 0) {
39134
        if (initGlobalRNG) {
39135
            wc_FreeRng(&globalRNG);
39136
            initGlobalRNG = 0;
39137
        }
39138
        wc_UnLockMutex(&globalRNGMutex);
39139
    }
39140
#endif
39141
}
39142
39143
/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
39144
int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
39145
{
39146
    int ret;
39147
    int hash;
39148
    byte secret[DRBG_SEED_LEN]; /* secret length arbitraily choosen */
39149
39150
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
39151
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
39152
        if (gRandMethods && gRandMethods->pseudorand) {
39153
            ret = gRandMethods->pseudorand(buf, num);
39154
            wc_UnLockMutex(&gRandMethodMutex);
39155
            return ret;
39156
        }
39157
        wc_UnLockMutex(&gRandMethodMutex);
39158
    }
39159
#endif
39160
39161
#ifdef WOLFSSL_HAVE_PRF
39162
    #ifndef NO_SHA256
39163
    hash = WC_SHA256;
39164
    #elif defined(WOLFSSL_SHA384)
39165
    hash = WC_SHA384;
39166
    #elif !defined(NO_SHA)
39167
    hash = WC_SHA;
39168
    #elif !defined(NO_MD5)
39169
    hash = WC_MD5;
39170
    #endif
39171
39172
    /* get secret value from source of entropy */
39173
    ret = wolfSSL_RAND_bytes(secret, DRBG_SEED_LEN);
39174
39175
    /* uses input buffer to seed for pseudo random number generation, each
39176
     * thread will potentially have different results this way */
39177
    if (ret == WOLFSSL_SUCCESS) {
39178
        PRIVATE_KEY_UNLOCK();
39179
        ret = wc_PRF(buf, num, secret, DRBG_SEED_LEN, (const byte*)buf, num,
39180
                hash, NULL, INVALID_DEVID);
39181
        PRIVATE_KEY_LOCK();
39182
        ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
39183
    }
39184
#else
39185
    /* fall back to just doing wolfSSL_RAND_bytes if PRF not avialbale */
39186
    ret = wolfSSL_RAND_bytes(buf, num);
39187
    (void)hash;
39188
    (void)secret;
39189
#endif
39190
    return ret;
39191
}
39192
39193
/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
39194
int wolfSSL_RAND_bytes(unsigned char* buf, int num)
39195
{
39196
    int     ret = 0;
39197
    WC_RNG* rng = NULL;
39198
#ifdef WOLFSSL_SMALL_STACK
39199
    WC_RNG* tmpRNG = NULL;
39200
#else
39201
    WC_RNG  tmpRNG[1];
39202
#endif
39203
    int initTmpRng = 0;
39204
    int blockCount = 0;
39205
#ifdef HAVE_GLOBAL_RNG
39206
    int used_global = 0;
39207
#endif
39208
39209
    WOLFSSL_ENTER("wolfSSL_RAND_bytes");
39210
    /* sanity check */
39211
    if (buf == NULL || num < 0)
39212
        /* return code compliant with OpenSSL */
39213
        return 0;
39214
39215
    /* if a RAND callback has been set try and use it */
39216
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
39217
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
39218
        if (gRandMethods && gRandMethods->bytes) {
39219
            ret = gRandMethods->bytes(buf, num);
39220
            wc_UnLockMutex(&gRandMethodMutex);
39221
            return ret;
39222
        }
39223
        wc_UnLockMutex(&gRandMethodMutex);
39224
    }
39225
#endif
39226
#ifdef HAVE_GLOBAL_RNG
39227
    if (initGlobalRNG) {
39228
        if (wc_LockMutex(&globalRNGMutex) != 0) {
39229
            WOLFSSL_MSG("Bad Lock Mutex rng");
39230
            return ret;
39231
        }
39232
39233
        rng = &globalRNG;
39234
        used_global = 1;
39235
    }
39236
    else
39237
#endif
39238
    {
39239
    #ifdef WOLFSSL_SMALL_STACK
39240
        tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
39241
        if (tmpRNG == NULL)
39242
            return ret;
39243
    #endif
39244
        if (wc_InitRng(tmpRNG) == 0) {
39245
            rng = tmpRNG;
39246
            initTmpRng = 1;
39247
        }
39248
    }
39249
    if (rng) {
39250
        /* handles size greater than RNG_MAX_BLOCK_LEN */
39251
        blockCount = num / RNG_MAX_BLOCK_LEN;
39252
39253
        while (blockCount--) {
39254
            ret = wc_RNG_GenerateBlock(rng, buf, RNG_MAX_BLOCK_LEN);
39255
            if (ret != 0) {
39256
                WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
39257
                break;
39258
            }
39259
            num -= RNG_MAX_BLOCK_LEN;
39260
            buf += RNG_MAX_BLOCK_LEN;
39261
        }
39262
39263
        if (ret == 0 && num)
39264
            ret = wc_RNG_GenerateBlock(rng, buf, num);
39265
39266
        if (ret != 0)
39267
            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
39268
        else
39269
            ret = WOLFSSL_SUCCESS;
39270
    }
39271
39272
#ifdef HAVE_GLOBAL_RNG
39273
    if (used_global == 1)
39274
        wc_UnLockMutex(&globalRNGMutex);
39275
#endif
39276
    if (initTmpRng)
39277
        wc_FreeRng(tmpRNG);
39278
#ifdef WOLFSSL_SMALL_STACK
39279
    if (tmpRNG)
39280
        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
39281
#endif
39282
39283
    return ret;
39284
}
39285
39286
39287
int wolfSSL_RAND_poll(void)
39288
{
39289
    byte  entropy[16];
39290
    int  ret = 0;
39291
    word32 entropy_sz = 16;
39292
39293
    WOLFSSL_ENTER("wolfSSL_RAND_poll");
39294
    if (initGlobalRNG == 0){
39295
        WOLFSSL_MSG("Global RNG no Init");
39296
        return  WOLFSSL_FAILURE;
39297
    }
39298
    ret = wc_GenerateSeed(&globalRNG.seed, entropy, entropy_sz);
39299
    if (ret != 0){
39300
        WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
39301
        ret = WOLFSSL_FAILURE;
39302
    }else
39303
        ret = WOLFSSL_SUCCESS;
39304
39305
    return ret;
39306
}
39307
39308
    /* If a valid struct is provided with function pointers, will override
39309
       RAND_seed, bytes, cleanup, add, pseudo_bytes and status.  If a NULL
39310
       pointer is passed in, it will cancel any previous function overrides.
39311
39312
       Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. */
39313
    int wolfSSL_RAND_set_rand_method(const WOLFSSL_RAND_METHOD *methods)
39314
    {
39315
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
39316
        if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
39317
            gRandMethods = methods;
39318
            wc_UnLockMutex(&gRandMethodMutex);
39319
            return WOLFSSL_SUCCESS;
39320
        }
39321
    #else
39322
        (void)methods;
39323
    #endif
39324
        return WOLFSSL_FAILURE;
39325
    }
39326
39327
    /* Returns WOLFSSL_SUCCESS if the RNG has been seeded with enough data */
39328
    int wolfSSL_RAND_status(void)
39329
    {
39330
        int ret = WOLFSSL_SUCCESS;
39331
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
39332
        if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
39333
            if (gRandMethods && gRandMethods->status)
39334
                ret = gRandMethods->status();
39335
            wc_UnLockMutex(&gRandMethodMutex);
39336
        }
39337
        else {
39338
            ret = WOLFSSL_FAILURE;
39339
        }
39340
    #else
39341
        /* wolfCrypt provides enough seed internally, so return success */
39342
    #endif
39343
        return ret;
39344
    }
39345
39346
    void wolfSSL_RAND_add(const void* add, int len, double entropy)
39347
    {
39348
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
39349
        if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
39350
            if (gRandMethods && gRandMethods->add) {
39351
                /* callback has return code, but RAND_add does not */
39352
                (void)gRandMethods->add(add, len, entropy);
39353
            }
39354
            wc_UnLockMutex(&gRandMethodMutex);
39355
        }
39356
    #else
39357
        /* wolfSSL seeds/adds internally, use explicit RNG if you want
39358
           to take control */
39359
        (void)add;
39360
        (void)len;
39361
        (void)entropy;
39362
    #endif
39363
    }
39364
39365
#endif /* OPENSSL_EXTRA */
39366
39367
/*******************************************************************************
39368
 * END OF RAND API
39369
 ******************************************************************************/
39370
39371
/*******************************************************************************
39372
 * START OF EVP_CIPHER API
39373
 ******************************************************************************/
39374
39375
#ifdef OPENSSL_EXTRA
39376
39377
    /* store for external read of iv, WOLFSSL_SUCCESS on success */
39378
    int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
39379
    {
39380
        WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
39381
39382
        if (ctx == NULL) {
39383
            WOLFSSL_MSG("Bad function argument");
39384
            return WOLFSSL_FATAL_ERROR;
39385
        }
39386
39387
        switch (ctx->cipherType) {
39388
#ifndef NO_AES
39389
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
39390
            case AES_128_CBC_TYPE :
39391
            case AES_192_CBC_TYPE :
39392
            case AES_256_CBC_TYPE :
39393
                WOLFSSL_MSG("AES CBC");
39394
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
39395
                break;
39396
#endif
39397
#ifdef HAVE_AESGCM
39398
            case AES_128_GCM_TYPE :
39399
            case AES_192_GCM_TYPE :
39400
            case AES_256_GCM_TYPE :
39401
                WOLFSSL_MSG("AES GCM");
39402
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
39403
                break;
39404
#endif /* HAVE_AESGCM */
39405
#ifdef HAVE_AES_ECB
39406
            case AES_128_ECB_TYPE :
39407
            case AES_192_ECB_TYPE :
39408
            case AES_256_ECB_TYPE :
39409
                WOLFSSL_MSG("AES ECB");
39410
                break;
39411
#endif
39412
#ifdef WOLFSSL_AES_COUNTER
39413
            case AES_128_CTR_TYPE :
39414
            case AES_192_CTR_TYPE :
39415
            case AES_256_CTR_TYPE :
39416
                WOLFSSL_MSG("AES CTR");
39417
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
39418
                break;
39419
#endif /* WOLFSSL_AES_COUNTER */
39420
#ifdef WOLFSSL_AES_CFB
39421
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
39422
            case AES_128_CFB1_TYPE:
39423
            case AES_192_CFB1_TYPE:
39424
            case AES_256_CFB1_TYPE:
39425
                WOLFSSL_MSG("AES CFB1");
39426
                break;
39427
            case AES_128_CFB8_TYPE:
39428
            case AES_192_CFB8_TYPE:
39429
            case AES_256_CFB8_TYPE:
39430
                WOLFSSL_MSG("AES CFB8");
39431
                break;
39432
#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
39433
            case AES_128_CFB128_TYPE:
39434
            case AES_192_CFB128_TYPE:
39435
            case AES_256_CFB128_TYPE:
39436
                WOLFSSL_MSG("AES CFB128");
39437
                break;
39438
#endif /* WOLFSSL_AES_CFB */
39439
#if defined(WOLFSSL_AES_OFB)
39440
            case AES_128_OFB_TYPE:
39441
            case AES_192_OFB_TYPE:
39442
            case AES_256_OFB_TYPE:
39443
                WOLFSSL_MSG("AES OFB");
39444
                break;
39445
#endif /* WOLFSSL_AES_OFB */
39446
#ifdef WOLFSSL_AES_XTS
39447
            case AES_128_XTS_TYPE:
39448
            case AES_256_XTS_TYPE:
39449
                WOLFSSL_MSG("AES XTS");
39450
                break;
39451
#endif /* WOLFSSL_AES_XTS */
39452
#endif /* NO_AES */
39453
39454
#ifndef NO_DES3
39455
            case DES_CBC_TYPE :
39456
                WOLFSSL_MSG("DES CBC");
39457
                XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
39458
                break;
39459
39460
            case DES_EDE3_CBC_TYPE :
39461
                WOLFSSL_MSG("DES EDE3 CBC");
39462
                XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
39463
                break;
39464
#endif
39465
#ifdef WOLFSSL_DES_ECB
39466
            case DES_ECB_TYPE :
39467
                WOLFSSL_MSG("DES ECB");
39468
                break;
39469
            case DES_EDE3_ECB_TYPE :
39470
                WOLFSSL_MSG("DES3 ECB");
39471
                break;
39472
#endif
39473
            case ARC4_TYPE :
39474
                WOLFSSL_MSG("ARC4");
39475
                break;
39476
39477
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
39478
            case CHACHA20_POLY1305_TYPE:
39479
                break;
39480
#endif
39481
39482
#ifdef HAVE_CHACHA
39483
            case CHACHA20_TYPE:
39484
                break;
39485
#endif
39486
39487
            case NULL_CIPHER_TYPE :
39488
                WOLFSSL_MSG("NULL");
39489
                break;
39490
39491
            default: {
39492
                WOLFSSL_MSG("bad type");
39493
                return WOLFSSL_FATAL_ERROR;
39494
            }
39495
        }
39496
        return WOLFSSL_SUCCESS;
39497
    }
39498
39499
    /* set internal IV from external, WOLFSSL_SUCCESS on success */
39500
    int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
39501
    {
39502
39503
        WOLFSSL_ENTER("wolfSSL_SetInternalIV");
39504
39505
        if (ctx == NULL) {
39506
            WOLFSSL_MSG("Bad function argument");
39507
            return WOLFSSL_FATAL_ERROR;
39508
        }
39509
39510
        switch (ctx->cipherType) {
39511
39512
#ifndef NO_AES
39513
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
39514
            case AES_128_CBC_TYPE :
39515
            case AES_192_CBC_TYPE :
39516
            case AES_256_CBC_TYPE :
39517
                WOLFSSL_MSG("AES CBC");
39518
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
39519
                break;
39520
#endif
39521
#ifdef HAVE_AESGCM
39522
            case AES_128_GCM_TYPE :
39523
            case AES_192_GCM_TYPE :
39524
            case AES_256_GCM_TYPE :
39525
                WOLFSSL_MSG("AES GCM");
39526
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
39527
                break;
39528
#endif
39529
#ifdef HAVE_AES_ECB
39530
            case AES_128_ECB_TYPE :
39531
            case AES_192_ECB_TYPE :
39532
            case AES_256_ECB_TYPE :
39533
                WOLFSSL_MSG("AES ECB");
39534
                break;
39535
#endif
39536
#ifdef WOLFSSL_AES_COUNTER
39537
            case AES_128_CTR_TYPE :
39538
            case AES_192_CTR_TYPE :
39539
            case AES_256_CTR_TYPE :
39540
                WOLFSSL_MSG("AES CTR");
39541
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
39542
                break;
39543
#endif
39544
39545
#endif /* NO_AES */
39546
39547
#ifndef NO_DES3
39548
            case DES_CBC_TYPE :
39549
                WOLFSSL_MSG("DES CBC");
39550
                XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
39551
                break;
39552
39553
            case DES_EDE3_CBC_TYPE :
39554
                WOLFSSL_MSG("DES EDE3 CBC");
39555
                XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
39556
                break;
39557
#endif
39558
#ifdef WOLFSSL_DES_ECB
39559
            case DES_ECB_TYPE :
39560
                WOLFSSL_MSG("DES ECB");
39561
                break;
39562
            case DES_EDE3_ECB_TYPE :
39563
                WOLFSSL_MSG("DES3 ECB");
39564
                break;
39565
#endif
39566
39567
            case ARC4_TYPE :
39568
                WOLFSSL_MSG("ARC4");
39569
                break;
39570
39571
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
39572
            case CHACHA20_POLY1305_TYPE:
39573
                break;
39574
#endif
39575
39576
#ifdef HAVE_CHACHA
39577
            case CHACHA20_TYPE:
39578
                break;
39579
#endif
39580
39581
            case NULL_CIPHER_TYPE :
39582
                WOLFSSL_MSG("NULL");
39583
                break;
39584
39585
            default: {
39586
                WOLFSSL_MSG("bad type");
39587
                return WOLFSSL_FATAL_ERROR;
39588
            }
39589
        }
39590
        return WOLFSSL_SUCCESS;
39591
    }
39592
39593
#ifndef NO_DES3
39594
39595
void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
39596
                            unsigned char* iv, int len)
39597
{
39598
    (void)len;
39599
39600
    WOLFSSL_MSG("wolfSSL_3des_iv");
39601
39602
    if (ctx == NULL || iv == NULL) {
39603
        WOLFSSL_MSG("Bad function argument");
39604
        return;
39605
    }
39606
39607
    if (doset)
39608
        wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
39609
    else
39610
        XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
39611
}
39612
39613
#endif /* NO_DES3 */
39614
39615
39616
#ifndef NO_AES
39617
39618
void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
39619
                      unsigned char* iv, int len)
39620
{
39621
    (void)len;
39622
39623
    WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
39624
39625
    if (ctx == NULL || iv == NULL) {
39626
        WOLFSSL_MSG("Bad function argument");
39627
        return;
39628
    }
39629
39630
    if (doset)
39631
       (void)wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
39632
    else
39633
        XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
39634
}
39635
39636
#endif /* NO_AES */
39637
39638
#endif /* OPENSSL_EXTRA */
39639
39640
/*******************************************************************************
39641
 * END OF EVP_CIPHER API
39642
 ******************************************************************************/
39643
39644
#ifndef NO_CERTS
39645
39646
#define WOLFSSL_X509_STORE_INCLUDED
39647
#include <src/x509_str.c>
39648
39649
/*******************************************************************************
39650
 * START OF PKCS7 APIs
39651
 ******************************************************************************/
39652
#ifdef HAVE_PKCS7
39653
39654
#ifdef OPENSSL_ALL
39655
PKCS7* wolfSSL_PKCS7_new(void)
39656
{
39657
    WOLFSSL_PKCS7* pkcs7;
39658
    int ret = 0;
39659
39660
    pkcs7 = (WOLFSSL_PKCS7*)XMALLOC(sizeof(WOLFSSL_PKCS7), NULL,
39661
                                    DYNAMIC_TYPE_PKCS7);
39662
    if (pkcs7 != NULL) {
39663
        XMEMSET(pkcs7, 0, sizeof(WOLFSSL_PKCS7));
39664
        ret = wc_PKCS7_Init(&pkcs7->pkcs7, NULL, INVALID_DEVID);
39665
    }
39666
39667
    if (ret != 0 && pkcs7 != NULL) {
39668
        XFREE(pkcs7, NULL, DYNAMIC_TYPE_PKCS7);
39669
        pkcs7 = NULL;
39670
    }
39671
39672
    return (PKCS7*)pkcs7;
39673
}
39674
39675
/******************************************************************************
39676
* wolfSSL_PKCS7_SIGNED_new - allocates PKCS7 and initialize it for a signed data
39677
*
39678
* RETURNS:
39679
* returns pointer to the PKCS7 structure on success, otherwise returns NULL
39680
*/
39681
PKCS7_SIGNED* wolfSSL_PKCS7_SIGNED_new(void)
39682
{
39683
    byte signedData[]= { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02};
39684
    PKCS7* pkcs7 = NULL;
39685
39686
    if ((pkcs7 = wolfSSL_PKCS7_new()) == NULL)
39687
        return NULL;
39688
    pkcs7->contentOID = SIGNED_DATA;
39689
    if ((wc_PKCS7_SetContentType(pkcs7, signedData, sizeof(signedData))) < 0) {
39690
        if (pkcs7) {
39691
            wolfSSL_PKCS7_free(pkcs7);
39692
            return NULL;
39693
        }
39694
    }
39695
    return pkcs7;
39696
}
39697
39698
void wolfSSL_PKCS7_free(PKCS7* pkcs7)
39699
{
39700
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39701
39702
    if (p7 != NULL) {
39703
        if (p7->data != NULL)
39704
            XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
39705
        wc_PKCS7_Free(&p7->pkcs7);
39706
        if (p7->certs)
39707
            wolfSSL_sk_pop_free(p7->certs, NULL);
39708
        XFREE(p7, NULL, DYNAMIC_TYPE_PKCS7);
39709
    }
39710
}
39711
39712
void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7)
39713
{
39714
    wolfSSL_PKCS7_free(p7);
39715
    return;
39716
}
39717
39718
/**
39719
 * Convert DER/ASN.1 encoded signedData structure to internal PKCS7
39720
 * structure. Note, does not support detached content.
39721
 *
39722
 * p7 - pointer to set to address of newly created PKCS7 structure on return
39723
 * in - pointer to pointer of DER/ASN.1 data
39724
 * len - length of input data, bytes
39725
 *
39726
 * Returns newly allocated and populated PKCS7 structure or NULL on error.
39727
 */
39728
PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len)
39729
{
39730
    return wolfSSL_d2i_PKCS7_ex(p7, in, len, NULL, 0);
39731
}
39732
39733
/*****************************************************************************
39734
* wolfSSL_d2i_PKCS7_ex - Converts the given unsigned char buffer of size len
39735
* into a PKCS7 object.  Optionally, accepts a byte buffer of content which
39736
* is stored as the PKCS7 object's content, to support detached signatures.
39737
* @param content The content which is signed, in case the signature is
39738
*                detached.  Ignored if NULL.
39739
* @param contentSz The size of the passed in content.
39740
*
39741
* RETURNS:
39742
* returns pointer to a PKCS7 structure on success, otherwise returns NULL
39743
*/
39744
PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len,
39745
        byte* content, word32 contentSz)
39746
{
39747
    WOLFSSL_PKCS7* pkcs7 = NULL;
39748
39749
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_ex");
39750
39751
    if (in == NULL || *in == NULL || len < 0)
39752
        return NULL;
39753
39754
    if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
39755
        return NULL;
39756
39757
    pkcs7->len = len;
39758
    pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
39759
    if (pkcs7->data == NULL) {
39760
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39761
        return NULL;
39762
    }
39763
    XMEMCPY(pkcs7->data, *in, pkcs7->len);
39764
39765
    if (content != NULL) {
39766
        pkcs7->pkcs7.content = content;
39767
        pkcs7->pkcs7.contentSz = contentSz;
39768
    }
39769
    if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
39770
                                                                         != 0) {
39771
        WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
39772
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39773
        return NULL;
39774
    }
39775
39776
    if (p7 != NULL)
39777
        *p7 = (PKCS7*)pkcs7;
39778
    *in += pkcs7->len;
39779
    return (PKCS7*)pkcs7;
39780
}
39781
39782
/**
39783
 * This API was added as a helper function for libest. It
39784
 * extracts a stack of certificates from the pkcs7 object.
39785
 * @param pkcs7 PKCS7 parameter object
39786
 * @return WOLFSSL_STACK_OF(WOLFSSL_X509)*
39787
 */
39788
WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7)
39789
{
39790
    int i;
39791
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39792
    WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
39793
39794
    WOLFSSL_ENTER("wolfSSL_PKCS7_to_stack");
39795
39796
    if (!p7) {
39797
        WOLFSSL_MSG("Bad parameter");
39798
        return NULL;
39799
    }
39800
39801
    if (p7->certs)
39802
        return p7->certs;
39803
39804
    for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) {
39805
        WOLFSSL_X509* x509 = wolfSSL_X509_d2i(NULL, p7->pkcs7.cert[i],
39806
            p7->pkcs7.certSz[i]);
39807
        if (!ret)
39808
            ret = wolfSSL_sk_X509_new_null();
39809
        if (x509) {
39810
            if (wolfSSL_sk_X509_push(ret, x509) != WOLFSSL_SUCCESS) {
39811
                wolfSSL_X509_free(x509);
39812
                WOLFSSL_MSG("wolfSSL_sk_X509_push error");
39813
                goto error;
39814
            }
39815
        }
39816
        else {
39817
            WOLFSSL_MSG("wolfSSL_X509_d2i error");
39818
            goto error;
39819
        }
39820
    }
39821
39822
    /* Save stack to free later */
39823
    if (p7->certs)
39824
        wolfSSL_sk_pop_free(p7->certs, NULL);
39825
    p7->certs = ret;
39826
39827
    return ret;
39828
error:
39829
    if (ret) {
39830
        wolfSSL_sk_pop_free(ret, NULL);
39831
    }
39832
    return NULL;
39833
}
39834
39835
/**
39836
 * Return stack of signers contained in PKCS7 cert.
39837
 * Notes:
39838
 * - Currently only PKCS#7 messages with a single signer cert is supported.
39839
 * - Returned WOLFSSL_STACK must be freed by caller.
39840
 *
39841
 * pkcs7 - PKCS7 struct to retrieve signer certs from.
39842
 * certs - currently unused
39843
 * flags - flags to control function behavior.
39844
 *
39845
 * Return WOLFSSL_STACK of signers on success, NULL on error.
39846
 */
39847
WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs,
39848
                                          int flags)
39849
{
39850
    WOLFSSL_X509* x509 = NULL;
39851
    WOLFSSL_STACK* signers = NULL;
39852
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39853
39854
    if (p7 == NULL)
39855
        return NULL;
39856
39857
    /* Only PKCS#7 messages with a single cert that is the verifying certificate
39858
     * is supported.
39859
     */
39860
    if (flags & PKCS7_NOINTERN) {
39861
        WOLFSSL_MSG("PKCS7_NOINTERN flag not supported");
39862
        return NULL;
39863
    }
39864
39865
    signers = wolfSSL_sk_X509_new_null();
39866
    if (signers == NULL)
39867
        return NULL;
39868
39869
    if (wolfSSL_d2i_X509(&x509, (const byte**)&p7->pkcs7.singleCert,
39870
                         p7->pkcs7.singleCertSz) == NULL) {
39871
        wolfSSL_sk_X509_pop_free(signers, NULL);
39872
        return NULL;
39873
    }
39874
39875
    if (wolfSSL_sk_X509_push(signers, x509) != WOLFSSL_SUCCESS) {
39876
        wolfSSL_sk_X509_pop_free(signers, NULL);
39877
        return NULL;
39878
    }
39879
39880
    (void)certs;
39881
39882
    return signers;
39883
}
39884
39885
#ifndef NO_BIO
39886
39887
PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7)
39888
{
39889
    WOLFSSL_PKCS7* pkcs7;
39890
    int ret;
39891
39892
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_bio");
39893
39894
    if (bio == NULL)
39895
        return NULL;
39896
39897
    if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
39898
        return NULL;
39899
39900
    pkcs7->len = wolfSSL_BIO_get_len(bio);
39901
    pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
39902
    if (pkcs7->data == NULL) {
39903
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39904
        return NULL;
39905
    }
39906
39907
    if ((ret = wolfSSL_BIO_read(bio, pkcs7->data, pkcs7->len)) <= 0) {
39908
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39909
        return NULL;
39910
    }
39911
    /* pkcs7->len may change if using b64 for example */
39912
    pkcs7->len = ret;
39913
39914
    if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
39915
                                                                         != 0) {
39916
        WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
39917
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39918
        return NULL;
39919
    }
39920
39921
    if (p7 != NULL)
39922
        *p7 = (PKCS7*)pkcs7;
39923
    return (PKCS7*)pkcs7;
39924
}
39925
39926
int wolfSSL_i2d_PKCS7(PKCS7 *p7, unsigned char **out)
39927
{
39928
    byte* output = NULL;
39929
    int localBuf = 0;
39930
    int len;
39931
    WC_RNG rng;
39932
    int ret = WOLFSSL_FAILURE;
39933
    WOLFSSL_ENTER("wolfSSL_i2d_PKCS7");
39934
39935
    if (!out || !p7) {
39936
        WOLFSSL_MSG("Bad parameter");
39937
        return WOLFSSL_FAILURE;
39938
    }
39939
39940
    if (!p7->rng) {
39941
        if (wc_InitRng(&rng) != 0) {
39942
            WOLFSSL_MSG("wc_InitRng error");
39943
            return WOLFSSL_FAILURE;
39944
        }
39945
        p7->rng = &rng; // cppcheck-suppress autoVariables
39946
    }
39947
39948
    if ((len = wc_PKCS7_EncodeSignedData(p7, NULL, 0)) < 0) {
39949
        WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
39950
        goto cleanup;
39951
    }
39952
39953
    if (*out == NULL) {
39954
        output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
39955
        if (!output) {
39956
            WOLFSSL_MSG("malloc error");
39957
            goto cleanup;
39958
        }
39959
        localBuf = 1;
39960
    }
39961
    else {
39962
        output = *out;
39963
    }
39964
39965
    if ((len = wc_PKCS7_EncodeSignedData(p7, output, len)) < 0) {
39966
        WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
39967
        goto cleanup;
39968
    }
39969
39970
    ret = len;
39971
cleanup:
39972
    if (p7->rng == &rng) {
39973
        wc_FreeRng(&rng);
39974
        p7->rng = NULL;
39975
    }
39976
    if (ret == WOLFSSL_FAILURE && localBuf && output)
39977
        XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
39978
    if (ret != WOLFSSL_FAILURE)
39979
        *out = output;
39980
    return ret;
39981
}
39982
39983
int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7)
39984
{
39985
    byte* output = NULL;
39986
    int len;
39987
    int ret = WOLFSSL_FAILURE;
39988
    WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio");
39989
39990
    if (!bio || !p7) {
39991
        WOLFSSL_MSG("Bad parameter");
39992
        return WOLFSSL_FAILURE;
39993
    }
39994
39995
    if ((len = wolfSSL_i2d_PKCS7(p7, &output)) == WOLFSSL_FAILURE) {
39996
        WOLFSSL_MSG("wolfSSL_i2d_PKCS7 error");
39997
        goto cleanup;
39998
    }
39999
40000
    if (wolfSSL_BIO_write(bio, output, len) <= 0) {
40001
        WOLFSSL_MSG("wolfSSL_BIO_write error");
40002
        goto cleanup;
40003
    }
40004
40005
    ret = WOLFSSL_SUCCESS;
40006
cleanup:
40007
    if (output)
40008
        XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40009
    return ret;
40010
}
40011
40012
/**
40013
 * Creates and returns a PKCS7 signedData structure.
40014
 *
40015
 * Inner content type is set to DATA to match OpenSSL behavior.
40016
 *
40017
 * signer   - certificate to sign bundle with
40018
 * pkey     - private key matching signer
40019
 * certs    - optional additional set of certificates to include
40020
 * in       - input data to be signed
40021
 * flags    - optional set of flags to control sign behavior
40022
 *
40023
 *    PKCS7_BINARY   - Do not translate input data to MIME canonical
40024
 *                     format (\r\n line endings), thus preventing corruption of
40025
 *                     binary content.
40026
 *    PKCS7_TEXT     - Prepend MIME headers for text/plain to content.
40027
 *    PKCS7_DETACHED - Set signature detached, omit content from output bundle.
40028
 *    PKCS7_STREAM   - initialize PKCS7 struct for signing, do not read data.
40029
 *
40030
 * Flags not currently supported:
40031
 *    PKCS7_NOCERTS  - Do not include the signer cert in the output bundle.
40032
 *    PKCS7_PARTIAL  - Allow for PKCS7_sign() to be only partially set up,
40033
 *                     then signers etc to be added separately before
40034
 *                     calling PKCS7_final().
40035
 *
40036
 * Returns valid PKCS7 structure pointer, or NULL if an error occurred.
40037
 */
40038
PKCS7* wolfSSL_PKCS7_sign(WOLFSSL_X509* signer, WOLFSSL_EVP_PKEY* pkey,
40039
        WOLFSSL_STACK* certs, WOLFSSL_BIO* in, int flags)
40040
{
40041
    int err = 0;
40042
    WOLFSSL_PKCS7* p7 = NULL;
40043
    WOLFSSL_STACK* cert = certs;
40044
40045
    WOLFSSL_ENTER("wolfSSL_PKCS7_sign");
40046
40047
    if (flags & PKCS7_NOCERTS) {
40048
        WOLFSSL_MSG("PKCS7_NOCERTS flag not yet supported");
40049
        err = 1;
40050
    }
40051
40052
    if (flags & PKCS7_PARTIAL) {
40053
        WOLFSSL_MSG("PKCS7_PARTIAL flag not yet supported");
40054
        err = 1;
40055
    }
40056
40057
    if ((err == 0) && (signer == NULL || signer->derCert == NULL ||
40058
                       signer->derCert->length == 0)) {
40059
        WOLFSSL_MSG("Bad function arg, signer is NULL or incomplete");
40060
        err = 1;
40061
    }
40062
40063
    if ((err == 0) && (pkey == NULL || pkey->pkey.ptr == NULL ||
40064
                       pkey->pkey_sz <= 0)) {
40065
        WOLFSSL_MSG("Bad function arg, pkey is NULL or incomplete");
40066
        err = 1;
40067
    }
40068
40069
    if ((err == 0) && (in == NULL) && !(flags & PKCS7_STREAM)) {
40070
        WOLFSSL_MSG("input data required unless PKCS7_STREAM used");
40071
        err = 1;
40072
    }
40073
40074
    if ((err == 0) && ((p7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)) {
40075
        WOLFSSL_MSG("Error allocating new WOLFSSL_PKCS7");
40076
        err = 1;
40077
    }
40078
40079
    /* load signer certificate */
40080
    if (err == 0) {
40081
        if (wc_PKCS7_InitWithCert(&p7->pkcs7, signer->derCert->buffer,
40082
                                  signer->derCert->length) != 0) {
40083
            WOLFSSL_MSG("Failed to load signer certificate");
40084
            err = 1;
40085
        }
40086
    }
40087
40088
    /* set signer private key, data types, defaults */
40089
    if (err == 0) {
40090
        p7->pkcs7.privateKey = (byte*)pkey->pkey.ptr;
40091
        p7->pkcs7.privateKeySz = pkey->pkey_sz;
40092
        p7->pkcs7.contentOID = DATA;  /* inner content default is DATA */
40093
        p7->pkcs7.hashOID = SHA256h;  /* default to SHA-256 hash type */
40094
        p7->type = SIGNED_DATA;       /* PKCS7_final switches on type */
40095
    }
40096
40097
    /* add additional chain certs if provided */
40098
    while (cert && (err == 0)) {
40099
        if (cert->data.x509 != NULL && cert->data.x509->derCert != NULL) {
40100
            if (wc_PKCS7_AddCertificate(&p7->pkcs7,
40101
                                cert->data.x509->derCert->buffer,
40102
                                cert->data.x509->derCert->length) != 0) {
40103
                WOLFSSL_MSG("Error in wc_PKCS7_AddCertificate");
40104
                err = 1;
40105
            }
40106
        }
40107
        cert = cert->next;
40108
    }
40109
40110
    if ((err == 0) && (flags & PKCS7_DETACHED)) {
40111
        if (wc_PKCS7_SetDetached(&p7->pkcs7, 1) != 0) {
40112
            WOLFSSL_MSG("Failed to set signature detached");
40113
            err = 1;
40114
        }
40115
    }
40116
40117
    if ((err == 0) && (flags & PKCS7_STREAM)) {
40118
        /* if streaming, return before finalizing */
40119
        return (PKCS7*)p7;
40120
    }
40121
40122
    if ((err == 0) && (wolfSSL_PKCS7_final((PKCS7*)p7, in, flags) != 1)) {
40123
        WOLFSSL_MSG("Error calling wolfSSL_PKCS7_final");
40124
        err = 1;
40125
    }
40126
40127
    if ((err != 0) && (p7 != NULL)) {
40128
        wolfSSL_PKCS7_free((PKCS7*)p7);
40129
        p7 = NULL;
40130
    }
40131
40132
    return (PKCS7*)p7;
40133
}
40134
40135
#ifdef HAVE_SMIME
40136
40137
#ifndef MAX_MIME_LINE_LEN
40138
    #define MAX_MIME_LINE_LEN 1024
40139
#endif
40140
40141
/**
40142
 * Copy input BIO to output BIO, but convert all line endings to CRLF (\r\n),
40143
 * used by PKCS7_final().
40144
 *
40145
 * in  - input WOLFSSL_BIO to be converted
40146
 * out - output WOLFSSL_BIO to hold copy of in, with line endings adjusted
40147
 *
40148
 * Return 0 on success, negative on error
40149
 */
40150
static int wolfSSL_BIO_to_MIME_crlf(WOLFSSL_BIO* in, WOLFSSL_BIO* out)
40151
{
40152
    int ret = 0;
40153
    int lineLen = 0;
40154
    word32 canonLineLen = 0;
40155
    char* canonLine = NULL;
40156
#ifdef WOLFSSL_SMALL_STACK
40157
    char* line = NULL;
40158
#else
40159
    char line[MAX_MIME_LINE_LEN];
40160
#endif
40161
40162
    if (in == NULL || out == NULL) {
40163
        return BAD_FUNC_ARG;
40164
    }
40165
40166
#ifdef WOLFSSL_SMALL_STACK
40167
    line = (char*)XMALLOC(MAX_MIME_LINE_LEN, in->heap,
40168
                          DYNAMIC_TYPE_TMP_BUFFER);
40169
    if (line == NULL) {
40170
        return MEMORY_E;
40171
    }
40172
#endif
40173
    XMEMSET(line, 0, MAX_MIME_LINE_LEN);
40174
40175
    while ((lineLen = wolfSSL_BIO_gets(in, line, (int)sizeof(line))) > 0) {
40176
40177
        if (line[lineLen - 1] == '\r' || line[lineLen - 1] == '\n') {
40178
            canonLineLen = (word32)lineLen;
40179
            if ((canonLine = wc_MIME_single_canonicalize(
40180
                                line, &canonLineLen)) == NULL) {
40181
                ret = -1;
40182
                break;
40183
            }
40184
40185
            /* remove trailing null */
40186
            if (canonLine[canonLineLen] == '\0') {
40187
                canonLineLen--;
40188
            }
40189
40190
            if (wolfSSL_BIO_write(out, canonLine, (int)canonLineLen) < 0) {
40191
                ret = -1;
40192
                break;
40193
            }
40194
            XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
40195
            canonLine = NULL;
40196
        }
40197
        else {
40198
            /* no line ending in current line, write direct to out */
40199
            if (wolfSSL_BIO_write(out, line, lineLen) < 0) {
40200
                ret = -1;
40201
                break;
40202
            }
40203
        }
40204
    }
40205
40206
    if (canonLine != NULL) {
40207
        XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
40208
    }
40209
#ifdef WOLFSSL_SMALL_STACK
40210
    XFREE(line, in->heap, DYNAMIC_TYPE_TMP_BUFFER);
40211
#endif
40212
40213
    return ret;
40214
}
40215
40216
#endif /* HAVE_SMIME */
40217
40218
/* Used by both PKCS7_final() and PKCS7_verify() */
40219
static const char contTypeText[] = "Content-Type: text/plain\r\n\r\n";
40220
40221
/**
40222
 * Finalize PKCS7 structure, currently supports signedData only.
40223
 *
40224
 * Does not generate final bundle (ie: signedData), but finalizes
40225
 * the PKCS7 structure in preparation for a output function to be called next.
40226
 *
40227
 * pkcs7 - initialized PKCS7 structure, populated with signer, etc
40228
 * in    - input data
40229
 * flags - flags to control PKCS7 behavior. Other flags except those noted
40230
 *         below are ignored:
40231
 *
40232
 *    PKCS7_BINARY - Do not translate input data to MIME canonical
40233
 *                   format (\r\n line endings), thus preventing corruption of
40234
 *                   binary content.
40235
 *    PKCS7_TEXT   - Prepend MIME headers for text/plain to content.
40236
 *
40237
 * Returns 1 on success, 0 on error
40238
 */
40239
int wolfSSL_PKCS7_final(PKCS7* pkcs7, WOLFSSL_BIO* in, int flags)
40240
{
40241
    int ret = 1;
40242
    int memSz = 0;
40243
    unsigned char* mem = NULL;
40244
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
40245
    WOLFSSL_BIO* data = NULL;
40246
40247
    WOLFSSL_ENTER("wolfSSL_PKCS7_final");
40248
40249
    if (p7 == NULL || in == NULL) {
40250
        WOLFSSL_MSG("Bad input args to PKCS7_final");
40251
        ret = 0;
40252
    }
40253
40254
    if (ret == 1) {
40255
        if ((data = wolfSSL_BIO_new(wolfSSL_BIO_s_mem())) == NULL) {
40256
            WOLFSSL_MSG("Error in wolfSSL_BIO_new");
40257
            ret = 0;
40258
        }
40259
    }
40260
40261
    /* prepend Content-Type header if PKCS7_TEXT */
40262
    if ((ret == 1) && (flags & PKCS7_TEXT)) {
40263
        if (wolfSSL_BIO_write(data, contTypeText,
40264
                              (int)XSTR_SIZEOF(contTypeText)) < 0) {
40265
            WOLFSSL_MSG("Error prepending Content-Type header");
40266
            ret = 0;
40267
        }
40268
    }
40269
40270
    /* convert line endings to CRLF if !PKCS7_BINARY */
40271
    if (ret == 1) {
40272
        if (flags & PKCS7_BINARY) {
40273
40274
            /* no CRLF conversion, direct copy content */
40275
            if ((memSz = wolfSSL_BIO_get_len(in)) <= 0) {
40276
                ret = 0;
40277
            }
40278
            if (ret == 1) {
40279
                mem = (unsigned char*)XMALLOC(memSz, in->heap,
40280
                                              DYNAMIC_TYPE_TMP_BUFFER);
40281
                if (mem == NULL) {
40282
                    WOLFSSL_MSG("Failed to allocate memory for input data");
40283
                    ret = 0;
40284
                }
40285
            }
40286
40287
            if (ret == 1) {
40288
                if (wolfSSL_BIO_read(in, mem, memSz) != memSz) {
40289
                    WOLFSSL_MSG("Error reading from input BIO");
40290
                    ret = 0;
40291
                }
40292
                else if (wolfSSL_BIO_write(data, mem, memSz) < 0) {
40293
                    ret = 0;
40294
                }
40295
            }
40296
40297
            if (mem != NULL) {
40298
                XFREE(mem, in->heap, DYNAMIC_TYPE_TMP_BUFFER);
40299
            }
40300
        }
40301
        else {
40302
    #ifdef HAVE_SMIME
40303
            /* convert content line endings to CRLF */
40304
            if (wolfSSL_BIO_to_MIME_crlf(in, data) != 0) {
40305
                WOLFSSL_MSG("Error converting line endings to CRLF");
40306
                ret = 0;
40307
            }
40308
            else {
40309
                p7->pkcs7.contentCRLF = 1;
40310
            }
40311
    #else
40312
            WOLFSSL_MSG("Without PKCS7_BINARY requires wolfSSL to be built "
40313
                        "with HAVE_SMIME");
40314
            ret = 0;
40315
    #endif
40316
        }
40317
    }
40318
40319
    if ((ret == 1) && ((memSz = wolfSSL_BIO_get_mem_data(data, &mem)) < 0)) {
40320
        WOLFSSL_MSG("Error in wolfSSL_BIO_get_mem_data");
40321
        ret = 0;
40322
    }
40323
40324
    if (ret == 1) {
40325
        if (p7->data != NULL) {
40326
            XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
40327
        }
40328
        p7->data = (byte*)XMALLOC(memSz, NULL, DYNAMIC_TYPE_PKCS7);
40329
        if (p7->data == NULL) {
40330
            ret = 0;
40331
        }
40332
        else {
40333
            XMEMCPY(p7->data, mem, memSz);
40334
            p7->len = memSz;
40335
        }
40336
    }
40337
40338
    if (ret == 1) {
40339
        p7->pkcs7.content = p7->data;
40340
        p7->pkcs7.contentSz = p7->len;
40341
    }
40342
40343
    if (data != NULL) {
40344
        wolfSSL_BIO_free(data);
40345
    }
40346
40347
    return ret;
40348
}
40349
40350
int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs,
40351
        WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags)
40352
{
40353
    int i, ret = 0;
40354
    unsigned char* mem = NULL;
40355
    int memSz = 0;
40356
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
40357
    int contTypeLen;
40358
    WOLFSSL_X509* signer = NULL;
40359
    WOLFSSL_STACK* signers = NULL;
40360
40361
    WOLFSSL_ENTER("wolfSSL_PKCS7_verify");
40362
40363
    if (pkcs7 == NULL)
40364
        return WOLFSSL_FAILURE;
40365
40366
    if (in != NULL) {
40367
        if ((memSz = wolfSSL_BIO_get_mem_data(in, &mem)) < 0)
40368
            return WOLFSSL_FAILURE;
40369
40370
        p7->pkcs7.content = mem;
40371
        p7->pkcs7.contentSz = memSz;
40372
    }
40373
40374
    /* certs is the list of certificates to find the cert with issuer/serial. */
40375
    (void)certs;
40376
    /* store is the certificate store to use to verify signer certificate
40377
     * associated with the signers.
40378
     */
40379
    (void)store;
40380
40381
    ret = wc_PKCS7_VerifySignedData(&p7->pkcs7, p7->data, p7->len);
40382
    if (ret != 0)
40383
        return WOLFSSL_FAILURE;
40384
40385
    if ((flags & PKCS7_NOVERIFY) != PKCS7_NOVERIFY) {
40386
        /* Verify signer certificates */
40387
        if (store == NULL || store->cm == NULL) {
40388
            WOLFSSL_MSG("No store or store certs, but PKCS7_NOVERIFY not set");
40389
            return WOLFSSL_FAILURE;
40390
        }
40391
40392
        signers = wolfSSL_PKCS7_get0_signers(pkcs7, certs, flags);
40393
        if (signers == NULL) {
40394
            WOLFSSL_MSG("No signers found to verify");
40395
            return WOLFSSL_FAILURE;
40396
        }
40397
        for (i = 0; i < wolfSSL_sk_X509_num(signers); i++) {
40398
            signer = wolfSSL_sk_X509_value(signers, i);
40399
40400
            if (wolfSSL_CertManagerVerifyBuffer(store->cm,
40401
                        signer->derCert->buffer,
40402
                        signer->derCert->length,
40403
                        WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
40404
                WOLFSSL_MSG("Failed to verify signer certificate");
40405
                wolfSSL_sk_X509_pop_free(signers, NULL);
40406
                return WOLFSSL_FAILURE;
40407
            }
40408
        }
40409
        wolfSSL_sk_X509_pop_free(signers, NULL);
40410
    }
40411
40412
    if (flags & PKCS7_TEXT) {
40413
        /* strip MIME header for text/plain, otherwise error */
40414
        contTypeLen = XSTR_SIZEOF(contTypeText);
40415
        if ((p7->pkcs7.contentSz < (word32)contTypeLen) ||
40416
            (XMEMCMP(p7->pkcs7.content, contTypeText, contTypeLen) != 0)) {
40417
            WOLFSSL_MSG("Error PKCS7 Content-Type not found with PKCS7_TEXT");
40418
            return WOLFSSL_FAILURE;
40419
        }
40420
        p7->pkcs7.content += contTypeLen;
40421
        p7->pkcs7.contentSz -= contTypeLen;
40422
    }
40423
40424
    if (out != NULL) {
40425
        wolfSSL_BIO_write(out, p7->pkcs7.content, p7->pkcs7.contentSz);
40426
    }
40427
40428
    WOLFSSL_LEAVE("wolfSSL_PKCS7_verify", WOLFSSL_SUCCESS);
40429
40430
    return WOLFSSL_SUCCESS;
40431
}
40432
40433
/**
40434
 * This API was added as a helper function for libest. It
40435
 * encodes a stack of certificates to pkcs7 format.
40436
 * @param pkcs7 PKCS7 parameter object
40437
 * @param certs WOLFSSL_STACK_OF(WOLFSSL_X509)*
40438
 * @param out   Output bio
40439
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
40440
 */
40441
int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs,
40442
        WOLFSSL_BIO* out)
40443
{
40444
    int ret;
40445
    WOLFSSL_PKCS7* p7;
40446
    WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs");
40447
40448
    if (!pkcs7 || !certs || !out) {
40449
        WOLFSSL_MSG("Bad parameter");
40450
        return WOLFSSL_FAILURE;
40451
    }
40452
40453
    p7 = (WOLFSSL_PKCS7*)pkcs7;
40454
40455
    /* take ownership of certs */
40456
    p7->certs = certs;
40457
40458
    if (pkcs7->certList) {
40459
        WOLFSSL_MSG("wolfSSL_PKCS7_encode_certs called multiple times on same "
40460
                    "struct");
40461
        return WOLFSSL_FAILURE;
40462
    }
40463
40464
    if (certs) {
40465
        /* Save some of the values */
40466
        int hashOID = pkcs7->hashOID;
40467
        byte version = pkcs7->version;
40468
40469
        if (!certs->data.x509 || !certs->data.x509->derCert) {
40470
            WOLFSSL_MSG("Missing cert");
40471
            return WOLFSSL_FAILURE;
40472
        }
40473
40474
        if (wc_PKCS7_InitWithCert(pkcs7, certs->data.x509->derCert->buffer,
40475
                                      certs->data.x509->derCert->length) != 0) {
40476
            WOLFSSL_MSG("wc_PKCS7_InitWithCert error");
40477
            return WOLFSSL_FAILURE;
40478
        }
40479
        certs = certs->next;
40480
40481
        pkcs7->hashOID = hashOID;
40482
        pkcs7->version = version;
40483
    }
40484
40485
    /* Add the certs to the PKCS7 struct */
40486
    while (certs) {
40487
        if (!certs->data.x509 || !certs->data.x509->derCert) {
40488
            WOLFSSL_MSG("Missing cert");
40489
            return WOLFSSL_FAILURE;
40490
        }
40491
        if (wc_PKCS7_AddCertificate(pkcs7, certs->data.x509->derCert->buffer,
40492
                                      certs->data.x509->derCert->length) != 0) {
40493
            WOLFSSL_MSG("wc_PKCS7_AddCertificate error");
40494
            return WOLFSSL_FAILURE;
40495
        }
40496
        certs = certs->next;
40497
    }
40498
40499
    if (wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID) != 0) {
40500
        WOLFSSL_MSG("wc_PKCS7_SetSignerIdentifierType error");
40501
        return WOLFSSL_FAILURE;
40502
    }
40503
40504
    ret = wolfSSL_i2d_PKCS7_bio(out, pkcs7);
40505
40506
    return ret;
40507
}
40508
40509
/******************************************************************************
40510
* wolfSSL_PEM_write_bio_PKCS7 - writes the PKCS7 data to BIO
40511
*
40512
* RETURNS:
40513
* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
40514
*/
40515
int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7)
40516
{
40517
#ifdef WOLFSSL_SMALL_STACK
40518
    byte* outputHead;
40519
    byte* outputFoot;
40520
#else
40521
    byte outputHead[2048];
40522
    byte outputFoot[2048];
40523
#endif
40524
    word32 outputHeadSz = 2048;
40525
    word32 outputFootSz = 2048;
40526
    word32 outputSz = 0;
40527
    byte*  output = NULL;
40528
    byte*  pem = NULL;
40529
    int    pemSz = -1;
40530
    enum wc_HashType hashType;
40531
    byte hashBuf[WC_MAX_DIGEST_SIZE];
40532
    word32 hashSz = -1;
40533
40534
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PKCS7()");
40535
40536
    if (bio == NULL || p7 == NULL)
40537
        return WOLFSSL_FAILURE;
40538
40539
#ifdef WOLFSSL_SMALL_STACK
40540
    outputHead = (byte*)XMALLOC(outputHeadSz, bio->heap,
40541
        DYNAMIC_TYPE_TMP_BUFFER);
40542
    if (outputHead == NULL)
40543
        return MEMORY_E;
40544
40545
    outputFoot = (byte*)XMALLOC(outputFootSz, bio->heap,
40546
        DYNAMIC_TYPE_TMP_BUFFER);
40547
    if (outputFoot == NULL)
40548
        goto error;
40549
40550
#endif
40551
40552
    XMEMSET(hashBuf, 0, WC_MAX_DIGEST_SIZE);
40553
    XMEMSET(outputHead, 0, outputHeadSz);
40554
    XMEMSET(outputFoot, 0, outputFootSz);
40555
40556
    hashType = wc_OidGetHash(p7->hashOID);
40557
    hashSz = wc_HashGetDigestSize(hashType);
40558
    if (hashSz > WC_MAX_DIGEST_SIZE)
40559
        return WOLFSSL_FAILURE;
40560
40561
    /* only SIGNED_DATA is supported */
40562
    switch (p7->contentOID) {
40563
        case SIGNED_DATA:
40564
            break;
40565
        default:
40566
            WOLFSSL_MSG("Unknown PKCS#7 Type");
40567
            return WOLFSSL_FAILURE;
40568
    };
40569
40570
    if ((wc_PKCS7_EncodeSignedData_ex(p7, hashBuf, hashSz,
40571
        outputHead, &outputHeadSz, outputFoot, &outputFootSz)) != 0)
40572
        return WOLFSSL_FAILURE;
40573
40574
    outputSz = outputHeadSz + p7->contentSz + outputFootSz;
40575
    output = (byte*)XMALLOC(outputSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40576
40577
    if (!output)
40578
         return WOLFSSL_FAILURE;
40579
40580
    XMEMSET(output, 0, outputSz);
40581
    outputSz = 0;
40582
    XMEMCPY(&output[outputSz], outputHead, outputHeadSz);
40583
    outputSz += outputHeadSz;
40584
    XMEMCPY(&output[outputSz], p7->content, p7->contentSz);
40585
    outputSz += p7->contentSz;
40586
    XMEMCPY(&output[outputSz], outputFoot, outputFootSz);
40587
    outputSz += outputFootSz;
40588
40589
    /* get PEM size */
40590
    pemSz = wc_DerToPemEx(output, outputSz, NULL, 0, NULL, CERT_TYPE);
40591
    if (pemSz < 0)
40592
        goto error;
40593
40594
    pemSz++; /* for '\0'*/
40595
40596
    /* create PEM buffer and convert from DER to PEM*/
40597
    if ((pem = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER))
40598
                                                                        == NULL)
40599
        goto error;
40600
40601
    XMEMSET(pem, 0, pemSz);
40602
40603
    if (wc_DerToPemEx(output, outputSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
40604
        goto error;
40605
    }
40606
    if ((wolfSSL_BIO_write(bio, pem, pemSz) == pemSz)) {
40607
        XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40608
        XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40609
#ifdef WOLFSSL_SMALL_STACK
40610
        XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40611
        XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40612
#endif
40613
        return WOLFSSL_SUCCESS;
40614
    }
40615
40616
error:
40617
#ifdef WOLFSSL_SMALL_STACK
40618
    if (outputHead) {
40619
        XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40620
    }
40621
    if (outputFoot) {
40622
        XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40623
    }
40624
#endif
40625
    if (output) {
40626
        XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40627
    }
40628
    if (pem) {
40629
        XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40630
    }
40631
    return WOLFSSL_FAILURE;
40632
}
40633
40634
#ifdef HAVE_SMIME
40635
/*****************************************************************************
40636
* wolfSSL_SMIME_read_PKCS7 - Reads the given S/MIME message and parses it into
40637
* a PKCS7 object. In case of a multipart message, stores the signed data in
40638
* bcont.
40639
*
40640
* RETURNS:
40641
* returns pointer to a PKCS7 structure on success, otherwise returns NULL
40642
*/
40643
WOLFSSL_API PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
40644
        WOLFSSL_BIO** bcont)
40645
{
40646
    MimeHdr* allHdrs = NULL;
40647
    MimeHdr* curHdr = NULL;
40648
    MimeParam* curParam = NULL;
40649
    int inLen = 0;
40650
    byte* bcontMem = NULL;
40651
    int bcontMemSz = 0;
40652
    int sectionLen = 0;
40653
    int ret = -1;
40654
    char* section = NULL;
40655
    char* canonLine = NULL;
40656
    char* canonSection = NULL;
40657
    PKCS7* pkcs7 = NULL;
40658
    word32 outLen = 0;
40659
    word32 canonLineLen = 0;
40660
    byte* out = NULL;
40661
    byte* outHead = NULL;
40662
40663
    int canonPos = 0;
40664
    int lineLen = 0;
40665
    int remainLen = 0;
40666
    byte isEnd = 0;
40667
    size_t canonSize = 0;
40668
    size_t boundLen = 0;
40669
    char* boundary = NULL;
40670
40671
    static const char kContType[] = "Content-Type";
40672
    static const char kCTE[] = "Content-Transfer-Encoding";
40673
    static const char kMultSigned[] = "multipart/signed";
40674
    static const char kAppPkcsSign[] = "application/pkcs7-signature";
40675
    static const char kAppXPkcsSign[] = "application/x-pkcs7-signature";
40676
    static const char kAppPkcs7Mime[] = "application/pkcs7-mime";
40677
    static const char kAppXPkcs7Mime[] = "application/x-pkcs7-mime";
40678
40679
    WOLFSSL_ENTER("wolfSSL_SMIME_read_PKCS7");
40680
40681
    if (in == NULL || bcont == NULL) {
40682
        goto error;
40683
    }
40684
    inLen = wolfSSL_BIO_get_len(in);
40685
    if (inLen <= 0) {
40686
        goto error;
40687
    }
40688
    remainLen = wolfSSL_BIO_get_len(in);
40689
    if (remainLen <= 0) {
40690
        goto error;
40691
    }
40692
40693
    section = (char*)XMALLOC(remainLen+1, NULL, DYNAMIC_TYPE_PKCS7);
40694
    if (section == NULL) {
40695
        goto error;
40696
    }
40697
    lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40698
    if (lineLen <= 0) {
40699
        goto error;
40700
    }
40701
    while (isEnd == 0 && remainLen > 0) {
40702
        sectionLen += lineLen;
40703
        remainLen -= lineLen;
40704
        lineLen = wolfSSL_BIO_gets(in, &section[sectionLen], remainLen);
40705
        if (lineLen <= 0) {
40706
            goto error;
40707
        }
40708
        /* Line with just newline signals end of headers. */
40709
        if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
40710
                                     "\r\n", 2)) ||
40711
            (lineLen==1 && (section[sectionLen] == '\r' ||
40712
                            section[sectionLen] == '\n'))) {
40713
            isEnd = 1;
40714
        }
40715
    }
40716
    section[sectionLen] = '\0';
40717
    ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
40718
    if (ret < 0) {
40719
        WOLFSSL_MSG("Parsing MIME headers failed.");
40720
        goto error;
40721
    }
40722
    isEnd = 0;
40723
    section[0] = '\0';
40724
    sectionLen = 0;
40725
40726
    curHdr = wc_MIME_find_header_name(kContType, allHdrs);
40727
    if (curHdr && !XSTRNCMP(curHdr->body, kMultSigned,
40728
                            XSTR_SIZEOF(kMultSigned))) {
40729
        curParam = wc_MIME_find_param_attr("protocol", curHdr->params);
40730
        if (curParam && (!XSTRNCMP(curParam->value, kAppPkcsSign,
40731
                                   XSTR_SIZEOF(kAppPkcsSign)) ||
40732
                         !XSTRNCMP(curParam->value, kAppXPkcsSign,
40733
                                   XSTR_SIZEOF(kAppXPkcsSign)))) {
40734
            curParam = wc_MIME_find_param_attr("boundary", curHdr->params);
40735
            if (curParam == NULL) {
40736
                goto error;
40737
            }
40738
40739
            boundLen = XSTRLEN(curParam->value) + 2;
40740
            boundary = (char*)XMALLOC(boundLen+1, NULL, DYNAMIC_TYPE_PKCS7);
40741
            if (boundary == NULL) {
40742
                goto error;
40743
            }
40744
            XMEMSET(boundary, 0, (word32)(boundLen+1));
40745
            boundary[0] = boundary[1] = '-';
40746
            XSTRNCPY(&boundary[2], curParam->value, boundLen-2);
40747
40748
            /* Parse up to first boundary, ignore everything here. */
40749
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40750
            if (lineLen <= 0) {
40751
                goto error;
40752
            }
40753
            while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
40754
                   remainLen > 0) {
40755
                sectionLen += lineLen;
40756
                remainLen -= lineLen;
40757
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40758
                                           remainLen);
40759
                if (lineLen <= 0) {
40760
                    goto error;
40761
                }
40762
            }
40763
40764
            section[0] = '\0';
40765
            sectionLen = 0;
40766
            canonSize = remainLen + 1;
40767
            canonSection = (char*)XMALLOC(canonSize, NULL,
40768
                                          DYNAMIC_TYPE_PKCS7);
40769
            if (canonSection == NULL) {
40770
                goto error;
40771
            }
40772
40773
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40774
            while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
40775
                            remainLen > 0) {
40776
                canonLineLen = lineLen;
40777
                canonLine = wc_MIME_single_canonicalize(&section[sectionLen],
40778
                                                        &canonLineLen);
40779
                if (canonLine == NULL) {
40780
                    goto error;
40781
                }
40782
                /* If line endings were added, the initial length may be
40783
                 * exceeded. */
40784
                if ((canonPos + canonLineLen) >= canonSize) {
40785
                    canonSize = canonPos + canonLineLen;
40786
                    canonSection = (char*)XREALLOC(canonSection, canonSize,
40787
                                                   NULL, DYNAMIC_TYPE_PKCS7);
40788
                    if (canonSection == NULL) {
40789
                        goto error;
40790
                    }
40791
                }
40792
                XMEMCPY(&canonSection[canonPos], canonLine,
40793
                        (int)canonLineLen - 1);
40794
                canonPos += canonLineLen - 1;
40795
                XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
40796
                canonLine = NULL;
40797
40798
                sectionLen += lineLen;
40799
                remainLen -= lineLen;
40800
40801
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40802
                                           remainLen);
40803
                if (lineLen <= 0) {
40804
                    goto error;
40805
                }
40806
            }
40807
40808
            if (canonPos > 0) {
40809
                canonPos--;
40810
            }
40811
40812
            /* Strip the final trailing newline.  Support \r, \n or \r\n. */
40813
            if (canonSection[canonPos] == '\n') {
40814
                if (canonPos > 0) {
40815
                    canonPos--;
40816
                }
40817
            }
40818
40819
            if (canonSection[canonPos] == '\r') {
40820
                if (canonPos > 0) {
40821
                    canonPos--;
40822
                }
40823
            }
40824
40825
            canonSection[canonPos+1] = '\0';
40826
40827
            *bcont = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
40828
            ret = wolfSSL_BIO_write(*bcont, canonSection,
40829
                                    canonPos + 1);
40830
            if (ret != (canonPos+1)) {
40831
                goto error;
40832
            }
40833
            if ((bcontMemSz = wolfSSL_BIO_get_mem_data(*bcont, &bcontMem))
40834
                                                                          < 0) {
40835
                goto error;
40836
            }
40837
            XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
40838
            canonSection = NULL;
40839
40840
            wc_MIME_free_hdrs(allHdrs);
40841
            allHdrs = NULL;
40842
            section[0] = '\0';
40843
            sectionLen = 0;
40844
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40845
            if (lineLen <= 0) {
40846
                goto error;
40847
            }
40848
            while (isEnd == 0 && remainLen > 0) {
40849
                sectionLen += lineLen;
40850
                remainLen -= lineLen;
40851
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40852
                                           remainLen);
40853
                if (lineLen <= 0) {
40854
                    goto error;
40855
                }
40856
                /* Line with just newline signals end of headers. */
40857
                if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
40858
                                             "\r\n", 2)) ||
40859
                    (lineLen==1 && (section[sectionLen] == '\r' ||
40860
                                    section[sectionLen] == '\n'))) {
40861
                    isEnd = 1;
40862
                }
40863
            }
40864
            section[sectionLen] = '\0';
40865
            ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
40866
            if (ret < 0) {
40867
                WOLFSSL_MSG("Parsing MIME headers failed.");
40868
                goto error;
40869
            }
40870
            curHdr = wc_MIME_find_header_name(kContType, allHdrs);
40871
            if (curHdr == NULL || (XSTRNCMP(curHdr->body, kAppPkcsSign,
40872
                                   XSTR_SIZEOF(kAppPkcsSign)) &&
40873
                                   XSTRNCMP(curHdr->body, kAppXPkcsSign,
40874
                                   XSTR_SIZEOF(kAppXPkcsSign)))) {
40875
                WOLFSSL_MSG("S/MIME headers not found inside "
40876
                            "multipart message.\n");
40877
                goto error;
40878
            }
40879
40880
            section[0] = '\0';
40881
            sectionLen = 0;
40882
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40883
            while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
40884
                   remainLen > 0) {
40885
                sectionLen += lineLen;
40886
                remainLen -= lineLen;
40887
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40888
                                           remainLen);
40889
                if (lineLen <= 0) {
40890
                    goto error;
40891
                }
40892
            }
40893
40894
            XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
40895
            boundary = NULL;
40896
        }
40897
    }
40898
    else if (curHdr && (!XSTRNCMP(curHdr->body, kAppPkcs7Mime,
40899
                                  XSTR_SIZEOF(kAppPkcs7Mime)) ||
40900
                        !XSTRNCMP(curHdr->body, kAppXPkcs7Mime,
40901
                                  XSTR_SIZEOF(kAppXPkcs7Mime)))) {
40902
        sectionLen = wolfSSL_BIO_get_len(in);
40903
        if (sectionLen <= 0) {
40904
            goto error;
40905
        }
40906
        ret = wolfSSL_BIO_read(in, section, sectionLen);
40907
        if (ret < 0 || ret != sectionLen) {
40908
            WOLFSSL_MSG("Error reading input BIO.");
40909
            goto error;
40910
        }
40911
    }
40912
    else {
40913
        WOLFSSL_MSG("S/MIME headers not found.");
40914
        goto error;
40915
    }
40916
40917
    curHdr = wc_MIME_find_header_name(kCTE, allHdrs);
40918
    if (curHdr == NULL) {
40919
        WOLFSSL_MSG("Content-Transfer-Encoding header not found, "
40920
                    "assuming base64 encoding.");
40921
    }
40922
    else if (XSTRNCMP(curHdr->body, "base64", XSTRLEN("base64"))) {
40923
        WOLFSSL_MSG("S/MIME encodings other than base64 are not "
40924
                    "currently supported.\n");
40925
        goto error;
40926
    }
40927
40928
    if (section == NULL || sectionLen <= 0) {
40929
        goto error;
40930
    }
40931
    outLen = ((sectionLen*3+3)/4)+1;
40932
    out = (byte*)XMALLOC(outLen*sizeof(byte), NULL, DYNAMIC_TYPE_PKCS7);
40933
    outHead = out;
40934
    if (outHead == NULL) {
40935
        goto error;
40936
    }
40937
    /* Strip trailing newlines. */
40938
    while ((sectionLen > 0) &&
40939
           (section[sectionLen-1] == '\r' || section[sectionLen-1] == '\n')) {
40940
        sectionLen--;
40941
    }
40942
    section[sectionLen] = '\0';
40943
    ret = Base64_Decode((const byte*)section, sectionLen, out, &outLen);
40944
    if (ret < 0) {
40945
        WOLFSSL_MSG("Error base64 decoding S/MIME message.");
40946
        goto error;
40947
    }
40948
    pkcs7 = wolfSSL_d2i_PKCS7_ex(NULL, (const unsigned char**)&out, outLen,
40949
        bcontMem, bcontMemSz);
40950
40951
    wc_MIME_free_hdrs(allHdrs);
40952
    XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
40953
    XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
40954
40955
    return pkcs7;
40956
40957
error:
40958
    wc_MIME_free_hdrs(allHdrs);
40959
    XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
40960
    XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
40961
    XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
40962
    if (canonSection != NULL)
40963
        XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
40964
    if (bcont) {
40965
        wolfSSL_BIO_free(*bcont);
40966
        *bcont = NULL; /* reset 'bcount' pointer to NULL on failure */
40967
    }
40968
40969
    return NULL;
40970
}
40971
40972
/* Convert hash algo OID (from Hash_Sum in asn.h) to SMIME string equivalent.
40973
 * Returns hash algorithm string or "unknown" if not found */
40974
static const char* wolfSSL_SMIME_HashOIDToString(int hashOID)
40975
{
40976
    switch (hashOID) {
40977
        case MD5h:
40978
            return "md5";
40979
        case SHAh:
40980
            return "sha1";
40981
        case SHA224h:
40982
            return "sha-224";
40983
        case SHA256h:
40984
            return "sha-256";
40985
        case SHA384h:
40986
            return "sha-384";
40987
        case SHA512h:
40988
            return "sha-512";
40989
        case SHA3_224h:
40990
            return "sha3-224";
40991
        case SHA3_384h:
40992
            return "sha3-384";
40993
        case SHA3_512h:
40994
            return "sha3-512";
40995
        default:
40996
            break;
40997
    }
40998
40999
    return "unknown";
41000
}
41001
41002
/* Convert PKCS#7 type (from PKCS7_TYPES in pkcs7.h) to SMIME string.
41003
 * RFC2633 only defines signed-data, enveloped-data, certs-only.
41004
 * Returns string on success, NULL on unknown type. */
41005
static const char* wolfSSL_SMIME_PKCS7TypeToString(int type)
41006
{
41007
    switch (type) {
41008
        case SIGNED_DATA:
41009
            return "signed-data";
41010
        case ENVELOPED_DATA:
41011
            return "enveloped-data";
41012
        default:
41013
            break;
41014
    }
41015
41016
    return NULL;
41017
}
41018
41019
/**
41020
 * Convert PKCS7 structure to SMIME format, adding necessary headers.
41021
 *
41022
 * Handles generation of PKCS7 bundle (ie: signedData). PKCS7 structure
41023
 * should be set up beforehand with PKCS7_sign/final/etc. Output is always
41024
 * Base64 encoded.
41025
 *
41026
 * out   - output BIO for SMIME formatted data to be placed
41027
 * pkcs7 - input PKCS7 structure, initialized and set up
41028
 * in    - input content to be encoded into PKCS7
41029
 * flags - flags to control behavior of PKCS7 generation
41030
 *
41031
 * Returns 1 on success, 0 or negative on failure
41032
 */
41033
int wolfSSL_SMIME_write_PKCS7(WOLFSSL_BIO* out, PKCS7* pkcs7, WOLFSSL_BIO* in,
41034
                              int flags)
41035
{
41036
    int i;
41037
    int ret = 1;
41038
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
41039
    byte* p7out = NULL;
41040
    int len = 0;
41041
41042
    char boundary[33]; /* 32 chars + \0 */
41043
    byte* sigBase64 = NULL;
41044
    word32 sigBase64Len = 0;
41045
    const char* p7TypeString = NULL;
41046
41047
    static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
41048
41049
    if (out == NULL || p7 == NULL) {
41050
        WOLFSSL_MSG("Bad function arguments");
41051
        return 0;
41052
    }
41053
41054
    if (in != NULL && (p7->pkcs7.content == NULL || p7->pkcs7.contentSz == 0 ||
41055
                       p7->pkcs7.contentCRLF == 0)) {
41056
        /* store and adjust content line endings for CRLF if needed */
41057
        if (wolfSSL_PKCS7_final((PKCS7*)p7, in, flags) != 1) {
41058
            ret = 0;
41059
        }
41060
    }
41061
41062
    if (ret > 0) {
41063
        /* Generate signedData bundle, DER in output (dynamic) */
41064
        if ((len = wolfSSL_i2d_PKCS7((PKCS7*)p7, &p7out)) == WOLFSSL_FAILURE) {
41065
            WOLFSSL_MSG("Error in wolfSSL_i2d_PKCS7");
41066
            ret = 0;
41067
        }
41068
    }
41069
41070
    /* Base64 encode signedData bundle */
41071
    if (ret > 0) {
41072
        if (Base64_Encode(p7out, len, NULL, &sigBase64Len) != LENGTH_ONLY_E) {
41073
            ret = 0;
41074
        }
41075
        else {
41076
            sigBase64 = (byte*)XMALLOC(sigBase64Len, NULL,
41077
                                       DYNAMIC_TYPE_TMP_BUFFER);
41078
            if (sigBase64 == NULL) {
41079
                ret = 0;
41080
            }
41081
        }
41082
    }
41083
41084
    if (ret > 0) {
41085
        XMEMSET(sigBase64, 0, sigBase64Len);
41086
        if (Base64_Encode(p7out, len, sigBase64, &sigBase64Len) < 0) {
41087
            WOLFSSL_MSG("Error in Base64_Encode of signature");
41088
            ret = 0;
41089
        }
41090
    }
41091
41092
    /* build up SMIME message */
41093
    if (ret > 0) {
41094
        if (flags & PKCS7_DETACHED) {
41095
41096
            /* generate random boundary */
41097
            if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
41098
                WOLFSSL_MSG("No RNG to use");
41099
                ret = 0;
41100
            }
41101
41102
            /* no need to generate random byte for null terminator (size-1) */
41103
            if ((ret > 0) && (wc_RNG_GenerateBlock(&globalRNG, (byte*)boundary,
41104
                                  sizeof(boundary) - 1 ) != 0)) {
41105
                    WOLFSSL_MSG("Error in wc_RNG_GenerateBlock");
41106
                    ret = 0;
41107
            }
41108
41109
            if (ret > 0) {
41110
                for (i = 0; i < (int)sizeof(boundary) - 1; i++) {
41111
                    boundary[i] =
41112
                        alphanum[boundary[i] % XSTR_SIZEOF(alphanum)];
41113
                }
41114
                boundary[sizeof(boundary)-1] = 0;
41115
            }
41116
41117
            if (ret > 0) {
41118
                /* S/MIME header beginning */
41119
                ret = wolfSSL_BIO_printf(out,
41120
                        "MIME-Version: 1.0\n"
41121
                        "Content-Type: multipart/signed; "
41122
                        "protocol=\"application/x-pkcs7-signature\"; "
41123
                        "micalg=\"%s\"; "
41124
                        "boundary=\"----%s\"\n\n"
41125
                        "This is an S/MIME signed message\n\n"
41126
                        "------%s\n",
41127
                        wolfSSL_SMIME_HashOIDToString(p7->pkcs7.hashOID),
41128
                        boundary, boundary);
41129
            }
41130
41131
            if (ret > 0) {
41132
                /* S/MIME content */
41133
                ret = wolfSSL_BIO_write(out,
41134
                        p7->pkcs7.content, p7->pkcs7.contentSz);
41135
            }
41136
41137
            if (ret > 0) {
41138
                /* S/SMIME header end boundary */
41139
                ret = wolfSSL_BIO_printf(out,
41140
                        "\n------%s\n", boundary);
41141
            }
41142
41143
            if (ret > 0) {
41144
                /* Signature and header */
41145
                ret = wolfSSL_BIO_printf(out,
41146
                        "Content-Type: application/x-pkcs7-signature; "
41147
                        "name=\"smime.p7s\"\n"
41148
                        "Content-Transfer-Encoding: base64\n"
41149
                        "Content-Disposition: attachment; "
41150
                        "filename=\"smime.p7s\"\n\n"
41151
                        "%.*s\n" /* Base64 encoded signature */
41152
                        "------%s--\n\n",
41153
                        sigBase64Len, sigBase64,
41154
                        boundary);
41155
            }
41156
        }
41157
        else {
41158
            p7TypeString = wolfSSL_SMIME_PKCS7TypeToString(p7->type);
41159
            if (p7TypeString == NULL) {
41160
                WOLFSSL_MSG("Unsupported PKCS7 SMIME type");
41161
                ret = 0;
41162
            }
41163
41164
            if (ret > 0) {
41165
                /* not detached */
41166
                ret = wolfSSL_BIO_printf(out,
41167
                        "MIME-Version: 1.0\n"
41168
                        "Content-Disposition: attachment; "
41169
                        "filename=\"smime.p7m\"\n"
41170
                        "Content-Type: application/x-pkcs7-mime; "
41171
                        "smime-type=%s; name=\"smime.p7m\"\n"
41172
                        "Content-Transfer-Encoding: base64\n\n"
41173
                        "%.*s\n" /* signature */,
41174
                        p7TypeString, sigBase64Len, sigBase64);
41175
            }
41176
        }
41177
    }
41178
41179
    if (p7out != NULL) {
41180
        XFREE(p7out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41181
    }
41182
    if (sigBase64 != NULL) {
41183
        XFREE(sigBase64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
41184
    }
41185
41186
    if (ret > 0) {
41187
        return WOLFSSL_SUCCESS;
41188
    }
41189
41190
    return WOLFSSL_FAILURE;
41191
}
41192
41193
#endif /* HAVE_SMIME */
41194
#endif /* !NO_BIO */
41195
#endif /* OPENSSL_ALL */
41196
41197
#endif /* HAVE_PKCS7 */
41198
/*******************************************************************************
41199
 * END OF PKCS7 APIs
41200
 ******************************************************************************/
41201
41202
/*******************************************************************************
41203
 * START OF PKCS12 APIs
41204
 ******************************************************************************/
41205
#ifdef OPENSSL_EXTRA
41206
41207
/* no-op function. Was initially used for adding encryption algorithms available
41208
 * for PKCS12 */
41209
void wolfSSL_PKCS12_PBE_add(void)
41210
{
41211
    WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
41212
}
41213
41214
#if !defined(NO_FILESYSTEM)
41215
WOLFSSL_X509_PKCS12 *wolfSSL_d2i_PKCS12_fp(XFILE fp,
41216
        WOLFSSL_X509_PKCS12 **pkcs12)
41217
{
41218
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_fp");
41219
    return (WOLFSSL_X509_PKCS12 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)pkcs12,
41220
        PKCS12_TYPE);
41221
}
41222
#endif /* !NO_FILESYSTEM */
41223
41224
#endif /* OPENSSL_EXTRA */
41225
41226
#if defined(HAVE_PKCS12)
41227
41228
#ifdef OPENSSL_EXTRA
41229
41230
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
41231
41232
#ifndef NO_BIO
41233
WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
41234
{
41235
    WC_PKCS12* localPkcs12 = NULL;
41236
    unsigned char* mem = NULL;
41237
    long memSz;
41238
    int ret = -1;
41239
41240
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
41241
41242
    if (bio == NULL) {
41243
        WOLFSSL_MSG("Bad Function Argument bio is NULL");
41244
        return NULL;
41245
    }
41246
41247
    memSz = wolfSSL_BIO_get_len(bio);
41248
    if (memSz <= 0) {
41249
        return NULL;
41250
    }
41251
    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
41252
    if (mem == NULL) {
41253
        return NULL;
41254
    }
41255
41256
    if (mem != NULL) {
41257
        localPkcs12 = wc_PKCS12_new();
41258
        if (localPkcs12 == NULL) {
41259
            WOLFSSL_MSG("Memory error");
41260
        }
41261
    }
41262
41263
    if (mem != NULL && localPkcs12 != NULL) {
41264
        if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
41265
            ret = wc_d2i_PKCS12(mem, (word32)memSz, localPkcs12);
41266
            if (ret < 0) {
41267
                WOLFSSL_MSG("Failed to get PKCS12 sequence");
41268
            }
41269
        }
41270
        else {
41271
            WOLFSSL_MSG("Failed to get data from bio struct");
41272
        }
41273
    }
41274
41275
    /* cleanup */
41276
    if (mem != NULL)
41277
        XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
41278
    if (ret < 0 && localPkcs12 != NULL) {
41279
        wc_PKCS12_free(localPkcs12);
41280
        localPkcs12 = NULL;
41281
    }
41282
    if (pkcs12 != NULL)
41283
        *pkcs12 = localPkcs12;
41284
41285
    return localPkcs12;
41286
}
41287
41288
/* Converts the PKCS12 to DER format and outputs it into bio.
41289
 *
41290
 * bio is the structure to hold output DER
41291
 * pkcs12 structure to create DER from
41292
 *
41293
 * return 1 for success or 0 if an error occurs
41294
 */
41295
int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12)
41296
{
41297
    int ret = WOLFSSL_FAILURE;
41298
41299
    WOLFSSL_ENTER("wolfSSL_i2d_PKCS12_bio");
41300
41301
    if ((bio != NULL) && (pkcs12 != NULL)) {
41302
        word32 certSz = 0;
41303
        byte *certDer = NULL;
41304
41305
        certSz = wc_i2d_PKCS12(pkcs12, &certDer, NULL);
41306
        if ((certSz > 0) && (certDer != NULL)) {
41307
            if (wolfSSL_BIO_write(bio, certDer, certSz) == (int)certSz) {
41308
                ret = WOLFSSL_SUCCESS;
41309
            }
41310
        }
41311
41312
        if (certDer != NULL) {
41313
            XFREE(certDer, NULL, DYNAMIC_TYPE_PKCS);
41314
        }
41315
    }
41316
41317
    return ret;
41318
}
41319
#endif /* !NO_BIO */
41320
41321
/* Creates a new WC_PKCS12 structure
41322
 *
41323
 * pass  password to use
41324
 * name  friendlyName to use
41325
 * pkey  private key to go into PKCS12 bundle
41326
 * cert  certificate to go into PKCS12 bundle
41327
 * ca    extra certificates that can be added to bundle. Can be NULL
41328
 * keyNID  type of encryption to use on the key (-1 means no encryption)
41329
 * certNID type of encryption to use on the certificate
41330
 * itt     number of iterations with encryption
41331
 * macItt  number of iterations with mac creation
41332
 * keyType flag for signature and/or encryption key
41333
 *
41334
 * returns a pointer to a new WC_PKCS12 structure on success and NULL on fail
41335
 */
41336
WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, WOLFSSL_EVP_PKEY* pkey,
41337
        WOLFSSL_X509* cert, WOLF_STACK_OF(WOLFSSL_X509)* ca, int keyNID,
41338
        int certNID, int itt, int macItt, int keyType)
41339
{
41340
    WC_PKCS12* pkcs12;
41341
    WC_DerCertList* list = NULL;
41342
    word32 passSz;
41343
    byte* keyDer = NULL;
41344
    word32 keyDerSz;
41345
    byte* certDer;
41346
    int certDerSz;
41347
41348
    WOLFSSL_ENTER("wolfSSL_PKCS12_create()");
41349
41350
    if (pass == NULL || pkey == NULL || cert == NULL) {
41351
        WOLFSSL_LEAVE("wolfSSL_PKCS12_create()", BAD_FUNC_ARG);
41352
        return NULL;
41353
    }
41354
    passSz = (word32)XSTRLEN(pass);
41355
41356
    keyDer = (byte*)pkey->pkey.ptr;
41357
    keyDerSz = pkey->pkey_sz;
41358
41359
    certDer = (byte*)wolfSSL_X509_get_der(cert, &certDerSz);
41360
    if (certDer == NULL) {
41361
        return NULL;
41362
    }
41363
41364
    if (ca != NULL) {
41365
        WC_DerCertList* cur;
41366
        unsigned long numCerts = ca->num;
41367
        byte* curDer;
41368
        int   curDerSz = 0;
41369
        WOLFSSL_STACK* sk = ca;
41370
41371
        while (numCerts > 0 && sk != NULL) {
41372
            cur = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList), NULL,
41373
                    DYNAMIC_TYPE_PKCS);
41374
            if (cur == NULL) {
41375
                wc_FreeCertList(list, NULL);
41376
                return NULL;
41377
            }
41378
41379
            curDer = (byte*)wolfSSL_X509_get_der(sk->data.x509, &curDerSz);
41380
            if (curDer == NULL || curDerSz < 0) {
41381
                XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
41382
                wc_FreeCertList(list, NULL);
41383
                return NULL;
41384
            }
41385
41386
            cur->buffer = (byte*)XMALLOC(curDerSz, NULL, DYNAMIC_TYPE_PKCS);
41387
            if (cur->buffer == NULL) {
41388
                XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
41389
                wc_FreeCertList(list, NULL);
41390
                return NULL;
41391
            }
41392
            XMEMCPY(cur->buffer, curDer, curDerSz);
41393
            cur->bufferSz = curDerSz;
41394
            cur->next = list;
41395
            list = cur;
41396
41397
            sk = sk->next;
41398
            numCerts--;
41399
        }
41400
    }
41401
41402
    pkcs12 = wc_PKCS12_create(pass, passSz, name, keyDer, keyDerSz,
41403
            certDer, certDerSz, list, keyNID, certNID, itt, macItt,
41404
            keyType, NULL);
41405
41406
    if (ca != NULL) {
41407
        wc_FreeCertList(list, NULL);
41408
    }
41409
41410
    return pkcs12;
41411
}
41412
41413
41414
/* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure */
41415
int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
41416
          WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert,
41417
          WOLF_STACK_OF(WOLFSSL_X509)** ca)
41418
{
41419
    void* heap = NULL;
41420
    int ret;
41421
    byte* certData = NULL;
41422
    word32 certDataSz;
41423
    byte* pk = NULL;
41424
    word32 pkSz;
41425
    WC_DerCertList* certList = NULL;
41426
#ifdef WOLFSSL_SMALL_STACK
41427
    DecodedCert *DeCert;
41428
#else
41429
    DecodedCert DeCert[1];
41430
#endif
41431
41432
    WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
41433
41434
    /* make sure we init return args */
41435
    if (pkey) *pkey = NULL;
41436
    if (cert) *cert = NULL;
41437
    if (ca)   *ca = NULL;
41438
41439
    if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
41440
        WOLFSSL_MSG("Bad argument value");
41441
        return WOLFSSL_FAILURE;
41442
    }
41443
41444
    heap  = wc_PKCS12_GetHeap(pkcs12);
41445
41446
    if (ca == NULL) {
41447
        ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
41448
            NULL);
41449
    }
41450
    else {
41451
        ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
41452
            &certList);
41453
    }
41454
    if (ret < 0) {
41455
        WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
41456
        return WOLFSSL_FAILURE;
41457
    }
41458
41459
#ifdef WOLFSSL_SMALL_STACK
41460
    DeCert = (DecodedCert *)XMALLOC(sizeof(*DeCert), heap,
41461
                                    DYNAMIC_TYPE_DCERT);
41462
    if (DeCert == NULL) {
41463
        WOLFSSL_MSG("out of memory");
41464
        return WOLFSSL_FAILURE;
41465
    }
41466
#endif
41467
41468
    /* Decode cert and place in X509 stack struct */
41469
    if (certList != NULL) {
41470
        WC_DerCertList* current = certList;
41471
41472
        *ca = (WOLF_STACK_OF(WOLFSSL_X509)*)XMALLOC(
41473
            sizeof(WOLF_STACK_OF(WOLFSSL_X509)), heap, DYNAMIC_TYPE_X509);
41474
        if (*ca == NULL) {
41475
            if (pk != NULL) {
41476
                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
41477
            }
41478
            if (certData != NULL) {
41479
                XFREE(*cert, heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
41480
            }
41481
            /* Free up WC_DerCertList and move on */
41482
            while (current != NULL) {
41483
                WC_DerCertList* next = current->next;
41484
41485
                XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
41486
                XFREE(current, heap, DYNAMIC_TYPE_PKCS);
41487
                current = next;
41488
            }
41489
            ret = WOLFSSL_FAILURE;
41490
            goto out;
41491
        }
41492
        XMEMSET(*ca, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509)));
41493
41494
        /* add list of DER certs as X509's to stack */
41495
        while (current != NULL) {
41496
            WC_DerCertList*  toFree = current;
41497
            WOLFSSL_X509* x509;
41498
41499
            x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
41500
                DYNAMIC_TYPE_X509);
41501
            InitX509(x509, 1, heap);
41502
            InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap);
41503
            if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
41504
                WOLFSSL_MSG("Issue with parsing certificate");
41505
                FreeDecodedCert(DeCert);
41506
                wolfSSL_X509_free(x509);
41507
            }
41508
            else {
41509
                if (CopyDecodedToX509(x509, DeCert) != 0) {
41510
                    WOLFSSL_MSG("Failed to copy decoded cert");
41511
                    FreeDecodedCert(DeCert);
41512
                    wolfSSL_X509_free(x509);
41513
                    wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41514
                    if (pk != NULL) {
41515
                        XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
41516
                    }
41517
                    if (certData != NULL) {
41518
                        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
41519
                    }
41520
                    /* Free up WC_DerCertList */
41521
                    while (current != NULL) {
41522
                        WC_DerCertList* next = current->next;
41523
41524
                        XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
41525
                        XFREE(current, heap, DYNAMIC_TYPE_PKCS);
41526
                        current = next;
41527
                    }
41528
                    ret = WOLFSSL_FAILURE;
41529
                    goto out;
41530
                }
41531
                FreeDecodedCert(DeCert);
41532
41533
                if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
41534
                    WOLFSSL_MSG("Failed to push x509 onto stack");
41535
                    wolfSSL_X509_free(x509);
41536
                    wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41537
                    if (pk != NULL) {
41538
                        XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
41539
                    }
41540
                    if (certData != NULL) {
41541
                        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
41542
                    }
41543
41544
                    /* Free up WC_DerCertList */
41545
                    while (current != NULL) {
41546
                        WC_DerCertList* next = current->next;
41547
41548
                        XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
41549
                        XFREE(current, heap, DYNAMIC_TYPE_PKCS);
41550
                        current = next;
41551
                    }
41552
                    ret = WOLFSSL_FAILURE;
41553
                    goto out;
41554
                }
41555
            }
41556
            current = current->next;
41557
            XFREE(toFree->buffer, heap, DYNAMIC_TYPE_PKCS);
41558
            XFREE(toFree, heap, DYNAMIC_TYPE_PKCS);
41559
        }
41560
    }
41561
41562
41563
    /* Decode cert and place in X509 struct */
41564
    if (certData != NULL) {
41565
        *cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
41566
            DYNAMIC_TYPE_X509);
41567
        if (*cert == NULL) {
41568
            if (pk != NULL) {
41569
                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
41570
            }
41571
            if (ca != NULL) {
41572
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41573
            }
41574
            XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
41575
            ret = WOLFSSL_FAILURE;
41576
            goto out;
41577
        }
41578
        InitX509(*cert, 1, heap);
41579
        InitDecodedCert(DeCert, certData, certDataSz, heap);
41580
        if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
41581
            WOLFSSL_MSG("Issue with parsing certificate");
41582
        }
41583
        if (CopyDecodedToX509(*cert, DeCert) != 0) {
41584
            WOLFSSL_MSG("Failed to copy decoded cert");
41585
            FreeDecodedCert(DeCert);
41586
            if (pk != NULL) {
41587
                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
41588
            }
41589
            if (ca != NULL) {
41590
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41591
            }
41592
            wolfSSL_X509_free(*cert); *cert = NULL;
41593
            ret = WOLFSSL_FAILURE;
41594
            goto out;
41595
        }
41596
        FreeDecodedCert(DeCert);
41597
        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
41598
    }
41599
41600
41601
    /* get key type */
41602
    ret = BAD_STATE_E;
41603
    if (pk != NULL) { /* decode key if present */
41604
        *pkey = wolfSSL_EVP_PKEY_new_ex(heap);
41605
        if (*pkey == NULL) {
41606
            wolfSSL_X509_free(*cert); *cert = NULL;
41607
            if (ca != NULL) {
41608
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41609
            }
41610
            XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
41611
            ret = WOLFSSL_FAILURE;
41612
            goto out;
41613
        }
41614
41615
    #ifndef NO_RSA
41616
        {
41617
            const unsigned char* pt = pk;
41618
            if (wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, pkey, &pt, pkSz) !=
41619
                    NULL) {
41620
                ret = 0;
41621
            }
41622
        }
41623
    #endif /* NO_RSA */
41624
41625
    #ifdef HAVE_ECC
41626
        if (ret != 0) { /* if is in fail state check if ECC key */
41627
            const unsigned char* pt = pk;
41628
            if (wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, pkey, &pt, pkSz) !=
41629
                    NULL) {
41630
                ret = 0;
41631
            }
41632
        }
41633
    #endif /* HAVE_ECC */
41634
        if (pk != NULL)
41635
            XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
41636
        if (ret != 0) { /* if is in fail state and no PKEY then fail */
41637
            wolfSSL_X509_free(*cert); *cert = NULL;
41638
            if (ca != NULL) {
41639
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41640
            }
41641
            wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
41642
            WOLFSSL_MSG("Bad PKCS12 key format");
41643
            ret = WOLFSSL_FAILURE;
41644
            goto out;
41645
        }
41646
41647
        if (pkey != NULL && *pkey != NULL) {
41648
            (*pkey)->save_type = 0;
41649
        }
41650
    }
41651
41652
    (void)ret;
41653
    (void)ca;
41654
41655
    ret = WOLFSSL_SUCCESS;
41656
41657
out:
41658
41659
#ifdef WOLFSSL_SMALL_STACK
41660
    XFREE(DeCert, heap, DYNAMIC_TYPE_DCERT);
41661
#endif
41662
41663
    return ret;
41664
}
41665
41666
int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw,
41667
        int pswLen)
41668
{
41669
    WOLFSSL_ENTER("wolfSSL_PKCS12_verify_mac");
41670
41671
    if (!pkcs12) {
41672
        return WOLFSSL_FAILURE;
41673
    }
41674
41675
    return wc_PKCS12_verify_ex(pkcs12, (const byte*)psw, pswLen) == 0 ?
41676
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
41677
}
41678
41679
#endif /* !NO_ASN && !NO_PWDBASED */
41680
41681
#endif /* OPENSSL_EXTRA */
41682
41683
#endif /* HAVE_PKCS12 */
41684
/*******************************************************************************
41685
 * END OF PKCS12 APIs
41686
 ******************************************************************************/
41687
41688
#endif /* !NO_CERTS */
41689
41690
41691
/*******************************************************************************
41692
 * BEGIN OPENSSL FIPS DRBG APIs
41693
 ******************************************************************************/
41694
#if defined(OPENSSL_EXTRA) && !defined(WC_NO_RNG) && defined(HAVE_HASHDRBG)
41695
int wolfSSL_FIPS_drbg_init(WOLFSSL_DRBG_CTX *ctx, int type, unsigned int flags)
41696
{
41697
    int ret = WOLFSSL_FAILURE;
41698
    if (ctx != NULL) {
41699
        XMEMSET(ctx, 0, sizeof(WOLFSSL_DRBG_CTX));
41700
        ctx->type = type;
41701
        ctx->xflags = flags;
41702
        ctx->status = DRBG_STATUS_UNINITIALISED;
41703
        ret = WOLFSSL_SUCCESS;
41704
    }
41705
    return ret;
41706
}
41707
WOLFSSL_DRBG_CTX* wolfSSL_FIPS_drbg_new(int type, unsigned int flags)
41708
{
41709
    int ret = WOLFSSL_FAILURE;
41710
    WOLFSSL_DRBG_CTX* ctx = (WOLFSSL_DRBG_CTX*)XMALLOC(sizeof(WOLFSSL_DRBG_CTX),
41711
        NULL, DYNAMIC_TYPE_OPENSSL);
41712
    ret = wolfSSL_FIPS_drbg_init(ctx, type, flags);
41713
    if (ret == WOLFSSL_SUCCESS && type != 0) {
41714
        ret = wolfSSL_FIPS_drbg_instantiate(ctx, NULL, 0);
41715
    }
41716
    if (ret != WOLFSSL_SUCCESS) {
41717
        WOLFSSL_ERROR(ret);
41718
        wolfSSL_FIPS_drbg_free(ctx);
41719
        ctx = NULL;
41720
    }
41721
    return ctx;
41722
}
41723
int wolfSSL_FIPS_drbg_instantiate(WOLFSSL_DRBG_CTX* ctx,
41724
    const unsigned char* pers, size_t perslen)
41725
{
41726
    int ret = WOLFSSL_FAILURE;
41727
    if (ctx != NULL && ctx->rng == NULL) {
41728
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
41729
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
41730
        ctx->rng = wc_rng_new((byte*)pers, (word32)perslen, NULL);
41731
    #else
41732
        ctx->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
41733
        if (ctx->rng != NULL) {
41734
        #if defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)
41735
            ret = wc_InitRngNonce(ctx->rng, (byte*)pers, (word32)perslen);
41736
        #else
41737
            ret = wc_InitRng(ctx->rng);
41738
            (void)pers;
41739
            (void)perslen;
41740
        #endif
41741
            if (ret != 0) {
41742
                WOLFSSL_ERROR(ret);
41743
                XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
41744
                ctx->rng = NULL;
41745
            }
41746
        }
41747
    #endif
41748
    }
41749
    if (ctx != NULL && ctx->rng != NULL) {
41750
        ctx->status = DRBG_STATUS_READY;
41751
        ret = WOLFSSL_SUCCESS;
41752
    }
41753
    return ret;
41754
}
41755
int wolfSSL_FIPS_drbg_set_callbacks(WOLFSSL_DRBG_CTX* ctx,
41756
    drbg_entropy_get entropy_get, drbg_entropy_clean entropy_clean,
41757
    size_t entropy_blocklen,
41758
    drbg_nonce_get none_get, drbg_nonce_clean nonce_clean)
41759
{
41760
    int ret = WOLFSSL_FAILURE;
41761
    if (ctx != NULL) {
41762
        ctx->entropy_get = entropy_get;
41763
        ctx->entropy_clean = entropy_clean;
41764
        ctx->entropy_blocklen = entropy_blocklen;
41765
        ctx->none_get = none_get;
41766
        ctx->nonce_clean = nonce_clean;
41767
        ret = WOLFSSL_SUCCESS;
41768
    }
41769
    return ret;
41770
}
41771
void wolfSSL_FIPS_rand_add(const void* buf, int num, double entropy)
41772
{
41773
    /* not implemented */
41774
    (void)buf;
41775
    (void)num;
41776
    (void)entropy;
41777
}
41778
int wolfSSL_FIPS_drbg_reseed(WOLFSSL_DRBG_CTX* ctx, const unsigned char* adin,
41779
    size_t adinlen)
41780
{
41781
    int ret = WOLFSSL_FAILURE;
41782
    if (ctx != NULL && ctx->rng != NULL) {
41783
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
41784
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)))
41785
        if (wc_RNG_DRBG_Reseed(ctx->rng, adin, (word32)adinlen) == 0) {
41786
            ret = WOLFSSL_SUCCESS;
41787
        }
41788
    #else
41789
        ret = WOLFSSL_SUCCESS;
41790
        (void)adin;
41791
        (void)adinlen;
41792
    #endif
41793
    }
41794
    return ret;
41795
}
41796
int wolfSSL_FIPS_drbg_generate(WOLFSSL_DRBG_CTX* ctx, unsigned char* out,
41797
    size_t outlen, int prediction_resistance, const unsigned char* adin,
41798
    size_t adinlen)
41799
{
41800
    int ret = WOLFSSL_FAILURE;
41801
    if (ctx != NULL && ctx->rng != NULL) {
41802
        ret = wc_RNG_GenerateBlock(ctx->rng, out, (word32)outlen);
41803
        if (ret == 0) {
41804
            ret = WOLFSSL_SUCCESS;
41805
        }
41806
    }
41807
    (void)prediction_resistance;
41808
    (void)adin;
41809
    (void)adinlen;
41810
    return ret;
41811
}
41812
int wolfSSL_FIPS_drbg_uninstantiate(WOLFSSL_DRBG_CTX *ctx)
41813
{
41814
    if (ctx != NULL && ctx->rng != NULL) {
41815
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
41816
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
41817
        wc_rng_free(ctx->rng);
41818
    #else
41819
        wc_FreeRng(ctx->rng);
41820
        XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
41821
    #endif
41822
        ctx->rng = NULL;
41823
        ctx->status = DRBG_STATUS_UNINITIALISED;
41824
    }
41825
    return WOLFSSL_SUCCESS;
41826
}
41827
void wolfSSL_FIPS_drbg_free(WOLFSSL_DRBG_CTX *ctx)
41828
{
41829
    if (ctx != NULL) {
41830
        /* As saftey check if free'ing the default drbg, then mark global NULL.
41831
         * Technically the user should not call free on the default drbg. */
41832
        if (ctx == gDrbgDefCtx) {
41833
            gDrbgDefCtx = NULL;
41834
        }
41835
        wolfSSL_FIPS_drbg_uninstantiate(ctx);
41836
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
41837
    }
41838
}
41839
WOLFSSL_DRBG_CTX* wolfSSL_FIPS_get_default_drbg(void)
41840
{
41841
    if (gDrbgDefCtx == NULL) {
41842
        gDrbgDefCtx = wolfSSL_FIPS_drbg_new(0, 0);
41843
    }
41844
    return gDrbgDefCtx;
41845
}
41846
void wolfSSL_FIPS_get_timevec(unsigned char* buf, unsigned long* pctr)
41847
{
41848
    /* not implemented */
41849
    (void)buf;
41850
    (void)pctr;
41851
}
41852
void* wolfSSL_FIPS_drbg_get_app_data(WOLFSSL_DRBG_CTX *ctx)
41853
{
41854
    if (ctx != NULL) {
41855
        return ctx->app_data;
41856
    }
41857
    return NULL;
41858
}
41859
void wolfSSL_FIPS_drbg_set_app_data(WOLFSSL_DRBG_CTX *ctx, void *app_data)
41860
{
41861
    if (ctx != NULL) {
41862
        ctx->app_data = app_data;
41863
    }
41864
}
41865
#endif
41866
/*******************************************************************************
41867
 * END OF OPENSSL FIPS DRBG APIs
41868
 ******************************************************************************/
41869
41870
41871
#endif /* !WOLFCRYPT_ONLY */
41872
41873
/*******************************************************************************
41874
 * START OF CRYPTO-ONLY APIs
41875
 ******************************************************************************/
41876
41877
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
41878
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
41879
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
41880
    defined(WOLFSSL_HAPROXY)
41881
41882
#ifndef NO_SHA
41883
    /* One shot SHA1 hash of message.
41884
     *
41885
     * d  message to hash
41886
     * n  size of d buffer
41887
     * md buffer to hold digest. Should be SHA_DIGEST_SIZE.
41888
     *
41889
     * Note: if md is null then a static buffer of SHA_DIGEST_SIZE is used.
41890
     *       When the static buffer is used this function is not thread safe.
41891
     *
41892
     * Returns a pointer to the message digest on success and NULL on failure.
41893
     */
41894
    unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n,
41895
            unsigned char *md)
41896
    {
41897
        static byte dig[WC_SHA_DIGEST_SIZE];
41898
        byte* ret = md;
41899
        wc_Sha sha;
41900
41901
        WOLFSSL_ENTER("wolfSSL_SHA1");
41902
41903
        if (wc_InitSha_ex(&sha, NULL, INVALID_DEVID) != 0) {
41904
            WOLFSSL_MSG("SHA1 Init failed");
41905
            return NULL;
41906
        }
41907
41908
        if (wc_ShaUpdate(&sha, (const byte*)d, (word32)n) != 0) {
41909
            WOLFSSL_MSG("SHA1 Update failed");
41910
            return NULL;
41911
        }
41912
41913
        if (md == NULL) {
41914
            WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA1 IS NOT "
41915
                        "THREAD SAFE WHEN md == NULL");
41916
            ret = dig;
41917
        }
41918
        if (wc_ShaFinal(&sha, ret) != 0) {
41919
            WOLFSSL_MSG("SHA1 Final failed");
41920
            wc_ShaFree(&sha);
41921
            return NULL;
41922
        }
41923
        wc_ShaFree(&sha);
41924
41925
        return ret;
41926
    }
41927
#endif /* ! NO_SHA */
41928
41929
#ifdef WOLFSSL_SHA224
41930
    /* One shot SHA224 hash of message.
41931
     *
41932
     * d  message to hash
41933
     * n  size of d buffer
41934
     * md buffer to hold digest. Should be WC_SHA224_DIGEST_SIZE.
41935
     *
41936
     * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
41937
     *       When the static buffer is used this function is not thread safe.
41938
     *
41939
     * Returns a pointer to the message digest on success and NULL on failure.
41940
     */
41941
      unsigned char *wolfSSL_SHA224(const unsigned char *d, size_t n,
41942
            unsigned char *md)
41943
     {
41944
        static byte dig[WC_SHA224_DIGEST_SIZE];
41945
        byte* ret = md;
41946
        wc_Sha256 sha;
41947
41948
        WOLFSSL_ENTER("wolfSSL_SHA224");
41949
41950
        if (wc_InitSha224_ex(&sha, NULL, INVALID_DEVID) != 0) {
41951
            WOLFSSL_MSG("SHA224 Init failed");
41952
            return NULL;
41953
        }
41954
41955
        if (wc_Sha224Update(&sha, (const byte*)d, (word32)n) != 0) {
41956
            WOLFSSL_MSG("SHA224 Update failed");
41957
            return NULL;
41958
        }
41959
41960
        if (md == NULL) {
41961
            WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA224 IS NOT "
41962
                        "THREAD SAFE WHEN md == NULL");
41963
            ret = dig;
41964
        }
41965
        if (wc_Sha224Final(&sha, ret) != 0) {
41966
            WOLFSSL_MSG("SHA224 Final failed");
41967
            wc_Sha224Free(&sha);
41968
            return NULL;
41969
        }
41970
        wc_Sha224Free(&sha);
41971
41972
        return ret;
41973
    }
41974
#endif
41975
41976
#ifndef NO_SHA256
41977
    /* One shot SHA256 hash of message.
41978
     *
41979
     * d  message to hash
41980
     * n  size of d buffer
41981
     * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
41982
     *
41983
     * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
41984
     *       When the static buffer is used this function is not thread safe.
41985
     *
41986
     * Returns a pointer to the message digest on success and NULL on failure.
41987
     */
41988
    unsigned char *wolfSSL_SHA256(const unsigned char *d, size_t n,
41989
            unsigned char *md)
41990
    {
41991
        static byte dig[WC_SHA256_DIGEST_SIZE];
41992
        byte* ret = md;
41993
        wc_Sha256 sha;
41994
41995
        WOLFSSL_ENTER("wolfSSL_SHA256");
41996
41997
        if (wc_InitSha256_ex(&sha, NULL, INVALID_DEVID) != 0) {
41998
            WOLFSSL_MSG("SHA256 Init failed");
41999
            return NULL;
42000
        }
42001
42002
        if (wc_Sha256Update(&sha, (const byte*)d, (word32)n) != 0) {
42003
            WOLFSSL_MSG("SHA256 Update failed");
42004
            return NULL;
42005
        }
42006
42007
        if (md == NULL) {
42008
            WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA256 IS NOT "
42009
                        "THREAD SAFE WHEN md == NULL");
42010
            ret = dig;
42011
        }
42012
        if (wc_Sha256Final(&sha, ret) != 0) {
42013
            WOLFSSL_MSG("SHA256 Final failed");
42014
            wc_Sha256Free(&sha);
42015
            return NULL;
42016
        }
42017
        wc_Sha256Free(&sha);
42018
42019
        return ret;
42020
    }
42021
#endif /* ! NO_SHA256 */
42022
42023
#ifdef WOLFSSL_SHA384
42024
     /* One shot SHA384 hash of message.
42025
      *
42026
      * d  message to hash
42027
      * n  size of d buffer
42028
      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
42029
      *
42030
      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
42031
      *       When the static buffer is used this function is not thread safe.
42032
      *
42033
      * Returns a pointer to the message digest on success and NULL on failure.
42034
      */
42035
     unsigned char *wolfSSL_SHA384(const unsigned char *d, size_t n,
42036
             unsigned char *md)
42037
     {
42038
         static byte dig[WC_SHA384_DIGEST_SIZE];
42039
         byte* ret = md;
42040
         wc_Sha384 sha;
42041
42042
         WOLFSSL_ENTER("wolfSSL_SHA384");
42043
42044
         if (wc_InitSha384_ex(&sha, NULL, INVALID_DEVID) != 0) {
42045
             WOLFSSL_MSG("SHA384 Init failed");
42046
             return NULL;
42047
         }
42048
42049
         if (wc_Sha384Update(&sha, (const byte*)d, (word32)n) != 0) {
42050
             WOLFSSL_MSG("SHA384 Update failed");
42051
             return NULL;
42052
         }
42053
42054
         if (md == NULL) {
42055
             WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA384 IS NOT "
42056
                         "THREAD SAFE WHEN md == NULL");
42057
             ret = dig;
42058
         }
42059
         if (wc_Sha384Final(&sha, ret) != 0) {
42060
             WOLFSSL_MSG("SHA384 Final failed");
42061
             wc_Sha384Free(&sha);
42062
             return NULL;
42063
         }
42064
         wc_Sha384Free(&sha);
42065
42066
         return ret;
42067
     }
42068
#endif /* WOLFSSL_SHA384  */
42069
42070
#if defined(WOLFSSL_SHA512)
42071
     /* One shot SHA512 hash of message.
42072
      *
42073
      * d  message to hash
42074
      * n  size of d buffer
42075
      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
42076
      *
42077
      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
42078
      *       When the static buffer is used this function is not thread safe.
42079
      *
42080
      * Returns a pointer to the message digest on success and NULL on failure.
42081
      */
42082
     unsigned char *wolfSSL_SHA512(const unsigned char *d, size_t n,
42083
             unsigned char *md)
42084
     {
42085
         static byte dig[WC_SHA512_DIGEST_SIZE];
42086
         byte* ret = md;
42087
         wc_Sha512 sha;
42088
42089
         WOLFSSL_ENTER("wolfSSL_SHA512");
42090
42091
         if (wc_InitSha512_ex(&sha, NULL, INVALID_DEVID) != 0) {
42092
             WOLFSSL_MSG("SHA512 Init failed");
42093
             return NULL;
42094
         }
42095
42096
         if (wc_Sha512Update(&sha, (const byte*)d, (word32)n) != 0) {
42097
             WOLFSSL_MSG("SHA512 Update failed");
42098
             return NULL;
42099
         }
42100
42101
         if (md == NULL) {
42102
             WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA512 IS NOT "
42103
                         "THREAD SAFE WHEN md == NULL");
42104
             ret = dig;
42105
         }
42106
         if (wc_Sha512Final(&sha, ret) != 0) {
42107
             WOLFSSL_MSG("SHA512 Final failed");
42108
             wc_Sha512Free(&sha);
42109
             return NULL;
42110
         }
42111
         wc_Sha512Free(&sha);
42112
42113
         return ret;
42114
     }
42115
#endif /* WOLFSSL_SHA512 */
42116
#endif /* OPENSSL_EXTRA || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
42117
        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
42118
42119
/*******************************************************************************
42120
 * END OF CRYPTO-ONLY APIs
42121
 ******************************************************************************/