Coverage Report

Created: 2022-08-24 06:25

/src/wolfssl-openssl-api/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
    {XSTR_SIZEOF("NTRU_HPS_LEVEL1"), "NTRU_HPS_LEVEL1", WOLFSSL_NTRU_HPS_LEVEL1},
229
    {XSTR_SIZEOF("NTRU_HPS_LEVEL3"), "NTRU_HPS_LEVEL3", WOLFSSL_NTRU_HPS_LEVEL3},
230
    {XSTR_SIZEOF("NTRU_HPS_LEVEL5"), "NTRU_HPS_LEVEL5", WOLFSSL_NTRU_HPS_LEVEL5},
231
    {XSTR_SIZEOF("NTRU_HRSS_LEVEL3"), "NTRU_HRSS_LEVEL3", WOLFSSL_NTRU_HRSS_LEVEL3},
232
    {XSTR_SIZEOF("SABER_LEVEL1"), "SABER_LEVEL1", WOLFSSL_SABER_LEVEL1},
233
    {XSTR_SIZEOF("SABER_LEVEL3"), "SABER_LEVEL3", WOLFSSL_SABER_LEVEL3},
234
    {XSTR_SIZEOF("SABER_LEVEL5"), "SABER_LEVEL5", WOLFSSL_SABER_LEVEL5},
235
    {XSTR_SIZEOF("KYBER_90S_LEVEL1"), "KYBER_90S_LEVEL1", WOLFSSL_KYBER_90S_LEVEL1},
236
    {XSTR_SIZEOF("KYBER_90S_LEVEL3"), "KYBER_90S_LEVEL3", WOLFSSL_KYBER_90S_LEVEL3},
237
    {XSTR_SIZEOF("KYBER_90S_LEVEL5"), "KYBER_90S_LEVEL5", WOLFSSL_KYBER_90S_LEVEL5},
238
    {XSTR_SIZEOF("P256_NTRU_HPS_LEVEL1"), "P256_NTRU_HPS_LEVEL1", WOLFSSL_P256_NTRU_HPS_LEVEL1},
239
    {XSTR_SIZEOF("P384_NTRU_HPS_LEVEL3"), "P384_NTRU_HPS_LEVEL3", WOLFSSL_P384_NTRU_HPS_LEVEL3},
240
    {XSTR_SIZEOF("P521_NTRU_HPS_LEVEL5"), "P521_NTRU_HPS_LEVEL5", WOLFSSL_P521_NTRU_HPS_LEVEL5},
241
    {XSTR_SIZEOF("P384_NTRU_HRSS_LEVEL3"), "P384_NTRU_HRSS_LEVEL3", WOLFSSL_P384_NTRU_HRSS_LEVEL3},
242
    {XSTR_SIZEOF("P256_SABER_LEVEL1"), "P256_SABER_LEVEL1", WOLFSSL_P256_SABER_LEVEL1},
243
    {XSTR_SIZEOF("P384_SABER_LEVEL3"), "P384_SABER_LEVEL3", WOLFSSL_P384_SABER_LEVEL3},
244
    {XSTR_SIZEOF("P521_SABER_LEVEL5"), "P521_SABER_LEVEL5", WOLFSSL_P521_SABER_LEVEL5},
245
    {XSTR_SIZEOF("P256_KYBER_LEVEL1"), "P256_KYBER_LEVEL1", WOLFSSL_P256_KYBER_LEVEL1},
246
    {XSTR_SIZEOF("P384_KYBER_LEVEL3"), "P384_KYBER_LEVEL3", WOLFSSL_P384_KYBER_LEVEL3},
247
    {XSTR_SIZEOF("P521_KYBER_LEVEL5"), "P521_KYBER_LEVEL5", WOLFSSL_P521_KYBER_LEVEL5},
248
    {XSTR_SIZEOF("P256_KYBER_90S_LEVEL1"), "P256_KYBER_90S_LEVEL1", WOLFSSL_P256_KYBER_90S_LEVEL1},
249
    {XSTR_SIZEOF("P384_KYBER_90S_LEVEL3"), "P384_KYBER_90S_LEVEL3", WOLFSSL_P384_KYBER_90S_LEVEL3},
250
    {XSTR_SIZEOF("P521_KYBER_90S_LEVEL5"), "P521_KYBER_90S_LEVEL5", WOLFSSL_P521_KYBER_90S_LEVEL5},
251
#endif
252
    {0, NULL, 0},
253
};
254
#endif
255
256
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
257
#include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
258
#endif
259
260
#ifdef WOLFSSL_SESSION_EXPORT
261
/* Used to import a serialized TLS session.
262
 * WARNING: buf contains sensitive information about the state and is best to be
263
 *          encrypted before storing if stored.
264
 *
265
 * @param ssl WOLFSSL structure to import the session into
266
 * @param buf serialized session
267
 * @param sz  size of buffer 'buf'
268
 * @return the number of bytes read from buffer 'buf'
269
 */
270
int wolfSSL_tls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
271
{
272
    if (ssl == NULL || buf == NULL) {
273
        return BAD_FUNC_ARG;
274
    }
275
    return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
276
}
277
278
279
/* Used to export a serialized TLS session.
280
 * WARNING: buf contains sensitive information about the state and is best to be
281
 *          encrypted before storing if stored.
282
 *
283
 * @param ssl WOLFSSL structure to export the session from
284
 * @param buf output of serialized session
285
 * @param sz  size in bytes set in 'buf'
286
 * @return the number of bytes written into buffer 'buf'
287
 */
288
int wolfSSL_tls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
289
{
290
    if (ssl == NULL || sz == NULL) {
291
        return BAD_FUNC_ARG;
292
    }
293
    return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_TLS);
294
}
295
296
#ifdef WOLFSSL_DTLS
297
int wolfSSL_dtls_import(WOLFSSL* ssl, const unsigned char* buf, unsigned int sz)
298
{
299
    WOLFSSL_ENTER("wolfSSL_session_import");
300
301
    if (ssl == NULL || buf == NULL) {
302
        return BAD_FUNC_ARG;
303
    }
304
305
    /* sanity checks on buffer and protocol are done in internal function */
306
    return wolfSSL_session_import_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
307
}
308
309
310
/* Sets the function to call for serializing the session. This function is
311
 * called right after the handshake is completed. */
312
int wolfSSL_CTX_dtls_set_export(WOLFSSL_CTX* ctx, wc_dtls_export func)
313
{
314
315
    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_export");
316
317
    /* purposefully allow func to be NULL */
318
    if (ctx == NULL) {
319
        return BAD_FUNC_ARG;
320
    }
321
322
    ctx->dtls_export = func;
323
324
    return WOLFSSL_SUCCESS;
325
}
326
327
328
/* Sets the function in WOLFSSL struct to call for serializing the session. This
329
 * function is called right after the handshake is completed. */
330
int wolfSSL_dtls_set_export(WOLFSSL* ssl, wc_dtls_export func)
331
{
332
333
    WOLFSSL_ENTER("wolfSSL_dtls_set_export");
334
335
    /* purposefully allow func to be NULL */
336
    if (ssl == NULL) {
337
        return BAD_FUNC_ARG;
338
    }
339
340
    ssl->dtls_export = func;
341
342
    return WOLFSSL_SUCCESS;
343
}
344
345
346
/* This function allows for directly serializing a session rather than using
347
 * callbacks. It has less overhead by removing a temporary buffer and gives
348
 * control over when the session gets serialized. When using callbacks the
349
 * session is always serialized immediately after the handshake is finished.
350
 *
351
 * buf is the argument to contain the serialized session
352
 * sz  is the size of the buffer passed in
353
 * ssl is the WOLFSSL struct to serialize
354
 * returns the size of serialized session on success, 0 on no action, and
355
 *         negative value on error */
356
int wolfSSL_dtls_export(WOLFSSL* ssl, unsigned char* buf, unsigned int* sz)
357
{
358
    WOLFSSL_ENTER("wolfSSL_dtls_export");
359
360
    if (ssl == NULL || sz == NULL) {
361
        return BAD_FUNC_ARG;
362
    }
363
364
    if (buf == NULL) {
365
        *sz = MAX_EXPORT_BUFFER;
366
        return 0;
367
    }
368
369
    /* if not DTLS do nothing */
370
    if (!ssl->options.dtls) {
371
        WOLFSSL_MSG("Currently only DTLS export is supported");
372
        return 0;
373
    }
374
375
    /* copy over keys, options, and dtls state struct */
376
    return wolfSSL_session_export_internal(ssl, buf, sz, WOLFSSL_EXPORT_DTLS);
377
}
378
379
380
/* This function is similar to wolfSSL_dtls_export but only exports the portion
381
 * of the WOLFSSL structure related to the state of the connection, i.e. peer
382
 * sequence number, epoch, AEAD state etc.
383
 *
384
 * buf is the argument to contain the serialized state, if null then set "sz" to
385
 *     buffer size required
386
 * sz  is the size of the buffer passed in
387
 * ssl is the WOLFSSL struct to serialize
388
 * returns the size of serialized session on success, 0 on no action, and
389
 *         negative value on error */
390
int wolfSSL_dtls_export_state_only(WOLFSSL* ssl, unsigned char* buf,
391
        unsigned int* sz)
392
{
393
    WOLFSSL_ENTER("wolfSSL_dtls_export_state_only");
394
395
    if (ssl == NULL || sz == NULL) {
396
        return BAD_FUNC_ARG;
397
    }
398
399
    if (buf == NULL) {
400
        *sz = MAX_EXPORT_STATE_BUFFER;
401
        return 0;
402
    }
403
404
    /* if not DTLS do nothing */
405
    if (!ssl->options.dtls) {
406
        WOLFSSL_MSG("Currently only DTLS export state is supported");
407
        return 0;
408
    }
409
410
    /* copy over keys, options, and dtls state struct */
411
    return wolfSSL_dtls_export_state_internal(ssl, buf, *sz);
412
}
413
414
415
/* returns 0 on success */
416
int wolfSSL_send_session(WOLFSSL* ssl)
417
{
418
    int ret;
419
    byte* buf;
420
    word32 bufSz = MAX_EXPORT_BUFFER;
421
422
    WOLFSSL_ENTER("wolfSSL_send_session");
423
424
    if (ssl == NULL) {
425
        return BAD_FUNC_ARG;
426
    }
427
428
    buf = (byte*)XMALLOC(bufSz, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
429
    if (buf == NULL) {
430
        return MEMORY_E;
431
    }
432
433
    /* if not DTLS do nothing */
434
    if (!ssl->options.dtls) {
435
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
436
        WOLFSSL_MSG("Currently only DTLS export is supported");
437
        return 0;
438
    }
439
440
    /* copy over keys, options, and dtls state struct */
441
    ret = wolfSSL_session_export_internal(ssl, buf, &bufSz, WOLFSSL_EXPORT_DTLS);
442
    if (ret < 0) {
443
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
444
        return ret;
445
    }
446
447
    /* if no error ret has size of buffer */
448
    ret = ssl->dtls_export(ssl, buf, ret, NULL);
449
    if (ret != WOLFSSL_SUCCESS) {
450
        XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
451
        return ret;
452
    }
453
454
    XFREE(buf, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
455
    return 0;
456
}
457
#endif /* WOLFSSL_DTLS */
458
#endif /* WOLFSSL_SESSION_EXPORT */
459
460
/* prevent multiple mutex initializations */
461
static volatile WOLFSSL_GLOBAL int initRefCount = 0;
462
static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex;   /* init ref count mutex */
463
static WOLFSSL_GLOBAL int count_mutex_valid = 0;
464
465
/* Create a new WOLFSSL_CTX struct and return the pointer to created struct.
466
   WOLFSSL_METHOD pointer passed in is given to ctx to manage.
467
   This function frees the passed in WOLFSSL_METHOD struct on failure and on
468
   success is freed when ctx is freed.
469
 */
470
WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap)
471
0
{
472
0
    WOLFSSL_CTX* ctx = NULL;
473
474
0
    WOLFSSL_ENTER("wolfSSL_CTX_new_ex");
475
476
0
    if (initRefCount == 0) {
477
        /* user no longer forced to call Init themselves */
478
0
        int ret = wolfSSL_Init();
479
0
        if (ret != WOLFSSL_SUCCESS) {
480
0
            WOLFSSL_MSG("wolfSSL_Init failed");
481
0
            WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
482
0
            if (method != NULL) {
483
0
                XFREE(method, heap, DYNAMIC_TYPE_METHOD);
484
0
            }
485
0
            return NULL;
486
0
        }
487
0
    }
488
489
0
    if (method == NULL)
490
0
        return ctx;
491
492
0
    ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX);
493
0
    if (ctx) {
494
0
        int ret;
495
496
0
        ret = InitSSL_Ctx(ctx, method, heap);
497
    #ifdef WOLFSSL_STATIC_MEMORY
498
        if (heap != NULL) {
499
            ctx->onHeapHint = 1; /* free the memory back to heap when done */
500
        }
501
    #endif
502
0
        if (ret < 0) {
503
0
            WOLFSSL_MSG("Init CTX failed");
504
0
            wolfSSL_CTX_free(ctx);
505
0
            ctx = NULL;
506
0
        }
507
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
508
                           && !defined(NO_SHA256) && !defined(WC_NO_RNG)
509
        else {
510
            ctx->srp = (Srp*)XMALLOC(sizeof(Srp), heap, DYNAMIC_TYPE_SRP);
511
            if (ctx->srp == NULL){
512
                WOLFSSL_MSG("Init CTX failed");
513
                wolfSSL_CTX_free(ctx);
514
                return NULL;
515
            }
516
            XMEMSET(ctx->srp, 0, sizeof(Srp));
517
        }
518
#endif
519
0
    }
520
0
    else {
521
0
        WOLFSSL_MSG("Alloc CTX failed, method freed");
522
0
        XFREE(method, heap, DYNAMIC_TYPE_METHOD);
523
0
    }
524
525
#ifdef OPENSSL_COMPATIBLE_DEFAULTS
526
    if (ctx) {
527
        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
528
        wolfSSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
529
        if (wolfSSL_CTX_set_min_proto_version(ctx,
530
                                              (method->version.major == DTLS_MAJOR) ?
531
                                               DTLS1_VERSION : SSL3_VERSION) != WOLFSSL_SUCCESS ||
532
#ifdef HAVE_ANON
533
                wolfSSL_CTX_allow_anon_cipher(ctx) != WOLFSSL_SUCCESS ||
534
#endif
535
                wolfSSL_CTX_set_group_messages(ctx) != WOLFSSL_SUCCESS) {
536
            WOLFSSL_MSG("Setting OpenSSL CTX defaults failed");
537
            wolfSSL_CTX_free(ctx);
538
            ctx = NULL;
539
        }
540
    }
541
#endif
542
543
0
    WOLFSSL_LEAVE("WOLFSSL_CTX_new", 0);
544
0
    return ctx;
545
0
}
546
547
548
WOLFSSL_ABI
549
WOLFSSL_CTX* wolfSSL_CTX_new(WOLFSSL_METHOD* method)
550
0
{
551
#ifdef WOLFSSL_HEAP_TEST
552
    /* if testing the heap hint then set top level CTX to have test value */
553
    return wolfSSL_CTX_new_ex(method, (void*)WOLFSSL_HEAP_TEST);
554
#else
555
0
    return wolfSSL_CTX_new_ex(method, NULL);
556
0
#endif
557
0
}
558
559
/* increases CTX reference count to track proper time to "free" */
560
int wolfSSL_CTX_up_ref(WOLFSSL_CTX* ctx)
561
0
{
562
0
    int refCount = SSL_CTX_RefCount(ctx, 1);
563
0
    return ((refCount > 1) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
564
0
}
565
566
WOLFSSL_ABI
567
void wolfSSL_CTX_free(WOLFSSL_CTX* ctx)
568
0
{
569
0
    WOLFSSL_ENTER("SSL_CTX_free");
570
0
    if (ctx) {
571
#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \
572
&& !defined(NO_SHA256) && !defined(WC_NO_RNG)
573
        if (ctx->srp != NULL) {
574
            if (ctx->srp_password != NULL){
575
                XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
576
                ctx->srp_password = NULL;
577
            }
578
            wc_SrpTerm(ctx->srp);
579
            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
580
            ctx->srp = NULL;
581
        }
582
#endif
583
0
        FreeSSL_Ctx(ctx);
584
0
    }
585
586
0
    WOLFSSL_LEAVE("SSL_CTX_free", 0);
587
0
}
588
589
590
#ifdef HAVE_ENCRYPT_THEN_MAC
591
/**
592
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
593
 * The default value: enabled.
594
 *
595
 * ctx  SSL/TLS context.
596
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
597
 * returns WOLFSSL_SUCCESS
598
 */
599
int wolfSSL_CTX_AllowEncryptThenMac(WOLFSSL_CTX *ctx, int set)
600
0
{
601
0
    ctx->disallowEncThenMac = !set;
602
0
    return WOLFSSL_SUCCESS;
603
0
}
604
605
/**
606
 * Sets whether Encrypt-Then-MAC extension can be negotiated against context.
607
 * The default value comes from context.
608
 *
609
 * ctx  SSL/TLS context.
610
 * set  Whether to allow or not: 1 is allow and 0 is disallow.
611
 * returns WOLFSSL_SUCCESS
612
 */
613
int wolfSSL_AllowEncryptThenMac(WOLFSSL *ssl, int set)
614
0
{
615
0
    ssl->options.disallowEncThenMac = !set;
616
0
    return WOLFSSL_SUCCESS;
617
0
}
618
#endif
619
620
#ifdef SINGLE_THREADED
621
/* no locking in single threaded mode, allow a CTX level rng to be shared with
622
 * WOLFSSL objects, WOLFSSL_SUCCESS on ok */
623
int wolfSSL_CTX_new_rng(WOLFSSL_CTX* ctx)
624
{
625
    WC_RNG* rng;
626
    int     ret;
627
628
    if (ctx == NULL) {
629
        return BAD_FUNC_ARG;
630
    }
631
632
    rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), ctx->heap, DYNAMIC_TYPE_RNG);
633
    if (rng == NULL) {
634
        return MEMORY_E;
635
    }
636
637
#ifndef HAVE_FIPS
638
    ret = wc_InitRng_ex(rng, ctx->heap, ctx->devId);
639
#else
640
    ret = wc_InitRng(rng);
641
#endif
642
    if (ret != 0) {
643
        XFREE(rng, ctx->heap, DYNAMIC_TYPE_RNG);
644
        return ret;
645
    }
646
647
    ctx->rng = rng;
648
    return WOLFSSL_SUCCESS;
649
}
650
#endif
651
652
653
WOLFSSL_ABI
654
WOLFSSL* wolfSSL_new(WOLFSSL_CTX* ctx)
655
0
{
656
0
    WOLFSSL* ssl = NULL;
657
0
    int ret = 0;
658
659
0
    WOLFSSL_ENTER("SSL_new");
660
661
0
    if (ctx == NULL)
662
0
        return ssl;
663
664
0
    ssl = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ctx->heap, DYNAMIC_TYPE_SSL);
665
0
    if (ssl)
666
0
        if ( (ret = InitSSL(ssl, ctx, 0)) < 0) {
667
0
            FreeSSL(ssl, ctx->heap);
668
0
            ssl = 0;
669
0
        }
670
671
0
    WOLFSSL_LEAVE("SSL_new", ret);
672
0
    (void)ret;
673
674
0
    return ssl;
675
0
}
676
677
678
WOLFSSL_ABI
679
void wolfSSL_free(WOLFSSL* ssl)
680
0
{
681
0
    WOLFSSL_ENTER("SSL_free");
682
0
    if (ssl)
683
0
        FreeSSL(ssl, ssl->ctx->heap);
684
0
    WOLFSSL_LEAVE("SSL_free", 0);
685
0
}
686
687
688
int wolfSSL_is_server(WOLFSSL* ssl)
689
0
{
690
0
    if (ssl == NULL)
691
0
        return BAD_FUNC_ARG;
692
0
    return ssl->options.side == WOLFSSL_SERVER_END;
693
0
}
694
695
#ifdef HAVE_WRITE_DUP
696
697
/*
698
 * Release resources around WriteDup object
699
 *
700
 * ssl WOLFSSL object
701
 *
702
 * no return, destruction so make best attempt
703
*/
704
void FreeWriteDup(WOLFSSL* ssl)
705
{
706
    int doFree = 0;
707
708
    WOLFSSL_ENTER("FreeWriteDup");
709
710
    if (ssl->dupWrite) {
711
        if (wc_LockMutex(&ssl->dupWrite->dupMutex) == 0) {
712
            ssl->dupWrite->dupCount--;
713
            if (ssl->dupWrite->dupCount == 0) {
714
                doFree = 1;
715
            } else {
716
                WOLFSSL_MSG("WriteDup count not zero, no full free");
717
            }
718
            wc_UnLockMutex(&ssl->dupWrite->dupMutex);
719
        }
720
    }
721
722
    if (doFree) {
723
        WOLFSSL_MSG("Doing WriteDup full free, count to zero");
724
        wc_FreeMutex(&ssl->dupWrite->dupMutex);
725
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
726
    }
727
}
728
729
730
/*
731
 * duplicate existing ssl members into dup needed for writing
732
 *
733
 * dup write only WOLFSSL
734
 * ssl existing WOLFSSL
735
 *
736
 * 0 on success
737
*/
738
static int DupSSL(WOLFSSL* dup, WOLFSSL* ssl)
739
{
740
    /* shared dupWrite setup */
741
    ssl->dupWrite = (WriteDup*)XMALLOC(sizeof(WriteDup), ssl->heap,
742
                                       DYNAMIC_TYPE_WRITEDUP);
743
    if (ssl->dupWrite == NULL) {
744
        return MEMORY_E;
745
    }
746
    XMEMSET(ssl->dupWrite, 0, sizeof(WriteDup));
747
748
    if (wc_InitMutex(&ssl->dupWrite->dupMutex) != 0) {
749
        XFREE(ssl->dupWrite, ssl->heap, DYNAMIC_TYPE_WRITEDUP);
750
        ssl->dupWrite = NULL;
751
        return BAD_MUTEX_E;
752
    }
753
    ssl->dupWrite->dupCount = 2;    /* both sides have a count to start */
754
    dup->dupWrite = ssl->dupWrite; /* each side uses */
755
756
    /* copy write parts over to dup writer */
757
    XMEMCPY(&dup->specs,   &ssl->specs,   sizeof(CipherSpecs));
758
    XMEMCPY(&dup->options, &ssl->options, sizeof(Options));
759
    XMEMCPY(&dup->keys,    &ssl->keys,    sizeof(Keys));
760
    XMEMCPY(&dup->encrypt, &ssl->encrypt, sizeof(Ciphers));
761
    XMEMCPY(&dup->version, &ssl->version, sizeof(ProtocolVersion));
762
    XMEMCPY(&dup->chVersion, &ssl->chVersion, sizeof(ProtocolVersion));
763
764
    /* dup side now owns encrypt/write ciphers */
765
    XMEMSET(&ssl->encrypt, 0, sizeof(Ciphers));
766
767
    dup->IOCB_WriteCtx = ssl->IOCB_WriteCtx;
768
    dup->CBIOSend = ssl->CBIOSend;
769
#ifdef OPENSSL_EXTRA
770
    dup->cbioFlag = ssl->cbioFlag;
771
#endif
772
    dup->wfd    = ssl->wfd;
773
    dup->wflags = ssl->wflags;
774
#ifndef WOLFSSL_AEAD_ONLY
775
    dup->hmac   = ssl->hmac;
776
#endif
777
#ifdef HAVE_TRUNCATED_HMAC
778
    dup->truncated_hmac = ssl->truncated_hmac;
779
#endif
780
781
    /* unique side dup setup */
782
    dup->dupSide = WRITE_DUP_SIDE;
783
    ssl->dupSide = READ_DUP_SIDE;
784
785
    return 0;
786
}
787
788
789
/*
790
 * duplicate a WOLFSSL object post handshake for writing only
791
 * turn existing object into read only.  Allows concurrent access from two
792
 * different threads.
793
 *
794
 * ssl existing WOLFSSL object
795
 *
796
 * return dup'd WOLFSSL object on success
797
*/
798
WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl)
799
{
800
    WOLFSSL* dup = NULL;
801
    int ret = 0;
802
803
    (void)ret;
804
    WOLFSSL_ENTER("wolfSSL_write_dup");
805
806
    if (ssl == NULL) {
807
        return ssl;
808
    }
809
810
    if (ssl->options.handShakeDone == 0) {
811
        WOLFSSL_MSG("wolfSSL_write_dup called before handshake complete");
812
        return NULL;
813
    }
814
815
    if (ssl->dupWrite) {
816
        WOLFSSL_MSG("wolfSSL_write_dup already called once");
817
        return NULL;
818
    }
819
820
    dup = (WOLFSSL*) XMALLOC(sizeof(WOLFSSL), ssl->ctx->heap, DYNAMIC_TYPE_SSL);
821
    if (dup) {
822
        if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) {
823
            FreeSSL(dup, ssl->ctx->heap);
824
            dup = NULL;
825
        } else if ( (ret = DupSSL(dup, ssl)) < 0) {
826
            FreeSSL(dup, ssl->ctx->heap);
827
            dup = NULL;
828
        }
829
    }
830
831
    WOLFSSL_LEAVE("wolfSSL_write_dup", ret);
832
833
    return dup;
834
}
835
836
837
/*
838
 * Notify write dup side of fatal error or close notify
839
 *
840
 * ssl WOLFSSL object
841
 * err Notify err
842
 *
843
 * 0 on success
844
*/
845
int NotifyWriteSide(WOLFSSL* ssl, int err)
846
{
847
    int ret;
848
849
    WOLFSSL_ENTER("NotifyWriteSide");
850
851
    ret = wc_LockMutex(&ssl->dupWrite->dupMutex);
852
    if (ret == 0) {
853
        ssl->dupWrite->dupErr = err;
854
        ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
855
    }
856
857
    return ret;
858
}
859
860
861
#endif /* HAVE_WRITE_DUP */
862
863
864
#ifdef HAVE_POLY1305
865
/* set if to use old poly 1 for yes 0 to use new poly */
866
int wolfSSL_use_old_poly(WOLFSSL* ssl, int value)
867
0
{
868
0
    (void)ssl;
869
0
    (void)value;
870
871
0
#ifndef WOLFSSL_NO_TLS12
872
0
    WOLFSSL_ENTER("SSL_use_old_poly");
873
0
    WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function"
874
0
            "is depreciated");
875
0
    ssl->options.oldPoly = (word16)value;
876
0
    WOLFSSL_LEAVE("SSL_use_old_poly", 0);
877
0
#endif
878
0
    return 0;
879
0
}
880
#endif
881
882
883
WOLFSSL_ABI
884
int wolfSSL_set_fd(WOLFSSL* ssl, int fd)
885
0
{
886
0
    int ret;
887
888
0
    WOLFSSL_ENTER("SSL_set_fd");
889
890
0
    if (ssl == NULL) {
891
0
        return BAD_FUNC_ARG;
892
0
    }
893
894
0
    ret = wolfSSL_set_read_fd(ssl, fd);
895
0
    if (ret == WOLFSSL_SUCCESS) {
896
0
        ret = wolfSSL_set_write_fd(ssl, fd);
897
0
    }
898
899
0
    return ret;
900
0
}
901
902
#ifdef WOLFSSL_DTLS
903
int wolfSSL_set_dtls_fd_connected(WOLFSSL* ssl, int fd)
904
{
905
    int ret;
906
907
    WOLFSSL_ENTER("SSL_set_dtls_fd_connected");
908
909
    if (ssl == NULL) {
910
        return BAD_FUNC_ARG;
911
    }
912
913
    ret = wolfSSL_set_fd(ssl, fd);
914
    if (ret == WOLFSSL_SUCCESS)
915
        ssl->buffers.dtlsCtx.connected = 1;
916
917
    return ret;
918
}
919
#endif
920
921
922
int wolfSSL_set_read_fd(WOLFSSL* ssl, int fd)
923
0
{
924
0
    WOLFSSL_ENTER("SSL_set_read_fd");
925
926
0
    if (ssl == NULL) {
927
0
        return BAD_FUNC_ARG;
928
0
    }
929
930
0
    ssl->rfd = fd;      /* not used directly to allow IO callbacks */
931
0
    ssl->IOCB_ReadCtx  = &ssl->rfd;
932
933
    #ifdef WOLFSSL_DTLS
934
        ssl->buffers.dtlsCtx.connected = 0;
935
        if (ssl->options.dtls) {
936
            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
937
            ssl->buffers.dtlsCtx.rfd = fd;
938
        }
939
    #endif
940
941
0
    WOLFSSL_LEAVE("SSL_set_read_fd", WOLFSSL_SUCCESS);
942
0
    return WOLFSSL_SUCCESS;
943
0
}
944
945
946
int wolfSSL_set_write_fd(WOLFSSL* ssl, int fd)
947
0
{
948
0
    WOLFSSL_ENTER("SSL_set_write_fd");
949
950
0
    if (ssl == NULL) {
951
0
        return BAD_FUNC_ARG;
952
0
    }
953
954
0
    ssl->wfd = fd;      /* not used directly to allow IO callbacks */
955
0
    ssl->IOCB_WriteCtx  = &ssl->wfd;
956
957
    #ifdef WOLFSSL_DTLS
958
        ssl->buffers.dtlsCtx.connected = 0;
959
        if (ssl->options.dtls) {
960
            ssl->IOCB_WriteCtx = &ssl->buffers.dtlsCtx;
961
            ssl->buffers.dtlsCtx.wfd = fd;
962
        }
963
    #endif
964
965
0
    WOLFSSL_LEAVE("SSL_set_write_fd", WOLFSSL_SUCCESS);
966
0
    return WOLFSSL_SUCCESS;
967
0
}
968
969
970
/**
971
  * Get the name of cipher at priority level passed in.
972
  */
973
char* wolfSSL_get_cipher_list(int priority)
974
0
{
975
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
976
977
0
    if (priority >= GetCipherNamesSize() || priority < 0) {
978
0
        return 0;
979
0
    }
980
981
0
    return (char*)ciphers[priority].name;
982
0
}
983
984
985
/**
986
  * Get the name of cipher at priority level passed in.
987
  */
988
char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority)
989
0
{
990
991
0
    if (ssl == NULL) {
992
0
        return NULL;
993
0
    }
994
0
    else {
995
0
        const char* cipher;
996
997
0
        if ((cipher = wolfSSL_get_cipher_name_internal(ssl)) != NULL) {
998
0
            if (priority == 0) {
999
0
                return (char*)cipher;
1000
0
            }
1001
0
            else {
1002
0
                return NULL;
1003
0
            }
1004
0
        }
1005
0
        else {
1006
0
            return wolfSSL_get_cipher_list(priority);
1007
0
        }
1008
0
    }
1009
0
}
1010
1011
1012
int wolfSSL_get_ciphers(char* buf, int len)
1013
0
{
1014
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1015
0
    int ciphersSz = GetCipherNamesSize();
1016
0
    int i;
1017
0
    int cipherNameSz;
1018
1019
0
    if (buf == NULL || len <= 0)
1020
0
        return BAD_FUNC_ARG;
1021
1022
    /* Add each member to the buffer delimited by a : */
1023
0
    for (i = 0; i < ciphersSz; i++) {
1024
0
        cipherNameSz = (int)XSTRLEN(ciphers[i].name);
1025
0
        if (cipherNameSz + 1 < len) {
1026
0
            XSTRNCPY(buf, ciphers[i].name, len);
1027
0
            buf += cipherNameSz;
1028
1029
0
            if (i < ciphersSz - 1)
1030
0
                *buf++ = ':';
1031
0
            *buf = 0;
1032
1033
0
            len -= cipherNameSz + 1;
1034
0
        }
1035
0
        else
1036
0
            return BUFFER_E;
1037
0
    }
1038
0
    return WOLFSSL_SUCCESS;
1039
0
}
1040
1041
1042
#ifndef NO_ERROR_STRINGS
1043
/* places a list of all supported cipher suites in TLS_* format into "buf"
1044
 * return WOLFSSL_SUCCESS on success */
1045
int wolfSSL_get_ciphers_iana(char* buf, int len)
1046
0
{
1047
0
    const CipherSuiteInfo* ciphers = GetCipherNames();
1048
0
    int ciphersSz = GetCipherNamesSize();
1049
0
    int i;
1050
0
    int cipherNameSz;
1051
1052
0
    if (buf == NULL || len <= 0)
1053
0
        return BAD_FUNC_ARG;
1054
1055
    /* Add each member to the buffer delimited by a : */
1056
0
    for (i = 0; i < ciphersSz; i++) {
1057
0
#ifndef NO_CIPHER_SUITE_ALIASES
1058
0
        if (ciphers[i].flags & WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS)
1059
0
            continue;
1060
0
#endif
1061
0
        cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana);
1062
0
        if (cipherNameSz + 1 < len) {
1063
0
            XSTRNCPY(buf, ciphers[i].name_iana, len);
1064
0
            buf += cipherNameSz;
1065
1066
0
            if (i < ciphersSz - 1)
1067
0
                *buf++ = ':';
1068
0
            *buf = 0;
1069
1070
0
            len -= cipherNameSz + 1;
1071
0
        }
1072
0
        else
1073
0
            return BUFFER_E;
1074
0
    }
1075
0
    return WOLFSSL_SUCCESS;
1076
0
}
1077
#endif /* NO_ERROR_STRINGS */
1078
1079
1080
const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len)
1081
0
{
1082
0
    const char* cipher;
1083
1084
0
    if (ssl == NULL)
1085
0
        return NULL;
1086
1087
0
    cipher = wolfSSL_get_cipher_name_iana(ssl);
1088
0
    len = min(len, (int)(XSTRLEN(cipher) + 1));
1089
0
    XMEMCPY(buf, cipher, len);
1090
0
    return buf;
1091
0
}
1092
1093
int wolfSSL_get_fd(const WOLFSSL* ssl)
1094
0
{
1095
0
    int fd = -1;
1096
0
    WOLFSSL_ENTER("SSL_get_fd");
1097
0
    if (ssl) {
1098
0
        fd = ssl->rfd;
1099
0
    }
1100
0
    WOLFSSL_LEAVE("SSL_get_fd", fd);
1101
0
    return fd;
1102
0
}
1103
1104
1105
int wolfSSL_dtls(WOLFSSL* ssl)
1106
0
{
1107
0
    int dtlsOpt = 0;
1108
0
    if (ssl)
1109
0
        dtlsOpt = ssl->options.dtls;
1110
0
    return dtlsOpt;
1111
0
}
1112
1113
#if !defined(NO_CERTS)
1114
/* Set whether mutual authentication is required for connections.
1115
 * Server side only.
1116
 *
1117
 * ctx  The SSL/TLS CTX object.
1118
 * req  1 to indicate required and 0 when not.
1119
 * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and
1120
 * 0 on success.
1121
 */
1122
int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
1123
0
{
1124
0
    if (ctx == NULL)
1125
0
        return BAD_FUNC_ARG;
1126
0
    if (ctx->method->side == WOLFSSL_CLIENT_END)
1127
0
        return SIDE_ERROR;
1128
1129
0
    ctx->mutualAuth = (byte)req;
1130
1131
0
    return 0;
1132
0
}
1133
1134
/* Set whether mutual authentication is required for the connection.
1135
 * Server side only.
1136
 *
1137
 * ssl  The SSL/TLS object.
1138
 * req  1 to indicate required and 0 when not.
1139
 * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3,
1140
 * SIDE_ERROR when not a client and 0 on success.
1141
 */
1142
int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
1143
0
{
1144
0
    if (ssl == NULL)
1145
0
        return BAD_FUNC_ARG;
1146
0
    if (ssl->options.side == WOLFSSL_SERVER_END)
1147
0
        return SIDE_ERROR;
1148
1149
0
    ssl->options.mutualAuth = (word16)req;
1150
1151
0
    return 0;
1152
0
}
1153
#endif /* NO_CERTS */
1154
1155
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
1156
1157
int wolfSSL_CTX_set_AcceptFilter(
1158
    WOLFSSL_CTX *ctx,
1159
    NetworkFilterCallback_t AcceptFilter,
1160
    void *AcceptFilter_arg)
1161
{
1162
    if (ctx == NULL)
1163
        return BAD_FUNC_ARG;
1164
    ctx->AcceptFilter = AcceptFilter;
1165
    ctx->AcceptFilter_arg = AcceptFilter_arg;
1166
    return 0;
1167
}
1168
1169
int wolfSSL_set_AcceptFilter(
1170
    WOLFSSL *ssl,
1171
    NetworkFilterCallback_t AcceptFilter,
1172
    void *AcceptFilter_arg)
1173
{
1174
    if (ssl == NULL)
1175
        return BAD_FUNC_ARG;
1176
    ssl->AcceptFilter = AcceptFilter;
1177
    ssl->AcceptFilter_arg = AcceptFilter_arg;
1178
    return 0;
1179
}
1180
1181
int wolfSSL_CTX_set_ConnectFilter(
1182
    WOLFSSL_CTX *ctx,
1183
    NetworkFilterCallback_t ConnectFilter,
1184
    void *ConnectFilter_arg)
1185
{
1186
    if (ctx == NULL)
1187
        return BAD_FUNC_ARG;
1188
    ctx->ConnectFilter = ConnectFilter;
1189
    ctx->ConnectFilter_arg = ConnectFilter_arg;
1190
    return 0;
1191
}
1192
1193
int wolfSSL_set_ConnectFilter(
1194
    WOLFSSL *ssl,
1195
    NetworkFilterCallback_t ConnectFilter,
1196
    void *ConnectFilter_arg)
1197
{
1198
    if (ssl == NULL)
1199
        return BAD_FUNC_ARG;
1200
    ssl->ConnectFilter = ConnectFilter;
1201
    ssl->ConnectFilter_arg = ConnectFilter_arg;
1202
    return 0;
1203
}
1204
1205
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
1206
1207
#ifndef WOLFSSL_LEANPSK
1208
#if defined(WOLFSSL_DTLS) && defined(XINET_PTON) && \
1209
    !defined(WOLFSSL_NO_SOCK) && defined(HAVE_SOCKADDR)
1210
void* wolfSSL_dtls_create_peer(int port, char* ip)
1211
{
1212
    SOCKADDR_IN *addr;
1213
    addr = (SOCKADDR_IN*)XMALLOC(sizeof(*addr), NULL,
1214
            DYNAMIC_TYPE_SOCKADDR);
1215
    if (addr == NULL) {
1216
        return NULL;
1217
    }
1218
1219
    addr->sin_family = AF_INET;
1220
    addr->sin_port = htons(port);
1221
    if (XINET_PTON(AF_INET, ip, &addr->sin_addr) < 1) {
1222
        XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
1223
        return NULL;
1224
    }
1225
1226
    return addr;
1227
}
1228
1229
int wolfSSL_dtls_free_peer(void* addr)
1230
{
1231
    XFREE(addr, NULL, DYNAMIC_TYPE_SOCKADDR);
1232
    return WOLFSSL_SUCCESS;
1233
}
1234
#endif
1235
1236
int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz)
1237
0
{
1238
#ifdef WOLFSSL_DTLS
1239
    void* sa;
1240
1241
    if (ssl == NULL)
1242
        return WOLFSSL_FAILURE;
1243
1244
    if (peer == NULL || peerSz == 0) {
1245
        if (ssl->buffers.dtlsCtx.peer.sa != NULL)
1246
            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
1247
        ssl->buffers.dtlsCtx.peer.sa = NULL;
1248
        ssl->buffers.dtlsCtx.peer.sz = 0;
1249
        ssl->buffers.dtlsCtx.peer.bufSz = 0;
1250
        ssl->buffers.dtlsCtx.userSet = 0;
1251
        return WOLFSSL_SUCCESS;
1252
    }
1253
1254
    sa = (void*)XMALLOC(peerSz, ssl->heap, DYNAMIC_TYPE_SOCKADDR);
1255
    if (sa != NULL) {
1256
        if (ssl->buffers.dtlsCtx.peer.sa != NULL) {
1257
            XFREE(ssl->buffers.dtlsCtx.peer.sa,ssl->heap,DYNAMIC_TYPE_SOCKADDR);
1258
            ssl->buffers.dtlsCtx.peer.sa = NULL;
1259
        }
1260
        XMEMCPY(sa, peer, peerSz);
1261
        ssl->buffers.dtlsCtx.peer.sa = sa;
1262
        ssl->buffers.dtlsCtx.peer.sz = peerSz;
1263
        ssl->buffers.dtlsCtx.peer.bufSz = peerSz;
1264
        ssl->buffers.dtlsCtx.userSet = 1;
1265
        return WOLFSSL_SUCCESS;
1266
    }
1267
    return WOLFSSL_FAILURE;
1268
#else
1269
0
    (void)ssl;
1270
0
    (void)peer;
1271
0
    (void)peerSz;
1272
0
    return WOLFSSL_NOT_IMPLEMENTED;
1273
0
#endif
1274
0
}
1275
1276
int wolfSSL_dtls_get_peer(WOLFSSL* ssl, void* peer, unsigned int* peerSz)
1277
0
{
1278
#ifdef WOLFSSL_DTLS
1279
    if (ssl == NULL) {
1280
        return WOLFSSL_FAILURE;
1281
    }
1282
1283
    if (peer != NULL && peerSz != NULL
1284
            && *peerSz >= ssl->buffers.dtlsCtx.peer.sz
1285
            && ssl->buffers.dtlsCtx.peer.sa != NULL) {
1286
        *peerSz = ssl->buffers.dtlsCtx.peer.sz;
1287
        XMEMCPY(peer, ssl->buffers.dtlsCtx.peer.sa, *peerSz);
1288
        return WOLFSSL_SUCCESS;
1289
    }
1290
    return WOLFSSL_FAILURE;
1291
#else
1292
0
    (void)ssl;
1293
0
    (void)peer;
1294
0
    (void)peerSz;
1295
0
    return WOLFSSL_NOT_IMPLEMENTED;
1296
0
#endif
1297
0
}
1298
1299
1300
#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS)
1301
1302
int wolfSSL_CTX_dtls_set_sctp(WOLFSSL_CTX* ctx)
1303
{
1304
    WOLFSSL_ENTER("wolfSSL_CTX_dtls_set_sctp()");
1305
1306
    if (ctx == NULL)
1307
        return BAD_FUNC_ARG;
1308
1309
    ctx->dtlsSctp = 1;
1310
    return WOLFSSL_SUCCESS;
1311
}
1312
1313
1314
int wolfSSL_dtls_set_sctp(WOLFSSL* ssl)
1315
{
1316
    WOLFSSL_ENTER("wolfSSL_dtls_set_sctp()");
1317
1318
    if (ssl == NULL)
1319
        return BAD_FUNC_ARG;
1320
1321
    ssl->options.dtlsSctp = 1;
1322
    return WOLFSSL_SUCCESS;
1323
}
1324
1325
#endif /* WOLFSSL_DTLS && WOLFSSL_SCTP */
1326
1327
#if (defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)) && \
1328
                                                           defined(WOLFSSL_DTLS)
1329
1330
int wolfSSL_CTX_dtls_set_mtu(WOLFSSL_CTX* ctx, word16 newMtu)
1331
{
1332
    if (ctx == NULL || newMtu > MAX_RECORD_SIZE)
1333
        return BAD_FUNC_ARG;
1334
1335
    ctx->dtlsMtuSz = newMtu;
1336
    return WOLFSSL_SUCCESS;
1337
}
1338
1339
1340
int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu)
1341
{
1342
    if (ssl == NULL)
1343
        return BAD_FUNC_ARG;
1344
1345
    if (newMtu > MAX_RECORD_SIZE) {
1346
        ssl->error = BAD_FUNC_ARG;
1347
        return WOLFSSL_FAILURE;
1348
    }
1349
1350
    ssl->dtlsMtuSz = newMtu;
1351
    return WOLFSSL_SUCCESS;
1352
}
1353
1354
#endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */
1355
1356
#ifdef WOLFSSL_SRTP
1357
1358
static const WOLFSSL_SRTP_PROTECTION_PROFILE gSrtpProfiles[] = {
1359
    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 80-bits
1360
     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
1361
    {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, (((128 + 112) * 2) / 8) },
1362
    /* AES CCM 128, Salt:112-bits, Auth HMAC-SHA1 Tag: 32-bits
1363
     * (master_key:128bits + master_salt:112bits) * 2 = 480 bits (60) */
1364
    {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, (((128 + 112) * 2) / 8) },
1365
    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 80-bits */
1366
    {"SRTP_NULL_SHA1_80", SRTP_NULL_SHA1_80, ((112 * 2) / 8)},
1367
    /* NULL Cipher, Salt:112-bits, Auth HMAC-SHA1 Tag 32-bits */
1368
    {"SRTP_NULL_SHA1_32", SRTP_NULL_SHA1_32, ((112 * 2) / 8)},
1369
    /* AES GCM 128, Salt: 96-bits, Auth GCM Tag 128-bits
1370
     * (master_key:128bits + master_salt:96bits) * 2 = 448 bits (56) */
1371
    {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, (((128 + 96) * 2) / 8) },
1372
    /* AES GCM 256, Salt: 96-bits, Auth GCM Tag 128-bits
1373
     * (master_key:256bits + master_salt:96bits) * 2 = 704 bits (88) */
1374
    {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, (((256 + 96) * 2) / 8) },
1375
};
1376
1377
static const WOLFSSL_SRTP_PROTECTION_PROFILE* DtlsSrtpFindProfile(
1378
    const char* profile_str, word32 profile_str_len, unsigned long id)
1379
{
1380
    int i;
1381
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1382
    for (i=0;
1383
         i<(int)(sizeof(gSrtpProfiles)/sizeof(WOLFSSL_SRTP_PROTECTION_PROFILE));
1384
         i++) {
1385
        if (profile_str != NULL) {
1386
            word32 srtp_profile_len = (word32)XSTRLEN(gSrtpProfiles[i].name);
1387
            if (srtp_profile_len == profile_str_len &&
1388
                XMEMCMP(gSrtpProfiles[i].name, profile_str, profile_str_len)
1389
                                                                         == 0) {
1390
                profile = &gSrtpProfiles[i];
1391
                break;
1392
            }
1393
        }
1394
        else if (id != 0 && gSrtpProfiles[i].id == id) {
1395
            profile = &gSrtpProfiles[i];
1396
            break;
1397
        }
1398
    }
1399
    return profile;
1400
}
1401
1402
/* profile_str: accepts ":" colon separated list of SRTP profiles */
1403
static int DtlsSrtpSelProfiles(word16* id, const char* profile_str)
1404
{
1405
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile;
1406
    const char *current, *next = NULL;
1407
    word32 length = 0, current_length;
1408
1409
    *id = 0; /* reset destination ID's */
1410
1411
    if (profile_str == NULL) {
1412
        return WOLFSSL_FAILURE;
1413
    }
1414
1415
    /* loop on end of line or colon ":" */
1416
    next = profile_str;
1417
    length = (word32)XSTRLEN(profile_str);
1418
    do {
1419
        current = next;
1420
        next = XSTRSTR(current, ":");
1421
        current_length = (!next) ? (word32)XSTRLEN(current)
1422
                                 : (word32)(next - current);
1423
        if (current_length < length)
1424
            length = current_length;
1425
        profile = DtlsSrtpFindProfile(current, current_length, 0);
1426
        if (profile != NULL) {
1427
            *id |= (1 << profile->id); /* selected bit based on ID */
1428
        }
1429
    } while (next != NULL && next++); /* ++ needed to skip ':' */
1430
    return WOLFSSL_SUCCESS;
1431
}
1432
1433
int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str)
1434
{
1435
    int ret = WOLFSSL_FAILURE;
1436
    if (ctx != NULL) {
1437
        ret = DtlsSrtpSelProfiles(&ctx->dtlsSrtpProfiles, profile_str);
1438
    }
1439
    return ret;
1440
}
1441
int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str)
1442
{
1443
    int ret = WOLFSSL_FAILURE;
1444
    if (ssl != NULL) {
1445
        ret = DtlsSrtpSelProfiles(&ssl->dtlsSrtpProfiles, profile_str);
1446
    }
1447
    return ret;
1448
}
1449
1450
const WOLFSSL_SRTP_PROTECTION_PROFILE* wolfSSL_get_selected_srtp_profile(
1451
    WOLFSSL* ssl)
1452
{
1453
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1454
    if (ssl) {
1455
        profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
1456
    }
1457
    return profile;
1458
}
1459
#ifndef NO_WOLFSSL_STUB
1460
WOLF_STACK_OF(WOLFSSL_SRTP_PROTECTION_PROFILE)* wolfSSL_get_srtp_profiles(
1461
    WOLFSSL* ssl)
1462
{
1463
    /* Not yet implemented - should return list of available SRTP profiles
1464
     * ssl->dtlsSrtpProfiles */
1465
    (void)ssl;
1466
    return NULL;
1467
}
1468
#endif
1469
1470
int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl,
1471
    unsigned char* out, size_t* olen)
1472
{
1473
    int ret = WOLFSSL_FAILURE;
1474
    const char* label = "EXTRACTOR-dtls_srtp";
1475
    const WOLFSSL_SRTP_PROTECTION_PROFILE* profile = NULL;
1476
    byte seed[SEED_LEN];
1477
1478
    if (ssl == NULL || olen == NULL) {
1479
        return BAD_FUNC_ARG;
1480
    }
1481
1482
    profile = DtlsSrtpFindProfile(NULL, 0, ssl->dtlsSrtpId);
1483
    if (profile == NULL) {
1484
        WOLFSSL_MSG("Not using DTLS SRTP");
1485
        return EXT_MISSING;
1486
    }
1487
    if (out == NULL) {
1488
        *olen = profile->kdfBits;
1489
        return LENGTH_ONLY_E;
1490
    }
1491
1492
    if (*olen < (size_t)profile->kdfBits) {
1493
        return BUFFER_E;
1494
    }
1495
1496
#ifdef WOLFSSL_HAVE_PRF
1497
    XMEMCPY(seed, ssl->arrays->clientRandom, RAN_LEN);
1498
    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
1499
1500
    PRIVATE_KEY_UNLOCK();
1501
    ret = wc_PRF_TLS(out, profile->kdfBits,   /* out: generated keys / salt */
1502
        ssl->arrays->masterSecret, SECRET_LEN,  /* existing master secret */
1503
        (const byte*)label, (int)XSTRLEN(label),/* label */
1504
        seed, SEED_LEN,                         /* seed: client/server random */
1505
        IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm,
1506
        ssl->heap, INVALID_DEVID);
1507
    if (ret == 0) {
1508
        *olen = profile->kdfBits;
1509
        ret = WOLFSSL_SUCCESS;
1510
    }
1511
    PRIVATE_KEY_LOCK();
1512
#else
1513
    /* Pseudo random function must be enabled in the configuration */
1514
    ret = PRF_MISSING;
1515
#endif
1516
1517
    return ret;
1518
}
1519
1520
#endif /* WOLFSSL_SRTP */
1521
1522
1523
#ifdef WOLFSSL_DTLS_DROP_STATS
1524
1525
int wolfSSL_dtls_get_drop_stats(WOLFSSL* ssl,
1526
                                word32* macDropCount, word32* replayDropCount)
1527
{
1528
    int ret;
1529
1530
    WOLFSSL_ENTER("wolfSSL_dtls_get_drop_stats()");
1531
1532
    if (ssl == NULL)
1533
        ret = BAD_FUNC_ARG;
1534
    else {
1535
        ret = WOLFSSL_SUCCESS;
1536
        if (macDropCount != NULL)
1537
            *macDropCount = ssl->macDropCount;
1538
        if (replayDropCount != NULL)
1539
            *replayDropCount = ssl->replayDropCount;
1540
    }
1541
1542
    WOLFSSL_LEAVE("wolfSSL_dtls_get_drop_stats()", ret);
1543
    return ret;
1544
}
1545
1546
#endif /* WOLFSSL_DTLS_DROP_STATS */
1547
1548
1549
#if defined(WOLFSSL_MULTICAST)
1550
1551
int wolfSSL_CTX_mcast_set_member_id(WOLFSSL_CTX* ctx, word16 id)
1552
{
1553
    int ret = 0;
1554
1555
    WOLFSSL_ENTER("wolfSSL_CTX_mcast_set_member_id()");
1556
1557
    if (ctx == NULL || id > 255)
1558
        ret = BAD_FUNC_ARG;
1559
1560
    if (ret == 0) {
1561
        ctx->haveEMS = 0;
1562
        ctx->haveMcast = 1;
1563
        ctx->mcastID = (byte)id;
1564
#ifndef WOLFSSL_USER_IO
1565
        ctx->CBIORecv = EmbedReceiveFromMcast;
1566
#endif /* WOLFSSL_USER_IO */
1567
1568
        ret = WOLFSSL_SUCCESS;
1569
    }
1570
    WOLFSSL_LEAVE("wolfSSL_CTX_mcast_set_member_id()", ret);
1571
    return ret;
1572
}
1573
1574
int wolfSSL_mcast_get_max_peers(void)
1575
{
1576
    return WOLFSSL_MULTICAST_PEERS;
1577
}
1578
1579
#ifdef WOLFSSL_DTLS
1580
static WC_INLINE word32 UpdateHighwaterMark(word32 cur, word32 first,
1581
                                         word32 second, word32 high)
1582
{
1583
    word32 newCur = 0;
1584
1585
    if (cur < first)
1586
        newCur = first;
1587
    else if (cur < second)
1588
        newCur = second;
1589
    else if (cur < high)
1590
        newCur = high;
1591
1592
    return newCur;
1593
}
1594
#endif /* WOLFSSL_DTLS */
1595
1596
1597
int wolfSSL_set_secret(WOLFSSL* ssl, word16 epoch,
1598
                       const byte* preMasterSecret, word32 preMasterSz,
1599
                       const byte* clientRandom, const byte* serverRandom,
1600
                       const byte* suite)
1601
{
1602
    int ret = 0;
1603
1604
    WOLFSSL_ENTER("wolfSSL_set_secret()");
1605
1606
    if (ssl == NULL || preMasterSecret == NULL ||
1607
        preMasterSz == 0 || preMasterSz > ENCRYPT_LEN ||
1608
        clientRandom == NULL || serverRandom == NULL || suite == NULL) {
1609
1610
        ret = BAD_FUNC_ARG;
1611
    }
1612
1613
    if (ret == 0 && ssl->arrays->preMasterSecret == NULL) {
1614
        ssl->arrays->preMasterSz = ENCRYPT_LEN;
1615
        ssl->arrays->preMasterSecret = (byte*)XMALLOC(ENCRYPT_LEN, ssl->heap,
1616
            DYNAMIC_TYPE_SECRET);
1617
        if (ssl->arrays->preMasterSecret == NULL) {
1618
            ret = MEMORY_E;
1619
        }
1620
    }
1621
1622
    if (ret == 0) {
1623
        XMEMCPY(ssl->arrays->preMasterSecret, preMasterSecret, preMasterSz);
1624
        XMEMSET(ssl->arrays->preMasterSecret + preMasterSz, 0, ENCRYPT_LEN - preMasterSz);
1625
        ssl->arrays->preMasterSz = preMasterSz;
1626
        XMEMCPY(ssl->arrays->clientRandom, clientRandom, RAN_LEN);
1627
        XMEMCPY(ssl->arrays->serverRandom, serverRandom, RAN_LEN);
1628
        ssl->options.cipherSuite0 = suite[0];
1629
        ssl->options.cipherSuite = suite[1];
1630
1631
        ret = SetCipherSpecs(ssl);
1632
    }
1633
1634
    if (ret == 0)
1635
        ret = MakeTlsMasterSecret(ssl);
1636
1637
    if (ret == 0) {
1638
        ssl->keys.encryptionOn = 1;
1639
        ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE);
1640
    }
1641
1642
    if (ret == 0) {
1643
        if (ssl->options.dtls) {
1644
        #ifdef WOLFSSL_DTLS
1645
            WOLFSSL_DTLS_PEERSEQ* peerSeq;
1646
            int i;
1647
1648
            ssl->keys.dtls_epoch = epoch;
1649
            for (i = 0, peerSeq = ssl->keys.peerSeq;
1650
                 i < WOLFSSL_DTLS_PEERSEQ_SZ;
1651
                 i++, peerSeq++) {
1652
1653
                peerSeq->nextEpoch = epoch;
1654
                peerSeq->prevSeq_lo = peerSeq->nextSeq_lo;
1655
                peerSeq->prevSeq_hi = peerSeq->nextSeq_hi;
1656
                peerSeq->nextSeq_lo = 0;
1657
                peerSeq->nextSeq_hi = 0;
1658
                XMEMCPY(peerSeq->prevWindow, peerSeq->window, DTLS_SEQ_SZ);
1659
                XMEMSET(peerSeq->window, 0, DTLS_SEQ_SZ);
1660
                peerSeq->highwaterMark = UpdateHighwaterMark(0,
1661
                        ssl->ctx->mcastFirstSeq,
1662
                        ssl->ctx->mcastSecondSeq,
1663
                        ssl->ctx->mcastMaxSeq);
1664
            }
1665
        #else
1666
            (void)epoch;
1667
        #endif
1668
        }
1669
        FreeHandshakeResources(ssl);
1670
        ret = WOLFSSL_SUCCESS;
1671
    }
1672
    else {
1673
        if (ssl)
1674
            ssl->error = ret;
1675
        ret = WOLFSSL_FATAL_ERROR;
1676
    }
1677
    WOLFSSL_LEAVE("wolfSSL_set_secret()", ret);
1678
    return ret;
1679
}
1680
1681
1682
#ifdef WOLFSSL_DTLS
1683
1684
int wolfSSL_mcast_peer_add(WOLFSSL* ssl, word16 peerId, int sub)
1685
{
1686
    WOLFSSL_DTLS_PEERSEQ* p = NULL;
1687
    int ret = WOLFSSL_SUCCESS;
1688
    int i;
1689
1690
    WOLFSSL_ENTER("wolfSSL_mcast_peer_add()");
1691
    if (ssl == NULL || peerId > 255)
1692
        return BAD_FUNC_ARG;
1693
1694
    if (!sub) {
1695
        /* Make sure it isn't already present, while keeping the first
1696
         * open spot. */
1697
        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1698
            if (ssl->keys.peerSeq[i].peerId == INVALID_PEER_ID)
1699
                p = &ssl->keys.peerSeq[i];
1700
            if (ssl->keys.peerSeq[i].peerId == peerId) {
1701
                WOLFSSL_MSG("Peer ID already in multicast peer list.");
1702
                p = NULL;
1703
            }
1704
        }
1705
1706
        if (p != NULL) {
1707
            XMEMSET(p, 0, sizeof(WOLFSSL_DTLS_PEERSEQ));
1708
            p->peerId = peerId;
1709
            p->highwaterMark = UpdateHighwaterMark(0,
1710
                ssl->ctx->mcastFirstSeq,
1711
                ssl->ctx->mcastSecondSeq,
1712
                ssl->ctx->mcastMaxSeq);
1713
        }
1714
        else {
1715
            WOLFSSL_MSG("No room in peer list.");
1716
            ret = -1;
1717
        }
1718
    }
1719
    else {
1720
        for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1721
            if (ssl->keys.peerSeq[i].peerId == peerId)
1722
                p = &ssl->keys.peerSeq[i];
1723
        }
1724
1725
        if (p != NULL) {
1726
            p->peerId = INVALID_PEER_ID;
1727
        }
1728
        else {
1729
            WOLFSSL_MSG("Peer not found in list.");
1730
        }
1731
    }
1732
1733
    WOLFSSL_LEAVE("wolfSSL_mcast_peer_add()", ret);
1734
    return ret;
1735
}
1736
1737
1738
/* If peerId is in the list of peers and its last sequence number is non-zero,
1739
 * return 1, otherwise return 0. */
1740
int wolfSSL_mcast_peer_known(WOLFSSL* ssl, unsigned short peerId)
1741
{
1742
    int known = 0;
1743
    int i;
1744
1745
    WOLFSSL_ENTER("wolfSSL_mcast_peer_known()");
1746
1747
    if (ssl == NULL || peerId > 255) {
1748
        return BAD_FUNC_ARG;
1749
    }
1750
1751
    for (i = 0; i < WOLFSSL_DTLS_PEERSEQ_SZ; i++) {
1752
        if (ssl->keys.peerSeq[i].peerId == peerId) {
1753
            if (ssl->keys.peerSeq[i].nextSeq_hi ||
1754
                ssl->keys.peerSeq[i].nextSeq_lo) {
1755
1756
                known = 1;
1757
            }
1758
            break;
1759
        }
1760
    }
1761
1762
    WOLFSSL_LEAVE("wolfSSL_mcast_peer_known()", known);
1763
    return known;
1764
}
1765
1766
1767
int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX* ctx, word32 maxSeq,
1768
                                       word32 first, word32 second,
1769
                                       CallbackMcastHighwater cb)
1770
{
1771
    if (ctx == NULL || (second && first > second) ||
1772
        first > maxSeq || second > maxSeq || cb == NULL) {
1773
1774
        return BAD_FUNC_ARG;
1775
    }
1776
1777
    ctx->mcastHwCb = cb;
1778
    ctx->mcastFirstSeq = first;
1779
    ctx->mcastSecondSeq = second;
1780
    ctx->mcastMaxSeq = maxSeq;
1781
1782
    return WOLFSSL_SUCCESS;
1783
}
1784
1785
1786
int wolfSSL_mcast_set_highwater_ctx(WOLFSSL* ssl, void* ctx)
1787
{
1788
    if (ssl == NULL || ctx == NULL)
1789
        return BAD_FUNC_ARG;
1790
1791
    ssl->mcastHwCbCtx = ctx;
1792
1793
    return WOLFSSL_SUCCESS;
1794
}
1795
1796
#endif /* WOLFSSL_DTLS */
1797
1798
#endif /* WOLFSSL_MULTICAST */
1799
1800
1801
#endif /* WOLFSSL_LEANPSK */
1802
1803
1804
/* return underlying connect or accept, WOLFSSL_SUCCESS on ok */
1805
int wolfSSL_negotiate(WOLFSSL* ssl)
1806
0
{
1807
0
    int err = WOLFSSL_FATAL_ERROR;
1808
1809
0
    WOLFSSL_ENTER("wolfSSL_negotiate");
1810
1811
0
    if (ssl == NULL)
1812
0
        return WOLFSSL_FATAL_ERROR;
1813
1814
0
#ifndef NO_WOLFSSL_SERVER
1815
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
1816
0
#ifdef WOLFSSL_TLS13
1817
0
        if (IsAtLeastTLSv1_3(ssl->version))
1818
0
            err = wolfSSL_accept_TLSv13(ssl);
1819
0
        else
1820
0
#endif
1821
0
            err = wolfSSL_accept(ssl);
1822
0
    }
1823
0
#endif
1824
1825
0
#ifndef NO_WOLFSSL_CLIENT
1826
0
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
1827
0
#ifdef WOLFSSL_TLS13
1828
0
        if (IsAtLeastTLSv1_3(ssl->version))
1829
0
            err = wolfSSL_connect_TLSv13(ssl);
1830
0
        else
1831
0
#endif
1832
0
            err = wolfSSL_connect(ssl);
1833
0
    }
1834
0
#endif
1835
1836
0
    (void)ssl;
1837
1838
0
    WOLFSSL_LEAVE("wolfSSL_negotiate", err);
1839
1840
0
    return err;
1841
0
}
1842
1843
1844
WOLFSSL_ABI
1845
WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl)
1846
0
{
1847
0
    if (ssl) {
1848
0
        return ssl->rng;
1849
0
    }
1850
1851
0
    return NULL;
1852
0
}
1853
1854
1855
#ifndef WOLFSSL_LEANPSK
1856
/* object size based on build */
1857
int wolfSSL_GetObjectSize(void)
1858
0
{
1859
#ifdef SHOW_SIZES
1860
    printf("sizeof suites           = %lu\n", (unsigned long)sizeof(Suites));
1861
    printf("sizeof ciphers(2)       = %lu\n", (unsigned long)sizeof(Ciphers));
1862
#ifndef NO_RC4
1863
    printf("\tsizeof arc4         = %lu\n", (unsigned long)sizeof(Arc4));
1864
#endif
1865
    printf("\tsizeof aes          = %lu\n", (unsigned long)sizeof(Aes));
1866
#ifndef NO_DES3
1867
    printf("\tsizeof des3         = %lu\n", (unsigned long)sizeof(Des3));
1868
#endif
1869
#ifdef HAVE_CHACHA
1870
    printf("\tsizeof chacha       = %lu\n", (unsigned long)sizeof(ChaCha));
1871
#endif
1872
    printf("sizeof cipher specs     = %lu\n", (unsigned long)sizeof(CipherSpecs));
1873
    printf("sizeof keys             = %lu\n", (unsigned long)sizeof(Keys));
1874
    printf("sizeof Hashes(2)        = %lu\n", (unsigned long)sizeof(Hashes));
1875
#ifndef NO_MD5
1876
    printf("\tsizeof MD5          = %lu\n", (unsigned long)sizeof(wc_Md5));
1877
#endif
1878
#ifndef NO_SHA
1879
    printf("\tsizeof SHA          = %lu\n", (unsigned long)sizeof(wc_Sha));
1880
#endif
1881
#ifdef WOLFSSL_SHA224
1882
    printf("\tsizeof SHA224       = %lu\n", (unsigned long)sizeof(wc_Sha224));
1883
#endif
1884
#ifndef NO_SHA256
1885
    printf("\tsizeof SHA256       = %lu\n", (unsigned long)sizeof(wc_Sha256));
1886
#endif
1887
#ifdef WOLFSSL_SHA384
1888
    printf("\tsizeof SHA384       = %lu\n", (unsigned long)sizeof(wc_Sha384));
1889
#endif
1890
#ifdef WOLFSSL_SHA384
1891
    printf("\tsizeof SHA512       = %lu\n", (unsigned long)sizeof(wc_Sha512));
1892
#endif
1893
    printf("sizeof Buffers          = %lu\n", (unsigned long)sizeof(Buffers));
1894
    printf("sizeof Options          = %lu\n", (unsigned long)sizeof(Options));
1895
    printf("sizeof Arrays           = %lu\n", (unsigned long)sizeof(Arrays));
1896
#ifndef NO_RSA
1897
    printf("sizeof RsaKey           = %lu\n", (unsigned long)sizeof(RsaKey));
1898
#endif
1899
#ifdef HAVE_ECC
1900
    printf("sizeof ecc_key          = %lu\n", (unsigned long)sizeof(ecc_key));
1901
#endif
1902
    printf("sizeof WOLFSSL_CIPHER    = %lu\n", (unsigned long)sizeof(WOLFSSL_CIPHER));
1903
    printf("sizeof WOLFSSL_SESSION   = %lu\n", (unsigned long)sizeof(WOLFSSL_SESSION));
1904
    printf("sizeof WOLFSSL           = %lu\n", (unsigned long)sizeof(WOLFSSL));
1905
    printf("sizeof WOLFSSL_CTX       = %lu\n", (unsigned long)sizeof(WOLFSSL_CTX));
1906
#endif
1907
1908
0
    return sizeof(WOLFSSL);
1909
0
}
1910
1911
int wolfSSL_CTX_GetObjectSize(void)
1912
0
{
1913
0
    return sizeof(WOLFSSL_CTX);
1914
0
}
1915
1916
int wolfSSL_METHOD_GetObjectSize(void)
1917
0
{
1918
0
    return sizeof(WOLFSSL_METHOD);
1919
0
}
1920
#endif
1921
1922
1923
#ifdef WOLFSSL_STATIC_MEMORY
1924
1925
int wolfSSL_CTX_load_static_memory(WOLFSSL_CTX** ctx, wolfSSL_method_func method,
1926
                                   unsigned char* buf, unsigned int sz,
1927
                                   int flag, int maxSz)
1928
{
1929
    WOLFSSL_HEAP*      heap;
1930
    WOLFSSL_HEAP_HINT* hint;
1931
    word32 idx = 0;
1932
1933
    if (ctx == NULL || buf == NULL) {
1934
        return BAD_FUNC_ARG;
1935
    }
1936
1937
    if (*ctx == NULL && method == NULL) {
1938
        return BAD_FUNC_ARG;
1939
    }
1940
1941
    if (*ctx == NULL || (*ctx)->heap == NULL) {
1942
        if (sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT) > sz - idx) {
1943
            return BUFFER_E; /* not enough memory for structures */
1944
        }
1945
        heap = (WOLFSSL_HEAP*)buf;
1946
        idx += sizeof(WOLFSSL_HEAP);
1947
        if (wolfSSL_init_memory_heap(heap) != 0) {
1948
            return WOLFSSL_FAILURE;
1949
        }
1950
        hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
1951
        idx += sizeof(WOLFSSL_HEAP_HINT);
1952
        XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
1953
        hint->memory = heap;
1954
1955
        if (*ctx && (*ctx)->heap == NULL) {
1956
            (*ctx)->heap = (void*)hint;
1957
        }
1958
    }
1959
    else {
1960
#ifdef WOLFSSL_HEAP_TEST
1961
        /* do not load in memory if test has been set */
1962
        if ((*ctx)->heap == (void*)WOLFSSL_HEAP_TEST) {
1963
            return WOLFSSL_SUCCESS;
1964
        }
1965
#endif
1966
        hint = (WOLFSSL_HEAP_HINT*)((*ctx)->heap);
1967
        heap = hint->memory;
1968
    }
1969
1970
    if (wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap) != 1) {
1971
        WOLFSSL_MSG("Error partitioning memory");
1972
        return WOLFSSL_FAILURE;
1973
    }
1974
1975
    /* create ctx if needed */
1976
    if (*ctx == NULL) {
1977
        *ctx = wolfSSL_CTX_new_ex(method(hint), hint);
1978
        if (*ctx == NULL) {
1979
            WOLFSSL_MSG("Error creating ctx");
1980
            return WOLFSSL_FAILURE;
1981
        }
1982
    }
1983
1984
    /* determine what max applies too */
1985
    if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
1986
        heap->maxIO = maxSz;
1987
    }
1988
    else { /* general memory used in handshakes */
1989
        heap->maxHa = maxSz;
1990
    }
1991
1992
    heap->flag |= flag;
1993
1994
    (void)maxSz;
1995
    (void)method;
1996
1997
    return WOLFSSL_SUCCESS;
1998
}
1999
2000
2001
int wolfSSL_is_static_memory(WOLFSSL* ssl, WOLFSSL_MEM_CONN_STATS* mem_stats)
2002
{
2003
    if (ssl == NULL) {
2004
        return BAD_FUNC_ARG;
2005
    }
2006
    WOLFSSL_ENTER("wolfSSL_is_static_memory");
2007
2008
    /* fill out statistics if wanted and WOLFMEM_TRACK_STATS flag */
2009
    if (mem_stats != NULL && ssl->heap != NULL) {
2010
        WOLFSSL_HEAP_HINT* hint = ((WOLFSSL_HEAP_HINT*)(ssl->heap));
2011
        WOLFSSL_HEAP* heap      = hint->memory;
2012
        if (heap->flag & WOLFMEM_TRACK_STATS && hint->stats != NULL) {
2013
            XMEMCPY(mem_stats, hint->stats, sizeof(WOLFSSL_MEM_CONN_STATS));
2014
        }
2015
    }
2016
2017
    return (ssl->heap) ? 1 : 0;
2018
}
2019
2020
2021
int wolfSSL_CTX_is_static_memory(WOLFSSL_CTX* ctx, WOLFSSL_MEM_STATS* mem_stats)
2022
{
2023
    if (ctx == NULL) {
2024
        return BAD_FUNC_ARG;
2025
    }
2026
    WOLFSSL_ENTER("wolfSSL_CTX_is_static_memory");
2027
2028
    /* fill out statistics if wanted */
2029
    if (mem_stats != NULL && ctx->heap != NULL) {
2030
        WOLFSSL_HEAP* heap = ((WOLFSSL_HEAP_HINT*)(ctx->heap))->memory;
2031
        if (wolfSSL_GetMemStats(heap, mem_stats) != 1) {
2032
            return MEMORY_E;
2033
        }
2034
    }
2035
2036
    return (ctx->heap) ? 1 : 0;
2037
}
2038
2039
#endif /* WOLFSSL_STATIC_MEMORY */
2040
2041
2042
/* return max record layer size plaintext input size */
2043
int wolfSSL_GetMaxOutputSize(WOLFSSL* ssl)
2044
0
{
2045
0
    WOLFSSL_ENTER("wolfSSL_GetMaxOutputSize");
2046
2047
0
    if (ssl == NULL)
2048
0
        return BAD_FUNC_ARG;
2049
2050
0
    if (ssl->options.handShakeState != HANDSHAKE_DONE) {
2051
0
        WOLFSSL_MSG("Handshake not complete yet");
2052
0
        return BAD_FUNC_ARG;
2053
0
    }
2054
2055
0
    return wolfSSL_GetMaxFragSize(ssl, OUTPUT_RECORD_SIZE);
2056
0
}
2057
2058
2059
/* return record layer size of plaintext input size */
2060
int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz)
2061
0
{
2062
0
    int maxSize;
2063
2064
0
    WOLFSSL_ENTER("wolfSSL_GetOutputSize");
2065
2066
0
    if (inSz < 0)
2067
0
        return BAD_FUNC_ARG;
2068
2069
0
    maxSize = wolfSSL_GetMaxOutputSize(ssl);
2070
0
    if (maxSize < 0)
2071
0
        return maxSize;   /* error */
2072
0
    if (inSz > maxSize)
2073
0
        return INPUT_SIZE_E;
2074
2075
0
    return BuildMessage(ssl, NULL, 0, NULL, inSz, application_data, 0, 1, 0, CUR_ORDER);
2076
0
}
2077
2078
2079
#ifdef HAVE_ECC
2080
int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2081
0
{
2082
0
    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
2083
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
2084
0
        return BAD_FUNC_ARG;
2085
0
    }
2086
2087
0
    ctx->minEccKeySz     = keySz / 8;
2088
0
#ifndef NO_CERTS
2089
0
    ctx->cm->minEccKeySz = keySz / 8;
2090
0
#endif
2091
0
    return WOLFSSL_SUCCESS;
2092
0
}
2093
2094
2095
int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz)
2096
0
{
2097
0
    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
2098
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
2099
0
        return BAD_FUNC_ARG;
2100
0
    }
2101
2102
0
    ssl->options.minEccKeySz = keySz / 8;
2103
0
    return WOLFSSL_SUCCESS;
2104
0
}
2105
2106
#endif /* HAVE_ECC */
2107
2108
#ifndef NO_RSA
2109
int wolfSSL_CTX_SetMinRsaKey_Sz(WOLFSSL_CTX* ctx, short keySz)
2110
0
{
2111
0
    if (ctx == NULL || keySz < 0 || keySz % 8 != 0) {
2112
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null");
2113
0
        return BAD_FUNC_ARG;
2114
0
    }
2115
2116
0
    ctx->minRsaKeySz     = keySz / 8;
2117
0
    ctx->cm->minRsaKeySz = keySz / 8;
2118
0
    return WOLFSSL_SUCCESS;
2119
0
}
2120
2121
2122
int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
2123
0
{
2124
0
    if (ssl == NULL || keySz < 0 || keySz % 8 != 0) {
2125
0
        WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null");
2126
0
        return BAD_FUNC_ARG;
2127
0
    }
2128
2129
0
    ssl->options.minRsaKeySz = keySz / 8;
2130
0
    return WOLFSSL_SUCCESS;
2131
0
}
2132
#endif /* !NO_RSA */
2133
2134
#ifndef NO_DH
2135
/* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
2136
int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
2137
                    const unsigned char* g, int gSz)
2138
0
{
2139
0
    WOLFSSL_ENTER("wolfSSL_SetTmpDH");
2140
2141
0
    if (ssl == NULL || p == NULL || g == NULL)
2142
0
        return BAD_FUNC_ARG;
2143
2144
0
    if ((word16)pSz < ssl->options.minDhKeySz)
2145
0
        return DH_KEY_SIZE_E;
2146
0
    if ((word16)pSz > ssl->options.maxDhKeySz)
2147
0
        return DH_KEY_SIZE_E;
2148
2149
    /* this function is for server only */
2150
0
    if (ssl->options.side == WOLFSSL_CLIENT_END)
2151
0
        return SIDE_ERROR;
2152
2153
0
    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2154
0
        !defined(HAVE_SELFTEST)
2155
0
        ssl->options.dhKeyTested = 0;
2156
0
        ssl->options.dhDoKeyTest = 1;
2157
0
    #endif
2158
2159
0
    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
2160
0
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2161
0
        ssl->buffers.serverDH_P.buffer = NULL;
2162
0
    }
2163
0
    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
2164
0
        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2165
0
        ssl->buffers.serverDH_G.buffer = NULL;
2166
0
    }
2167
2168
0
    ssl->buffers.weOwnDH = 1;  /* SSL owns now */
2169
0
    ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, ssl->heap,
2170
0
                                                    DYNAMIC_TYPE_PUBLIC_KEY);
2171
0
    if (ssl->buffers.serverDH_P.buffer == NULL)
2172
0
            return MEMORY_E;
2173
2174
0
    ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, ssl->heap,
2175
0
                                                    DYNAMIC_TYPE_PUBLIC_KEY);
2176
0
    if (ssl->buffers.serverDH_G.buffer == NULL) {
2177
0
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2178
0
        ssl->buffers.serverDH_P.buffer = NULL;
2179
0
        return MEMORY_E;
2180
0
    }
2181
2182
0
    ssl->buffers.serverDH_P.length = pSz;
2183
0
    ssl->buffers.serverDH_G.length = gSz;
2184
2185
0
    XMEMCPY(ssl->buffers.serverDH_P.buffer, p, pSz);
2186
0
    XMEMCPY(ssl->buffers.serverDH_G.buffer, g, gSz);
2187
2188
0
    ssl->options.haveDH = 1;
2189
2190
0
    if (ssl->options.side != WOLFSSL_NEITHER_END) {
2191
0
        word16 havePSK;
2192
0
        word16 haveRSA;
2193
0
        int    keySz   = 0;
2194
2195
    #ifndef NO_PSK
2196
        havePSK = ssl->options.havePSK;
2197
    #else
2198
0
        havePSK = 0;
2199
0
    #endif
2200
    #ifdef NO_RSA
2201
        haveRSA = 0;
2202
    #else
2203
0
        haveRSA = 1;
2204
0
    #endif
2205
0
    #ifndef NO_CERTS
2206
0
        keySz = ssl->buffers.keySz;
2207
0
    #endif
2208
0
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
2209
0
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
2210
0
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
2211
0
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
2212
0
                   ssl->options.haveAnon, TRUE, ssl->options.side);
2213
0
    }
2214
2215
0
    WOLFSSL_LEAVE("wolfSSL_SetTmpDH", 0);
2216
2217
0
    return WOLFSSL_SUCCESS;
2218
0
}
2219
2220
2221
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2222
    !defined(HAVE_SELFTEST)
2223
/* Enables or disables the session's DH key prime test. */
2224
int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable)
2225
0
{
2226
0
    WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest");
2227
2228
0
    if (ssl == NULL)
2229
0
        return BAD_FUNC_ARG;
2230
2231
0
    if (!enable)
2232
0
        ssl->options.dhDoKeyTest = 0;
2233
0
    else
2234
0
        ssl->options.dhDoKeyTest = 1;
2235
2236
0
    WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS);
2237
0
    return WOLFSSL_SUCCESS;
2238
0
}
2239
#endif
2240
2241
2242
/* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
2243
int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
2244
                         const unsigned char* g, int gSz)
2245
0
{
2246
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetTmpDH");
2247
0
    if (ctx == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG;
2248
2249
0
    if ((word16)pSz < ctx->minDhKeySz)
2250
0
        return DH_KEY_SIZE_E;
2251
0
    if ((word16)pSz > ctx->maxDhKeySz)
2252
0
        return DH_KEY_SIZE_E;
2253
2254
0
    #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
2255
0
        !defined(HAVE_SELFTEST)
2256
0
    {
2257
0
        WC_RNG rng;
2258
0
        int error, freeKey = 0;
2259
0
    #ifdef WOLFSSL_SMALL_STACK
2260
0
        DhKey *checkKey = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
2261
0
        if (checkKey == NULL)
2262
0
            return MEMORY_E;
2263
    #else
2264
        DhKey checkKey[1];
2265
    #endif
2266
2267
0
        error = wc_InitRng(&rng);
2268
0
        if (!error)
2269
0
            error = wc_InitDhKey(checkKey);
2270
0
        if (!error) {
2271
0
            freeKey = 1;
2272
0
            error = wc_DhSetCheckKey(checkKey,
2273
0
                                 p, pSz, g, gSz, NULL, 0, 0, &rng);
2274
0
        }
2275
0
        if (freeKey)
2276
0
            wc_FreeDhKey(checkKey);
2277
0
    #ifdef WOLFSSL_SMALL_STACK
2278
0
        XFREE(checkKey, NULL, DYNAMIC_TYPE_DH);
2279
0
    #endif
2280
0
        wc_FreeRng(&rng);
2281
0
        if (error)
2282
0
            return error;
2283
2284
0
        ctx->dhKeyTested = 1;
2285
0
    }
2286
0
    #endif
2287
2288
0
    XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2289
0
    ctx->serverDH_P.buffer = NULL;
2290
0
    XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2291
0
    ctx->serverDH_G.buffer = NULL;
2292
2293
0
    ctx->serverDH_P.buffer = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2294
0
    if (ctx->serverDH_P.buffer == NULL)
2295
0
       return MEMORY_E;
2296
2297
0
    ctx->serverDH_G.buffer = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2298
0
    if (ctx->serverDH_G.buffer == NULL) {
2299
0
        XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
2300
0
        ctx->serverDH_P.buffer = NULL;
2301
0
        return MEMORY_E;
2302
0
    }
2303
2304
0
    ctx->serverDH_P.length = pSz;
2305
0
    ctx->serverDH_G.length = gSz;
2306
2307
0
    XMEMCPY(ctx->serverDH_P.buffer, p, pSz);
2308
0
    XMEMCPY(ctx->serverDH_G.buffer, g, gSz);
2309
2310
0
    ctx->haveDH = 1;
2311
2312
0
    WOLFSSL_LEAVE("wolfSSL_CTX_SetTmpDH", 0);
2313
0
    return WOLFSSL_SUCCESS;
2314
0
}
2315
2316
2317
int wolfSSL_CTX_SetMinDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2318
0
{
2319
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2320
0
        return BAD_FUNC_ARG;
2321
2322
0
    ctx->minDhKeySz = keySz_bits / 8;
2323
0
    return WOLFSSL_SUCCESS;
2324
0
}
2325
2326
2327
int wolfSSL_SetMinDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2328
0
{
2329
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2330
0
        return BAD_FUNC_ARG;
2331
2332
0
    ssl->options.minDhKeySz = keySz_bits / 8;
2333
0
    return WOLFSSL_SUCCESS;
2334
0
}
2335
2336
2337
int wolfSSL_CTX_SetMaxDhKey_Sz(WOLFSSL_CTX* ctx, word16 keySz_bits)
2338
0
{
2339
0
    if (ctx == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2340
0
        return BAD_FUNC_ARG;
2341
2342
0
    ctx->maxDhKeySz = keySz_bits / 8;
2343
0
    return WOLFSSL_SUCCESS;
2344
0
}
2345
2346
2347
int wolfSSL_SetMaxDhKey_Sz(WOLFSSL* ssl, word16 keySz_bits)
2348
0
{
2349
0
    if (ssl == NULL || keySz_bits > 16000 || keySz_bits % 8 != 0)
2350
0
        return BAD_FUNC_ARG;
2351
2352
0
    ssl->options.maxDhKeySz = keySz_bits / 8;
2353
0
    return WOLFSSL_SUCCESS;
2354
0
}
2355
2356
2357
int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl)
2358
0
{
2359
0
    if (ssl == NULL)
2360
0
        return BAD_FUNC_ARG;
2361
2362
0
    return (ssl->options.dhKeySz * 8);
2363
0
}
2364
2365
#endif /* !NO_DH */
2366
2367
2368
WOLFSSL_ABI
2369
int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz)
2370
0
{
2371
0
    int ret;
2372
2373
0
    WOLFSSL_ENTER("SSL_write()");
2374
2375
0
    if (ssl == NULL || data == NULL || sz < 0)
2376
0
        return BAD_FUNC_ARG;
2377
2378
#ifdef WOLFSSL_QUIC
2379
    if (WOLFSSL_IS_QUIC(ssl)) {
2380
        WOLFSSL_MSG("SSL_write() on QUIC not allowed");
2381
        return BAD_FUNC_ARG;
2382
    }
2383
#endif
2384
#ifdef WOLFSSL_EARLY_DATA
2385
    if (ssl->earlyData != no_early_data && (ret = wolfSSL_negotiate(ssl)) < 0) {
2386
        ssl->error = ret;
2387
        return WOLFSSL_FATAL_ERROR;
2388
    }
2389
    ssl->earlyData = no_early_data;
2390
#endif
2391
2392
#ifdef HAVE_WRITE_DUP
2393
    { /* local variable scope */
2394
        int dupErr = 0;   /* local copy */
2395
2396
        ret = 0;
2397
2398
        if (ssl->dupWrite && ssl->dupSide == READ_DUP_SIDE) {
2399
            WOLFSSL_MSG("Read dup side cannot write");
2400
            return WRITE_DUP_WRITE_E;
2401
        }
2402
        if (ssl->dupWrite) {
2403
            if (wc_LockMutex(&ssl->dupWrite->dupMutex) != 0) {
2404
                return BAD_MUTEX_E;
2405
            }
2406
            dupErr = ssl->dupWrite->dupErr;
2407
            ret = wc_UnLockMutex(&ssl->dupWrite->dupMutex);
2408
        }
2409
2410
        if (ret != 0) {
2411
            ssl->error = ret;  /* high priority fatal error */
2412
            return WOLFSSL_FATAL_ERROR;
2413
        }
2414
        if (dupErr != 0) {
2415
            WOLFSSL_MSG("Write dup error from other side");
2416
            ssl->error = dupErr;
2417
            return WOLFSSL_FATAL_ERROR;
2418
        }
2419
    }
2420
#endif
2421
2422
0
#ifdef HAVE_ERRNO_H
2423
0
    errno = 0;
2424
0
#endif
2425
2426
0
    #ifdef OPENSSL_EXTRA
2427
0
    if (ssl->CBIS != NULL) {
2428
0
        ssl->CBIS(ssl, SSL_CB_WRITE, WOLFSSL_SUCCESS);
2429
0
        ssl->cbmode = SSL_CB_WRITE;
2430
0
    }
2431
0
    #endif
2432
0
    ret = SendData(ssl, data, sz);
2433
2434
0
    WOLFSSL_LEAVE("SSL_write()", ret);
2435
2436
0
    if (ret < 0)
2437
0
        return WOLFSSL_FATAL_ERROR;
2438
0
    else
2439
0
        return ret;
2440
0
}
2441
2442
static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek)
2443
0
{
2444
0
    int ret;
2445
2446
0
    WOLFSSL_ENTER("wolfSSL_read_internal()");
2447
2448
0
    if (ssl == NULL || data == NULL || sz < 0)
2449
0
        return BAD_FUNC_ARG;
2450
2451
#ifdef WOLFSSL_QUIC
2452
    if (WOLFSSL_IS_QUIC(ssl)) {
2453
        WOLFSSL_MSG("SSL_read() on QUIC not allowed");
2454
        return BAD_FUNC_ARG;
2455
    }
2456
#endif
2457
0
#if defined(WOLFSSL_ERROR_CODE_OPENSSL) && defined(OPENSSL_EXTRA)
2458
    /* This additional logic is meant to simulate following openSSL behavior:
2459
     * After bidirectional SSL_shutdown complete, SSL_read returns 0 and
2460
     * SSL_get_error_code returns SSL_ERROR_ZERO_RETURN.
2461
     * This behavior is used to know the disconnect of the underlying
2462
     * transport layer.
2463
     *
2464
     * In this logic, CBIORecv is called with a read size of 0 to check the
2465
     * transport layer status. It also returns WOLFSSL_FAILURE so that
2466
     * SSL_read does not return a positive number on failure.
2467
     */
2468
2469
    /* make sure bidirectional TLS shutdown completes */
2470
0
    if (ssl->error == WOLFSSL_ERROR_SYSCALL) {
2471
        /* ask the underlying transport the connection is closed */
2472
0
        if (ssl->CBIORecv(ssl, (char*)data, 0, ssl->IOCB_ReadCtx) ==
2473
0
                                            WOLFSSL_CBIO_ERR_CONN_CLOSE) {
2474
0
            ssl->options.isClosed = 1;
2475
0
            ssl->error = WOLFSSL_ERROR_ZERO_RETURN;
2476
0
        }
2477
0
        return WOLFSSL_FAILURE;
2478
0
    }
2479
0
#endif
2480
2481
#ifdef HAVE_WRITE_DUP
2482
    if (ssl->dupWrite && ssl->dupSide == WRITE_DUP_SIDE) {
2483
        WOLFSSL_MSG("Write dup side cannot read");
2484
        return WRITE_DUP_READ_E;
2485
    }
2486
#endif
2487
2488
0
#ifdef HAVE_ERRNO_H
2489
0
        errno = 0;
2490
0
#endif
2491
2492
#ifdef WOLFSSL_DTLS
2493
    if (ssl->options.dtls) {
2494
        ssl->dtls_expected_rx = max(sz + DTLS_MTU_ADDITIONAL_READ_BUFFER,
2495
                MAX_MTU);
2496
#ifdef WOLFSSL_SCTP
2497
        if (ssl->options.dtlsSctp)
2498
#endif
2499
#if defined(WOLFSSL_SCTP) || defined(WOLFSSL_DTLS_MTU)
2500
            /* Add some bytes so that we can operate with slight difference
2501
             * in set MTU size on each peer */
2502
            ssl->dtls_expected_rx = max(ssl->dtls_expected_rx,
2503
                    ssl->dtlsMtuSz + (word32)DTLS_MTU_ADDITIONAL_READ_BUFFER);
2504
#endif
2505
    }
2506
#endif
2507
2508
0
    ret = ReceiveData(ssl, (byte*)data, sz, peek);
2509
2510
#ifdef HAVE_WRITE_DUP
2511
    if (ssl->dupWrite) {
2512
        if (ssl->error != 0 && ssl->error != WANT_READ
2513
        #ifdef WOLFSSL_ASYNC_CRYPT
2514
            && ssl->error != WC_PENDING_E
2515
        #endif
2516
        ) {
2517
            int notifyErr;
2518
2519
            WOLFSSL_MSG("Notifying write side of fatal read error");
2520
            notifyErr  = NotifyWriteSide(ssl, ssl->error);
2521
            if (notifyErr < 0) {
2522
                ret = ssl->error = notifyErr;
2523
            }
2524
        }
2525
    }
2526
#endif
2527
2528
0
    WOLFSSL_LEAVE("wolfSSL_read_internal()", ret);
2529
2530
0
    if (ret < 0)
2531
0
        return WOLFSSL_FATAL_ERROR;
2532
0
    else
2533
0
        return ret;
2534
0
}
2535
2536
2537
int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz)
2538
0
{
2539
0
    WOLFSSL_ENTER("wolfSSL_peek()");
2540
2541
0
    return wolfSSL_read_internal(ssl, data, sz, TRUE);
2542
0
}
2543
2544
2545
WOLFSSL_ABI
2546
int wolfSSL_read(WOLFSSL* ssl, void* data, int sz)
2547
0
{
2548
0
    WOLFSSL_ENTER("wolfSSL_read()");
2549
2550
0
    #ifdef OPENSSL_EXTRA
2551
0
    if (ssl == NULL) {
2552
0
        return BAD_FUNC_ARG;
2553
0
    }
2554
0
    if (ssl->CBIS != NULL) {
2555
0
        ssl->CBIS(ssl, SSL_CB_READ, WOLFSSL_SUCCESS);
2556
0
        ssl->cbmode = SSL_CB_READ;
2557
0
    }
2558
0
    #endif
2559
0
    return wolfSSL_read_internal(ssl, data, sz, FALSE);
2560
0
}
2561
2562
2563
#ifdef WOLFSSL_MULTICAST
2564
2565
int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz)
2566
{
2567
    int ret = 0;
2568
2569
    WOLFSSL_ENTER("wolfSSL_mcast_read()");
2570
2571
    if (ssl == NULL)
2572
        return BAD_FUNC_ARG;
2573
2574
    ret = wolfSSL_read_internal(ssl, data, sz, FALSE);
2575
    if (ssl->options.dtls && ssl->options.haveMcast && id != NULL)
2576
        *id = ssl->keys.curPeerId;
2577
    return ret;
2578
}
2579
2580
#endif /* WOLFSSL_MULTICAST */
2581
2582
2583
/* helpers to set the device id, WOLFSSL_SUCCESS on ok */
2584
WOLFSSL_ABI
2585
int wolfSSL_SetDevId(WOLFSSL* ssl, int devId)
2586
0
{
2587
0
    if (ssl == NULL)
2588
0
        return BAD_FUNC_ARG;
2589
2590
0
    ssl->devId = devId;
2591
2592
0
    return WOLFSSL_SUCCESS;
2593
0
}
2594
2595
WOLFSSL_ABI
2596
int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId)
2597
0
{
2598
0
    if (ctx == NULL)
2599
0
        return BAD_FUNC_ARG;
2600
2601
0
    ctx->devId = devId;
2602
2603
0
    return WOLFSSL_SUCCESS;
2604
0
}
2605
2606
/* helpers to get device id and heap */
2607
WOLFSSL_ABI
2608
int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2609
0
{
2610
0
    int devId = INVALID_DEVID;
2611
0
    if (ssl != NULL)
2612
0
        devId = ssl->devId;
2613
0
    if (ctx != NULL && devId == INVALID_DEVID)
2614
0
        devId = ctx->devId;
2615
0
    return devId;
2616
0
}
2617
void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
2618
0
{
2619
0
    void* heap = NULL;
2620
0
    if (ctx != NULL)
2621
0
        heap = ctx->heap;
2622
0
    else if (ssl != NULL)
2623
0
        heap = ssl->heap;
2624
0
    return heap;
2625
0
}
2626
2627
2628
#ifdef HAVE_SNI
2629
2630
WOLFSSL_ABI
2631
int wolfSSL_UseSNI(WOLFSSL* ssl, byte type, const void* data, word16 size)
2632
0
{
2633
0
    if (ssl == NULL)
2634
0
        return BAD_FUNC_ARG;
2635
2636
0
    return TLSX_UseSNI(&ssl->extensions, type, data, size, ssl->heap);
2637
0
}
2638
2639
2640
WOLFSSL_ABI
2641
int wolfSSL_CTX_UseSNI(WOLFSSL_CTX* ctx, byte type, const void* data,
2642
                                                                    word16 size)
2643
0
{
2644
0
    if (ctx == NULL)
2645
0
        return BAD_FUNC_ARG;
2646
2647
0
    return TLSX_UseSNI(&ctx->extensions, type, data, size, ctx->heap);
2648
0
}
2649
2650
#ifndef NO_WOLFSSL_SERVER
2651
2652
void wolfSSL_SNI_SetOptions(WOLFSSL* ssl, byte type, byte options)
2653
0
{
2654
0
    if (ssl && ssl->extensions)
2655
0
        TLSX_SNI_SetOptions(ssl->extensions, type, options);
2656
0
}
2657
2658
2659
void wolfSSL_CTX_SNI_SetOptions(WOLFSSL_CTX* ctx, byte type, byte options)
2660
0
{
2661
0
    if (ctx && ctx->extensions)
2662
0
        TLSX_SNI_SetOptions(ctx->extensions, type, options);
2663
0
}
2664
2665
2666
byte wolfSSL_SNI_Status(WOLFSSL* ssl, byte type)
2667
0
{
2668
0
    return TLSX_SNI_Status(ssl ? ssl->extensions : NULL, type);
2669
0
}
2670
2671
2672
word16 wolfSSL_SNI_GetRequest(WOLFSSL* ssl, byte type, void** data)
2673
0
{
2674
0
    if (data)
2675
0
        *data = NULL;
2676
2677
0
    if (ssl && ssl->extensions)
2678
0
        return TLSX_SNI_GetRequest(ssl->extensions, type, data);
2679
2680
0
    return 0;
2681
0
}
2682
2683
2684
int wolfSSL_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
2685
                              byte type, byte* sni, word32* inOutSz)
2686
0
{
2687
0
    if (clientHello && helloSz > 0 && sni && inOutSz && *inOutSz > 0)
2688
0
        return TLSX_SNI_GetFromBuffer(clientHello, helloSz, type, sni, inOutSz);
2689
2690
0
    return BAD_FUNC_ARG;
2691
0
}
2692
2693
#endif /* NO_WOLFSSL_SERVER */
2694
2695
#endif /* HAVE_SNI */
2696
2697
2698
#ifdef HAVE_TRUSTED_CA
2699
2700
WOLFSSL_API int wolfSSL_UseTrustedCA(WOLFSSL* ssl, byte type,
2701
            const byte* certId, word32 certIdSz)
2702
{
2703
    if (ssl == NULL)
2704
        return BAD_FUNC_ARG;
2705
2706
    if (type == WOLFSSL_TRUSTED_CA_PRE_AGREED) {
2707
        if (certId != NULL || certIdSz != 0)
2708
            return BAD_FUNC_ARG;
2709
    }
2710
    else if (type == WOLFSSL_TRUSTED_CA_X509_NAME) {
2711
        if (certId == NULL || certIdSz == 0)
2712
            return BAD_FUNC_ARG;
2713
    }
2714
    #ifndef NO_SHA
2715
    else if (type == WOLFSSL_TRUSTED_CA_KEY_SHA1 ||
2716
            type == WOLFSSL_TRUSTED_CA_CERT_SHA1) {
2717
        if (certId == NULL || certIdSz != WC_SHA_DIGEST_SIZE)
2718
            return BAD_FUNC_ARG;
2719
    }
2720
    #endif
2721
    else
2722
        return BAD_FUNC_ARG;
2723
2724
    return TLSX_UseTrustedCA(&ssl->extensions,
2725
            type, certId, certIdSz, ssl->heap);
2726
}
2727
2728
#endif /* HAVE_TRUSTED_CA */
2729
2730
2731
#ifdef HAVE_MAX_FRAGMENT
2732
#ifndef NO_WOLFSSL_CLIENT
2733
2734
int wolfSSL_UseMaxFragment(WOLFSSL* ssl, byte mfl)
2735
{
2736
    if (ssl == NULL)
2737
        return BAD_FUNC_ARG;
2738
2739
#ifdef WOLFSSL_ALLOW_MAX_FRAGMENT_ADJUST
2740
    /* The following is a non-standard way to reconfigure the max packet size
2741
        post-handshake for wolfSSL_write/wolfSSL_read */
2742
    if (ssl->options.handShakeState == HANDSHAKE_DONE) {
2743
        switch (mfl) {
2744
            case WOLFSSL_MFL_2_8 : ssl->max_fragment =  256; break;
2745
            case WOLFSSL_MFL_2_9 : ssl->max_fragment =  512; break;
2746
            case WOLFSSL_MFL_2_10: ssl->max_fragment = 1024; break;
2747
            case WOLFSSL_MFL_2_11: ssl->max_fragment = 2048; break;
2748
            case WOLFSSL_MFL_2_12: ssl->max_fragment = 4096; break;
2749
            case WOLFSSL_MFL_2_13: ssl->max_fragment = 8192; break;
2750
            default: ssl->max_fragment = MAX_RECORD_SIZE; break;
2751
        }
2752
        return WOLFSSL_SUCCESS;
2753
    }
2754
#endif /* WOLFSSL_MAX_FRAGMENT_ADJUST */
2755
2756
    /* This call sets the max fragment TLS extension, which gets sent to server.
2757
        The server_hello response is what sets the `ssl->max_fragment` in
2758
        TLSX_MFL_Parse */
2759
    return TLSX_UseMaxFragment(&ssl->extensions, mfl, ssl->heap);
2760
}
2761
2762
2763
int wolfSSL_CTX_UseMaxFragment(WOLFSSL_CTX* ctx, byte mfl)
2764
{
2765
    if (ctx == NULL)
2766
        return BAD_FUNC_ARG;
2767
2768
    return TLSX_UseMaxFragment(&ctx->extensions, mfl, ctx->heap);
2769
}
2770
2771
#endif /* NO_WOLFSSL_CLIENT */
2772
#endif /* HAVE_MAX_FRAGMENT */
2773
2774
#ifdef HAVE_TRUNCATED_HMAC
2775
#ifndef NO_WOLFSSL_CLIENT
2776
2777
int wolfSSL_UseTruncatedHMAC(WOLFSSL* ssl)
2778
{
2779
    if (ssl == NULL)
2780
        return BAD_FUNC_ARG;
2781
2782
    return TLSX_UseTruncatedHMAC(&ssl->extensions, ssl->heap);
2783
}
2784
2785
2786
int wolfSSL_CTX_UseTruncatedHMAC(WOLFSSL_CTX* ctx)
2787
{
2788
    if (ctx == NULL)
2789
        return BAD_FUNC_ARG;
2790
2791
    return TLSX_UseTruncatedHMAC(&ctx->extensions, ctx->heap);
2792
}
2793
2794
#endif /* NO_WOLFSSL_CLIENT */
2795
#endif /* HAVE_TRUNCATED_HMAC */
2796
2797
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
2798
2799
int wolfSSL_UseOCSPStapling(WOLFSSL* ssl, byte status_type, byte options)
2800
{
2801
    WOLFSSL_ENTER("wolfSSL_UseOCSPStapling");
2802
2803
    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
2804
        return BAD_FUNC_ARG;
2805
2806
    return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
2807
                                          options, NULL, ssl->heap, ssl->devId);
2808
}
2809
2810
2811
int wolfSSL_CTX_UseOCSPStapling(WOLFSSL_CTX* ctx, byte status_type,
2812
                                                                   byte options)
2813
{
2814
    WOLFSSL_ENTER("wolfSSL_CTX_UseOCSPStapling");
2815
2816
    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
2817
        return BAD_FUNC_ARG;
2818
2819
    return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type,
2820
                                          options, NULL, ctx->heap, ctx->devId);
2821
}
2822
2823
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
2824
2825
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
2826
2827
int wolfSSL_UseOCSPStaplingV2(WOLFSSL* ssl, byte status_type, byte options)
2828
{
2829
    if (ssl == NULL || ssl->options.side != WOLFSSL_CLIENT_END)
2830
        return BAD_FUNC_ARG;
2831
2832
    return TLSX_UseCertificateStatusRequestV2(&ssl->extensions, status_type,
2833
                                                options, ssl->heap, ssl->devId);
2834
}
2835
2836
2837
int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type,
2838
                                                                   byte options)
2839
{
2840
    if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
2841
        return BAD_FUNC_ARG;
2842
2843
    return TLSX_UseCertificateStatusRequestV2(&ctx->extensions, status_type,
2844
                                                options, ctx->heap, ctx->devId);
2845
}
2846
2847
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
2848
2849
/* Elliptic Curves */
2850
#if defined(HAVE_SUPPORTED_CURVES)
2851
2852
static int isValidCurveGroup(word16 name)
2853
0
{
2854
0
    switch (name) {
2855
0
        case WOLFSSL_ECC_SECP160K1:
2856
0
        case WOLFSSL_ECC_SECP160R1:
2857
0
        case WOLFSSL_ECC_SECP160R2:
2858
0
        case WOLFSSL_ECC_SECP192K1:
2859
0
        case WOLFSSL_ECC_SECP192R1:
2860
0
        case WOLFSSL_ECC_SECP224K1:
2861
0
        case WOLFSSL_ECC_SECP224R1:
2862
0
        case WOLFSSL_ECC_SECP256K1:
2863
0
        case WOLFSSL_ECC_SECP256R1:
2864
0
        case WOLFSSL_ECC_SECP384R1:
2865
0
        case WOLFSSL_ECC_SECP521R1:
2866
0
        case WOLFSSL_ECC_BRAINPOOLP256R1:
2867
0
        case WOLFSSL_ECC_BRAINPOOLP384R1:
2868
0
        case WOLFSSL_ECC_BRAINPOOLP512R1:
2869
0
        case WOLFSSL_ECC_X25519:
2870
0
        case WOLFSSL_ECC_X448:
2871
2872
0
        case WOLFSSL_FFDHE_2048:
2873
0
        case WOLFSSL_FFDHE_3072:
2874
0
        case WOLFSSL_FFDHE_4096:
2875
0
        case WOLFSSL_FFDHE_6144:
2876
0
        case WOLFSSL_FFDHE_8192:
2877
2878
#ifdef HAVE_PQC
2879
        case WOLFSSL_KYBER_LEVEL1:
2880
        case WOLFSSL_KYBER_LEVEL3:
2881
        case WOLFSSL_KYBER_LEVEL5:
2882
        case WOLFSSL_NTRU_HPS_LEVEL1:
2883
        case WOLFSSL_NTRU_HPS_LEVEL3:
2884
        case WOLFSSL_NTRU_HPS_LEVEL5:
2885
        case WOLFSSL_NTRU_HRSS_LEVEL3:
2886
        case WOLFSSL_SABER_LEVEL1:
2887
        case WOLFSSL_SABER_LEVEL3:
2888
        case WOLFSSL_SABER_LEVEL5:
2889
        case WOLFSSL_KYBER_90S_LEVEL1:
2890
        case WOLFSSL_KYBER_90S_LEVEL3:
2891
        case WOLFSSL_KYBER_90S_LEVEL5:
2892
        case WOLFSSL_P256_NTRU_HPS_LEVEL1:
2893
        case WOLFSSL_P384_NTRU_HPS_LEVEL3:
2894
        case WOLFSSL_P521_NTRU_HPS_LEVEL5:
2895
        case WOLFSSL_P384_NTRU_HRSS_LEVEL3:
2896
        case WOLFSSL_P256_SABER_LEVEL1:
2897
        case WOLFSSL_P384_SABER_LEVEL3:
2898
        case WOLFSSL_P521_SABER_LEVEL5:
2899
        case WOLFSSL_P256_KYBER_LEVEL1:
2900
        case WOLFSSL_P384_KYBER_LEVEL3:
2901
        case WOLFSSL_P521_KYBER_LEVEL5:
2902
        case WOLFSSL_P256_KYBER_90S_LEVEL1:
2903
        case WOLFSSL_P384_KYBER_90S_LEVEL3:
2904
        case WOLFSSL_P521_KYBER_90S_LEVEL5:
2905
#endif
2906
0
            return 1;
2907
2908
0
        default:
2909
0
            return 0;
2910
0
    }
2911
0
}
2912
2913
int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
2914
0
{
2915
0
    if (ssl == NULL || !isValidCurveGroup(name))
2916
0
        return BAD_FUNC_ARG;
2917
2918
0
    ssl->options.userCurves = 1;
2919
#if defined(NO_TLS)
2920
    return WOLFSSL_FAILURE;
2921
#else
2922
0
    return TLSX_UseSupportedCurve(&ssl->extensions, name, ssl->heap);
2923
0
#endif /* NO_TLS */
2924
0
}
2925
2926
2927
int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
2928
0
{
2929
0
    if (ctx == NULL || !isValidCurveGroup(name))
2930
0
        return BAD_FUNC_ARG;
2931
2932
0
    ctx->userCurves = 1;
2933
#if defined(NO_TLS)
2934
    return WOLFSSL_FAILURE;
2935
#else
2936
0
    return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap);
2937
0
#endif /* NO_TLS */
2938
0
}
2939
2940
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13)
2941
int  wolfSSL_CTX_set1_groups(WOLFSSL_CTX* ctx, int* groups,
2942
                                        int count)
2943
0
{
2944
0
    int i;
2945
0
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
2946
0
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
2947
0
    if (count == 0) {
2948
0
        WOLFSSL_MSG("Group count is zero");
2949
0
        return WOLFSSL_FAILURE;
2950
0
    }
2951
0
    for (i = 0; i < count; i++) {
2952
0
        if (isValidCurveGroup((word16)groups[i])) {
2953
0
            _groups[i] = groups[i];
2954
0
        }
2955
0
#ifdef HAVE_ECC
2956
0
        else {
2957
            /* groups may be populated with curve NIDs */
2958
0
            int oid = nid2oid(groups[i], oidCurveType);
2959
0
            int name = (int)GetCurveByOID(oid);
2960
0
            if (name == 0) {
2961
0
                WOLFSSL_MSG("Invalid group name");
2962
0
                return WOLFSSL_FAILURE;
2963
0
            }
2964
0
            _groups[i] = name;
2965
0
        }
2966
#else
2967
        else {
2968
            WOLFSSL_MSG("Invalid group name");
2969
            return WOLFSSL_FAILURE;
2970
        }
2971
#endif
2972
0
    }
2973
0
    return wolfSSL_CTX_set_groups(ctx, _groups, count) == WOLFSSL_SUCCESS ?
2974
0
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
2975
0
}
2976
2977
int  wolfSSL_set1_groups(WOLFSSL* ssl, int* groups, int count)
2978
0
{
2979
0
    int i;
2980
0
    int _groups[WOLFSSL_MAX_GROUP_COUNT];
2981
0
    WOLFSSL_ENTER("wolfSSL_CTX_set1_groups");
2982
0
    if (count == 0) {
2983
0
        WOLFSSL_MSG("Group count is zero");
2984
0
        return WOLFSSL_FAILURE;
2985
0
    }
2986
0
    for (i = 0; i < count; i++) {
2987
0
        if (isValidCurveGroup((word16)groups[i])) {
2988
0
            _groups[i] = groups[i];
2989
0
        }
2990
0
#ifdef HAVE_ECC
2991
0
        else {
2992
            /* groups may be populated with curve NIDs */
2993
0
            int oid = nid2oid(groups[i], oidCurveType);
2994
0
            int name = (int)GetCurveByOID(oid);
2995
0
            if (name == 0) {
2996
0
                WOLFSSL_MSG("Invalid group name");
2997
0
                return WOLFSSL_FAILURE;
2998
0
            }
2999
0
            _groups[i] = name;
3000
0
        }
3001
#else
3002
        else {
3003
            WOLFSSL_MSG("Invalid group name");
3004
            return WOLFSSL_FAILURE;
3005
        }
3006
#endif
3007
0
    }
3008
0
    return wolfSSL_set_groups(ssl, _groups, count) == WOLFSSL_SUCCESS ?
3009
0
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
3010
0
}
3011
#endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 */
3012
#endif /* HAVE_SUPPORTED_CURVES */
3013
3014
/* Application-Layer Protocol Negotiation */
3015
#ifdef HAVE_ALPN
3016
3017
WOLFSSL_ABI
3018
int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list,
3019
                    word32 protocol_name_listSz, byte options)
3020
{
3021
    char    *list, *ptr, **token;
3022
    word16  len;
3023
    int     idx = 0;
3024
    int     ret = WOLFSSL_FAILURE;
3025
3026
    WOLFSSL_ENTER("wolfSSL_UseALPN");
3027
3028
    if (ssl == NULL || protocol_name_list == NULL)
3029
        return BAD_FUNC_ARG;
3030
3031
    if (protocol_name_listSz > (WOLFSSL_MAX_ALPN_NUMBER *
3032
                                WOLFSSL_MAX_ALPN_PROTO_NAME_LEN +
3033
                                WOLFSSL_MAX_ALPN_NUMBER)) {
3034
        WOLFSSL_MSG("Invalid arguments, protocol name list too long");
3035
        return BAD_FUNC_ARG;
3036
    }
3037
3038
    if (!(options & WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) &&
3039
        !(options & WOLFSSL_ALPN_FAILED_ON_MISMATCH)) {
3040
            WOLFSSL_MSG("Invalid arguments, options not supported");
3041
            return BAD_FUNC_ARG;
3042
        }
3043
3044
3045
    list = (char *)XMALLOC(protocol_name_listSz+1, ssl->heap,
3046
                           DYNAMIC_TYPE_ALPN);
3047
    if (list == NULL) {
3048
        WOLFSSL_MSG("Memory failure");
3049
        return MEMORY_ERROR;
3050
    }
3051
3052
    token = (char **)XMALLOC(sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1), ssl->heap, DYNAMIC_TYPE_ALPN);
3053
    if (token == NULL) {
3054
        XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3055
        WOLFSSL_MSG("Memory failure");
3056
        return MEMORY_ERROR;
3057
    }
3058
    XMEMSET(token, 0, sizeof(char *) * (WOLFSSL_MAX_ALPN_NUMBER+1));
3059
3060
    XSTRNCPY(list, protocol_name_list, protocol_name_listSz);
3061
    list[protocol_name_listSz] = '\0';
3062
3063
    /* read all protocol name from the list */
3064
    token[idx] = XSTRTOK(list, ",", &ptr);
3065
    while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL)
3066
        token[++idx] = XSTRTOK(NULL, ",", &ptr);
3067
3068
    /* add protocol name list in the TLS extension in reverse order */
3069
    while ((idx--) > 0) {
3070
        len = (word16)XSTRLEN(token[idx]);
3071
3072
        ret = TLSX_UseALPN(&ssl->extensions, token[idx], len, options,
3073
                                                                     ssl->heap);
3074
        if (ret != WOLFSSL_SUCCESS) {
3075
            WOLFSSL_MSG("TLSX_UseALPN failure");
3076
            break;
3077
        }
3078
    }
3079
3080
    XFREE(token, ssl->heap, DYNAMIC_TYPE_ALPN);
3081
    XFREE(list, ssl->heap, DYNAMIC_TYPE_ALPN);
3082
3083
    return ret;
3084
}
3085
3086
int wolfSSL_ALPN_GetProtocol(WOLFSSL* ssl, char **protocol_name, word16 *size)
3087
{
3088
    return TLSX_ALPN_GetRequest(ssl ? ssl->extensions : NULL,
3089
                               (void **)protocol_name, size);
3090
}
3091
3092
int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz)
3093
{
3094
    if (list == NULL || listSz == NULL)
3095
        return BAD_FUNC_ARG;
3096
3097
    if (ssl->alpn_client_list == NULL)
3098
        return BUFFER_ERROR;
3099
3100
    *listSz = (word16)XSTRLEN(ssl->alpn_client_list);
3101
    if (*listSz == 0)
3102
        return BUFFER_ERROR;
3103
3104
    *list = (char *)XMALLOC((*listSz)+1, ssl->heap, DYNAMIC_TYPE_TLSX);
3105
    if (*list == NULL)
3106
        return MEMORY_ERROR;
3107
3108
    XSTRNCPY(*list, ssl->alpn_client_list, (*listSz)+1);
3109
    (*list)[*listSz] = 0;
3110
3111
    return WOLFSSL_SUCCESS;
3112
}
3113
3114
3115
/* used to free memory allocated by wolfSSL_ALPN_GetPeerProtocol */
3116
int wolfSSL_ALPN_FreePeerProtocol(WOLFSSL* ssl, char **list)
3117
{
3118
    if (ssl == NULL) {
3119
        return BAD_FUNC_ARG;
3120
    }
3121
3122
    XFREE(*list, ssl->heap, DYNAMIC_TYPE_TLSX);
3123
    *list = NULL;
3124
3125
    return WOLFSSL_SUCCESS;
3126
}
3127
3128
#endif /* HAVE_ALPN */
3129
3130
/* Secure Renegotiation */
3131
#ifdef HAVE_SERVER_RENEGOTIATION_INFO
3132
3133
/* user is forcing ability to use secure renegotiation, we discourage it */
3134
int wolfSSL_UseSecureRenegotiation(WOLFSSL* ssl)
3135
0
{
3136
0
    int ret = BAD_FUNC_ARG;
3137
#if defined(NO_TLS)
3138
    (void)ssl;
3139
#else
3140
0
    if (ssl)
3141
0
        ret = TLSX_UseSecureRenegotiation(&ssl->extensions, ssl->heap);
3142
3143
0
    if (ret == WOLFSSL_SUCCESS) {
3144
0
        TLSX* extension = TLSX_Find(ssl->extensions, TLSX_RENEGOTIATION_INFO);
3145
3146
0
        if (extension)
3147
0
            ssl->secure_renegotiation = (SecureRenegotiation*)extension->data;
3148
0
    }
3149
0
#endif /* !NO_TLS */
3150
0
    return ret;
3151
0
}
3152
3153
int wolfSSL_CTX_UseSecureRenegotiation(WOLFSSL_CTX* ctx)
3154
0
{
3155
0
    if (ctx == NULL)
3156
0
        return BAD_FUNC_ARG;
3157
3158
0
    ctx->useSecureReneg = 1;
3159
0
    return WOLFSSL_SUCCESS;
3160
0
}
3161
3162
3163
/* do a secure renegotiation handshake, user forced, we discourage */
3164
static int _Rehandshake(WOLFSSL* ssl)
3165
0
{
3166
0
    int ret;
3167
3168
0
    if (ssl == NULL)
3169
0
        return BAD_FUNC_ARG;
3170
3171
0
    if (ssl->secure_renegotiation == NULL) {
3172
0
        WOLFSSL_MSG("Secure Renegotiation not forced on by user");
3173
0
        return SECURE_RENEGOTIATION_E;
3174
0
    }
3175
3176
0
    if (ssl->secure_renegotiation->enabled == 0) {
3177
0
        WOLFSSL_MSG("Secure Renegotiation not enabled at extension level");
3178
0
        return SECURE_RENEGOTIATION_E;
3179
0
    }
3180
3181
    /* If the client started the renegotiation, the server will already
3182
     * have processed the client's hello. */
3183
0
    if (ssl->options.side != WOLFSSL_SERVER_END ||
3184
0
        ssl->options.acceptState != ACCEPT_FIRST_REPLY_DONE) {
3185
3186
0
        if (ssl->options.handShakeState != HANDSHAKE_DONE) {
3187
0
            if (!ssl->options.handShakeDone) {
3188
0
                WOLFSSL_MSG("Can't renegotiate until initial "
3189
0
                            "handshake complete");
3190
0
                return SECURE_RENEGOTIATION_E;
3191
0
            }
3192
0
            else {
3193
0
                WOLFSSL_MSG("Renegotiation already started. "
3194
0
                            "Moving it forward.");
3195
0
                ret = wolfSSL_negotiate(ssl);
3196
0
                if (ret == WOLFSSL_SUCCESS)
3197
0
                    ssl->secure_rene_count++;
3198
0
                return ret;
3199
0
            }
3200
0
        }
3201
3202
0
#ifndef NO_FORCE_SCR_SAME_SUITE
3203
        /* force same suite */
3204
0
        if (ssl->suites) {
3205
0
            ssl->suites->suiteSz = SUITE_LEN;
3206
0
            ssl->suites->suites[0] = ssl->options.cipherSuite0;
3207
0
            ssl->suites->suites[1] = ssl->options.cipherSuite;
3208
0
        }
3209
0
#endif
3210
3211
        /* reset handshake states */
3212
0
        ssl->options.sendVerify = 0;
3213
0
        ssl->options.serverState = NULL_STATE;
3214
0
        ssl->options.clientState = NULL_STATE;
3215
0
        ssl->options.connectState  = CONNECT_BEGIN;
3216
0
        ssl->options.acceptState   = ACCEPT_BEGIN_RENEG;
3217
0
        ssl->options.handShakeState = NULL_STATE;
3218
0
        ssl->options.processReply  = 0;  /* TODO, move states in internal.h */
3219
3220
0
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
3221
3222
0
        ssl->secure_renegotiation->cache_status = SCR_CACHE_NEEDED;
3223
3224
#if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SECURE_RENEGOTIATION)
3225
        if (ssl->options.side == WOLFSSL_SERVER_END) {
3226
            ret = SendHelloRequest(ssl);
3227
            if (ret != 0) {
3228
                ssl->error = ret;
3229
                return WOLFSSL_FATAL_ERROR;
3230
            }
3231
        }
3232
#endif /* !NO_WOLFSSL_SERVER && HAVE_SECURE_RENEGOTIATION */
3233
3234
0
        ret = InitHandshakeHashes(ssl);
3235
0
        if (ret != 0) {
3236
0
            ssl->error = ret;
3237
0
            return WOLFSSL_FATAL_ERROR;
3238
0
        }
3239
0
    }
3240
0
    ret = wolfSSL_negotiate(ssl);
3241
0
    if (ret == WOLFSSL_SUCCESS)
3242
0
        ssl->secure_rene_count++;
3243
0
    return ret;
3244
0
}
3245
3246
3247
/* do a secure renegotiation handshake, user forced, we discourage */
3248
int wolfSSL_Rehandshake(WOLFSSL* ssl)
3249
0
{
3250
0
    int ret;
3251
0
    WOLFSSL_ENTER("wolfSSL_Rehandshake");
3252
3253
0
    if (ssl == NULL)
3254
0
        return WOLFSSL_FAILURE;
3255
3256
0
#ifdef HAVE_SESSION_TICKET
3257
0
    ret = WOLFSSL_SUCCESS;
3258
0
#endif
3259
3260
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
3261
        /* Reset option to send certificate verify. */
3262
0
        ssl->options.sendVerify = 0;
3263
0
    }
3264
0
    else {
3265
        /* Reset resuming flag to do full secure handshake. */
3266
0
        ssl->options.resuming = 0;
3267
0
        #ifdef HAVE_SESSION_TICKET
3268
            /* Clearing the ticket. */
3269
0
            ret = wolfSSL_UseSessionTicket(ssl);
3270
0
        #endif
3271
0
    }
3272
    /* CLIENT/SERVER: Reset peer authentication for full secure handshake. */
3273
0
    ssl->options.peerAuthGood = 0;
3274
3275
0
#ifdef HAVE_SESSION_TICKET
3276
0
    if (ret == WOLFSSL_SUCCESS)
3277
0
#endif
3278
0
        ret = _Rehandshake(ssl);
3279
3280
0
    return ret;
3281
0
}
3282
3283
3284
#ifndef NO_WOLFSSL_CLIENT
3285
3286
/* do a secure resumption handshake, user forced, we discourage */
3287
int wolfSSL_SecureResume(WOLFSSL* ssl)
3288
0
{
3289
0
    WOLFSSL_ENTER("wolfSSL_SecureResume");
3290
3291
0
    if (ssl == NULL)
3292
0
        return BAD_FUNC_ARG;
3293
3294
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
3295
0
        ssl->error = SIDE_ERROR;
3296
0
        return WOLFSSL_FATAL_ERROR;
3297
0
    }
3298
3299
0
    return _Rehandshake(ssl);
3300
0
}
3301
3302
#endif /* NO_WOLFSSL_CLIENT */
3303
3304
long wolfSSL_SSL_get_secure_renegotiation_support(WOLFSSL* ssl)
3305
0
{
3306
0
    WOLFSSL_ENTER("wolfSSL_SSL_get_secure_renegotiation_support");
3307
3308
0
    if (!ssl || !ssl->secure_renegotiation)
3309
0
        return WOLFSSL_FAILURE;
3310
0
    return ssl->secure_renegotiation->enabled;
3311
0
}
3312
3313
#endif /* HAVE_SECURE_RENEGOTIATION_INFO */
3314
3315
#if defined(HAVE_SESSION_TICKET)
3316
/* Session Ticket */
3317
3318
#if !defined(NO_WOLFSSL_SERVER)
3319
int wolfSSL_CTX_NoTicketTLSv12(WOLFSSL_CTX* ctx)
3320
0
{
3321
0
    if (ctx == NULL)
3322
0
        return BAD_FUNC_ARG;
3323
3324
0
    ctx->noTicketTls12 = 1;
3325
3326
0
    return WOLFSSL_SUCCESS;
3327
0
}
3328
3329
int wolfSSL_NoTicketTLSv12(WOLFSSL* ssl)
3330
0
{
3331
0
    if (ssl == NULL)
3332
0
        return BAD_FUNC_ARG;
3333
3334
0
    ssl->options.noTicketTls12 = 1;
3335
3336
0
    return WOLFSSL_SUCCESS;
3337
0
}
3338
3339
/* WOLFSSL_SUCCESS on ok */
3340
int wolfSSL_CTX_set_TicketEncCb(WOLFSSL_CTX* ctx, SessionTicketEncCb cb)
3341
0
{
3342
0
    if (ctx == NULL)
3343
0
        return BAD_FUNC_ARG;
3344
3345
0
    ctx->ticketEncCb = cb;
3346
3347
0
    return WOLFSSL_SUCCESS;
3348
0
}
3349
3350
/* set hint interval, WOLFSSL_SUCCESS on ok */
3351
int wolfSSL_CTX_set_TicketHint(WOLFSSL_CTX* ctx, int hint)
3352
0
{
3353
0
    if (ctx == NULL)
3354
0
        return BAD_FUNC_ARG;
3355
3356
0
    ctx->ticketHint = hint;
3357
3358
0
    return WOLFSSL_SUCCESS;
3359
0
}
3360
3361
/* set user context, WOLFSSL_SUCCESS on ok */
3362
int wolfSSL_CTX_set_TicketEncCtx(WOLFSSL_CTX* ctx, void* userCtx)
3363
0
{
3364
0
    if (ctx == NULL)
3365
0
        return BAD_FUNC_ARG;
3366
3367
0
    ctx->ticketEncCtx = userCtx;
3368
3369
0
    return WOLFSSL_SUCCESS;
3370
0
}
3371
3372
/* get user context - returns userCtx on success, NULL on failure */
3373
void* wolfSSL_CTX_get_TicketEncCtx(WOLFSSL_CTX* ctx)
3374
0
{
3375
0
    if (ctx == NULL)
3376
0
        return NULL;
3377
3378
0
    return ctx->ticketEncCtx;
3379
0
}
3380
3381
#ifdef WOLFSSL_TLS13
3382
/* set the maximum number of tickets to send
3383
 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on fail
3384
 */
3385
int wolfSSL_CTX_set_num_tickets(WOLFSSL_CTX* ctx, size_t mxTickets)
3386
0
{
3387
0
    if (ctx == NULL)
3388
0
        return WOLFSSL_FAILURE;
3389
3390
0
    ctx->maxTicketTls13 = (unsigned int)mxTickets;
3391
0
    return WOLFSSL_SUCCESS;
3392
0
}
3393
3394
/* get the maximum number of tickets to send
3395
 * return number of tickets set to be sent
3396
 */
3397
size_t wolfSSL_CTX_get_num_tickets(WOLFSSL_CTX* ctx)
3398
0
{
3399
0
    if (ctx == NULL)
3400
0
        return 0;
3401
3402
0
    return (size_t)ctx->maxTicketTls13;
3403
0
}
3404
#endif /* WOLFSSL_TLS13 */
3405
#endif /* !NO_WOLFSSL_SERVER */
3406
3407
#if !defined(NO_WOLFSSL_CLIENT)
3408
int wolfSSL_UseSessionTicket(WOLFSSL* ssl)
3409
0
{
3410
0
    if (ssl == NULL)
3411
0
        return BAD_FUNC_ARG;
3412
3413
0
    return TLSX_UseSessionTicket(&ssl->extensions, NULL, ssl->heap);
3414
0
}
3415
3416
int wolfSSL_CTX_UseSessionTicket(WOLFSSL_CTX* ctx)
3417
0
{
3418
0
    if (ctx == NULL)
3419
0
        return BAD_FUNC_ARG;
3420
3421
0
    return TLSX_UseSessionTicket(&ctx->extensions, NULL, ctx->heap);
3422
0
}
3423
3424
WOLFSSL_API int wolfSSL_get_SessionTicket(WOLFSSL* ssl,
3425
                                          byte* buf, word32* bufSz)
3426
0
{
3427
0
    if (ssl == NULL || buf == NULL || bufSz == NULL || *bufSz == 0)
3428
0
        return BAD_FUNC_ARG;
3429
3430
0
    if (ssl->session->ticketLen <= *bufSz) {
3431
0
        XMEMCPY(buf, ssl->session->ticket, ssl->session->ticketLen);
3432
0
        *bufSz = ssl->session->ticketLen;
3433
0
    }
3434
0
    else
3435
0
        *bufSz = 0;
3436
3437
0
    return WOLFSSL_SUCCESS;
3438
0
}
3439
3440
WOLFSSL_API int wolfSSL_set_SessionTicket(WOLFSSL* ssl, const byte* buf,
3441
                                          word32 bufSz)
3442
0
{
3443
0
    if (ssl == NULL || (buf == NULL && bufSz > 0))
3444
0
        return BAD_FUNC_ARG;
3445
3446
0
    if (bufSz > 0) {
3447
        /* Ticket will fit into static ticket */
3448
0
        if (bufSz <= SESSION_TICKET_LEN) {
3449
0
            if (ssl->session->ticketLenAlloc > 0) {
3450
0
                XFREE(ssl->session->ticket, ssl->session->heap,
3451
0
                      DYNAMIC_TYPE_SESSION_TICK);
3452
0
                ssl->session->ticketLenAlloc = 0;
3453
0
                ssl->session->ticket = ssl->session->staticTicket;
3454
0
            }
3455
0
        }
3456
0
        else { /* Ticket requires dynamic ticket storage */
3457
0
            if (ssl->session->ticketLen < bufSz) { /* is dyn buffer big enough */
3458
0
                if (ssl->session->ticketLenAlloc > 0) {
3459
0
                    XFREE(ssl->session->ticket, ssl->session->heap,
3460
0
                          DYNAMIC_TYPE_SESSION_TICK);
3461
0
                }
3462
0
                ssl->session->ticket = (byte*)XMALLOC(bufSz, ssl->session->heap,
3463
0
                        DYNAMIC_TYPE_SESSION_TICK);
3464
0
                if(ssl->session->ticket == NULL) {
3465
0
                    ssl->session->ticket = ssl->session->staticTicket;
3466
0
                    ssl->session->ticketLenAlloc = 0;
3467
0
                    return MEMORY_ERROR;
3468
0
                }
3469
0
                ssl->session->ticketLenAlloc = (word16)bufSz;
3470
0
            }
3471
0
        }
3472
0
        XMEMCPY(ssl->session->ticket, buf, bufSz);
3473
0
    }
3474
0
    ssl->session->ticketLen = (word16)bufSz;
3475
3476
0
    return WOLFSSL_SUCCESS;
3477
0
}
3478
3479
3480
WOLFSSL_API int wolfSSL_set_SessionTicket_cb(WOLFSSL* ssl,
3481
                                            CallbackSessionTicket cb, void* ctx)
3482
0
{
3483
0
    if (ssl == NULL)
3484
0
        return BAD_FUNC_ARG;
3485
3486
0
    ssl->session_ticket_cb = cb;
3487
0
    ssl->session_ticket_ctx = ctx;
3488
3489
0
    return WOLFSSL_SUCCESS;
3490
0
}
3491
#endif /* !NO_WOLFSSL_CLIENT */
3492
3493
#endif /* HAVE_SESSION_TICKET */
3494
3495
3496
#ifdef HAVE_EXTENDED_MASTER
3497
#ifndef NO_WOLFSSL_CLIENT
3498
3499
int wolfSSL_CTX_DisableExtendedMasterSecret(WOLFSSL_CTX* ctx)
3500
0
{
3501
0
    if (ctx == NULL)
3502
0
        return BAD_FUNC_ARG;
3503
3504
0
    ctx->haveEMS = 0;
3505
3506
0
    return WOLFSSL_SUCCESS;
3507
0
}
3508
3509
3510
int wolfSSL_DisableExtendedMasterSecret(WOLFSSL* ssl)
3511
0
{
3512
0
    if (ssl == NULL)
3513
0
        return BAD_FUNC_ARG;
3514
3515
0
    ssl->options.haveEMS = 0;
3516
3517
0
    return WOLFSSL_SUCCESS;
3518
0
}
3519
3520
#endif
3521
#endif
3522
3523
3524
#ifndef WOLFSSL_LEANPSK
3525
3526
int wolfSSL_send(WOLFSSL* ssl, const void* data, int sz, int flags)
3527
0
{
3528
0
    int ret;
3529
0
    int oldFlags;
3530
3531
0
    WOLFSSL_ENTER("wolfSSL_send()");
3532
3533
0
    if (ssl == NULL || data == NULL || sz < 0)
3534
0
        return BAD_FUNC_ARG;
3535
3536
0
    oldFlags = ssl->wflags;
3537
3538
0
    ssl->wflags = flags;
3539
0
    ret = wolfSSL_write(ssl, data, sz);
3540
0
    ssl->wflags = oldFlags;
3541
3542
0
    WOLFSSL_LEAVE("wolfSSL_send()", ret);
3543
3544
0
    return ret;
3545
0
}
3546
3547
3548
int wolfSSL_recv(WOLFSSL* ssl, void* data, int sz, int flags)
3549
0
{
3550
0
    int ret;
3551
0
    int oldFlags;
3552
3553
0
    WOLFSSL_ENTER("wolfSSL_recv()");
3554
3555
0
    if (ssl == NULL || data == NULL || sz < 0)
3556
0
        return BAD_FUNC_ARG;
3557
3558
0
    oldFlags = ssl->rflags;
3559
3560
0
    ssl->rflags = flags;
3561
0
    ret = wolfSSL_read(ssl, data, sz);
3562
0
    ssl->rflags = oldFlags;
3563
3564
0
    WOLFSSL_LEAVE("wolfSSL_recv()", ret);
3565
3566
0
    return ret;
3567
0
}
3568
#endif
3569
3570
3571
/* WOLFSSL_SUCCESS on ok */
3572
WOLFSSL_ABI
3573
int wolfSSL_shutdown(WOLFSSL* ssl)
3574
0
{
3575
0
    int  ret = WOLFSSL_FATAL_ERROR;
3576
0
    WOLFSSL_ENTER("SSL_shutdown()");
3577
3578
0
    if (ssl == NULL)
3579
0
        return WOLFSSL_FATAL_ERROR;
3580
3581
0
    if (ssl->options.quietShutdown) {
3582
0
        WOLFSSL_MSG("quiet shutdown, no close notify sent");
3583
0
        ret = WOLFSSL_SUCCESS;
3584
0
    }
3585
0
    else {
3586
        /* try to send close notify, not an error if can't */
3587
0
        if (!ssl->options.isClosed && !ssl->options.connReset &&
3588
0
                                      !ssl->options.sentNotify) {
3589
0
            ssl->error = SendAlert(ssl, alert_warning, close_notify);
3590
0
            if (ssl->error < 0) {
3591
0
                WOLFSSL_ERROR(ssl->error);
3592
0
                return WOLFSSL_FATAL_ERROR;
3593
0
            }
3594
0
            ssl->options.sentNotify = 1;  /* don't send close_notify twice */
3595
0
            if (ssl->options.closeNotify)
3596
0
                ret = WOLFSSL_SUCCESS;
3597
0
            else {
3598
0
                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
3599
0
                WOLFSSL_LEAVE("SSL_shutdown()", ret);
3600
0
                return ret;
3601
0
            }
3602
0
        }
3603
3604
#ifdef WOLFSSL_SHUTDOWNONCE
3605
        if (ssl->options.isClosed || ssl->options.connReset) {
3606
            /* Shutdown has already occurred.
3607
             * Caller is free to ignore this error. */
3608
            return SSL_SHUTDOWN_ALREADY_DONE_E;
3609
        }
3610
#endif
3611
3612
        /* call wolfSSL_shutdown again for bidirectional shutdown */
3613
0
        if (ssl->options.sentNotify && !ssl->options.closeNotify) {
3614
0
            ret = ProcessReply(ssl);
3615
0
            if (ret == ZERO_RETURN) {
3616
                /* simulate OpenSSL behavior */
3617
0
                ssl->error = WOLFSSL_ERROR_SYSCALL;
3618
0
                ret = WOLFSSL_SUCCESS;
3619
0
            } else if (ssl->error == WOLFSSL_ERROR_NONE) {
3620
0
                ret = WOLFSSL_SHUTDOWN_NOT_DONE;
3621
0
            } else {
3622
0
                WOLFSSL_ERROR(ssl->error);
3623
0
                ret = WOLFSSL_FATAL_ERROR;
3624
0
            }
3625
0
        }
3626
0
    }
3627
3628
0
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
3629
    /* reset WOLFSSL structure state for possible re-use */
3630
0
    if (ret == WOLFSSL_SUCCESS) {
3631
0
        if (wolfSSL_clear(ssl) != WOLFSSL_SUCCESS) {
3632
0
            WOLFSSL_MSG("could not clear WOLFSSL");
3633
0
            ret = WOLFSSL_FATAL_ERROR;
3634
0
        }
3635
0
    }
3636
0
#endif
3637
3638
0
    WOLFSSL_LEAVE("SSL_shutdown()", ret);
3639
3640
0
    return ret;
3641
0
}
3642
3643
3644
/* get current error state value */
3645
int wolfSSL_state(WOLFSSL* ssl)
3646
0
{
3647
0
    if (ssl == NULL) {
3648
0
        return BAD_FUNC_ARG;
3649
0
    }
3650
3651
0
    return ssl->error;
3652
0
}
3653
3654
3655
WOLFSSL_ABI
3656
int wolfSSL_get_error(WOLFSSL* ssl, int ret)
3657
0
{
3658
0
    WOLFSSL_ENTER("SSL_get_error");
3659
3660
0
    if (ret > 0)
3661
0
        return WOLFSSL_ERROR_NONE;
3662
0
    if (ssl == NULL)
3663
0
        return BAD_FUNC_ARG;
3664
3665
0
    WOLFSSL_LEAVE("SSL_get_error", ssl->error);
3666
3667
    /* make sure converted types are handled in SetErrorString() too */
3668
0
    if (ssl->error == WANT_READ)
3669
0
        return WOLFSSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
3670
0
    else if (ssl->error == WANT_WRITE)
3671
0
        return WOLFSSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
3672
0
    else if (ssl->error == ZERO_RETURN)
3673
0
        return WOLFSSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
3674
0
    return ssl->error;
3675
0
}
3676
3677
3678
/* retrieve alert history, WOLFSSL_SUCCESS on ok */
3679
int wolfSSL_get_alert_history(WOLFSSL* ssl, WOLFSSL_ALERT_HISTORY *h)
3680
0
{
3681
0
    if (ssl && h) {
3682
0
        *h = ssl->alert_history;
3683
0
    }
3684
0
    return WOLFSSL_SUCCESS;
3685
0
}
3686
3687
#ifdef OPENSSL_EXTRA
3688
/* returns SSL_WRITING, SSL_READING or SSL_NOTHING */
3689
int wolfSSL_want(WOLFSSL* ssl)
3690
0
{
3691
0
    int rw_state = SSL_NOTHING;
3692
0
    if (ssl) {
3693
0
        if (ssl->error == WANT_READ)
3694
0
            rw_state = SSL_READING;
3695
0
        else if (ssl->error == WANT_WRITE)
3696
0
            rw_state = SSL_WRITING;
3697
0
    }
3698
0
    return rw_state;
3699
0
}
3700
#endif
3701
3702
/* return TRUE if current error is want read */
3703
int wolfSSL_want_read(WOLFSSL* ssl)
3704
0
{
3705
0
    WOLFSSL_ENTER("SSL_want_read");
3706
0
    if (ssl->error == WANT_READ)
3707
0
        return 1;
3708
3709
0
    return 0;
3710
0
}
3711
3712
3713
/* return TRUE if current error is want write */
3714
int wolfSSL_want_write(WOLFSSL* ssl)
3715
0
{
3716
0
    WOLFSSL_ENTER("SSL_want_write");
3717
0
    if (ssl->error == WANT_WRITE)
3718
0
        return 1;
3719
3720
0
    return 0;
3721
0
}
3722
3723
3724
char* wolfSSL_ERR_error_string(unsigned long errNumber, char* data)
3725
0
{
3726
0
    static char tmp[WOLFSSL_MAX_ERROR_SZ] = {0};
3727
3728
0
    WOLFSSL_ENTER("ERR_error_string");
3729
0
    if (data) {
3730
0
        SetErrorString((int)errNumber, data);
3731
0
        return data;
3732
0
    }
3733
0
    else {
3734
0
        SetErrorString((int)errNumber, tmp);
3735
0
        return tmp;
3736
0
    }
3737
0
}
3738
3739
3740
void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, unsigned long len)
3741
0
{
3742
0
    WOLFSSL_ENTER("wolfSSL_ERR_error_string_n");
3743
0
    if (len >= WOLFSSL_MAX_ERROR_SZ)
3744
0
        wolfSSL_ERR_error_string(e, buf);
3745
0
    else {
3746
0
        char tmp[WOLFSSL_MAX_ERROR_SZ];
3747
3748
0
        WOLFSSL_MSG("Error buffer too short, truncating");
3749
0
        if (len) {
3750
0
            wolfSSL_ERR_error_string(e, tmp);
3751
0
            XMEMCPY(buf, tmp, len-1);
3752
0
            buf[len-1] = '\0';
3753
0
        }
3754
0
    }
3755
0
}
3756
3757
3758
/* don't free temporary arrays at end of handshake */
3759
void wolfSSL_KeepArrays(WOLFSSL* ssl)
3760
0
{
3761
0
    if (ssl)
3762
0
        ssl->options.saveArrays = 1;
3763
0
}
3764
3765
3766
/* user doesn't need temporary arrays anymore, Free */
3767
void wolfSSL_FreeArrays(WOLFSSL* ssl)
3768
0
{
3769
0
    if (ssl && ssl->options.handShakeState == HANDSHAKE_DONE) {
3770
0
        ssl->options.saveArrays = 0;
3771
0
        FreeArrays(ssl, 1);
3772
0
    }
3773
0
}
3774
3775
/* Set option to indicate that the resources are not to be freed after
3776
 * handshake.
3777
 *
3778
 * ssl  The SSL/TLS object.
3779
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3780
 */
3781
int wolfSSL_KeepHandshakeResources(WOLFSSL* ssl)
3782
0
{
3783
0
    if (ssl == NULL)
3784
0
        return BAD_FUNC_ARG;
3785
3786
0
    ssl->options.keepResources = 1;
3787
3788
0
    return 0;
3789
0
}
3790
3791
/* Free the handshake resources after handshake.
3792
 *
3793
 * ssl  The SSL/TLS object.
3794
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3795
 */
3796
int wolfSSL_FreeHandshakeResources(WOLFSSL* ssl)
3797
0
{
3798
0
    if (ssl == NULL)
3799
0
        return BAD_FUNC_ARG;
3800
3801
0
    FreeHandshakeResources(ssl);
3802
3803
0
    return 0;
3804
0
}
3805
3806
/* Use the client's order of preference when matching cipher suites.
3807
 *
3808
 * ssl  The SSL/TLS context object.
3809
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3810
 */
3811
int wolfSSL_CTX_UseClientSuites(WOLFSSL_CTX* ctx)
3812
0
{
3813
0
    if (ctx == NULL)
3814
0
        return BAD_FUNC_ARG;
3815
3816
0
    ctx->useClientOrder = 1;
3817
3818
0
    return 0;
3819
0
}
3820
3821
/* Use the client's order of preference when matching cipher suites.
3822
 *
3823
 * ssl  The SSL/TLS object.
3824
 * returns BAD_FUNC_ARG when ssl is NULL and 0 on success.
3825
 */
3826
int wolfSSL_UseClientSuites(WOLFSSL* ssl)
3827
0
{
3828
0
    if (ssl == NULL)
3829
0
        return BAD_FUNC_ARG;
3830
3831
0
    ssl->options.useClientOrder = 1;
3832
3833
0
    return 0;
3834
0
}
3835
3836
#ifdef WOLFSSL_DTLS
3837
const byte* wolfSSL_GetDtlsMacSecret(WOLFSSL* ssl, int verify, int epochOrder)
3838
{
3839
#ifndef WOLFSSL_AEAD_ONLY
3840
    Keys* keys = NULL;
3841
3842
    (void)epochOrder;
3843
3844
    if (ssl == NULL)
3845
        return NULL;
3846
3847
#ifdef HAVE_SECURE_RENEGOTIATION
3848
    switch (epochOrder) {
3849
    case PEER_ORDER:
3850
        if (IsDtlsMsgSCRKeys(ssl))
3851
            keys = &ssl->secure_renegotiation->tmp_keys;
3852
        else
3853
            keys = &ssl->keys;
3854
        break;
3855
    case PREV_ORDER:
3856
        keys = &ssl->keys;
3857
        break;
3858
    case CUR_ORDER:
3859
        if (DtlsUseSCRKeys(ssl))
3860
            keys = &ssl->secure_renegotiation->tmp_keys;
3861
        else
3862
            keys = &ssl->keys;
3863
        break;
3864
    default:
3865
        WOLFSSL_MSG("Unknown epoch order");
3866
        return NULL;
3867
    }
3868
#else
3869
    keys = &ssl->keys;
3870
#endif
3871
3872
    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
3873
         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
3874
        return keys->client_write_MAC_secret;
3875
    else
3876
        return keys->server_write_MAC_secret;
3877
#else
3878
    (void)ssl;
3879
    (void)verify;
3880
    (void)epochOrder;
3881
3882
    return NULL;
3883
#endif
3884
}
3885
#endif /* WOLFSSL_DTLS */
3886
3887
const byte* wolfSSL_GetMacSecret(WOLFSSL* ssl, int verify)
3888
0
{
3889
0
#ifndef WOLFSSL_AEAD_ONLY
3890
0
    if (ssl == NULL)
3891
0
        return NULL;
3892
3893
0
    if ( (ssl->options.side == WOLFSSL_CLIENT_END && !verify) ||
3894
0
         (ssl->options.side == WOLFSSL_SERVER_END &&  verify) )
3895
0
        return ssl->keys.client_write_MAC_secret;
3896
0
    else
3897
0
        return ssl->keys.server_write_MAC_secret;
3898
#else
3899
    (void)ssl;
3900
    (void)verify;
3901
3902
    return NULL;
3903
#endif
3904
0
}
3905
3906
3907
#ifdef ATOMIC_USER
3908
3909
void  wolfSSL_CTX_SetMacEncryptCb(WOLFSSL_CTX* ctx, CallbackMacEncrypt cb)
3910
{
3911
    if (ctx)
3912
        ctx->MacEncryptCb = cb;
3913
}
3914
3915
3916
void  wolfSSL_SetMacEncryptCtx(WOLFSSL* ssl, void *ctx)
3917
{
3918
    if (ssl)
3919
        ssl->MacEncryptCtx = ctx;
3920
}
3921
3922
3923
void* wolfSSL_GetMacEncryptCtx(WOLFSSL* ssl)
3924
{
3925
    if (ssl)
3926
        return ssl->MacEncryptCtx;
3927
3928
    return NULL;
3929
}
3930
3931
3932
void  wolfSSL_CTX_SetDecryptVerifyCb(WOLFSSL_CTX* ctx, CallbackDecryptVerify cb)
3933
{
3934
    if (ctx)
3935
        ctx->DecryptVerifyCb = cb;
3936
}
3937
3938
3939
void  wolfSSL_SetDecryptVerifyCtx(WOLFSSL* ssl, void *ctx)
3940
{
3941
    if (ssl)
3942
        ssl->DecryptVerifyCtx = ctx;
3943
}
3944
3945
3946
void* wolfSSL_GetDecryptVerifyCtx(WOLFSSL* ssl)
3947
{
3948
    if (ssl)
3949
        return ssl->DecryptVerifyCtx;
3950
3951
    return NULL;
3952
}
3953
3954
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
3955
/**
3956
 * Set the callback, against the context, that encrypts then MACs.
3957
 *
3958
 * ctx  SSL/TLS context.
3959
 * cb   Callback function to use with Encrypt-Then-MAC.
3960
 */
3961
void  wolfSSL_CTX_SetEncryptMacCb(WOLFSSL_CTX* ctx, CallbackEncryptMac cb)
3962
{
3963
    if (ctx)
3964
        ctx->EncryptMacCb = cb;
3965
}
3966
3967
/**
3968
 * Set the context to use with callback that encrypts then MACs.
3969
 *
3970
 * ssl  SSL/TLS object.
3971
 * ctx  Callback function's context.
3972
 */
3973
void  wolfSSL_SetEncryptMacCtx(WOLFSSL* ssl, void *ctx)
3974
{
3975
    if (ssl)
3976
        ssl->EncryptMacCtx = ctx;
3977
}
3978
3979
/**
3980
 * Get the context being used with callback that encrypts then MACs.
3981
 *
3982
 * ssl  SSL/TLS object.
3983
 * returns callback function's context or NULL if SSL/TLS object is NULL.
3984
 */
3985
void* wolfSSL_GetEncryptMacCtx(WOLFSSL* ssl)
3986
{
3987
    if (ssl)
3988
        return ssl->EncryptMacCtx;
3989
3990
    return NULL;
3991
}
3992
3993
3994
/**
3995
 * Set the callback, against the context, that MAC verifies then decrypts.
3996
 *
3997
 * ctx  SSL/TLS context.
3998
 * cb   Callback function to use with Encrypt-Then-MAC.
3999
 */
4000
void  wolfSSL_CTX_SetVerifyDecryptCb(WOLFSSL_CTX* ctx, CallbackVerifyDecrypt cb)
4001
{
4002
    if (ctx)
4003
        ctx->VerifyDecryptCb = cb;
4004
}
4005
4006
/**
4007
 * Set the context to use with callback that MAC verifies then decrypts.
4008
 *
4009
 * ssl  SSL/TLS object.
4010
 * ctx  Callback function's context.
4011
 */
4012
void  wolfSSL_SetVerifyDecryptCtx(WOLFSSL* ssl, void *ctx)
4013
{
4014
    if (ssl)
4015
        ssl->VerifyDecryptCtx = ctx;
4016
}
4017
4018
/**
4019
 * Get the context being used with callback that MAC verifies then decrypts.
4020
 *
4021
 * ssl  SSL/TLS object.
4022
 * returns callback function's context or NULL if SSL/TLS object is NULL.
4023
 */
4024
void* wolfSSL_GetVerifyDecryptCtx(WOLFSSL* ssl)
4025
{
4026
    if (ssl)
4027
        return ssl->VerifyDecryptCtx;
4028
4029
    return NULL;
4030
}
4031
#endif /* HAVE_ENCRYPT_THEN_MAC !WOLFSSL_AEAD_ONLY */
4032
4033
4034
4035
const byte* wolfSSL_GetClientWriteKey(WOLFSSL* ssl)
4036
{
4037
    if (ssl)
4038
        return ssl->keys.client_write_key;
4039
4040
    return NULL;
4041
}
4042
4043
4044
const byte* wolfSSL_GetClientWriteIV(WOLFSSL* ssl)
4045
{
4046
    if (ssl)
4047
        return ssl->keys.client_write_IV;
4048
4049
    return NULL;
4050
}
4051
4052
4053
const byte* wolfSSL_GetServerWriteKey(WOLFSSL* ssl)
4054
{
4055
    if (ssl)
4056
        return ssl->keys.server_write_key;
4057
4058
    return NULL;
4059
}
4060
4061
4062
const byte* wolfSSL_GetServerWriteIV(WOLFSSL* ssl)
4063
{
4064
    if (ssl)
4065
        return ssl->keys.server_write_IV;
4066
4067
    return NULL;
4068
}
4069
4070
int wolfSSL_GetKeySize(WOLFSSL* ssl)
4071
{
4072
    if (ssl)
4073
        return ssl->specs.key_size;
4074
4075
    return BAD_FUNC_ARG;
4076
}
4077
4078
4079
int wolfSSL_GetIVSize(WOLFSSL* ssl)
4080
{
4081
    if (ssl)
4082
        return ssl->specs.iv_size;
4083
4084
    return BAD_FUNC_ARG;
4085
}
4086
4087
4088
int wolfSSL_GetBulkCipher(WOLFSSL* ssl)
4089
{
4090
    if (ssl)
4091
        return ssl->specs.bulk_cipher_algorithm;
4092
4093
    return BAD_FUNC_ARG;
4094
}
4095
4096
4097
int wolfSSL_GetCipherType(WOLFSSL* ssl)
4098
{
4099
    if (ssl == NULL)
4100
        return BAD_FUNC_ARG;
4101
4102
#ifndef WOLFSSL_AEAD_ONLY
4103
    if (ssl->specs.cipher_type == block)
4104
        return WOLFSSL_BLOCK_TYPE;
4105
    if (ssl->specs.cipher_type == stream)
4106
        return WOLFSSL_STREAM_TYPE;
4107
#endif
4108
    if (ssl->specs.cipher_type == aead)
4109
        return WOLFSSL_AEAD_TYPE;
4110
4111
    return -1;
4112
}
4113
4114
4115
int wolfSSL_GetCipherBlockSize(WOLFSSL* ssl)
4116
{
4117
    if (ssl == NULL)
4118
        return BAD_FUNC_ARG;
4119
4120
    return ssl->specs.block_size;
4121
}
4122
4123
4124
int wolfSSL_GetAeadMacSize(WOLFSSL* ssl)
4125
{
4126
    if (ssl == NULL)
4127
        return BAD_FUNC_ARG;
4128
4129
    return ssl->specs.aead_mac_size;
4130
}
4131
4132
4133
int wolfSSL_IsTLSv1_1(WOLFSSL* ssl)
4134
{
4135
    if (ssl == NULL)
4136
        return BAD_FUNC_ARG;
4137
4138
    if (ssl->options.tls1_1)
4139
        return 1;
4140
4141
    return 0;
4142
}
4143
4144
4145
int wolfSSL_GetSide(WOLFSSL* ssl)
4146
{
4147
    if (ssl)
4148
        return ssl->options.side;
4149
4150
    return BAD_FUNC_ARG;
4151
}
4152
4153
4154
int wolfSSL_GetHmacSize(WOLFSSL* ssl)
4155
{
4156
    /* AEAD ciphers don't have HMAC keys */
4157
    if (ssl)
4158
        return (ssl->specs.cipher_type != aead) ? ssl->specs.hash_size : 0;
4159
4160
    return BAD_FUNC_ARG;
4161
}
4162
4163
#ifdef WORD64_AVAILABLE
4164
int wolfSSL_GetPeerSequenceNumber(WOLFSSL* ssl, word64 *seq)
4165
{
4166
    if ((ssl == NULL) || (seq == NULL))
4167
        return BAD_FUNC_ARG;
4168
4169
    *seq = ((word64)ssl->keys.peer_sequence_number_hi << 32) |
4170
                    ssl->keys.peer_sequence_number_lo;
4171
    return !(*seq);
4172
}
4173
4174
int wolfSSL_GetSequenceNumber(WOLFSSL* ssl, word64 *seq)
4175
{
4176
    if ((ssl == NULL) || (seq == NULL))
4177
        return BAD_FUNC_ARG;
4178
4179
    *seq = ((word64)ssl->keys.sequence_number_hi << 32) |
4180
                    ssl->keys.sequence_number_lo;
4181
    return !(*seq);
4182
}
4183
#endif
4184
4185
#endif /* ATOMIC_USER */
4186
4187
#ifndef NO_CERTS
4188
4189
WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
4190
0
{
4191
0
    WOLFSSL_CERT_MANAGER* cm = NULL;
4192
0
    if (ctx)
4193
0
        cm = ctx->cm;
4194
0
    return cm;
4195
0
}
4196
4197
WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap)
4198
0
{
4199
0
    WOLFSSL_CERT_MANAGER* cm;
4200
4201
0
    WOLFSSL_ENTER("wolfSSL_CertManagerNew");
4202
4203
0
    cm = (WOLFSSL_CERT_MANAGER*) XMALLOC(sizeof(WOLFSSL_CERT_MANAGER), heap,
4204
0
                                         DYNAMIC_TYPE_CERT_MANAGER);
4205
0
    if (cm) {
4206
0
        XMEMSET(cm, 0, sizeof(WOLFSSL_CERT_MANAGER));
4207
0
        cm->refCount = 1;
4208
4209
0
        if (wc_InitMutex(&cm->caLock) != 0) {
4210
0
            WOLFSSL_MSG("Bad mutex init");
4211
0
            wolfSSL_CertManagerFree(cm);
4212
0
            return NULL;
4213
0
        }
4214
0
        #ifndef SINGLE_THREADED
4215
0
        if (wc_InitMutex(&cm->refMutex) != 0) {
4216
0
            WOLFSSL_MSG("Bad mutex init");
4217
0
            wolfSSL_CertManagerFree(cm);
4218
0
            return NULL;
4219
0
        }
4220
0
        #endif
4221
4222
        #ifdef WOLFSSL_TRUST_PEER_CERT
4223
        if (wc_InitMutex(&cm->tpLock) != 0) {
4224
            WOLFSSL_MSG("Bad mutex init");
4225
            wolfSSL_CertManagerFree(cm);
4226
            return NULL;
4227
        }
4228
        #endif
4229
4230
        /* set default minimum key size allowed */
4231
0
        #ifndef NO_RSA
4232
0
            cm->minRsaKeySz = MIN_RSAKEY_SZ;
4233
0
        #endif
4234
0
        #ifdef HAVE_ECC
4235
0
            cm->minEccKeySz = MIN_ECCKEY_SZ;
4236
0
        #endif
4237
        #ifdef HAVE_PQC
4238
        #ifdef HAVE_FALCON
4239
            cm->minFalconKeySz = MIN_FALCONKEY_SZ;
4240
        #endif /* HAVE_FALCON */
4241
        #ifdef HAVE_DILITHIUM
4242
            cm->minDilithiumKeySz = MIN_DILITHIUMKEY_SZ;
4243
        #endif /* HAVE_DILITHIUM */
4244
        #endif /* HAVE_PQC */
4245
4246
0
            cm->heap = heap;
4247
0
    }
4248
4249
0
    return cm;
4250
0
}
4251
4252
4253
WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew(void)
4254
0
{
4255
0
    return wolfSSL_CertManagerNew_ex(NULL);
4256
0
}
4257
4258
4259
void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
4260
0
{
4261
0
    int doFree = 0;
4262
0
    WOLFSSL_ENTER("wolfSSL_CertManagerFree");
4263
4264
0
    if (cm) {
4265
0
        #ifndef SINGLE_THREADED
4266
0
        if (wc_LockMutex(&cm->refMutex) != 0) {
4267
0
            WOLFSSL_MSG("Couldn't lock cm mutex");
4268
0
        }
4269
0
        #endif
4270
0
        cm->refCount--;
4271
0
        if (cm->refCount == 0)
4272
0
            doFree = 1;
4273
0
        #ifndef SINGLE_THREADED
4274
0
        wc_UnLockMutex(&cm->refMutex);
4275
0
        #endif
4276
0
        if (doFree) {
4277
            #ifdef HAVE_CRL
4278
                if (cm->crl)
4279
                    FreeCRL(cm->crl, 1);
4280
            #endif
4281
0
            #ifdef HAVE_OCSP
4282
0
                if (cm->ocsp)
4283
0
                    FreeOCSP(cm->ocsp, 1);
4284
0
                XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
4285
            #if !defined(NO_WOLFSSL_SERVER) && \
4286
                (defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
4287
                 defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
4288
                if (cm->ocsp_stapling)
4289
                    FreeOCSP(cm->ocsp_stapling, 1);
4290
            #endif
4291
0
            #endif
4292
0
            FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
4293
0
            wc_FreeMutex(&cm->caLock);
4294
4295
            #ifdef WOLFSSL_TRUST_PEER_CERT
4296
            FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
4297
            wc_FreeMutex(&cm->tpLock);
4298
            #endif
4299
0
            #ifndef SINGLE_THREADED
4300
0
            if (wc_FreeMutex(&cm->refMutex) != 0) {
4301
0
                WOLFSSL_MSG("Couldn't free refMutex mutex");
4302
0
            }
4303
0
            #endif
4304
0
            XFREE(cm, cm->heap, DYNAMIC_TYPE_CERT_MANAGER);
4305
0
        }
4306
0
    }
4307
4308
0
}
4309
4310
int wolfSSL_CertManager_up_ref(WOLFSSL_CERT_MANAGER* cm)
4311
0
{
4312
0
    if (cm) {
4313
0
#ifndef SINGLE_THREADED
4314
0
        if (wc_LockMutex(&cm->refMutex) != 0) {
4315
0
            WOLFSSL_MSG("Failed to lock cm mutex");
4316
0
            return WOLFSSL_FAILURE;
4317
0
        }
4318
0
#endif
4319
0
        cm->refCount++;
4320
0
#ifndef SINGLE_THREADED
4321
0
        wc_UnLockMutex(&cm->refMutex);
4322
0
#endif
4323
4324
0
        return WOLFSSL_SUCCESS;
4325
0
    }
4326
4327
0
    return WOLFSSL_FAILURE;
4328
0
}
4329
4330
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
4331
#if defined(WOLFSSL_SIGNER_DER_CERT)
4332
/******************************************************************************
4333
* wolfSSL_CertManagerGetCerts - retrieve stack of X509 certificates in a
4334
* certificate manager (CM).
4335
*
4336
* RETURNS:
4337
* returns stack of X509 certs on success, otherwise returns a NULL.
4338
*/
4339
WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm)
4340
{
4341
    WOLFSSL_STACK* sk = NULL;
4342
    int numCerts = 0;
4343
    DerBuffer** certBuffers = NULL;
4344
    const byte* derBuffer = NULL;
4345
    Signer* signers = NULL;
4346
    word32  row = 0;
4347
    WOLFSSL_X509* x509 = NULL;
4348
    int i = 0;
4349
    int ret = 0;
4350
4351
    if (cm == NULL)
4352
        return NULL;
4353
4354
    sk = wolfSSL_sk_X509_new();
4355
    if (sk == NULL)
4356
        goto error;
4357
4358
    if (wc_LockMutex(&cm->caLock) != 0)
4359
        goto error;
4360
4361
    /* Iterate once to get the number of certs, for memory allocation
4362
       purposes. */
4363
    for (row = 0; row < CA_TABLE_SIZE; row++) {
4364
        signers = cm->caTable[row];
4365
        while (signers && signers->derCert && signers->derCert->buffer) {
4366
            ++numCerts;
4367
            signers = signers->next;
4368
        }
4369
    }
4370
4371
    if (numCerts == 0) {
4372
        wc_UnLockMutex(&cm->caLock);
4373
        goto error;
4374
    }
4375
4376
    certBuffers = (DerBuffer**)XMALLOC(sizeof(DerBuffer*) * numCerts, cm->heap,
4377
                                       DYNAMIC_TYPE_TMP_BUFFER);
4378
    if (certBuffers == NULL) {
4379
        wc_UnLockMutex(&cm->caLock);
4380
        goto error;
4381
    }
4382
    XMEMSET(certBuffers, 0, sizeof(DerBuffer*) * numCerts);
4383
4384
    /* Copy the certs locally so that we can release the caLock. If the lock is
4385
       held when wolfSSL_d2i_X509 is called, GetCA will also try to get the
4386
       lock, leading to deadlock. */
4387
    for (row = 0; row < CA_TABLE_SIZE; row++) {
4388
        signers = cm->caTable[row];
4389
        while (signers && signers->derCert && signers->derCert->buffer) {
4390
            ret = AllocDer(&certBuffers[i], signers->derCert->length, CA_TYPE,
4391
                           cm->heap);
4392
            if (ret < 0) {
4393
                wc_UnLockMutex(&cm->caLock);
4394
                goto error;
4395
            }
4396
4397
            XMEMCPY(certBuffers[i]->buffer, signers->derCert->buffer,
4398
                    signers->derCert->length);
4399
            certBuffers[i]->length = signers->derCert->length;
4400
4401
            ++i;
4402
            signers = signers->next;
4403
        }
4404
    }
4405
4406
    wc_UnLockMutex(&cm->caLock);
4407
4408
    for (i = 0; i < numCerts; ++i) {
4409
        derBuffer = certBuffers[i]->buffer;
4410
        wolfSSL_d2i_X509(&x509, &derBuffer, certBuffers[i]->length);
4411
        if (x509 == NULL)
4412
            goto error;
4413
4414
        if (wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS)
4415
            goto error;
4416
    }
4417
4418
    for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
4419
        FreeDer(&certBuffers[i]);
4420
    }
4421
4422
    XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4423
4424
    return sk;
4425
4426
error:
4427
    if (sk)
4428
        wolfSSL_sk_X509_pop_free(sk, NULL);
4429
4430
    if (certBuffers != NULL) {
4431
        for (i = 0; i < numCerts && certBuffers[i] != NULL; ++i) {
4432
            FreeDer(&certBuffers[i]);
4433
        }
4434
    }
4435
4436
    if (certBuffers)
4437
        XFREE(certBuffers, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
4438
4439
    return NULL;
4440
}
4441
4442
#endif /* WOLFSSL_SIGNER_DER_CERT */
4443
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
4444
4445
/* Unload the CA signer list */
4446
int wolfSSL_CertManagerUnloadCAs(WOLFSSL_CERT_MANAGER* cm)
4447
0
{
4448
0
    WOLFSSL_ENTER("wolfSSL_CertManagerUnloadCAs");
4449
4450
0
    if (cm == NULL)
4451
0
        return BAD_FUNC_ARG;
4452
4453
0
    if (wc_LockMutex(&cm->caLock) != 0)
4454
0
        return BAD_MUTEX_E;
4455
4456
0
    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
4457
4458
0
    wc_UnLockMutex(&cm->caLock);
4459
4460
4461
0
    return WOLFSSL_SUCCESS;
4462
0
}
4463
4464
4465
#ifdef WOLFSSL_TRUST_PEER_CERT
4466
int wolfSSL_CertManagerUnload_trust_peers(WOLFSSL_CERT_MANAGER* cm)
4467
{
4468
    WOLFSSL_ENTER("wolfSSL_CertManagerUnload_trust_peers");
4469
4470
    if (cm == NULL)
4471
        return BAD_FUNC_ARG;
4472
4473
    if (wc_LockMutex(&cm->tpLock) != 0)
4474
        return BAD_MUTEX_E;
4475
4476
    FreeTrustedPeerTable(cm->tpTable, TP_TABLE_SIZE, cm->heap);
4477
4478
    wc_UnLockMutex(&cm->tpLock);
4479
4480
4481
    return WOLFSSL_SUCCESS;
4482
}
4483
#endif /* WOLFSSL_TRUST_PEER_CERT */
4484
4485
#endif /* NO_CERTS */
4486
4487
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
4488
4489
void wolfSSL_ERR_print_errors_fp(XFILE fp, int err)
4490
0
{
4491
0
    char data[WOLFSSL_MAX_ERROR_SZ + 1];
4492
4493
0
    WOLFSSL_ENTER("wolfSSL_ERR_print_errors_fp");
4494
0
    SetErrorString(err, data);
4495
0
    if (XFPRINTF(fp, "%s", data) < 0)
4496
0
        WOLFSSL_MSG("fprintf failed in wolfSSL_ERR_print_errors_fp");
4497
0
}
4498
4499
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
4500
void wolfSSL_ERR_dump_errors_fp(XFILE fp)
4501
0
{
4502
0
    wc_ERR_print_errors_fp(fp);
4503
0
}
4504
4505
void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len,
4506
                                            void *u), void *u)
4507
0
{
4508
0
    wc_ERR_print_errors_cb(cb, u);
4509
0
}
4510
#endif
4511
#endif
4512
4513
/*
4514
 * TODO This ssl parameter needs to be changed to const once our ABI checker
4515
 *      stops flagging qualifier additions as ABI breaking.
4516
 */
4517
WOLFSSL_ABI
4518
int wolfSSL_pending(WOLFSSL* ssl)
4519
0
{
4520
0
    WOLFSSL_ENTER("SSL_pending");
4521
0
    if (ssl == NULL)
4522
0
        return WOLFSSL_FAILURE;
4523
4524
0
    return ssl->buffers.clearOutputBuffer.length;
4525
0
}
4526
4527
int wolfSSL_has_pending(const WOLFSSL* ssl)
4528
0
{
4529
0
    WOLFSSL_ENTER("wolfSSL_has_pending");
4530
0
    if (ssl == NULL)
4531
0
        return WOLFSSL_FAILURE;
4532
4533
0
    return ssl->buffers.clearOutputBuffer.length > 0;
4534
0
}
4535
4536
#ifndef WOLFSSL_LEANPSK
4537
/* turn on handshake group messages for context */
4538
int wolfSSL_CTX_set_group_messages(WOLFSSL_CTX* ctx)
4539
0
{
4540
0
    if (ctx == NULL)
4541
0
       return BAD_FUNC_ARG;
4542
4543
0
    ctx->groupMessages = 1;
4544
4545
0
    return WOLFSSL_SUCCESS;
4546
0
}
4547
#endif
4548
4549
4550
#ifndef NO_WOLFSSL_CLIENT
4551
/* connect enough to get peer cert chain */
4552
int wolfSSL_connect_cert(WOLFSSL* ssl)
4553
0
{
4554
0
    int  ret;
4555
4556
0
    if (ssl == NULL)
4557
0
        return WOLFSSL_FAILURE;
4558
4559
0
    ssl->options.certOnly = 1;
4560
0
    ret = wolfSSL_connect(ssl);
4561
0
    ssl->options.certOnly   = 0;
4562
4563
0
    return ret;
4564
0
}
4565
#endif
4566
4567
4568
#ifndef WOLFSSL_LEANPSK
4569
/* turn on handshake group messages for ssl object */
4570
int wolfSSL_set_group_messages(WOLFSSL* ssl)
4571
0
{
4572
0
    if (ssl == NULL)
4573
0
       return BAD_FUNC_ARG;
4574
4575
0
    ssl->options.groupMessages = 1;
4576
4577
0
    return WOLFSSL_SUCCESS;
4578
0
}
4579
4580
4581
/* make minVersion the internal equivalent SSL version */
4582
static int SetMinVersionHelper(byte* minVersion, int version)
4583
0
{
4584
#ifdef NO_TLS
4585
    (void)minVersion;
4586
#endif
4587
4588
0
    switch (version) {
4589
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4590
        case WOLFSSL_SSLV3:
4591
            *minVersion = SSLv3_MINOR;
4592
            break;
4593
#endif
4594
4595
0
#ifndef NO_TLS
4596
0
    #ifndef NO_OLD_TLS
4597
        #ifdef WOLFSSL_ALLOW_TLSV10
4598
        case WOLFSSL_TLSV1:
4599
            *minVersion = TLSv1_MINOR;
4600
            break;
4601
        #endif
4602
4603
0
        case WOLFSSL_TLSV1_1:
4604
0
            *minVersion = TLSv1_1_MINOR;
4605
0
            break;
4606
0
    #endif
4607
0
    #ifndef WOLFSSL_NO_TLS12
4608
0
        case WOLFSSL_TLSV1_2:
4609
0
            *minVersion = TLSv1_2_MINOR;
4610
0
            break;
4611
0
    #endif
4612
0
#endif
4613
0
    #ifdef WOLFSSL_TLS13
4614
0
        case WOLFSSL_TLSV1_3:
4615
0
            *minVersion = TLSv1_3_MINOR;
4616
0
            break;
4617
0
    #endif
4618
4619
#ifdef WOLFSSL_DTLS
4620
        case WOLFSSL_DTLSV1:
4621
            *minVersion = DTLS_MINOR;
4622
            break;
4623
        case WOLFSSL_DTLSV1_2:
4624
            *minVersion = DTLSv1_2_MINOR;
4625
            break;
4626
#ifdef WOLFSSL_DTLS13
4627
        case WOLFSSL_DTLSV1_3:
4628
            *minVersion = DTLSv1_3_MINOR;
4629
            break;
4630
#endif /* WOLFSSL_DTLS13 */
4631
#endif /* WOLFSSL_DTLS */
4632
4633
0
        default:
4634
0
            WOLFSSL_MSG("Bad function argument");
4635
0
            return BAD_FUNC_ARG;
4636
0
    }
4637
4638
0
    return WOLFSSL_SUCCESS;
4639
0
}
4640
4641
4642
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
4643
WOLFSSL_ABI
4644
int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX* ctx, int version)
4645
0
{
4646
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetMinVersion");
4647
4648
0
    if (ctx == NULL) {
4649
0
        WOLFSSL_MSG("Bad function argument");
4650
0
        return BAD_FUNC_ARG;
4651
0
    }
4652
4653
0
    return SetMinVersionHelper(&ctx->minDowngrade, version);
4654
0
}
4655
4656
4657
/* Set minimum downgrade version allowed, WOLFSSL_SUCCESS on ok */
4658
int wolfSSL_SetMinVersion(WOLFSSL* ssl, int version)
4659
0
{
4660
0
    WOLFSSL_ENTER("wolfSSL_SetMinVersion");
4661
4662
0
    if (ssl == NULL) {
4663
0
        WOLFSSL_MSG("Bad function argument");
4664
0
        return BAD_FUNC_ARG;
4665
0
    }
4666
4667
0
    return SetMinVersionHelper(&ssl->options.minDowngrade, version);
4668
0
}
4669
4670
4671
/* Function to get version as WOLFSSL_ enum value for wolfSSL_SetVersion */
4672
int wolfSSL_GetVersion(const WOLFSSL* ssl)
4673
0
{
4674
0
    if (ssl == NULL)
4675
0
        return BAD_FUNC_ARG;
4676
4677
0
    if (ssl->version.major == SSLv3_MAJOR) {
4678
0
        switch (ssl->version.minor) {
4679
0
            case SSLv3_MINOR :
4680
0
                return WOLFSSL_SSLV3;
4681
0
            case TLSv1_MINOR :
4682
0
                return WOLFSSL_TLSV1;
4683
0
            case TLSv1_1_MINOR :
4684
0
                return WOLFSSL_TLSV1_1;
4685
0
            case TLSv1_2_MINOR :
4686
0
                return WOLFSSL_TLSV1_2;
4687
0
            case TLSv1_3_MINOR :
4688
0
                return WOLFSSL_TLSV1_3;
4689
0
            default:
4690
0
                break;
4691
0
        }
4692
0
    }
4693
4694
0
    return VERSION_ERROR;
4695
0
}
4696
4697
int wolfSSL_SetVersion(WOLFSSL* ssl, int version)
4698
0
{
4699
0
    word16 haveRSA = 1;
4700
0
    word16 havePSK = 0;
4701
0
    int    keySz   = 0;
4702
4703
0
    WOLFSSL_ENTER("wolfSSL_SetVersion");
4704
4705
0
    if (ssl == NULL) {
4706
0
        WOLFSSL_MSG("Bad function argument");
4707
0
        return BAD_FUNC_ARG;
4708
0
    }
4709
4710
0
    switch (version) {
4711
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
4712
        case WOLFSSL_SSLV3:
4713
            ssl->version = MakeSSLv3();
4714
            break;
4715
#endif
4716
4717
0
#ifndef NO_TLS
4718
0
    #ifndef NO_OLD_TLS
4719
        #ifdef WOLFSSL_ALLOW_TLSV10
4720
        case WOLFSSL_TLSV1:
4721
            ssl->version = MakeTLSv1();
4722
            break;
4723
        #endif
4724
4725
0
        case WOLFSSL_TLSV1_1:
4726
0
            ssl->version = MakeTLSv1_1();
4727
0
            break;
4728
0
    #endif
4729
0
    #ifndef WOLFSSL_NO_TLS12
4730
0
        case WOLFSSL_TLSV1_2:
4731
0
            ssl->version = MakeTLSv1_2();
4732
0
            break;
4733
0
    #endif
4734
4735
0
    #ifdef WOLFSSL_TLS13
4736
0
        case WOLFSSL_TLSV1_3:
4737
0
            ssl->version = MakeTLSv1_3();
4738
0
            break;
4739
0
    #endif /* WOLFSSL_TLS13 */
4740
0
#endif
4741
4742
0
        default:
4743
0
            WOLFSSL_MSG("Bad function argument");
4744
0
            return BAD_FUNC_ARG;
4745
0
    }
4746
4747
    #ifdef NO_RSA
4748
        haveRSA = 0;
4749
    #endif
4750
    #ifndef NO_PSK
4751
        havePSK = ssl->options.havePSK;
4752
    #endif
4753
0
    #ifndef NO_CERTS
4754
0
        keySz = ssl->buffers.keySz;
4755
0
    #endif
4756
4757
0
    InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
4758
0
               ssl->options.haveDH, ssl->options.haveECDSAsig,
4759
0
               ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
4760
0
               ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
4761
0
               ssl->options.haveAnon, TRUE, ssl->options.side);
4762
0
    return WOLFSSL_SUCCESS;
4763
0
}
4764
#endif /* !leanpsk */
4765
4766
#ifndef NO_CERTS
4767
4768
/* hash is the SHA digest of name, just use first 32 bits as hash */
4769
static WC_INLINE word32 HashSigner(const byte* hash)
4770
0
{
4771
0
    return MakeWordFromHash(hash) % CA_TABLE_SIZE;
4772
0
}
4773
4774
4775
/* does CA already exist on signer list */
4776
int AlreadySigner(WOLFSSL_CERT_MANAGER* cm, byte* hash)
4777
0
{
4778
0
    Signer* signers;
4779
0
    int     ret = 0;
4780
0
    word32  row;
4781
4782
0
    if (cm == NULL || hash == NULL) {
4783
0
        return ret;
4784
0
    }
4785
4786
0
    row = HashSigner(hash);
4787
4788
0
    if (wc_LockMutex(&cm->caLock) != 0) {
4789
0
        return ret;
4790
0
    }
4791
0
    signers = cm->caTable[row];
4792
0
    while (signers) {
4793
0
        byte* subjectHash;
4794
4795
0
    #ifndef NO_SKID
4796
0
        subjectHash = signers->subjectKeyIdHash;
4797
    #else
4798
        subjectHash = signers->subjectNameHash;
4799
    #endif
4800
4801
0
        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4802
0
            ret = 1; /* success */
4803
0
            break;
4804
0
        }
4805
0
        signers = signers->next;
4806
0
    }
4807
0
    wc_UnLockMutex(&cm->caLock);
4808
4809
0
    return ret;
4810
0
}
4811
4812
4813
#ifdef WOLFSSL_TRUST_PEER_CERT
4814
/* hash is the SHA digest of name, just use first 32 bits as hash */
4815
static WC_INLINE word32 TrustedPeerHashSigner(const byte* hash)
4816
{
4817
    return MakeWordFromHash(hash) % TP_TABLE_SIZE;
4818
}
4819
4820
/* does trusted peer already exist on signer list */
4821
int AlreadyTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DecodedCert* cert)
4822
{
4823
    TrustedPeerCert* tp;
4824
    int     ret = 0;
4825
    word32  row = TrustedPeerHashSigner(cert->subjectHash);
4826
4827
    if (wc_LockMutex(&cm->tpLock) != 0)
4828
        return  ret;
4829
    tp = cm->tpTable[row];
4830
    while (tp) {
4831
        if (XMEMCMP(cert->subjectHash, tp->subjectNameHash,
4832
                SIGNER_DIGEST_SIZE) == 0)
4833
            ret = 1;
4834
    #ifndef NO_SKID
4835
        if (cert->extSubjKeyIdSet) {
4836
            /* Compare SKID as well if available */
4837
            if (ret == 1 && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
4838
                    SIGNER_DIGEST_SIZE) != 0)
4839
                ret = 0;
4840
        }
4841
    #endif
4842
        if (ret == 1)
4843
            break;
4844
        tp = tp->next;
4845
    }
4846
    wc_UnLockMutex(&cm->tpLock);
4847
4848
    return ret;
4849
}
4850
4851
4852
/* return Trusted Peer if found, otherwise NULL
4853
    type is what to match on
4854
 */
4855
TrustedPeerCert* GetTrustedPeer(void* vp, DecodedCert* cert)
4856
{
4857
    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4858
    TrustedPeerCert* ret = NULL;
4859
    TrustedPeerCert* tp  = NULL;
4860
    word32  row;
4861
4862
    if (cm == NULL || cert == NULL)
4863
        return NULL;
4864
4865
    row = TrustedPeerHashSigner(cert->subjectHash);
4866
4867
    if (wc_LockMutex(&cm->tpLock) != 0)
4868
        return ret;
4869
4870
    tp = cm->tpTable[row];
4871
    while (tp) {
4872
        if (XMEMCMP(cert->subjectHash, tp->subjectNameHash,
4873
                SIGNER_DIGEST_SIZE) == 0)
4874
            ret = tp;
4875
    #ifndef NO_SKID
4876
        if (cert->extSubjKeyIdSet) {
4877
            /* Compare SKID as well if available */
4878
            if (ret != NULL && XMEMCMP(cert->extSubjKeyId, tp->subjectKeyIdHash,
4879
                    SIGNER_DIGEST_SIZE) != 0)
4880
                ret = NULL;
4881
        }
4882
    #endif
4883
        if (ret != NULL)
4884
            break;
4885
        tp = tp->next;
4886
    }
4887
    wc_UnLockMutex(&cm->tpLock);
4888
4889
    return ret;
4890
}
4891
4892
4893
int MatchTrustedPeer(TrustedPeerCert* tp, DecodedCert* cert)
4894
{
4895
    if (tp == NULL || cert == NULL)
4896
        return BAD_FUNC_ARG;
4897
4898
    /* subject key id or subject hash has been compared when searching
4899
       tpTable for the cert from function GetTrustedPeer */
4900
4901
    /* compare signatures */
4902
    if (tp->sigLen == cert->sigLength) {
4903
        if (XMEMCMP(tp->sig, cert->signature, cert->sigLength)) {
4904
            return WOLFSSL_FAILURE;
4905
        }
4906
    }
4907
    else {
4908
        return WOLFSSL_FAILURE;
4909
    }
4910
4911
    return WOLFSSL_SUCCESS;
4912
}
4913
#endif /* WOLFSSL_TRUST_PEER_CERT */
4914
4915
4916
/* return CA if found, otherwise NULL */
4917
Signer* GetCA(void* vp, byte* hash)
4918
0
{
4919
0
    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4920
0
    Signer* ret = NULL;
4921
0
    Signer* signers;
4922
0
    word32  row = 0;
4923
4924
0
    if (cm == NULL || hash == NULL)
4925
0
        return NULL;
4926
4927
0
    row = HashSigner(hash);
4928
4929
0
    if (wc_LockMutex(&cm->caLock) != 0)
4930
0
        return ret;
4931
4932
0
    signers = cm->caTable[row];
4933
0
    while (signers) {
4934
0
        byte* subjectHash;
4935
0
        #ifndef NO_SKID
4936
0
            subjectHash = signers->subjectKeyIdHash;
4937
        #else
4938
            subjectHash = signers->subjectNameHash;
4939
        #endif
4940
0
        if (XMEMCMP(hash, subjectHash, SIGNER_DIGEST_SIZE) == 0) {
4941
0
            ret = signers;
4942
0
            break;
4943
0
        }
4944
0
        signers = signers->next;
4945
0
    }
4946
0
    wc_UnLockMutex(&cm->caLock);
4947
4948
0
    return ret;
4949
0
}
4950
4951
4952
#ifndef NO_SKID
4953
/* return CA if found, otherwise NULL. Walk through hash table. */
4954
Signer* GetCAByName(void* vp, byte* hash)
4955
0
{
4956
0
    WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)vp;
4957
0
    Signer* ret = NULL;
4958
0
    Signer* signers;
4959
0
    word32  row;
4960
4961
0
    if (cm == NULL)
4962
0
        return NULL;
4963
4964
0
    if (wc_LockMutex(&cm->caLock) != 0)
4965
0
        return ret;
4966
4967
0
    for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
4968
0
        signers = cm->caTable[row];
4969
0
        while (signers && ret == NULL) {
4970
0
            if (XMEMCMP(hash, signers->subjectNameHash,
4971
0
                        SIGNER_DIGEST_SIZE) == 0) {
4972
0
                ret = signers;
4973
0
            }
4974
0
            signers = signers->next;
4975
0
        }
4976
0
    }
4977
0
    wc_UnLockMutex(&cm->caLock);
4978
4979
0
    return ret;
4980
0
}
4981
#endif
4982
4983
4984
#ifdef WOLFSSL_TRUST_PEER_CERT
4985
/* add a trusted peer cert to linked list */
4986
int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
4987
{
4988
    int ret, row;
4989
    TrustedPeerCert* peerCert;
4990
    DecodedCert* cert;
4991
    DerBuffer*   der = *pDer;
4992
4993
    WOLFSSL_MSG("Adding a Trusted Peer Cert");
4994
4995
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
4996
                                 DYNAMIC_TYPE_DCERT);
4997
    if (cert == NULL) {
4998
        FreeDer(&der);
4999
        return MEMORY_E;
5000
    }
5001
5002
    InitDecodedCert(cert, der->buffer, der->length, cm->heap);
5003
    if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) {
5004
        FreeDecodedCert(cert);
5005
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
5006
        FreeDer(&der);
5007
        return ret;
5008
    }
5009
    WOLFSSL_MSG("\tParsed new trusted peer cert");
5010
5011
    peerCert = (TrustedPeerCert*)XMALLOC(sizeof(TrustedPeerCert), cm->heap,
5012
                                                             DYNAMIC_TYPE_CERT);
5013
    if (peerCert == NULL) {
5014
        FreeDecodedCert(cert);
5015
        XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5016
        FreeDer(&der);
5017
        return MEMORY_E;
5018
    }
5019
    XMEMSET(peerCert, 0, sizeof(TrustedPeerCert));
5020
5021
    #ifndef IGNORE_NAME_CONSTRAINTS
5022
        if (peerCert->permittedNames)
5023
            FreeNameSubtrees(peerCert->permittedNames, cm->heap);
5024
        if (peerCert->excludedNames)
5025
            FreeNameSubtrees(peerCert->excludedNames, cm->heap);
5026
    #endif
5027
5028
    if (AlreadyTrustedPeer(cm, cert)) {
5029
        WOLFSSL_MSG("\tAlready have this CA, not adding again");
5030
        FreeTrustedPeer(peerCert, cm->heap);
5031
        (void)ret;
5032
    }
5033
    else {
5034
        /* add trusted peer signature */
5035
        peerCert->sigLen = cert->sigLength;
5036
        peerCert->sig = (byte *)XMALLOC(cert->sigLength, cm->heap,
5037
                                                        DYNAMIC_TYPE_SIGNATURE);
5038
        if (peerCert->sig == NULL) {
5039
            FreeDecodedCert(cert);
5040
            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5041
            FreeTrustedPeer(peerCert, cm->heap);
5042
            FreeDer(&der);
5043
            return MEMORY_E;
5044
        }
5045
        XMEMCPY(peerCert->sig, cert->signature, cert->sigLength);
5046
5047
        /* add trusted peer name */
5048
        peerCert->nameLen = cert->subjectCNLen;
5049
        peerCert->name    = cert->subjectCN;
5050
        #ifndef IGNORE_NAME_CONSTRAINTS
5051
            peerCert->permittedNames = cert->permittedNames;
5052
            peerCert->excludedNames  = cert->excludedNames;
5053
        #endif
5054
5055
        /* add SKID when available and hash of name */
5056
        #ifndef NO_SKID
5057
            XMEMCPY(peerCert->subjectKeyIdHash, cert->extSubjKeyId,
5058
                    SIGNER_DIGEST_SIZE);
5059
        #endif
5060
            XMEMCPY(peerCert->subjectNameHash, cert->subjectHash,
5061
                    SIGNER_DIGEST_SIZE);
5062
            peerCert->next    = NULL; /* If Key Usage not set, all uses valid. */
5063
            cert->subjectCN = 0;
5064
        #ifndef IGNORE_NAME_CONSTRAINTS
5065
            cert->permittedNames = NULL;
5066
            cert->excludedNames = NULL;
5067
        #endif
5068
5069
            row = TrustedPeerHashSigner(peerCert->subjectNameHash);
5070
5071
            if (wc_LockMutex(&cm->tpLock) == 0) {
5072
                peerCert->next = cm->tpTable[row];
5073
                cm->tpTable[row] = peerCert;   /* takes ownership */
5074
                wc_UnLockMutex(&cm->tpLock);
5075
            }
5076
            else {
5077
                WOLFSSL_MSG("\tTrusted Peer Cert Mutex Lock failed");
5078
                FreeDecodedCert(cert);
5079
                XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5080
                FreeTrustedPeer(peerCert, cm->heap);
5081
                FreeDer(&der);
5082
                return BAD_MUTEX_E;
5083
            }
5084
        }
5085
5086
    WOLFSSL_MSG("\tFreeing parsed trusted peer cert");
5087
    FreeDecodedCert(cert);
5088
    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
5089
    WOLFSSL_MSG("\tFreeing der trusted peer cert");
5090
    FreeDer(&der);
5091
    WOLFSSL_MSG("\t\tOK Freeing der trusted peer cert");
5092
    WOLFSSL_LEAVE("AddTrustedPeer", ret);
5093
5094
    return WOLFSSL_SUCCESS;
5095
}
5096
#endif /* WOLFSSL_TRUST_PEER_CERT */
5097
5098
5099
/* owns der, internal now uses too */
5100
/* type flag ids from user or from chain received during verify
5101
   don't allow chain ones to be added w/o isCA extension */
5102
int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
5103
0
{
5104
0
    int         ret;
5105
0
    Signer*     signer = NULL;
5106
0
    word32      row;
5107
0
    byte*       subjectHash;
5108
0
#ifdef WOLFSSL_SMALL_STACK
5109
0
    DecodedCert* cert = NULL;
5110
#else
5111
    DecodedCert  cert[1];
5112
#endif
5113
0
    DerBuffer*   der = *pDer;
5114
5115
0
    WOLFSSL_MSG("Adding a CA");
5116
5117
0
    if (cm == NULL) {
5118
0
        FreeDer(pDer);
5119
0
        return BAD_FUNC_ARG;
5120
0
    }
5121
5122
0
#ifdef WOLFSSL_SMALL_STACK
5123
0
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
5124
0
                                 DYNAMIC_TYPE_DCERT);
5125
0
    if (cert == NULL) {
5126
0
        FreeDer(pDer);
5127
0
        return MEMORY_E;
5128
0
    }
5129
0
#endif
5130
5131
0
    InitDecodedCert(cert, der->buffer, der->length, cm->heap);
5132
0
    ret = ParseCert(cert, CA_TYPE, verify, cm);
5133
0
    WOLFSSL_MSG("\tParsed new CA");
5134
5135
0
#ifndef NO_SKID
5136
0
    subjectHash = cert->extSubjKeyId;
5137
#else
5138
    subjectHash = cert->subjectHash;
5139
#endif
5140
5141
    /* check CA key size */
5142
0
    if (verify) {
5143
0
        switch (cert->keyOID) {
5144
0
        #ifndef NO_RSA
5145
0
            #ifdef WC_RSA_PSS
5146
0
            case RSAPSSk:
5147
0
            #endif
5148
0
            case RSAk:
5149
0
                if (cm->minRsaKeySz < 0 ||
5150
0
                                   cert->pubKeySize < (word16)cm->minRsaKeySz) {
5151
0
                    ret = RSA_KEY_SIZE_E;
5152
0
                    WOLFSSL_MSG("\tCA RSA key size error");
5153
0
                }
5154
0
                break;
5155
0
        #endif /* !NO_RSA */
5156
0
            #ifdef HAVE_ECC
5157
0
            case ECDSAk:
5158
0
                if (cm->minEccKeySz < 0 ||
5159
0
                                   cert->pubKeySize < (word16)cm->minEccKeySz) {
5160
0
                    ret = ECC_KEY_SIZE_E;
5161
0
                    WOLFSSL_MSG("\tCA ECC key size error");
5162
0
                }
5163
0
                break;
5164
0
            #endif /* HAVE_ECC */
5165
0
            #ifdef HAVE_ED25519
5166
0
            case ED25519k:
5167
0
                if (cm->minEccKeySz < 0 ||
5168
0
                                   ED25519_KEY_SIZE < (word16)cm->minEccKeySz) {
5169
0
                    ret = ECC_KEY_SIZE_E;
5170
0
                    WOLFSSL_MSG("\tCA ECC key size error");
5171
0
                }
5172
0
                break;
5173
0
            #endif /* HAVE_ED25519 */
5174
0
            #ifdef HAVE_ED448
5175
0
            case ED448k:
5176
0
                if (cm->minEccKeySz < 0 ||
5177
0
                                     ED448_KEY_SIZE < (word16)cm->minEccKeySz) {
5178
0
                    ret = ECC_KEY_SIZE_E;
5179
0
                    WOLFSSL_MSG("\tCA ECC key size error");
5180
0
                }
5181
0
                break;
5182
0
            #endif /* HAVE_ED448 */
5183
            #if defined(HAVE_PQC)
5184
            #if defined(HAVE_FALCON)
5185
            case FALCON_LEVEL1k:
5186
                if (cm->minFalconKeySz < 0 ||
5187
                          FALCON_LEVEL1_KEY_SIZE < (word16)cm->minFalconKeySz) {
5188
                    ret = FALCON_KEY_SIZE_E;
5189
                    WOLFSSL_MSG("\tCA Falcon level 1 key size error");
5190
                }
5191
                break;
5192
            case FALCON_LEVEL5k:
5193
                if (cm->minFalconKeySz < 0 ||
5194
                          FALCON_LEVEL5_KEY_SIZE < (word16)cm->minFalconKeySz) {
5195
                    ret = FALCON_KEY_SIZE_E;
5196
                    WOLFSSL_MSG("\tCA Falcon level 5 key size error");
5197
                }
5198
                break;
5199
            #endif /* HAVE_FALCON */
5200
            #if defined(HAVE_DILITHIUM)
5201
            case DILITHIUM_LEVEL2k:
5202
            case DILITHIUM_AES_LEVEL2k:
5203
                if (cm->minDilithiumKeySz < 0 ||
5204
                    DILITHIUM_LEVEL2_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
5205
                    ret = DILITHIUM_KEY_SIZE_E;
5206
                    WOLFSSL_MSG("\tCA Dilithium level 2 key size error");
5207
                }
5208
                break;
5209
            case DILITHIUM_LEVEL3k:
5210
            case DILITHIUM_AES_LEVEL3k:
5211
                if (cm->minDilithiumKeySz < 0 ||
5212
                    DILITHIUM_LEVEL3_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
5213
                    ret = DILITHIUM_KEY_SIZE_E;
5214
                    WOLFSSL_MSG("\tCA Dilithium level 3 key size error");
5215
                }
5216
                break;
5217
            case DILITHIUM_LEVEL5k:
5218
            case DILITHIUM_AES_LEVEL5k:
5219
                if (cm->minDilithiumKeySz < 0 ||
5220
                    DILITHIUM_LEVEL5_KEY_SIZE < (word16)cm->minDilithiumKeySz) {
5221
                    ret = DILITHIUM_KEY_SIZE_E;
5222
                    WOLFSSL_MSG("\tCA Dilithium level 5 key size error");
5223
                }
5224
                break;
5225
            #endif /* HAVE_DILITHIUM */
5226
            #endif /* HAVE_PQC */
5227
5228
0
            default:
5229
0
                WOLFSSL_MSG("\tNo key size check done on CA");
5230
0
                break; /* no size check if key type is not in switch */
5231
0
        }
5232
0
    }
5233
5234
0
    if (ret == 0 && cert->isCA == 0 && type != WOLFSSL_USER_CA) {
5235
0
        WOLFSSL_MSG("\tCan't add as CA if not actually one");
5236
0
        ret = NOT_CA_ERROR;
5237
0
    }
5238
0
#ifndef ALLOW_INVALID_CERTSIGN
5239
0
    else if (ret == 0 && cert->isCA == 1 && type != WOLFSSL_USER_CA &&
5240
0
        !cert->selfSigned && (cert->extKeyUsage & KEYUSE_KEY_CERT_SIGN) == 0) {
5241
        /* Intermediate CA certs are required to have the keyCertSign
5242
        * extension set. User loaded root certs are not. */
5243
0
        WOLFSSL_MSG("\tDoesn't have key usage certificate signing");
5244
0
        ret = NOT_CA_ERROR;
5245
0
    }
5246
0
#endif
5247
0
    else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
5248
0
        WOLFSSL_MSG("\tAlready have this CA, not adding again");
5249
0
        (void)ret;
5250
0
    }
5251
0
    else if (ret == 0) {
5252
        /* take over signer parts */
5253
0
        signer = MakeSigner(cm->heap);
5254
0
        if (!signer)
5255
0
            ret = MEMORY_ERROR;
5256
0
    }
5257
0
    if (ret == 0 && signer != NULL) {
5258
    #ifdef WOLFSSL_SIGNER_DER_CERT
5259
        ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
5260
    }
5261
    if (ret == 0 && signer != NULL) {
5262
        XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
5263
    #endif
5264
0
        signer->keyOID         = cert->keyOID;
5265
0
        if (cert->pubKeyStored) {
5266
0
            signer->publicKey      = cert->publicKey;
5267
0
            signer->pubKeySize     = cert->pubKeySize;
5268
0
        }
5269
0
        if (cert->subjectCNStored) {
5270
0
            signer->nameLen        = cert->subjectCNLen;
5271
0
            signer->name           = cert->subjectCN;
5272
0
        }
5273
0
        signer->pathLength     = cert->pathLength;
5274
0
        signer->maxPathLen     = cert->maxPathLen;
5275
0
        signer->pathLengthSet  = cert->pathLengthSet;
5276
0
        signer->selfSigned     = cert->selfSigned;
5277
0
    #ifndef IGNORE_NAME_CONSTRAINTS
5278
0
        signer->permittedNames = cert->permittedNames;
5279
0
        signer->excludedNames  = cert->excludedNames;
5280
0
    #endif
5281
0
    #ifndef NO_SKID
5282
0
        XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
5283
0
                SIGNER_DIGEST_SIZE);
5284
0
    #endif
5285
0
        XMEMCPY(signer->subjectNameHash, cert->subjectHash,
5286
0
                SIGNER_DIGEST_SIZE);
5287
0
    #ifdef HAVE_OCSP
5288
0
        XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash,
5289
0
                KEYID_SIZE);
5290
0
    #endif
5291
0
        signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
5292
0
                                                : 0xFFFF;
5293
0
        signer->next    = NULL; /* If Key Usage not set, all uses valid. */
5294
0
        cert->publicKey = 0;    /* in case lock fails don't free here.   */
5295
0
        cert->subjectCN = 0;
5296
0
    #ifndef IGNORE_NAME_CONSTRAINTS
5297
0
        cert->permittedNames = NULL;
5298
0
        cert->excludedNames = NULL;
5299
0
    #endif
5300
5301
0
    #ifndef NO_SKID
5302
0
        row = HashSigner(signer->subjectKeyIdHash);
5303
    #else
5304
        row = HashSigner(signer->subjectNameHash);
5305
    #endif
5306
5307
0
        if (wc_LockMutex(&cm->caLock) == 0) {
5308
0
            signer->next = cm->caTable[row];
5309
0
            cm->caTable[row] = signer;   /* takes ownership */
5310
0
            wc_UnLockMutex(&cm->caLock);
5311
0
            if (cm->caCacheCallback)
5312
0
                cm->caCacheCallback(der->buffer, (int)der->length, type);
5313
0
        }
5314
0
        else {
5315
0
            WOLFSSL_MSG("\tCA Mutex Lock failed");
5316
0
            ret = BAD_MUTEX_E;
5317
0
            FreeSigner(signer, cm->heap);
5318
0
        }
5319
0
    }
5320
#if defined(WOLFSSL_RENESAS_TSIP_TLS) || defined(WOLFSSL_RENESAS_SCEPROTECT)
5321
    /* Verify CA by TSIP so that generated tsip key is going to be able to */
5322
    /* be used for peer's cert verification                                */
5323
    /* TSIP is only able to handle USER CA, and only one CA.               */
5324
    /* Therefore, it doesn't need to call TSIP again if there is already   */
5325
    /* verified CA.                                                        */
5326
    if ( ret == 0 && signer != NULL ) {
5327
        signer->cm_idx = row;
5328
        if (type == WOLFSSL_USER_CA) {
5329
            if ((ret = wc_Renesas_cmn_RootCertVerify(cert->source, cert->maxIdx,
5330
                 cert->sigCtx.CertAtt.pubkey_n_start,
5331
                 cert->sigCtx.CertAtt.pubkey_n_len - 1,
5332
                 cert->sigCtx.CertAtt.pubkey_e_start,
5333
                cert->sigCtx.CertAtt.pubkey_e_len - 1,
5334
                 row/* cm index */))
5335
                < 0)
5336
                WOLFSSL_MSG("Renesas_RootCertVerify() failed");
5337
            else
5338
                WOLFSSL_MSG("Renesas_RootCertVerify() succeed or skipped");
5339
        }
5340
    }
5341
#endif /* TSIP or SCE */
5342
5343
0
    WOLFSSL_MSG("\tFreeing Parsed CA");
5344
0
    FreeDecodedCert(cert);
5345
0
#ifdef WOLFSSL_SMALL_STACK
5346
0
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
5347
0
#endif
5348
0
    WOLFSSL_MSG("\tFreeing der CA");
5349
0
    FreeDer(pDer);
5350
0
    WOLFSSL_MSG("\t\tOK Freeing der CA");
5351
5352
0
    WOLFSSL_LEAVE("AddCA", ret);
5353
5354
0
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
5355
0
}
5356
5357
#endif /* !NO_CERTS */
5358
5359
5360
#ifndef NO_SESSION_CACHE
5361
5362
    /* basic config gives a cache with 33 sessions, adequate for clients and
5363
       embedded servers
5364
5365
       TITAN_SESSION_CACHE allows just over 2 million sessions, for servers
5366
       with titanic amounts of memory with long session ID timeouts and high
5367
       levels of traffic.
5368
5369
       ENABLE_SESSION_CACHE_ROW_LOCK: Allows row level locking for increased
5370
       performance with large session caches
5371
5372
       HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
5373
       allows over 13,000 new sessions per minute or over 200 new sessions per
5374
       second
5375
5376
       BIG_SESSION_CACHE yields 20,027 sessions
5377
5378
       MEDIUM_SESSION_CACHE allows 1055 sessions, adequate for servers that
5379
       aren't under heavy load, basically allows 200 new sessions per minute
5380
5381
       SMALL_SESSION_CACHE only stores 6 sessions, good for embedded clients
5382
       or systems where the default of nearly 3kB is too much RAM, this define
5383
       uses less than 500 bytes RAM
5384
5385
       default SESSION_CACHE stores 33 sessions (no XXX_SESSION_CACHE defined)
5386
    */
5387
    #if defined(TITAN_SESSION_CACHE)
5388
        #define SESSIONS_PER_ROW 31
5389
        #define SESSION_ROWS 64937
5390
        #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5391
        #define ENABLE_SESSION_CACHE_ROW_LOCK
5392
        #endif
5393
    #elif defined(HUGE_SESSION_CACHE)
5394
        #define SESSIONS_PER_ROW 11
5395
        #define SESSION_ROWS 5981
5396
    #elif defined(BIG_SESSION_CACHE)
5397
        #define SESSIONS_PER_ROW 7
5398
        #define SESSION_ROWS 2861
5399
    #elif defined(MEDIUM_SESSION_CACHE)
5400
        #define SESSIONS_PER_ROW 5
5401
        #define SESSION_ROWS 211
5402
    #elif defined(SMALL_SESSION_CACHE)
5403
        #define SESSIONS_PER_ROW 2
5404
        #define SESSION_ROWS 3
5405
    #else
5406
0
        #define SESSIONS_PER_ROW 3
5407
0
        #define SESSION_ROWS 11
5408
    #endif
5409
0
    #define INVALID_SESSION_ROW (-1)
5410
5411
    #ifdef NO_SESSION_CACHE_ROW_LOCK
5412
        #undef ENABLE_SESSION_CACHE_ROW_LOCK
5413
    #endif
5414
5415
    typedef struct SessionRow {
5416
        int nextIdx;                           /* where to place next one   */
5417
        int totalCount;                        /* sessions ever on this row */
5418
        WOLFSSL_SESSION Sessions[SESSIONS_PER_ROW];
5419
5420
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5421
        /* not included in import/export */
5422
        wolfSSL_Mutex row_mutex;
5423
        int mutex_valid;
5424
    #endif
5425
    } SessionRow;
5426
    #define SIZEOF_SESSION_ROW (sizeof(WOLFSSL_SESSION) + (sizeof(int) * 2))
5427
5428
    static WOLFSSL_GLOBAL SessionRow SessionCache[SESSION_ROWS];
5429
5430
    #if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
5431
        static WOLFSSL_GLOBAL word32 PeakSessions;
5432
    #endif
5433
5434
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5435
    #define SESSION_ROW_LOCK(row)   wc_LockMutex(&(row)->row_mutex)
5436
    #define SESSION_ROW_UNLOCK(row) wc_UnLockMutex(&(row)->row_mutex);
5437
    #else
5438
    static WOLFSSL_GLOBAL wolfSSL_Mutex session_mutex; /* SessionCache mutex */
5439
    static WOLFSSL_GLOBAL int session_mutex_valid = 0;
5440
0
    #define SESSION_ROW_LOCK(row)   wc_LockMutex(&session_mutex)
5441
0
    #define SESSION_ROW_UNLOCK(row) wc_UnLockMutex(&session_mutex);
5442
    #endif
5443
5444
    #if !defined(NO_SESSION_CACHE_REF) && defined(NO_CLIENT_CACHE)
5445
    #error ClientCache is required when not using NO_SESSION_CACHE_REF
5446
    #endif
5447
5448
    #ifndef NO_CLIENT_CACHE
5449
5450
        #ifndef CLIENT_SESSIONS_MULTIPLIER
5451
            #ifdef NO_SESSION_CACHE_REF
5452
                #define CLIENT_SESSIONS_MULTIPLIER 1
5453
            #else
5454
                /* ClientSession objects are lightweight (compared to
5455
                 * WOLFSSL_SESSION) so to decrease chance that user will reuse
5456
                 * thse wrong session, increase the ClientCache size. This will
5457
                 * make the entire ClientCache about the size of one
5458
                 * WOLFSSL_SESSION object. */
5459
0
                #define CLIENT_SESSIONS_MULTIPLIER 8
5460
            #endif
5461
        #endif
5462
        #define CLIENT_SESSIONS_PER_ROW \
5463
0
                                (SESSIONS_PER_ROW * CLIENT_SESSIONS_MULTIPLIER)
5464
0
        #define CLIENT_SESSION_ROWS (SESSION_ROWS * CLIENT_SESSIONS_MULTIPLIER)
5465
5466
        #if CLIENT_SESSIONS_PER_ROW > 65535
5467
        #error CLIENT_SESSIONS_PER_ROW too big
5468
        #endif
5469
        #if CLIENT_SESSION_ROWS > 65535
5470
        #error CLIENT_SESSION_ROWS too big
5471
        #endif
5472
5473
        struct ClientSession {
5474
            word16 serverRow;            /* SessionCache Row id */
5475
            word16 serverIdx;            /* SessionCache Idx (column) */
5476
            word32 sessionIDHash;
5477
        };
5478
    #ifndef WOLFSSL_CLIENT_SESSION_DEFINED
5479
        typedef struct ClientSession ClientSession;
5480
        #define WOLFSSL_CLIENT_SESSION_DEFINED
5481
    #endif
5482
5483
        typedef struct ClientRow {
5484
            int nextIdx;                /* where to place next one   */
5485
            int totalCount;             /* sessions ever on this row */
5486
            ClientSession Clients[CLIENT_SESSIONS_PER_ROW];
5487
        } ClientRow;
5488
5489
        static WOLFSSL_GLOBAL ClientRow ClientCache[CLIENT_SESSION_ROWS];
5490
                                                     /* Client Cache */
5491
                                                     /* uses session mutex */
5492
5493
        static WOLFSSL_GLOBAL wolfSSL_Mutex clisession_mutex; /* ClientCache mutex */
5494
        static WOLFSSL_GLOBAL int clisession_mutex_valid = 0;
5495
    #endif /* !NO_CLIENT_CACHE */
5496
5497
#endif /* !NO_SESSION_CACHE */
5498
5499
#if !defined(WC_NO_RNG) && (defined(OPENSSL_EXTRA) || \
5500
    (defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA)))
5501
5502
    #define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
5503
    static WC_RNG globalRNG;
5504
    static int initGlobalRNG = 0;
5505
    static wolfSSL_Mutex globalRNGMutex;
5506
    static int globalRNGMutex_valid = 0;
5507
5508
    #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
5509
    static WOLFSSL_DRBG_CTX* gDrbgDefCtx = NULL;
5510
    #endif
5511
5512
    WC_RNG* wolfssl_get_global_rng(void)
5513
0
    {
5514
0
        WC_RNG* ret = NULL;
5515
5516
0
        if (initGlobalRNG == 0)
5517
0
            WOLFSSL_MSG("Global RNG no Init");
5518
0
        else
5519
0
            ret = &globalRNG;
5520
5521
0
        return ret;
5522
0
    }
5523
#endif
5524
5525
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
5526
static int wolfSSL_RAND_InitMutex(void);
5527
#endif
5528
5529
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
5530
static void AtExitCleanup(void)
5531
0
{
5532
0
    if (initRefCount > 0) {
5533
0
        initRefCount = 1;
5534
0
        (void)wolfSSL_Cleanup();
5535
0
    }
5536
0
}
5537
#endif
5538
5539
WOLFSSL_ABI
5540
int wolfSSL_Init(void)
5541
0
{
5542
0
    int ret = WOLFSSL_SUCCESS;
5543
#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
5544
    int i;
5545
#endif
5546
5547
0
    WOLFSSL_ENTER("wolfSSL_Init");
5548
5549
    #if FIPS_VERSION_GE(5,1)
5550
        ret = wolfCrypt_SetPrivateKeyReadEnable_fips(1, WC_KEYTYPE_ALL);
5551
        if (ret != 0)
5552
            return ret;
5553
        else
5554
            ret = WOLFSSL_SUCCESS;
5555
    #endif
5556
5557
0
    if (initRefCount == 0) {
5558
        /* Initialize crypto for use with TLS connection */
5559
0
        if (wolfCrypt_Init() != 0) {
5560
0
            WOLFSSL_MSG("Bad wolfCrypt Init");
5561
0
            ret = WC_INIT_E;
5562
0
        }
5563
5564
0
#ifdef HAVE_GLOBAL_RNG
5565
0
        if (ret == WOLFSSL_SUCCESS) {
5566
0
            if (wc_InitMutex(&globalRNGMutex) != 0) {
5567
0
                WOLFSSL_MSG("Bad Init Mutex rng");
5568
0
                ret = BAD_MUTEX_E;
5569
0
            }
5570
0
            else {
5571
0
                globalRNGMutex_valid = 1;
5572
0
            }
5573
0
        }
5574
0
#endif
5575
5576
    #ifdef WC_RNG_SEED_CB
5577
        wc_SetSeed_Cb(wc_GenerateSeed);
5578
    #endif
5579
5580
0
#ifdef OPENSSL_EXTRA
5581
0
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
5582
0
        if ((ret == WOLFSSL_SUCCESS) && (wolfSSL_RAND_InitMutex() != 0)) {
5583
0
            ret = BAD_MUTEX_E;
5584
0
        }
5585
0
    #endif
5586
0
        if ((ret == WOLFSSL_SUCCESS) &&
5587
0
            (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS)) {
5588
0
            WOLFSSL_MSG("wolfSSL_RAND_Seed failed");
5589
0
            ret = WC_INIT_E;
5590
0
        }
5591
0
#endif
5592
5593
0
#ifndef NO_SESSION_CACHE
5594
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
5595
        for (i = 0; i < SESSION_ROWS; ++i) {
5596
            SessionCache[i].mutex_valid = 0;
5597
        }
5598
        for (i = 0; (ret == WOLFSSL_SUCCESS) && (i < SESSION_ROWS); ++i) {
5599
            if (wc_InitMutex(&SessionCache[i].row_mutex) != 0) {
5600
                WOLFSSL_MSG("Bad Init Mutex session");
5601
                ret = BAD_MUTEX_E;
5602
            }
5603
            else {
5604
                SessionCache[i].mutex_valid = 1;
5605
            }
5606
        }
5607
    #else
5608
0
        if (ret == WOLFSSL_SUCCESS) {
5609
0
            if (wc_InitMutex(&session_mutex) != 0) {
5610
0
                WOLFSSL_MSG("Bad Init Mutex session");
5611
0
                ret = BAD_MUTEX_E;
5612
0
            }
5613
0
            else {
5614
0
                session_mutex_valid = 1;
5615
0
            }
5616
0
        }
5617
0
    #endif
5618
0
    #ifndef NO_CLIENT_CACHE
5619
0
        if (ret == WOLFSSL_SUCCESS) {
5620
0
            if (wc_InitMutex(&clisession_mutex) != 0) {
5621
0
                WOLFSSL_MSG("Bad Init Mutex session");
5622
0
                ret = BAD_MUTEX_E;
5623
0
            }
5624
0
            else {
5625
0
                clisession_mutex_valid = 1;
5626
0
            }
5627
0
        }
5628
0
    #endif
5629
0
#endif
5630
0
        if (ret == WOLFSSL_SUCCESS) {
5631
0
            if (wc_InitMutex(&count_mutex) != 0) {
5632
0
                WOLFSSL_MSG("Bad Init Mutex count");
5633
0
                ret = BAD_MUTEX_E;
5634
0
            }
5635
0
            else {
5636
0
                count_mutex_valid = 1;
5637
0
            }
5638
0
        }
5639
0
#if defined(OPENSSL_EXTRA) && defined(HAVE_ATEXIT)
5640
        /* OpenSSL registers cleanup using atexit */
5641
0
        if ((ret == WOLFSSL_SUCCESS) && (atexit(AtExitCleanup) != 0)) {
5642
0
            WOLFSSL_MSG("Bad atexit registration");
5643
0
            ret = WC_INIT_E;
5644
0
        }
5645
0
#endif
5646
0
    }
5647
5648
0
    if (ret == WOLFSSL_SUCCESS) {
5649
0
        if (wc_LockMutex(&count_mutex) != 0) {
5650
0
            WOLFSSL_MSG("Bad Lock Mutex count");
5651
0
            ret = BAD_MUTEX_E;
5652
0
        }
5653
0
        else {
5654
0
            initRefCount++;
5655
0
            wc_UnLockMutex(&count_mutex);
5656
0
        }
5657
0
    }
5658
5659
0
    if (ret != WOLFSSL_SUCCESS) {
5660
0
        initRefCount = 1; /* Force cleanup */
5661
0
        (void)wolfSSL_Cleanup(); /* Ignore any error from cleanup */
5662
0
    }
5663
5664
0
    return ret;
5665
0
}
5666
5667
5668
#ifndef NO_CERTS
5669
5670
/* process user cert chain to pass during the handshake */
5671
static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff,
5672
                         long sz, int format, int type, WOLFSSL* ssl,
5673
                         long* used, EncryptedInfo* info, int verify)
5674
0
{
5675
0
    int ret = 0;
5676
0
    void* heap = wolfSSL_CTX_GetHeap(ctx, ssl);
5677
0
#ifdef WOLFSSL_TLS13
5678
0
    int cnt = 0;
5679
0
#endif
5680
5681
0
    if ((type == CA_TYPE) && (ctx == NULL)) {
5682
0
        WOLFSSL_MSG("Need context for CA load");
5683
0
        return BAD_FUNC_ARG;
5684
0
    }
5685
5686
    /* we may have a user cert chain, try to consume */
5687
0
    if ((type == CERT_TYPE || type == CA_TYPE) && (info->consumed < sz)) {
5688
0
    #ifdef WOLFSSL_SMALL_STACK
5689
0
        byte   staticBuffer[1];                 /* force heap usage */
5690
    #else
5691
        byte   staticBuffer[FILE_BUFFER_SIZE];  /* tmp chain buffer */
5692
    #endif
5693
0
        byte*  chainBuffer = staticBuffer;
5694
0
        int    dynamicBuffer = 0;
5695
0
        word32 bufferSz;
5696
0
        long   consumed = info->consumed;
5697
0
        word32 idx = 0;
5698
0
        int    gotOne = 0;
5699
5700
        /* Calculate max possible size, including max headers */
5701
0
        bufferSz = (word32)(sz - consumed) + (CERT_HEADER_SZ * MAX_CHAIN_DEPTH);
5702
0
        if (bufferSz > sizeof(staticBuffer)) {
5703
0
            WOLFSSL_MSG("Growing Tmp Chain Buffer");
5704
            /* will shrink to actual size */
5705
0
            chainBuffer = (byte*)XMALLOC(bufferSz, heap, DYNAMIC_TYPE_FILE);
5706
0
            if (chainBuffer == NULL) {
5707
0
                return MEMORY_E;
5708
0
            }
5709
0
            dynamicBuffer = 1;
5710
0
        }
5711
5712
0
        WOLFSSL_MSG("Processing Cert Chain");
5713
0
        while (consumed < sz) {
5714
0
            DerBuffer* part = NULL;
5715
0
            word32 remain = (word32)(sz - consumed);
5716
0
            info->consumed = 0;
5717
5718
0
            if (format == WOLFSSL_FILETYPE_PEM) {
5719
0
            #ifdef WOLFSSL_PEM_TO_DER
5720
0
                ret = PemToDer(buff + consumed, remain, type, &part,
5721
0
                               heap, info, NULL);
5722
            #else
5723
                ret = NOT_COMPILED_IN;
5724
            #endif
5725
0
            }
5726
0
            else {
5727
0
                int length = remain;
5728
0
                if (format == WOLFSSL_FILETYPE_ASN1) {
5729
                    /* get length of der (read sequence) */
5730
0
                    word32 inOutIdx = 0;
5731
0
                    if (GetSequence(buff + consumed, &inOutIdx, &length,
5732
0
                            remain) < 0) {
5733
0
                        ret = ASN_NO_PEM_HEADER;
5734
0
                    }
5735
0
                    length += inOutIdx; /* include leading sequence */
5736
0
                }
5737
0
                info->consumed = length;
5738
0
                if (ret == 0) {
5739
0
                    ret = AllocDer(&part, length, type, heap);
5740
0
                    if (ret == 0) {
5741
0
                        XMEMCPY(part->buffer, buff + consumed, length);
5742
0
                    }
5743
0
                }
5744
0
            }
5745
0
            if (ret == 0) {
5746
0
                gotOne = 1;
5747
0
#ifdef WOLFSSL_TLS13
5748
0
                cnt++;
5749
0
#endif
5750
0
                if ((idx + part->length + CERT_HEADER_SZ) > bufferSz) {
5751
0
                    WOLFSSL_MSG("   Cert Chain bigger than buffer. "
5752
0
                                "Consider increasing MAX_CHAIN_DEPTH");
5753
0
                    ret = BUFFER_E;
5754
0
                }
5755
0
                else {
5756
0
                    c32to24(part->length, &chainBuffer[idx]);
5757
0
                    idx += CERT_HEADER_SZ;
5758
0
                    XMEMCPY(&chainBuffer[idx], part->buffer, part->length);
5759
0
                    idx += part->length;
5760
0
                    consumed  += info->consumed;
5761
0
                    if (used)
5762
0
                        *used += info->consumed;
5763
0
                }
5764
5765
                /* add CA's to certificate manager */
5766
0
                if (ret == 0 && type == CA_TYPE) {
5767
                    /* verify CA unless user set to no verify */
5768
0
                    ret = AddCA(ctx->cm, &part, WOLFSSL_USER_CA, verify);
5769
0
                    if (ret == WOLFSSL_SUCCESS) {
5770
0
                        ret = 0; /* converted success case */
5771
0
                    }
5772
0
                    gotOne = 0; /* don't exit loop for CA type */
5773
0
                }
5774
0
            }
5775
5776
0
            FreeDer(&part);
5777
5778
0
            if (ret == ASN_NO_PEM_HEADER && gotOne) {
5779
0
                WOLFSSL_MSG("We got one good cert, so stuff at end ok");
5780
0
                break;
5781
0
            }
5782
5783
0
            if (ret < 0) {
5784
0
                WOLFSSL_MSG("   Error in Cert in Chain");
5785
0
                if (dynamicBuffer)
5786
0
                    XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
5787
0
                return ret;
5788
0
            }
5789
0
            WOLFSSL_MSG("   Consumed another Cert in Chain");
5790
0
        }
5791
0
        WOLFSSL_MSG("Finished Processing Cert Chain");
5792
5793
        /* only retain actual size used */
5794
0
        ret = 0;
5795
0
        if (idx > 0) {
5796
0
            if (ssl) {
5797
0
                if (ssl->buffers.weOwnCertChain) {
5798
0
                    FreeDer(&ssl->buffers.certChain);
5799
0
                }
5800
0
                ret = AllocDer(&ssl->buffers.certChain, idx, type, heap);
5801
0
                if (ret == 0) {
5802
0
                    XMEMCPY(ssl->buffers.certChain->buffer, chainBuffer,
5803
0
                            idx);
5804
0
                    ssl->buffers.weOwnCertChain = 1;
5805
0
                }
5806
0
            #ifdef WOLFSSL_TLS13
5807
0
                ssl->buffers.certChainCnt = cnt;
5808
0
            #endif
5809
0
            } else if (ctx) {
5810
0
                FreeDer(&ctx->certChain);
5811
0
                ret = AllocDer(&ctx->certChain, idx, type, heap);
5812
0
                if (ret == 0) {
5813
0
                    XMEMCPY(ctx->certChain->buffer, chainBuffer, idx);
5814
0
                }
5815
0
            #ifdef WOLFSSL_TLS13
5816
0
                ctx->certChainCnt = cnt;
5817
0
            #endif
5818
0
            }
5819
0
        }
5820
5821
0
        if (dynamicBuffer)
5822
0
            XFREE(chainBuffer, heap, DYNAMIC_TYPE_FILE);
5823
0
    }
5824
5825
0
    return ret;
5826
0
}
5827
5828
static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der,
5829
    int* keySz, word32* idx, int* resetSuites, int* keyFormat, void* heap, int devId)
5830
0
{
5831
0
    int ret = 0;
5832
5833
0
    (void)heap;
5834
0
    (void)devId;
5835
5836
0
    if (ctx == NULL && ssl == NULL)
5837
0
        return BAD_FUNC_ARG;
5838
0
    if (!der || !keySz || !idx || !resetSuites || !keyFormat)
5839
0
        return BAD_FUNC_ARG;
5840
5841
0
#ifndef NO_RSA
5842
0
    if ((*keyFormat == 0 || *keyFormat == RSAk)) {
5843
        /* make sure RSA key can be used */
5844
0
    #ifdef WOLFSSL_SMALL_STACK
5845
0
        RsaKey* key;
5846
    #else
5847
        RsaKey  key[1];
5848
    #endif
5849
5850
0
    #ifdef WOLFSSL_SMALL_STACK
5851
0
        key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA);
5852
0
        if (key == NULL)
5853
0
            return MEMORY_E;
5854
0
    #endif
5855
5856
0
        ret = wc_InitRsaKey_ex(key, heap, devId);
5857
0
        if (ret == 0) {
5858
0
            *idx = 0;
5859
0
            ret = wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length);
5860
0
        #ifdef WOLF_PRIVATE_KEY_ID
5861
0
            if (ret != 0 && (devId != INVALID_DEVID
5862
            #ifdef HAVE_PK_CALLBACKS
5863
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
5864
            #endif
5865
0
            )) {
5866
                /* if using crypto or PK callbacks, try public key decode */
5867
0
                *idx = 0;
5868
0
                ret = wc_RsaPublicKeyDecode(der->buffer, idx, key, der->length);
5869
0
            }
5870
0
        #endif
5871
0
            if (ret != 0) {
5872
            #if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
5873
                !defined(HAVE_ED448) && !defined(HAVE_PQC)
5874
                WOLFSSL_MSG("RSA decode failed and other algorithms "
5875
                            "not enabled to try");
5876
                ret = WOLFSSL_BAD_FILE;
5877
            #else
5878
0
                ret = 0; /* continue trying other algorithms */
5879
0
            #endif
5880
0
            }
5881
0
            else {
5882
                /* check that the size of the RSA key is enough */
5883
0
                int minRsaSz = ssl ? ssl->options.minRsaKeySz :
5884
0
                    ctx->minRsaKeySz;
5885
0
                *keySz = wc_RsaEncryptSize((RsaKey*)key);
5886
0
                if (*keySz < minRsaSz) {
5887
0
                    ret = RSA_KEY_SIZE_E;
5888
0
                    WOLFSSL_MSG("Private Key size too small");
5889
0
                }
5890
5891
0
                if (ssl) {
5892
0
                    ssl->buffers.keyType = rsa_sa_algo;
5893
0
                    ssl->buffers.keySz = *keySz;
5894
0
                }
5895
0
                else {
5896
0
                    ctx->privateKeyType = rsa_sa_algo;
5897
0
                    ctx->privateKeySz = *keySz;
5898
0
                }
5899
5900
0
                *keyFormat = RSAk;
5901
5902
0
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
5903
0
                    ssl->options.haveStaticECC = 0;
5904
0
                    *resetSuites = 1;
5905
0
                }
5906
0
            }
5907
5908
0
            wc_FreeRsaKey(key);
5909
0
        }
5910
5911
0
    #ifdef WOLFSSL_SMALL_STACK
5912
0
        XFREE(key, heap, DYNAMIC_TYPE_RSA);
5913
0
    #endif
5914
0
        if (ret != 0)
5915
0
            return ret;
5916
0
    }
5917
0
#endif
5918
0
#ifdef HAVE_ECC
5919
0
    if ((*keyFormat == 0 || *keyFormat == ECDSAk)) {
5920
        /* make sure ECC key can be used */
5921
0
    #ifdef WOLFSSL_SMALL_STACK
5922
0
        ecc_key* key;
5923
    #else
5924
        ecc_key  key[1];
5925
    #endif
5926
5927
0
    #ifdef WOLFSSL_SMALL_STACK
5928
0
        key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC);
5929
0
        if (key == NULL)
5930
0
            return MEMORY_E;
5931
0
    #endif
5932
5933
0
        if (wc_ecc_init_ex(key, heap, devId) == 0) {
5934
0
            *idx = 0;
5935
0
            ret = wc_EccPrivateKeyDecode(der->buffer, idx, key, der->length);
5936
0
        #ifdef WOLF_PRIVATE_KEY_ID
5937
0
            if (ret != 0 && (devId != INVALID_DEVID
5938
            #ifdef HAVE_PK_CALLBACKS
5939
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
5940
            #endif
5941
0
            )) {
5942
                /* if using crypto or PK callbacks, try public key decode */
5943
0
                *idx = 0;
5944
0
                ret = wc_EccPublicKeyDecode(der->buffer, idx, key, der->length);
5945
0
            }
5946
0
        #endif
5947
0
            if (ret == 0) {
5948
                /* check for minimum ECC key size and then free */
5949
0
                int minKeySz = ssl ? ssl->options.minEccKeySz :
5950
0
                                                        ctx->minEccKeySz;
5951
0
                *keySz = wc_ecc_size(key);
5952
0
                if (*keySz < minKeySz) {
5953
0
                    WOLFSSL_MSG("ECC private key too small");
5954
0
                    ret = ECC_KEY_SIZE_E;
5955
0
                }
5956
5957
0
                *keyFormat = ECDSAk;
5958
0
                if (ssl) {
5959
0
                    ssl->options.haveStaticECC = 1;
5960
0
                    ssl->buffers.keyType = ecc_dsa_sa_algo;
5961
0
                    ssl->buffers.keySz = *keySz;
5962
0
                }
5963
0
                else {
5964
0
                    ctx->haveStaticECC = 1;
5965
0
                    ctx->privateKeyType = ecc_dsa_sa_algo;
5966
0
                    ctx->privateKeySz = *keySz;
5967
0
                }
5968
5969
0
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
5970
0
                    *resetSuites = 1;
5971
0
                }
5972
0
            }
5973
0
            else {
5974
0
                ret = 0; /* continue trying other algorithms */
5975
0
            }
5976
5977
0
            wc_ecc_free(key);
5978
0
        }
5979
5980
0
    #ifdef WOLFSSL_SMALL_STACK
5981
0
        XFREE(key, heap, DYNAMIC_TYPE_ECC);
5982
0
    #endif
5983
0
        if (ret != 0)
5984
0
            return ret;
5985
0
    }
5986
0
#endif /* HAVE_ECC */
5987
0
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT)
5988
0
    if ((*keyFormat == 0 || *keyFormat == ED25519k)) {
5989
        /* make sure Ed25519 key can be used */
5990
0
    #ifdef WOLFSSL_SMALL_STACK
5991
0
        ed25519_key* key;
5992
    #else
5993
        ed25519_key  key[1];
5994
    #endif
5995
5996
0
    #ifdef WOLFSSL_SMALL_STACK
5997
0
        key = (ed25519_key*)XMALLOC(sizeof(ed25519_key), heap,
5998
0
                                                      DYNAMIC_TYPE_ED25519);
5999
0
        if (key == NULL)
6000
0
            return MEMORY_E;
6001
0
    #endif
6002
6003
0
        ret = wc_ed25519_init_ex(key, heap, devId);
6004
0
        if (ret == 0) {
6005
0
            *idx = 0;
6006
0
            ret = wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, der->length);
6007
0
        #ifdef WOLF_PRIVATE_KEY_ID
6008
0
            if (ret != 0 && (devId != INVALID_DEVID
6009
            #ifdef HAVE_PK_CALLBACKS
6010
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
6011
            #endif
6012
0
            )) {
6013
                /* if using crypto or PK callbacks, try public key decode */
6014
0
                *idx = 0;
6015
0
                ret = wc_Ed25519PublicKeyDecode(der->buffer, idx, key,
6016
0
                                                der->length);
6017
0
            }
6018
0
        #endif
6019
0
            if (ret == 0) {
6020
                /* check for minimum key size and then free */
6021
0
                int minKeySz = ssl ? ssl->options.minEccKeySz :
6022
0
                                                           ctx->minEccKeySz;
6023
0
                *keySz = ED25519_KEY_SIZE;
6024
0
                if (*keySz < minKeySz) {
6025
0
                    WOLFSSL_MSG("ED25519 private key too small");
6026
0
                    ret = ECC_KEY_SIZE_E;
6027
0
                }
6028
0
                if (ret == 0) {
6029
0
                    if (ssl) {
6030
0
                        ssl->buffers.keyType = ed25519_sa_algo;
6031
0
                        ssl->buffers.keySz = *keySz;
6032
0
                    }
6033
0
                    else if (ctx) {
6034
0
                        ctx->privateKeyType = ed25519_sa_algo;
6035
0
                        ctx->privateKeySz = *keySz;
6036
0
                    }
6037
6038
0
                    *keyFormat = ED25519k;
6039
0
                    if (ssl != NULL) {
6040
                        /* ED25519 requires caching enabled for tracking message
6041
                         * hash used in EdDSA_Update for signing */
6042
0
                        ssl->options.cacheMessages = 1;
6043
0
                        if (ssl->options.side == WOLFSSL_SERVER_END) {
6044
0
                            *resetSuites = 1;
6045
0
                        }
6046
0
                    }
6047
0
                }
6048
0
            }
6049
0
            else {
6050
0
                ret = 0; /* continue trying other algorithms */
6051
0
            }
6052
6053
0
            wc_ed25519_free(key);
6054
0
        }
6055
6056
0
    #ifdef WOLFSSL_SMALL_STACK
6057
0
        XFREE(key, heap, DYNAMIC_TYPE_ED25519);
6058
0
    #endif
6059
0
        if (ret != 0)
6060
0
            return ret;
6061
0
    }
6062
0
#endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */
6063
0
#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT)
6064
0
    if ((*keyFormat == 0 || *keyFormat == ED448k)) {
6065
        /* make sure Ed448 key can be used */
6066
0
    #ifdef WOLFSSL_SMALL_STACK
6067
0
        ed448_key* key = NULL;
6068
    #else
6069
        ed448_key  key[1];
6070
    #endif
6071
6072
0
    #ifdef WOLFSSL_SMALL_STACK
6073
0
        key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
6074
0
        if (key == NULL)
6075
0
            return MEMORY_E;
6076
0
    #endif
6077
6078
0
        ret = wc_ed448_init(key);
6079
0
        if (ret == 0) {
6080
0
            *idx = 0;
6081
0
            ret = wc_Ed448PrivateKeyDecode(der->buffer, idx, key, der->length);
6082
0
        #ifdef WOLF_PRIVATE_KEY_ID
6083
0
            if (ret != 0 && (devId != INVALID_DEVID
6084
            #ifdef HAVE_PK_CALLBACKS
6085
                || wolfSSL_CTX_IsPrivatePkSet(ctx)
6086
            #endif
6087
0
            )) {
6088
                /* if using crypto or PK callbacks, try public key decode */
6089
0
                *idx = 0;
6090
0
                ret = wc_Ed448PublicKeyDecode(der->buffer, idx, key,
6091
0
                                              der->length);
6092
0
            }
6093
0
        #endif
6094
0
            if (ret == 0) {
6095
                /* check for minimum key size and then free */
6096
0
                int minKeySz = ssl ? ssl->options.minEccKeySz :
6097
0
                                                               ctx->minEccKeySz;
6098
0
                *keySz = ED448_KEY_SIZE;
6099
0
                if (*keySz < minKeySz) {
6100
0
                    WOLFSSL_MSG("ED448 private key too small");
6101
0
                    ret = ECC_KEY_SIZE_E;
6102
0
                }
6103
0
            }
6104
0
            if (ret == 0) {
6105
0
                if (ssl) {
6106
0
                    ssl->buffers.keyType = ed448_sa_algo;
6107
0
                    ssl->buffers.keySz = *keySz;
6108
0
                }
6109
0
                else if (ctx) {
6110
0
                    ctx->privateKeyType = ed448_sa_algo;
6111
0
                    ctx->privateKeySz = *keySz;
6112
0
                }
6113
6114
0
                *keyFormat = ED448k;
6115
0
                if (ssl != NULL) {
6116
                    /* ED448 requires caching enabled for tracking message
6117
                     * hash used in EdDSA_Update for signing */
6118
0
                    ssl->options.cacheMessages = 1;
6119
0
                    if (ssl->options.side == WOLFSSL_SERVER_END) {
6120
0
                        *resetSuites = 1;
6121
0
                    }
6122
0
                }
6123
0
            }
6124
6125
0
            wc_ed448_free(key);
6126
0
        }
6127
6128
0
    #ifdef WOLFSSL_SMALL_STACK
6129
0
        XFREE(key, heap, DYNAMIC_TYPE_ED448);
6130
0
    #endif
6131
0
        if (ret != 0)
6132
0
            return ret;
6133
0
    }
6134
0
#endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */
6135
#if defined(HAVE_PQC)
6136
#if defined(HAVE_FALCON)
6137
    if (((*keyFormat == 0) || (*keyFormat == FALCON_LEVEL1k) ||
6138
         (*keyFormat == FALCON_LEVEL5k))) {
6139
        /* make sure Falcon key can be used */
6140
        falcon_key* key = (falcon_key*)XMALLOC(sizeof(falcon_key), heap,
6141
                                               DYNAMIC_TYPE_FALCON);
6142
        if (key == NULL) {
6143
            return MEMORY_E;
6144
        }
6145
        ret = wc_falcon_init(key);
6146
        if (ret == 0) {
6147
            if (*keyFormat == FALCON_LEVEL1k) {
6148
                ret = wc_falcon_set_level(key, 1);
6149
            }
6150
            else if (*keyFormat == FALCON_LEVEL5k) {
6151
                ret = wc_falcon_set_level(key, 5);
6152
            }
6153
            else {
6154
                /* What if *keyformat is 0? We might want to do something more
6155
                 * graceful here. */
6156
                wc_falcon_free(key);
6157
                ret = ALGO_ID_E;
6158
            }
6159
        }
6160
6161
        if (ret == 0) {
6162
            *idx = 0;
6163
            ret = wc_falcon_import_private_only(der->buffer, der->length, key);
6164
            if (ret == 0) {
6165
                /* check for minimum key size and then free */
6166
                int minKeySz = ssl ? ssl->options.minFalconKeySz :
6167
                                     ctx->minFalconKeySz;
6168
                *keySz = FALCON_MAX_KEY_SIZE;
6169
                if (*keySz < minKeySz) {
6170
                    WOLFSSL_MSG("Falcon private key too small");
6171
                    ret = FALCON_KEY_SIZE_E;
6172
                }
6173
                if (ssl) {
6174
                    if (*keyFormat == FALCON_LEVEL1k) {
6175
                        ssl->buffers.keyType = falcon_level1_sa_algo;
6176
                    }
6177
                    else {
6178
                        ssl->buffers.keyType = falcon_level5_sa_algo;
6179
                    }
6180
                    ssl->buffers.keySz = *keySz;
6181
                }
6182
                else {
6183
                    if (*keyFormat == FALCON_LEVEL1k) {
6184
                        ctx->privateKeyType = falcon_level1_sa_algo;
6185
                    }
6186
                    else {
6187
                        ctx->privateKeyType = falcon_level5_sa_algo;
6188
                    }
6189
                    ctx->privateKeySz = *keySz;
6190
                }
6191
6192
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
6193
                    *resetSuites = 1;
6194
                }
6195
            }
6196
            wc_falcon_free(key);
6197
        }
6198
        XFREE(key, heap, DYNAMIC_TYPE_FALCON);
6199
        if (ret != 0)
6200
            return ret;
6201
    }
6202
#endif /* HAVE_FALCON */
6203
#if defined(HAVE_DILITHIUM)
6204
    if ((*keyFormat == 0) ||
6205
        (*keyFormat == DILITHIUM_LEVEL2k) ||
6206
        (*keyFormat == DILITHIUM_LEVEL3k) ||
6207
        (*keyFormat == DILITHIUM_LEVEL5k) ||
6208
        (*keyFormat == DILITHIUM_AES_LEVEL2k) ||
6209
        (*keyFormat == DILITHIUM_AES_LEVEL3k) ||
6210
        (*keyFormat == DILITHIUM_AES_LEVEL5k)) {
6211
        /* make sure Dilithium key can be used */
6212
        dilithium_key* key = (dilithium_key*)XMALLOC(sizeof(dilithium_key),
6213
                                                     heap,
6214
                                                     DYNAMIC_TYPE_DILITHIUM);
6215
        if (key == NULL) {
6216
            return MEMORY_E;
6217
        }
6218
        ret = wc_dilithium_init(key);
6219
        if (ret == 0) {
6220
            if (*keyFormat == DILITHIUM_LEVEL2k) {
6221
                ret = wc_dilithium_set_level_and_sym(key, 2, SHAKE_VARIANT);
6222
            }
6223
            else if (*keyFormat == DILITHIUM_LEVEL3k) {
6224
                ret = wc_dilithium_set_level_and_sym(key, 3, SHAKE_VARIANT);
6225
            }
6226
            else if (*keyFormat == DILITHIUM_LEVEL5k) {
6227
                ret = wc_dilithium_set_level_and_sym(key, 5, SHAKE_VARIANT);
6228
            }
6229
            else if (*keyFormat == DILITHIUM_AES_LEVEL2k) {
6230
                ret = wc_dilithium_set_level_and_sym(key, 2, AES_VARIANT);
6231
            }
6232
            else if (*keyFormat == DILITHIUM_AES_LEVEL3k) {
6233
                ret = wc_dilithium_set_level_and_sym(key, 3, AES_VARIANT);
6234
            }
6235
            else if (*keyFormat == DILITHIUM_AES_LEVEL5k) {
6236
                ret = wc_dilithium_set_level_and_sym(key, 5, AES_VARIANT);
6237
            }
6238
            else {
6239
                /* What if *keyformat is 0? We might want to do something more
6240
                 * graceful here. */
6241
                wc_dilithium_free(key);
6242
                ret = ALGO_ID_E;
6243
            }
6244
        }
6245
6246
        if (ret == 0) {
6247
            *idx = 0;
6248
            ret = wc_dilithium_import_private_only(der->buffer, der->length,
6249
                                                   key);
6250
            if (ret == 0) {
6251
                /* check for minimum key size and then free */
6252
                int minKeySz = ssl ? ssl->options.minDilithiumKeySz :
6253
                                     ctx->minDilithiumKeySz;
6254
                *keySz = DILITHIUM_MAX_KEY_SIZE;
6255
                if (*keySz < minKeySz) {
6256
                    WOLFSSL_MSG("Dilithium private key too small");
6257
                    ret = DILITHIUM_KEY_SIZE_E;
6258
                }
6259
                if (ssl) {
6260
                    if (*keyFormat == DILITHIUM_LEVEL2k) {
6261
                        ssl->buffers.keyType = dilithium_level2_sa_algo;
6262
                    }
6263
                    else if (*keyFormat == DILITHIUM_LEVEL3k) {
6264
                        ssl->buffers.keyType = dilithium_level3_sa_algo;
6265
                    }
6266
                    else if (*keyFormat == DILITHIUM_LEVEL5k) {
6267
                        ssl->buffers.keyType = dilithium_level5_sa_algo;
6268
                    }
6269
                    else if (*keyFormat == DILITHIUM_AES_LEVEL2k) {
6270
                        ssl->buffers.keyType = dilithium_aes_level2_sa_algo;
6271
                    }
6272
                    else if (*keyFormat == DILITHIUM_AES_LEVEL3k) {
6273
                        ssl->buffers.keyType = dilithium_aes_level3_sa_algo;
6274
                    }
6275
                    else if (*keyFormat == DILITHIUM_AES_LEVEL5k) {
6276
                        ssl->buffers.keyType = dilithium_aes_level5_sa_algo;
6277
                    }
6278
                    ssl->buffers.keySz = *keySz;
6279
                }
6280
                else {
6281
                    if (*keyFormat == DILITHIUM_LEVEL2k) {
6282
                        ctx->privateKeyType = dilithium_level2_sa_algo;
6283
                    }
6284
                    else if (*keyFormat == DILITHIUM_LEVEL3k) {
6285
                        ctx->privateKeyType = dilithium_level3_sa_algo;
6286
                    }
6287
                    else if (*keyFormat == DILITHIUM_LEVEL5k) {
6288
                        ctx->privateKeyType = dilithium_level5_sa_algo;
6289
                    }
6290
                    else if (*keyFormat == DILITHIUM_AES_LEVEL2k) {
6291
                        ctx->privateKeyType = dilithium_aes_level2_sa_algo;
6292
                    }
6293
                    else if (*keyFormat == DILITHIUM_AES_LEVEL3k) {
6294
                        ctx->privateKeyType = dilithium_aes_level3_sa_algo;
6295
                    }
6296
                    else if (*keyFormat == DILITHIUM_AES_LEVEL5k) {
6297
                        ctx->privateKeyType = dilithium_aes_level5_sa_algo;
6298
                    }
6299
                    ctx->privateKeySz = *keySz;
6300
                }
6301
6302
                if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
6303
                    *resetSuites = 1;
6304
                }
6305
            }
6306
            wc_dilithium_free(key);
6307
        }
6308
        XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM);
6309
        if (ret != 0) {
6310
            return ret;
6311
        }
6312
    }
6313
#endif /* HAVE_DILITHIUM */
6314
#endif /* HAVE_PQC */
6315
0
    return ret;
6316
0
}
6317
6318
/* process the buffer buff, length sz, into ctx of format and type
6319
   used tracks bytes consumed, userChain specifies a user cert chain
6320
   to pass during the handshake */
6321
int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
6322
                         long sz, int format, int type, WOLFSSL* ssl,
6323
                         long* used, int userChain, int verify)
6324
0
{
6325
0
    DerBuffer*    der = NULL;
6326
0
    int           ret = 0;
6327
0
    int           done = 0;
6328
0
    int           keyFormat = 0;
6329
0
    int           resetSuites = 0;
6330
0
    void*         heap = wolfSSL_CTX_GetHeap(ctx, ssl);
6331
0
    int           devId = wolfSSL_CTX_GetDevId(ctx, ssl);
6332
0
    word32        idx = 0;
6333
0
    int           keySz = 0;
6334
0
#if (defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)) || \
6335
0
     defined(HAVE_PKCS8)
6336
0
    word32        algId = 0;
6337
0
#endif
6338
0
#ifdef WOLFSSL_SMALL_STACK
6339
0
    EncryptedInfo* info = NULL;
6340
#else
6341
    EncryptedInfo  info[1];
6342
#endif
6343
6344
0
    (void)devId;
6345
0
    (void)idx;
6346
0
    (void)keySz;
6347
6348
0
    if (used)
6349
0
        *used = sz;     /* used bytes default to sz, PEM chain may shorten*/
6350
6351
    /* check args */
6352
0
    if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
6353
0
        return WOLFSSL_BAD_FILETYPE;
6354
6355
0
    if (ctx == NULL && ssl == NULL)
6356
0
        return BAD_FUNC_ARG;
6357
6358
0
#ifdef WOLFSSL_SMALL_STACK
6359
0
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), heap,
6360
0
                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
6361
0
    if (info == NULL)
6362
0
        return MEMORY_E;
6363
0
#endif
6364
6365
0
    XMEMSET(info, 0, sizeof(EncryptedInfo));
6366
0
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
6367
0
    if (ctx) {
6368
0
        info->passwd_cb       = ctx->passwd_cb;
6369
0
        info->passwd_userdata = ctx->passwd_userdata;
6370
0
    }
6371
0
#endif
6372
6373
0
    if (format == WOLFSSL_FILETYPE_PEM) {
6374
0
    #ifdef WOLFSSL_PEM_TO_DER
6375
0
        ret = PemToDer(buff, sz, type, &der, heap, info, &keyFormat);
6376
    #else
6377
        ret = NOT_COMPILED_IN;
6378
    #endif
6379
0
    }
6380
0
    else {
6381
        /* ASN1 (DER) */
6382
0
        int length = (int)sz;
6383
0
        if (format == WOLFSSL_FILETYPE_ASN1) {
6384
            /* get length of der (read sequence or octet string) */
6385
0
            word32 inOutIdx = 0;
6386
0
            if (GetSequence(buff, &inOutIdx, &length, (word32)sz) >= 0) {
6387
0
                length += inOutIdx; /* include leading sequence */
6388
0
            }
6389
            /* get length using octect string (allowed for private key types) */
6390
0
            else if (type == PRIVATEKEY_TYPE &&
6391
0
                    GetOctetString(buff, &inOutIdx, &length, (word32)sz) >= 0) {
6392
0
                length += inOutIdx; /* include leading oct string */
6393
0
            }
6394
0
            else {
6395
0
                ret = ASN_PARSE_E;
6396
0
            }
6397
0
        }
6398
6399
0
        info->consumed = length;
6400
6401
0
        if (ret == 0) {
6402
0
            ret = AllocDer(&der, (word32)length, type, heap);
6403
0
            if (ret == 0) {
6404
0
                XMEMCPY(der->buffer, buff, length);
6405
0
            }
6406
6407
0
        #ifdef HAVE_PKCS8
6408
            /* if private key try and remove PKCS8 header */
6409
0
            if (type == PRIVATEKEY_TYPE) {
6410
0
                if ((ret = ToTraditional_ex(der->buffer, der->length,
6411
0
                                                                 &algId)) > 0) {
6412
                    /* Found PKCS8 header */
6413
                    /* ToTraditional_ex moves buff and returns adjusted length */
6414
0
                    der->length = ret;
6415
0
                    keyFormat = algId;
6416
0
                }
6417
0
                ret = 0; /* failures should be ignored */
6418
0
            }
6419
0
        #endif
6420
0
        }
6421
0
    }
6422
6423
0
    if (used) {
6424
0
        *used = info->consumed;
6425
0
    }
6426
6427
    /* process user chain */
6428
0
    if (ret >= 0) {
6429
        /* Chain should have server cert first, then intermediates, then root.
6430
         * First certificate in chain is processed below after ProcessUserChain
6431
         *   and is loaded into ssl->buffers.certificate.
6432
         * Remainder are processed using ProcessUserChain and are loaded into
6433
         *   ssl->buffers.certChain. */
6434
0
        if (userChain) {
6435
0
            ret = ProcessUserChain(ctx, buff, sz, format, type, ssl, used, info,
6436
0
                                   verify);
6437
0
            if (ret == ASN_NO_PEM_HEADER) { /* Additional chain is optional */
6438
0
                unsigned long pemErr;
6439
0
                CLEAR_ASN_NO_PEM_HEADER_ERROR(pemErr);
6440
0
                ret = 0;
6441
0
            }
6442
0
        }
6443
0
    }
6444
6445
    /* info is only used for private key with DER or PEM, so free now */
6446
0
    if (ret < 0 || type != PRIVATEKEY_TYPE) {
6447
0
    #ifdef WOLFSSL_SMALL_STACK
6448
0
        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6449
0
    #endif
6450
0
    }
6451
6452
    /* check for error */
6453
0
    if (ret < 0) {
6454
0
        FreeDer(&der);
6455
0
        done = 1;
6456
0
    }
6457
6458
0
    if (done == 1) {
6459
        /* No operation, just skip the next section */
6460
0
    }
6461
    /* Handle DER owner */
6462
0
    else if (type == CA_TYPE) {
6463
0
        if (ctx == NULL) {
6464
0
            WOLFSSL_MSG("Need context for CA load");
6465
0
            FreeDer(&der);
6466
0
            return BAD_FUNC_ARG;
6467
0
        }
6468
        /* verify CA unless user set to no verify */
6469
0
        ret = AddCA(ctx->cm, &der, WOLFSSL_USER_CA, verify);
6470
0
        done = 1;
6471
0
    }
6472
#ifdef WOLFSSL_TRUST_PEER_CERT
6473
    else if (type == TRUSTED_PEER_TYPE) {
6474
        /* add trusted peer cert. der is freed within */
6475
        if (ctx != NULL)
6476
            ret = AddTrustedPeer(ctx->cm, &der, !ctx->verifyNone);
6477
        else
6478
            ret = AddTrustedPeer(SSL_CM(ssl), &der, !ssl->options.verifyNone);
6479
        if (ret != WOLFSSL_SUCCESS) {
6480
            WOLFSSL_MSG("Error adding trusted peer");
6481
        }
6482
        done = 1;
6483
    }
6484
#endif /* WOLFSSL_TRUST_PEER_CERT */
6485
0
    else if (type == CERT_TYPE) {
6486
0
        if (ssl != NULL) {
6487
             /* Make sure previous is free'd */
6488
0
            if (ssl->buffers.weOwnCert) {
6489
0
                FreeDer(&ssl->buffers.certificate);
6490
0
            #ifdef KEEP_OUR_CERT
6491
0
                wolfSSL_X509_free(ssl->ourCert);
6492
0
                ssl->ourCert = NULL;
6493
0
            #endif
6494
0
            }
6495
0
            ssl->buffers.certificate = der;
6496
0
        #ifdef KEEP_OUR_CERT
6497
0
            ssl->keepCert = 1; /* hold cert for ssl lifetime */
6498
0
        #endif
6499
0
            ssl->buffers.weOwnCert = 1;
6500
0
        }
6501
0
        else if (ctx != NULL) {
6502
0
            FreeDer(&ctx->certificate); /* Make sure previous is free'd */
6503
0
        #ifdef KEEP_OUR_CERT
6504
0
            if (ctx->ourCert) {
6505
0
                if (ctx->ownOurCert)
6506
0
                    wolfSSL_X509_free(ctx->ourCert);
6507
0
                ctx->ourCert = NULL;
6508
0
            }
6509
0
        #endif
6510
0
            ctx->certificate = der;
6511
0
        }
6512
0
    }
6513
0
    else if (type == PRIVATEKEY_TYPE) {
6514
0
        if (ssl != NULL) {
6515
             /* Make sure previous is free'd */
6516
0
            if (ssl->buffers.weOwnKey) {
6517
0
                ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
6518
0
                FreeDer(&ssl->buffers.key);
6519
0
            }
6520
0
            ssl->buffers.key = der;
6521
#ifdef WOLFSSL_CHECK_MEM_ZERO
6522
            wc_MemZero_Add("SSL Buffers key", der->buffer, der->length);
6523
#endif
6524
0
            ssl->buffers.weOwnKey = 1;
6525
0
        }
6526
0
        else if (ctx != NULL) {
6527
0
            if (ctx->privateKey != NULL && ctx->privateKey->buffer != NULL) {
6528
0
                ForceZero(ctx->privateKey->buffer, ctx->privateKey->length);
6529
0
            }
6530
0
            FreeDer(&ctx->privateKey);
6531
0
            ctx->privateKey = der;
6532
#ifdef WOLFSSL_CHECK_MEM_ZERO
6533
            wc_MemZero_Add("CTX private key", der->buffer, der->length);
6534
#endif
6535
0
        }
6536
0
    }
6537
0
    else {
6538
0
        FreeDer(&der);
6539
0
        return WOLFSSL_BAD_CERTTYPE;
6540
0
    }
6541
6542
0
    if (done == 1) {
6543
        /* No operation, just skip the next section */
6544
0
    }
6545
0
    else if (type == PRIVATEKEY_TYPE) {
6546
0
        ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites,
6547
0
                &keyFormat, heap, devId);
6548
6549
0
    #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
6550
        /* for WOLFSSL_FILETYPE_PEM, PemToDer manages the decryption */
6551
        /* If private key type PKCS8 header wasn't already removed (algoId == 0) */
6552
0
        if ((ret != 0 || keyFormat == 0)
6553
0
            && format != WOLFSSL_FILETYPE_PEM && info->passwd_cb && algId == 0)
6554
0
        {
6555
0
            int   passwordSz = NAME_SZ;
6556
        #ifndef WOLFSSL_SMALL_STACK
6557
            char  password[NAME_SZ];
6558
        #else
6559
0
            char* password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING);
6560
0
            if (password == NULL) {
6561
0
                XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6562
0
                FreeDer(&der);
6563
0
                return MEMORY_E;
6564
0
            }
6565
0
        #endif
6566
            /* get password */
6567
0
            ret = info->passwd_cb(password, passwordSz, PEM_PASS_READ,
6568
0
                info->passwd_userdata);
6569
0
            if (ret >= 0) {
6570
0
                passwordSz = ret;
6571
            #ifdef WOLFSSL_CHECK_MEM_ZERO
6572
                wc_MemZero_Add("ProcessBuffer password", password, passwordSz);
6573
            #endif
6574
6575
                /* PKCS8 decrypt */
6576
0
                ret = ToTraditionalEnc(der->buffer, der->length,
6577
0
                                       password, passwordSz, &algId);
6578
0
                if (ret >= 0) {
6579
0
                    ForceZero(der->buffer + ret, der->length - ret);
6580
0
                    der->length = ret;
6581
0
                }
6582
                /* ignore failures and try parsing as unencrypted */
6583
6584
0
                ForceZero(password, passwordSz);
6585
0
            }
6586
6587
0
        #ifdef WOLFSSL_SMALL_STACK
6588
0
            XFREE(password, heap, DYNAMIC_TYPE_STRING);
6589
        #elif defined(WOLFSSL_CHECK_MEM_ZERO)
6590
            wc_MemZero_Check(password, NAME_SZ);
6591
        #endif
6592
0
            ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx,
6593
0
                &resetSuites, &keyFormat, heap, devId);
6594
0
        }
6595
0
    #endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
6596
6597
0
    #ifdef WOLFSSL_SMALL_STACK
6598
0
        XFREE(info, heap, DYNAMIC_TYPE_ENCRYPTEDINFO);
6599
0
    #endif
6600
6601
0
        if (ret != 0)
6602
0
            return ret;
6603
0
        if (keyFormat == 0) {
6604
0
#ifdef OPENSSL_EXTRA
6605
            /* Reaching this point probably means that the
6606
             * decryption password is wrong */
6607
0
            if (info->passwd_cb)
6608
0
                EVPerr(0, EVP_R_BAD_DECRYPT);
6609
0
#endif
6610
0
            WOLFSSL_ERROR(WOLFSSL_BAD_FILE);
6611
0
            return WOLFSSL_BAD_FILE;
6612
0
        }
6613
6614
0
        (void)devId;
6615
0
    }
6616
0
    else if (type == CERT_TYPE) {
6617
0
    #ifdef WOLFSSL_SMALL_STACK
6618
0
        DecodedCert* cert;
6619
    #else
6620
        DecodedCert  cert[1];
6621
    #endif
6622
0
    #ifdef WOLF_PRIVATE_KEY_ID
6623
0
        int keyType = 0;
6624
0
    #endif
6625
6626
0
    #ifdef WOLFSSL_SMALL_STACK
6627
0
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap,
6628
0
                                     DYNAMIC_TYPE_DCERT);
6629
0
        if (cert == NULL)
6630
0
            return MEMORY_E;
6631
0
    #endif
6632
6633
0
        WOLFSSL_MSG("Checking cert signature type");
6634
0
        InitDecodedCert(cert, der->buffer, der->length, heap);
6635
6636
0
        if (DecodeToKey(cert, 0) < 0) {
6637
0
            WOLFSSL_MSG("Decode to key failed");
6638
0
            FreeDecodedCert(cert);
6639
0
        #ifdef WOLFSSL_SMALL_STACK
6640
0
            XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
6641
0
        #endif
6642
0
            return WOLFSSL_BAD_FILE;
6643
0
        }
6644
6645
0
        if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
6646
0
            resetSuites = 1;
6647
0
        }
6648
0
        if (ssl && ssl->ctx->haveECDSAsig) {
6649
0
            WOLFSSL_MSG("SSL layer setting cert, CTX had ECDSA, turning off");
6650
0
            ssl->options.haveECDSAsig = 0;   /* may turn back on next */
6651
0
        }
6652
6653
0
        switch (cert->signatureOID) {
6654
0
            case CTC_SHAwECDSA:
6655
0
            case CTC_SHA256wECDSA:
6656
0
            case CTC_SHA384wECDSA:
6657
0
            case CTC_SHA512wECDSA:
6658
0
            case CTC_ED25519:
6659
0
            case CTC_ED448:
6660
0
                WOLFSSL_MSG("ECDSA/ED25519/ED448 cert signature");
6661
0
                if (ssl)
6662
0
                    ssl->options.haveECDSAsig = 1;
6663
0
                else if (ctx)
6664
0
                    ctx->haveECDSAsig = 1;
6665
0
                break;
6666
0
            case CTC_FALCON_LEVEL1:
6667
0
            case CTC_FALCON_LEVEL5:
6668
0
                WOLFSSL_MSG("Falcon cert signature");
6669
0
                if (ssl)
6670
0
                    ssl->options.haveFalconSig = 1;
6671
0
                else if (ctx)
6672
0
                    ctx->haveFalconSig = 1;
6673
0
                break;
6674
0
            case CTC_DILITHIUM_LEVEL2:
6675
0
            case CTC_DILITHIUM_LEVEL3:
6676
0
            case CTC_DILITHIUM_LEVEL5:
6677
0
            case CTC_DILITHIUM_AES_LEVEL2:
6678
0
            case CTC_DILITHIUM_AES_LEVEL3:
6679
0
            case CTC_DILITHIUM_AES_LEVEL5:
6680
0
                WOLFSSL_MSG("Dilithium cert signature");
6681
0
                if (ssl)
6682
0
                    ssl->options.haveDilithiumSig = 1;
6683
0
                else if (ctx)
6684
0
                    ctx->haveDilithiumSig = 1;
6685
0
                break;
6686
0
            default:
6687
0
                WOLFSSL_MSG("Not ECDSA cert signature");
6688
0
                break;
6689
0
        }
6690
6691
0
    #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \
6692
0
        defined(HAVE_PQC) || !defined(NO_RSA)
6693
0
        if (ssl) {
6694
0
        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \
6695
0
            (defined(HAVE_CURVE448) && defined(HAVE_ED448))
6696
0
            ssl->pkCurveOID = cert->pkCurveOID;
6697
0
        #endif
6698
0
        #ifndef WC_STRICT_SIG
6699
0
            if (cert->keyOID == ECDSAk) {
6700
0
                ssl->options.haveECC = 1;
6701
0
            }
6702
0
            #ifndef NO_RSA
6703
0
            else if (cert->keyOID == RSAk) {
6704
0
                ssl->options.haveRSA = 1;
6705
0
            }
6706
0
            #ifdef WC_RSA_PSS
6707
0
            else if (cert->keyOID == RSAPSSk) {
6708
0
                ssl->options.haveRSA = 1;
6709
0
            }
6710
0
            #endif
6711
0
            #endif
6712
0
            #ifdef HAVE_ED25519
6713
0
                else if (cert->keyOID == ED25519k) {
6714
0
                    ssl->options.haveECC = 1;
6715
0
                }
6716
0
            #endif
6717
0
            #ifdef HAVE_ED448
6718
0
                else if (cert->keyOID == ED448k) {
6719
0
                    ssl->options.haveECC = 1;
6720
0
                }
6721
0
            #endif
6722
            #ifdef HAVE_PQC
6723
            #ifdef HAVE_FALCON
6724
                else if (cert->keyOID == FALCON_LEVEL1k ||
6725
                         cert->keyOID == FALCON_LEVEL5k) {
6726
                    ssl->options.haveFalconSig = 1;
6727
                }
6728
            #endif /* HAVE_FALCON */
6729
            #ifdef HAVE_DILITHIUM
6730
                else if (cert->keyOID == DILITHIUM_LEVEL2k ||
6731
                         cert->keyOID == DILITHIUM_LEVEL3k ||
6732
                         cert->keyOID == DILITHIUM_LEVEL5k ||
6733
                         cert->keyOID == DILITHIUM_AES_LEVEL2k ||
6734
                         cert->keyOID == DILITHIUM_AES_LEVEL3k ||
6735
                         cert->keyOID == DILITHIUM_AES_LEVEL5k) {
6736
                    ssl->options.haveDilithiumSig = 1;
6737
                }
6738
            #endif /* HAVE_DILITHIUM */
6739
            #endif /* HAVE_PQC */
6740
        #else
6741
            ssl->options.haveECC = ssl->options.haveECDSAsig;
6742
        #endif
6743
0
        }
6744
0
        else if (ctx) {
6745
0
        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
6746
0
            ctx->pkCurveOID = cert->pkCurveOID;
6747
0
        #endif
6748
0
        #ifndef WC_STRICT_SIG
6749
0
            if (cert->keyOID == ECDSAk) {
6750
0
                ctx->haveECC = 1;
6751
0
            }
6752
0
            #ifndef NO_RSA
6753
0
            else if (cert->keyOID == RSAk) {
6754
0
                ctx->haveRSA = 1;
6755
0
            }
6756
0
            #ifdef WC_RSA_PSS
6757
0
            else if (cert->keyOID == RSAPSSk) {
6758
0
                ctx->haveRSA = 1;
6759
0
            }
6760
0
            #endif
6761
0
            #endif
6762
0
            #ifdef HAVE_ED25519
6763
0
                else if (cert->keyOID == ED25519k) {
6764
0
                    ctx->haveECC = 1;
6765
0
                }
6766
0
            #endif
6767
0
            #ifdef HAVE_ED448
6768
0
                else if (cert->keyOID == ED448k) {
6769
0
                    ctx->haveECC = 1;
6770
0
                }
6771
0
            #endif
6772
            #ifdef HAVE_PQC
6773
            #ifdef HAVE_FALCON
6774
                else if (cert->keyOID == FALCON_LEVEL1k ||
6775
                         cert->keyOID == FALCON_LEVEL5k) {
6776
                    ctx->haveFalconSig = 1;
6777
                }
6778
            #endif /* HAVE_FALCON */
6779
            #ifdef HAVE_DILITHIUM
6780
                else if (cert->keyOID == DILITHIUM_LEVEL2k ||
6781
                         cert->keyOID == DILITHIUM_LEVEL3k ||
6782
                         cert->keyOID == DILITHIUM_LEVEL5k ||
6783
                         cert->keyOID == DILITHIUM_AES_LEVEL2k ||
6784
                         cert->keyOID == DILITHIUM_AES_LEVEL3k ||
6785
                         cert->keyOID == DILITHIUM_AES_LEVEL5k) {
6786
                    ctx->haveDilithiumSig = 1;
6787
                }
6788
            #endif /* HAVE_DILITHIUM */
6789
            #endif /* HAVE_PQC */
6790
        #else
6791
            ctx->haveECC = ctx->haveECDSAsig;
6792
        #endif
6793
0
        }
6794
0
    #endif
6795
6796
        /* check key size of cert unless specified not to */
6797
0
        switch (cert->keyOID) {
6798
0
        #ifndef NO_RSA
6799
0
            #ifdef WC_RSA_PSS
6800
0
            case RSAPSSk:
6801
0
            #endif
6802
0
            case RSAk:
6803
0
            #ifdef WOLF_PRIVATE_KEY_ID
6804
0
                keyType = rsa_sa_algo;
6805
0
            #endif
6806
                /* Determine RSA key size by parsing public key */
6807
0
                idx = 0;
6808
0
                ret = wc_RsaPublicKeyDecode_ex(cert->publicKey, &idx,
6809
0
                    cert->pubKeySize, NULL, (word32*)&keySz, NULL, NULL);
6810
0
                if (ret < 0)
6811
0
                    break;
6812
6813
0
                if (ssl && !ssl->options.verifyNone) {
6814
0
                    if (ssl->options.minRsaKeySz < 0 ||
6815
0
                          keySz < (int)ssl->options.minRsaKeySz) {
6816
0
                        ret = RSA_KEY_SIZE_E;
6817
0
                        WOLFSSL_MSG("Certificate RSA key size too small");
6818
0
                    }
6819
0
                }
6820
0
                else if (ctx && !ctx->verifyNone) {
6821
0
                    if (ctx->minRsaKeySz < 0 ||
6822
0
                                  keySz < (int)ctx->minRsaKeySz) {
6823
0
                        ret = RSA_KEY_SIZE_E;
6824
0
                        WOLFSSL_MSG("Certificate RSA key size too small");
6825
0
                    }
6826
0
                }
6827
0
                break;
6828
0
        #endif /* !NO_RSA */
6829
0
        #ifdef HAVE_ECC
6830
0
            case ECDSAk:
6831
0
            #ifdef WOLF_PRIVATE_KEY_ID
6832
0
                keyType = ecc_dsa_sa_algo;
6833
0
            #endif
6834
                /* Determine ECC key size based on curve */
6835
0
                keySz = wc_ecc_get_curve_size_from_id(
6836
0
                    wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL));
6837
6838
0
                if (ssl && !ssl->options.verifyNone) {
6839
0
                    if (ssl->options.minEccKeySz < 0 ||
6840
0
                          keySz < (int)ssl->options.minEccKeySz) {
6841
0
                        ret = ECC_KEY_SIZE_E;
6842
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6843
0
                    }
6844
0
                }
6845
0
                else if (ctx && !ctx->verifyNone) {
6846
0
                    if (ctx->minEccKeySz < 0 ||
6847
0
                                  keySz < (int)ctx->minEccKeySz) {
6848
0
                        ret = ECC_KEY_SIZE_E;
6849
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6850
0
                    }
6851
0
                }
6852
0
                break;
6853
0
        #endif /* HAVE_ECC */
6854
0
        #ifdef HAVE_ED25519
6855
0
            case ED25519k:
6856
0
            #ifdef WOLF_PRIVATE_KEY_ID
6857
0
                keyType = ed25519_sa_algo;
6858
0
            #endif
6859
                /* ED25519 is fixed key size */
6860
0
                keySz = ED25519_KEY_SIZE;
6861
0
                if (ssl && !ssl->options.verifyNone) {
6862
0
                    if (ssl->options.minEccKeySz < 0 ||
6863
0
                          keySz < (int)ssl->options.minEccKeySz) {
6864
0
                        ret = ECC_KEY_SIZE_E;
6865
0
                        WOLFSSL_MSG("Certificate Ed key size error");
6866
0
                    }
6867
0
                }
6868
0
                else if (ctx && !ctx->verifyNone) {
6869
0
                    if (ctx->minEccKeySz < 0 ||
6870
0
                                  keySz < (int)ctx->minEccKeySz) {
6871
0
                        ret = ECC_KEY_SIZE_E;
6872
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6873
0
                    }
6874
0
                }
6875
0
                break;
6876
0
        #endif /* HAVE_ED25519 */
6877
0
        #ifdef HAVE_ED448
6878
0
            case ED448k:
6879
0
            #ifdef WOLF_PRIVATE_KEY_ID
6880
0
                keyType = ed448_sa_algo;
6881
0
            #endif
6882
                /* ED448 is fixed key size */
6883
0
                keySz = ED448_KEY_SIZE;
6884
0
                if (ssl && !ssl->options.verifyNone) {
6885
0
                    if (ssl->options.minEccKeySz < 0 ||
6886
0
                          keySz < (int)ssl->options.minEccKeySz) {
6887
0
                        ret = ECC_KEY_SIZE_E;
6888
0
                        WOLFSSL_MSG("Certificate Ed key size error");
6889
0
                    }
6890
0
                }
6891
0
                else if (ctx && !ctx->verifyNone) {
6892
0
                    if (ctx->minEccKeySz < 0 ||
6893
0
                                  keySz < (int)ctx->minEccKeySz) {
6894
0
                        ret = ECC_KEY_SIZE_E;
6895
0
                        WOLFSSL_MSG("Certificate ECC key size error");
6896
0
                    }
6897
0
                }
6898
0
                break;
6899
0
        #endif /* HAVE_ED448 */
6900
        #if defined(HAVE_PQC)
6901
        #if defined(HAVE_FALCON)
6902
            case FALCON_LEVEL1k:
6903
            case FALCON_LEVEL5k:
6904
                /* Falcon is fixed key size */
6905
                keySz = FALCON_MAX_KEY_SIZE;
6906
                if (ssl && !ssl->options.verifyNone) {
6907
                    if (ssl->options.minFalconKeySz < 0 ||
6908
                          keySz < (int)ssl->options.minFalconKeySz) {
6909
                        ret = FALCON_KEY_SIZE_E;
6910
                        WOLFSSL_MSG("Certificate Falcon key size error");
6911
                    }
6912
                }
6913
                else if (ctx && !ctx->verifyNone) {
6914
                    if (ctx->minFalconKeySz < 0 ||
6915
                                  keySz < (int)ctx->minFalconKeySz) {
6916
                        ret = FALCON_KEY_SIZE_E;
6917
                        WOLFSSL_MSG("Certificate Falcon key size error");
6918
                    }
6919
                }
6920
                break;
6921
        #endif /* HAVE_FALCON */
6922
        #if defined(HAVE_DILITHIUM)
6923
            case DILITHIUM_LEVEL2k:
6924
            case DILITHIUM_LEVEL3k:
6925
            case DILITHIUM_LEVEL5k:
6926
            case DILITHIUM_AES_LEVEL2k:
6927
            case DILITHIUM_AES_LEVEL3k:
6928
            case DILITHIUM_AES_LEVEL5k:
6929
                /* Dilithium is fixed key size */
6930
                keySz = DILITHIUM_MAX_KEY_SIZE;
6931
                if (ssl && !ssl->options.verifyNone) {
6932
                    if (ssl->options.minDilithiumKeySz < 0 ||
6933
                          keySz < (int)ssl->options.minDilithiumKeySz) {
6934
                        ret = DILITHIUM_KEY_SIZE_E;
6935
                        WOLFSSL_MSG("Certificate Dilithium key size error");
6936
                    }
6937
                }
6938
                else if (ctx && !ctx->verifyNone) {
6939
                    if (ctx->minDilithiumKeySz < 0 ||
6940
                                  keySz < (int)ctx->minDilithiumKeySz) {
6941
                        ret = DILITHIUM_KEY_SIZE_E;
6942
                        WOLFSSL_MSG("Certificate Dilithium key size error");
6943
                    }
6944
                }
6945
                break;
6946
        #endif /* HAVE_DILITHIUM */
6947
        #endif /* HAVE_PQC */
6948
6949
0
            default:
6950
0
                WOLFSSL_MSG("No key size check done on certificate");
6951
0
                break; /* do no check if not a case for the key */
6952
0
        }
6953
6954
0
    #ifdef WOLF_PRIVATE_KEY_ID
6955
0
        if (ssl != NULL && ssl->buffers.keyType == 0) {
6956
0
            ssl->buffers.keyType = keyType;
6957
0
            ssl->buffers.keySz = keySz;
6958
0
        }
6959
0
        else if (ctx != NULL && ctx->privateKeyType == 0) {
6960
0
            ctx->privateKeyType = keyType;
6961
0
            ctx->privateKeySz = keySz;
6962
0
        }
6963
0
    #endif
6964
6965
0
        FreeDecodedCert(cert);
6966
0
    #ifdef WOLFSSL_SMALL_STACK
6967
0
        XFREE(cert, heap, DYNAMIC_TYPE_DCERT);
6968
0
    #endif
6969
6970
0
        if (ret != 0) {
6971
0
            done = 1;
6972
0
        }
6973
0
    }
6974
6975
0
    if (done == 1) {
6976
0
    #if !defined(NO_WOLFSSL_CM_VERIFY) && (!defined(NO_WOLFSSL_CLIENT) || \
6977
0
                                           !defined(WOLFSSL_NO_CLIENT_AUTH))
6978
0
        if ((type == CA_TYPE) || (type == CERT_TYPE)) {
6979
            /* Call to over-ride status */
6980
0
            if ((ctx != NULL) && (ctx->cm != NULL) &&
6981
0
                (ctx->cm->verifyCallback != NULL)) {
6982
0
                ret = CM_VerifyBuffer_ex(ctx->cm, buff,
6983
0
                        sz, format, (ret == WOLFSSL_SUCCESS ? 0 : ret));
6984
0
            }
6985
0
        }
6986
0
    #endif /* NO_WOLFSSL_CM_VERIFY */
6987
6988
0
        return ret;
6989
0
    }
6990
6991
6992
0
    if (ssl && resetSuites) {
6993
0
        word16 havePSK = 0;
6994
0
        word16 haveRSA = 0;
6995
6996
        #ifndef NO_PSK
6997
        if (ssl->options.havePSK) {
6998
            havePSK = 1;
6999
        }
7000
        #endif
7001
0
        #ifndef NO_RSA
7002
0
            haveRSA = 1;
7003
0
        #endif
7004
0
            keySz = ssl->buffers.keySz;
7005
7006
        /* let's reset suites */
7007
0
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA,
7008
0
                   havePSK, ssl->options.haveDH, ssl->options.haveECDSAsig,
7009
0
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
7010
0
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
7011
0
                   ssl->options.haveAnon, TRUE, ssl->options.side);
7012
0
    }
7013
7014
0
    return WOLFSSL_SUCCESS;
7015
0
}
7016
7017
7018
/* CA PEM file for verification, may have multiple/chain certs to process */
7019
static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
7020
                        long sz, int format, int type, WOLFSSL* ssl, int verify)
7021
0
{
7022
0
    long used   = 0;
7023
0
    int  ret    = 0;
7024
0
    int  gotOne = 0;
7025
7026
0
    WOLFSSL_MSG("Processing CA PEM file");
7027
0
    while (used < sz) {
7028
0
        long consumed = 0;
7029
7030
0
        ret = ProcessBuffer(ctx, buff + used, sz - used, format, type, ssl,
7031
0
                            &consumed, 0, verify);
7032
7033
0
        if (ret < 0) {
7034
#if defined(WOLFSSL_WPAS) && defined(HAVE_CRL)
7035
            DerBuffer*    der = NULL;
7036
            EncryptedInfo info;
7037
7038
            WOLFSSL_MSG("Trying a CRL");
7039
            if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info,
7040
                                                                   NULL) == 0) {
7041
                WOLFSSL_MSG("   Processed a CRL");
7042
                wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer,
7043
                                            der->length, WOLFSSL_FILETYPE_ASN1);
7044
                FreeDer(&der);
7045
                used += info.consumed;
7046
                continue;
7047
            }
7048
#endif
7049
7050
0
            if (consumed > 0) { /* Made progress in file */
7051
0
                WOLFSSL_ERROR(ret);
7052
0
                WOLFSSL_MSG("CA Parse failed, with progress in file.");
7053
0
                WOLFSSL_MSG("Search for other certs in file");
7054
0
            }
7055
0
            else {
7056
0
                WOLFSSL_MSG("CA Parse failed, no progress in file.");
7057
0
                WOLFSSL_MSG("Do not continue search for other certs in file");
7058
0
                break;
7059
0
            }
7060
0
        }
7061
0
        else {
7062
0
            WOLFSSL_MSG("   Processed a CA");
7063
0
            gotOne = 1;
7064
0
        }
7065
0
        used += consumed;
7066
0
    }
7067
7068
0
    if (gotOne) {
7069
0
        WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
7070
0
        return WOLFSSL_SUCCESS;
7071
0
    }
7072
0
    return ret;
7073
0
}
7074
7075
7076
static WC_INLINE WOLFSSL_METHOD* cm_pick_method(void)
7077
0
{
7078
0
    #ifndef NO_WOLFSSL_CLIENT
7079
        #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
7080
            return wolfSSLv3_client_method();
7081
        #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
7082
            return wolfTLSv1_client_method();
7083
        #elif !defined(NO_OLD_TLS)
7084
0
            return wolfTLSv1_1_client_method();
7085
        #elif !defined(WOLFSSL_NO_TLS12)
7086
            return wolfTLSv1_2_client_method();
7087
        #elif defined(WOLFSSL_TLS13)
7088
            return wolfTLSv1_3_client_method();
7089
        #else
7090
            return NULL;
7091
        #endif
7092
    #elif !defined(NO_WOLFSSL_SERVER)
7093
        #if !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_SSLV3)
7094
            return wolfSSLv3_server_method();
7095
        #elif !defined(NO_OLD_TLS) && defined(WOLFSSL_ALLOW_TLSV10)
7096
            return wolfTLSv1_server_method();
7097
        #elif !defined(NO_OLD_TLS)
7098
            return wolfTLSv1_1_server_method();
7099
        #elif !defined(WOLFSSL_NO_TLS12)
7100
            return wolfTLSv1_2_server_method();
7101
        #elif defined(WOLFSSL_TLS13)
7102
            return wolfTLSv1_3_server_method();
7103
        #else
7104
            return NULL;
7105
        #endif
7106
    #else
7107
        return NULL;
7108
    #endif
7109
0
}
7110
7111
7112
/* like load verify locations, 1 for success, < 0 for error */
7113
int wolfSSL_CertManagerLoadCABuffer(WOLFSSL_CERT_MANAGER* cm,
7114
                                   const unsigned char* in, long sz, int format)
7115
0
{
7116
0
    int ret = WOLFSSL_FATAL_ERROR;
7117
0
    WOLFSSL_CTX* tmp;
7118
7119
0
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCABuffer");
7120
7121
0
    if (cm == NULL) {
7122
0
        WOLFSSL_MSG("No CertManager error");
7123
0
        return ret;
7124
0
    }
7125
0
    tmp = wolfSSL_CTX_new(cm_pick_method());
7126
7127
0
    if (tmp == NULL) {
7128
0
        WOLFSSL_MSG("CTX new failed");
7129
0
        return ret;
7130
0
    }
7131
7132
    /* for tmp use */
7133
0
    wolfSSL_CertManagerFree(tmp->cm);
7134
0
    tmp->cm = cm;
7135
7136
0
    ret = wolfSSL_CTX_load_verify_buffer(tmp, in, sz, format);
7137
7138
    /* don't loose our good one */
7139
0
    tmp->cm = NULL;
7140
0
    wolfSSL_CTX_free(tmp);
7141
7142
0
    return ret;
7143
0
}
7144
7145
#ifdef HAVE_CRL
7146
7147
int wolfSSL_CertManagerLoadCRLBuffer(WOLFSSL_CERT_MANAGER* cm,
7148
                                   const unsigned char* buff, long sz, int type)
7149
{
7150
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLBuffer");
7151
    if (cm == NULL)
7152
        return BAD_FUNC_ARG;
7153
7154
    if (cm->crl == NULL) {
7155
        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
7156
            WOLFSSL_MSG("Enable CRL failed");
7157
            return WOLFSSL_FATAL_ERROR;
7158
        }
7159
    }
7160
7161
    return BufferLoadCRL(cm->crl, buff, sz, type, VERIFY);
7162
}
7163
7164
int wolfSSL_CertManagerFreeCRL(WOLFSSL_CERT_MANAGER* cm)
7165
{
7166
    WOLFSSL_ENTER("wolfSSL_CertManagerFreeCRL");
7167
    if (cm == NULL)
7168
        return BAD_FUNC_ARG;
7169
    if (cm->crl != NULL){
7170
        FreeCRL(cm->crl, 1);
7171
        cm->crl = NULL;
7172
    }
7173
    return WOLFSSL_SUCCESS;
7174
}
7175
7176
int wolfSSL_CTX_LoadCRLBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
7177
                              long sz, int type)
7178
{
7179
    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRLBuffer");
7180
7181
    if (ctx == NULL)
7182
        return BAD_FUNC_ARG;
7183
7184
    return wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, buff, sz, type);
7185
}
7186
7187
7188
int wolfSSL_LoadCRLBuffer(WOLFSSL* ssl, const unsigned char* buff,
7189
                          long sz, int type)
7190
{
7191
    WOLFSSL_ENTER("wolfSSL_LoadCRLBuffer");
7192
7193
    if (ssl == NULL || ssl->ctx == NULL)
7194
        return BAD_FUNC_ARG;
7195
7196
    return wolfSSL_CertManagerLoadCRLBuffer(SSL_CM(ssl), buff, sz, type);
7197
}
7198
7199
7200
#endif /* HAVE_CRL */
7201
7202
/* turn on CRL if off and compiled in, set options */
7203
int wolfSSL_CertManagerEnableCRL(WOLFSSL_CERT_MANAGER* cm, int options)
7204
0
{
7205
0
    int ret = WOLFSSL_SUCCESS;
7206
7207
0
    (void)options;
7208
7209
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableCRL");
7210
0
    if (cm == NULL)
7211
0
        return BAD_FUNC_ARG;
7212
7213
    #ifdef HAVE_CRL
7214
        if (cm->crl == NULL) {
7215
            cm->crl = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), cm->heap,
7216
                                            DYNAMIC_TYPE_CRL);
7217
            if (cm->crl == NULL)
7218
                return MEMORY_E;
7219
7220
            if (InitCRL(cm->crl, cm) != 0) {
7221
                WOLFSSL_MSG("Init CRL failed");
7222
                FreeCRL(cm->crl, 1);
7223
                cm->crl = NULL;
7224
                return WOLFSSL_FAILURE;
7225
            }
7226
7227
        #if defined(HAVE_CRL_IO) && defined(USE_WOLFSSL_IO)
7228
            cm->crl->crlIOCb = EmbedCrlLookup;
7229
        #endif
7230
        }
7231
7232
        cm->crlEnabled = 1;
7233
        if (options & WOLFSSL_CRL_CHECKALL)
7234
            cm->crlCheckAll = 1;
7235
    #else
7236
0
        ret = NOT_COMPILED_IN;
7237
0
    #endif
7238
7239
0
    return ret;
7240
0
}
7241
7242
7243
int wolfSSL_CertManagerDisableCRL(WOLFSSL_CERT_MANAGER* cm)
7244
0
{
7245
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableCRL");
7246
0
    if (cm == NULL)
7247
0
        return BAD_FUNC_ARG;
7248
7249
0
    cm->crlEnabled = 0;
7250
7251
0
    return WOLFSSL_SUCCESS;
7252
0
}
7253
7254
#ifndef NO_WOLFSSL_CM_VERIFY
7255
void wolfSSL_CertManagerSetVerify(WOLFSSL_CERT_MANAGER* cm, VerifyCallback vc)
7256
0
{
7257
0
    WOLFSSL_ENTER("wolfSSL_CertManagerSetVerify");
7258
0
    if (cm == NULL)
7259
0
        return;
7260
7261
0
    cm->verifyCallback = vc;
7262
0
}
7263
#endif /* NO_WOLFSSL_CM_VERIFY */
7264
7265
#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
7266
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
7267
int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
7268
                                    long sz, int format, int err_val)
7269
0
{
7270
0
    int ret = 0;
7271
0
    DerBuffer* der = NULL;
7272
0
#ifdef WOLFSSL_SMALL_STACK
7273
0
    DecodedCert* cert;
7274
#else
7275
    DecodedCert  cert[1];
7276
#endif
7277
7278
0
    WOLFSSL_ENTER("wolfSSL_CertManagerVerifyBuffer");
7279
7280
0
#ifdef WOLFSSL_SMALL_STACK
7281
0
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap,
7282
0
                                 DYNAMIC_TYPE_DCERT);
7283
0
    if (cert == NULL)
7284
0
        return MEMORY_E;
7285
0
#endif
7286
7287
0
    if (format == WOLFSSL_FILETYPE_PEM) {
7288
0
#ifdef WOLFSSL_PEM_TO_DER
7289
0
        ret = PemToDer(buff, sz, CERT_TYPE, &der, cm->heap, NULL, NULL);
7290
0
        if (ret != 0) {
7291
0
            FreeDer(&der);
7292
0
        #ifdef WOLFSSL_SMALL_STACK
7293
0
            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7294
0
        #endif
7295
0
            return ret;
7296
0
        }
7297
0
        InitDecodedCert(cert, der->buffer, der->length, cm->heap);
7298
#else
7299
        ret = NOT_COMPILED_IN;
7300
#endif
7301
0
    }
7302
0
    else {
7303
0
        InitDecodedCert(cert, buff, (word32)sz, cm->heap);
7304
0
    }
7305
7306
0
    if (ret == 0)
7307
0
        ret = ParseCertRelative(cert, CERT_TYPE, 1, cm);
7308
7309
#ifdef HAVE_CRL
7310
    if (ret == 0 && cm->crlEnabled)
7311
        ret = CheckCertCRL(cm->crl, cert);
7312
#endif
7313
7314
0
#ifndef NO_WOLFSSL_CM_VERIFY
7315
    /* if verify callback has been set */
7316
0
    if (cm->verifyCallback) {
7317
0
        buffer certBuf;
7318
0
    #ifdef WOLFSSL_SMALL_STACK
7319
0
        ProcPeerCertArgs* args;
7320
0
        args = (ProcPeerCertArgs*)XMALLOC(
7321
0
            sizeof(ProcPeerCertArgs), cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
7322
0
        if (args == NULL) {
7323
0
            XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7324
0
            return MEMORY_E;
7325
0
        }
7326
    #else
7327
        ProcPeerCertArgs  args[1];
7328
    #endif
7329
7330
0
        certBuf.buffer = (byte*)buff;
7331
0
        certBuf.length = (unsigned int)sz;
7332
0
        XMEMSET(args, 0, sizeof(ProcPeerCertArgs));
7333
7334
0
        args->totalCerts = 1;
7335
0
        args->certs = &certBuf;
7336
0
        args->dCert = cert;
7337
0
        args->dCertInit = 1;
7338
7339
0
        if (err_val != 0) {
7340
0
            ret = err_val;
7341
0
        }
7342
0
        ret = DoVerifyCallback(cm, NULL, ret, args);
7343
0
    #ifdef WOLFSSL_SMALL_STACK
7344
0
        XFREE(args, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
7345
0
    #endif
7346
0
    }
7347
#else
7348
    (void)err_val;
7349
#endif
7350
7351
0
    FreeDecodedCert(cert);
7352
0
    FreeDer(&der);
7353
0
#ifdef WOLFSSL_SMALL_STACK
7354
0
    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7355
0
#endif
7356
7357
0
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
7358
0
}
7359
7360
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
7361
int wolfSSL_CertManagerVerifyBuffer(WOLFSSL_CERT_MANAGER* cm, const byte* buff,
7362
                                    long sz, int format)
7363
0
{
7364
0
    return CM_VerifyBuffer_ex(cm, buff, sz, format, 0);
7365
0
}
7366
#endif /* !NO_WOLFSSL_CLIENT || !WOLFSSL_NO_CLIENT_AUTH */
7367
7368
/* turn on OCSP if off and compiled in, set options */
7369
int wolfSSL_CertManagerEnableOCSP(WOLFSSL_CERT_MANAGER* cm, int options)
7370
0
{
7371
0
    int ret = WOLFSSL_SUCCESS;
7372
7373
0
    (void)options;
7374
7375
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSP");
7376
0
    if (cm == NULL)
7377
0
        return BAD_FUNC_ARG;
7378
7379
0
    #ifdef HAVE_OCSP
7380
0
        if (cm->ocsp == NULL) {
7381
0
            cm->ocsp = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP), cm->heap,
7382
0
                                              DYNAMIC_TYPE_OCSP);
7383
0
            if (cm->ocsp == NULL)
7384
0
                return MEMORY_E;
7385
7386
0
            if (InitOCSP(cm->ocsp, cm) != 0) {
7387
0
                WOLFSSL_MSG("Init OCSP failed");
7388
0
                FreeOCSP(cm->ocsp, 1);
7389
0
                cm->ocsp = NULL;
7390
0
                return WOLFSSL_FAILURE;
7391
0
            }
7392
0
        }
7393
0
        cm->ocspEnabled = 1;
7394
0
        if (options & WOLFSSL_OCSP_URL_OVERRIDE)
7395
0
            cm->ocspUseOverrideURL = 1;
7396
0
        if (options & WOLFSSL_OCSP_NO_NONCE)
7397
0
            cm->ocspSendNonce = 0;
7398
0
        else
7399
0
            cm->ocspSendNonce = 1;
7400
0
        if (options & WOLFSSL_OCSP_CHECKALL)
7401
0
            cm->ocspCheckAll = 1;
7402
0
        #ifndef WOLFSSL_USER_IO
7403
0
            cm->ocspIOCb = EmbedOcspLookup;
7404
0
            cm->ocspRespFreeCb = EmbedOcspRespFree;
7405
0
            cm->ocspIOCtx = cm->heap;
7406
0
        #endif /* WOLFSSL_USER_IO */
7407
    #else
7408
        ret = NOT_COMPILED_IN;
7409
    #endif
7410
7411
0
    return ret;
7412
0
}
7413
7414
7415
int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
7416
0
{
7417
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSP");
7418
0
    if (cm == NULL)
7419
0
        return BAD_FUNC_ARG;
7420
7421
0
    cm->ocspEnabled = 0;
7422
7423
0
    return WOLFSSL_SUCCESS;
7424
0
}
7425
7426
/* turn on OCSP Stapling if off and compiled in, set options */
7427
int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
7428
0
{
7429
0
    int ret = WOLFSSL_SUCCESS;
7430
7431
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
7432
7433
0
    if (cm == NULL)
7434
0
        return BAD_FUNC_ARG;
7435
7436
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7437
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7438
    #ifndef NO_WOLFSSL_SERVER
7439
    if (cm->ocsp_stapling == NULL) {
7440
        cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
7441
                                               cm->heap, DYNAMIC_TYPE_OCSP);
7442
        if (cm->ocsp_stapling == NULL)
7443
            return MEMORY_E;
7444
7445
        if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
7446
            WOLFSSL_MSG("Init OCSP failed");
7447
            FreeOCSP(cm->ocsp_stapling, 1);
7448
            cm->ocsp_stapling = NULL;
7449
            return WOLFSSL_FAILURE;
7450
        }
7451
    }
7452
7453
    #ifndef WOLFSSL_USER_IO
7454
        cm->ocspIOCb = EmbedOcspLookup;
7455
        cm->ocspRespFreeCb = EmbedOcspRespFree;
7456
        cm->ocspIOCtx = cm->heap;
7457
    #endif /* WOLFSSL_USER_IO */
7458
    #endif /* NO_WOLFSSL_SERVER */
7459
    cm->ocspStaplingEnabled = 1;
7460
#else
7461
0
    ret = NOT_COMPILED_IN;
7462
0
#endif
7463
7464
0
    return ret;
7465
0
}
7466
7467
int wolfSSL_CertManagerDisableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
7468
0
{
7469
0
    int ret = WOLFSSL_SUCCESS;
7470
7471
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPStapling");
7472
7473
0
    if (cm == NULL)
7474
0
        return BAD_FUNC_ARG;
7475
7476
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7477
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7478
    cm->ocspStaplingEnabled = 0;
7479
#else
7480
0
    ret = NOT_COMPILED_IN;
7481
0
#endif
7482
0
    return ret;
7483
0
}
7484
7485
/* require OCSP stapling response */
7486
int wolfSSL_CertManagerEnableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
7487
0
{
7488
0
    int ret;
7489
7490
0
    WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPMustStaple");
7491
7492
0
    if (cm == NULL)
7493
0
        return BAD_FUNC_ARG;
7494
7495
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7496
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7497
    #ifndef NO_WOLFSSL_CLIENT
7498
        cm->ocspMustStaple = 1;
7499
    #endif
7500
    ret = WOLFSSL_SUCCESS;
7501
#else
7502
0
    ret = NOT_COMPILED_IN;
7503
0
#endif
7504
7505
0
    return ret;
7506
0
}
7507
7508
int wolfSSL_CertManagerDisableOCSPMustStaple(WOLFSSL_CERT_MANAGER* cm)
7509
0
{
7510
0
    int ret;
7511
7512
0
    WOLFSSL_ENTER("wolfSSL_CertManagerDisableOCSPMustStaple");
7513
7514
0
    if (cm == NULL)
7515
0
        return BAD_FUNC_ARG;
7516
7517
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7518
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7519
    #ifndef NO_WOLFSSL_CLIENT
7520
        cm->ocspMustStaple = 0;
7521
    #endif
7522
    ret = WOLFSSL_SUCCESS;
7523
#else
7524
0
    ret = NOT_COMPILED_IN;
7525
0
#endif
7526
0
    return ret;
7527
0
}
7528
7529
#ifdef HAVE_OCSP
7530
/* check CRL if enabled, WOLFSSL_SUCCESS  */
7531
int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
7532
0
{
7533
0
    int ret;
7534
0
#ifdef WOLFSSL_SMALL_STACK
7535
0
    DecodedCert* cert = NULL;
7536
#else
7537
    DecodedCert  cert[1];
7538
#endif
7539
7540
0
    WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSP");
7541
7542
0
    if (cm == NULL)
7543
0
        return BAD_FUNC_ARG;
7544
7545
0
    if (cm->ocspEnabled == 0)
7546
0
        return WOLFSSL_SUCCESS;
7547
7548
0
#ifdef WOLFSSL_SMALL_STACK
7549
0
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), cm->heap, DYNAMIC_TYPE_DCERT);
7550
0
    if (cert == NULL)
7551
0
        return MEMORY_E;
7552
0
#endif
7553
7554
0
    InitDecodedCert(cert, der, sz, NULL);
7555
7556
0
    if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_OCSP, cm)) != 0) {
7557
0
        WOLFSSL_MSG("ParseCert failed");
7558
0
    }
7559
0
    else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
7560
0
        WOLFSSL_MSG("CheckCertOCSP failed");
7561
0
    }
7562
7563
0
    FreeDecodedCert(cert);
7564
0
#ifdef WOLFSSL_SMALL_STACK
7565
0
    XFREE(cert, cm->heap, DYNAMIC_TYPE_DCERT);
7566
0
#endif
7567
7568
0
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
7569
0
}
7570
7571
WOLFSSL_API int wolfSSL_CertManagerCheckOCSPResponse(WOLFSSL_CERT_MANAGER *cm,
7572
                                                    byte *response, int responseSz, buffer *responseBuffer,
7573
                                                    CertStatus *status, OcspEntry *entry, OcspRequest *ocspRequest)
7574
0
{
7575
0
    int ret;
7576
7577
0
    WOLFSSL_ENTER("wolfSSL_CertManagerCheckOCSPResponse");
7578
0
    if (cm == NULL || response == NULL)
7579
0
        return BAD_FUNC_ARG;
7580
0
    if (cm->ocspEnabled == 0)
7581
0
        return WOLFSSL_SUCCESS;
7582
7583
0
    ret = CheckOcspResponse(cm->ocsp, response, responseSz, responseBuffer, status,
7584
0
                        entry, ocspRequest);
7585
7586
0
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
7587
0
}
7588
7589
int wolfSSL_CertManagerSetOCSPOverrideURL(WOLFSSL_CERT_MANAGER* cm,
7590
                                          const char* url)
7591
0
{
7592
0
    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSPOverrideURL");
7593
0
    if (cm == NULL)
7594
0
        return BAD_FUNC_ARG;
7595
7596
0
    XFREE(cm->ocspOverrideURL, cm->heap, DYNAMIC_TYPE_URL);
7597
0
    if (url != NULL) {
7598
0
        int urlSz = (int)XSTRLEN(url) + 1;
7599
0
        cm->ocspOverrideURL = (char*)XMALLOC(urlSz, cm->heap, DYNAMIC_TYPE_URL);
7600
0
        if (cm->ocspOverrideURL != NULL) {
7601
0
            XMEMCPY(cm->ocspOverrideURL, url, urlSz);
7602
0
        }
7603
0
        else
7604
0
            return MEMORY_E;
7605
0
    }
7606
0
    else
7607
0
        cm->ocspOverrideURL = NULL;
7608
7609
0
    return WOLFSSL_SUCCESS;
7610
0
}
7611
7612
7613
int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER* cm,
7614
                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
7615
0
{
7616
0
    WOLFSSL_ENTER("wolfSSL_CertManagerSetOCSP_Cb");
7617
0
    if (cm == NULL)
7618
0
        return BAD_FUNC_ARG;
7619
7620
0
    cm->ocspIOCb = ioCb;
7621
0
    cm->ocspRespFreeCb = respFreeCb;
7622
0
    cm->ocspIOCtx = ioCbCtx;
7623
7624
0
    return WOLFSSL_SUCCESS;
7625
0
}
7626
7627
7628
int wolfSSL_EnableOCSP(WOLFSSL* ssl, int options)
7629
0
{
7630
0
    WOLFSSL_ENTER("wolfSSL_EnableOCSP");
7631
0
    if (ssl)
7632
0
        return wolfSSL_CertManagerEnableOCSP(SSL_CM(ssl), options);
7633
0
    else
7634
0
        return BAD_FUNC_ARG;
7635
0
}
7636
7637
int wolfSSL_DisableOCSP(WOLFSSL* ssl)
7638
0
{
7639
0
    WOLFSSL_ENTER("wolfSSL_DisableOCSP");
7640
0
    if (ssl)
7641
0
        return wolfSSL_CertManagerDisableOCSP(SSL_CM(ssl));
7642
0
    else
7643
0
        return BAD_FUNC_ARG;
7644
0
}
7645
7646
7647
int wolfSSL_EnableOCSPStapling(WOLFSSL* ssl)
7648
0
{
7649
0
    WOLFSSL_ENTER("wolfSSL_EnableOCSPStapling");
7650
0
    if (ssl)
7651
0
        return wolfSSL_CertManagerEnableOCSPStapling(SSL_CM(ssl));
7652
0
    else
7653
0
        return BAD_FUNC_ARG;
7654
0
}
7655
7656
int wolfSSL_DisableOCSPStapling(WOLFSSL* ssl)
7657
0
{
7658
0
    WOLFSSL_ENTER("wolfSSL_DisableOCSPStapling");
7659
0
    if (ssl)
7660
0
        return wolfSSL_CertManagerDisableOCSPStapling(SSL_CM(ssl));
7661
0
    else
7662
0
        return BAD_FUNC_ARG;
7663
0
}
7664
7665
int wolfSSL_SetOCSP_OverrideURL(WOLFSSL* ssl, const char* url)
7666
0
{
7667
0
    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
7668
0
    if (ssl)
7669
0
        return wolfSSL_CertManagerSetOCSPOverrideURL(SSL_CM(ssl), url);
7670
0
    else
7671
0
        return BAD_FUNC_ARG;
7672
0
}
7673
7674
7675
int wolfSSL_SetOCSP_Cb(WOLFSSL* ssl,
7676
                        CbOCSPIO ioCb, CbOCSPRespFree respFreeCb, void* ioCbCtx)
7677
0
{
7678
0
    WOLFSSL_ENTER("wolfSSL_SetOCSP_Cb");
7679
0
    if (ssl) {
7680
0
        ssl->ocspIOCtx = ioCbCtx; /* use SSL specific ioCbCtx */
7681
0
        return wolfSSL_CertManagerSetOCSP_Cb(SSL_CM(ssl),
7682
0
                                             ioCb, respFreeCb, NULL);
7683
0
    }
7684
0
    else
7685
0
        return BAD_FUNC_ARG;
7686
0
}
7687
7688
7689
int wolfSSL_CTX_EnableOCSP(WOLFSSL_CTX* ctx, int options)
7690
0
{
7691
0
    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSP");
7692
0
    if (ctx)
7693
0
        return wolfSSL_CertManagerEnableOCSP(ctx->cm, options);
7694
0
    else
7695
0
        return BAD_FUNC_ARG;
7696
0
}
7697
7698
7699
int wolfSSL_CTX_DisableOCSP(WOLFSSL_CTX* ctx)
7700
0
{
7701
0
    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSP");
7702
0
    if (ctx)
7703
0
        return wolfSSL_CertManagerDisableOCSP(ctx->cm);
7704
0
    else
7705
0
        return BAD_FUNC_ARG;
7706
0
}
7707
7708
7709
int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX* ctx, const char* url)
7710
0
{
7711
0
    WOLFSSL_ENTER("wolfSSL_SetOCSP_OverrideURL");
7712
0
    if (ctx)
7713
0
        return wolfSSL_CertManagerSetOCSPOverrideURL(ctx->cm, url);
7714
0
    else
7715
0
        return BAD_FUNC_ARG;
7716
0
}
7717
7718
7719
int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
7720
                           CbOCSPRespFree respFreeCb, void* ioCbCtx)
7721
0
{
7722
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetOCSP_Cb");
7723
0
    if (ctx)
7724
0
        return wolfSSL_CertManagerSetOCSP_Cb(ctx->cm, ioCb,
7725
0
                                             respFreeCb, ioCbCtx);
7726
0
    else
7727
0
        return BAD_FUNC_ARG;
7728
0
}
7729
7730
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
7731
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
7732
int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
7733
{
7734
    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
7735
    if (ctx)
7736
        return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
7737
    else
7738
        return BAD_FUNC_ARG;
7739
}
7740
7741
int wolfSSL_CTX_DisableOCSPStapling(WOLFSSL_CTX* ctx)
7742
{
7743
    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPStapling");
7744
    if (ctx)
7745
        return wolfSSL_CertManagerDisableOCSPStapling(ctx->cm);
7746
    else
7747
        return BAD_FUNC_ARG;
7748
}
7749
7750
int wolfSSL_CTX_EnableOCSPMustStaple(WOLFSSL_CTX* ctx)
7751
{
7752
    WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPMustStaple");
7753
    if (ctx)
7754
        return wolfSSL_CertManagerEnableOCSPMustStaple(ctx->cm);
7755
    else
7756
        return BAD_FUNC_ARG;
7757
}
7758
7759
int wolfSSL_CTX_DisableOCSPMustStaple(WOLFSSL_CTX* ctx)
7760
{
7761
    WOLFSSL_ENTER("wolfSSL_CTX_DisableOCSPMustStaple");
7762
    if (ctx)
7763
        return wolfSSL_CertManagerDisableOCSPMustStaple(ctx->cm);
7764
    else
7765
        return BAD_FUNC_ARG;
7766
}
7767
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST || HAVE_CERTIFICATE_STATUS_REQUEST_V2 */
7768
7769
#endif /* HAVE_OCSP */
7770
7771
/* macro to get verify settings for AddCA */
7772
#define GET_VERIFY_SETTING_CTX(ctx) \
7773
0
    ((ctx) && (ctx)->verifyNone ? NO_VERIFY : VERIFY)
7774
#define GET_VERIFY_SETTING_SSL(ssl) \
7775
0
    ((ssl)->options.verifyNone ? NO_VERIFY : VERIFY)
7776
7777
#ifndef NO_FILESYSTEM
7778
7779
/* process a file with name fname into ctx of format and type
7780
   userChain specifies a user certificate chain to pass during handshake */
7781
int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
7782
                WOLFSSL* ssl, int userChain, WOLFSSL_CRL* crl, int verify)
7783
0
{
7784
0
#ifdef WOLFSSL_SMALL_STACK
7785
0
    byte   staticBuffer[1]; /* force heap usage */
7786
#else
7787
    byte   staticBuffer[FILE_BUFFER_SIZE];
7788
#endif
7789
0
    byte*  myBuffer = staticBuffer;
7790
0
    int    dynamic = 0;
7791
0
    int    ret;
7792
0
    long   sz = 0;
7793
0
    XFILE  file;
7794
0
    void*  heapHint = wolfSSL_CTX_GetHeap(ctx, ssl);
7795
0
#ifndef NO_CODING
7796
0
    const char* header = NULL;
7797
0
    const char* footer = NULL;
7798
0
#endif
7799
7800
0
    (void)crl;
7801
0
    (void)heapHint;
7802
7803
0
    if (fname == NULL) return WOLFSSL_BAD_FILE;
7804
7805
0
    file = XFOPEN(fname, "rb");
7806
0
    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
7807
0
    if (XFSEEK(file, 0, XSEEK_END) != 0) {
7808
0
        XFCLOSE(file);
7809
0
        return WOLFSSL_BAD_FILE;
7810
0
    }
7811
0
    sz = XFTELL(file);
7812
0
    XREWIND(file);
7813
7814
0
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
7815
0
        WOLFSSL_MSG("ProcessFile file size error");
7816
0
        XFCLOSE(file);
7817
0
        return WOLFSSL_BAD_FILE;
7818
0
    }
7819
7820
0
    if (sz > (long)sizeof(staticBuffer)) {
7821
0
        WOLFSSL_MSG("Getting dynamic buffer");
7822
0
        myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
7823
0
        if (myBuffer == NULL) {
7824
0
            XFCLOSE(file);
7825
0
            return WOLFSSL_BAD_FILE;
7826
0
        }
7827
0
        dynamic = 1;
7828
0
    }
7829
7830
0
    if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
7831
0
        ret = WOLFSSL_BAD_FILE;
7832
0
    else {
7833
        /* Try to detect type by parsing cert header and footer */
7834
0
        if (type == DETECT_CERT_TYPE) {
7835
0
#ifndef NO_CODING
7836
0
            if (wc_PemGetHeaderFooter(CA_TYPE, &header, &footer) == 0 &&
7837
0
               (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7838
0
                type = CA_TYPE;
7839
0
            }
7840
#ifdef HAVE_CRL
7841
            else if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
7842
                    (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7843
                type = CRL_TYPE;
7844
            }
7845
#endif
7846
0
            else if (wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer) == 0 &&
7847
0
                    (XSTRNSTR((char*)myBuffer, header, (int)sz) != NULL)) {
7848
0
                type = CERT_TYPE;
7849
0
            }
7850
0
            else
7851
0
#endif
7852
0
            {
7853
0
                WOLFSSL_MSG("Failed to detect certificate type");
7854
0
                if (dynamic)
7855
0
                    XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
7856
0
                XFCLOSE(file);
7857
0
                return WOLFSSL_BAD_CERTTYPE;
7858
0
            }
7859
0
        }
7860
0
        if ((type == CA_TYPE || type == TRUSTED_PEER_TYPE)
7861
0
                                          && format == WOLFSSL_FILETYPE_PEM) {
7862
0
            ret = ProcessChainBuffer(ctx, myBuffer, sz, format, type, ssl,
7863
0
                                     verify);
7864
0
        }
7865
#ifdef HAVE_CRL
7866
        else if (type == CRL_TYPE)
7867
            ret = BufferLoadCRL(crl, myBuffer, sz, format, verify);
7868
#endif
7869
0
        else
7870
0
            ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL,
7871
0
                                userChain, verify);
7872
0
    }
7873
7874
0
    XFCLOSE(file);
7875
0
    if (dynamic)
7876
0
        XFREE(myBuffer, heapHint, DYNAMIC_TYPE_FILE);
7877
7878
0
    return ret;
7879
0
}
7880
7881
/* loads file then loads each file in path, no c_rehash */
7882
int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
7883
                                     const char* path, word32 flags)
7884
0
{
7885
0
    int ret = WOLFSSL_SUCCESS;
7886
0
#ifndef NO_WOLFSSL_DIR
7887
0
    int fileRet;
7888
0
    int successCount = 0;
7889
0
    int failCount = 0;
7890
0
#endif
7891
0
    int verify;
7892
7893
0
    WOLFSSL_MSG("wolfSSL_CTX_load_verify_locations_ex");
7894
7895
0
    if (ctx == NULL || (file == NULL && path == NULL)) {
7896
0
        return WOLFSSL_FAILURE;
7897
0
    }
7898
7899
0
    verify = GET_VERIFY_SETTING_CTX(ctx);
7900
0
    if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
7901
0
        verify = VERIFY_SKIP_DATE;
7902
7903
0
    if (file) {
7904
0
        ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0,
7905
0
                          NULL, verify);
7906
0
#ifndef NO_WOLFSSL_DIR
7907
0
        if (ret == WOLFSSL_SUCCESS)
7908
0
            successCount++;
7909
0
#endif
7910
#if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
7911
        ret = wolfSSL_CTX_trust_peer_cert(ctx, file, WOLFSSL_FILETYPE_PEM);
7912
        if (ret != WOLFSSL_SUCCESS) {
7913
            WOLFSSL_MSG("wolfSSL_CTX_trust_peer_cert error");
7914
        }
7915
#endif
7916
0
    }
7917
7918
0
    if (ret == WOLFSSL_SUCCESS && path) {
7919
0
#ifndef NO_WOLFSSL_DIR
7920
0
        char* name = NULL;
7921
0
    #ifdef WOLFSSL_SMALL_STACK
7922
0
        ReadDirCtx* readCtx;
7923
0
        readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
7924
0
                                                       DYNAMIC_TYPE_DIRCTX);
7925
0
        if (readCtx == NULL)
7926
0
            return MEMORY_E;
7927
    #else
7928
        ReadDirCtx readCtx[1];
7929
    #endif
7930
7931
        /* try to load each regular file in path */
7932
0
        fileRet = wc_ReadDirFirst(readCtx, path, &name);
7933
0
        while (fileRet == 0 && name) {
7934
0
            WOLFSSL_MSG(name); /* log file name */
7935
0
            ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, CA_TYPE,
7936
0
                              NULL, 0, NULL, verify);
7937
0
            if (ret != WOLFSSL_SUCCESS) {
7938
                /* handle flags for ignoring errors, skipping expired certs or
7939
                   by PEM certificate header error */
7940
0
                if ( (flags & WOLFSSL_LOAD_FLAG_IGNORE_ERR) ||
7941
0
                    ((flags & WOLFSSL_LOAD_FLAG_PEM_CA_ONLY) &&
7942
0
                       (ret == ASN_NO_PEM_HEADER))) {
7943
                    /* Do not fail here if a certificate fails to load,
7944
                       continue to next file */
7945
0
                    unsigned long err;
7946
0
                    CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
7947
    #if defined(WOLFSSL_QT)
7948
                    ret = WOLFSSL_SUCCESS;
7949
    #endif
7950
0
                }
7951
0
                else {
7952
0
                    WOLFSSL_ERROR(ret);
7953
0
                    WOLFSSL_MSG("Load CA file failed, continuing");
7954
0
                    failCount++;
7955
0
                }
7956
0
            }
7957
0
            else {
7958
    #if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
7959
                ret = wolfSSL_CTX_trust_peer_cert(ctx, file, WOLFSSL_FILETYPE_PEM);
7960
                if (ret != WOLFSSL_SUCCESS) {
7961
                    WOLFSSL_MSG("wolfSSL_CTX_trust_peer_cert error. Ignoring"
7962
                            "this error.");
7963
                }
7964
    #endif
7965
0
                successCount++;
7966
0
            }
7967
0
            fileRet = wc_ReadDirNext(readCtx, path, &name);
7968
0
        }
7969
0
        wc_ReadDirClose(readCtx);
7970
7971
        /* pass directory read failure to response code */
7972
0
        if (fileRet != WC_READDIR_NOFILE) {
7973
0
            ret = fileRet;
7974
    #if defined(WOLFSSL_QT)
7975
            if (ret == BAD_PATH_ERROR &&
7976
                flags & WOLFSSL_LOAD_FLAG_IGNORE_BAD_PATH_ERR) {
7977
               /* QSslSocket always loads certs in system folder
7978
                * when it is initialized.
7979
                * Compliant with OpenSSL when flag sets.
7980
                */
7981
                ret = WOLFSSL_SUCCESS;
7982
            }
7983
            else {
7984
                /* qssl socket wants to know errors. */
7985
                WOLFSSL_ERROR(ret);
7986
            }
7987
    #endif
7988
0
        }
7989
        /* report failure if no files were loaded or there were failures */
7990
0
        else if (successCount == 0 || failCount > 0) {
7991
            /* use existing error code if exists */
7992
    #if defined(WOLFSSL_QT)
7993
            /* compliant with OpenSSL when flag sets*/
7994
            if (!(flags & WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE))
7995
    #endif
7996
0
            {
7997
0
                ret = WOLFSSL_FAILURE;
7998
0
            }
7999
0
        }
8000
0
        else {
8001
0
            ret = WOLFSSL_SUCCESS;
8002
0
        }
8003
8004
0
    #ifdef WOLFSSL_SMALL_STACK
8005
0
        XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
8006
0
    #endif
8007
#else
8008
        ret = NOT_COMPILED_IN;
8009
        (void)flags;
8010
#endif
8011
0
    }
8012
8013
0
    return ret;
8014
0
}
8015
8016
WOLFSSL_ABI
8017
int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
8018
                                     const char* path)
8019
0
{
8020
0
    int ret = wolfSSL_CTX_load_verify_locations_ex(ctx, file, path,
8021
0
        WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
8022
8023
0
    return WS_RETURN_CODE(ret,WOLFSSL_FAILURE);
8024
0
}
8025
8026
8027
#ifdef WOLFSSL_TRUST_PEER_CERT
8028
/* Used to specify a peer cert to match when connecting
8029
    ctx : the ctx structure to load in peer cert
8030
    file: the string name of cert file
8031
    type: type of format such as PEM/DER
8032
 */
8033
int wolfSSL_CTX_trust_peer_cert(WOLFSSL_CTX* ctx, const char* file, int type)
8034
{
8035
    WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_cert");
8036
8037
    if (ctx == NULL || file == NULL) {
8038
        return WOLFSSL_FAILURE;
8039
    }
8040
8041
    return ProcessFile(ctx, file, type, TRUSTED_PEER_TYPE, NULL, 0, NULL,
8042
                       GET_VERIFY_SETTING_CTX(ctx));
8043
}
8044
8045
int wolfSSL_trust_peer_cert(WOLFSSL* ssl, const char* file, int type)
8046
{
8047
    WOLFSSL_ENTER("wolfSSL_trust_peer_cert");
8048
8049
    if (ssl == NULL || file == NULL) {
8050
        return WOLFSSL_FAILURE;
8051
    }
8052
8053
    return ProcessFile(NULL, file, type, TRUSTED_PEER_TYPE, ssl, 0, NULL,
8054
                       GET_VERIFY_SETTING_SSL(ssl));
8055
}
8056
#endif /* WOLFSSL_TRUST_PEER_CERT */
8057
8058
8059
#if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH)
8060
/* Verify the certificate, WOLFSSL_SUCCESS for ok, < 0 for error */
8061
int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
8062
                             int format)
8063
0
{
8064
0
    int    ret = WOLFSSL_FATAL_ERROR;
8065
0
#ifdef WOLFSSL_SMALL_STACK
8066
0
    byte   staticBuffer[1]; /* force heap usage */
8067
#else
8068
    byte   staticBuffer[FILE_BUFFER_SIZE];
8069
#endif
8070
0
    byte*  myBuffer = staticBuffer;
8071
0
    int    dynamic = 0;
8072
0
    long   sz = 0;
8073
0
    XFILE  file = XFOPEN(fname, "rb");
8074
8075
0
    WOLFSSL_ENTER("wolfSSL_CertManagerVerify");
8076
8077
0
    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
8078
0
    if(XFSEEK(file, 0, XSEEK_END) != 0) {
8079
0
        XFCLOSE(file);
8080
0
        return WOLFSSL_BAD_FILE;
8081
0
    }
8082
0
    sz = XFTELL(file);
8083
0
    XREWIND(file);
8084
8085
0
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
8086
0
        WOLFSSL_MSG("CertManagerVerify file size error");
8087
0
        XFCLOSE(file);
8088
0
        return WOLFSSL_BAD_FILE;
8089
0
    }
8090
8091
0
    if (sz > (long)sizeof(staticBuffer)) {
8092
0
        WOLFSSL_MSG("Getting dynamic buffer");
8093
0
        myBuffer = (byte*) XMALLOC(sz, cm->heap, DYNAMIC_TYPE_FILE);
8094
0
        if (myBuffer == NULL) {
8095
0
            XFCLOSE(file);
8096
0
            return WOLFSSL_BAD_FILE;
8097
0
        }
8098
0
        dynamic = 1;
8099
0
    }
8100
8101
0
    if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
8102
0
        ret = WOLFSSL_BAD_FILE;
8103
0
    else
8104
0
        ret = wolfSSL_CertManagerVerifyBuffer(cm, myBuffer, sz, format);
8105
8106
0
    XFCLOSE(file);
8107
0
    if (dynamic)
8108
0
        XFREE(myBuffer, cm->heap, DYNAMIC_TYPE_FILE);
8109
8110
0
    return ret;
8111
0
}
8112
#endif
8113
8114
/* like load verify locations, 1 for success, < 0 for error */
8115
int wolfSSL_CertManagerLoadCA(WOLFSSL_CERT_MANAGER* cm, const char* file,
8116
                             const char* path)
8117
0
{
8118
0
    int ret = WOLFSSL_FATAL_ERROR;
8119
0
    WOLFSSL_CTX* tmp;
8120
8121
0
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCA");
8122
8123
0
    if (cm == NULL) {
8124
0
        WOLFSSL_MSG("No CertManager error");
8125
0
        return ret;
8126
0
    }
8127
0
    tmp = wolfSSL_CTX_new(cm_pick_method());
8128
8129
0
    if (tmp == NULL) {
8130
0
        WOLFSSL_MSG("CTX new failed");
8131
0
        return ret;
8132
0
    }
8133
8134
    /* for tmp use */
8135
0
    wolfSSL_CertManagerFree(tmp->cm);
8136
0
    tmp->cm = cm;
8137
8138
0
    ret = wolfSSL_CTX_load_verify_locations(tmp, file, path);
8139
8140
    /* don't lose our good one */
8141
0
    tmp->cm = NULL;
8142
0
    wolfSSL_CTX_free(tmp);
8143
8144
0
    return ret;
8145
0
}
8146
8147
8148
#endif /* NO_FILESYSTEM */
8149
8150
#ifdef HAVE_CRL
8151
8152
/* check CRL if enabled, WOLFSSL_SUCCESS  */
8153
int wolfSSL_CertManagerCheckCRL(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
8154
{
8155
    int ret = 0;
8156
#ifdef WOLFSSL_SMALL_STACK
8157
    DecodedCert* cert = NULL;
8158
#else
8159
    DecodedCert  cert[1];
8160
#endif
8161
8162
    WOLFSSL_ENTER("wolfSSL_CertManagerCheckCRL");
8163
8164
    if (cm == NULL)
8165
        return BAD_FUNC_ARG;
8166
8167
    if (cm->crlEnabled == 0)
8168
        return WOLFSSL_SUCCESS;
8169
8170
#ifdef WOLFSSL_SMALL_STACK
8171
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
8172
    if (cert == NULL)
8173
        return MEMORY_E;
8174
#endif
8175
8176
    InitDecodedCert(cert, der, sz, NULL);
8177
8178
    if ((ret = ParseCertRelative(cert, CERT_TYPE, VERIFY_CRL, cm)) != 0) {
8179
        WOLFSSL_MSG("ParseCert failed");
8180
    }
8181
    else if ((ret = CheckCertCRL(cm->crl, cert)) != 0) {
8182
        WOLFSSL_MSG("CheckCertCRL failed");
8183
    }
8184
8185
    FreeDecodedCert(cert);
8186
#ifdef WOLFSSL_SMALL_STACK
8187
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
8188
#endif
8189
8190
    return ret == 0 ? WOLFSSL_SUCCESS : ret;
8191
}
8192
8193
8194
int wolfSSL_CertManagerSetCRL_Cb(WOLFSSL_CERT_MANAGER* cm, CbMissingCRL cb)
8195
{
8196
    WOLFSSL_ENTER("wolfSSL_CertManagerSetCRL_Cb");
8197
    if (cm == NULL)
8198
        return BAD_FUNC_ARG;
8199
8200
    cm->cbMissingCRL = cb;
8201
8202
    return WOLFSSL_SUCCESS;
8203
}
8204
8205
#ifdef HAVE_CRL_IO
8206
int wolfSSL_CertManagerSetCRL_IOCb(WOLFSSL_CERT_MANAGER* cm, CbCrlIO cb)
8207
{
8208
    if (cm == NULL)
8209
        return BAD_FUNC_ARG;
8210
8211
    cm->crl->crlIOCb = cb;
8212
8213
    return WOLFSSL_SUCCESS;
8214
}
8215
#endif
8216
8217
#ifndef NO_FILESYSTEM
8218
int wolfSSL_CertManagerLoadCRL(WOLFSSL_CERT_MANAGER* cm, const char* path,
8219
                              int type, int monitor)
8220
{
8221
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRL");
8222
    if (cm == NULL)
8223
        return BAD_FUNC_ARG;
8224
8225
    if (cm->crl == NULL) {
8226
        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
8227
            WOLFSSL_MSG("Enable CRL failed");
8228
            return WOLFSSL_FATAL_ERROR;
8229
        }
8230
    }
8231
8232
    return LoadCRL(cm->crl, path, type, monitor);
8233
}
8234
8235
int wolfSSL_CertManagerLoadCRLFile(WOLFSSL_CERT_MANAGER* cm, const char* file,
8236
                              int type)
8237
{
8238
    WOLFSSL_ENTER("wolfSSL_CertManagerLoadCRLFile");
8239
    if (cm == NULL || file == NULL)
8240
        return BAD_FUNC_ARG;
8241
8242
    if (cm->crl == NULL) {
8243
        if (wolfSSL_CertManagerEnableCRL(cm, 0) != WOLFSSL_SUCCESS) {
8244
            WOLFSSL_MSG("Enable CRL failed");
8245
            return WOLFSSL_FATAL_ERROR;
8246
        }
8247
    }
8248
8249
    return ProcessFile(NULL, file, type, CRL_TYPE, NULL, 0, cm->crl,
8250
            VERIFY);
8251
}
8252
#endif
8253
8254
int wolfSSL_EnableCRL(WOLFSSL* ssl, int options)
8255
{
8256
    WOLFSSL_ENTER("wolfSSL_EnableCRL");
8257
    if (ssl)
8258
        return wolfSSL_CertManagerEnableCRL(SSL_CM(ssl), options);
8259
    else
8260
        return BAD_FUNC_ARG;
8261
}
8262
8263
8264
int wolfSSL_DisableCRL(WOLFSSL* ssl)
8265
{
8266
    WOLFSSL_ENTER("wolfSSL_DisableCRL");
8267
    if (ssl)
8268
        return wolfSSL_CertManagerDisableCRL(SSL_CM(ssl));
8269
    else
8270
        return BAD_FUNC_ARG;
8271
}
8272
8273
#ifndef NO_FILESYSTEM
8274
int wolfSSL_LoadCRL(WOLFSSL* ssl, const char* path, int type, int monitor)
8275
{
8276
    WOLFSSL_ENTER("wolfSSL_LoadCRL");
8277
    if (ssl)
8278
        return wolfSSL_CertManagerLoadCRL(SSL_CM(ssl), path, type, monitor);
8279
    else
8280
        return BAD_FUNC_ARG;
8281
}
8282
8283
int wolfSSL_LoadCRLFile(WOLFSSL* ssl, const char* file, int type)
8284
{
8285
    WOLFSSL_ENTER("wolfSSL_LoadCRL");
8286
    if (ssl)
8287
        return wolfSSL_CertManagerLoadCRLFile(SSL_CM(ssl), file, type);
8288
    else
8289
        return BAD_FUNC_ARG;
8290
}
8291
#endif
8292
8293
8294
int wolfSSL_SetCRL_Cb(WOLFSSL* ssl, CbMissingCRL cb)
8295
{
8296
    WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
8297
    if (ssl)
8298
        return wolfSSL_CertManagerSetCRL_Cb(SSL_CM(ssl), cb);
8299
    else
8300
        return BAD_FUNC_ARG;
8301
}
8302
8303
#ifdef HAVE_CRL_IO
8304
int wolfSSL_SetCRL_IOCb(WOLFSSL* ssl, CbCrlIO cb)
8305
{
8306
    WOLFSSL_ENTER("wolfSSL_SetCRL_Cb");
8307
    if (ssl)
8308
        return wolfSSL_CertManagerSetCRL_IOCb(SSL_CM(ssl), cb);
8309
    else
8310
        return BAD_FUNC_ARG;
8311
}
8312
#endif
8313
8314
int wolfSSL_CTX_EnableCRL(WOLFSSL_CTX* ctx, int options)
8315
{
8316
    WOLFSSL_ENTER("wolfSSL_CTX_EnableCRL");
8317
    if (ctx)
8318
        return wolfSSL_CertManagerEnableCRL(ctx->cm, options);
8319
    else
8320
        return BAD_FUNC_ARG;
8321
}
8322
8323
8324
int wolfSSL_CTX_DisableCRL(WOLFSSL_CTX* ctx)
8325
{
8326
    WOLFSSL_ENTER("wolfSSL_CTX_DisableCRL");
8327
    if (ctx)
8328
        return wolfSSL_CertManagerDisableCRL(ctx->cm);
8329
    else
8330
        return BAD_FUNC_ARG;
8331
}
8332
8333
8334
#ifndef NO_FILESYSTEM
8335
int wolfSSL_CTX_LoadCRL(WOLFSSL_CTX* ctx, const char* path,
8336
                        int type, int monitor)
8337
{
8338
    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
8339
    if (ctx)
8340
        return wolfSSL_CertManagerLoadCRL(ctx->cm, path, type, monitor);
8341
    else
8342
        return BAD_FUNC_ARG;
8343
}
8344
8345
int wolfSSL_CTX_LoadCRLFile(WOLFSSL_CTX* ctx, const char* file,
8346
                        int type)
8347
{
8348
    WOLFSSL_ENTER("wolfSSL_CTX_LoadCRL");
8349
    if (ctx)
8350
        return wolfSSL_CertManagerLoadCRLFile(ctx->cm, file, type);
8351
    else
8352
        return BAD_FUNC_ARG;
8353
}
8354
#endif
8355
8356
8357
int wolfSSL_CTX_SetCRL_Cb(WOLFSSL_CTX* ctx, CbMissingCRL cb)
8358
{
8359
    WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_Cb");
8360
    if (ctx)
8361
        return wolfSSL_CertManagerSetCRL_Cb(ctx->cm, cb);
8362
    else
8363
        return BAD_FUNC_ARG;
8364
}
8365
8366
#ifdef HAVE_CRL_IO
8367
int wolfSSL_CTX_SetCRL_IOCb(WOLFSSL_CTX* ctx, CbCrlIO cb)
8368
{
8369
    WOLFSSL_ENTER("wolfSSL_CTX_SetCRL_IOCb");
8370
    if (ctx)
8371
        return wolfSSL_CertManagerSetCRL_IOCb(ctx->cm, cb);
8372
    else
8373
        return BAD_FUNC_ARG;
8374
}
8375
#endif
8376
8377
8378
#endif /* HAVE_CRL */
8379
8380
8381
#ifndef NO_FILESYSTEM
8382
8383
8384
#ifdef WOLFSSL_DER_LOAD
8385
8386
/* Add format parameter to allow DER load of CA files */
8387
int wolfSSL_CTX_der_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
8388
                                          int format)
8389
{
8390
    WOLFSSL_ENTER("wolfSSL_CTX_der_load_verify_locations");
8391
    if (ctx == NULL || file == NULL)
8392
        return WOLFSSL_FAILURE;
8393
8394
    if (ProcessFile(ctx, file, format, CA_TYPE, NULL, 0, NULL,
8395
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8396
        return WOLFSSL_SUCCESS;
8397
    }
8398
8399
    return WOLFSSL_FAILURE;
8400
}
8401
8402
#endif /* WOLFSSL_DER_LOAD */
8403
8404
8405
8406
WOLFSSL_ABI
8407
int wolfSSL_CTX_use_certificate_file(WOLFSSL_CTX* ctx, const char* file,
8408
                                     int format)
8409
0
{
8410
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_file");
8411
8412
0
    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0, NULL,
8413
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8414
0
        return WOLFSSL_SUCCESS;
8415
0
    }
8416
8417
0
    return WOLFSSL_FAILURE;
8418
0
}
8419
8420
8421
WOLFSSL_ABI
8422
int wolfSSL_CTX_use_PrivateKey_file(WOLFSSL_CTX* ctx, const char* file,
8423
                                    int format)
8424
0
{
8425
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_file");
8426
8427
0
    if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0, NULL,
8428
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8429
0
        return WOLFSSL_SUCCESS;
8430
0
    }
8431
8432
0
    return WOLFSSL_FAILURE;
8433
0
}
8434
8435
8436
#endif /* NO_FILESYSTEM */
8437
8438
8439
/* Sets the max chain depth when verifying a certificate chain. Default depth
8440
 * is set to MAX_CHAIN_DEPTH.
8441
 *
8442
 * ctx   WOLFSSL_CTX structure to set depth in
8443
 * depth max depth
8444
 */
8445
0
void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth) {
8446
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
8447
8448
0
    if (ctx == NULL || depth < 0 || depth > MAX_CHAIN_DEPTH) {
8449
0
        WOLFSSL_MSG("Bad depth argument, too large or less than 0");
8450
0
        return;
8451
0
    }
8452
8453
0
    ctx->verifyDepth = (byte)depth;
8454
0
}
8455
8456
8457
/* get cert chaining depth using ssl struct */
8458
long wolfSSL_get_verify_depth(WOLFSSL* ssl)
8459
0
{
8460
0
    if(ssl == NULL) {
8461
0
        return BAD_FUNC_ARG;
8462
0
    }
8463
#ifndef OPENSSL_EXTRA
8464
    return MAX_CHAIN_DEPTH;
8465
#else
8466
0
    return ssl->options.verifyDepth;
8467
0
#endif
8468
0
}
8469
8470
8471
/* get cert chaining depth using ctx struct */
8472
long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
8473
0
{
8474
0
    if (ctx == NULL) {
8475
0
        return BAD_FUNC_ARG;
8476
0
    }
8477
#ifndef OPENSSL_EXTRA
8478
    return MAX_CHAIN_DEPTH;
8479
#else
8480
0
    return ctx->verifyDepth;
8481
0
#endif
8482
0
}
8483
8484
8485
#ifndef NO_FILESYSTEM
8486
8487
8488
WOLFSSL_ABI
8489
int wolfSSL_CTX_use_certificate_chain_file(WOLFSSL_CTX* ctx, const char* file)
8490
0
{
8491
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
8492
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file");
8493
8494
0
    if (ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE, NULL, 1, NULL,
8495
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8496
0
        return WOLFSSL_SUCCESS;
8497
0
    }
8498
8499
0
   return WOLFSSL_FAILURE;
8500
0
}
8501
8502
8503
int wolfSSL_CTX_use_certificate_chain_file_format(WOLFSSL_CTX* ctx,
8504
                                                  const char* file, int format)
8505
0
{
8506
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
8507
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_file_format");
8508
8509
0
    if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 1, NULL,
8510
0
                    GET_VERIFY_SETTING_CTX(ctx)) == WOLFSSL_SUCCESS) {
8511
0
        return WOLFSSL_SUCCESS;
8512
0
    }
8513
8514
0
   return WOLFSSL_FAILURE;
8515
0
}
8516
8517
8518
#ifndef NO_DH
8519
8520
/* server Diffie-Hellman parameters */
8521
static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
8522
                                        const char* fname, int format)
8523
0
{
8524
0
#ifdef WOLFSSL_SMALL_STACK
8525
0
    byte   staticBuffer[1]; /* force heap usage */
8526
#else
8527
    byte   staticBuffer[FILE_BUFFER_SIZE];
8528
#endif
8529
0
    byte*  myBuffer = staticBuffer;
8530
0
    int    dynamic = 0;
8531
0
    int    ret;
8532
0
    long   sz = 0;
8533
0
    XFILE  file;
8534
8535
0
    if (ctx == NULL || fname == NULL)
8536
0
        return BAD_FUNC_ARG;
8537
8538
0
    file = XFOPEN(fname, "rb");
8539
0
    if (file == XBADFILE) return WOLFSSL_BAD_FILE;
8540
0
    if(XFSEEK(file, 0, XSEEK_END) != 0) {
8541
0
        XFCLOSE(file);
8542
0
        return WOLFSSL_BAD_FILE;
8543
0
    }
8544
0
    sz = XFTELL(file);
8545
0
    XREWIND(file);
8546
8547
0
    if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
8548
0
        WOLFSSL_MSG("SetTmpDH file size error");
8549
0
        XFCLOSE(file);
8550
0
        return WOLFSSL_BAD_FILE;
8551
0
    }
8552
8553
0
    if (sz > (long)sizeof(staticBuffer)) {
8554
0
        WOLFSSL_MSG("Getting dynamic buffer");
8555
0
        myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
8556
0
        if (myBuffer == NULL) {
8557
0
            XFCLOSE(file);
8558
0
            return WOLFSSL_BAD_FILE;
8559
0
        }
8560
0
        dynamic = 1;
8561
0
    }
8562
8563
0
    if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz)
8564
0
        ret = WOLFSSL_BAD_FILE;
8565
0
    else {
8566
0
        if (ssl)
8567
0
            ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format);
8568
0
        else
8569
0
            ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format);
8570
0
    }
8571
8572
0
    XFCLOSE(file);
8573
0
    if (dynamic)
8574
0
        XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
8575
8576
0
    return ret;
8577
0
}
8578
8579
/* server Diffie-Hellman parameters */
8580
int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format)
8581
0
{
8582
0
    if (ssl == NULL)
8583
0
        return BAD_FUNC_ARG;
8584
8585
0
    return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format);
8586
0
}
8587
8588
8589
/* server Diffie-Hellman parameters */
8590
int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format)
8591
0
{
8592
0
    return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format);
8593
0
}
8594
8595
#endif /* NO_DH */
8596
8597
#endif /* NO_FILESYSTEM */
8598
8599
#ifndef NO_CHECK_PRIVATE_KEY
8600
/* Check private against public in certificate for match
8601
 *
8602
 * Returns WOLFSSL_SUCCESS on good private key
8603
 *         WOLFSSL_FAILURE if mismatched */
8604
static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap,
8605
    int devId, int isKeyLabel, int isKeyId)
8606
0
{
8607
0
#ifdef WOLFSSL_SMALL_STACK
8608
0
    DecodedCert* der = NULL;
8609
#else
8610
    DecodedCert  der[1];
8611
#endif
8612
0
    word32 size;
8613
0
    byte*  buff;
8614
0
    int    ret = WOLFSSL_FAILURE;
8615
8616
0
    WOLFSSL_ENTER("check_cert_key");
8617
8618
0
    if (cert == NULL || key == NULL) {
8619
0
        return WOLFSSL_FAILURE;
8620
0
    }
8621
8622
0
#ifdef WOLFSSL_SMALL_STACK
8623
0
    der = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
8624
0
    if (der == NULL)
8625
0
        return MEMORY_E;
8626
0
#endif
8627
8628
0
    size = cert->length;
8629
0
    buff = cert->buffer;
8630
0
    InitDecodedCert(der, buff, size, heap);
8631
0
    if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL) != 0) {
8632
0
        FreeDecodedCert(der);
8633
0
    #ifdef WOLFSSL_SMALL_STACK
8634
0
        XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
8635
0
    #endif
8636
0
        return WOLFSSL_FAILURE;
8637
0
    }
8638
8639
0
    size = key->length;
8640
0
    buff = key->buffer;
8641
0
#ifdef WOLF_PRIVATE_KEY_ID
8642
0
    if (devId != INVALID_DEVID) {
8643
0
        int type = 0;
8644
0
        void *pkey = NULL;
8645
8646
0
    #ifndef NO_RSA
8647
0
        if (der->keyOID == RSAk) {
8648
0
            type = DYNAMIC_TYPE_RSA;
8649
0
        }
8650
0
    #ifdef WC_RSA_PSS
8651
0
        if (der->keyOID == RSAPSSk) {
8652
0
            type = DYNAMIC_TYPE_RSA;
8653
0
        }
8654
0
    #endif
8655
0
    #endif
8656
0
    #ifdef HAVE_ECC
8657
0
        if (der->keyOID == ECDSAk) {
8658
0
            type = DYNAMIC_TYPE_ECC;
8659
0
        }
8660
0
    #endif
8661
8662
0
        ret = CreateDevPrivateKey(&pkey, buff, size, type,
8663
0
                                  isKeyLabel, isKeyId, heap, devId);
8664
0
        #ifdef WOLF_CRYPTO_CB
8665
0
        if (ret == 0) {
8666
0
            #ifndef NO_RSA
8667
0
            if (der->keyOID == RSAk
8668
0
            #ifdef WC_RSA_PSS
8669
0
                || der->keyOID == RSAPSSk
8670
0
            #endif
8671
0
                ) {
8672
0
                ret = wc_CryptoCb_RsaCheckPrivKey((RsaKey*)pkey,
8673
0
                                               der->publicKey, der->pubKeySize);
8674
0
            }
8675
0
            #endif
8676
0
            #ifdef HAVE_ECC
8677
0
            if (der->keyOID == ECDSAk) {
8678
0
                ret = wc_CryptoCb_EccCheckPrivKey((ecc_key*)pkey,
8679
0
                                               der->publicKey, der->pubKeySize);
8680
0
            }
8681
0
            #endif
8682
0
        }
8683
        #else
8684
            /* devId was set, don't check, for now */
8685
            /* TODO: Add callback for private key check? */
8686
        #endif
8687
0
        if (pkey != NULL) {
8688
0
        #ifndef NO_RSA
8689
0
            if (der->keyOID == RSAk
8690
0
            #ifdef WC_RSA_PSS
8691
0
                || der->keyOID == RSAPSSk
8692
0
            #endif
8693
0
                ) {
8694
0
                wc_FreeRsaKey((RsaKey*)pkey);
8695
0
            }
8696
0
        #endif
8697
0
        #ifdef HAVE_ECC
8698
0
            if (der->keyOID == ECDSAk) {
8699
0
                wc_ecc_free((ecc_key*)pkey);
8700
0
            }
8701
0
        #endif
8702
0
            XFREE(pkey, heap, type);
8703
0
        }
8704
0
        if (ret != CRYPTOCB_UNAVAILABLE) {
8705
0
            ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
8706
0
        }
8707
0
    }
8708
0
    else {
8709
        /* fall through if unavailable */
8710
0
        ret = CRYPTOCB_UNAVAILABLE;
8711
0
    }
8712
8713
0
    if (ret == CRYPTOCB_UNAVAILABLE)
8714
0
#endif /* WOLF_PRIVATE_KEY_ID */
8715
0
    {
8716
0
        ret = wc_CheckPrivateKeyCert(buff, size, der);
8717
0
        ret = (ret == 1) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
8718
0
    }
8719
0
    FreeDecodedCert(der);
8720
0
#ifdef WOLFSSL_SMALL_STACK
8721
0
    XFREE(der, NULL, DYNAMIC_TYPE_DCERT);
8722
0
#endif
8723
8724
0
    (void)devId;
8725
0
    (void)isKeyLabel;
8726
0
    (void)isKeyId;
8727
8728
0
    return ret;
8729
0
}
8730
8731
/* Check private against public in certificate for match
8732
 *
8733
 * ctx  WOLFSSL_CTX structure to check private key in
8734
 *
8735
 * Returns WOLFSSL_SUCCESS on good private key
8736
 *         WOLFSSL_FAILURE if mismatched. */
8737
int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
8738
0
{
8739
0
    if (ctx == NULL) {
8740
0
        return WOLFSSL_FAILURE;
8741
0
    }
8742
0
    return check_cert_key(ctx->certificate, ctx->privateKey, ctx->heap,
8743
0
        ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId);
8744
0
}
8745
#endif /* !NO_CHECK_PRIVATE_KEY */
8746
8747
#ifdef OPENSSL_ALL
8748
/**
8749
 * Return the private key of the WOLFSSL_CTX struct
8750
 * @return WOLFSSL_EVP_PKEY* The caller doesn *NOT*` free the returned object.
8751
 */
8752
WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
8753
0
{
8754
0
    const unsigned char *key;
8755
0
    int type;
8756
8757
0
    WOLFSSL_ENTER("wolfSSL_CTX_get0_privatekey");
8758
8759
0
    if (ctx == NULL || ctx->privateKey == NULL ||
8760
0
            ctx->privateKey->buffer == NULL) {
8761
0
        WOLFSSL_MSG("Bad parameter or key not set");
8762
0
        return NULL;
8763
0
    }
8764
8765
0
    switch (ctx->privateKeyType) {
8766
0
#ifndef NO_RSA
8767
0
        case rsa_sa_algo:
8768
0
            type = EVP_PKEY_RSA;
8769
0
            break;
8770
0
#endif
8771
0
#ifdef HAVE_ECC
8772
0
        case ecc_dsa_sa_algo:
8773
0
            type = EVP_PKEY_EC;
8774
0
            break;
8775
0
#endif
8776
0
        default:
8777
            /* Other key types not supported either as ssl private keys
8778
             * or in the EVP layer */
8779
0
            WOLFSSL_MSG("Unsupported key type");
8780
0
            return NULL;
8781
0
    }
8782
8783
0
    key = ctx->privateKey->buffer;
8784
8785
0
    if (ctx->privateKeyPKey != NULL)
8786
0
        return ctx->privateKeyPKey;
8787
0
    else
8788
0
        return wolfSSL_d2i_PrivateKey(type,
8789
0
                (WOLFSSL_EVP_PKEY**)&ctx->privateKeyPKey, &key,
8790
0
                (long)ctx->privateKey->length);
8791
0
}
8792
#endif
8793
8794
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
8795
8796
static WOLFSSL_EVP_PKEY* d2iGenericKey(WOLFSSL_EVP_PKEY** out,
8797
                                 const unsigned char** in, long inSz, int priv)
8798
0
{
8799
8800
0
    WOLFSSL_EVP_PKEY* pkey = NULL;
8801
0
    const unsigned char* mem;
8802
0
    long memSz = inSz;
8803
8804
0
    WOLFSSL_ENTER("d2iGenericKey");
8805
8806
0
    if (in == NULL || *in == NULL || inSz < 0) {
8807
0
        WOLFSSL_MSG("Bad argument");
8808
0
        return NULL;
8809
0
    }
8810
0
    mem = *in;
8811
8812
0
    #if !defined(NO_RSA)
8813
0
    {
8814
0
        word32 keyIdx = 0;
8815
0
        int isRsaKey;
8816
0
    #ifdef WOLFSSL_SMALL_STACK
8817
0
        RsaKey *rsa = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA);
8818
0
        if (rsa == NULL)
8819
0
            return NULL;
8820
    #else
8821
        RsaKey rsa[1];
8822
    #endif
8823
0
        XMEMSET(rsa, 0, sizeof(RsaKey));
8824
8825
        /* test if RSA key */
8826
0
        if (priv)
8827
0
            isRsaKey = wc_InitRsaKey(rsa, NULL) == 0 &&
8828
0
                wc_RsaPrivateKeyDecode(mem, &keyIdx, rsa, (word32)memSz) == 0;
8829
0
        else
8830
0
            isRsaKey = wc_InitRsaKey(rsa, NULL) == 0 &&
8831
0
                wc_RsaPublicKeyDecode(mem, &keyIdx, rsa, (word32)memSz) == 0;
8832
0
        wc_FreeRsaKey(rsa);
8833
0
    #ifdef WOLFSSL_SMALL_STACK
8834
0
        XFREE(rsa, NULL, DYNAMIC_TYPE_RSA);
8835
0
    #endif
8836
8837
0
        if (isRsaKey) {
8838
0
            pkey = wolfSSL_EVP_PKEY_new();
8839
0
            if (pkey != NULL) {
8840
0
                pkey->pkey_sz = keyIdx;
8841
0
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
8842
0
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8843
0
                               DYNAMIC_TYPE_PUBLIC_KEY);
8844
0
                if (pkey->pkey.ptr == NULL) {
8845
0
                    wolfSSL_EVP_PKEY_free(pkey);
8846
0
                    return NULL;
8847
0
                }
8848
0
                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
8849
0
                pkey->type = EVP_PKEY_RSA;
8850
0
                if (out != NULL) {
8851
0
                    *out = pkey;
8852
0
                }
8853
8854
0
                pkey->ownRsa = 1;
8855
0
                pkey->rsa = wolfSSL_RSA_new();
8856
0
                if (pkey->rsa == NULL) {
8857
0
                    wolfSSL_EVP_PKEY_free(pkey);
8858
0
                    return NULL;
8859
0
                }
8860
8861
0
                if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
8862
0
                        (const unsigned char*)pkey->pkey.ptr,
8863
0
                        pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
8864
0
                                            : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
8865
0
                    wolfSSL_EVP_PKEY_free(pkey);
8866
0
                    return NULL;
8867
0
                }
8868
8869
0
                return pkey;
8870
0
            }
8871
0
            else {
8872
0
                WOLFSSL_MSG("RSA wolfSSL_EVP_PKEY_new error");
8873
0
            }
8874
0
        }
8875
0
    }
8876
0
    #endif /* NO_RSA */
8877
8878
0
    #if defined(HAVE_ECC) && defined(OPENSSL_EXTRA)
8879
0
    {
8880
0
        word32  keyIdx = 0;
8881
0
        int     isEccKey;
8882
0
    #ifdef WOLFSSL_SMALL_STACK
8883
0
        ecc_key *ecc = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, DYNAMIC_TYPE_ECC);
8884
0
        if (ecc == NULL)
8885
0
            return NULL;
8886
    #else
8887
        ecc_key ecc[1];
8888
    #endif
8889
0
        XMEMSET(ecc, 0, sizeof(ecc_key));
8890
8891
0
        if (priv)
8892
0
            isEccKey = wc_ecc_init(ecc) == 0 &&
8893
0
                wc_EccPrivateKeyDecode(mem, &keyIdx, ecc, (word32)memSz) == 0;
8894
0
        else
8895
0
            isEccKey = wc_ecc_init(ecc) == 0 &&
8896
0
                wc_EccPublicKeyDecode(mem, &keyIdx, ecc, (word32)memSz) == 0;
8897
0
        wc_ecc_free(ecc);
8898
0
    #ifdef WOLFSSL_SMALL_STACK
8899
0
        XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
8900
0
    #endif
8901
8902
0
        if (isEccKey) {
8903
0
            pkey = wolfSSL_EVP_PKEY_new();
8904
0
            if (pkey != NULL) {
8905
0
                pkey->pkey_sz = keyIdx;
8906
0
                pkey->pkey.ptr = (char*)XMALLOC(keyIdx, NULL,
8907
0
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8908
0
                               DYNAMIC_TYPE_PUBLIC_KEY);
8909
0
                if (pkey->pkey.ptr == NULL) {
8910
0
                    wolfSSL_EVP_PKEY_free(pkey);
8911
0
                    return NULL;
8912
0
                }
8913
0
                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
8914
0
                pkey->type = EVP_PKEY_EC;
8915
0
                if (out != NULL) {
8916
0
                    *out = pkey;
8917
0
                }
8918
8919
0
                pkey->ownEcc = 1;
8920
0
                pkey->ecc = wolfSSL_EC_KEY_new();
8921
0
                if (pkey->ecc == NULL) {
8922
0
                    wolfSSL_EVP_PKEY_free(pkey);
8923
0
                    return NULL;
8924
0
                }
8925
8926
0
                if (wolfSSL_EC_KEY_LoadDer_ex(pkey->ecc,
8927
0
                        (const unsigned char*)pkey->pkey.ptr,
8928
0
                        pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
8929
0
                                            : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
8930
0
                    wolfSSL_EVP_PKEY_free(pkey);
8931
0
                    return NULL;
8932
0
                }
8933
8934
0
                return pkey;
8935
0
            }
8936
0
            else {
8937
0
                WOLFSSL_MSG("ECC wolfSSL_EVP_PKEY_new error");
8938
0
            }
8939
0
        }
8940
0
    }
8941
0
    #endif /* HAVE_ECC && OPENSSL_EXTRA */
8942
8943
    #if !defined(NO_DSA)
8944
    {
8945
        word32 keyIdx = 0;
8946
        int     isDsaKey;
8947
    #ifdef WOLFSSL_SMALL_STACK
8948
        DsaKey *dsa = (DsaKey*)XMALLOC(sizeof(DsaKey), NULL, DYNAMIC_TYPE_DSA);
8949
        if (dsa == NULL)
8950
            return NULL;
8951
    #else
8952
        DsaKey dsa[1];
8953
    #endif
8954
        XMEMSET(dsa, 0, sizeof(DsaKey));
8955
8956
        if (priv)
8957
            isDsaKey = wc_InitDsaKey(dsa) == 0 &&
8958
                wc_DsaPrivateKeyDecode(mem, &keyIdx, dsa, (word32)memSz) == 0;
8959
        else
8960
            isDsaKey = wc_InitDsaKey(dsa) == 0 &&
8961
                wc_DsaPublicKeyDecode(mem, &keyIdx, dsa, (word32)memSz) == 0;
8962
        wc_FreeDsaKey(dsa);
8963
    #ifdef WOLFSSL_SMALL_STACK
8964
        XFREE(dsa, NULL, DYNAMIC_TYPE_DSA);
8965
    #endif
8966
8967
        /* test if DSA key */
8968
        if (isDsaKey) {
8969
            pkey = wolfSSL_EVP_PKEY_new();
8970
8971
            if (pkey != NULL) {
8972
                pkey->pkey_sz = keyIdx;
8973
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
8974
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
8975
                               DYNAMIC_TYPE_PUBLIC_KEY);
8976
                if (pkey->pkey.ptr == NULL) {
8977
                    wolfSSL_EVP_PKEY_free(pkey);
8978
                    return NULL;
8979
                }
8980
                XMEMCPY(pkey->pkey.ptr, mem, keyIdx);
8981
                pkey->type = EVP_PKEY_DSA;
8982
                if (out != NULL) {
8983
                    *out = pkey;
8984
                }
8985
8986
                pkey->ownDsa = 1;
8987
                pkey->dsa = wolfSSL_DSA_new();
8988
                if (pkey->dsa == NULL) {
8989
                    wolfSSL_EVP_PKEY_free(pkey);
8990
                    return NULL;
8991
                }
8992
8993
                if (wolfSSL_DSA_LoadDer_ex(pkey->dsa,
8994
                        (const unsigned char*)pkey->pkey.ptr,
8995
                        pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
8996
                                            : WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
8997
                    wolfSSL_EVP_PKEY_free(pkey);
8998
                    return NULL;
8999
                }
9000
9001
                return pkey;
9002
            }
9003
            else {
9004
                WOLFSSL_MSG("DSA wolfSSL_EVP_PKEY_new error");
9005
            }
9006
        }
9007
    }
9008
    #endif /* NO_DSA */
9009
9010
0
    #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
9011
0
    #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
9012
0
        (HAVE_FIPS_VERSION > 2))
9013
0
    {
9014
0
        int isDhKey;
9015
0
        word32 keyIdx = 0;
9016
0
    #ifdef WOLFSSL_SMALL_STACK
9017
0
        DhKey *dh = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
9018
0
        if (dh == NULL)
9019
0
            return NULL;
9020
    #else
9021
        DhKey dh[1];
9022
    #endif
9023
0
        XMEMSET(dh, 0, sizeof(DhKey));
9024
9025
0
        isDhKey = wc_InitDhKey(dh) == 0 &&
9026
0
                  wc_DhKeyDecode(mem, &keyIdx, dh, (word32)memSz) == 0;
9027
0
        wc_FreeDhKey(dh);
9028
0
    #ifdef WOLFSSL_SMALL_STACK
9029
0
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
9030
0
    #endif
9031
9032
        /* test if DH key */
9033
0
        if (isDhKey) {
9034
0
            pkey = wolfSSL_EVP_PKEY_new();
9035
9036
0
            if (pkey != NULL) {
9037
0
                pkey->pkey_sz = (int)memSz;
9038
0
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
9039
0
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
9040
0
                               DYNAMIC_TYPE_PUBLIC_KEY);
9041
0
                if (pkey->pkey.ptr == NULL) {
9042
0
                    wolfSSL_EVP_PKEY_free(pkey);
9043
0
                    return NULL;
9044
0
                }
9045
0
                XMEMCPY(pkey->pkey.ptr, mem, memSz);
9046
0
                pkey->type = EVP_PKEY_DH;
9047
0
                if (out != NULL) {
9048
0
                    *out = pkey;
9049
0
                }
9050
9051
0
                pkey->ownDh = 1;
9052
0
                pkey->dh = wolfSSL_DH_new();
9053
0
                if (pkey->dh == NULL) {
9054
0
                    wolfSSL_EVP_PKEY_free(pkey);
9055
0
                    return NULL;
9056
0
                }
9057
9058
0
                if (wolfSSL_DH_LoadDer(pkey->dh,
9059
0
                            (const unsigned char*)pkey->pkey.ptr,
9060
0
                            pkey->pkey_sz) != WOLFSSL_SUCCESS) {
9061
0
                    wolfSSL_EVP_PKEY_free(pkey);
9062
0
                    return NULL;
9063
0
                }
9064
9065
0
                return pkey;
9066
0
            }
9067
0
            else {
9068
0
                WOLFSSL_MSG("DH wolfSSL_EVP_PKEY_new error");
9069
0
            }
9070
0
        }
9071
0
    }
9072
0
    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9073
0
    #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
9074
9075
0
    #if !defined(NO_DH) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA)
9076
0
    #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
9077
0
            (HAVE_FIPS_VERSION > 2))
9078
0
    {
9079
0
        word32  keyIdx = 0;
9080
0
        DhKey*  key = NULL;
9081
0
        int ret;
9082
0
        int elements;
9083
0
    #ifdef WOLFSSL_SMALL_STACK
9084
0
        DhKey* dh = (DhKey*)XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_DH);
9085
0
        if (dh == NULL)
9086
0
            return NULL;
9087
    #else
9088
        DhKey  dh[1];
9089
    #endif
9090
0
        XMEMSET(dh, 0, sizeof(DhKey));
9091
9092
        /* test if DH-public key */
9093
0
        if (wc_InitDhKey(dh) != 0)
9094
0
            return NULL;
9095
9096
0
        ret = wc_DhKeyDecode(mem, &keyIdx, dh, (word32)memSz);
9097
0
        wc_FreeDhKey(dh);
9098
0
    #ifdef WOLFSSL_SMALL_STACK
9099
0
        XFREE(dh, NULL, DYNAMIC_TYPE_DH);
9100
0
    #endif
9101
9102
0
        if (ret == 0) {
9103
0
            pkey = wolfSSL_EVP_PKEY_new();
9104
0
            if (pkey != NULL) {
9105
0
                pkey->type     = EVP_PKEY_DH;
9106
0
                pkey->pkey_sz  = (int)memSz;
9107
0
                pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL,
9108
0
                        priv ? DYNAMIC_TYPE_PRIVATE_KEY :
9109
0
                               DYNAMIC_TYPE_PUBLIC_KEY);
9110
0
                if (pkey->pkey.ptr == NULL) {
9111
0
                    wolfSSL_EVP_PKEY_free(pkey);
9112
0
                    return NULL;
9113
0
                }
9114
0
                XMEMCPY(pkey->pkey.ptr, mem, memSz);
9115
0
                if (out != NULL) {
9116
0
                    *out = pkey;
9117
0
                }
9118
0
                pkey->ownDh = 1;
9119
0
                pkey->dh = wolfSSL_DH_new();
9120
0
                if (pkey->dh == NULL) {
9121
0
                    wolfSSL_EVP_PKEY_free(pkey);
9122
0
                    return NULL;
9123
0
                }
9124
9125
0
                key = (DhKey*)pkey->dh->internal;
9126
9127
0
                keyIdx = 0;
9128
0
                if (wc_DhKeyDecode(mem, &keyIdx, key, (word32)memSz) == 0)
9129
0
                {
9130
0
                    elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q | ELEMENT_PUB;
9131
0
                    if (priv)
9132
0
                        elements |= ELEMENT_PRV;
9133
0
                    if(SetDhExternal_ex(pkey->dh, elements)
9134
0
                            == WOLFSSL_SUCCESS ) {
9135
0
                        return pkey;
9136
0
                    }
9137
0
                }
9138
0
                else {
9139
0
                    wolfSSL_EVP_PKEY_free(pkey);
9140
0
                    return NULL;
9141
0
                }
9142
0
            }
9143
0
        }
9144
0
    }
9145
0
    #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9146
0
    #endif /* !NO_DH &&  OPENSSL_EXTRA && WOLFSSL_DH_EXTRA */
9147
9148
    #ifdef HAVE_PQC
9149
    #ifdef HAVE_FALCON
9150
    {
9151
        int isFalcon = 0;
9152
    #ifdef WOLFSSL_SMALL_STACK
9153
        falcon_key *falcon = (falcon_key *)XMALLOC(sizeof(falcon_key), NULL,
9154
                                                  DYNAMIC_TYPE_FALCON);
9155
        if (falcon == NULL) {
9156
            return NULL;
9157
        }
9158
    #else
9159
        falcon_key falcon[1];
9160
    #endif
9161
9162
        if (wc_falcon_init(falcon) == 0) {
9163
            /* test if Falcon key */
9164
            if (priv) {
9165
                /* Try level 1 */
9166
                isFalcon = wc_falcon_set_level(falcon, 1) == 0 &&
9167
                           wc_falcon_import_private_only(mem, (word32)memSz,
9168
                                                         falcon) == 0;
9169
                if (!isFalcon) {
9170
                    /* Try level 5 */
9171
                    isFalcon = wc_falcon_set_level(falcon, 5) == 0 &&
9172
                               wc_falcon_import_private_only(mem, (word32)memSz,
9173
                                                             falcon) == 0;
9174
                }
9175
            } else {
9176
                /* Try level 1 */
9177
                isFalcon = wc_falcon_set_level(falcon, 1) == 0 &&
9178
                           wc_falcon_import_public(mem, (word32)memSz, falcon)
9179
                           == 0;
9180
9181
                if (!isFalcon) {
9182
                    /* Try level 5 */
9183
                    isFalcon = wc_falcon_set_level(falcon, 5) == 0 &&
9184
                               wc_falcon_import_public(mem, (word32)memSz,
9185
                                                       falcon) == 0;
9186
                }
9187
            }
9188
            wc_falcon_free(falcon);
9189
        }
9190
9191
    #ifdef WOLFSSL_SMALL_STACK
9192
        XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON);
9193
    #endif
9194
        if (isFalcon) {
9195
            /* Create a fake Falcon EVP_PKEY. In the future, we might integrate
9196
             * Falcon into the compatibility layer. */
9197
            pkey = wolfSSL_EVP_PKEY_new();
9198
            if (pkey == NULL) {
9199
                WOLFSSL_MSG("Falcon wolfSSL_EVP_PKEY_new error");
9200
                return NULL;
9201
            }
9202
            pkey->type = EVP_PKEY_FALCON;
9203
            pkey->pkey.ptr = NULL;
9204
            pkey->pkey_sz = 0;
9205
            return pkey;
9206
        }
9207
9208
    }
9209
    #endif /* HAVE_FALCON */
9210
    #ifdef HAVE_DILITHIUM
9211
    {
9212
        int isDilithium = 0;
9213
    #ifdef WOLFSSL_SMALL_STACK
9214
        dilithium_key *dilithium = (dilithium_key *)
9215
            XMALLOC(sizeof(dilithium_key), NULL, DYNAMIC_TYPE_DILITHIUM);
9216
        if (dilithium == NULL) {
9217
            return NULL;
9218
        }
9219
    #else
9220
        dilithium_key dilithium[1];
9221
    #endif
9222
9223
        if (wc_dilithium_init(dilithium) == 0) {
9224
            /* Test if Dilithium key. Try all levels for both SHAKE and AES */
9225
            if (priv) {
9226
                isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9227
                                  SHAKE_VARIANT) == 0 &&
9228
                              wc_dilithium_import_private_only(mem,
9229
                                  (word32)memSz, dilithium) == 0;
9230
                if (!isDilithium) {
9231
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9232
                                      SHAKE_VARIANT) == 0 &&
9233
                                  wc_dilithium_import_private_only(mem,
9234
                                      (word32)memSz, dilithium) == 0;
9235
                }
9236
                if (!isDilithium) {
9237
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9238
                                      SHAKE_VARIANT) == 0 &&
9239
                                  wc_dilithium_import_private_only(mem,
9240
                                      (word32)memSz, dilithium) == 0;
9241
                }
9242
                if (!isDilithium) {
9243
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9244
                                      AES_VARIANT) == 0 &&
9245
                                  wc_dilithium_import_private_only(mem,
9246
                                      (word32)memSz, dilithium) == 0;
9247
                }
9248
                if (!isDilithium) {
9249
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9250
                                      AES_VARIANT) == 0 &&
9251
                                  wc_dilithium_import_private_only(mem,
9252
                                      (word32)memSz, dilithium) == 0;
9253
                }
9254
                if (!isDilithium) {
9255
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9256
                                      AES_VARIANT) == 0 &&
9257
                                  wc_dilithium_import_private_only(mem,
9258
                                      (word32)memSz, dilithium) == 0;
9259
                }
9260
            } else {
9261
                isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9262
                                  SHAKE_VARIANT) == 0 &&
9263
                              wc_dilithium_import_public(mem, (word32)memSz,
9264
                                  dilithium) == 0;
9265
                if (!isDilithium) {
9266
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9267
                                      SHAKE_VARIANT) == 0 &&
9268
                                  wc_dilithium_import_public(mem, (word32)memSz,
9269
                                      dilithium) == 0;
9270
                }
9271
                if (!isDilithium) {
9272
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9273
                                      SHAKE_VARIANT) == 0 &&
9274
                                  wc_dilithium_import_public(mem, (word32)memSz,
9275
                                      dilithium) == 0;
9276
                }
9277
                if (!isDilithium) {
9278
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 2,
9279
                                      AES_VARIANT) == 0 &&
9280
                                  wc_dilithium_import_public(mem, (word32)memSz,
9281
                                      dilithium) == 0;
9282
                }
9283
                if (!isDilithium) {
9284
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 3,
9285
                                      AES_VARIANT) == 0 &&
9286
                                  wc_dilithium_import_public(mem, (word32)memSz,
9287
                                      dilithium) == 0;
9288
                }
9289
                if (!isDilithium) {
9290
                    isDilithium = wc_dilithium_set_level_and_sym(dilithium, 5,
9291
                                      AES_VARIANT) == 0 &&
9292
                                  wc_dilithium_import_public(mem, (word32)memSz,
9293
                                      dilithium) == 0;
9294
                }
9295
            }
9296
            wc_dilithium_free(dilithium);
9297
        }
9298
9299
    #ifdef WOLFSSL_SMALL_STACK
9300
        XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM);
9301
    #endif
9302
        if (isDilithium) {
9303
            /* Create a fake Dilithium EVP_PKEY. In the future, we might
9304
             * integrate Dilithium into the compatibility layer. */
9305
            pkey = wolfSSL_EVP_PKEY_new();
9306
            if (pkey == NULL) {
9307
                WOLFSSL_MSG("Dilithium wolfSSL_EVP_PKEY_new error");
9308
                return NULL;
9309
            }
9310
            pkey->type = EVP_PKEY_DILITHIUM;
9311
            pkey->pkey.ptr = NULL;
9312
            pkey->pkey_sz = 0;
9313
            return pkey;
9314
        }
9315
9316
    }
9317
    #endif /* HAVE_DILITHIUM */
9318
    #endif /* HAVE_PQC */
9319
9320
0
    if (pkey == NULL) {
9321
0
        WOLFSSL_MSG("wolfSSL_d2i_PUBKEY couldn't determine key type");
9322
0
    }
9323
9324
0
    return pkey;
9325
9326
0
}
9327
#endif /* OPENSSL_EXTRA || WPA_SMALL */
9328
9329
#ifdef OPENSSL_EXTRA
9330
9331
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
9332
    WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey, const unsigned char** keyBuf, long keyLen)
9333
0
{
9334
0
    WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
9335
0
#ifdef WOLFSSL_PEM_TO_DER
9336
0
    int ret;
9337
0
    DerBuffer* der = NULL;
9338
9339
0
    if (keyBuf == NULL || *keyBuf == NULL || keyLen <= 0) {
9340
0
        WOLFSSL_MSG("Bad key PEM/DER args");
9341
0
        return NULL;
9342
0
    }
9343
9344
0
    ret = PemToDer(*keyBuf, keyLen, PRIVATEKEY_TYPE, &der, NULL, NULL, NULL);
9345
0
    if (ret < 0) {
9346
0
        WOLFSSL_MSG("Not PEM format");
9347
0
        ret = AllocDer(&der, (word32)keyLen, PRIVATEKEY_TYPE, NULL);
9348
0
        if (ret == 0) {
9349
0
            XMEMCPY(der->buffer, *keyBuf, keyLen);
9350
0
        }
9351
0
    }
9352
9353
0
    if (ret == 0) {
9354
        /* Verify this is PKCS8 Key */
9355
0
        word32 inOutIdx = 0;
9356
0
        word32 algId;
9357
0
        ret = ToTraditionalInline_ex(der->buffer, &inOutIdx, der->length, &algId);
9358
0
        if (ret >= 0) {
9359
0
            ret = 0; /* good DER */
9360
0
        }
9361
0
    }
9362
9363
0
    if (ret == 0) {
9364
0
        pkcs8 = wolfSSL_EVP_PKEY_new();
9365
0
        if (pkcs8 == NULL)
9366
0
            ret = MEMORY_E;
9367
0
    }
9368
0
    if (ret == 0) {
9369
0
        pkcs8->pkey.ptr = (char*)XMALLOC(der->length, NULL,
9370
0
            DYNAMIC_TYPE_PUBLIC_KEY);
9371
0
        if (pkcs8->pkey.ptr == NULL)
9372
0
            ret = MEMORY_E;
9373
0
    }
9374
0
    if (ret == 0) {
9375
0
        XMEMCPY(pkcs8->pkey.ptr, der->buffer, der->length);
9376
0
        pkcs8->pkey_sz = der->length;
9377
0
    }
9378
9379
0
    FreeDer(&der);
9380
0
    if (ret != 0) {
9381
0
        wolfSSL_EVP_PKEY_free(pkcs8);
9382
0
        pkcs8 = NULL;
9383
0
    }
9384
0
    if (pkey != NULL) {
9385
0
        *pkey = pkcs8;
9386
0
    }
9387
9388
#else
9389
    (void)bio;
9390
    (void)pkey;
9391
#endif /* WOLFSSL_PEM_TO_DER */
9392
9393
0
    return pkcs8;
9394
0
}
9395
9396
9397
#ifndef NO_BIO
9398
/* put SSL type in extra for now, not very common */
9399
9400
/* Converts a DER format key read from "bio" to a PKCS8 structure.
9401
 *
9402
 * bio  input bio to read DER from
9403
 * pkey If not NULL then this pointer will be overwritten with a new PKCS8
9404
 *      structure.
9405
 *
9406
 * returns a WOLFSSL_PKCS8_PRIV_KEY_INFO pointer on success and NULL in fail
9407
 *         case.
9408
 */
9409
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY_bio(WOLFSSL_BIO* bio,
9410
        WOLFSSL_PKCS8_PRIV_KEY_INFO** pkey)
9411
0
{
9412
0
    WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
9413
0
#ifdef WOLFSSL_PEM_TO_DER
9414
0
    unsigned char* mem = NULL;
9415
0
    int memSz;
9416
9417
0
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS8_PKEY_bio");
9418
9419
0
    if (bio == NULL) {
9420
0
        return NULL;
9421
0
    }
9422
9423
0
    if ((memSz = wolfSSL_BIO_get_mem_data(bio, &mem)) < 0) {
9424
0
        return NULL;
9425
0
    }
9426
9427
0
    pkcs8 = wolfSSL_d2i_PKCS8_PKEY(pkey, (const unsigned char**)&mem, memSz);
9428
#else
9429
    (void)bio;
9430
    (void)pkey;
9431
#endif /* WOLFSSL_PEM_TO_DER */
9432
9433
0
    return pkcs8;
9434
0
}
9435
9436
9437
/* expecting DER format public key
9438
 *
9439
 * bio  input bio to read DER from
9440
 * out  If not NULL then this pointer will be overwritten with a new
9441
 * WOLFSSL_EVP_PKEY pointer
9442
 *
9443
 * returns a WOLFSSL_EVP_PKEY pointer on success and NULL in fail case.
9444
 */
9445
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio,
9446
                                         WOLFSSL_EVP_PKEY** out)
9447
0
{
9448
0
    unsigned char* mem;
9449
0
    long memSz;
9450
0
    WOLFSSL_EVP_PKEY* pkey = NULL;
9451
9452
0
    WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY_bio()");
9453
9454
0
    if (bio == NULL) {
9455
0
        return NULL;
9456
0
    }
9457
0
    (void)out;
9458
9459
0
    memSz = wolfSSL_BIO_get_len(bio);
9460
0
    if (memSz <= 0) {
9461
0
        return NULL;
9462
0
    }
9463
9464
0
    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
9465
0
    if (mem == NULL) {
9466
0
        return NULL;
9467
0
    }
9468
9469
0
    if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
9470
0
        pkey = wolfSSL_d2i_PUBKEY(NULL, (const unsigned char**)&mem, memSz);
9471
0
        if (out != NULL && pkey != NULL) {
9472
0
            *out = pkey;
9473
0
        }
9474
0
    }
9475
9476
0
    XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
9477
0
    return pkey;
9478
0
}
9479
9480
#endif /* !NO_BIO */
9481
9482
9483
/* Converts a DER encoded public key to a WOLFSSL_EVP_PKEY structure.
9484
 *
9485
 * out  pointer to new WOLFSSL_EVP_PKEY structure. Can be NULL
9486
 * in   DER buffer to convert
9487
 * inSz size of in buffer
9488
 *
9489
 * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
9490
 *         on fail
9491
 */
9492
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out,
9493
                                     const unsigned char** in, long inSz)
9494
0
{
9495
0
    WOLFSSL_ENTER("wolfSSL_d2i_PUBKEY");
9496
0
    return d2iGenericKey(out, in, inSz, 0);
9497
0
}
9498
9499
/* helper function to get raw pointer to DER buffer from WOLFSSL_EVP_PKEY */
9500
static int wolfSSL_EVP_PKEY_get_der(const WOLFSSL_EVP_PKEY* key, unsigned char** der)
9501
0
{
9502
0
    unsigned char* pt;
9503
0
    int sz;
9504
0
    word16 pkcs8HeaderSz;
9505
9506
0
    if (!key || !key->pkey_sz)
9507
0
        return WOLFSSL_FATAL_ERROR;
9508
9509
    /* return the key without PKCS8 for compatibility */
9510
    /* if pkcs8HeaderSz is invalid, use 0 and return all of pkey */
9511
0
    pkcs8HeaderSz = 0;
9512
0
    if (key->pkey_sz > key->pkcs8HeaderSz)
9513
0
        pkcs8HeaderSz = key->pkcs8HeaderSz;
9514
0
    sz = key->pkey_sz - pkcs8HeaderSz;
9515
0
    if (der) {
9516
0
        pt = (unsigned char*)key->pkey.ptr;
9517
0
        if (*der) {
9518
            /* since this function signature has no size value passed in it is
9519
             * assumed that the user has allocated a large enough buffer */
9520
0
            XMEMCPY(*der, pt + pkcs8HeaderSz, sz);
9521
0
            *der += sz;
9522
0
        }
9523
0
        else {
9524
0
            *der = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL);
9525
0
            if (*der == NULL) {
9526
0
                return WOLFSSL_FATAL_ERROR;
9527
0
            }
9528
0
            XMEMCPY(*der, pt + pkcs8HeaderSz, sz);
9529
0
        }
9530
0
    }
9531
0
    return sz;
9532
0
}
9533
9534
int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
9535
0
{
9536
0
    return wolfSSL_EVP_PKEY_get_der(key, der);
9537
0
}
9538
9539
static WOLFSSL_EVP_PKEY* _d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out,
9540
    const unsigned char **in, long inSz, int priv)
9541
0
{
9542
0
    int ret = 0;
9543
0
    word32 idx = 0, algId;
9544
0
    word16 pkcs8HeaderSz = 0;
9545
0
    WOLFSSL_EVP_PKEY* local;
9546
0
    int opt;
9547
9548
0
    (void)opt;
9549
9550
0
    if (in == NULL || inSz < 0) {
9551
0
        WOLFSSL_MSG("Bad argument");
9552
0
        return NULL;
9553
0
    }
9554
9555
0
    if (priv == 1) {
9556
        /* Check if input buffer has PKCS8 header. In the case that it does not
9557
         * have a PKCS8 header then do not error out. */
9558
0
        if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx,
9559
0
                                          (word32)inSz, &algId)) > 0) {
9560
0
            WOLFSSL_MSG("Found PKCS8 header");
9561
0
            pkcs8HeaderSz = (word16)idx;
9562
9563
0
            if ((type == EVP_PKEY_RSA && algId != RSAk
9564
0
            #ifdef WC_RSA_PSS
9565
0
                 && algId != RSAPSSk
9566
0
            #endif
9567
0
                 ) ||
9568
0
                (type == EVP_PKEY_EC && algId != ECDSAk) ||
9569
0
                (type == EVP_PKEY_DSA && algId != DSAk) ||
9570
0
                (type == EVP_PKEY_DH && algId != DHk)) {
9571
0
                WOLFSSL_MSG("PKCS8 does not match EVP key type");
9572
0
                return NULL;
9573
0
            }
9574
9575
0
            (void)idx; /* not used */
9576
0
        }
9577
0
        else {
9578
0
            if (ret != ASN_PARSE_E) {
9579
0
                WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 "
9580
0
                    "header");
9581
0
                return NULL;
9582
0
            }
9583
0
        }
9584
0
    }
9585
9586
0
    if (out != NULL && *out != NULL) {
9587
0
        wolfSSL_EVP_PKEY_free(*out);
9588
0
        *out = NULL;
9589
0
    }
9590
0
    local = wolfSSL_EVP_PKEY_new();
9591
0
    if (local == NULL) {
9592
0
        return NULL;
9593
0
    }
9594
9595
0
    local->type     = type;
9596
0
    local->pkey_sz  = (int)inSz;
9597
0
    local->pkcs8HeaderSz = pkcs8HeaderSz;
9598
0
    local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
9599
0
    if (local->pkey.ptr == NULL) {
9600
0
        wolfSSL_EVP_PKEY_free(local);
9601
0
        local = NULL;
9602
0
        return NULL;
9603
0
    }
9604
0
    else {
9605
0
        XMEMCPY(local->pkey.ptr, *in, inSz);
9606
0
    }
9607
9608
0
    switch (type) {
9609
0
#ifndef NO_RSA
9610
0
        case EVP_PKEY_RSA:
9611
0
            local->ownRsa = 1;
9612
0
            local->rsa = wolfSSL_RSA_new();
9613
0
            if (local->rsa == NULL) {
9614
0
                wolfSSL_EVP_PKEY_free(local);
9615
0
                return NULL;
9616
0
            }
9617
0
            opt = priv ? WOLFSSL_RSA_LOAD_PRIVATE : WOLFSSL_RSA_LOAD_PUBLIC;
9618
0
            if (wolfSSL_RSA_LoadDer_ex(local->rsa,
9619
0
                      (const unsigned char*)local->pkey.ptr, local->pkey_sz,
9620
0
                      opt) != WOLFSSL_SUCCESS) {
9621
0
                wolfSSL_EVP_PKEY_free(local);
9622
0
                return NULL;
9623
0
            }
9624
0
            break;
9625
0
#endif /* NO_RSA */
9626
0
#ifdef HAVE_ECC
9627
0
        case EVP_PKEY_EC:
9628
0
            local->ownEcc = 1;
9629
0
            local->ecc = wolfSSL_EC_KEY_new();
9630
0
            if (local->ecc == NULL) {
9631
0
                wolfSSL_EVP_PKEY_free(local);
9632
0
                return NULL;
9633
0
            }
9634
0
            opt = priv ? WOLFSSL_EC_KEY_LOAD_PRIVATE :
9635
0
                         WOLFSSL_EC_KEY_LOAD_PUBLIC;
9636
0
            if (wolfSSL_EC_KEY_LoadDer_ex(local->ecc,
9637
0
                      (const unsigned char*)local->pkey.ptr, local->pkey_sz,
9638
0
                      opt)
9639
0
                      != WOLFSSL_SUCCESS) {
9640
0
                wolfSSL_EVP_PKEY_free(local);
9641
0
                return NULL;
9642
0
            }
9643
0
            break;
9644
0
#endif /* HAVE_ECC */
9645
0
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
9646
#ifndef NO_DSA
9647
        case EVP_PKEY_DSA:
9648
            local->ownDsa = 1;
9649
            local->dsa = wolfSSL_DSA_new();
9650
            if (local->dsa == NULL) {
9651
                wolfSSL_EVP_PKEY_free(local);
9652
                return NULL;
9653
            }
9654
            opt = priv ? WOLFSSL_DSA_LOAD_PRIVATE : WOLFSSL_DSA_LOAD_PUBLIC;
9655
            if (wolfSSL_DSA_LoadDer_ex(local->dsa,
9656
                    (const unsigned char*)local->pkey.ptr, local->pkey_sz,
9657
                    opt)
9658
                    != WOLFSSL_SUCCESS) {
9659
                wolfSSL_EVP_PKEY_free(local);
9660
                return NULL;
9661
            }
9662
            break;
9663
#endif /* NO_DSA */
9664
0
#ifndef NO_DH
9665
0
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION>2))
9666
0
        case EVP_PKEY_DH:
9667
0
            local->ownDh = 1;
9668
0
            local->dh = wolfSSL_DH_new();
9669
0
            if (local->dh == NULL) {
9670
0
                wolfSSL_EVP_PKEY_free(local);
9671
0
                return NULL;
9672
0
            }
9673
0
            if (wolfSSL_DH_LoadDer(local->dh,
9674
0
                      (const unsigned char*)local->pkey.ptr, local->pkey_sz)
9675
0
                      != WOLFSSL_SUCCESS) {
9676
0
                wolfSSL_EVP_PKEY_free(local);
9677
0
                return NULL;
9678
0
            }
9679
0
            break;
9680
0
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
9681
0
#endif /* HAVE_DH */
9682
0
#endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH */
9683
0
        default:
9684
0
            WOLFSSL_MSG("Unsupported key type");
9685
0
            wolfSSL_EVP_PKEY_free(local);
9686
0
            return NULL;
9687
0
    }
9688
9689
    /* advance pointer with success */
9690
0
    if (local != NULL) {
9691
0
        if (local->pkey_sz <= (int)inSz) {
9692
0
            *in += local->pkey_sz;
9693
0
        }
9694
9695
0
        if (out != NULL) {
9696
0
            *out = local;
9697
0
        }
9698
0
    }
9699
9700
0
    return local;
9701
0
}
9702
9703
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out,
9704
        const unsigned char **in, long inSz)
9705
0
{
9706
0
    WOLFSSL_ENTER("wolfSSL_d2i_PublicKey");
9707
9708
0
    return _d2i_PublicKey(type, out, in, inSz, 0);
9709
0
}
9710
/* Reads in a DER format key. If PKCS8 headers are found they are stripped off.
9711
 *
9712
 * type  type of key
9713
 * out   newly created WOLFSSL_EVP_PKEY structure
9714
 * in    pointer to input key DER
9715
 * inSz  size of in buffer
9716
 *
9717
 * On success a non null pointer is returned and the pointer in is advanced the
9718
 * same number of bytes read.
9719
 */
9720
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
9721
        const unsigned char **in, long inSz)
9722
0
{
9723
0
    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey");
9724
9725
0
    return _d2i_PublicKey(type, out, in, inSz, 1);
9726
0
}
9727
9728
#ifdef WOLF_PRIVATE_KEY_ID
9729
/* Create an EVP structure for use with crypto callbacks */
9730
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_id(int type, WOLFSSL_EVP_PKEY** out,
9731
    void* heap, int devId)
9732
0
{
9733
0
    WOLFSSL_EVP_PKEY* local;
9734
9735
0
    if (out != NULL && *out != NULL) {
9736
0
        wolfSSL_EVP_PKEY_free(*out);
9737
0
        *out = NULL;
9738
0
    }
9739
9740
0
    local = wolfSSL_EVP_PKEY_new_ex(heap);
9741
0
    if (local == NULL) {
9742
0
        return NULL;
9743
0
    }
9744
9745
0
    local->type     = type;
9746
0
    local->pkey_sz  = 0;
9747
0
    local->pkcs8HeaderSz = 0;
9748
9749
0
    switch (type) {
9750
0
#ifndef NO_RSA
9751
0
        case EVP_PKEY_RSA:
9752
0
        {
9753
0
            RsaKey* key;
9754
0
            local->ownRsa = 1;
9755
0
            local->rsa = wolfSSL_RSA_new_ex(heap, devId);
9756
0
            if (local->rsa == NULL) {
9757
0
                wolfSSL_EVP_PKEY_free(local);
9758
0
                return NULL;
9759
0
            }
9760
0
            key = (RsaKey*)local->rsa->internal;
9761
0
        #ifdef WOLF_CRYPTO_CB
9762
0
            key->devId = devId;
9763
0
        #endif
9764
0
            (void)key;
9765
0
            local->rsa->inSet = 1;
9766
0
            break;
9767
0
        }
9768
0
#endif /* !NO_RSA */
9769
0
#ifdef HAVE_ECC
9770
0
        case EVP_PKEY_EC:
9771
0
        {
9772
0
            ecc_key* key;
9773
0
            local->ownEcc = 1;
9774
0
            local->ecc = wolfSSL_EC_KEY_new_ex(heap, devId);
9775
0
            if (local->ecc == NULL) {
9776
0
                wolfSSL_EVP_PKEY_free(local);
9777
0
                return NULL;
9778
0
            }
9779
0
            key = (ecc_key*)local->ecc->internal;
9780
0
        #ifdef WOLF_CRYPTO_CB
9781
0
            key->devId = devId;
9782
0
        #endif
9783
0
            key->type = ECC_PRIVATEKEY;
9784
            /* key is required to have a key size / curve set, although
9785
             * actual one used is determined by devId callback function */
9786
0
            wc_ecc_set_curve(key, ECDHE_SIZE, ECC_CURVE_DEF);
9787
9788
0
            local->ecc->inSet = 1;
9789
0
            break;
9790
0
        }
9791
0
#endif /* HAVE_ECC */
9792
0
        default:
9793
0
            WOLFSSL_MSG("Unsupported private key id type");
9794
0
            wolfSSL_EVP_PKEY_free(local);
9795
0
            return NULL;
9796
0
    }
9797
9798
0
    if (local != NULL && out != NULL) {
9799
0
        *out = local;
9800
0
    }
9801
9802
0
    return local;
9803
0
}
9804
#endif /* WOLF_PRIVATE_KEY_ID */
9805
9806
#ifndef NO_CERTS // NOLINT(readability-redundant-preprocessor)
9807
9808
#ifndef NO_CHECK_PRIVATE_KEY
9809
/* Check private against public in certificate for match
9810
 *
9811
 * ssl  WOLFSSL structure to check private key in
9812
 *
9813
 * Returns WOLFSSL_SUCCESS on good private key
9814
 *         WOLFSSL_FAILURE if mismatched. */
9815
int wolfSSL_check_private_key(const WOLFSSL* ssl)
9816
0
{
9817
0
    if (ssl == NULL) {
9818
0
        return WOLFSSL_FAILURE;
9819
0
    }
9820
0
    return check_cert_key(ssl->buffers.certificate, ssl->buffers.key, ssl->heap,
9821
0
        ssl->buffers.keyDevId, ssl->buffers.keyLabel, ssl->buffers.keyId);
9822
0
}
9823
#endif /* !NO_CHECK_PRIVATE_KEY */
9824
9825
#if defined(OPENSSL_ALL)
9826
9827
int wolfSSL_ASN1_BIT_STRING_set_bit(WOLFSSL_ASN1_BIT_STRING* str, int pos,
9828
    int val)
9829
0
{
9830
0
    int bytes_cnt, bit;
9831
0
    byte* temp;
9832
9833
0
    if (!str || (val != 0 && val != 1) || pos < 0) {
9834
0
        return WOLFSSL_FAILURE;
9835
0
    }
9836
9837
0
    bytes_cnt = pos/8;
9838
0
    bit = 1<<(7-(pos%8));
9839
9840
0
    if (bytes_cnt+1 > str->length) {
9841
0
        if (!(temp = (byte*)XREALLOC(str->data, bytes_cnt+1, NULL,
9842
0
                DYNAMIC_TYPE_OPENSSL))) {
9843
0
            return WOLFSSL_FAILURE;
9844
0
        }
9845
0
        XMEMSET(temp+str->length, 0, bytes_cnt+1 - str->length);
9846
0
        str->data = temp;
9847
0
        str->length = bytes_cnt+1;
9848
0
    }
9849
9850
0
    str->data[bytes_cnt] &= ~bit;
9851
0
    str->data[bytes_cnt] |= val ? bit : 0;
9852
9853
0
    return WOLFSSL_SUCCESS;
9854
0
}
9855
9856
#endif /* OPENSSL_ALL */
9857
9858
#endif /* !NO_CERTS */
9859
#endif /* OPENSSL_EXTRA */
9860
9861
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
9862
WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void)
9863
0
{
9864
0
    WOLFSSL_ASN1_BIT_STRING* str;
9865
9866
0
    str = (WOLFSSL_ASN1_BIT_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_BIT_STRING),
9867
0
                                                  NULL, DYNAMIC_TYPE_OPENSSL);
9868
0
    if (str) {
9869
0
        XMEMSET(str, 0, sizeof(WOLFSSL_ASN1_BIT_STRING));
9870
0
    }
9871
0
    return str;
9872
0
}
9873
9874
void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING* str)
9875
0
{
9876
0
    if (str) {
9877
0
        if (str->data) {
9878
0
            XFREE(str->data, NULL, DYNAMIC_TYPE_OPENSSL);
9879
0
            str->data = NULL;
9880
0
        }
9881
0
        XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
9882
0
    }
9883
0
}
9884
9885
int wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING* str, int i)
9886
0
{
9887
0
    if (!str || !str->data || str->length <= (i/8) || i < 0) {
9888
0
        return WOLFSSL_FAILURE;
9889
0
    }
9890
9891
0
    return (str->data[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
9892
0
}
9893
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
9894
9895
#ifdef OPENSSL_EXTRA
9896
9897
int wolfSSL_use_PrivateKey(WOLFSSL* ssl, WOLFSSL_EVP_PKEY* pkey)
9898
0
{
9899
0
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey");
9900
0
    if (ssl == NULL || pkey == NULL ) {
9901
0
        return WOLFSSL_FAILURE;
9902
0
    }
9903
9904
0
    return wolfSSL_use_PrivateKey_buffer(ssl, (unsigned char*)pkey->pkey.ptr,
9905
0
                                         pkey->pkey_sz, WOLFSSL_FILETYPE_ASN1);
9906
0
}
9907
9908
9909
int wolfSSL_use_PrivateKey_ASN1(int pri, WOLFSSL* ssl, const unsigned char* der,
9910
                                long derSz)
9911
0
{
9912
0
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_ASN1");
9913
0
    if (ssl == NULL || der == NULL ) {
9914
0
        return WOLFSSL_FAILURE;
9915
0
    }
9916
9917
0
    (void)pri; /* type of private key */
9918
0
    return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
9919
0
}
9920
/******************************************************************************
9921
* wolfSSL_CTX_use_PrivateKey_ASN1 - loads a private key buffer into the SSL ctx
9922
*
9923
* RETURNS:
9924
* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
9925
*/
9926
9927
int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx,
9928
                                            unsigned char* der, long derSz)
9929
0
{
9930
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_ASN1");
9931
0
    if (ctx == NULL || der == NULL ) {
9932
0
        return WOLFSSL_FAILURE;
9933
0
    }
9934
9935
0
    (void)pri; /* type of private key */
9936
0
    return wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1);
9937
0
}
9938
9939
9940
#ifndef NO_RSA
9941
int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, long derSz)
9942
0
{
9943
0
    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_ASN1");
9944
0
    if (ssl == NULL || der == NULL ) {
9945
0
        return WOLFSSL_FAILURE;
9946
0
    }
9947
9948
0
    return wolfSSL_use_PrivateKey_buffer(ssl, der, derSz, WOLFSSL_FILETYPE_ASN1);
9949
0
}
9950
#endif
9951
9952
int wolfSSL_use_certificate(WOLFSSL* ssl, WOLFSSL_X509* x509)
9953
0
{
9954
0
    long idx;
9955
9956
0
    WOLFSSL_ENTER("wolfSSL_use_certificate");
9957
0
    if (x509 != NULL && ssl != NULL && x509->derCert != NULL) {
9958
0
        if (ProcessBuffer(NULL, x509->derCert->buffer, x509->derCert->length,
9959
0
                          WOLFSSL_FILETYPE_ASN1, CERT_TYPE, ssl, &idx, 0,
9960
0
                          GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
9961
0
            return WOLFSSL_SUCCESS;
9962
0
        }
9963
0
    }
9964
9965
0
    (void)idx;
9966
0
    return WOLFSSL_FAILURE;
9967
0
}
9968
9969
#endif /* OPENSSL_EXTRA */
9970
9971
int wolfSSL_use_certificate_ASN1(WOLFSSL* ssl, const unsigned char* der,
9972
                                 int derSz)
9973
0
{
9974
0
    long idx;
9975
9976
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_ASN1");
9977
0
    if (der != NULL && ssl != NULL) {
9978
0
        if (ProcessBuffer(NULL, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
9979
0
                ssl, &idx, 0, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
9980
0
            return WOLFSSL_SUCCESS;
9981
0
        }
9982
0
    }
9983
9984
0
    (void)idx;
9985
0
    return WOLFSSL_FAILURE;
9986
0
}
9987
9988
#ifndef NO_FILESYSTEM
9989
9990
WOLFSSL_ABI
9991
int wolfSSL_use_certificate_file(WOLFSSL* ssl, const char* file, int format)
9992
0
{
9993
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_file");
9994
9995
0
    if (ssl == NULL) {
9996
0
        return BAD_FUNC_ARG;
9997
0
    }
9998
9999
0
    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE,
10000
0
                ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10001
0
        return WOLFSSL_SUCCESS;
10002
0
    }
10003
10004
0
    return WOLFSSL_FAILURE;
10005
0
}
10006
10007
10008
WOLFSSL_ABI
10009
int wolfSSL_use_PrivateKey_file(WOLFSSL* ssl, const char* file, int format)
10010
0
{
10011
0
    WOLFSSL_ENTER("wolfSSL_use_PrivateKey_file");
10012
10013
0
    if (ssl == NULL) {
10014
0
        return BAD_FUNC_ARG;
10015
0
    }
10016
10017
0
    if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE,
10018
0
                ssl, 0, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10019
0
        return WOLFSSL_SUCCESS;
10020
0
    }
10021
10022
0
    return WOLFSSL_FAILURE;
10023
0
}
10024
10025
10026
WOLFSSL_ABI
10027
int wolfSSL_use_certificate_chain_file(WOLFSSL* ssl, const char* file)
10028
0
{
10029
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
10030
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file");
10031
10032
0
    if (ssl == NULL) {
10033
0
        return BAD_FUNC_ARG;
10034
0
    }
10035
10036
0
    if (ProcessFile(ssl->ctx, file, WOLFSSL_FILETYPE_PEM, CERT_TYPE,
10037
0
               ssl, 1, NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10038
0
        return WOLFSSL_SUCCESS;
10039
0
    }
10040
10041
0
   return WOLFSSL_FAILURE;
10042
0
}
10043
10044
int wolfSSL_use_certificate_chain_file_format(WOLFSSL* ssl, const char* file,
10045
                                              int format)
10046
0
{
10047
    /* process up to MAX_CHAIN_DEPTH plus subject cert */
10048
0
    WOLFSSL_ENTER("wolfSSL_use_certificate_chain_file_format");
10049
10050
0
    if (ssl == NULL) {
10051
0
        return BAD_FUNC_ARG;
10052
0
    }
10053
10054
0
    if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 1,
10055
0
                    NULL, GET_VERIFY_SETTING_SSL(ssl)) == WOLFSSL_SUCCESS) {
10056
0
        return WOLFSSL_SUCCESS;
10057
0
    }
10058
0
    return WOLFSSL_FAILURE;
10059
0
}
10060
10061
#endif /* !NO_FILESYSTEM */
10062
10063
#ifdef HAVE_ECC
10064
10065
/* Set Temp CTX EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
10066
int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
10067
0
{
10068
0
    if (ctx == NULL)
10069
0
        return BAD_FUNC_ARG;
10070
10071
    /* if 0 then get from loaded private key */
10072
0
    if (sz == 0) {
10073
        /* applies only to ECDSA */
10074
0
        if (ctx->privateKeyType != ecc_dsa_sa_algo)
10075
0
            return WOLFSSL_SUCCESS;
10076
10077
0
        if (ctx->privateKeySz == 0) {
10078
0
            WOLFSSL_MSG("Must set private key/cert first");
10079
0
            return BAD_FUNC_ARG;
10080
0
        }
10081
10082
0
        sz = (word16)ctx->privateKeySz;
10083
0
    }
10084
10085
    /* check size */
10086
0
    if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
10087
0
        return BAD_FUNC_ARG;
10088
10089
0
    ctx->eccTempKeySz = sz;
10090
10091
0
    return WOLFSSL_SUCCESS;
10092
0
}
10093
10094
10095
/* Set Temp SSL EC-DHE size in octets, can be 14 - 66 (112 - 521 bit) */
10096
int wolfSSL_SetTmpEC_DHE_Sz(WOLFSSL* ssl, word16 sz)
10097
0
{
10098
0
    if (ssl == NULL)
10099
0
        return BAD_FUNC_ARG;
10100
10101
    /* check size */
10102
0
    if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
10103
0
        return BAD_FUNC_ARG;
10104
10105
0
    ssl->eccTempKeySz = sz;
10106
10107
0
    return WOLFSSL_SUCCESS;
10108
0
}
10109
10110
#endif /* HAVE_ECC */
10111
10112
10113
#ifdef OPENSSL_EXTRA
10114
10115
#ifndef NO_FILESYSTEM
10116
int wolfSSL_CTX_use_RSAPrivateKey_file(WOLFSSL_CTX* ctx,const char* file,
10117
                                   int format)
10118
0
{
10119
0
    WOLFSSL_ENTER("SSL_CTX_use_RSAPrivateKey_file");
10120
10121
0
    return wolfSSL_CTX_use_PrivateKey_file(ctx, file, format);
10122
0
}
10123
10124
10125
int wolfSSL_use_RSAPrivateKey_file(WOLFSSL* ssl, const char* file, int format)
10126
0
{
10127
0
    WOLFSSL_ENTER("wolfSSL_use_RSAPrivateKey_file");
10128
10129
0
    return wolfSSL_use_PrivateKey_file(ssl, file, format);
10130
0
}
10131
#endif /* NO_FILESYSTEM */
10132
10133
10134
/* Copies the master secret over to out buffer. If outSz is 0 returns the size
10135
 * of master secret.
10136
 *
10137
 * ses : a session from completed TLS/SSL handshake
10138
 * out : buffer to hold copy of master secret
10139
 * outSz : size of out buffer
10140
 * returns : number of bytes copied into out buffer on success
10141
 *           less then or equal to 0 is considered a failure case
10142
 */
10143
int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses,
10144
        unsigned char* out, int outSz)
10145
0
{
10146
0
    int size;
10147
10148
0
    ses = ClientSessionToSession(ses);
10149
10150
0
    if (outSz == 0) {
10151
0
        return SECRET_LEN;
10152
0
    }
10153
10154
0
    if (ses == NULL || out == NULL || outSz < 0) {
10155
0
        return 0;
10156
0
    }
10157
10158
0
    if (outSz > SECRET_LEN) {
10159
0
        size = SECRET_LEN;
10160
0
    }
10161
0
    else {
10162
0
        size = outSz;
10163
0
    }
10164
10165
0
    XMEMCPY(out, ses->masterSecret, size);
10166
0
    return size;
10167
0
}
10168
10169
10170
int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses)
10171
0
{
10172
0
    (void)ses;
10173
0
    return SECRET_LEN;
10174
0
}
10175
10176
#ifdef WOLFSSL_EARLY_DATA
10177
unsigned int wolfSSL_SESSION_get_max_early_data(const WOLFSSL_SESSION *session)
10178
{
10179
    return session->maxEarlyDataSz;
10180
}
10181
#endif /* WOLFSSL_EARLY_DATA */
10182
10183
#endif /* OPENSSL_EXTRA */
10184
10185
typedef struct {
10186
    byte verifyPeer:1;
10187
    byte verifyNone:1;
10188
    byte failNoCert:1;
10189
    byte failNoCertxPSK:1;
10190
    byte verifyPostHandshake:1;
10191
} SetVerifyOptions;
10192
10193
static SetVerifyOptions ModeToVerifyOptions(int mode)
10194
0
{
10195
0
    SetVerifyOptions opts;
10196
0
    XMEMSET(&opts, 0, sizeof(SetVerifyOptions));
10197
10198
0
    if (mode != WOLFSSL_VERIFY_DEFAULT) {
10199
0
        opts.verifyNone = (mode == WOLFSSL_VERIFY_NONE);
10200
0
        if (!opts.verifyNone) {
10201
0
            opts.verifyPeer =
10202
0
                    (mode & WOLFSSL_VERIFY_PEER) != 0;
10203
0
            opts.failNoCertxPSK =
10204
0
                    (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) != 0;
10205
0
            opts.failNoCert =
10206
0
                    (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) != 0;
10207
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10208
            opts.verifyPostHandshake =
10209
                    (mode & WOLFSSL_VERIFY_POST_HANDSHAKE) != 0;
10210
#endif
10211
0
        }
10212
0
    }
10213
10214
0
    return opts;
10215
0
}
10216
10217
WOLFSSL_ABI
10218
void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode, VerifyCallback vc)
10219
0
{
10220
0
    SetVerifyOptions opts;
10221
10222
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
10223
0
    if (ctx == NULL)
10224
0
        return;
10225
10226
0
    opts = ModeToVerifyOptions(mode);
10227
10228
0
    ctx->verifyNone     = opts.verifyNone;
10229
0
    ctx->verifyPeer     = opts.verifyPeer;
10230
0
    ctx->failNoCert     = opts.failNoCert;
10231
0
    ctx->failNoCertxPSK = opts.failNoCertxPSK;
10232
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10233
    ctx->verifyPostHandshake = opts.verifyPostHandshake;
10234
#endif
10235
10236
0
    ctx->verifyCallback = vc;
10237
0
}
10238
10239
#ifdef OPENSSL_ALL
10240
void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx,
10241
    CertVerifyCallback cb, void* arg)
10242
0
{
10243
0
    WOLFSSL_ENTER("SSL_CTX_set_cert_verify_callback");
10244
0
    if (ctx == NULL)
10245
0
        return;
10246
10247
0
    ctx->verifyCertCb = cb;
10248
0
    ctx->verifyCertCbArg = arg;
10249
0
}
10250
#endif
10251
10252
10253
void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback vc)
10254
0
{
10255
0
    SetVerifyOptions opts;
10256
10257
0
    WOLFSSL_ENTER("wolfSSL_set_verify");
10258
0
    if (ssl == NULL)
10259
0
        return;
10260
10261
0
    opts = ModeToVerifyOptions(mode);
10262
10263
0
    ssl->options.verifyNone = opts.verifyNone;
10264
0
    ssl->options.verifyPeer = opts.verifyPeer;
10265
0
    ssl->options.failNoCert = opts.failNoCert;
10266
0
    ssl->options.failNoCertxPSK = opts.failNoCertxPSK;
10267
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10268
    ssl->options.verifyPostHandshake = opts.verifyPostHandshake;
10269
#endif
10270
10271
0
    ssl->verifyCallback = vc;
10272
0
}
10273
10274
void wolfSSL_set_verify_result(WOLFSSL *ssl, long v)
10275
0
{
10276
0
    WOLFSSL_ENTER("wolfSSL_set_verify_result");
10277
10278
0
    if (ssl == NULL)
10279
0
        return;
10280
10281
0
#ifdef OPENSSL_ALL
10282
0
    ssl->verifyCallbackResult = v;
10283
#else
10284
    (void)v;
10285
    WOLFSSL_STUB("wolfSSL_set_verify_result");
10286
#endif
10287
0
}
10288
10289
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
10290
    defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
10291
/* For TLS v1.3 send handshake messages after handshake completes. */
10292
/* Returns 1=WOLFSSL_SUCCESS or 0=WOLFSSL_FAILURE */
10293
int wolfSSL_verify_client_post_handshake(WOLFSSL* ssl)
10294
{
10295
    int ret = wolfSSL_request_certificate(ssl);
10296
    if (ret != WOLFSSL_SUCCESS) {
10297
        if (!IsAtLeastTLSv1_3(ssl->version)) {
10298
            /* specific error of wrong version expected */
10299
            WOLFSSL_ERROR(UNSUPPORTED_PROTO_VERSION);
10300
10301
        }
10302
        else {
10303
            WOLFSSL_ERROR(ret); /* log the error in the error queue */
10304
        }
10305
    }
10306
    return (ret == WOLFSSL_SUCCESS) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
10307
}
10308
10309
int wolfSSL_CTX_set_post_handshake_auth(WOLFSSL_CTX* ctx, int val)
10310
{
10311
    int ret = wolfSSL_CTX_allow_post_handshake_auth(ctx);
10312
    if (ret == 0) {
10313
        ctx->postHandshakeAuth = (val != 0);
10314
    }
10315
    return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
10316
}
10317
int wolfSSL_set_post_handshake_auth(WOLFSSL* ssl, int val)
10318
{
10319
    int ret = wolfSSL_allow_post_handshake_auth(ssl);
10320
    if (ret == 0) {
10321
        ssl->options.postHandshakeAuth = (val != 0);
10322
    }
10323
    return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
10324
}
10325
#endif /* OPENSSL_EXTRA && !NO_CERTS && WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
10326
10327
/* store user ctx for verify callback */
10328
void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
10329
0
{
10330
0
    WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
10331
0
    if (ssl)
10332
0
        ssl->verifyCbCtx = ctx;
10333
0
}
10334
10335
10336
/* store user ctx for verify callback */
10337
void wolfSSL_CTX_SetCertCbCtx(WOLFSSL_CTX* ctx, void* userCtx)
10338
0
{
10339
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetCertCbCtx");
10340
0
    if (ctx)
10341
0
        ctx->verifyCbCtx = userCtx;
10342
0
}
10343
10344
10345
/* store context CA Cache addition callback */
10346
void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
10347
0
{
10348
0
    if (ctx && ctx->cm)
10349
0
        ctx->cm->caCacheCallback = cb;
10350
0
}
10351
10352
10353
#if defined(PERSIST_CERT_CACHE)
10354
10355
#if !defined(NO_FILESYSTEM)
10356
10357
/* Persist cert cache to file */
10358
int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
10359
{
10360
    WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
10361
10362
    if (ctx == NULL || fname == NULL)
10363
        return BAD_FUNC_ARG;
10364
10365
    return CM_SaveCertCache(ctx->cm, fname);
10366
}
10367
10368
10369
/* Persist cert cache from file */
10370
int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
10371
{
10372
    WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
10373
10374
    if (ctx == NULL || fname == NULL)
10375
        return BAD_FUNC_ARG;
10376
10377
    return CM_RestoreCertCache(ctx->cm, fname);
10378
}
10379
10380
#endif /* NO_FILESYSTEM */
10381
10382
/* Persist cert cache to memory */
10383
int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
10384
                                   int sz, int* used)
10385
{
10386
    WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
10387
10388
    if (ctx == NULL || mem == NULL || used == NULL || sz <= 0)
10389
        return BAD_FUNC_ARG;
10390
10391
    return CM_MemSaveCertCache(ctx->cm, mem, sz, used);
10392
}
10393
10394
10395
/* Restore cert cache from memory */
10396
int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
10397
{
10398
    WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
10399
10400
    if (ctx == NULL || mem == NULL || sz <= 0)
10401
        return BAD_FUNC_ARG;
10402
10403
    return CM_MemRestoreCertCache(ctx->cm, mem, sz);
10404
}
10405
10406
10407
/* get how big the the cert cache save buffer needs to be */
10408
int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
10409
{
10410
    WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
10411
10412
    if (ctx == NULL)
10413
        return BAD_FUNC_ARG;
10414
10415
    return CM_GetCertCacheMemSize(ctx->cm);
10416
}
10417
10418
#endif /* PERSIST_CERT_CACHE */
10419
#endif /* !NO_CERTS */
10420
10421
10422
#ifndef NO_SESSION_CACHE
10423
10424
WOLFSSL_ABI
10425
WOLFSSL_SESSION* wolfSSL_get_session(WOLFSSL* ssl)
10426
0
{
10427
0
    WOLFSSL_ENTER("SSL_get_session");
10428
0
    if (ssl) {
10429
#ifdef NO_SESSION_CACHE_REF
10430
        return ssl->session;
10431
#else
10432
0
        if (ssl->options.side == WOLFSSL_CLIENT_END) {
10433
            /* On the client side we want to return a persistant reference for
10434
             * backwards compatibility. */
10435
0
#ifndef NO_CLIENT_CACHE
10436
0
            if (ssl->clientSession) {
10437
0
                return (WOLFSSL_SESSION*)ssl->clientSession;
10438
0
            }
10439
0
            else {
10440
                /* Try to add a ClientCache entry to associate with the current
10441
                 * session. Ignore any session cache options. */
10442
0
                int err;
10443
0
                const byte* id = ssl->session->sessionID;
10444
0
                byte idSz = ssl->session->sessionIDSz;
10445
0
                if (ssl->session->haveAltSessionID) {
10446
0
                    id = ssl->session->altSessionID;
10447
0
                    idSz = ID_LEN;
10448
0
                }
10449
0
                err = AddSessionToCache(ssl->ctx, ssl->session, id, idSz,
10450
0
                        NULL, ssl->session->side,
10451
0
                #ifdef HAVE_SESSION_TICKET
10452
0
                        ssl->session->ticketLen > 0,
10453
                #else
10454
                        0,
10455
                #endif
10456
0
                        &ssl->clientSession);
10457
0
                if (err == 0) {
10458
0
                    return (WOLFSSL_SESSION*)ssl->clientSession;
10459
0
                }
10460
0
            }
10461
0
#endif
10462
0
        }
10463
0
        else {
10464
0
            return ssl->session;
10465
0
        }
10466
0
#endif
10467
0
    }
10468
10469
0
    return NULL;
10470
0
}
10471
10472
/* The get1 version requires caller to call SSL_SESSION_free */
10473
WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl)
10474
0
{
10475
0
    WOLFSSL_SESSION* sess = NULL;
10476
0
    WOLFSSL_ENTER("SSL_get1_session");
10477
0
    if (ssl != NULL) {
10478
0
        sess = ssl->session;
10479
0
        if (sess != NULL) {
10480
            /* increase reference count if allocated session */
10481
0
            if (sess->type == WOLFSSL_SESSION_TYPE_HEAP) {
10482
0
                if (wolfSSL_SESSION_up_ref(sess) != WOLFSSL_SUCCESS)
10483
0
                    sess = NULL;
10484
0
            }
10485
0
        }
10486
0
    }
10487
0
    return sess;
10488
0
}
10489
10490
10491
/*
10492
 * Sets the session object to use when establishing a TLS/SSL session using
10493
 * the ssl object. Therefore, this function must be called before
10494
 * wolfSSL_connect. The session object to use can be obtained in a previous
10495
 * TLS/SSL connection using wolfSSL_get_session.
10496
 *
10497
 * This function rejects the session if it has been expired when this function
10498
 * is called. Note that this expiration check is wolfSSL specific and differs
10499
 * from OpenSSL return code behavior.
10500
 *
10501
 * By default, wolfSSL_set_session returns WOLFSSL_SUCCESS on successfully
10502
 * setting the session, WOLFSSL_FAILURE on failure due to the session cache
10503
 * being disabled, or the session has expired.
10504
 *
10505
 * To match OpenSSL return code behavior when session is expired, define
10506
 * OPENSSL_EXTRA and WOLFSSL_ERROR_CODE_OPENSSL. This behavior will return
10507
 * WOLFSSL_SUCCESS even when the session is expired and rejected.
10508
 */
10509
WOLFSSL_ABI
10510
int wolfSSL_set_session(WOLFSSL* ssl, WOLFSSL_SESSION* session)
10511
0
{
10512
0
    WOLFSSL_ENTER("SSL_set_session");
10513
0
    if (session)
10514
0
        return wolfSSL_SetSession(ssl, session);
10515
10516
0
    return WOLFSSL_FAILURE;
10517
0
}
10518
10519
10520
#ifndef NO_CLIENT_CACHE
10521
10522
/* Associate client session with serverID, find existing or store for saving
10523
   if newSession flag on, don't reuse existing session
10524
   WOLFSSL_SUCCESS on ok */
10525
int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession)
10526
0
{
10527
0
    WOLFSSL_SESSION* session = NULL;
10528
10529
0
    WOLFSSL_ENTER("wolfSSL_SetServerID");
10530
10531
0
    if (ssl == NULL || id == NULL || len <= 0)
10532
0
        return BAD_FUNC_ARG;
10533
10534
0
    if (newSession == 0) {
10535
0
        session = wolfSSL_GetSessionClient(ssl, id, len);
10536
0
        if (session) {
10537
0
            if (wolfSSL_SetSession(ssl, session) != WOLFSSL_SUCCESS) {
10538
0
            #ifdef HAVE_EXT_CACHE
10539
0
                wolfSSL_FreeSession(ssl->ctx, session);
10540
0
            #endif
10541
0
                WOLFSSL_MSG("wolfSSL_SetSession failed");
10542
0
                session = NULL;
10543
0
            }
10544
0
        }
10545
0
    }
10546
10547
0
    if (session == NULL) {
10548
0
        WOLFSSL_MSG("Valid ServerID not cached already");
10549
10550
0
        ssl->session->idLen = (word16)min(SERVER_ID_LEN, (word32)len);
10551
0
        XMEMCPY(ssl->session->serverID, id, ssl->session->idLen);
10552
0
    }
10553
0
#ifdef HAVE_EXT_CACHE
10554
0
    else {
10555
0
        wolfSSL_FreeSession(ssl->ctx, session);
10556
0
    }
10557
0
#endif
10558
10559
0
    return WOLFSSL_SUCCESS;
10560
0
}
10561
10562
#endif /* !NO_CLIENT_CACHE */
10563
10564
#if defined(PERSIST_SESSION_CACHE)
10565
10566
/* for persistence, if changes to layout need to increment and modify
10567
   save_session_cache() and restore_session_cache and memory versions too */
10568
#define WOLFSSL_CACHE_VERSION 2
10569
10570
/* Session Cache Header information */
10571
typedef struct {
10572
    int version;     /* cache layout version id */
10573
    int rows;        /* session rows */
10574
    int columns;     /* session columns */
10575
    int sessionSz;   /* sizeof WOLFSSL_SESSION */
10576
} cache_header_t;
10577
10578
/* current persistence layout is:
10579
10580
   1) cache_header_t
10581
   2) SessionCache
10582
   3) ClientCache
10583
10584
   update WOLFSSL_CACHE_VERSION if change layout for the following
10585
   PERSISTENT_SESSION_CACHE functions
10586
*/
10587
10588
10589
/* get how big the the session cache save buffer needs to be */
10590
int wolfSSL_get_session_cache_memsize(void)
10591
{
10592
    int sz  = (int)(sizeof(SessionCache) + sizeof(cache_header_t));
10593
#ifndef NO_CLIENT_CACHE
10594
    sz += (int)(sizeof(ClientCache));
10595
#endif
10596
    return sz;
10597
}
10598
10599
10600
/* Persist session cache to memory */
10601
int wolfSSL_memsave_session_cache(void* mem, int sz)
10602
{
10603
    int i;
10604
    cache_header_t cache_header;
10605
    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
10606
10607
    WOLFSSL_ENTER("wolfSSL_memsave_session_cache");
10608
10609
    if (sz < wolfSSL_get_session_cache_memsize()) {
10610
        WOLFSSL_MSG("Memory buffer too small");
10611
        return BUFFER_E;
10612
    }
10613
10614
    cache_header.version   = WOLFSSL_CACHE_VERSION;
10615
    cache_header.rows      = SESSION_ROWS;
10616
    cache_header.columns   = SESSIONS_PER_ROW;
10617
    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
10618
    XMEMCPY(mem, &cache_header, sizeof(cache_header));
10619
10620
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10621
    if (wc_LockMutex(&session_mutex) != 0) {
10622
        WOLFSSL_MSG("Session cache mutex lock failed");
10623
        return BAD_MUTEX_E;
10624
    }
10625
#endif
10626
    for (i = 0; i < cache_header.rows; ++i) {
10627
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10628
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10629
            WOLFSSL_MSG("Session row cache mutex lock failed");
10630
            return BAD_MUTEX_E;
10631
        }
10632
    #endif
10633
10634
        XMEMCPY(row++, &SessionCache[i], SIZEOF_SESSION_ROW);
10635
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10636
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10637
    #endif
10638
    }
10639
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10640
    wc_UnLockMutex(&session_mutex);
10641
#endif
10642
10643
#ifndef NO_CLIENT_CACHE
10644
    if (wc_LockMutex(&clisession_mutex) != 0) {
10645
        WOLFSSL_MSG("Client cache mutex lock failed");
10646
        return BAD_MUTEX_E;
10647
    }
10648
    XMEMCPY(row, ClientCache, sizeof(ClientCache));
10649
    wc_UnLockMutex(&clisession_mutex);
10650
#endif
10651
10652
    WOLFSSL_LEAVE("wolfSSL_memsave_session_cache", WOLFSSL_SUCCESS);
10653
10654
    return WOLFSSL_SUCCESS;
10655
}
10656
10657
10658
/* Restore the persistent session cache from memory */
10659
int wolfSSL_memrestore_session_cache(const void* mem, int sz)
10660
{
10661
    int    i;
10662
    cache_header_t cache_header;
10663
    SessionRow*    row  = (SessionRow*)((byte*)mem + sizeof(cache_header));
10664
10665
    WOLFSSL_ENTER("wolfSSL_memrestore_session_cache");
10666
10667
    if (sz < wolfSSL_get_session_cache_memsize()) {
10668
        WOLFSSL_MSG("Memory buffer too small");
10669
        return BUFFER_E;
10670
    }
10671
10672
    XMEMCPY(&cache_header, mem, sizeof(cache_header));
10673
    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
10674
        cache_header.rows      != SESSION_ROWS ||
10675
        cache_header.columns   != SESSIONS_PER_ROW ||
10676
        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
10677
10678
        WOLFSSL_MSG("Session cache header match failed");
10679
        return CACHE_MATCH_ERROR;
10680
    }
10681
10682
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10683
    if (wc_LockMutex(&session_mutex) != 0) {
10684
        WOLFSSL_MSG("Session cache mutex lock failed");
10685
        return BAD_MUTEX_E;
10686
    }
10687
#endif
10688
    for (i = 0; i < cache_header.rows; ++i) {
10689
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10690
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10691
            WOLFSSL_MSG("Session row cache mutex lock failed");
10692
            return BAD_MUTEX_E;
10693
        }
10694
    #endif
10695
10696
        XMEMCPY(&SessionCache[i], row++, SIZEOF_SESSION_ROW);
10697
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10698
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10699
    #endif
10700
    }
10701
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10702
    wc_UnLockMutex(&session_mutex);
10703
#endif
10704
10705
#ifndef NO_CLIENT_CACHE
10706
    if (wc_LockMutex(&clisession_mutex) != 0) {
10707
        WOLFSSL_MSG("Client cache mutex lock failed");
10708
        return BAD_MUTEX_E;
10709
    }
10710
    XMEMCPY(ClientCache, row, sizeof(ClientCache));
10711
    wc_UnLockMutex(&clisession_mutex);
10712
#endif
10713
10714
    WOLFSSL_LEAVE("wolfSSL_memrestore_session_cache", WOLFSSL_SUCCESS);
10715
10716
    return WOLFSSL_SUCCESS;
10717
}
10718
10719
#if !defined(NO_FILESYSTEM)
10720
10721
/* Persist session cache to file */
10722
/* doesn't use memsave because of additional memory use */
10723
int wolfSSL_save_session_cache(const char *fname)
10724
{
10725
    XFILE  file;
10726
    int    ret;
10727
    int    rc = WOLFSSL_SUCCESS;
10728
    int    i;
10729
    cache_header_t cache_header;
10730
10731
    WOLFSSL_ENTER("wolfSSL_save_session_cache");
10732
10733
    file = XFOPEN(fname, "w+b");
10734
    if (file == XBADFILE) {
10735
        WOLFSSL_MSG("Couldn't open session cache save file");
10736
        return WOLFSSL_BAD_FILE;
10737
    }
10738
    cache_header.version   = WOLFSSL_CACHE_VERSION;
10739
    cache_header.rows      = SESSION_ROWS;
10740
    cache_header.columns   = SESSIONS_PER_ROW;
10741
    cache_header.sessionSz = (int)sizeof(WOLFSSL_SESSION);
10742
10743
    /* cache header */
10744
    ret = (int)XFWRITE(&cache_header, sizeof cache_header, 1, file);
10745
    if (ret != 1) {
10746
        WOLFSSL_MSG("Session cache header file write failed");
10747
        XFCLOSE(file);
10748
        return FWRITE_ERROR;
10749
    }
10750
10751
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10752
    if (wc_LockMutex(&session_mutex) != 0) {
10753
        WOLFSSL_MSG("Session cache mutex lock failed");
10754
        XFCLOSE(file);
10755
        return BAD_MUTEX_E;
10756
    }
10757
#endif
10758
    /* session cache */
10759
    for (i = 0; i < cache_header.rows; ++i) {
10760
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10761
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10762
            WOLFSSL_MSG("Session row cache mutex lock failed");
10763
            XFCLOSE(file);
10764
            return BAD_MUTEX_E;
10765
        }
10766
    #endif
10767
10768
        ret = (int)XFWRITE(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
10769
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10770
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10771
    #endif
10772
        if (ret != 1) {
10773
            WOLFSSL_MSG("Session cache member file write failed");
10774
            rc = FWRITE_ERROR;
10775
            break;
10776
        }
10777
    }
10778
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10779
    wc_UnLockMutex(&session_mutex);
10780
#endif
10781
10782
#ifndef NO_CLIENT_CACHE
10783
    /* client cache */
10784
    if (wc_LockMutex(&clisession_mutex) != 0) {
10785
        WOLFSSL_MSG("Client cache mutex lock failed");
10786
        XFCLOSE(file);
10787
        return BAD_MUTEX_E;
10788
    }
10789
    ret = (int)XFWRITE(ClientCache, sizeof(ClientCache), 1, file);
10790
    if (ret != 1) {
10791
        WOLFSSL_MSG("Client cache member file write failed");
10792
        rc = FWRITE_ERROR;
10793
    }
10794
    wc_UnLockMutex(&clisession_mutex);
10795
#endif /* !NO_CLIENT_CACHE */
10796
10797
    XFCLOSE(file);
10798
    WOLFSSL_LEAVE("wolfSSL_save_session_cache", rc);
10799
10800
    return rc;
10801
}
10802
10803
10804
/* Restore the persistent session cache from file */
10805
/* doesn't use memstore because of additional memory use */
10806
int wolfSSL_restore_session_cache(const char *fname)
10807
{
10808
    XFILE  file;
10809
    int    rc = WOLFSSL_SUCCESS;
10810
    int    ret;
10811
    int    i;
10812
    cache_header_t cache_header;
10813
10814
    WOLFSSL_ENTER("wolfSSL_restore_session_cache");
10815
10816
    file = XFOPEN(fname, "rb");
10817
    if (file == XBADFILE) {
10818
        WOLFSSL_MSG("Couldn't open session cache save file");
10819
        return WOLFSSL_BAD_FILE;
10820
    }
10821
    /* cache header */
10822
    ret = (int)XFREAD(&cache_header, sizeof(cache_header), 1, file);
10823
    if (ret != 1) {
10824
        WOLFSSL_MSG("Session cache header file read failed");
10825
        XFCLOSE(file);
10826
        return FREAD_ERROR;
10827
    }
10828
    if (cache_header.version   != WOLFSSL_CACHE_VERSION ||
10829
        cache_header.rows      != SESSION_ROWS ||
10830
        cache_header.columns   != SESSIONS_PER_ROW ||
10831
        cache_header.sessionSz != (int)sizeof(WOLFSSL_SESSION)) {
10832
10833
        WOLFSSL_MSG("Session cache header match failed");
10834
        XFCLOSE(file);
10835
        return CACHE_MATCH_ERROR;
10836
    }
10837
10838
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10839
    if (wc_LockMutex(&session_mutex) != 0) {
10840
        WOLFSSL_MSG("Session cache mutex lock failed");
10841
        XFCLOSE(file);
10842
        return BAD_MUTEX_E;
10843
    }
10844
#endif
10845
    /* session cache */
10846
    for (i = 0; i < cache_header.rows; ++i) {
10847
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10848
        if (SESSION_ROW_LOCK(&SessionCache[i]) != 0) {
10849
            WOLFSSL_MSG("Session row cache mutex lock failed");
10850
            XFCLOSE(file);
10851
            return BAD_MUTEX_E;
10852
        }
10853
    #endif
10854
10855
        ret = (int)XFREAD(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
10856
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
10857
        SESSION_ROW_UNLOCK(&SessionCache[i]);
10858
    #endif
10859
        if (ret != 1) {
10860
            WOLFSSL_MSG("Session cache member file read failed");
10861
            XMEMSET(SessionCache, 0, sizeof SessionCache);
10862
            rc = FREAD_ERROR;
10863
            break;
10864
        }
10865
    }
10866
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
10867
    wc_UnLockMutex(&session_mutex);
10868
#endif
10869
10870
#ifndef NO_CLIENT_CACHE
10871
    /* client cache */
10872
    if (wc_LockMutex(&clisession_mutex) != 0) {
10873
        WOLFSSL_MSG("Client cache mutex lock failed");
10874
        XFCLOSE(file);
10875
        return BAD_MUTEX_E;
10876
    }
10877
    ret = (int)XFREAD(ClientCache, sizeof(ClientCache), 1, file);
10878
    if (ret != 1) {
10879
        WOLFSSL_MSG("Client cache member file read failed");
10880
        XMEMSET(ClientCache, 0, sizeof ClientCache);
10881
        rc = FREAD_ERROR;
10882
    }
10883
    wc_UnLockMutex(&clisession_mutex);
10884
#endif /* !NO_CLIENT_CACHE */
10885
10886
    XFCLOSE(file);
10887
    WOLFSSL_LEAVE("wolfSSL_restore_session_cache", rc);
10888
10889
    return rc;
10890
}
10891
10892
#endif /* !NO_FILESYSTEM */
10893
#endif /* PERSIST_SESSION_CACHE */
10894
#endif /* NO_SESSION_CACHE */
10895
10896
10897
void wolfSSL_load_error_strings(void)
10898
0
{
10899
    /* compatibility only */
10900
0
}
10901
10902
10903
int wolfSSL_library_init(void)
10904
0
{
10905
0
    WOLFSSL_ENTER("SSL_library_init");
10906
0
    if (wolfSSL_Init() == WOLFSSL_SUCCESS)
10907
0
        return WOLFSSL_SUCCESS;
10908
0
    else
10909
0
        return WOLFSSL_FATAL_ERROR;
10910
0
}
10911
10912
10913
#ifdef HAVE_SECRET_CALLBACK
10914
10915
int wolfSSL_set_session_secret_cb(WOLFSSL* ssl, SessionSecretCb cb, void* ctx)
10916
{
10917
    WOLFSSL_ENTER("wolfSSL_set_session_secret_cb");
10918
    if (ssl == NULL)
10919
        return WOLFSSL_FATAL_ERROR;
10920
10921
    ssl->sessionSecretCb = cb;
10922
    ssl->sessionSecretCtx = ctx;
10923
    if (cb != NULL) {
10924
        /* If using a pre-set key, assume session resumption. */
10925
        ssl->session->sessionIDSz = 0;
10926
        ssl->options.resuming = 1;
10927
    }
10928
10929
    return WOLFSSL_SUCCESS;
10930
}
10931
10932
#endif
10933
10934
10935
#ifndef NO_SESSION_CACHE
10936
10937
/* on by default if built in but allow user to turn off */
10938
WOLFSSL_ABI
10939
long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX* ctx, long mode)
10940
0
{
10941
0
    WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
10942
10943
0
    if (ctx == NULL)
10944
0
        return WOLFSSL_FAILURE;
10945
10946
0
    if (mode == WOLFSSL_SESS_CACHE_OFF)
10947
0
        ctx->sessionCacheOff = 1;
10948
10949
0
    if ((mode & WOLFSSL_SESS_CACHE_NO_AUTO_CLEAR) != 0)
10950
0
        ctx->sessionCacheFlushOff = 1;
10951
10952
0
#ifdef HAVE_EXT_CACHE
10953
0
    if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE) != 0)
10954
0
        ctx->internalCacheOff = 1;
10955
0
    if ((mode & WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP) != 0)
10956
0
        ctx->internalCacheLookupOff = 1;
10957
0
#endif
10958
10959
0
    return WOLFSSL_SUCCESS;
10960
0
}
10961
10962
#endif /* NO_SESSION_CACHE */
10963
10964
10965
#if !defined(NO_CERTS)
10966
#if defined(PERSIST_CERT_CACHE)
10967
10968
10969
#define WOLFSSL_CACHE_CERT_VERSION 1
10970
10971
typedef struct {
10972
    int version;                 /* cache cert layout version id */
10973
    int rows;                    /* hash table rows, CA_TABLE_SIZE */
10974
    int columns[CA_TABLE_SIZE];  /* columns per row on list */
10975
    int signerSz;                /* sizeof Signer object */
10976
} CertCacheHeader;
10977
10978
/* current cert persistence layout is:
10979
10980
   1) CertCacheHeader
10981
   2) caTable
10982
10983
   update WOLFSSL_CERT_CACHE_VERSION if change layout for the following
10984
   PERSIST_CERT_CACHE functions
10985
*/
10986
10987
10988
/* Return memory needed to persist this signer, have lock */
10989
static WC_INLINE int GetSignerMemory(Signer* signer)
10990
{
10991
    int sz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID)
10992
           + sizeof(signer->nameLen)    + sizeof(signer->subjectNameHash);
10993
10994
#if !defined(NO_SKID)
10995
        sz += (int)sizeof(signer->subjectKeyIdHash);
10996
#endif
10997
10998
    /* add dynamic bytes needed */
10999
    sz += signer->pubKeySize;
11000
    sz += signer->nameLen;
11001
11002
    return sz;
11003
}
11004
11005
11006
/* Return memory needed to persist this row, have lock */
11007
static WC_INLINE int GetCertCacheRowMemory(Signer* row)
11008
{
11009
    int sz = 0;
11010
11011
    while (row) {
11012
        sz += GetSignerMemory(row);
11013
        row = row->next;
11014
    }
11015
11016
    return sz;
11017
}
11018
11019
11020
/* get the size of persist cert cache, have lock */
11021
static WC_INLINE int GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
11022
{
11023
    int sz;
11024
    int i;
11025
11026
    sz = sizeof(CertCacheHeader);
11027
11028
    for (i = 0; i < CA_TABLE_SIZE; i++)
11029
        sz += GetCertCacheRowMemory(cm->caTable[i]);
11030
11031
    return sz;
11032
}
11033
11034
11035
/* Store cert cache header columns with number of items per list, have lock */
11036
static WC_INLINE void SetCertHeaderColumns(WOLFSSL_CERT_MANAGER* cm, int* columns)
11037
{
11038
    int     i;
11039
    Signer* row;
11040
11041
    for (i = 0; i < CA_TABLE_SIZE; i++) {
11042
        int count = 0;
11043
        row = cm->caTable[i];
11044
11045
        while (row) {
11046
            ++count;
11047
            row = row->next;
11048
        }
11049
        columns[i] = count;
11050
    }
11051
}
11052
11053
11054
/* Restore whole cert row from memory, have lock, return bytes consumed,
11055
   < 0 on error, have lock */
11056
static WC_INLINE int RestoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current,
11057
                                 int row, int listSz, const byte* end)
11058
{
11059
    int idx = 0;
11060
11061
    if (listSz < 0) {
11062
        WOLFSSL_MSG("Row header corrupted, negative value");
11063
        return PARSE_ERROR;
11064
    }
11065
11066
    while (listSz) {
11067
        Signer* signer;
11068
        byte*   publicKey;
11069
        byte*   start = current + idx;  /* for end checks on this signer */
11070
        int     minSz = sizeof(signer->pubKeySize) + sizeof(signer->keyOID) +
11071
                      sizeof(signer->nameLen) + sizeof(signer->subjectNameHash);
11072
        #ifndef NO_SKID
11073
                minSz += (int)sizeof(signer->subjectKeyIdHash);
11074
        #endif
11075
11076
        if (start + minSz > end) {
11077
            WOLFSSL_MSG("Would overread restore buffer");
11078
            return BUFFER_E;
11079
        }
11080
        signer = MakeSigner(cm->heap);
11081
        if (signer == NULL)
11082
            return MEMORY_E;
11083
11084
        /* pubKeySize */
11085
        XMEMCPY(&signer->pubKeySize, current + idx, sizeof(signer->pubKeySize));
11086
        idx += (int)sizeof(signer->pubKeySize);
11087
11088
        /* keyOID */
11089
        XMEMCPY(&signer->keyOID, current + idx, sizeof(signer->keyOID));
11090
        idx += (int)sizeof(signer->keyOID);
11091
11092
        /* publicKey */
11093
        if (start + minSz + signer->pubKeySize > end) {
11094
            WOLFSSL_MSG("Would overread restore buffer");
11095
            FreeSigner(signer, cm->heap);
11096
            return BUFFER_E;
11097
        }
11098
        publicKey = (byte*)XMALLOC(signer->pubKeySize, cm->heap,
11099
                                   DYNAMIC_TYPE_KEY);
11100
        if (publicKey == NULL) {
11101
            FreeSigner(signer, cm->heap);
11102
            return MEMORY_E;
11103
        }
11104
11105
        XMEMCPY(publicKey, current + idx, signer->pubKeySize);
11106
        signer->publicKey = publicKey;
11107
        idx += signer->pubKeySize;
11108
11109
        /* nameLen */
11110
        XMEMCPY(&signer->nameLen, current + idx, sizeof(signer->nameLen));
11111
        idx += (int)sizeof(signer->nameLen);
11112
11113
        /* name */
11114
        if (start + minSz + signer->pubKeySize + signer->nameLen > end) {
11115
            WOLFSSL_MSG("Would overread restore buffer");
11116
            FreeSigner(signer, cm->heap);
11117
            return BUFFER_E;
11118
        }
11119
        signer->name = (char*)XMALLOC(signer->nameLen, cm->heap,
11120
                                      DYNAMIC_TYPE_SUBJECT_CN);
11121
        if (signer->name == NULL) {
11122
            FreeSigner(signer, cm->heap);
11123
            return MEMORY_E;
11124
        }
11125
11126
        XMEMCPY(signer->name, current + idx, signer->nameLen);
11127
        idx += signer->nameLen;
11128
11129
        /* subjectNameHash */
11130
        XMEMCPY(signer->subjectNameHash, current + idx, SIGNER_DIGEST_SIZE);
11131
        idx += SIGNER_DIGEST_SIZE;
11132
11133
        #ifndef NO_SKID
11134
            /* subjectKeyIdHash */
11135
            XMEMCPY(signer->subjectKeyIdHash, current + idx,SIGNER_DIGEST_SIZE);
11136
            idx += SIGNER_DIGEST_SIZE;
11137
        #endif
11138
11139
        signer->next = cm->caTable[row];
11140
        cm->caTable[row] = signer;
11141
11142
        --listSz;
11143
    }
11144
11145
    return idx;
11146
}
11147
11148
11149
/* Store whole cert row into memory, have lock, return bytes added */
11150
static WC_INLINE int StoreCertRow(WOLFSSL_CERT_MANAGER* cm, byte* current, int row)
11151
{
11152
    int     added  = 0;
11153
    Signer* list   = cm->caTable[row];
11154
11155
    while (list) {
11156
        XMEMCPY(current + added, &list->pubKeySize, sizeof(list->pubKeySize));
11157
        added += (int)sizeof(list->pubKeySize);
11158
11159
        XMEMCPY(current + added, &list->keyOID,     sizeof(list->keyOID));
11160
        added += (int)sizeof(list->keyOID);
11161
11162
        XMEMCPY(current + added, list->publicKey, list->pubKeySize);
11163
        added += list->pubKeySize;
11164
11165
        XMEMCPY(current + added, &list->nameLen, sizeof(list->nameLen));
11166
        added += (int)sizeof(list->nameLen);
11167
11168
        XMEMCPY(current + added, list->name, list->nameLen);
11169
        added += list->nameLen;
11170
11171
        XMEMCPY(current + added, list->subjectNameHash, SIGNER_DIGEST_SIZE);
11172
        added += SIGNER_DIGEST_SIZE;
11173
11174
        #ifndef NO_SKID
11175
            XMEMCPY(current + added, list->subjectKeyIdHash,SIGNER_DIGEST_SIZE);
11176
            added += SIGNER_DIGEST_SIZE;
11177
        #endif
11178
11179
        list = list->next;
11180
    }
11181
11182
    return added;
11183
}
11184
11185
11186
/* Persist cert cache to memory, have lock */
11187
static WC_INLINE int DoMemSaveCertCache(WOLFSSL_CERT_MANAGER* cm,
11188
                                     void* mem, int sz)
11189
{
11190
    int realSz;
11191
    int ret = WOLFSSL_SUCCESS;
11192
    int i;
11193
11194
    WOLFSSL_ENTER("DoMemSaveCertCache");
11195
11196
    realSz = GetCertCacheMemSize(cm);
11197
    if (realSz > sz) {
11198
        WOLFSSL_MSG("Mem output buffer too small");
11199
        ret = BUFFER_E;
11200
    }
11201
    else {
11202
        byte*           current;
11203
        CertCacheHeader hdr;
11204
11205
        hdr.version  = WOLFSSL_CACHE_CERT_VERSION;
11206
        hdr.rows     = CA_TABLE_SIZE;
11207
        SetCertHeaderColumns(cm, hdr.columns);
11208
        hdr.signerSz = (int)sizeof(Signer);
11209
11210
        XMEMCPY(mem, &hdr, sizeof(CertCacheHeader));
11211
        current = (byte*)mem + sizeof(CertCacheHeader);
11212
11213
        for (i = 0; i < CA_TABLE_SIZE; ++i)
11214
            current += StoreCertRow(cm, current, i);
11215
    }
11216
11217
    return ret;
11218
}
11219
11220
11221
#if !defined(NO_FILESYSTEM)
11222
11223
/* Persist cert cache to file */
11224
int CM_SaveCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
11225
{
11226
    XFILE file;
11227
    int   rc = WOLFSSL_SUCCESS;
11228
    int   memSz;
11229
    byte* mem;
11230
11231
    WOLFSSL_ENTER("CM_SaveCertCache");
11232
11233
    file = XFOPEN(fname, "w+b");
11234
    if (file == XBADFILE) {
11235
       WOLFSSL_MSG("Couldn't open cert cache save file");
11236
       return WOLFSSL_BAD_FILE;
11237
    }
11238
11239
    if (wc_LockMutex(&cm->caLock) != 0) {
11240
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11241
        XFCLOSE(file);
11242
        return BAD_MUTEX_E;
11243
    }
11244
11245
    memSz = GetCertCacheMemSize(cm);
11246
    mem   = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11247
    if (mem == NULL) {
11248
        WOLFSSL_MSG("Alloc for tmp buffer failed");
11249
        rc = MEMORY_E;
11250
    } else {
11251
        rc = DoMemSaveCertCache(cm, mem, memSz);
11252
        if (rc == WOLFSSL_SUCCESS) {
11253
            int ret = (int)XFWRITE(mem, memSz, 1, file);
11254
            if (ret != 1) {
11255
                WOLFSSL_MSG("Cert cache file write failed");
11256
                rc = FWRITE_ERROR;
11257
            }
11258
        }
11259
        XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11260
    }
11261
11262
    wc_UnLockMutex(&cm->caLock);
11263
    XFCLOSE(file);
11264
11265
    return rc;
11266
}
11267
11268
11269
/* Restore cert cache from file */
11270
int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
11271
{
11272
    XFILE file;
11273
    int   rc = WOLFSSL_SUCCESS;
11274
    int   ret;
11275
    int   memSz;
11276
    byte* mem;
11277
11278
    WOLFSSL_ENTER("CM_RestoreCertCache");
11279
11280
    file = XFOPEN(fname, "rb");
11281
    if (file == XBADFILE) {
11282
       WOLFSSL_MSG("Couldn't open cert cache save file");
11283
       return WOLFSSL_BAD_FILE;
11284
    }
11285
11286
    if(XFSEEK(file, 0, XSEEK_END) != 0) {
11287
        XFCLOSE(file);
11288
        return WOLFSSL_BAD_FILE;
11289
    }
11290
    memSz = (int)XFTELL(file);
11291
    XREWIND(file);
11292
11293
    if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz <= 0) {
11294
        WOLFSSL_MSG("CM_RestoreCertCache file size error");
11295
        XFCLOSE(file);
11296
        return WOLFSSL_BAD_FILE;
11297
    }
11298
11299
    mem = (byte*)XMALLOC(memSz, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11300
    if (mem == NULL) {
11301
        WOLFSSL_MSG("Alloc for tmp buffer failed");
11302
        XFCLOSE(file);
11303
        return MEMORY_E;
11304
    }
11305
11306
    ret = (int)XFREAD(mem, memSz, 1, file);
11307
    if (ret != 1) {
11308
        WOLFSSL_MSG("Cert file read error");
11309
        rc = FREAD_ERROR;
11310
    } else {
11311
        rc = CM_MemRestoreCertCache(cm, mem, memSz);
11312
        if (rc != WOLFSSL_SUCCESS) {
11313
            WOLFSSL_MSG("Mem restore cert cache failed");
11314
        }
11315
    }
11316
11317
    XFREE(mem, cm->heap, DYNAMIC_TYPE_TMP_BUFFER);
11318
    XFCLOSE(file);
11319
11320
    return rc;
11321
}
11322
11323
#endif /* NO_FILESYSTEM */
11324
11325
11326
/* Persist cert cache to memory */
11327
int CM_MemSaveCertCache(WOLFSSL_CERT_MANAGER* cm, void* mem, int sz, int* used)
11328
{
11329
    int ret = WOLFSSL_SUCCESS;
11330
11331
    WOLFSSL_ENTER("CM_MemSaveCertCache");
11332
11333
    if (wc_LockMutex(&cm->caLock) != 0) {
11334
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11335
        return BAD_MUTEX_E;
11336
    }
11337
11338
    ret = DoMemSaveCertCache(cm, mem, sz);
11339
    if (ret == WOLFSSL_SUCCESS)
11340
        *used  = GetCertCacheMemSize(cm);
11341
11342
    wc_UnLockMutex(&cm->caLock);
11343
11344
    return ret;
11345
}
11346
11347
11348
/* Restore cert cache from memory */
11349
int CM_MemRestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const void* mem, int sz)
11350
{
11351
    int ret = WOLFSSL_SUCCESS;
11352
    int i;
11353
    CertCacheHeader* hdr = (CertCacheHeader*)mem;
11354
    byte*            current = (byte*)mem + sizeof(CertCacheHeader);
11355
    byte*            end     = (byte*)mem + sz;  /* don't go over */
11356
11357
    WOLFSSL_ENTER("CM_MemRestoreCertCache");
11358
11359
    if (current > end) {
11360
        WOLFSSL_MSG("Cert Cache Memory buffer too small");
11361
        return BUFFER_E;
11362
    }
11363
11364
    if (hdr->version  != WOLFSSL_CACHE_CERT_VERSION ||
11365
        hdr->rows     != CA_TABLE_SIZE ||
11366
        hdr->signerSz != (int)sizeof(Signer)) {
11367
11368
        WOLFSSL_MSG("Cert Cache Memory header mismatch");
11369
        return CACHE_MATCH_ERROR;
11370
    }
11371
11372
    if (wc_LockMutex(&cm->caLock) != 0) {
11373
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11374
        return BAD_MUTEX_E;
11375
    }
11376
11377
    FreeSignerTable(cm->caTable, CA_TABLE_SIZE, cm->heap);
11378
11379
    for (i = 0; i < CA_TABLE_SIZE; ++i) {
11380
        int added = RestoreCertRow(cm, current, i, hdr->columns[i], end);
11381
        if (added < 0) {
11382
            WOLFSSL_MSG("RestoreCertRow error");
11383
            ret = added;
11384
            break;
11385
        }
11386
        current += added;
11387
    }
11388
11389
    wc_UnLockMutex(&cm->caLock);
11390
11391
    return ret;
11392
}
11393
11394
11395
/* get how big the the cert cache save buffer needs to be */
11396
int CM_GetCertCacheMemSize(WOLFSSL_CERT_MANAGER* cm)
11397
{
11398
    int sz;
11399
11400
    WOLFSSL_ENTER("CM_GetCertCacheMemSize");
11401
11402
    if (wc_LockMutex(&cm->caLock) != 0) {
11403
        WOLFSSL_MSG("wc_LockMutex on caLock failed");
11404
        return BAD_MUTEX_E;
11405
    }
11406
11407
    sz = GetCertCacheMemSize(cm);
11408
11409
    wc_UnLockMutex(&cm->caLock);
11410
11411
    return sz;
11412
}
11413
11414
#endif /* PERSIST_CERT_CACHE */
11415
#endif /* NO_CERTS */
11416
11417
#ifdef OPENSSL_EXTRA
11418
11419
/*
11420
 * build enabled cipher list w/ TLS13 or w/o TLS13 suites
11421
 * @param ctx    a pointer to WOLFSSL_CTX structure
11422
 * @param suites currently enabled suites
11423
 * @param onlytlsv13suites flag whether correcting w/ TLS13 suites
11424
 *                         or w/o TLS13 suties
11425
 * @param list   suites list that user wants to update
11426
 * @return suites list on success, otherwise NULL
11427
 */
11428
static char* buildEnabledCipherList(WOLFSSL_CTX* ctx, Suites* suites,
11429
           int tls13Only, const char* list)
11430
0
{
11431
0
    word32 idx = 0;
11432
0
    word32 listsz = 0;
11433
0
    word32 len = 0;
11434
0
    word32 ianasz = 0;
11435
0
    const char* enabledcs = NULL;
11436
0
    char* locallist = NULL;
11437
0
    char* head = NULL;
11438
0
    byte cipherSuite0;
11439
0
    byte cipherSuite;
11440
11441
    /* sanity check */
11442
0
    if (ctx == NULL || suites == NULL || list == NULL)
11443
0
        return NULL;
11444
11445
0
    if (!suites->setSuites)
11446
0
        return NULL;
11447
11448
0
    listsz = (word32)XSTRLEN(list);
11449
11450
    /* calculate necessary buffer length */
11451
0
    for(idx = 0; idx < suites->suiteSz; idx++) {
11452
11453
0
        cipherSuite0 = suites->suites[idx];
11454
0
        cipherSuite  = suites->suites[++idx];
11455
11456
0
        if (tls13Only && cipherSuite0 == TLS13_BYTE) {
11457
0
            enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11458
0
        }
11459
0
        else if (!tls13Only && cipherSuite0 != TLS13_BYTE) {
11460
0
            enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11461
0
        }
11462
0
        else
11463
0
            continue;
11464
11465
0
        if (XSTRCMP(enabledcs, "None") != 0) {
11466
0
            len += (word32)XSTRLEN(enabledcs) + 2;
11467
0
        }
11468
0
    }
11469
11470
0
    len += listsz + 2;
11471
11472
    /* build string */
11473
0
    if (len > (listsz + 2)) {
11474
0
        locallist = (char*)XMALLOC(len, ctx->heap,
11475
0
                                           DYNAMIC_TYPE_TMP_BUFFER);
11476
        /* sanity check */
11477
0
        if (!locallist)
11478
0
            return NULL;
11479
11480
0
        XMEMSET(locallist, 0, len);
11481
11482
0
        head = locallist;
11483
11484
0
        if (!tls13Only)
11485
0
        {
11486
            /* always tls13 suites in the head position */
11487
0
            XSTRNCPY(locallist, list, len);
11488
0
            locallist += listsz;
11489
0
            *locallist++ = ':';
11490
0
            *locallist = 0;
11491
0
            len -= listsz + 1;
11492
0
        }
11493
11494
0
        for(idx = 0; idx < suites->suiteSz; idx++) {
11495
0
            cipherSuite0 = suites->suites[idx];
11496
0
            cipherSuite  = suites->suites[++idx];
11497
11498
0
            if (tls13Only && cipherSuite0 == TLS13_BYTE) {
11499
0
                enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11500
0
            }
11501
0
            else if (!tls13Only && cipherSuite0 != TLS13_BYTE) {
11502
0
                enabledcs = GetCipherNameInternal(cipherSuite0, cipherSuite);
11503
0
            }
11504
0
            else
11505
0
                continue;
11506
11507
0
            ianasz = (int)XSTRLEN(enabledcs);
11508
0
            if (ianasz + 1 < len) {
11509
0
                XSTRNCPY(locallist, enabledcs, len);
11510
0
                locallist += ianasz;
11511
11512
0
                *locallist++ = ':';
11513
0
                *locallist = 0;
11514
0
                len -= ianasz + 1;
11515
0
            }
11516
0
            else{
11517
0
                XFREE(locallist, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
11518
0
                return NULL;
11519
0
            }
11520
0
        }
11521
11522
0
        if (tls13Only) {
11523
0
            XSTRNCPY(locallist, list, len);
11524
0
            locallist += listsz;
11525
0
            *locallist = 0;
11526
0
        }
11527
11528
0
        return head;
11529
0
    }
11530
0
    else
11531
0
        return NULL;
11532
0
}
11533
11534
/*
11535
 * check if the list has TLS13 and pre-TLS13 suites
11536
 * @param list cipher suite list that user want to set
11537
 * @return mixed: 0, only pre-TLS13: 1, only TLS13: 2
11538
 */
11539
static int CheckcipherList(const char* list)
11540
0
{
11541
0
    int ret;
11542
0
    int findTLSv13Suites = 0;
11543
0
    int findbeforeSuites = 0;
11544
0
    byte cipherSuite0;
11545
0
    byte cipherSuite1;
11546
0
    int flags;
11547
0
    char* next = (char*)list;
11548
11549
0
    do {
11550
0
        char*  current = next;
11551
0
        char   name[MAX_SUITE_NAME + 1];
11552
0
        word32 length = MAX_SUITE_NAME;
11553
0
        word32 current_length;
11554
11555
0
        next   = XSTRSTR(next, ":");
11556
11557
0
        current_length = (!next) ? (word32)XSTRLEN(current)
11558
0
                                 : (word32)(next - current);
11559
11560
0
        if (current_length < length) {
11561
0
            length = current_length;
11562
0
        }
11563
0
        XMEMCPY(name, current, length);
11564
0
        name[length] = 0;
11565
11566
0
        ret = wolfSSL_get_cipher_suite_from_name(name, &cipherSuite0,
11567
0
                                                        &cipherSuite1, &flags);
11568
0
        if (ret == 0) {
11569
0
            if (cipherSuite0 == TLS13_BYTE) {
11570
                /* TLSv13 suite */
11571
0
                findTLSv13Suites = 1;
11572
0
                break;
11573
0
            }
11574
0
            else {
11575
0
                findbeforeSuites = 1;
11576
0
                break;
11577
0
            }
11578
0
        }
11579
0
        if (findTLSv13Suites == 1 && findbeforeSuites == 1) {
11580
            /* list has mixed suites */
11581
0
            return 0;
11582
0
        }
11583
0
    }  while (next++); /* ++ needed to skip ':' */
11584
11585
0
    if (findTLSv13Suites == 0 && findbeforeSuites == 1) {
11586
0
        return 1;/* only before TLSv13 suites */
11587
0
    }
11588
0
    else if (findTLSv13Suites == 1 && findbeforeSuites == 0) {
11589
0
        return 2;/* only TLSv13 suties */
11590
0
    }
11591
0
    else {
11592
0
        return 0;/* handle as mixed */
11593
0
    }
11594
0
}
11595
11596
/* parse some bulk lists like !eNULL / !aNULL
11597
 *
11598
 * returns WOLFSSL_SUCCESS on success and sets the cipher suite list
11599
 */
11600
static int wolfSSL_parse_cipher_list(WOLFSSL_CTX* ctx, Suites* suites,
11601
        const char* list)
11602
0
{
11603
0
    int       ret          = 0;
11604
0
    int listattribute = 0;
11605
0
    char*     buildcipherList = NULL;
11606
0
    int tls13Only = 0;
11607
11608
0
    if (suites == NULL || list == NULL) {
11609
0
        WOLFSSL_MSG("NULL argument");
11610
0
        return WOLFSSL_FAILURE;
11611
0
    }
11612
11613
0
    listattribute = CheckcipherList(list);
11614
11615
0
    if (listattribute == 0) {
11616
       /* list has mixed(pre-TLSv13 and TLSv13) suites
11617
        * update cipher suites the same as before
11618
        */
11619
0
        return (SetCipherList(ctx, suites, list)) ? WOLFSSL_SUCCESS :
11620
0
        WOLFSSL_FAILURE;
11621
0
    }
11622
0
    else if (listattribute == 1) {
11623
       /* list has only pre-TLSv13 suites.
11624
        * Only update before TLSv13 suites.
11625
        */
11626
0
        tls13Only = 1;
11627
0
    }
11628
0
    else if (listattribute == 2) {
11629
       /* list has only TLSv13 suites. Only update TLv13 suites
11630
        * simulate set_ciphersuites() compatibility layer API
11631
        */
11632
0
        tls13Only = 0;
11633
0
    }
11634
11635
0
    buildcipherList = buildEnabledCipherList(ctx, ctx->suites,
11636
0
                                            tls13Only, list);
11637
11638
0
    if (buildcipherList) {
11639
0
        ret = SetCipherList(ctx, suites, buildcipherList);
11640
0
        XFREE(buildcipherList, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
11641
0
    }
11642
0
    else {
11643
0
        ret = SetCipherList(ctx, suites, list);
11644
0
    }
11645
11646
0
    return ret;
11647
0
}
11648
11649
#endif
11650
11651
11652
int wolfSSL_CTX_set_cipher_list(WOLFSSL_CTX* ctx, const char* list)
11653
0
{
11654
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_cipher_list");
11655
11656
0
    if (ctx == NULL)
11657
0
        return WOLFSSL_FAILURE;
11658
11659
    /* alloc/init on demand only */
11660
0
    if (ctx->suites == NULL) {
11661
0
        ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
11662
0
                                       DYNAMIC_TYPE_SUITES);
11663
0
        if (ctx->suites == NULL) {
11664
0
            WOLFSSL_MSG("Memory alloc for Suites failed");
11665
0
            return WOLFSSL_FAILURE;
11666
0
        }
11667
0
        XMEMSET(ctx->suites, 0, sizeof(Suites));
11668
0
    }
11669
11670
0
#ifdef OPENSSL_EXTRA
11671
0
    return wolfSSL_parse_cipher_list(ctx, ctx->suites, list);
11672
#else
11673
    return (SetCipherList(ctx, ctx->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
11674
#endif
11675
0
}
11676
11677
11678
int wolfSSL_set_cipher_list(WOLFSSL* ssl, const char* list)
11679
0
{
11680
0
    WOLFSSL_ENTER("wolfSSL_set_cipher_list");
11681
#ifdef SINGLE_THREADED
11682
    if (ssl->ctx->suites == ssl->suites) {
11683
        ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
11684
                                       DYNAMIC_TYPE_SUITES);
11685
        if (ssl->suites == NULL) {
11686
            WOLFSSL_MSG("Suites Memory error");
11687
            return MEMORY_E;
11688
        }
11689
        *ssl->suites = *ssl->ctx->suites;
11690
        ssl->options.ownSuites = 1;
11691
    }
11692
#endif
11693
11694
0
#ifdef OPENSSL_EXTRA
11695
0
    return wolfSSL_parse_cipher_list(ssl->ctx, ssl->suites, list);
11696
#else
11697
    return (SetCipherList(ssl->ctx, ssl->suites, list)) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
11698
#endif
11699
0
}
11700
11701
#ifdef HAVE_KEYING_MATERIAL
11702
11703
#define TLS_PRF_LABEL_CLIENT_FINISHED     "client finished"
11704
#define TLS_PRF_LABEL_SERVER_FINISHED     "server finished"
11705
#define TLS_PRF_LABEL_MASTER_SECRET       "master secret"
11706
#define TLS_PRF_LABEL_EXT_MASTER_SECRET   "extended master secret"
11707
#define TLS_PRF_LABEL_KEY_EXPANSION       "key expansion"
11708
11709
static const struct ForbiddenLabels {
11710
    const char* label;
11711
    size_t labelLen;
11712
} forbiddenLabels[] = {
11713
    {TLS_PRF_LABEL_CLIENT_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_CLIENT_FINISHED)},
11714
    {TLS_PRF_LABEL_SERVER_FINISHED, XSTR_SIZEOF(TLS_PRF_LABEL_SERVER_FINISHED)},
11715
    {TLS_PRF_LABEL_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_MASTER_SECRET)},
11716
    {TLS_PRF_LABEL_EXT_MASTER_SECRET, XSTR_SIZEOF(TLS_PRF_LABEL_EXT_MASTER_SECRET)},
11717
    {TLS_PRF_LABEL_KEY_EXPANSION, XSTR_SIZEOF(TLS_PRF_LABEL_KEY_EXPANSION)},
11718
    {NULL, 0},
11719
};
11720
11721
/**
11722
 * Implement RFC 5705
11723
 * TLS 1.3 uses a different exporter definition (section 7.5 of RFC 8446)
11724
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
11725
 */
11726
int wolfSSL_export_keying_material(WOLFSSL *ssl,
11727
        unsigned char *out, size_t outLen,
11728
        const char *label, size_t labelLen,
11729
        const unsigned char *context, size_t contextLen,
11730
        int use_context)
11731
{
11732
    byte*  seed = NULL;
11733
    word32 seedLen;
11734
    const struct ForbiddenLabels* fl;
11735
11736
    WOLFSSL_ENTER("wolfSSL_export_keying_material");
11737
11738
    if (ssl == NULL || out == NULL || label == NULL ||
11739
            (use_context && contextLen && context == NULL)) {
11740
        WOLFSSL_MSG("Bad argument");
11741
        return WOLFSSL_FAILURE;
11742
    }
11743
11744
    /* clientRandom + serverRandom
11745
     * OR
11746
     * clientRandom + serverRandom + ctx len encoding + ctx */
11747
    seedLen = !use_context ? (word32)SEED_LEN :
11748
                             (word32)SEED_LEN + 2 + (word32)contextLen;
11749
11750
    if (ssl->options.saveArrays == 0 || ssl->arrays == NULL) {
11751
        WOLFSSL_MSG("To export keying material wolfSSL needs to keep handshake "
11752
                    "data. Call wolfSSL_KeepArrays before attempting to "
11753
                    "export keyid material.");
11754
        return WOLFSSL_FAILURE;
11755
    }
11756
11757
    /* check forbidden labels */
11758
    for (fl = &forbiddenLabels[0]; fl->label != NULL; fl++) {
11759
        if (labelLen >= fl->labelLen &&
11760
                XMEMCMP(label, fl->label, fl->labelLen) == 0) {
11761
            WOLFSSL_MSG("Forbidden label");
11762
            return WOLFSSL_FAILURE;
11763
        }
11764
    }
11765
11766
#ifdef WOLFSSL_TLS13
11767
    if (IsAtLeastTLSv1_3(ssl->version)) {
11768
        /* Path for TLS 1.3 */
11769
        if (!use_context) {
11770
            contextLen = 0;
11771
            context = (byte*)""; /* Give valid pointer for 0 length memcpy */
11772
        }
11773
11774
        if (Tls13_Exporter(ssl, out, (word32)outLen, label, labelLen,
11775
                context, contextLen) != 0) {
11776
            WOLFSSL_MSG("Tls13_Exporter error");
11777
            return WOLFSSL_FAILURE;
11778
        }
11779
        return WOLFSSL_SUCCESS;
11780
    }
11781
#endif
11782
11783
    /* Path for <=TLS 1.2 */
11784
    seed = (byte*)XMALLOC(seedLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11785
    if (seed == NULL) {
11786
        WOLFSSL_MSG("malloc error");
11787
        return WOLFSSL_FAILURE;
11788
    }
11789
11790
    XMEMCPY(seed,           ssl->arrays->clientRandom, RAN_LEN);
11791
    XMEMCPY(seed + RAN_LEN, ssl->arrays->serverRandom, RAN_LEN);
11792
11793
    if (use_context) {
11794
        /* Encode len in big endian */
11795
        seed[SEED_LEN    ] = (contextLen >> 8) & 0xFF;
11796
        seed[SEED_LEN + 1] = (contextLen) & 0xFF;
11797
        if (contextLen) {
11798
            /* 0 length context is allowed */
11799
            XMEMCPY(seed + SEED_LEN + 2, context, contextLen);
11800
        }
11801
    }
11802
11803
    PRIVATE_KEY_UNLOCK();
11804
    if (wc_PRF_TLS(out, (word32)outLen, ssl->arrays->masterSecret, SECRET_LEN,
11805
            (byte*)label, (word32)labelLen, seed, seedLen, IsAtLeastTLSv1_2(ssl),
11806
            ssl->specs.mac_algorithm, ssl->heap, ssl->devId) != 0) {
11807
        WOLFSSL_MSG("wc_PRF_TLS error");
11808
        PRIVATE_KEY_LOCK();
11809
        XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11810
        return WOLFSSL_FAILURE;
11811
    }
11812
    PRIVATE_KEY_LOCK();
11813
11814
    XFREE(seed, NULL, DYNAMIC_TYPE_TMP_BUFFER);
11815
    return WOLFSSL_SUCCESS;
11816
}
11817
#endif /* HAVE_KEYING_MATERIAL */
11818
11819
int wolfSSL_dtls_get_using_nonblock(WOLFSSL* ssl)
11820
0
{
11821
0
    int useNb = 0;
11822
11823
0
    if (ssl == NULL)
11824
0
        return WOLFSSL_FAILURE;
11825
11826
0
    WOLFSSL_ENTER("wolfSSL_dtls_get_using_nonblock");
11827
0
    if (ssl->options.dtls) {
11828
#ifdef WOLFSSL_DTLS
11829
        useNb = ssl->options.dtlsUseNonblock;
11830
#endif
11831
0
    }
11832
0
    else {
11833
0
        WOLFSSL_MSG("wolfSSL_dtls_get_using_nonblock() is "
11834
0
                    "DEPRECATED for non-DTLS use.");
11835
0
    }
11836
0
    return useNb;
11837
0
}
11838
11839
11840
#ifndef WOLFSSL_LEANPSK
11841
11842
void wolfSSL_dtls_set_using_nonblock(WOLFSSL* ssl, int nonblock)
11843
0
{
11844
0
    (void)nonblock;
11845
11846
0
    WOLFSSL_ENTER("wolfSSL_dtls_set_using_nonblock");
11847
11848
0
    if (ssl == NULL)
11849
0
        return;
11850
11851
0
    if (ssl->options.dtls) {
11852
#ifdef WOLFSSL_DTLS
11853
        ssl->options.dtlsUseNonblock = (nonblock != 0);
11854
#endif
11855
0
    }
11856
0
    else {
11857
0
        WOLFSSL_MSG("wolfSSL_dtls_set_using_nonblock() is "
11858
0
                    "DEPRECATED for non-DTLS use.");
11859
0
    }
11860
0
}
11861
11862
11863
#ifdef WOLFSSL_DTLS
11864
11865
int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl)
11866
{
11867
    int timeout = 0;
11868
    if (ssl)
11869
        timeout = ssl->dtls_timeout;
11870
11871
    WOLFSSL_LEAVE("wolfSSL_dtls_get_current_timeout()", timeout);
11872
    return timeout;
11873
}
11874
11875
#ifdef WOLFSSL_DTLS13
11876
11877
/*
11878
 * This API returns 1 when the user should set a short timeout for receiving
11879
 * data. It is recommended that it is at most 1/4 the value returned by
11880
 * wolfSSL_dtls_get_current_timeout().
11881
 */
11882
int wolfSSL_dtls13_use_quick_timeout(WOLFSSL* ssl)
11883
{
11884
    return ssl->dtls13FastTimeout;
11885
}
11886
11887
/*
11888
 * When this is set, a DTLS 1.3 connection will send acks immediately when a
11889
 * disruption is detected to shortcut timeouts. This results in potentially
11890
 * more traffic but may make the handshake quicker.
11891
 */
11892
void wolfSSL_dtls13_set_send_more_acks(WOLFSSL* ssl, int value)
11893
{
11894
    if (ssl != NULL)
11895
        ssl->options.dtls13SendMoreAcks = !!value;
11896
}
11897
#endif /* WOLFSSL_DTLS13 */
11898
11899
int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft)
11900
{
11901
    if (ssl && timeleft) {
11902
        XMEMSET(timeleft, 0, sizeof(WOLFSSL_TIMEVAL));
11903
        timeleft->tv_sec = ssl->dtls_timeout;
11904
    }
11905
    return 0;
11906
}
11907
11908
#ifndef NO_WOLFSSL_STUB
11909
int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl)
11910
{
11911
    WOLFSSL_STUB("SSL_DTLSv1_handle_timeout");
11912
    (void)ssl;
11913
    return 0;
11914
}
11915
#endif
11916
11917
#ifndef NO_WOLFSSL_STUB
11918
void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl, word32 duration_ms)
11919
{
11920
    WOLFSSL_STUB("SSL_DTLSv1_set_initial_timeout_duration");
11921
    (void)ssl;
11922
    (void)duration_ms;
11923
}
11924
#endif
11925
11926
/* user may need to alter init dtls recv timeout, WOLFSSL_SUCCESS on ok */
11927
int wolfSSL_dtls_set_timeout_init(WOLFSSL* ssl, int timeout)
11928
{
11929
    if (ssl == NULL || timeout < 0)
11930
        return BAD_FUNC_ARG;
11931
11932
    if (timeout > ssl->dtls_timeout_max) {
11933
        WOLFSSL_MSG("Can't set dtls timeout init greater than dtls timeout max");
11934
        return BAD_FUNC_ARG;
11935
    }
11936
11937
    ssl->dtls_timeout_init = timeout;
11938
    ssl->dtls_timeout = timeout;
11939
11940
    return WOLFSSL_SUCCESS;
11941
}
11942
11943
11944
/* user may need to alter max dtls recv timeout, WOLFSSL_SUCCESS on ok */
11945
int wolfSSL_dtls_set_timeout_max(WOLFSSL* ssl, int timeout)
11946
{
11947
    if (ssl == NULL || timeout < 0)
11948
        return BAD_FUNC_ARG;
11949
11950
    if (timeout < ssl->dtls_timeout_init) {
11951
        WOLFSSL_MSG("Can't set dtls timeout max less than dtls timeout init");
11952
        return BAD_FUNC_ARG;
11953
    }
11954
11955
    ssl->dtls_timeout_max = timeout;
11956
11957
    return WOLFSSL_SUCCESS;
11958
}
11959
11960
11961
int wolfSSL_dtls_got_timeout(WOLFSSL* ssl)
11962
{
11963
    int result = WOLFSSL_SUCCESS;
11964
    WOLFSSL_ENTER("wolfSSL_dtls_got_timeout()");
11965
11966
    if (ssl == NULL)
11967
        return WOLFSSL_FATAL_ERROR;
11968
11969
#ifdef WOLFSSL_DTLS13
11970
    if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)) {
11971
        result = Dtls13RtxTimeout(ssl);
11972
        if (result < 0) {
11973
            if (result == WANT_WRITE)
11974
                ssl->dtls13SendingAckOrRtx = 1;
11975
            ssl->error = result;
11976
            WOLFSSL_ERROR(result);
11977
            return WOLFSSL_FATAL_ERROR;
11978
        }
11979
11980
        return WOLFSSL_SUCCESS;
11981
    }
11982
#endif /* WOLFSSL_DTLS13 */
11983
11984
    if ((IsSCR(ssl) || !ssl->options.handShakeDone)) {
11985
        if (DtlsMsgPoolTimeout(ssl) < 0){
11986
            ssl->error = SOCKET_ERROR_E;
11987
            WOLFSSL_ERROR(ssl->error);
11988
            result = WOLFSSL_FATAL_ERROR;
11989
        }
11990
        else if ((result = DtlsMsgPoolSend(ssl, 0)) < 0)  {
11991
            ssl->error = result;
11992
            WOLFSSL_ERROR(result);
11993
            result = WOLFSSL_FATAL_ERROR;
11994
        }
11995
        else {
11996
            /* Reset return value to success */
11997
            result = WOLFSSL_SUCCESS;
11998
        }
11999
    }
12000
12001
    WOLFSSL_LEAVE("wolfSSL_dtls_got_timeout()", result);
12002
    return result;
12003
}
12004
12005
12006
/* retransmit all the saves messages, WOLFSSL_SUCCESS on ok */
12007
int wolfSSL_dtls_retransmit(WOLFSSL* ssl)
12008
{
12009
    WOLFSSL_ENTER("wolfSSL_dtls_retransmit()");
12010
12011
    if (ssl == NULL)
12012
        return WOLFSSL_FATAL_ERROR;
12013
12014
    if (!ssl->options.handShakeDone) {
12015
        int result = DtlsMsgPoolSend(ssl, 0);
12016
        if (result < 0) {
12017
            ssl->error = result;
12018
            WOLFSSL_ERROR(result);
12019
            return WOLFSSL_FATAL_ERROR;
12020
        }
12021
    }
12022
12023
    return 0;
12024
}
12025
12026
#endif /* DTLS */
12027
#endif /* LEANPSK */
12028
12029
12030
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
12031
12032
/* Not an SSL function, return 0 for success, error code otherwise */
12033
/* Prereq: ssl's RNG needs to be initialized. */
12034
int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
12035
                                 const byte* secret, word32 secretSz)
12036
{
12037
    int ret = 0;
12038
12039
    WOLFSSL_ENTER("wolfSSL_DTLS_SetCookieSecret");
12040
12041
    if (ssl == NULL) {
12042
        WOLFSSL_MSG("need a SSL object");
12043
        return BAD_FUNC_ARG;
12044
    }
12045
12046
    if (secret != NULL && secretSz == 0) {
12047
        WOLFSSL_MSG("can't have a new secret without a size");
12048
        return BAD_FUNC_ARG;
12049
    }
12050
12051
    /* If secretSz is 0, use the default size. */
12052
    if (secretSz == 0)
12053
        secretSz = COOKIE_SECRET_SZ;
12054
12055
    if (secretSz != ssl->buffers.dtlsCookieSecret.length) {
12056
        byte* newSecret;
12057
12058
        if (ssl->buffers.dtlsCookieSecret.buffer != NULL) {
12059
            ForceZero(ssl->buffers.dtlsCookieSecret.buffer,
12060
                      ssl->buffers.dtlsCookieSecret.length);
12061
            XFREE(ssl->buffers.dtlsCookieSecret.buffer,
12062
                  ssl->heap, DYNAMIC_TYPE_NONE);
12063
        }
12064
12065
        newSecret = (byte*)XMALLOC(secretSz, ssl->heap,DYNAMIC_TYPE_COOKIE_PWD);
12066
        if (newSecret == NULL) {
12067
            ssl->buffers.dtlsCookieSecret.buffer = NULL;
12068
            ssl->buffers.dtlsCookieSecret.length = 0;
12069
            WOLFSSL_MSG("couldn't allocate new cookie secret");
12070
            return MEMORY_ERROR;
12071
        }
12072
        ssl->buffers.dtlsCookieSecret.buffer = newSecret;
12073
        ssl->buffers.dtlsCookieSecret.length = secretSz;
12074
    #ifdef WOLFSSL_CHECK_MEM_ZERO
12075
        wc_MemZero_Add("wolfSSL_DTLS_SetCookieSecret secret",
12076
            ssl->buffers.dtlsCookieSecret.buffer,
12077
            ssl->buffers.dtlsCookieSecret.length);
12078
    #endif
12079
    }
12080
12081
    /* If the supplied secret is NULL, randomly generate a new secret. */
12082
    if (secret == NULL) {
12083
        ret = wc_RNG_GenerateBlock(ssl->rng,
12084
                             ssl->buffers.dtlsCookieSecret.buffer, secretSz);
12085
    }
12086
    else
12087
        XMEMCPY(ssl->buffers.dtlsCookieSecret.buffer, secret, secretSz);
12088
12089
    WOLFSSL_LEAVE("wolfSSL_DTLS_SetCookieSecret", 0);
12090
    return ret;
12091
}
12092
12093
#endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
12094
12095
12096
/* EITHER SIDE METHODS */
12097
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
12098
    WOLFSSL_METHOD* wolfSSLv23_method(void)
12099
0
    {
12100
0
        return wolfSSLv23_method_ex(NULL);
12101
0
    }
12102
    WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap)
12103
0
    {
12104
0
        WOLFSSL_METHOD* m = NULL;
12105
0
        WOLFSSL_ENTER("SSLv23_method");
12106
0
    #if !defined(NO_WOLFSSL_CLIENT)
12107
0
        m = wolfSSLv23_client_method_ex(heap);
12108
    #elif !defined(NO_WOLFSSL_SERVER)
12109
        m = wolfSSLv23_server_method_ex(heap);
12110
    #else
12111
        (void)heap;
12112
    #endif
12113
0
        if (m != NULL) {
12114
0
            m->side = WOLFSSL_NEITHER_END;
12115
0
        }
12116
12117
0
        return m;
12118
0
    }
12119
12120
    #ifdef WOLFSSL_ALLOW_SSLV3
12121
    WOLFSSL_METHOD* wolfSSLv3_method(void)
12122
    {
12123
        return wolfSSLv3_method_ex(NULL);
12124
    }
12125
    WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap)
12126
    {
12127
        WOLFSSL_METHOD* m = NULL;
12128
        WOLFSSL_ENTER("SSLv3_method");
12129
    #if !defined(NO_WOLFSSL_CLIENT)
12130
        m = wolfSSLv3_client_method_ex(heap);
12131
    #elif !defined(NO_WOLFSSL_SERVER)
12132
        m = wolfSSLv3_server_method_ex(heap);
12133
    #endif
12134
        if (m != NULL) {
12135
            m->side = WOLFSSL_NEITHER_END;
12136
        }
12137
12138
        return m;
12139
    }
12140
    #endif
12141
#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
12142
12143
/* client only parts */
12144
#ifndef NO_WOLFSSL_CLIENT
12145
12146
    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
12147
    WOLFSSL_METHOD* wolfSSLv2_client_method(void)
12148
0
    {
12149
0
        WOLFSSL_STUB("wolfSSLv2_client_method");
12150
0
        return NULL;
12151
0
    }
12152
    #endif
12153
12154
    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
12155
    WOLFSSL_METHOD* wolfSSLv3_client_method(void)
12156
    {
12157
        return wolfSSLv3_client_method_ex(NULL);
12158
    }
12159
    WOLFSSL_METHOD* wolfSSLv3_client_method_ex(void* heap)
12160
    {
12161
        WOLFSSL_METHOD* method =
12162
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12163
                                                     heap, DYNAMIC_TYPE_METHOD);
12164
        (void)heap;
12165
        WOLFSSL_ENTER("SSLv3_client_method_ex");
12166
        if (method)
12167
            InitSSL_Method(method, MakeSSLv3());
12168
        return method;
12169
    }
12170
    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
12171
12172
12173
    WOLFSSL_METHOD* wolfSSLv23_client_method(void)
12174
0
    {
12175
0
        return wolfSSLv23_client_method_ex(NULL);
12176
0
    }
12177
    WOLFSSL_METHOD* wolfSSLv23_client_method_ex(void* heap)
12178
0
    {
12179
0
        WOLFSSL_METHOD* method =
12180
0
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12181
0
                                                     heap, DYNAMIC_TYPE_METHOD);
12182
0
        (void)heap;
12183
0
        WOLFSSL_ENTER("SSLv23_client_method_ex");
12184
0
        if (method) {
12185
0
    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
12186
0
        #if defined(WOLFSSL_TLS13)
12187
0
            InitSSL_Method(method, MakeTLSv1_3());
12188
        #elif !defined(WOLFSSL_NO_TLS12)
12189
            InitSSL_Method(method, MakeTLSv1_2());
12190
        #elif !defined(NO_OLD_TLS)
12191
            InitSSL_Method(method, MakeTLSv1_1());
12192
        #endif
12193
    #else
12194
        #ifndef NO_OLD_TLS
12195
            InitSSL_Method(method, MakeTLSv1_1());
12196
        #endif
12197
    #endif
12198
0
    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
12199
0
            method->downgrade = 1;
12200
0
    #endif
12201
0
        }
12202
0
        return method;
12203
0
    }
12204
12205
    /* please see note at top of README if you get an error from connect */
12206
    WOLFSSL_ABI
12207
    int wolfSSL_connect(WOLFSSL* ssl)
12208
0
    {
12209
0
    #if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
12210
0
        int neededState;
12211
0
        byte advanceState;
12212
0
    #endif
12213
0
        int ret = 0;
12214
12215
0
        (void)ret;
12216
12217
0
        #ifdef HAVE_ERRNO_H
12218
0
            errno = 0;
12219
0
        #endif
12220
12221
0
        if (ssl == NULL)
12222
0
            return BAD_FUNC_ARG;
12223
12224
0
    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
12225
0
        if (ssl->options.side == WOLFSSL_NEITHER_END) {
12226
0
            ssl->error = InitSSL_Side(ssl, WOLFSSL_CLIENT_END);
12227
0
            if (ssl->error != WOLFSSL_SUCCESS) {
12228
0
                WOLFSSL_ERROR(ssl->error);
12229
0
                return WOLFSSL_FATAL_ERROR;
12230
0
            }
12231
0
            ssl->error = 0; /* expected to be zero here */
12232
0
        }
12233
12234
0
    #ifdef OPENSSL_EXTRA
12235
0
        if (ssl->CBIS != NULL) {
12236
0
            ssl->CBIS(ssl, SSL_ST_CONNECT, WOLFSSL_SUCCESS);
12237
0
            ssl->cbmode = SSL_CB_WRITE;
12238
0
        }
12239
0
    #endif
12240
0
    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
12241
12242
    #if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
12243
        return wolfSSL_connect_TLSv13(ssl);
12244
    #else
12245
0
        #ifdef WOLFSSL_TLS13
12246
0
        if (ssl->options.tls1_3)
12247
0
            return wolfSSL_connect_TLSv13(ssl);
12248
0
        #endif
12249
12250
0
        WOLFSSL_ENTER("SSL_connect()");
12251
12252
        /* make sure this wolfSSL object has arrays and rng setup. Protects
12253
         * case where the WOLFSSL object is re-used via wolfSSL_clear() */
12254
0
        if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
12255
0
            return ret;
12256
0
        }
12257
12258
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
12259
        if ((ssl->ConnectFilter != NULL) &&
12260
            (ssl->options.connectState == CONNECT_BEGIN)) {
12261
            wolfSSL_netfilter_decision_t res;
12262
            if ((ssl->ConnectFilter(ssl, ssl->ConnectFilter_arg, &res) ==
12263
                 WOLFSSL_SUCCESS) &&
12264
                (res == WOLFSSL_NETFILTER_REJECT)) {
12265
                ssl->error = SOCKET_FILTERED_E;
12266
                WOLFSSL_ERROR(ssl->error);
12267
                return WOLFSSL_FATAL_ERROR;
12268
            }
12269
        }
12270
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
12271
12272
0
        if (ssl->options.side != WOLFSSL_CLIENT_END) {
12273
0
            ssl->error = SIDE_ERROR;
12274
0
            WOLFSSL_ERROR(ssl->error);
12275
0
            return WOLFSSL_FATAL_ERROR;
12276
0
        }
12277
12278
        #ifdef WOLFSSL_DTLS
12279
        if (ssl->version.major == DTLS_MAJOR) {
12280
            ssl->options.dtls   = 1;
12281
            ssl->options.tls    = 1;
12282
            ssl->options.tls1_1 = 1;
12283
        }
12284
        #endif
12285
12286
        /* fragOffset is non-zero when sending fragments. On the last
12287
         * fragment, fragOffset is zero again, and the state can be
12288
         * advanced. */
12289
0
        advanceState = ssl->fragOffset == 0 &&
12290
0
            (ssl->options.connectState == CONNECT_BEGIN ||
12291
0
             ssl->options.connectState == HELLO_AGAIN ||
12292
0
             (ssl->options.connectState >= FIRST_REPLY_DONE &&
12293
0
              ssl->options.connectState <= FIRST_REPLY_FOURTH));
12294
12295
#ifdef WOLFSSL_DTLS13
12296
        if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version))
12297
            advanceState = advanceState && !ssl->dtls13SendingAckOrRtx;
12298
#endif /* WOLFSSL_DTLS13 */
12299
12300
0
        if (ssl->buffers.outputBuffer.length > 0
12301
        #ifdef WOLFSSL_ASYNC_CRYPT
12302
            /* do not send buffered or advance state if last error was an
12303
                async pending operation */
12304
            && ssl->error != WC_PENDING_E
12305
        #endif
12306
0
        ) {
12307
0
            ret = SendBuffered(ssl);
12308
0
            if (ret == 0) {
12309
0
                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
12310
0
                    if (advanceState) {
12311
0
                        ssl->options.connectState++;
12312
0
                        WOLFSSL_MSG("connect state: "
12313
0
                                    "Advanced from last buffered fragment send");
12314
0
                    #ifdef WOLFSSL_ASYNC_IO
12315
                        /* Cleanup async */
12316
0
                        FreeAsyncCtx(ssl, 0);
12317
0
                    #endif
12318
0
                    }
12319
0
                }
12320
0
                else {
12321
0
                    WOLFSSL_MSG("connect state: "
12322
0
                                "Not advanced, more fragments to send");
12323
0
                }
12324
0
            }
12325
0
            else {
12326
0
                ssl->error = ret;
12327
0
                WOLFSSL_ERROR(ssl->error);
12328
0
                return WOLFSSL_FATAL_ERROR;
12329
0
            }
12330
0
        }
12331
12332
0
        ret = RetrySendAlert(ssl);
12333
0
        if (ret != 0) {
12334
0
            ssl->error = ret;
12335
0
            WOLFSSL_ERROR(ssl->error);
12336
0
            return WOLFSSL_FATAL_ERROR;
12337
0
        }
12338
12339
0
        switch (ssl->options.connectState) {
12340
12341
0
        case CONNECT_BEGIN :
12342
            /* always send client hello first */
12343
0
            if ( (ssl->error = SendClientHello(ssl)) != 0) {
12344
0
                WOLFSSL_ERROR(ssl->error);
12345
0
                return WOLFSSL_FATAL_ERROR;
12346
0
            }
12347
0
            ssl->options.connectState = CLIENT_HELLO_SENT;
12348
0
            WOLFSSL_MSG("connect state: CLIENT_HELLO_SENT");
12349
0
            FALL_THROUGH;
12350
12351
0
        case CLIENT_HELLO_SENT :
12352
0
            neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
12353
0
                                          SERVER_HELLODONE_COMPLETE;
12354
            #ifdef WOLFSSL_DTLS
12355
                /* In DTLS, when resuming, we can go straight to FINISHED,
12356
                 * or do a cookie exchange and then skip to FINISHED, assume
12357
                 * we need the cookie exchange first. */
12358
                if (IsDtlsNotSctpMode(ssl))
12359
                    neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
12360
            #endif
12361
            /* get response */
12362
0
            while (ssl->options.serverState < neededState) {
12363
0
                #ifdef WOLFSSL_TLS13
12364
0
                    if (ssl->options.tls1_3)
12365
0
                        return wolfSSL_connect_TLSv13(ssl);
12366
0
                #endif
12367
0
                if ( (ssl->error = ProcessReply(ssl)) < 0) {
12368
0
                    WOLFSSL_ERROR(ssl->error);
12369
0
                    return WOLFSSL_FATAL_ERROR;
12370
0
                }
12371
                /* if resumption failed, reset needed state */
12372
0
                else if (neededState == SERVER_FINISHED_COMPLETE)
12373
0
                    if (!ssl->options.resuming) {
12374
                    #ifdef WOLFSSL_DTLS
12375
                        if (IsDtlsNotSctpMode(ssl))
12376
                            neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
12377
                        else
12378
                    #endif
12379
0
                            neededState = SERVER_HELLODONE_COMPLETE;
12380
0
                    }
12381
#ifdef WOLFSSL_DTLS13
12382
12383
                if (ssl->options.dtls && IsAtLeastTLSv1_3(ssl->version)
12384
                    && ssl->dtls13Rtx.sendAcks == 1) {
12385
                    ssl->dtls13Rtx.sendAcks = 0;
12386
                    /* we aren't negotiated the version yet, so we aren't sure
12387
                     * the other end can speak v1.3. On the other side we have
12388
                     * received a unified records, assuming that the
12389
                     * ServerHello got lost, we will send an empty ACK. In case
12390
                     * the server is a DTLS with version less than 1.3, it
12391
                     * should just ignore the message */
12392
                    if ((ssl->error = SendDtls13Ack(ssl)) < 0) {
12393
                        if (ssl->error == WANT_WRITE)
12394
                            ssl->dtls13SendingAckOrRtx = 1;
12395
                        WOLFSSL_ERROR(ssl->error);
12396
                        return WOLFSSL_FATAL_ERROR;
12397
                    }
12398
                }
12399
12400
12401
#endif /* WOLFSSL_DTLS13 */
12402
0
            }
12403
12404
0
            ssl->options.connectState = HELLO_AGAIN;
12405
0
            WOLFSSL_MSG("connect state: HELLO_AGAIN");
12406
0
            FALL_THROUGH;
12407
12408
0
        case HELLO_AGAIN :
12409
0
            if (ssl->options.certOnly)
12410
0
                return WOLFSSL_SUCCESS;
12411
12412
0
        #ifdef WOLFSSL_TLS13
12413
0
            if (ssl->options.tls1_3)
12414
0
                return wolfSSL_connect_TLSv13(ssl);
12415
0
        #endif
12416
12417
            #ifdef WOLFSSL_DTLS
12418
            if (ssl->options.serverState ==
12419
                    SERVER_HELLOVERIFYREQUEST_COMPLETE) {
12420
                if (IsDtlsNotSctpMode(ssl)) {
12421
                    /* re-init hashes, exclude first hello and verify request */
12422
                    if ((ssl->error = InitHandshakeHashes(ssl)) != 0) {
12423
                        WOLFSSL_ERROR(ssl->error);
12424
                        return WOLFSSL_FATAL_ERROR;
12425
                    }
12426
                    if ( (ssl->error = SendClientHello(ssl)) != 0) {
12427
                        WOLFSSL_ERROR(ssl->error);
12428
                        return WOLFSSL_FATAL_ERROR;
12429
                    }
12430
                }
12431
            }
12432
            #endif
12433
12434
0
            ssl->options.connectState = HELLO_AGAIN_REPLY;
12435
0
            WOLFSSL_MSG("connect state: HELLO_AGAIN_REPLY");
12436
0
            FALL_THROUGH;
12437
12438
0
        case HELLO_AGAIN_REPLY :
12439
            #ifdef WOLFSSL_DTLS
12440
                if (IsDtlsNotSctpMode(ssl)) {
12441
                    neededState = ssl->options.resuming ?
12442
                           SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
12443
12444
                    /* get response */
12445
                    while (ssl->options.serverState < neededState) {
12446
                        if ( (ssl->error = ProcessReply(ssl)) < 0) {
12447
                            WOLFSSL_ERROR(ssl->error);
12448
                            return WOLFSSL_FATAL_ERROR;
12449
                        }
12450
                        /* if resumption failed, reset needed state */
12451
                        if (neededState == SERVER_FINISHED_COMPLETE) {
12452
                            if (!ssl->options.resuming)
12453
                                neededState = SERVER_HELLODONE_COMPLETE;
12454
                        }
12455
                    }
12456
                }
12457
            #endif
12458
12459
0
            ssl->options.connectState = FIRST_REPLY_DONE;
12460
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_DONE");
12461
0
            FALL_THROUGH;
12462
12463
0
        case FIRST_REPLY_DONE :
12464
0
            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
12465
0
                #ifdef WOLFSSL_TLS13
12466
0
                    if (ssl->options.tls1_3)
12467
0
                        return wolfSSL_connect_TLSv13(ssl);
12468
0
                #endif
12469
0
                if (ssl->options.sendVerify) {
12470
0
                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
12471
                    #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12472
                        ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12473
                    #endif
12474
0
                        WOLFSSL_ERROR(ssl->error);
12475
0
                        return WOLFSSL_FATAL_ERROR;
12476
0
                    }
12477
0
                    WOLFSSL_MSG("sent: certificate");
12478
0
                }
12479
12480
0
            #endif
12481
0
            ssl->options.connectState = FIRST_REPLY_FIRST;
12482
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_FIRST");
12483
0
            FALL_THROUGH;
12484
12485
0
        case FIRST_REPLY_FIRST :
12486
0
        #ifdef WOLFSSL_TLS13
12487
0
            if (ssl->options.tls1_3)
12488
0
                return wolfSSL_connect_TLSv13(ssl);
12489
0
        #endif
12490
0
            if (!ssl->options.resuming) {
12491
0
                if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
12492
                #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12493
                    ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12494
                #endif
12495
0
                    WOLFSSL_ERROR(ssl->error);
12496
0
                    return WOLFSSL_FATAL_ERROR;
12497
0
                }
12498
0
                WOLFSSL_MSG("sent: client key exchange");
12499
0
            }
12500
12501
0
            ssl->options.connectState = FIRST_REPLY_SECOND;
12502
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_SECOND");
12503
0
            FALL_THROUGH;
12504
12505
0
    #if !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
12506
0
        case FIRST_REPLY_SECOND :
12507
            /* CLIENT: Fail-safe for Server Authentication. */
12508
0
            if (!ssl->options.peerAuthGood) {
12509
0
                WOLFSSL_MSG("Server authentication did not happen");
12510
0
                ssl->error = NO_PEER_VERIFY;
12511
0
                return WOLFSSL_FATAL_ERROR;
12512
0
            }
12513
12514
0
            #if !defined(NO_CERTS) && !defined(WOLFSSL_NO_CLIENT_AUTH)
12515
0
                if (ssl->options.sendVerify) {
12516
0
                    if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
12517
                    #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12518
                        ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12519
                    #endif
12520
0
                        WOLFSSL_ERROR(ssl->error);
12521
0
                        return WOLFSSL_FATAL_ERROR;
12522
0
                    }
12523
0
                    WOLFSSL_MSG("sent: certificate verify");
12524
0
                }
12525
0
            #endif /* !NO_CERTS && !WOLFSSL_NO_CLIENT_AUTH */
12526
0
            ssl->options.connectState = FIRST_REPLY_THIRD;
12527
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_THIRD");
12528
0
            FALL_THROUGH;
12529
12530
0
        case FIRST_REPLY_THIRD :
12531
0
            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
12532
            #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12533
                ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12534
            #endif
12535
0
                WOLFSSL_ERROR(ssl->error);
12536
0
                return WOLFSSL_FATAL_ERROR;
12537
0
            }
12538
0
            WOLFSSL_MSG("sent: change cipher spec");
12539
0
            ssl->options.connectState = FIRST_REPLY_FOURTH;
12540
0
            WOLFSSL_MSG("connect state: FIRST_REPLY_FOURTH");
12541
0
            FALL_THROUGH;
12542
12543
0
        case FIRST_REPLY_FOURTH :
12544
0
            if ( (ssl->error = SendFinished(ssl)) != 0) {
12545
            #ifdef WOLFSSL_CHECK_ALERT_ON_ERR
12546
                ProcessReplyEx(ssl, 1); /* See if an alert was sent. */
12547
            #endif
12548
0
                WOLFSSL_ERROR(ssl->error);
12549
0
                return WOLFSSL_FATAL_ERROR;
12550
0
            }
12551
0
            WOLFSSL_MSG("sent: finished");
12552
0
            ssl->options.connectState = FINISHED_DONE;
12553
0
            WOLFSSL_MSG("connect state: FINISHED_DONE");
12554
0
            FALL_THROUGH;
12555
12556
#ifdef WOLFSSL_DTLS13
12557
        case WAIT_FINISHED_ACK:
12558
            ssl->options.connectState = FINISHED_DONE;
12559
            FALL_THROUGH;
12560
#endif /* WOLFSSL_DTLS13 */
12561
12562
0
        case FINISHED_DONE :
12563
            /* get response */
12564
0
            while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
12565
0
                if ( (ssl->error = ProcessReply(ssl)) < 0) {
12566
0
                    WOLFSSL_ERROR(ssl->error);
12567
0
                    return WOLFSSL_FATAL_ERROR;
12568
0
                }
12569
12570
0
            ssl->options.connectState = SECOND_REPLY_DONE;
12571
0
            WOLFSSL_MSG("connect state: SECOND_REPLY_DONE");
12572
0
            FALL_THROUGH;
12573
12574
0
        case SECOND_REPLY_DONE:
12575
0
        #ifndef NO_HANDSHAKE_DONE_CB
12576
0
            if (ssl->hsDoneCb) {
12577
0
                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
12578
0
                if (cbret < 0) {
12579
0
                    ssl->error = cbret;
12580
0
                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
12581
0
                    return WOLFSSL_FATAL_ERROR;
12582
0
                }
12583
0
            }
12584
0
        #endif /* NO_HANDSHAKE_DONE_CB */
12585
12586
0
            if (!ssl->options.dtls) {
12587
0
                if (!ssl->options.keepResources) {
12588
0
                    FreeHandshakeResources(ssl);
12589
0
                }
12590
0
            }
12591
        #ifdef WOLFSSL_DTLS
12592
            else {
12593
                ssl->options.dtlsHsRetain = 1;
12594
            }
12595
        #endif /* WOLFSSL_DTLS */
12596
12597
        #if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
12598
            /* This may be necessary in async so that we don't try to
12599
             * renegotiate again */
12600
            if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
12601
                ssl->secure_renegotiation->startScr = 0;
12602
            }
12603
        #endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
12604
0
        #if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
12605
            /* Free the remaining async context if not using it for crypto */
12606
0
            FreeAsyncCtx(ssl, 1);
12607
0
        #endif
12608
12609
0
            ssl->error = 0; /* clear the error */
12610
12611
0
            WOLFSSL_LEAVE("SSL_connect()", WOLFSSL_SUCCESS);
12612
0
            return WOLFSSL_SUCCESS;
12613
0
    #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS */
12614
12615
0
        default:
12616
0
            WOLFSSL_MSG("Unknown connect state ERROR");
12617
0
            return WOLFSSL_FATAL_ERROR; /* unknown connect state */
12618
0
        }
12619
0
    #endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS || !WOLFSSL_TLS13 */
12620
0
    }
12621
12622
#endif /* NO_WOLFSSL_CLIENT */
12623
12624
12625
/* server only parts */
12626
#ifndef NO_WOLFSSL_SERVER
12627
12628
    #if defined(OPENSSL_EXTRA) && !defined(NO_OLD_TLS)
12629
    WOLFSSL_METHOD* wolfSSLv2_server_method(void)
12630
0
    {
12631
0
        WOLFSSL_STUB("wolfSSLv2_server_method");
12632
0
        return 0;
12633
0
    }
12634
    #endif
12635
12636
    #if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
12637
    WOLFSSL_METHOD* wolfSSLv3_server_method(void)
12638
    {
12639
        return wolfSSLv3_server_method_ex(NULL);
12640
    }
12641
    WOLFSSL_METHOD* wolfSSLv3_server_method_ex(void* heap)
12642
    {
12643
        WOLFSSL_METHOD* method =
12644
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12645
                                                     heap, DYNAMIC_TYPE_METHOD);
12646
        (void)heap;
12647
        WOLFSSL_ENTER("SSLv3_server_method_ex");
12648
        if (method) {
12649
            InitSSL_Method(method, MakeSSLv3());
12650
            method->side = WOLFSSL_SERVER_END;
12651
        }
12652
        return method;
12653
    }
12654
    #endif /* WOLFSSL_ALLOW_SSLV3 && !NO_OLD_TLS */
12655
12656
    WOLFSSL_METHOD* wolfSSLv23_server_method(void)
12657
0
    {
12658
0
        return wolfSSLv23_server_method_ex(NULL);
12659
0
    }
12660
12661
    WOLFSSL_METHOD* wolfSSLv23_server_method_ex(void* heap)
12662
0
    {
12663
0
        WOLFSSL_METHOD* method =
12664
0
                              (WOLFSSL_METHOD*) XMALLOC(sizeof(WOLFSSL_METHOD),
12665
0
                                                     heap, DYNAMIC_TYPE_METHOD);
12666
0
        (void)heap;
12667
0
        WOLFSSL_ENTER("SSLv23_server_method_ex");
12668
0
        if (method) {
12669
0
    #if !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
12670
0
        #ifdef WOLFSSL_TLS13
12671
0
            InitSSL_Method(method, MakeTLSv1_3());
12672
        #elif !defined(WOLFSSL_NO_TLS12)
12673
            InitSSL_Method(method, MakeTLSv1_2());
12674
        #elif !defined(NO_OLD_TLS)
12675
            InitSSL_Method(method, MakeTLSv1_1());
12676
        #endif
12677
    #else
12678
        #ifndef NO_OLD_TLS
12679
            InitSSL_Method(method, MakeTLSv1_1());
12680
        #else
12681
            #error Must have SHA256, SHA384 or SHA512 enabled for TLS 1.2
12682
        #endif
12683
    #endif
12684
0
    #if !defined(NO_OLD_TLS) || defined(WOLFSSL_TLS13)
12685
0
            method->downgrade = 1;
12686
0
    #endif
12687
0
            method->side      = WOLFSSL_SERVER_END;
12688
0
        }
12689
0
        return method;
12690
0
    }
12691
12692
12693
    WOLFSSL_ABI
12694
    int wolfSSL_accept(WOLFSSL* ssl)
12695
0
    {
12696
0
#if !(defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13))
12697
0
        word16 havePSK = 0;
12698
0
        word16 haveAnon = 0;
12699
0
        word16 haveMcast = 0;
12700
0
#endif
12701
0
        int ret = 0;
12702
12703
0
        (void)ret;
12704
12705
0
        if (ssl == NULL)
12706
0
            return WOLFSSL_FATAL_ERROR;
12707
12708
0
    #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EITHER_SIDE)
12709
0
        if (ssl->options.side == WOLFSSL_NEITHER_END) {
12710
0
            WOLFSSL_MSG("Setting WOLFSSL_SSL to be server side");
12711
0
            ssl->error = InitSSL_Side(ssl, WOLFSSL_SERVER_END);
12712
0
            if (ssl->error != WOLFSSL_SUCCESS) {
12713
0
                WOLFSSL_ERROR(ssl->error);
12714
0
                return WOLFSSL_FATAL_ERROR;
12715
0
            }
12716
0
            ssl->error = 0; /* expected to be zero here */
12717
0
        }
12718
0
    #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */
12719
12720
#if defined(WOLFSSL_NO_TLS12) && defined(NO_OLD_TLS) && defined(WOLFSSL_TLS13)
12721
        return wolfSSL_accept_TLSv13(ssl);
12722
#else
12723
0
    #ifdef WOLFSSL_TLS13
12724
0
        if (ssl->options.tls1_3)
12725
0
            return wolfSSL_accept_TLSv13(ssl);
12726
0
    #endif
12727
0
        WOLFSSL_ENTER("SSL_accept()");
12728
12729
        /* make sure this wolfSSL object has arrays and rng setup. Protects
12730
         * case where the WOLFSSL object is re-used via wolfSSL_clear() */
12731
0
        if ((ret = ReinitSSL(ssl, ssl->ctx, 0)) != 0) {
12732
0
            return ret;
12733
0
        }
12734
12735
#ifdef WOLFSSL_WOLFSENTRY_HOOKS
12736
        if ((ssl->AcceptFilter != NULL) &&
12737
            ((ssl->options.acceptState == ACCEPT_BEGIN)
12738
#ifdef HAVE_SECURE_RENEGOTIATION
12739
             || (ssl->options.acceptState == ACCEPT_BEGIN_RENEG)
12740
#endif
12741
                ))
12742
        {
12743
            wolfSSL_netfilter_decision_t res;
12744
            if ((ssl->AcceptFilter(ssl, ssl->AcceptFilter_arg, &res) ==
12745
                 WOLFSSL_SUCCESS) &&
12746
                (res == WOLFSSL_NETFILTER_REJECT)) {
12747
                ssl->error = SOCKET_FILTERED_E;
12748
                WOLFSSL_ERROR(ssl->error);
12749
                return WOLFSSL_FATAL_ERROR;
12750
            }
12751
        }
12752
#endif /* WOLFSSL_WOLFSENTRY_HOOKS */
12753
12754
0
        #ifdef HAVE_ERRNO_H
12755
0
            errno = 0;
12756
0
        #endif
12757
12758
        #ifndef NO_PSK
12759
            havePSK = ssl->options.havePSK;
12760
        #endif
12761
0
        (void)havePSK;
12762
12763
        #ifdef HAVE_ANON
12764
            haveAnon = ssl->options.haveAnon;
12765
        #endif
12766
0
        (void)haveAnon;
12767
12768
        #ifdef WOLFSSL_MULTICAST
12769
            haveMcast = ssl->options.haveMcast;
12770
        #endif
12771
0
        (void)haveMcast;
12772
12773
0
        if (ssl->options.side != WOLFSSL_SERVER_END) {
12774
0
            ssl->error = SIDE_ERROR;
12775
0
            WOLFSSL_ERROR(ssl->error);
12776
0
            return WOLFSSL_FATAL_ERROR;
12777
0
        }
12778
12779
0
    #ifndef NO_CERTS
12780
        /* in case used set_accept_state after init */
12781
0
        if (!havePSK && !haveAnon && !haveMcast) {
12782
0
        #ifdef OPENSSL_EXTRA
12783
0
            if (ssl->ctx->certSetupCb != NULL) {
12784
0
                WOLFSSL_MSG("CertSetupCb set. server cert and "
12785
0
                            "key not checked");
12786
0
            }
12787
0
            else
12788
0
        #endif
12789
0
            {
12790
0
                if (!ssl->buffers.certificate ||
12791
0
                    !ssl->buffers.certificate->buffer) {
12792
12793
0
                    WOLFSSL_MSG("accept error: server cert required");
12794
0
                    ssl->error = NO_PRIVATE_KEY;
12795
0
                    WOLFSSL_ERROR(ssl->error);
12796
0
                    return WOLFSSL_FATAL_ERROR;
12797
0
                }
12798
12799
0
                if (!ssl->buffers.key || !ssl->buffers.key->buffer) {
12800
                    /* allow no private key if using existing key */
12801
0
                #ifdef WOLF_PRIVATE_KEY_ID
12802
0
                    if (ssl->devId != INVALID_DEVID
12803
                    #ifdef HAVE_PK_CALLBACKS
12804
                        || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)
12805
                    #endif
12806
0
                    ) {
12807
0
                        WOLFSSL_MSG("Allowing no server private key "
12808
0
                                    "(external)");
12809
0
                    }
12810
0
                    else
12811
0
                #endif
12812
0
                    {
12813
0
                        WOLFSSL_MSG("accept error: server key required");
12814
0
                        ssl->error = NO_PRIVATE_KEY;
12815
0
                        WOLFSSL_ERROR(ssl->error);
12816
0
                        return WOLFSSL_FATAL_ERROR;
12817
0
                    }
12818
0
                }
12819
0
            }
12820
0
        }
12821
0
    #endif
12822
12823
    #ifdef WOLFSSL_DTLS
12824
        if (ssl->version.major == DTLS_MAJOR) {
12825
            ssl->options.dtls   = 1;
12826
            ssl->options.tls    = 1;
12827
            ssl->options.tls1_1 = 1;
12828
        }
12829
    #endif
12830
12831
0
        if (ssl->buffers.outputBuffer.length > 0
12832
        #ifdef WOLFSSL_ASYNC_CRYPT
12833
            /* do not send buffered or advance state if last error was an
12834
                async pending operation */
12835
            && ssl->error != WC_PENDING_E
12836
        #endif
12837
0
        ) {
12838
0
            ret = SendBuffered(ssl);
12839
0
            if (ret == 0) {
12840
                /* fragOffset is non-zero when sending fragments. On the last
12841
                 * fragment, fragOffset is zero again, and the state can be
12842
                 * advanced. */
12843
0
                if (ssl->fragOffset == 0 && !ssl->options.buildingMsg) {
12844
0
                    if (ssl->options.acceptState == ACCEPT_FIRST_REPLY_DONE ||
12845
0
                        ssl->options.acceptState == SERVER_HELLO_SENT ||
12846
0
                        ssl->options.acceptState == CERT_SENT ||
12847
0
                        ssl->options.acceptState == CERT_STATUS_SENT ||
12848
0
                        ssl->options.acceptState == KEY_EXCHANGE_SENT ||
12849
0
                        ssl->options.acceptState == CERT_REQ_SENT ||
12850
0
                        ssl->options.acceptState == ACCEPT_SECOND_REPLY_DONE ||
12851
0
                        ssl->options.acceptState == TICKET_SENT ||
12852
0
                        ssl->options.acceptState == CHANGE_CIPHER_SENT) {
12853
0
                        ssl->options.acceptState++;
12854
0
                        WOLFSSL_MSG("accept state: "
12855
0
                                    "Advanced from last buffered fragment send");
12856
0
                    #ifdef WOLFSSL_ASYNC_IO
12857
                        /* Cleanup async */
12858
0
                        FreeAsyncCtx(ssl, 0);
12859
0
                    #endif
12860
0
                    }
12861
0
                }
12862
0
                else {
12863
0
                    WOLFSSL_MSG("accept state: "
12864
0
                                "Not advanced, more fragments to send");
12865
0
                }
12866
0
            }
12867
0
            else {
12868
0
                ssl->error = ret;
12869
0
                WOLFSSL_ERROR(ssl->error);
12870
0
                return WOLFSSL_FATAL_ERROR;
12871
0
            }
12872
0
        }
12873
12874
0
        ret = RetrySendAlert(ssl);
12875
0
        if (ret != 0) {
12876
0
            ssl->error = ret;
12877
0
            WOLFSSL_ERROR(ssl->error);
12878
0
            return WOLFSSL_FATAL_ERROR;
12879
0
        }
12880
12881
0
        switch (ssl->options.acceptState) {
12882
12883
0
        case ACCEPT_BEGIN :
12884
#ifdef HAVE_SECURE_RENEGOTIATION
12885
        case ACCEPT_BEGIN_RENEG:
12886
#endif
12887
            /* get response */
12888
0
            while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
12889
0
                if ( (ssl->error = ProcessReply(ssl)) < 0) {
12890
0
                    WOLFSSL_ERROR(ssl->error);
12891
0
                    return WOLFSSL_FATAL_ERROR;
12892
0
                }
12893
0
#ifdef WOLFSSL_TLS13
12894
0
            ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
12895
0
            WOLFSSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
12896
0
            FALL_THROUGH;
12897
12898
0
        case ACCEPT_CLIENT_HELLO_DONE :
12899
0
            if (ssl->options.tls1_3) {
12900
0
                return wolfSSL_accept_TLSv13(ssl);
12901
0
            }
12902
0
#endif
12903
12904
#ifdef WOLFSSL_DTLS
12905
            if (ssl->chGoodCb != NULL && !IsSCR(ssl)) {
12906
                int cbret = ssl->chGoodCb(ssl, ssl->chGoodCtx);
12907
                if (cbret < 0) {
12908
                    ssl->error = cbret;
12909
                    WOLFSSL_MSG("ClientHello Good Cb don't continue error");
12910
                    return WOLFSSL_FATAL_ERROR;
12911
                }
12912
            }
12913
#endif
12914
12915
0
            ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
12916
0
            WOLFSSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
12917
0
            FALL_THROUGH;
12918
12919
0
        case ACCEPT_FIRST_REPLY_DONE :
12920
0
            if ( (ssl->error = SendServerHello(ssl)) != 0) {
12921
0
                WOLFSSL_ERROR(ssl->error);
12922
0
                return WOLFSSL_FATAL_ERROR;
12923
0
            }
12924
0
            ssl->options.acceptState = SERVER_HELLO_SENT;
12925
0
            WOLFSSL_MSG("accept state SERVER_HELLO_SENT");
12926
0
            FALL_THROUGH;
12927
12928
0
        case SERVER_HELLO_SENT :
12929
0
        #ifdef WOLFSSL_TLS13
12930
0
            if (ssl->options.tls1_3) {
12931
0
                return wolfSSL_accept_TLSv13(ssl);
12932
0
            }
12933
0
        #endif
12934
0
            #ifndef NO_CERTS
12935
0
                if (!ssl->options.resuming)
12936
0
                    if ( (ssl->error = SendCertificate(ssl)) != 0) {
12937
0
                        WOLFSSL_ERROR(ssl->error);
12938
0
                        return WOLFSSL_FATAL_ERROR;
12939
0
                    }
12940
0
            #endif
12941
0
            ssl->options.acceptState = CERT_SENT;
12942
0
            WOLFSSL_MSG("accept state CERT_SENT");
12943
0
            FALL_THROUGH;
12944
12945
0
        case CERT_SENT :
12946
0
            #ifndef NO_CERTS
12947
0
            if (!ssl->options.resuming)
12948
0
                if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
12949
0
                    WOLFSSL_ERROR(ssl->error);
12950
0
                    return WOLFSSL_FATAL_ERROR;
12951
0
                }
12952
0
            #endif
12953
0
            ssl->options.acceptState = CERT_STATUS_SENT;
12954
0
            WOLFSSL_MSG("accept state CERT_STATUS_SENT");
12955
0
            FALL_THROUGH;
12956
12957
0
        case CERT_STATUS_SENT :
12958
0
        #ifdef WOLFSSL_TLS13
12959
0
            if (ssl->options.tls1_3) {
12960
0
                return wolfSSL_accept_TLSv13(ssl);
12961
0
            }
12962
0
        #endif
12963
0
            if (!ssl->options.resuming)
12964
0
                if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
12965
0
                    WOLFSSL_ERROR(ssl->error);
12966
0
                    return WOLFSSL_FATAL_ERROR;
12967
0
                }
12968
0
            ssl->options.acceptState = KEY_EXCHANGE_SENT;
12969
0
            WOLFSSL_MSG("accept state KEY_EXCHANGE_SENT");
12970
0
            FALL_THROUGH;
12971
12972
0
        case KEY_EXCHANGE_SENT :
12973
0
            #ifndef NO_CERTS
12974
0
                if (!ssl->options.resuming) {
12975
0
                    if (ssl->options.verifyPeer) {
12976
0
                        if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
12977
0
                            WOLFSSL_ERROR(ssl->error);
12978
0
                            return WOLFSSL_FATAL_ERROR;
12979
0
                        }
12980
0
                    }
12981
0
                    else {
12982
                        /* SERVER: Peer auth good if not verifying client. */
12983
0
                        ssl->options.peerAuthGood = 1;
12984
0
                    }
12985
0
                }
12986
0
            #endif
12987
0
            ssl->options.acceptState = CERT_REQ_SENT;
12988
0
            WOLFSSL_MSG("accept state CERT_REQ_SENT");
12989
0
            FALL_THROUGH;
12990
12991
0
        case CERT_REQ_SENT :
12992
0
            if (!ssl->options.resuming)
12993
0
                if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
12994
0
                    WOLFSSL_ERROR(ssl->error);
12995
0
                    return WOLFSSL_FATAL_ERROR;
12996
0
                }
12997
0
            ssl->options.acceptState = SERVER_HELLO_DONE;
12998
0
            WOLFSSL_MSG("accept state SERVER_HELLO_DONE");
12999
0
            FALL_THROUGH;
13000
13001
0
        case SERVER_HELLO_DONE :
13002
0
            if (!ssl->options.resuming) {
13003
0
                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
13004
0
                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
13005
0
                        WOLFSSL_ERROR(ssl->error);
13006
0
                        return WOLFSSL_FATAL_ERROR;
13007
0
                    }
13008
0
            }
13009
0
            ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
13010
0
            WOLFSSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
13011
0
            FALL_THROUGH;
13012
13013
0
        case ACCEPT_SECOND_REPLY_DONE :
13014
0
        #ifndef NO_CERTS
13015
            /* SERVER: When not resuming and verifying peer but no certificate
13016
             * received and not failing when not received then peer auth good.
13017
             */
13018
0
            if (!ssl->options.resuming && ssl->options.verifyPeer &&
13019
0
                !ssl->options.havePeerCert && !ssl->options.failNoCert) {
13020
0
                ssl->options.peerAuthGood = 1;
13021
0
            }
13022
0
        #endif /* !NO_CERTS  */
13023
        #ifdef WOLFSSL_NO_CLIENT_AUTH
13024
            if (!ssl->options.resuming) {
13025
                ssl->options.peerAuthGood = 1;
13026
            }
13027
        #endif
13028
13029
0
#ifdef HAVE_SESSION_TICKET
13030
0
            if (ssl->options.createTicket && !ssl->options.noTicketTls12) {
13031
0
                if ( (ssl->error = SendTicket(ssl)) != 0) {
13032
0
                    WOLFSSL_ERROR(ssl->error);
13033
0
                    return WOLFSSL_FATAL_ERROR;
13034
0
                }
13035
0
            }
13036
0
#endif /* HAVE_SESSION_TICKET */
13037
0
            ssl->options.acceptState = TICKET_SENT;
13038
0
            WOLFSSL_MSG("accept state  TICKET_SENT");
13039
0
            FALL_THROUGH;
13040
13041
0
        case TICKET_SENT:
13042
            /* SERVER: Fail-safe for CLient Authentication. */
13043
0
            if (!ssl->options.peerAuthGood) {
13044
0
                WOLFSSL_MSG("Client authentication did not happen");
13045
0
                return WOLFSSL_FATAL_ERROR;
13046
0
            }
13047
13048
0
            if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
13049
0
                WOLFSSL_ERROR(ssl->error);
13050
0
                return WOLFSSL_FATAL_ERROR;
13051
0
            }
13052
0
            ssl->options.acceptState = CHANGE_CIPHER_SENT;
13053
0
            WOLFSSL_MSG("accept state  CHANGE_CIPHER_SENT");
13054
0
            FALL_THROUGH;
13055
13056
0
        case CHANGE_CIPHER_SENT :
13057
0
            if ( (ssl->error = SendFinished(ssl)) != 0) {
13058
0
                WOLFSSL_ERROR(ssl->error);
13059
0
                return WOLFSSL_FATAL_ERROR;
13060
0
            }
13061
13062
0
            ssl->options.acceptState = ACCEPT_FINISHED_DONE;
13063
0
            WOLFSSL_MSG("accept state ACCEPT_FINISHED_DONE");
13064
0
            FALL_THROUGH;
13065
13066
0
        case ACCEPT_FINISHED_DONE :
13067
0
            if (ssl->options.resuming) {
13068
0
                while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE) {
13069
0
                    if ( (ssl->error = ProcessReply(ssl)) < 0) {
13070
0
                        WOLFSSL_ERROR(ssl->error);
13071
0
                        return WOLFSSL_FATAL_ERROR;
13072
0
                    }
13073
0
                }
13074
0
            }
13075
0
            ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
13076
0
            WOLFSSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
13077
0
            FALL_THROUGH;
13078
13079
0
        case ACCEPT_THIRD_REPLY_DONE :
13080
0
#ifndef NO_HANDSHAKE_DONE_CB
13081
0
            if (ssl->hsDoneCb) {
13082
0
                int cbret = ssl->hsDoneCb(ssl, ssl->hsDoneCtx);
13083
0
                if (cbret < 0) {
13084
0
                    ssl->error = cbret;
13085
0
                    WOLFSSL_MSG("HandShake Done Cb don't continue error");
13086
0
                    return WOLFSSL_FATAL_ERROR;
13087
0
                }
13088
0
            }
13089
0
#endif /* NO_HANDSHAKE_DONE_CB */
13090
13091
0
            if (!ssl->options.dtls) {
13092
0
                if (!ssl->options.keepResources) {
13093
0
                    FreeHandshakeResources(ssl);
13094
0
                }
13095
0
            }
13096
#ifdef WOLFSSL_DTLS
13097
            else {
13098
                ssl->options.dtlsHsRetain = 1;
13099
            }
13100
#endif /* WOLFSSL_DTLS */
13101
13102
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(HAVE_SECURE_RENEGOTIATION)
13103
            /* This may be necessary in async so that we don't try to
13104
             * renegotiate again */
13105
            if (ssl->secure_renegotiation && ssl->secure_renegotiation->startScr) {
13106
                ssl->secure_renegotiation->startScr = 0;
13107
            }
13108
#endif /* WOLFSSL_ASYNC_CRYPT && HAVE_SECURE_RENEGOTIATION */
13109
0
#if defined(WOLFSSL_ASYNC_IO) && !defined(WOLFSSL_ASYNC_CRYPT)
13110
            /* Free the remaining async context if not using it for crypto */
13111
0
            FreeAsyncCtx(ssl, 1);
13112
0
#endif
13113
13114
#if defined(WOLFSSL_SESSION_EXPORT) && defined(WOLFSSL_DTLS)
13115
            if (ssl->dtls_export) {
13116
                if ((ssl->error = wolfSSL_send_session(ssl)) != 0) {
13117
                    WOLFSSL_MSG("Export DTLS session error");
13118
                    WOLFSSL_ERROR(ssl->error);
13119
                    return WOLFSSL_FATAL_ERROR;
13120
                }
13121
            }
13122
#endif
13123
0
            ssl->error = 0; /* clear the error */
13124
13125
0
            WOLFSSL_LEAVE("SSL_accept()", WOLFSSL_SUCCESS);
13126
0
            return WOLFSSL_SUCCESS;
13127
13128
0
        default :
13129
0
            WOLFSSL_MSG("Unknown accept state ERROR");
13130
0
            return WOLFSSL_FATAL_ERROR;
13131
0
        }
13132
0
#endif /* !WOLFSSL_NO_TLS12 */
13133
0
    }
13134
13135
#endif /* NO_WOLFSSL_SERVER */
13136
13137
#if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
13138
int wolfDTLS_SetChGoodCb(WOLFSSL* ssl, ClientHelloGoodCb cb, void* user_ctx)
13139
{
13140
    WOLFSSL_ENTER("wolfDTLS_SetChGoodCb");
13141
13142
    if (ssl == NULL)
13143
        return BAD_FUNC_ARG;
13144
13145
    ssl->chGoodCb  = cb;
13146
    ssl->chGoodCtx = user_ctx;
13147
13148
    return WOLFSSL_SUCCESS;
13149
}
13150
#endif
13151
13152
#ifndef NO_HANDSHAKE_DONE_CB
13153
13154
int wolfSSL_SetHsDoneCb(WOLFSSL* ssl, HandShakeDoneCb cb, void* user_ctx)
13155
0
{
13156
0
    WOLFSSL_ENTER("wolfSSL_SetHsDoneCb");
13157
13158
0
    if (ssl == NULL)
13159
0
        return BAD_FUNC_ARG;
13160
13161
0
    ssl->hsDoneCb  = cb;
13162
0
    ssl->hsDoneCtx = user_ctx;
13163
13164
13165
0
    return WOLFSSL_SUCCESS;
13166
0
}
13167
13168
#endif /* NO_HANDSHAKE_DONE_CB */
13169
13170
WOLFSSL_ABI
13171
int wolfSSL_Cleanup(void)
13172
0
{
13173
0
    int ret = WOLFSSL_SUCCESS; /* Only the first error will be returned */
13174
0
    int release = 0;
13175
#if !defined(NO_SESSION_CACHE) && defined(ENABLE_SESSION_CACHE_ROW_LOCK)
13176
    int i;
13177
#endif
13178
13179
0
    WOLFSSL_ENTER("wolfSSL_Cleanup");
13180
13181
0
    if (initRefCount == 0)
13182
0
        return ret;  /* possibly no init yet, but not failure either way */
13183
13184
0
    if ((count_mutex_valid == 1) && (wc_LockMutex(&count_mutex) != 0)) {
13185
0
        WOLFSSL_MSG("Bad Lock Mutex count");
13186
0
        ret = BAD_MUTEX_E;
13187
0
    }
13188
13189
0
    release = initRefCount-- == 1;
13190
0
    if (initRefCount < 0)
13191
0
        initRefCount = 0;
13192
13193
0
    if (count_mutex_valid == 1) {
13194
0
        wc_UnLockMutex(&count_mutex);
13195
0
    }
13196
13197
0
    if (!release)
13198
0
        return ret;
13199
13200
0
#ifdef OPENSSL_EXTRA
13201
0
    if (bn_one) {
13202
0
        wolfSSL_BN_free(bn_one);
13203
0
        bn_one = NULL;
13204
0
    }
13205
0
#endif
13206
13207
0
#ifndef NO_SESSION_CACHE
13208
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
13209
    for (i = 0; i < SESSION_ROWS; ++i) {
13210
        if ((SessionCache[i].mutex_valid == 1) &&
13211
            (wc_FreeMutex(&SessionCache[i].row_mutex) != 0)) {
13212
            if (ret == WOLFSSL_SUCCESS)
13213
                ret = BAD_MUTEX_E;
13214
        }
13215
        SessionCache[i].mutex_valid = 0;
13216
    }
13217
    #else
13218
0
    if ((session_mutex_valid == 1) && (wc_FreeMutex(&session_mutex) != 0)) {
13219
0
        if (ret == WOLFSSL_SUCCESS)
13220
0
            ret = BAD_MUTEX_E;
13221
0
    }
13222
0
    session_mutex_valid = 0;
13223
0
    #endif
13224
0
    #ifndef NO_CLIENT_CACHE
13225
0
    if ((clisession_mutex_valid == 1) &&
13226
0
        (wc_FreeMutex(&clisession_mutex) != 0)) {
13227
0
        if (ret == WOLFSSL_SUCCESS)
13228
0
            ret = BAD_MUTEX_E;
13229
0
    }
13230
0
    clisession_mutex_valid = 0;
13231
0
    #endif
13232
0
#endif /* !NO_SESSION_CACHE */
13233
13234
0
    if ((count_mutex_valid == 1) && (wc_FreeMutex(&count_mutex) != 0)) {
13235
0
        if (ret == WOLFSSL_SUCCESS)
13236
0
            ret = BAD_MUTEX_E;
13237
0
    }
13238
0
    count_mutex_valid = 0;
13239
13240
0
#ifdef OPENSSL_EXTRA
13241
0
    wolfSSL_RAND_Cleanup();
13242
0
#endif
13243
13244
0
    if (wolfCrypt_Cleanup() != 0) {
13245
0
        WOLFSSL_MSG("Error with wolfCrypt_Cleanup call");
13246
0
        if (ret == WOLFSSL_SUCCESS)
13247
0
            ret = WC_CLEANUP_E;
13248
0
    }
13249
13250
#if FIPS_VERSION_GE(5,1)
13251
    if (wolfCrypt_SetPrivateKeyReadEnable_fips(0, WC_KEYTYPE_ALL) < 0) {
13252
        if (ret == WOLFSSL_SUCCESS)
13253
            ret = WC_CLEANUP_E;
13254
    }
13255
#endif
13256
13257
0
#ifdef HAVE_GLOBAL_RNG
13258
0
    if ((globalRNGMutex_valid == 1) && (wc_FreeMutex(&globalRNGMutex) != 0)) {
13259
0
        if (ret == WOLFSSL_SUCCESS)
13260
0
            ret = BAD_MUTEX_E;
13261
0
    }
13262
0
    globalRNGMutex_valid = 0;
13263
13264
0
    #if defined(OPENSSL_EXTRA) && defined(HAVE_HASHDRBG)
13265
0
    wolfSSL_FIPS_drbg_free(gDrbgDefCtx);
13266
0
    gDrbgDefCtx = NULL;
13267
0
    #endif
13268
0
#endif
13269
13270
0
    return ret;
13271
0
}
13272
13273
13274
#ifndef NO_SESSION_CACHE
13275
13276
WOLFSSL_ABI
13277
void wolfSSL_flush_sessions(WOLFSSL_CTX* ctx, long tm)
13278
0
{
13279
    /* static table now, no flushing needed */
13280
0
    (void)ctx;
13281
0
    (void)tm;
13282
0
}
13283
13284
13285
/* set ssl session timeout in seconds */
13286
WOLFSSL_ABI
13287
int wolfSSL_set_timeout(WOLFSSL* ssl, unsigned int to)
13288
0
{
13289
0
    if (ssl == NULL)
13290
0
        return BAD_FUNC_ARG;
13291
13292
0
    if (to == 0)
13293
0
        to = WOLFSSL_SESSION_TIMEOUT;
13294
0
    ssl->timeout = to;
13295
13296
0
    return WOLFSSL_SUCCESS;
13297
0
}
13298
13299
13300
/**
13301
 * Sets ctx session timeout in seconds.
13302
 * The timeout value set here should be reflected in the
13303
 * "session ticket lifetime hint" if this API works in the openssl compat-layer.
13304
 * Therefore wolfSSL_CTX_set_TicketHint is called internally.
13305
 * Arguments:
13306
 *  - ctx  WOLFSSL_CTX object which the timeout is set to
13307
 *  - to   timeout value in second
13308
 * Returns:
13309
 *  WOLFSSL_SUCCESS on success, BAD_FUNC_ARG on failure.
13310
 *  When WOLFSSL_ERROR_CODE_OPENSSL is defined, returns previous timeout value
13311
 *  on success, BAD_FUNC_ARG on failure.
13312
 */
13313
WOLFSSL_ABI
13314
int wolfSSL_CTX_set_timeout(WOLFSSL_CTX* ctx, unsigned int to)
13315
0
{
13316
0
    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
13317
0
    word32 prev_timeout = 0;
13318
0
    #endif
13319
13320
0
    int ret = WOLFSSL_SUCCESS;
13321
0
    (void)ret;
13322
13323
0
    if (ctx == NULL)
13324
0
        ret = BAD_FUNC_ARG;
13325
13326
0
    if (ret == WOLFSSL_SUCCESS) {
13327
0
    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
13328
0
        prev_timeout = ctx->timeout;
13329
0
    #endif
13330
0
        if (to == 0) {
13331
0
            ctx->timeout = WOLFSSL_SESSION_TIMEOUT;
13332
0
        }
13333
0
        else {
13334
0
            ctx->timeout = to;
13335
0
        }
13336
0
    }
13337
0
#if defined(OPENSSL_EXTRA) && defined(HAVE_SESSION_TICKET) && \
13338
0
   !defined(NO_WOLFSSL_SERVER)
13339
0
    if (ret == WOLFSSL_SUCCESS) {
13340
0
        if (to == 0) {
13341
0
            ret = wolfSSL_CTX_set_TicketHint(ctx, SESSION_TICKET_HINT_DEFAULT);
13342
0
        }
13343
0
        else {
13344
0
            ret = wolfSSL_CTX_set_TicketHint(ctx, to);
13345
0
        }
13346
0
    }
13347
0
#endif /* OPENSSL_EXTRA && HAVE_SESSION_TICKET && !NO_WOLFSSL_SERVER */
13348
13349
0
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
13350
0
    if (ret == WOLFSSL_SUCCESS) {
13351
0
        return prev_timeout;
13352
0
    }
13353
0
    else {
13354
0
        return ret;
13355
0
    }
13356
#else
13357
    return ret;
13358
#endif /* WOLFSSL_ERROR_CODE_OPENSSL */
13359
0
}
13360
13361
13362
#ifndef NO_CLIENT_CACHE
13363
13364
/* Get Session from Client cache based on id/len, return NULL on failure */
13365
WOLFSSL_SESSION* wolfSSL_GetSessionClient(WOLFSSL* ssl, const byte* id, int len)
13366
0
{
13367
0
    WOLFSSL_SESSION* ret = NULL;
13368
0
    word32          row;
13369
0
    int             idx;
13370
0
    int             count;
13371
0
    int             error = 0;
13372
0
    ClientSession*  clSess;
13373
13374
0
    WOLFSSL_ENTER("GetSessionClient");
13375
13376
0
    if (ssl->ctx->sessionCacheOff) {
13377
0
        WOLFSSL_MSG("Session Cache off");
13378
0
        return NULL;
13379
0
    }
13380
13381
0
    if (ssl->options.side == WOLFSSL_SERVER_END)
13382
0
        return NULL;
13383
13384
0
    len = min(SERVER_ID_LEN, (word32)len);
13385
13386
0
#ifdef HAVE_EXT_CACHE
13387
0
    if (ssl->ctx->get_sess_cb != NULL) {
13388
0
        int copy = 0;
13389
0
        WOLFSSL_MSG("Calling external session cache");
13390
0
        ret = ssl->ctx->get_sess_cb(ssl, (byte*)id, len, &copy);
13391
0
        if (ret != NULL) {
13392
0
            WOLFSSL_MSG("Session found in external cache");
13393
0
            return ret;
13394
0
        }
13395
0
        WOLFSSL_MSG("Session not found in external cache");
13396
0
    }
13397
13398
0
    if (ssl->ctx->internalCacheLookupOff) {
13399
0
        WOLFSSL_MSG("Internal cache turned off");
13400
0
        return NULL;
13401
0
    }
13402
0
#endif
13403
13404
0
    row = HashObject(id, len, &error) % CLIENT_SESSION_ROWS;
13405
0
    if (error != 0) {
13406
0
        WOLFSSL_MSG("Hash session failed");
13407
0
        return NULL;
13408
0
    }
13409
13410
0
    if (wc_LockMutex(&clisession_mutex) != 0) {
13411
0
        WOLFSSL_MSG("Client cache mutex lock failed");
13412
0
        return NULL;
13413
0
    }
13414
13415
    /* start from most recently used */
13416
0
    count = min((word32)ClientCache[row].totalCount, CLIENT_SESSIONS_PER_ROW);
13417
0
    idx = ClientCache[row].nextIdx - 1;
13418
0
    if (idx < 0 || idx >= CLIENT_SESSIONS_PER_ROW) {
13419
0
        idx = CLIENT_SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
13420
0
    }
13421
0
    clSess = ClientCache[row].Clients;
13422
13423
0
    for (; count > 0; --count) {
13424
0
        WOLFSSL_SESSION* current;
13425
0
        SessionRow* sessRow;
13426
13427
0
        if (clSess[idx].serverRow >= SESSION_ROWS) {
13428
0
            WOLFSSL_MSG("Client cache serverRow invalid");
13429
0
            break;
13430
0
        }
13431
13432
        /* lock row */
13433
0
        sessRow = &SessionCache[clSess[idx].serverRow];
13434
0
        if (SESSION_ROW_LOCK(sessRow) != 0) {
13435
0
            WOLFSSL_MSG("Session cache row lock failure");
13436
0
            break;
13437
0
        }
13438
13439
0
        current = &sessRow->Sessions[clSess[idx].serverIdx];
13440
0
        if (XMEMCMP(current->serverID, id, len) == 0) {
13441
0
            WOLFSSL_MSG("Found a serverid match for client");
13442
0
            if (LowResTimer() < (current->bornOn + current->timeout)) {
13443
0
                WOLFSSL_MSG("Session valid");
13444
0
                ret = current;
13445
0
                SESSION_ROW_UNLOCK(sessRow);
13446
0
                break;
13447
0
            } else {
13448
0
                WOLFSSL_MSG("Session timed out");  /* could have more for id */
13449
0
            }
13450
0
        } else {
13451
0
            WOLFSSL_MSG("ServerID not a match from client table");
13452
0
        }
13453
0
        SESSION_ROW_UNLOCK(sessRow);
13454
13455
0
        idx = idx > 0 ? idx - 1 : CLIENT_SESSIONS_PER_ROW - 1;
13456
0
    }
13457
13458
0
    wc_UnLockMutex(&clisession_mutex);
13459
13460
0
    return ret;
13461
0
}
13462
13463
#endif /* !NO_CLIENT_CACHE */
13464
13465
static int SslSessionCacheOff(const WOLFSSL* ssl, const WOLFSSL_SESSION* session)
13466
0
{
13467
0
    (void)session;
13468
0
    return ssl->options.sessionCacheOff
13469
0
    #if defined(HAVE_SESSION_TICKET) && defined(WOLFSSL_FORCE_CACHE_ON_TICKET)
13470
0
                && session->ticketLen == 0
13471
0
    #endif
13472
0
    #ifdef OPENSSL_EXTRA
13473
0
                && ssl->options.side != WOLFSSL_CLIENT_END
13474
0
    #endif
13475
0
                ;
13476
0
}
13477
13478
13479
int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output)
13480
0
{
13481
0
    WOLFSSL_SESSION* sess = NULL;
13482
0
    const byte*  id = NULL;
13483
0
    word32       row;
13484
0
    int          idx;
13485
0
    int          count;
13486
0
    int          error = 0;
13487
0
    SessionRow*  sessRow;
13488
0
#ifdef HAVE_SESSION_TICKET
13489
#ifndef WOLFSSL_SMALL_STACK
13490
    byte         tmpTicket[PREALLOC_SESSION_TICKET_LEN];
13491
#else
13492
0
    byte*        tmpTicket = NULL;
13493
0
#endif
13494
0
    byte         tmpBufSet = 0;
13495
0
#endif
13496
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13497
    WOLFSSL_X509* peer = NULL;
13498
#endif
13499
0
    byte         bogusID[ID_LEN];
13500
0
    byte         bogusIDSz = 0;
13501
13502
0
    WOLFSSL_ENTER("wolfSSL_GetSessionFromCache");
13503
13504
0
    if (output == NULL) {
13505
0
        WOLFSSL_MSG("NULL output");
13506
0
        return WOLFSSL_FAILURE;
13507
0
    }
13508
13509
0
    if (SslSessionCacheOff(ssl, ssl->session))
13510
0
        return WOLFSSL_FAILURE;
13511
13512
0
    if (ssl->options.haveSessionId == 0)
13513
0
        return WOLFSSL_FAILURE;
13514
13515
0
#ifdef HAVE_SESSION_TICKET
13516
0
    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1)
13517
0
        return WOLFSSL_FAILURE;
13518
0
#endif
13519
13520
0
    XMEMSET(bogusID, 0, sizeof(bogusID));
13521
0
    if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
13522
0
        id = ssl->arrays->sessionID;
13523
0
    else if (ssl->session->haveAltSessionID) {
13524
0
        id = ssl->session->altSessionID;
13525
        /* We want to restore the bogus ID for TLS compatibility */
13526
0
        if (output == ssl->session) {
13527
0
            XMEMCPY(bogusID, ssl->session->sessionID, ID_LEN);
13528
0
            bogusIDSz = ssl->session->sessionIDSz;
13529
0
        }
13530
0
    }
13531
0
    else
13532
0
        id = ssl->session->sessionID;
13533
13534
13535
0
#ifdef HAVE_EXT_CACHE
13536
0
    if (ssl->ctx->get_sess_cb != NULL) {
13537
0
        int copy = 0;
13538
        /* Attempt to retrieve the session from the external cache. */
13539
0
        WOLFSSL_MSG("Calling external session cache");
13540
0
        sess = ssl->ctx->get_sess_cb(ssl, (byte*)id, ID_LEN, &copy);
13541
0
        if (sess != NULL) {
13542
0
            WOLFSSL_MSG("Session found in external cache");
13543
0
            error = wolfSSL_DupSession(sess, output, 0);
13544
#ifdef HAVE_EX_DATA
13545
            output->ownExData = 0; /* Session cache owns external data */
13546
#endif
13547
            /* If copy not set then free immediately */
13548
0
            if (!copy)
13549
0
                wolfSSL_FreeSession(ssl->ctx, sess);
13550
            /* We want to restore the bogus ID for TLS compatibility */
13551
0
            if (ssl->session->haveAltSessionID &&
13552
0
                    output == ssl->session) {
13553
0
                XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN);
13554
0
                ssl->session->sessionIDSz = bogusIDSz;
13555
0
            }
13556
0
            return error;
13557
0
        }
13558
0
        WOLFSSL_MSG("Session not found in external cache");
13559
0
    }
13560
13561
0
    if (ssl->ctx->internalCacheLookupOff) {
13562
0
        WOLFSSL_MSG("Internal cache lookup turned off");
13563
0
        return WOLFSSL_FAILURE;
13564
0
    }
13565
0
#endif
13566
13567
0
    row = HashObject(id, ID_LEN, &error) % SESSION_ROWS;
13568
0
    if (error != 0) {
13569
0
        WOLFSSL_MSG("Hash session failed");
13570
0
        return WOLFSSL_FAILURE;
13571
0
    }
13572
13573
13574
0
#ifdef HAVE_SESSION_TICKET
13575
0
    if (output->ticket == NULL ||
13576
0
            output->ticketLenAlloc < PREALLOC_SESSION_TICKET_LEN) {
13577
0
#ifdef WOLFSSL_SMALL_STACK
13578
0
        tmpTicket = (byte*)XMALLOC(PREALLOC_SESSION_TICKET_LEN, output->heap,
13579
0
                DYNAMIC_TYPE_TMP_BUFFER);
13580
0
        if (tmpTicket == NULL) {
13581
0
            WOLFSSL_MSG("tmpTicket malloc failed");
13582
0
            return WOLFSSL_FAILURE;
13583
0
        }
13584
0
#endif
13585
0
        if (output->ticketLenAlloc)
13586
0
            XFREE(output->ticket, output->heap, DYNAMIC_TYPE_SESSION_TICK);
13587
0
        output->ticket = tmpTicket;
13588
0
        output->ticketLenAlloc = PREALLOC_SESSION_TICKET_LEN;
13589
0
        output->ticketLen = 0;
13590
0
        tmpBufSet = 1;
13591
0
    }
13592
0
#endif
13593
13594
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13595
    if (output->peer != NULL) {
13596
        wolfSSL_X509_free(output->peer);
13597
        output->peer = NULL;
13598
    }
13599
#endif
13600
13601
    /* lock row */
13602
0
    sessRow = &SessionCache[row];
13603
0
    if (SESSION_ROW_LOCK(sessRow) != 0) {
13604
0
        WOLFSSL_MSG("Session cache row lock failure");
13605
0
#ifdef HAVE_SESSION_TICKET
13606
0
        if (tmpBufSet) {
13607
0
            output->ticket = output->staticTicket;
13608
0
            output->ticketLenAlloc = 0;
13609
0
        }
13610
0
#ifdef WOLFSSL_SMALL_STACK
13611
0
        if (tmpTicket != NULL)
13612
0
            XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
13613
0
#endif
13614
0
#endif
13615
0
        return WOLFSSL_FAILURE;
13616
0
    }
13617
13618
    /* start from most recently used */
13619
0
    count = min((word32)sessRow->totalCount, SESSIONS_PER_ROW);
13620
0
    idx = sessRow->nextIdx - 1;
13621
0
    if (idx < 0 || idx >= SESSIONS_PER_ROW) {
13622
0
        idx = SESSIONS_PER_ROW - 1; /* if back to front, the previous was end */
13623
0
    }
13624
13625
0
    for (; count > 0; --count) {
13626
0
        WOLFSSL_SESSION* current;
13627
13628
0
        current = &sessRow->Sessions[idx];
13629
0
        if (XMEMCMP(current->sessionID, id, ID_LEN) == 0 &&
13630
0
                current->side == ssl->options.side) {
13631
0
            WOLFSSL_MSG("Found a session match");
13632
0
            if (LowResTimer() < (current->bornOn + current->timeout)) {
13633
0
                WOLFSSL_MSG("Session valid");
13634
0
                sess = current;
13635
0
            } else {
13636
0
                WOLFSSL_MSG("Session timed out");
13637
0
            }
13638
0
            break;  /* no more sessionIDs whether valid or not that match */
13639
0
        } else {
13640
0
            WOLFSSL_MSG("SessionID not a match at this idx");
13641
0
        }
13642
13643
0
        idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
13644
0
    }
13645
13646
0
    if (sess != NULL) {
13647
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13648
        /* We don't want the peer member. We will free it at the end. */
13649
        if (sess->peer != NULL) {
13650
            peer = sess->peer;
13651
            sess->peer = NULL;
13652
        }
13653
#endif
13654
0
        error = wolfSSL_DupSession(sess, output, 1);
13655
#ifdef HAVE_EX_DATA
13656
        output->ownExData = 0; /* Session cache owns external data */
13657
#endif
13658
0
    }
13659
0
    else {
13660
0
        error = WOLFSSL_FAILURE;
13661
0
    }
13662
13663
0
    SESSION_ROW_UNLOCK(sessRow);
13664
13665
    /* We want to restore the bogus ID for TLS compatibility */
13666
0
    if (ssl->session->haveAltSessionID &&
13667
0
            output == ssl->session) {
13668
0
        XMEMCPY(ssl->session->sessionID, bogusID, ID_LEN);
13669
0
        ssl->session->sessionIDSz = bogusIDSz;
13670
0
    }
13671
13672
0
#ifdef HAVE_SESSION_TICKET
13673
0
    if (tmpBufSet) {
13674
0
        if (error == WOLFSSL_SUCCESS) {
13675
0
            if (output->ticketLen > SESSION_TICKET_LEN) {
13676
0
                output->ticket = (byte*)XMALLOC(output->ticketLen, output->heap,
13677
0
                        DYNAMIC_TYPE_SESSION_TICK);
13678
0
                if (output->ticket == NULL) {
13679
0
                    error = WOLFSSL_FAILURE;
13680
0
                    output->ticket = output->staticTicket;
13681
0
                    output->ticketLenAlloc = 0;
13682
0
                    output->ticketLen = 0;
13683
0
                }
13684
0
            }
13685
0
            else {
13686
0
                output->ticket = output->staticTicket;
13687
0
                output->ticketLenAlloc = 0;
13688
0
            }
13689
0
        }
13690
0
        else {
13691
0
            output->ticket = output->staticTicket;
13692
0
            output->ticketLenAlloc = 0;
13693
0
            output->ticketLen = 0;
13694
0
        }
13695
0
        if (error == WOLFSSL_SUCCESS) {
13696
0
            XMEMCPY(output->ticket, tmpTicket, output->ticketLen);
13697
0
        }
13698
0
    }
13699
0
#ifdef WOLFSSL_SMALL_STACK
13700
0
    if (tmpTicket != NULL)
13701
0
        XFREE(tmpTicket, output->heap, DYNAMIC_TYPE_TMP_BUFFER);
13702
0
#endif
13703
0
#endif
13704
13705
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
13706
    if (peer != NULL) {
13707
        wolfSSL_X509_free(peer);
13708
    }
13709
#endif
13710
13711
0
    return error;
13712
0
}
13713
13714
WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret,
13715
        byte restoreSessionCerts)
13716
0
{
13717
0
    WOLFSSL_SESSION* ret = NULL;
13718
13719
0
    (void)restoreSessionCerts; /* Kept for compatibility */
13720
13721
0
    if (wolfSSL_GetSessionFromCache(ssl, ssl->session) == WOLFSSL_SUCCESS) {
13722
0
        ret = ssl->session;
13723
0
    }
13724
0
    else {
13725
0
        WOLFSSL_MSG("wolfSSL_GetSessionFromCache did not return a session");
13726
0
    }
13727
13728
0
    if (ret != NULL && masterSecret != NULL)
13729
0
        XMEMCPY(masterSecret, ret->masterSecret, SECRET_LEN);
13730
13731
0
    return ret;
13732
0
}
13733
13734
int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
13735
0
{
13736
0
    SessionRow* sessRow = NULL;
13737
0
    int ret = WOLFSSL_SUCCESS;
13738
13739
0
    session = ClientSessionToSession(session);
13740
13741
0
    if (ssl == NULL || session == NULL) {
13742
0
        return WOLFSSL_FAILURE;
13743
0
    }
13744
13745
0
    if (session->type == WOLFSSL_SESSION_TYPE_CACHE) {
13746
0
        if (session->cacheRow < SESSION_ROWS) {
13747
0
            sessRow = &SessionCache[session->cacheRow];
13748
0
            if (SESSION_ROW_LOCK(sessRow) != 0) {
13749
0
                WOLFSSL_MSG("Session row lock failed");
13750
0
                return WOLFSSL_FAILURE;
13751
0
            }
13752
0
        }
13753
0
    }
13754
13755
0
    if (ret == WOLFSSL_SUCCESS && SslSessionCacheOff(ssl, session)) {
13756
0
        WOLFSSL_MSG("Session cache off");
13757
0
        ret = WOLFSSL_FAILURE;
13758
0
    }
13759
13760
0
    if (ret == WOLFSSL_SUCCESS && ssl->options.side != WOLFSSL_NEITHER_END &&
13761
0
            (byte)ssl->options.side != session->side) {
13762
0
        WOLFSSL_MSG("Setting session for wrong role");
13763
0
        ret = WOLFSSL_FAILURE;
13764
0
    }
13765
13766
13767
0
    if (ret == WOLFSSL_SUCCESS &&
13768
0
            wolfSSL_DupSession(session, ssl->session, 0) != WOLFSSL_SUCCESS) {
13769
0
        WOLFSSL_MSG("Session duplicate failed");
13770
0
        ret = WOLFSSL_FAILURE;
13771
0
    }
13772
13773
    /* Let's copy over the altSessionID for local cache purposes */
13774
0
    if (ret == WOLFSSL_SUCCESS && session->haveAltSessionID) {
13775
0
        ssl->session->haveAltSessionID = 1;
13776
0
        XMEMCPY(ssl->session->altSessionID, session->altSessionID, ID_LEN);
13777
0
    }
13778
13779
0
    if (sessRow != NULL) {
13780
0
        SESSION_ROW_UNLOCK(sessRow);
13781
0
        sessRow = NULL;
13782
0
    }
13783
13784
    /* Note: the `session` variable cannot be used below, since the row is
13785
     * un-locked */
13786
13787
0
    if (ret != WOLFSSL_SUCCESS)
13788
0
        return ret;
13789
13790
0
#ifdef OPENSSL_EXTRA
13791
    /* check for application context id */
13792
0
    if (ssl->sessionCtxSz > 0) {
13793
0
        if (XMEMCMP(ssl->sessionCtx, ssl->session->sessionCtx, ssl->sessionCtxSz)) {
13794
            /* context id did not match! */
13795
0
            WOLFSSL_MSG("Session context did not match");
13796
0
            return WOLFSSL_FAILURE;
13797
0
        }
13798
0
    }
13799
0
#endif /* OPENSSL_EXTRA */
13800
13801
0
    if (LowResTimer() < (ssl->session->bornOn + ssl->session->timeout)) {
13802
0
        ssl->options.resuming = 1;
13803
0
        ssl->options.haveEMS = ssl->session->haveEMS;
13804
13805
0
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
13806
0
                               defined(HAVE_SESSION_TICKET))
13807
0
        ssl->version              = ssl->session->version;
13808
0
        if (IsAtLeastTLSv1_3(ssl->version))
13809
0
            ssl->options.tls1_3 = 1;
13810
0
#endif
13811
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
13812
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
13813
0
        ssl->options.cipherSuite0 = ssl->session->cipherSuite0;
13814
0
        ssl->options.cipherSuite  = ssl->session->cipherSuite;
13815
0
#endif
13816
0
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
13817
0
        ssl->peerVerifyRet = (unsigned long)ssl->session->peerVerifyRet;
13818
0
#endif
13819
0
        ret = WOLFSSL_SUCCESS;
13820
0
    }
13821
0
    else {
13822
0
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_ERROR_CODE_OPENSSL)
13823
0
        WOLFSSL_MSG("Session is expired but return success for \
13824
0
                              OpenSSL compatibility");
13825
0
        ret = WOLFSSL_SUCCESS;
13826
#else
13827
        ret = WOLFSSL_FAILURE;  /* session timed out */
13828
#endif /* OPENSSL_EXTRA && WOLFSSL_ERROR_CODE_OPENSSL */
13829
0
    }
13830
0
    return ret;
13831
0
}
13832
13833
13834
#ifdef WOLFSSL_SESSION_STATS
13835
static int get_locked_session_stats(word32* active, word32* total,
13836
                                    word32* peak);
13837
#endif
13838
13839
#ifndef NO_CLIENT_CACHE
13840
ClientSession* AddSessionToClientCache(int side, int row, int idx, byte* serverID,
13841
                            word16 idLen, const byte* sessionID,
13842
                            word16 useTicket)
13843
0
{
13844
0
    int error = -1;
13845
0
    word32 clientRow = 0, clientIdx = 0, sessionIDHash = 0;
13846
0
    (void)useTicket;
13847
0
    if (side == WOLFSSL_CLIENT_END
13848
0
            && row != INVALID_SESSION_ROW
13849
0
            && (idLen
13850
0
#ifdef HAVE_SESSION_TICKET
13851
0
                || useTicket == 1
13852
0
#endif
13853
0
                || serverID != NULL
13854
0
                )) {
13855
13856
0
        WOLFSSL_MSG("Trying to add client cache entry");
13857
13858
0
        if (idLen) {
13859
0
            clientRow = HashObject(serverID,
13860
0
                    idLen, &error) % CLIENT_SESSION_ROWS;
13861
0
        }
13862
0
        else if (serverID != NULL) {
13863
0
            clientRow = HashObject(sessionID,
13864
0
                    ID_LEN, &error) % CLIENT_SESSION_ROWS;
13865
0
        }
13866
0
        else {
13867
0
            error = -1;
13868
0
        }
13869
0
        if (error == 0 && wc_LockMutex(&clisession_mutex) == 0) {
13870
0
            clientIdx = ClientCache[clientRow].nextIdx;
13871
0
            if (clientIdx < CLIENT_SESSIONS_PER_ROW) {
13872
0
                ClientCache[clientRow].Clients[clientIdx].serverRow =
13873
0
                                                                (word16)row;
13874
0
                ClientCache[clientRow].Clients[clientIdx].serverIdx =
13875
0
                                                                (word16)idx;
13876
0
                if (sessionID != NULL) {
13877
0
                    sessionIDHash = HashObject(sessionID, ID_LEN, &error);
13878
0
                    if (error == 0) {
13879
0
                        ClientCache[clientRow].Clients[clientIdx].sessionIDHash
13880
0
                            = sessionIDHash;
13881
0
                    }
13882
0
                }
13883
0
            }
13884
0
            else {
13885
0
                error = -1;
13886
0
                ClientCache[clientRow].nextIdx = 0; /* reset index as saftey */
13887
0
                WOLFSSL_MSG("Invalid client cache index! "
13888
0
                            "Possible corrupted memory");
13889
0
            }
13890
0
            if (error == 0) {
13891
0
                WOLFSSL_MSG("Adding client cache entry");
13892
0
                if (ClientCache[clientRow].totalCount < CLIENT_SESSIONS_PER_ROW)
13893
0
                    ClientCache[clientRow].totalCount++;
13894
0
                ClientCache[clientRow].nextIdx++;
13895
0
                ClientCache[clientRow].nextIdx %= CLIENT_SESSIONS_PER_ROW;
13896
0
            }
13897
13898
0
            wc_UnLockMutex(&clisession_mutex);
13899
0
        }
13900
0
        else {
13901
0
            WOLFSSL_MSG("Hash session or lock failed");
13902
0
            error = -1;
13903
0
        }
13904
0
    }
13905
0
    else {
13906
0
        WOLFSSL_MSG("Skipping client cache");
13907
0
    }
13908
0
    if (error == 0)
13909
0
        return &ClientCache[clientRow].Clients[clientIdx];
13910
0
    else
13911
0
        return NULL;
13912
0
}
13913
#endif
13914
13915
/**
13916
 * For backwards compatibility, this API needs to be used in *ALL* functions
13917
 * that access the WOLFSSL_SESSION members directly.
13918
 *
13919
 * This API checks if the passed in session is actually a ClientSession object
13920
 * and returns the matching session cache object. Otherwise just return the
13921
 * input. ClientSession objects only occur in the ClientCache. They are not
13922
 * allocated anywhere else.
13923
 */
13924
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
13925
0
{
13926
0
    WOLFSSL_ENTER("ClientSessionToSession");
13927
#ifdef NO_SESSION_CACHE_REF
13928
    return (WOLFSSL_SESSION*)session;
13929
#else
13930
0
#ifndef NO_CLIENT_CACHE
13931
0
    if (session == NULL)
13932
0
        return NULL;
13933
    /* Check if session points into ClientCache */
13934
0
    if ((byte*)session >= (byte*)ClientCache &&
13935
            /* Cast to byte* to make pointer arithmetic work per byte */
13936
0
            (byte*)session < ((byte*)ClientCache) + sizeof(ClientCache)) {
13937
0
        ClientSession* clientSession = (ClientSession*)session;
13938
0
        SessionRow* sessRow = NULL;
13939
0
        WOLFSSL_SESSION* cacheSession = NULL;
13940
0
        word32 sessionIDHash = 0;
13941
0
        int error = 0;
13942
0
        session = NULL; /* Default to NULL for failure case */
13943
0
        if (wc_LockMutex(&clisession_mutex) != 0) {
13944
0
            WOLFSSL_MSG("Client cache mutex lock failed");
13945
0
            return NULL;
13946
0
        }
13947
0
        if (clientSession->serverRow >= SESSION_ROWS ||
13948
0
                clientSession->serverIdx >= SESSIONS_PER_ROW) {
13949
0
            WOLFSSL_MSG("Client cache serverRow or serverIdx invalid");
13950
0
            error = -1;
13951
0
        }
13952
0
        if (error == 0) {
13953
            /* Lock row */
13954
0
            sessRow = &SessionCache[clientSession->serverRow];
13955
0
            error = SESSION_ROW_LOCK(sessRow);
13956
0
            if (error != 0) {
13957
0
                WOLFSSL_MSG("Session cache row lock failure");
13958
0
                sessRow = NULL;
13959
0
            }
13960
0
        }
13961
0
        if (error == 0) {
13962
0
            cacheSession = &sessRow->Sessions[clientSession->serverIdx];
13963
0
            if (cacheSession->sessionIDSz == 0) {
13964
0
                cacheSession = NULL;
13965
0
                WOLFSSL_MSG("Session cache entry not set");
13966
0
                error = -1;
13967
0
            }
13968
0
        }
13969
0
        if (error == 0) {
13970
            /* Calculate the hash of the session ID */
13971
0
            sessionIDHash = HashObject(cacheSession->sessionID, ID_LEN,
13972
0
                    &error);
13973
0
        }
13974
0
        if (error == 0) {
13975
            /* Check the session ID hash matches */
13976
0
            error = clientSession->sessionIDHash != sessionIDHash;
13977
0
        }
13978
0
        if (error == 0) {
13979
            /* Hashes match */
13980
0
            session = cacheSession;
13981
0
            WOLFSSL_MSG("Found session cache matching client session object");
13982
0
        }
13983
0
        if (sessRow != NULL) {
13984
0
            SESSION_ROW_UNLOCK(sessRow);
13985
0
        }
13986
0
        wc_UnLockMutex(&clisession_mutex);
13987
0
        return (WOLFSSL_SESSION*)session;
13988
0
    }
13989
0
    else {
13990
        /* Plain WOLFSSL_SESSION object */
13991
0
        return (WOLFSSL_SESSION*)session;
13992
0
    }
13993
#else
13994
    return (WOLFSSL_SESSION*)session;
13995
#endif
13996
0
#endif
13997
0
}
13998
13999
int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession,
14000
        const byte* id, byte idSz, int* sessionIndex, int side,
14001
        word16 useTicket, ClientSession** clientCacheEntry)
14002
0
{
14003
0
    WOLFSSL_SESSION* cacheSession = NULL;
14004
0
    SessionRow* sessRow = NULL;
14005
0
    word32 idx = 0;
14006
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
14007
    WOLFSSL_X509* peer = NULL;
14008
#endif
14009
0
#ifdef HAVE_SESSION_TICKET
14010
0
    byte*  cacheTicBuff = NULL;
14011
0
    byte   ticBuffUsed = 0;
14012
0
    byte*  ticBuff = NULL;
14013
0
    int    ticLen  = 0;
14014
0
#endif
14015
0
    int ret = 0;
14016
0
    int row;
14017
0
    int i;
14018
0
    int overwrite = 0;
14019
14020
0
    (void)ctx;
14021
0
    (void)sessionIndex;
14022
0
    (void)useTicket;
14023
0
    (void)clientCacheEntry;
14024
14025
0
    if (idSz == 0) {
14026
0
        WOLFSSL_MSG("AddSessionToCache idSz == 0");
14027
0
        return BAD_FUNC_ARG;
14028
0
    }
14029
14030
0
    addSession = ClientSessionToSession(addSession);
14031
0
    if (addSession == NULL) {
14032
0
        WOLFSSL_MSG("AddSessionToCache is NULL");
14033
0
        return MEMORY_E;
14034
0
    }
14035
14036
    /* Find a position for the new session in cache and use that */
14037
0
#ifdef HAVE_SESSION_TICKET
14038
0
    ticLen = addSession->ticketLen;
14039
    /* Alloc Memory here to avoid syscalls during lock */
14040
0
    if (ticLen > SESSION_TICKET_LEN) {
14041
0
        ticBuff = (byte*)XMALLOC(ticLen, NULL,
14042
0
                DYNAMIC_TYPE_SESSION_TICK);
14043
0
        if (ticBuff == NULL) {
14044
0
            return MEMORY_E;
14045
0
        }
14046
0
    }
14047
0
#endif
14048
    /* Use the session object in the cache for external cache if required */
14049
0
    row = (int)(HashObject(id, ID_LEN, &ret) % SESSION_ROWS);
14050
0
    if (ret != 0) {
14051
0
        WOLFSSL_MSG("Hash session failed");
14052
0
    #ifdef HAVE_SESSION_TICKET
14053
0
        XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14054
0
    #endif
14055
0
        return ret;
14056
0
    }
14057
14058
0
    sessRow = &SessionCache[row];
14059
0
    if (SESSION_ROW_LOCK(sessRow) != 0) {
14060
0
    #ifdef HAVE_SESSION_TICKET
14061
0
        XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14062
0
    #endif
14063
0
        WOLFSSL_MSG("Session row lock failed");
14064
0
        return BAD_MUTEX_E;
14065
0
    }
14066
14067
0
    for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
14068
0
        if (XMEMCMP(id,
14069
0
                sessRow->Sessions[i].sessionID, ID_LEN) == 0 &&
14070
0
                sessRow->Sessions[i].side == side) {
14071
0
            WOLFSSL_MSG("Session already exists. Overwriting.");
14072
0
            overwrite = 1;
14073
0
            idx = i;
14074
0
            break;
14075
0
        }
14076
0
    }
14077
14078
0
    if (!overwrite)
14079
0
        idx = sessRow->nextIdx;
14080
#ifdef SESSION_INDEX
14081
    if (sessionIndex != NULL)
14082
        *sessionIndex = (row << SESSIDX_ROW_SHIFT) | idx;
14083
#endif
14084
0
    cacheSession = &sessRow->Sessions[idx];
14085
14086
#ifdef HAVE_EX_DATA
14087
    if (cacheSession->rem_sess_cb && cacheSession->ownExData) {
14088
        cacheSession->rem_sess_cb(NULL, cacheSession);
14089
        /* Make sure not to call remove functions again */
14090
        cacheSession->ownExData = 0;
14091
        cacheSession->rem_sess_cb = NULL;
14092
    }
14093
#endif
14094
14095
0
    cacheSession->type = WOLFSSL_SESSION_TYPE_CACHE;
14096
0
    cacheSession->cacheRow = row;
14097
14098
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
14099
    /* Save the peer field to free after unlocking the row */
14100
    if (cacheSession->peer != NULL)
14101
        peer = cacheSession->peer;
14102
    cacheSession->peer = NULL;
14103
#endif
14104
0
#ifdef HAVE_SESSION_TICKET
14105
    /* If we can re-use the existing buffer in cacheSession then we won't touch
14106
     * ticBuff at all making it a very cheap malloc/free. The page on a modern
14107
     * OS will most likely not even be allocated to the process. */
14108
0
    if (ticBuff != NULL && cacheSession->ticketLenAlloc < ticLen) {
14109
        /* Save pointer only if separately allocated */
14110
0
        if (cacheSession->ticket != cacheSession->staticTicket)
14111
0
            cacheTicBuff = cacheSession->ticket;
14112
0
        ticBuffUsed = 1;
14113
0
        cacheSession->ticket = ticBuff;
14114
0
        cacheSession->ticketLenAlloc = (word16) ticLen;
14115
0
    }
14116
0
#endif
14117
#ifdef SESSION_CERTS
14118
    if (overwrite &&
14119
            addSession->chain.count == 0 &&
14120
            cacheSession->chain.count > 0) {
14121
        /* Copy in the certs from the session */
14122
        addSession->chain.count = cacheSession->chain.count;
14123
        XMEMCPY(addSession->chain.certs, cacheSession->chain.certs,
14124
                sizeof(x509_buffer) * cacheSession->chain.count);
14125
    }
14126
#endif /* SESSION_CERTS */
14127
0
    cacheSession->heap = NULL;
14128
    /* Copy data into the cache object */
14129
0
    ret = wolfSSL_DupSession(addSession, cacheSession, 1) == WOLFSSL_FAILURE;
14130
14131
0
    if (ret == 0) {
14132
        /* Increment the totalCount and the nextIdx */
14133
0
        if (sessRow->totalCount < SESSIONS_PER_ROW)
14134
0
            sessRow->totalCount++;
14135
0
        sessRow->nextIdx = (sessRow->nextIdx + 1) % SESSIONS_PER_ROW;
14136
0
        if (id != addSession->sessionID) {
14137
            /* ssl->session->sessionID may contain the bogus ID or we want the
14138
             * ID from the arrays object */
14139
0
            XMEMCPY(cacheSession->sessionID, id, ID_LEN);
14140
0
            cacheSession->sessionIDSz = ID_LEN;
14141
0
        }
14142
#ifdef HAVE_EX_DATA
14143
        if (ctx->rem_sess_cb != NULL) {
14144
            addSession->ownExData = 0;
14145
            cacheSession->ownExData = 1;
14146
            cacheSession->rem_sess_cb = ctx->rem_sess_cb;
14147
        }
14148
#endif
14149
0
    }
14150
0
#ifdef HAVE_SESSION_TICKET
14151
0
    else if (ticBuffUsed) {
14152
        /* Error occured. Need to clean up the ticket buffer. */
14153
0
        cacheSession->ticket = cacheSession->staticTicket;
14154
0
        cacheSession->ticketLenAlloc = 0;
14155
0
        cacheSession->ticketLen = 0;
14156
0
    }
14157
0
#endif
14158
14159
0
    SESSION_ROW_UNLOCK(sessRow);
14160
0
    cacheSession = NULL; /* Can't access after unlocked */
14161
14162
0
#ifndef NO_CLIENT_CACHE
14163
0
    if (ret == 0 && clientCacheEntry != NULL) {
14164
0
        ClientSession* clientCache = AddSessionToClientCache(side, row, idx,
14165
0
                addSession->serverID, addSession->idLen, id, useTicket);
14166
0
        if (clientCache != NULL)
14167
0
            *clientCacheEntry = clientCache;
14168
0
    }
14169
0
#endif
14170
14171
0
#ifdef HAVE_SESSION_TICKET
14172
0
    if (ticBuff != NULL && !ticBuffUsed)
14173
0
        XFREE(ticBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14174
0
    if (cacheTicBuff != NULL)
14175
0
        XFREE(cacheTicBuff, NULL, DYNAMIC_TYPE_SESSION_TICK);
14176
0
#endif
14177
14178
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
14179
    if (peer != NULL) {
14180
        wolfSSL_X509_free(peer);
14181
        peer = NULL; /* Make sure not use after this point */
14182
    }
14183
#endif
14184
14185
0
    return ret;
14186
0
}
14187
14188
#ifndef NO_CLIENT_CACHE
14189
#endif
14190
14191
void AddSession(WOLFSSL* ssl)
14192
0
{
14193
0
    int    error = 0;
14194
0
    const byte* id = NULL;
14195
0
    byte idSz = 0;
14196
0
    WOLFSSL_SESSION* session = ssl->session;
14197
0
#ifdef HAVE_EXT_CACHE
14198
0
    int cbRet = 0;
14199
0
#endif
14200
14201
0
    (void)error;
14202
14203
0
    WOLFSSL_ENTER("AddSession");
14204
14205
0
    if (SslSessionCacheOff(ssl, session)) {
14206
0
        WOLFSSL_MSG("Cache off");
14207
0
        return;
14208
0
    }
14209
14210
0
    if (ssl->options.haveSessionId == 0) {
14211
0
        WOLFSSL_MSG("Don't have session id");
14212
0
        return;
14213
0
    }
14214
14215
#if defined(HAVE_SESSION_TICKET) && !defined(OPENSSL_EXTRA)
14216
    /* For the compat layer generate a session object to use */
14217
    if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.useTicket == 1) {
14218
        WOLFSSL_MSG("Using tickets instead of cache");
14219
        return;
14220
    }
14221
#endif
14222
14223
0
    if (session->haveAltSessionID) {
14224
0
        id = session->altSessionID;
14225
0
        idSz = ID_LEN;
14226
0
    }
14227
0
    else {
14228
0
        if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) {
14229
            /* Make sure the session ID is available when the user calls any
14230
             * get_session API */
14231
0
            XMEMCPY(session->sessionID, ssl->arrays->sessionID, ID_LEN);
14232
0
            session->sessionIDSz = ssl->arrays->sessionIDSz;
14233
0
        }
14234
0
        id = session->sessionID;
14235
0
        idSz = session->sessionIDSz;
14236
0
    }
14237
14238
0
    session->timeout = ssl->timeout;
14239
0
    session->side = (byte)ssl->options.side;
14240
0
    if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL)
14241
0
        XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN);
14242
0
    session->haveEMS = ssl->options.haveEMS;
14243
0
#ifdef OPENSSL_EXTRA
14244
    /* If using compatibility layer then check for and copy over session context
14245
     * id. */
14246
0
    if (ssl->sessionCtxSz > 0 && ssl->sessionCtxSz < ID_LEN) {
14247
0
        XMEMCPY(ssl->session->sessionCtx, ssl->sessionCtx, ssl->sessionCtxSz);
14248
0
        session->sessionCtxSz = ssl->sessionCtxSz;
14249
0
    }
14250
0
#endif
14251
0
    session->timeout = ssl->timeout;
14252
0
    session->bornOn  = LowResTimer();
14253
0
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
14254
0
                               defined(HAVE_SESSION_TICKET))
14255
0
    session->version = ssl->version;
14256
0
#endif
14257
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
14258
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
14259
0
    session->cipherSuite0 = ssl->options.cipherSuite0;
14260
0
    session->cipherSuite = ssl->options.cipherSuite;
14261
0
#endif
14262
0
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
14263
0
    session->peerVerifyRet = (byte)ssl->peerVerifyRet;
14264
0
#endif
14265
    /* Do this last so that if it fails, the rest of the session is setup. Do
14266
     * this only for the client because if the server doesn't have an ID at
14267
     * this point, it won't on resumption. */
14268
0
    if (idSz == 0 && ssl->options.side == WOLFSSL_CLIENT_END) {
14269
0
        WC_RNG* rng = NULL;
14270
0
        if (ssl->rng != NULL)
14271
0
            rng = ssl->rng;
14272
0
#if defined(HAVE_GLOBAL_RNG) && defined(OPENSSL_EXTRA)
14273
0
        else if (initGlobalRNG == 1 || wolfSSL_RAND_Init() == WOLFSSL_SUCCESS) {
14274
0
            rng = &globalRNG;
14275
0
        }
14276
0
#endif
14277
0
        if (wc_RNG_GenerateBlock(rng, ssl->session->altSessionID,
14278
0
                ID_LEN) != 0)
14279
0
            return;
14280
0
        ssl->session->haveAltSessionID = 1;
14281
0
        id = ssl->session->altSessionID;
14282
0
        idSz = ID_LEN;
14283
0
    }
14284
    /* Setup done */
14285
14286
0
    if (ssl->options.side == WOLFSSL_SERVER_END /* No point in adding a
14287
                                                 * client session */
14288
0
#ifdef HAVE_EXT_CACHE
14289
0
            && !ssl->options.internalCacheOff
14290
0
#endif
14291
0
            )
14292
0
    {
14293
        /* Try to add the session to cache. Its ok if we don't succeed. */
14294
0
        (void)AddSessionToCache(ssl->ctx, session, id, idSz,
14295
#ifdef SESSION_INDEX
14296
                &ssl->sessionIndex,
14297
#else
14298
0
                NULL,
14299
0
#endif
14300
0
                ssl->options.side,
14301
0
#ifdef HAVE_SESSION_TICKET
14302
0
                ssl->options.useTicket,
14303
#else
14304
                0,
14305
#endif
14306
0
                NULL
14307
0
                );
14308
0
    }
14309
14310
0
#ifdef HAVE_EXT_CACHE
14311
0
    if (error == 0 && ssl->ctx->new_sess_cb != NULL) {
14312
0
        wolfSSL_SESSION_up_ref(session);
14313
0
        cbRet = ssl->ctx->new_sess_cb(ssl, session);
14314
0
        if (cbRet == 0)
14315
0
            wolfSSL_FreeSession(ssl->ctx, session);
14316
0
    }
14317
0
#endif
14318
14319
#if defined(WOLFSSL_SESSION_STATS) && defined(WOLFSSL_PEAK_SESSIONS)
14320
    if (error == 0) {
14321
        word32 active = 0;
14322
14323
        error = get_locked_session_stats(&active, NULL, NULL);
14324
        if (error == WOLFSSL_SUCCESS) {
14325
            error = 0;  /* back to this function ok */
14326
14327
            if (PeakSessions < active) {
14328
                PeakSessions = active;
14329
            }
14330
        }
14331
    }
14332
#endif /* WOLFSSL_SESSION_STATS && WOLFSSL_PEAK_SESSIONS */
14333
0
    (void)error;
14334
0
}
14335
14336
14337
#ifdef SESSION_INDEX
14338
14339
int wolfSSL_GetSessionIndex(WOLFSSL* ssl)
14340
{
14341
    WOLFSSL_ENTER("wolfSSL_GetSessionIndex");
14342
    WOLFSSL_LEAVE("wolfSSL_GetSessionIndex", ssl->sessionIndex);
14343
    return ssl->sessionIndex;
14344
}
14345
14346
14347
int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session)
14348
{
14349
    int row, col, result = WOLFSSL_FAILURE;
14350
    SessionRow* sessRow;
14351
14352
    WOLFSSL_ENTER("wolfSSL_GetSessionAtIndex");
14353
14354
    session = ClientSessionToSession(session);
14355
14356
    row = idx >> SESSIDX_ROW_SHIFT;
14357
    col = idx & SESSIDX_IDX_MASK;
14358
14359
    if (session == NULL ||
14360
            row < 0 || row >= SESSION_ROWS || col >= SESSIONS_PER_ROW) {
14361
        return WOLFSSL_FAILURE;
14362
    }
14363
14364
    sessRow = &SessionCache[row];
14365
    if (SESSION_ROW_LOCK(sessRow) != 0) {
14366
        return BAD_MUTEX_E;
14367
    }
14368
14369
    XMEMCPY(session, &sessRow->Sessions[col], sizeof(WOLFSSL_SESSION));
14370
    result = WOLFSSL_SUCCESS;
14371
14372
    SESSION_ROW_UNLOCK(sessRow);
14373
14374
    WOLFSSL_LEAVE("wolfSSL_GetSessionAtIndex", result);
14375
    return result;
14376
}
14377
14378
#endif /* SESSION_INDEX */
14379
14380
#if defined(SESSION_CERTS)
14381
14382
WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session)
14383
{
14384
    WOLFSSL_X509_CHAIN* chain = NULL;
14385
14386
    WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
14387
14388
    session = ClientSessionToSession(session);
14389
14390
    if (session)
14391
        chain = &session->chain;
14392
14393
    WOLFSSL_LEAVE("wolfSSL_SESSION_get_peer_chain", chain ? 1 : 0);
14394
    return chain;
14395
}
14396
14397
14398
#ifdef OPENSSL_EXTRA
14399
/* gets the peer certificate associated with the session passed in
14400
 * returns null on failure, the caller should not free the returned pointer */
14401
WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session)
14402
{
14403
    WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain");
14404
14405
    session = ClientSessionToSession(session);
14406
    if (session) {
14407
        int count;
14408
14409
        count = wolfSSL_get_chain_count(&session->chain);
14410
        if (count < 1 || count >= MAX_CHAIN_DEPTH) {
14411
            WOLFSSL_MSG("bad count found");
14412
            return NULL;
14413
        }
14414
14415
        if (session->peer == NULL) {
14416
            session->peer = wolfSSL_get_chain_X509(&session->chain, 0);
14417
        }
14418
        return session->peer;
14419
    }
14420
    WOLFSSL_MSG("No session passed in");
14421
14422
    return NULL;
14423
}
14424
#endif /* OPENSSL_EXTRA */
14425
#endif /* SESSION_INDEX && SESSION_CERTS */
14426
14427
14428
#ifdef WOLFSSL_SESSION_STATS
14429
14430
static int get_locked_session_stats(word32* active, word32* total, word32* peak)
14431
{
14432
    int result = WOLFSSL_SUCCESS;
14433
    int i;
14434
    int count;
14435
    int idx;
14436
    word32 now   = 0;
14437
    word32 seen  = 0;
14438
    word32 ticks = LowResTimer();
14439
14440
    WOLFSSL_ENTER("get_locked_session_stats");
14441
14442
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
14443
    wc_LockMutex(&session_mutex);
14444
#endif
14445
    for (i = 0; i < SESSION_ROWS; i++) {
14446
        SessionRow* row = &SessionCache[i];
14447
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
14448
        if (SESSION_ROW_LOCK(row) != 0) {
14449
            WOLFSSL_MSG("Session row cache mutex lock failed");
14450
            return BAD_MUTEX_E;
14451
        }
14452
    #endif
14453
14454
        seen += row->totalCount;
14455
14456
        if (active == NULL) {
14457
            SESSION_ROW_UNLOCK(row);
14458
            continue;
14459
        }
14460
14461
        count = min((word32)row->totalCount, SESSIONS_PER_ROW);
14462
        idx   = row->nextIdx - 1;
14463
        if (idx < 0 || idx >= SESSIONS_PER_ROW) {
14464
            idx = SESSIONS_PER_ROW - 1; /* if back to front previous was end */
14465
        }
14466
14467
        for (; count > 0; --count) {
14468
            /* if not expired then good */
14469
            if (ticks < (row->Sessions[idx].bornOn +
14470
                            row->Sessions[idx].timeout) ) {
14471
                now++;
14472
            }
14473
14474
            idx = idx > 0 ? idx - 1 : SESSIONS_PER_ROW - 1;
14475
        }
14476
14477
    #ifdef ENABLE_SESSION_CACHE_ROW_LOCK
14478
        SESSION_ROW_UNLOCK(row);
14479
    #endif
14480
    }
14481
#ifndef ENABLE_SESSION_CACHE_ROW_LOCK
14482
    wc_UnLockMutex(&session_mutex);
14483
#endif
14484
14485
    if (active) {
14486
        *active = now;
14487
    }
14488
    if (total) {
14489
        *total = seen;
14490
    }
14491
14492
#ifdef WOLFSSL_PEAK_SESSIONS
14493
    if (peak) {
14494
        *peak = PeakSessions;
14495
    }
14496
#else
14497
    (void)peak;
14498
#endif
14499
14500
    WOLFSSL_LEAVE("get_locked_session_stats", result);
14501
14502
    return result;
14503
}
14504
14505
14506
/* return WOLFSSL_SUCCESS on ok */
14507
int wolfSSL_get_session_stats(word32* active, word32* total, word32* peak,
14508
                              word32* maxSessions)
14509
{
14510
    int result = WOLFSSL_SUCCESS;
14511
14512
    WOLFSSL_ENTER("wolfSSL_get_session_stats");
14513
14514
    if (maxSessions) {
14515
        *maxSessions = SESSIONS_PER_ROW * SESSION_ROWS;
14516
14517
        if (active == NULL && total == NULL && peak == NULL)
14518
            return result;  /* we're done */
14519
    }
14520
14521
    /* user must provide at least one query value */
14522
    if (active == NULL && total == NULL && peak == NULL) {
14523
        return BAD_FUNC_ARG;
14524
    }
14525
14526
    result = get_locked_session_stats(active, total, peak);
14527
14528
    WOLFSSL_LEAVE("wolfSSL_get_session_stats", result);
14529
14530
    return result;
14531
}
14532
14533
#endif /* WOLFSSL_SESSION_STATS */
14534
14535
14536
    #ifdef PRINT_SESSION_STATS
14537
14538
    /* WOLFSSL_SUCCESS on ok */
14539
    int wolfSSL_PrintSessionStats(void)
14540
    {
14541
        word32 totalSessionsSeen = 0;
14542
        word32 totalSessionsNow = 0;
14543
        word32 peak = 0;
14544
        word32 maxSessions = 0;
14545
        int    i;
14546
        int    ret;
14547
        double E;               /* expected freq */
14548
        double chiSquare = 0;
14549
14550
        ret = wolfSSL_get_session_stats(&totalSessionsNow, &totalSessionsSeen,
14551
                                        &peak, &maxSessions);
14552
        if (ret != WOLFSSL_SUCCESS)
14553
            return ret;
14554
        printf("Total Sessions Seen = %u\n", totalSessionsSeen);
14555
        printf("Total Sessions Now  = %u\n", totalSessionsNow);
14556
#ifdef WOLFSSL_PEAK_SESSIONS
14557
        printf("Peak  Sessions      = %u\n", peak);
14558
#endif
14559
        printf("Max   Sessions      = %u\n", maxSessions);
14560
14561
        E = (double)totalSessionsSeen / SESSION_ROWS;
14562
14563
        for (i = 0; i < SESSION_ROWS; i++) {
14564
            double diff = SessionCache[i].totalCount - E;
14565
            diff *= diff;                /* square    */
14566
            diff /= E;                   /* normalize */
14567
14568
            chiSquare += diff;
14569
        }
14570
        printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
14571
                                                     SESSION_ROWS - 1);
14572
        #if (SESSION_ROWS == 11)
14573
            printf(" .05 p value =  18.3, chi-square should be less\n");
14574
        #elif (SESSION_ROWS == 211)
14575
            printf(".05 p value  = 244.8, chi-square should be less\n");
14576
        #elif (SESSION_ROWS == 5981)
14577
            printf(".05 p value  = 6161.0, chi-square should be less\n");
14578
        #elif (SESSION_ROWS == 3)
14579
            printf(".05 p value  =   6.0, chi-square should be less\n");
14580
        #elif (SESSION_ROWS == 2861)
14581
            printf(".05 p value  = 2985.5, chi-square should be less\n");
14582
        #endif
14583
        printf("\n");
14584
14585
        return ret;
14586
    }
14587
14588
    #endif /* SESSION_STATS */
14589
14590
#else  /* NO_SESSION_CACHE */
14591
14592
WOLFSSL_SESSION* ClientSessionToSession(const WOLFSSL_SESSION* session)
14593
{
14594
    return (WOLFSSL_SESSION*)session;
14595
}
14596
14597
/* No session cache version */
14598
WOLFSSL_SESSION* wolfSSL_GetSession(WOLFSSL* ssl, byte* masterSecret,
14599
        byte restoreSessionCerts)
14600
{
14601
    (void)ssl;
14602
    (void)masterSecret;
14603
    (void)restoreSessionCerts;
14604
14605
    return NULL;
14606
}
14607
14608
#endif /* NO_SESSION_CACHE */
14609
14610
14611
/* call before SSL_connect, if verifying will add name check to
14612
   date check and signature check */
14613
WOLFSSL_ABI
14614
int wolfSSL_check_domain_name(WOLFSSL* ssl, const char* dn)
14615
0
{
14616
0
    WOLFSSL_ENTER("wolfSSL_check_domain_name");
14617
14618
0
    if (ssl == NULL || dn == NULL) {
14619
0
        WOLFSSL_MSG("Bad function argument: NULL");
14620
0
        return WOLFSSL_FAILURE;
14621
0
    }
14622
14623
0
    if (ssl->buffers.domainName.buffer)
14624
0
        XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
14625
14626
0
    ssl->buffers.domainName.length = (word32)XSTRLEN(dn);
14627
0
    ssl->buffers.domainName.buffer = (byte*)XMALLOC(
14628
0
            ssl->buffers.domainName.length + 1, ssl->heap, DYNAMIC_TYPE_DOMAIN);
14629
14630
0
    if (ssl->buffers.domainName.buffer) {
14631
0
        unsigned char* domainName = ssl->buffers.domainName.buffer;
14632
0
        XMEMCPY(domainName, dn, ssl->buffers.domainName.length);
14633
0
        domainName[ssl->buffers.domainName.length] = '\0';
14634
0
        return WOLFSSL_SUCCESS;
14635
0
    }
14636
0
    else {
14637
0
        ssl->error = MEMORY_ERROR;
14638
0
        return WOLFSSL_FAILURE;
14639
0
    }
14640
0
}
14641
14642
14643
/* turn on wolfSSL zlib compression
14644
   returns WOLFSSL_SUCCESS for success, else error (not built in)
14645
*/
14646
int wolfSSL_set_compression(WOLFSSL* ssl)
14647
0
{
14648
0
    WOLFSSL_ENTER("wolfSSL_set_compression");
14649
0
    (void)ssl;
14650
#ifdef HAVE_LIBZ
14651
    ssl->options.usingCompression = 1;
14652
    return WOLFSSL_SUCCESS;
14653
#else
14654
0
    return NOT_COMPILED_IN;
14655
0
#endif
14656
0
}
14657
14658
14659
#ifndef USE_WINDOWS_API
14660
    #ifndef NO_WRITEV
14661
14662
        /* simulate writev semantics, doesn't actually do block at a time though
14663
           because of SSL_write behavior and because front adds may be small */
14664
        int wolfSSL_writev(WOLFSSL* ssl, const struct iovec* iov, int iovcnt)
14665
0
        {
14666
0
        #ifdef WOLFSSL_SMALL_STACK
14667
0
            byte   staticBuffer[1]; /* force heap usage */
14668
        #else
14669
            byte   staticBuffer[FILE_BUFFER_SIZE];
14670
        #endif
14671
0
            byte* myBuffer  = staticBuffer;
14672
0
            int   dynamic   = 0;
14673
0
            int   sending   = 0;
14674
0
            int   idx       = 0;
14675
0
            int   i;
14676
0
            int   ret;
14677
14678
0
            WOLFSSL_ENTER("wolfSSL_writev");
14679
14680
0
            for (i = 0; i < iovcnt; i++)
14681
0
                sending += (int)iov[i].iov_len;
14682
14683
0
            if (sending > (int)sizeof(staticBuffer)) {
14684
0
                myBuffer = (byte*)XMALLOC(sending, ssl->heap,
14685
0
                                                           DYNAMIC_TYPE_WRITEV);
14686
0
                if (!myBuffer)
14687
0
                    return MEMORY_ERROR;
14688
14689
0
                dynamic = 1;
14690
0
            }
14691
14692
0
            for (i = 0; i < iovcnt; i++) {
14693
0
                XMEMCPY(&myBuffer[idx], iov[i].iov_base, iov[i].iov_len);
14694
0
                idx += (int)iov[i].iov_len;
14695
0
            }
14696
14697
           /* myBuffer may not be initialized fully, but the span up to the
14698
            * sending length will be.
14699
            */
14700
0
            PRAGMA_GCC_DIAG_PUSH;
14701
0
            PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"");
14702
0
            ret = wolfSSL_write(ssl, myBuffer, sending);
14703
0
            PRAGMA_GCC_DIAG_POP;
14704
14705
0
            if (dynamic)
14706
0
                XFREE(myBuffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
14707
14708
0
            return ret;
14709
0
        }
14710
    #endif
14711
#endif
14712
14713
14714
#ifdef WOLFSSL_CALLBACKS
14715
14716
    typedef struct itimerval Itimerval;
14717
14718
    /* don't keep calling simple functions while setting up timer and signals
14719
       if no inlining these are the next best */
14720
14721
    #define AddTimes(a, b, c)                       \
14722
        do {                                        \
14723
            c.tv_sec  = a.tv_sec  + b.tv_sec;       \
14724
            c.tv_usec = a.tv_usec + b.tv_usec;      \
14725
            if (c.tv_usec >=  1000000) {            \
14726
                c.tv_sec++;                         \
14727
                c.tv_usec -= 1000000;               \
14728
            }                                       \
14729
        } while (0)
14730
14731
14732
    #define SubtractTimes(a, b, c)                  \
14733
        do {                                        \
14734
            c.tv_sec  = a.tv_sec  - b.tv_sec;       \
14735
            c.tv_usec = a.tv_usec - b.tv_usec;      \
14736
            if (c.tv_usec < 0) {                    \
14737
                c.tv_sec--;                         \
14738
                c.tv_usec += 1000000;               \
14739
            }                                       \
14740
        } while (0)
14741
14742
    #define CmpTimes(a, b, cmp)                     \
14743
        ((a.tv_sec  ==  b.tv_sec) ?                 \
14744
            (a.tv_usec cmp b.tv_usec) :             \
14745
            (a.tv_sec  cmp b.tv_sec))               \
14746
14747
14748
    /* do nothing handler */
14749
    static void myHandler(int signo)
14750
    {
14751
        (void)signo;
14752
        return;
14753
    }
14754
14755
14756
    static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb,
14757
                                 TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
14758
    {
14759
        int       ret        = WOLFSSL_FATAL_ERROR;
14760
        int       oldTimerOn = 0;   /* was timer already on */
14761
        WOLFSSL_TIMEVAL startTime;
14762
        WOLFSSL_TIMEVAL endTime;
14763
        WOLFSSL_TIMEVAL totalTime;
14764
        Itimerval myTimeout;
14765
        Itimerval oldTimeout; /* if old timer adjust from total time to reset */
14766
        struct sigaction act, oact;
14767
14768
        #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
14769
14770
        if (hsCb) {
14771
            ssl->hsInfoOn = 1;
14772
            InitHandShakeInfo(&ssl->handShakeInfo, ssl);
14773
        }
14774
        if (toCb) {
14775
            ssl->toInfoOn = 1;
14776
            InitTimeoutInfo(&ssl->timeoutInfo);
14777
14778
            if (gettimeofday(&startTime, 0) < 0)
14779
                ERR_OUT(GETTIME_ERROR);
14780
14781
            /* use setitimer to simulate getitimer, init 0 myTimeout */
14782
            myTimeout.it_interval.tv_sec  = 0;
14783
            myTimeout.it_interval.tv_usec = 0;
14784
            myTimeout.it_value.tv_sec     = 0;
14785
            myTimeout.it_value.tv_usec    = 0;
14786
            if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
14787
                ERR_OUT(SETITIMER_ERROR);
14788
14789
            if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
14790
                oldTimerOn = 1;
14791
14792
                /* is old timer going to expire before ours */
14793
                if (CmpTimes(oldTimeout.it_value, timeout, <)) {
14794
                    timeout.tv_sec  = oldTimeout.it_value.tv_sec;
14795
                    timeout.tv_usec = oldTimeout.it_value.tv_usec;
14796
                }
14797
            }
14798
            myTimeout.it_value.tv_sec  = timeout.tv_sec;
14799
            myTimeout.it_value.tv_usec = timeout.tv_usec;
14800
14801
            /* set up signal handler, don't restart socket send/recv */
14802
            act.sa_handler = myHandler;
14803
            sigemptyset(&act.sa_mask);
14804
            act.sa_flags = 0;
14805
#ifdef SA_INTERRUPT
14806
            act.sa_flags |= SA_INTERRUPT;
14807
#endif
14808
            if (sigaction(SIGALRM, &act, &oact) < 0)
14809
                ERR_OUT(SIGACT_ERROR);
14810
14811
            if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
14812
                ERR_OUT(SETITIMER_ERROR);
14813
        }
14814
14815
        /* do main work */
14816
#ifndef NO_WOLFSSL_CLIENT
14817
        if (ssl->options.side == WOLFSSL_CLIENT_END)
14818
            ret = wolfSSL_connect(ssl);
14819
#endif
14820
#ifndef NO_WOLFSSL_SERVER
14821
        if (ssl->options.side == WOLFSSL_SERVER_END)
14822
            ret = wolfSSL_accept(ssl);
14823
#endif
14824
14825
        /* do callbacks */
14826
        if (toCb) {
14827
            if (oldTimerOn) {
14828
                gettimeofday(&endTime, 0);
14829
                SubtractTimes(endTime, startTime, totalTime);
14830
                /* adjust old timer for elapsed time */
14831
                if (CmpTimes(totalTime, oldTimeout.it_value, <))
14832
                    SubtractTimes(oldTimeout.it_value, totalTime,
14833
                                  oldTimeout.it_value);
14834
                else {
14835
                    /* reset value to interval, may be off */
14836
                    oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
14837
                    oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
14838
                }
14839
                /* keep iter the same whether there or not */
14840
            }
14841
            /* restore old handler */
14842
            if (sigaction(SIGALRM, &oact, 0) < 0)
14843
                ret = SIGACT_ERROR;    /* more pressing error, stomp */
14844
            else
14845
                /* use old settings which may turn off (expired or not there) */
14846
                if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
14847
                    ret = SETITIMER_ERROR;
14848
14849
            /* if we had a timeout call callback */
14850
            if (ssl->timeoutInfo.timeoutName[0]) {
14851
                ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
14852
                ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
14853
                (toCb)(&ssl->timeoutInfo);
14854
            }
14855
            ssl->toInfoOn = 0;
14856
        }
14857
14858
        /* clean up buffers allocated by AddPacketInfo */
14859
        FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
14860
14861
        if (hsCb) {
14862
            FinishHandShakeInfo(&ssl->handShakeInfo);
14863
            (hsCb)(&ssl->handShakeInfo);
14864
            ssl->hsInfoOn = 0;
14865
        }
14866
        return ret;
14867
    }
14868
14869
14870
#ifndef NO_WOLFSSL_CLIENT
14871
14872
    int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
14873
                          TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
14874
    {
14875
        WOLFSSL_ENTER("wolfSSL_connect_ex");
14876
        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
14877
    }
14878
14879
#endif
14880
14881
14882
#ifndef NO_WOLFSSL_SERVER
14883
14884
    int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb,
14885
                         TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout)
14886
    {
14887
        WOLFSSL_ENTER("wolfSSL_accept_ex");
14888
        return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
14889
    }
14890
14891
#endif
14892
14893
#endif /* WOLFSSL_CALLBACKS */
14894
14895
14896
#ifndef NO_PSK
14897
14898
    void wolfSSL_CTX_set_psk_client_callback(WOLFSSL_CTX* ctx,
14899
                                         wc_psk_client_callback cb)
14900
    {
14901
        WOLFSSL_ENTER("SSL_CTX_set_psk_client_callback");
14902
14903
        if (ctx == NULL)
14904
            return;
14905
14906
        ctx->havePSK = 1;
14907
        ctx->client_psk_cb = cb;
14908
    }
14909
14910
    void wolfSSL_set_psk_client_callback(WOLFSSL* ssl,wc_psk_client_callback cb)
14911
    {
14912
        byte haveRSA = 1;
14913
        int  keySz   = 0;
14914
14915
        WOLFSSL_ENTER("SSL_set_psk_client_callback");
14916
14917
        if (ssl == NULL)
14918
            return;
14919
14920
        ssl->options.havePSK = 1;
14921
        ssl->options.client_psk_cb = cb;
14922
14923
        #ifdef NO_RSA
14924
            haveRSA = 0;
14925
        #endif
14926
        #ifndef NO_CERTS
14927
            keySz = ssl->buffers.keySz;
14928
        #endif
14929
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
14930
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
14931
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
14932
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
14933
                   ssl->options.haveAnon, TRUE, ssl->options.side);
14934
    }
14935
    #ifdef OPENSSL_EXTRA
14936
    /**
14937
     * set call back function for psk session use
14938
     * @param ssl  a pointer to WOLFSSL structure
14939
     * @param cb   a function pointer to wc_psk_use_session_cb
14940
     * @return none
14941
     */
14942
    void wolfSSL_set_psk_use_session_callback(WOLFSSL* ssl,
14943
                                                wc_psk_use_session_cb_func cb)
14944
    {
14945
        WOLFSSL_ENTER("wolfSSL_set_psk_use_session_callback");
14946
14947
        ssl->options.havePSK = 1;
14948
        ssl->options.session_psk_cb = cb;
14949
14950
        WOLFSSL_LEAVE("wolfSSL_set_psk_use_session_callback", WOLFSSL_SUCCESS);
14951
    }
14952
    #endif
14953
14954
    void wolfSSL_CTX_set_psk_server_callback(WOLFSSL_CTX* ctx,
14955
                                         wc_psk_server_callback cb)
14956
    {
14957
        WOLFSSL_ENTER("SSL_CTX_set_psk_server_callback");
14958
        if (ctx == NULL)
14959
            return;
14960
        ctx->havePSK = 1;
14961
        ctx->server_psk_cb = cb;
14962
    }
14963
14964
    void wolfSSL_set_psk_server_callback(WOLFSSL* ssl,wc_psk_server_callback cb)
14965
    {
14966
        byte haveRSA = 1;
14967
        int  keySz   = 0;
14968
14969
        WOLFSSL_ENTER("SSL_set_psk_server_callback");
14970
        if (ssl == NULL)
14971
            return;
14972
14973
        ssl->options.havePSK = 1;
14974
        ssl->options.server_psk_cb = cb;
14975
14976
        #ifdef NO_RSA
14977
            haveRSA = 0;
14978
        #endif
14979
        #ifndef NO_CERTS
14980
            keySz = ssl->buffers.keySz;
14981
        #endif
14982
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, TRUE,
14983
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
14984
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
14985
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
14986
                   ssl->options.haveAnon, TRUE, ssl->options.side);
14987
    }
14988
14989
    const char* wolfSSL_get_psk_identity_hint(const WOLFSSL* ssl)
14990
    {
14991
        WOLFSSL_ENTER("SSL_get_psk_identity_hint");
14992
14993
        if (ssl == NULL || ssl->arrays == NULL)
14994
            return NULL;
14995
14996
        return ssl->arrays->server_hint;
14997
    }
14998
14999
15000
    const char* wolfSSL_get_psk_identity(const WOLFSSL* ssl)
15001
    {
15002
        WOLFSSL_ENTER("SSL_get_psk_identity");
15003
15004
        if (ssl == NULL || ssl->arrays == NULL)
15005
            return NULL;
15006
15007
        return ssl->arrays->client_identity;
15008
    }
15009
15010
    int wolfSSL_CTX_use_psk_identity_hint(WOLFSSL_CTX* ctx, const char* hint)
15011
    {
15012
        WOLFSSL_ENTER("SSL_CTX_use_psk_identity_hint");
15013
        if (hint == 0)
15014
            ctx->server_hint[0] = '\0';
15015
        else {
15016
            /* Qt does not call CTX_set_*_psk_callbacks where havePSK is set */
15017
            #ifdef WOLFSSL_QT
15018
            ctx->havePSK=1;
15019
            #endif
15020
            XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
15021
            ctx->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */
15022
        }
15023
        return WOLFSSL_SUCCESS;
15024
    }
15025
15026
    int wolfSSL_use_psk_identity_hint(WOLFSSL* ssl, const char* hint)
15027
    {
15028
        WOLFSSL_ENTER("SSL_use_psk_identity_hint");
15029
15030
        if (ssl == NULL || ssl->arrays == NULL)
15031
            return WOLFSSL_FAILURE;
15032
15033
        if (hint == 0)
15034
            ssl->arrays->server_hint[0] = 0;
15035
        else {
15036
            XSTRNCPY(ssl->arrays->server_hint, hint,
15037
                                            sizeof(ssl->arrays->server_hint)-1);
15038
            ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0';
15039
        }
15040
        return WOLFSSL_SUCCESS;
15041
    }
15042
15043
    void* wolfSSL_get_psk_callback_ctx(WOLFSSL* ssl)
15044
    {
15045
        return ssl ? ssl->options.psk_ctx : NULL;
15046
    }
15047
    void* wolfSSL_CTX_get_psk_callback_ctx(WOLFSSL_CTX* ctx)
15048
    {
15049
        return ctx ? ctx->psk_ctx : NULL;
15050
    }
15051
    int wolfSSL_set_psk_callback_ctx(WOLFSSL* ssl, void* psk_ctx)
15052
    {
15053
        if (ssl == NULL)
15054
            return WOLFSSL_FAILURE;
15055
        ssl->options.psk_ctx = psk_ctx;
15056
        return WOLFSSL_SUCCESS;
15057
    }
15058
    int wolfSSL_CTX_set_psk_callback_ctx(WOLFSSL_CTX* ctx, void* psk_ctx)
15059
    {
15060
        if (ctx == NULL)
15061
            return WOLFSSL_FAILURE;
15062
        ctx->psk_ctx = psk_ctx;
15063
        return WOLFSSL_SUCCESS;
15064
    }
15065
#endif /* NO_PSK */
15066
15067
15068
#ifdef HAVE_ANON
15069
15070
    int wolfSSL_CTX_allow_anon_cipher(WOLFSSL_CTX* ctx)
15071
    {
15072
        WOLFSSL_ENTER("wolfSSL_CTX_allow_anon_cipher");
15073
15074
        if (ctx == NULL)
15075
            return WOLFSSL_FAILURE;
15076
15077
        ctx->haveAnon = 1;
15078
15079
        return WOLFSSL_SUCCESS;
15080
    }
15081
15082
#endif /* HAVE_ANON */
15083
15084
15085
#ifndef NO_CERTS
15086
/* used to be defined on NO_FILESYSTEM only, but are generally useful */
15087
15088
    int wolfSSL_CTX_load_verify_buffer_ex(WOLFSSL_CTX* ctx,
15089
                                         const unsigned char* in,
15090
                                         long sz, int format, int userChain,
15091
                                         word32 flags)
15092
0
    {
15093
0
        int verify;
15094
0
        int ret = WOLFSSL_FAILURE;
15095
15096
0
        WOLFSSL_ENTER("wolfSSL_CTX_load_verify_buffer_ex");
15097
15098
0
        verify = GET_VERIFY_SETTING_CTX(ctx);
15099
0
        if (flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY)
15100
0
            verify = VERIFY_SKIP_DATE;
15101
15102
0
        if (format == WOLFSSL_FILETYPE_PEM)
15103
0
            ret = ProcessChainBuffer(ctx, in, sz, format, CA_TYPE, NULL,
15104
0
                                      verify);
15105
0
        else
15106
0
            ret = ProcessBuffer(ctx, in, sz, format, CA_TYPE, NULL, NULL,
15107
0
                                 userChain, verify);
15108
#if defined(WOLFSSL_TRUST_PEER_CERT) && defined(OPENSSL_COMPATIBLE_DEFAULTS)
15109
        if (ret == WOLFSSL_SUCCESS)
15110
            ret = wolfSSL_CTX_trust_peer_buffer(ctx, in, sz, format);
15111
#endif
15112
15113
0
        WOLFSSL_LEAVE("wolfSSL_CTX_load_verify_buffer_ex", ret);
15114
0
        return ret;
15115
0
    }
15116
15117
    /* wolfSSL extension allows DER files to be loaded from buffers as well */
15118
    int wolfSSL_CTX_load_verify_buffer(WOLFSSL_CTX* ctx,
15119
                                       const unsigned char* in,
15120
                                       long sz, int format)
15121
0
    {
15122
0
        return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 0,
15123
0
            WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
15124
0
    }
15125
15126
    int wolfSSL_CTX_load_verify_chain_buffer_format(WOLFSSL_CTX* ctx,
15127
                                       const unsigned char* in,
15128
                                       long sz, int format)
15129
0
    {
15130
0
        return wolfSSL_CTX_load_verify_buffer_ex(ctx, in, sz, format, 1,
15131
0
            WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
15132
0
    }
15133
15134
15135
#ifdef WOLFSSL_TRUST_PEER_CERT
15136
    int wolfSSL_CTX_trust_peer_buffer(WOLFSSL_CTX* ctx,
15137
                                       const unsigned char* in,
15138
                                       long sz, int format)
15139
    {
15140
        WOLFSSL_ENTER("wolfSSL_CTX_trust_peer_buffer");
15141
15142
        /* sanity check on arguments */
15143
        if (sz < 0 || in == NULL || ctx == NULL) {
15144
            return BAD_FUNC_ARG;
15145
        }
15146
15147
        if (format == WOLFSSL_FILETYPE_PEM)
15148
            return ProcessChainBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE,
15149
                                      NULL, GET_VERIFY_SETTING_CTX(ctx));
15150
        else
15151
            return ProcessBuffer(ctx, in, sz, format, TRUSTED_PEER_TYPE, NULL,
15152
                                 NULL, 0, GET_VERIFY_SETTING_CTX(ctx));
15153
    }
15154
#endif /* WOLFSSL_TRUST_PEER_CERT */
15155
15156
15157
    int wolfSSL_CTX_use_certificate_buffer(WOLFSSL_CTX* ctx,
15158
                                 const unsigned char* in, long sz, int format)
15159
0
    {
15160
0
        int ret = WOLFSSL_FAILURE;
15161
15162
0
        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_buffer");
15163
0
        ret = ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 0,
15164
0
                             GET_VERIFY_SETTING_CTX(ctx));
15165
0
        WOLFSSL_LEAVE("wolfSSL_CTX_use_certificate_buffer", ret);
15166
0
        return ret;
15167
0
    }
15168
15169
15170
    int wolfSSL_CTX_use_PrivateKey_buffer(WOLFSSL_CTX* ctx,
15171
                                 const unsigned char* in, long sz, int format)
15172
0
    {
15173
0
        int ret = WOLFSSL_FAILURE;
15174
15175
0
        WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer");
15176
0
        ret = ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL, NULL,
15177
0
                             0, GET_VERIFY_SETTING_CTX(ctx));
15178
0
        WOLFSSL_LEAVE("wolfSSL_CTX_use_PrivateKey_buffer", ret);
15179
0
        return ret;
15180
0
    }
15181
15182
#ifdef WOLF_PRIVATE_KEY_ID
15183
    int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id,
15184
                                      long sz, int devId, long keySz)
15185
0
    {
15186
0
        int ret = wolfSSL_CTX_use_PrivateKey_Id(ctx, id, sz, devId);
15187
15188
0
        if (ret == WOLFSSL_SUCCESS)
15189
0
            ctx->privateKeySz = (word32)keySz;
15190
15191
0
        return ret;
15192
0
    }
15193
15194
    int wolfSSL_CTX_use_PrivateKey_Id(WOLFSSL_CTX* ctx, const unsigned char* id,
15195
                                      long sz, int devId)
15196
0
    {
15197
0
        int ret = WOLFSSL_FAILURE;
15198
15199
0
        FreeDer(&ctx->privateKey);
15200
0
        if (AllocDer(&ctx->privateKey, (word32)sz, PRIVATEKEY_TYPE,
15201
0
                                                              ctx->heap) == 0) {
15202
0
            XMEMCPY(ctx->privateKey->buffer, id, sz);
15203
0
            ctx->privateKeyId = 1;
15204
0
            if (devId != INVALID_DEVID)
15205
0
                ctx->privateKeyDevId = devId;
15206
0
            else
15207
0
                ctx->privateKeyDevId = ctx->devId;
15208
15209
0
            ret = WOLFSSL_SUCCESS;
15210
0
        }
15211
15212
0
        return ret;
15213
0
    }
15214
15215
    int wolfSSL_CTX_use_PrivateKey_Label(WOLFSSL_CTX* ctx, const char* label,
15216
                                         int devId)
15217
0
    {
15218
0
        int ret = WOLFSSL_FAILURE;
15219
0
        word32 sz = (word32)XSTRLEN(label) + 1;
15220
15221
0
        FreeDer(&ctx->privateKey);
15222
0
        if (AllocDer(&ctx->privateKey, (word32)sz, PRIVATEKEY_TYPE,
15223
0
                                                              ctx->heap) == 0) {
15224
0
            XMEMCPY(ctx->privateKey->buffer, label, sz);
15225
0
            ctx->privateKeyLabel = 1;
15226
0
            if (devId != INVALID_DEVID)
15227
0
                ctx->privateKeyDevId = devId;
15228
0
            else
15229
0
                ctx->privateKeyDevId = ctx->devId;
15230
15231
0
            ret = WOLFSSL_SUCCESS;
15232
0
        }
15233
15234
0
        return ret;
15235
0
    }
15236
#endif /* WOLF_PRIVATE_KEY_ID */
15237
15238
    int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx,
15239
                                 const unsigned char* in, long sz, int format)
15240
0
    {
15241
0
        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_chain_buffer_format");
15242
0
        return ProcessBuffer(ctx, in, sz, format, CERT_TYPE, NULL, NULL, 1,
15243
0
                             GET_VERIFY_SETTING_CTX(ctx));
15244
0
    }
15245
15246
    int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx,
15247
                                 const unsigned char* in, long sz)
15248
0
    {
15249
0
        return wolfSSL_CTX_use_certificate_chain_buffer_format(ctx, in, sz,
15250
0
                                                            WOLFSSL_FILETYPE_PEM);
15251
0
    }
15252
15253
15254
#ifndef NO_DH
15255
15256
    /* server wrapper for ctx or ssl Diffie-Hellman parameters */
15257
    static int wolfSSL_SetTmpDH_buffer_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
15258
                                               const unsigned char* buf,
15259
                                               long sz, int format)
15260
0
    {
15261
0
        DerBuffer* der = NULL;
15262
0
        int    ret      = 0;
15263
0
        word32 pSz = MAX_DH_SIZE;
15264
0
        word32 gSz = MAX_DH_SIZE;
15265
0
    #ifdef WOLFSSL_SMALL_STACK
15266
0
        byte*  p = NULL;
15267
0
        byte*  g = NULL;
15268
    #else
15269
        byte   p[MAX_DH_SIZE];
15270
        byte   g[MAX_DH_SIZE];
15271
    #endif
15272
15273
0
        if (ctx == NULL || buf == NULL)
15274
0
            return BAD_FUNC_ARG;
15275
15276
0
        ret = AllocDer(&der, 0, DH_PARAM_TYPE, ctx->heap);
15277
0
        if (ret != 0) {
15278
0
            return ret;
15279
0
        }
15280
0
        der->buffer = (byte*)buf;
15281
0
        der->length = (word32)sz;
15282
15283
0
    #ifdef WOLFSSL_SMALL_STACK
15284
0
        p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15285
0
        g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15286
15287
0
        if (p == NULL || g == NULL) {
15288
0
            XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15289
0
            XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15290
0
            return MEMORY_E;
15291
0
        }
15292
0
    #endif
15293
15294
0
        if (format != WOLFSSL_FILETYPE_ASN1 && format != WOLFSSL_FILETYPE_PEM)
15295
0
            ret = WOLFSSL_BAD_FILETYPE;
15296
0
        else {
15297
0
            if (format == WOLFSSL_FILETYPE_PEM) {
15298
0
#ifdef WOLFSSL_PEM_TO_DER
15299
0
                FreeDer(&der);
15300
0
                ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, ctx->heap,
15301
0
                               NULL, NULL);
15302
0
                if (ret < 0) {
15303
                    /* Also try X9.42 format */
15304
0
                    ret = PemToDer(buf, sz, X942_PARAM_TYPE, &der, ctx->heap,
15305
0
                               NULL, NULL);
15306
0
                }
15307
    #ifdef WOLFSSL_WPAS
15308
        #ifndef NO_DSA
15309
                if (ret < 0) {
15310
                    ret = PemToDer(buf, sz, DSA_PARAM_TYPE, &der, ctx->heap,
15311
                               NULL, NULL);
15312
                }
15313
        #endif
15314
    #endif /* WOLFSSL_WPAS */
15315
#else
15316
                ret = NOT_COMPILED_IN;
15317
#endif /* WOLFSSL_PEM_TO_DER */
15318
0
            }
15319
15320
0
            if (ret == 0) {
15321
0
                if (wc_DhParamsLoad(der->buffer, der->length, p, &pSz, g, &gSz) < 0)
15322
0
                    ret = WOLFSSL_BAD_FILETYPE;
15323
0
                else if (ssl)
15324
0
                    ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
15325
0
                else
15326
0
                    ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
15327
0
            }
15328
0
        }
15329
15330
0
        FreeDer(&der);
15331
15332
0
    #ifdef WOLFSSL_SMALL_STACK
15333
0
        XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15334
0
        XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
15335
0
    #endif
15336
15337
0
        return ret;
15338
0
    }
15339
15340
15341
    /* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
15342
    int wolfSSL_SetTmpDH_buffer(WOLFSSL* ssl, const unsigned char* buf, long sz,
15343
                               int format)
15344
0
    {
15345
0
        if (ssl == NULL)
15346
0
            return BAD_FUNC_ARG;
15347
15348
0
        return wolfSSL_SetTmpDH_buffer_wrapper(ssl->ctx, ssl, buf, sz, format);
15349
0
    }
15350
15351
15352
    /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
15353
    int wolfSSL_CTX_SetTmpDH_buffer(WOLFSSL_CTX* ctx, const unsigned char* buf,
15354
                                   long sz, int format)
15355
0
    {
15356
0
        return wolfSSL_SetTmpDH_buffer_wrapper(ctx, NULL, buf, sz, format);
15357
0
    }
15358
15359
#endif /* NO_DH */
15360
15361
15362
    int wolfSSL_use_certificate_buffer(WOLFSSL* ssl,
15363
                                 const unsigned char* in, long sz, int format)
15364
0
    {
15365
0
        WOLFSSL_ENTER("wolfSSL_use_certificate_buffer");
15366
0
        if (ssl == NULL)
15367
0
            return BAD_FUNC_ARG;
15368
15369
0
        return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE, ssl, NULL, 0,
15370
0
                             GET_VERIFY_SETTING_SSL(ssl));
15371
0
    }
15372
15373
15374
    int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl,
15375
                                 const unsigned char* in, long sz, int format)
15376
0
    {
15377
0
        WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer");
15378
0
        if (ssl == NULL)
15379
0
            return BAD_FUNC_ARG;
15380
15381
0
        return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE,
15382
0
                             ssl, NULL, 0, GET_VERIFY_SETTING_SSL(ssl));
15383
0
    }
15384
15385
#ifdef WOLF_PRIVATE_KEY_ID
15386
    int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id,
15387
                                  long sz, int devId, long keySz)
15388
0
    {
15389
0
        int ret = wolfSSL_use_PrivateKey_Id(ssl, id, sz, devId);
15390
15391
0
        if (ret == WOLFSSL_SUCCESS)
15392
0
            ssl->buffers.keySz = (word32)keySz;
15393
15394
0
        return ret;
15395
0
    }
15396
15397
    int wolfSSL_use_PrivateKey_Id(WOLFSSL* ssl, const unsigned char* id,
15398
                                  long sz, int devId)
15399
0
    {
15400
0
        int ret = WOLFSSL_FAILURE;
15401
15402
0
        if (ssl->buffers.weOwnKey)
15403
0
            FreeDer(&ssl->buffers.key);
15404
0
        if (AllocDer(&ssl->buffers.key, (word32)sz, PRIVATEKEY_TYPE,
15405
0
                                                            ssl->heap) == 0) {
15406
0
            XMEMCPY(ssl->buffers.key->buffer, id, sz);
15407
0
            ssl->buffers.weOwnKey = 1;
15408
0
            ssl->buffers.keyId = 1;
15409
0
            if (devId != INVALID_DEVID)
15410
0
                ssl->buffers.keyDevId = devId;
15411
0
            else
15412
0
                ssl->buffers.keyDevId = ssl->devId;
15413
15414
0
            ret = WOLFSSL_SUCCESS;
15415
0
        }
15416
15417
0
        return ret;
15418
0
    }
15419
15420
    int wolfSSL_use_PrivateKey_Label(WOLFSSL* ssl, const char* label, int devId)
15421
0
    {
15422
0
        int ret = WOLFSSL_FAILURE;
15423
0
        word32 sz = (word32)XSTRLEN(label) + 1;
15424
15425
0
        if (ssl->buffers.weOwnKey)
15426
0
            FreeDer(&ssl->buffers.key);
15427
0
        if (AllocDer(&ssl->buffers.key, (word32)sz, PRIVATEKEY_TYPE,
15428
0
                                                            ssl->heap) == 0) {
15429
0
            XMEMCPY(ssl->buffers.key->buffer, label, sz);
15430
0
            ssl->buffers.weOwnKey = 1;
15431
0
            ssl->buffers.keyLabel = 1;
15432
0
            if (devId != INVALID_DEVID)
15433
0
                ssl->buffers.keyDevId = devId;
15434
0
            else
15435
0
                ssl->buffers.keyDevId = ssl->devId;
15436
15437
0
            ret = WOLFSSL_SUCCESS;
15438
0
        }
15439
15440
0
        return ret;
15441
0
    }
15442
#endif /* WOLF_PRIVATE_KEY_ID */
15443
15444
    int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl,
15445
                                 const unsigned char* in, long sz, int format)
15446
0
    {
15447
0
        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
15448
0
        if (ssl == NULL)
15449
0
            return BAD_FUNC_ARG;
15450
15451
0
        return ProcessBuffer(ssl->ctx, in, sz, format, CERT_TYPE,
15452
0
                             ssl, NULL, 1, GET_VERIFY_SETTING_SSL(ssl));
15453
0
    }
15454
15455
    int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl,
15456
                                 const unsigned char* in, long sz)
15457
0
    {
15458
0
        return wolfSSL_use_certificate_chain_buffer_format(ssl, in, sz,
15459
0
                                                            WOLFSSL_FILETYPE_PEM);
15460
0
    }
15461
15462
15463
    /* unload any certs or keys that SSL owns, leave CTX as is
15464
       WOLFSSL_SUCCESS on ok */
15465
    int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
15466
0
    {
15467
0
        if (ssl == NULL) {
15468
0
            WOLFSSL_MSG("Null function arg");
15469
0
            return BAD_FUNC_ARG;
15470
0
        }
15471
15472
0
        if (ssl->buffers.weOwnCert && !ssl->keepCert) {
15473
0
            WOLFSSL_MSG("Unloading cert");
15474
0
            FreeDer(&ssl->buffers.certificate);
15475
0
            #ifdef KEEP_OUR_CERT
15476
0
            wolfSSL_X509_free(ssl->ourCert);
15477
0
            ssl->ourCert = NULL;
15478
0
            #endif
15479
0
            ssl->buffers.weOwnCert = 0;
15480
0
        }
15481
15482
0
        if (ssl->buffers.weOwnCertChain) {
15483
0
            WOLFSSL_MSG("Unloading cert chain");
15484
0
            FreeDer(&ssl->buffers.certChain);
15485
0
            ssl->buffers.weOwnCertChain = 0;
15486
0
        }
15487
15488
0
        if (ssl->buffers.weOwnKey) {
15489
0
            WOLFSSL_MSG("Unloading key");
15490
0
            ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
15491
0
            FreeDer(&ssl->buffers.key);
15492
0
            ssl->buffers.weOwnKey = 0;
15493
0
        }
15494
15495
0
        return WOLFSSL_SUCCESS;
15496
0
    }
15497
15498
15499
    int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
15500
0
    {
15501
0
        WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
15502
15503
0
        if (ctx == NULL)
15504
0
            return BAD_FUNC_ARG;
15505
15506
0
        return wolfSSL_CertManagerUnloadCAs(ctx->cm);
15507
0
    }
15508
15509
15510
#ifdef WOLFSSL_TRUST_PEER_CERT
15511
    int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
15512
    {
15513
        WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
15514
15515
        if (ctx == NULL)
15516
            return BAD_FUNC_ARG;
15517
15518
        return wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
15519
    }
15520
15521
#ifdef WOLFSSL_LOCAL_X509_STORE
15522
    int wolfSSL_Unload_trust_peers(WOLFSSL* ssl)
15523
    {
15524
        WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
15525
15526
        if (ssl == NULL)
15527
            return BAD_FUNC_ARG;
15528
15529
        return wolfSSL_CertManagerUnload_trust_peers(SSL_CM(ssl));
15530
    }
15531
#endif /* WOLFSSL_LOCAL_X509_STORE */
15532
#endif /* WOLFSSL_TRUST_PEER_CERT */
15533
/* old NO_FILESYSTEM end */
15534
#endif /* !NO_CERTS */
15535
15536
15537
#ifdef OPENSSL_EXTRA
15538
15539
    int wolfSSL_add_all_algorithms(void)
15540
0
    {
15541
0
        WOLFSSL_ENTER("wolfSSL_add_all_algorithms");
15542
0
        if (initRefCount != 0 || wolfSSL_Init() == WOLFSSL_SUCCESS)
15543
0
            return WOLFSSL_SUCCESS;
15544
0
        else
15545
0
            return WOLFSSL_FATAL_ERROR;
15546
0
    }
15547
15548
    int wolfSSL_OpenSSL_add_all_algorithms_noconf(void)
15549
0
    {
15550
0
        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_noconf");
15551
15552
0
        if  (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR)
15553
0
            return WOLFSSL_FATAL_ERROR;
15554
15555
0
        return  WOLFSSL_SUCCESS;
15556
0
    }
15557
15558
    int wolfSSL_OpenSSL_add_all_algorithms_conf(void)
15559
0
    {
15560
0
        WOLFSSL_ENTER("wolfSSL_OpenSSL_add_all_algorithms_conf");
15561
        /* This function is currently the same as
15562
        wolfSSL_OpenSSL_add_all_algorithms_noconf since we do not employ
15563
        the use of a wolfssl.cnf type configuration file and is only used for
15564
        OpenSSL compatability. */
15565
15566
0
        if (wolfSSL_add_all_algorithms() == WOLFSSL_FATAL_ERROR) {
15567
0
            return WOLFSSL_FATAL_ERROR;
15568
0
        }
15569
0
        return WOLFSSL_SUCCESS;
15570
0
    }
15571
15572
   /* returns previous set cache size which stays constant */
15573
    long wolfSSL_CTX_sess_set_cache_size(WOLFSSL_CTX* ctx, long sz)
15574
0
    {
15575
        /* cache size fixed at compile time in wolfSSL */
15576
0
        (void)ctx;
15577
0
        (void)sz;
15578
0
        WOLFSSL_MSG("session cache is set at compile time");
15579
0
        #ifndef NO_SESSION_CACHE
15580
0
            return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
15581
        #else
15582
            return 0;
15583
        #endif
15584
0
    }
15585
15586
#endif
15587
15588
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
15589
    void wolfSSL_CTX_set_quiet_shutdown(WOLFSSL_CTX* ctx, int mode)
15590
0
    {
15591
0
        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
15592
0
        if (mode)
15593
0
            ctx->quietShutdown = 1;
15594
0
    }
15595
15596
15597
    void wolfSSL_set_quiet_shutdown(WOLFSSL* ssl, int mode)
15598
0
    {
15599
0
        WOLFSSL_ENTER("wolfSSL_CTX_set_quiet_shutdown");
15600
0
        if (mode)
15601
0
            ssl->options.quietShutdown = 1;
15602
0
    }
15603
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
15604
15605
#ifdef OPENSSL_EXTRA
15606
#ifndef NO_BIO
15607
    void wolfSSL_set_bio(WOLFSSL* ssl, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr)
15608
0
    {
15609
0
        WOLFSSL_ENTER("wolfSSL_set_bio");
15610
15611
0
        if (ssl == NULL) {
15612
0
            WOLFSSL_MSG("Bad argument, ssl was NULL");
15613
0
            return;
15614
0
        }
15615
15616
        /* free any existing WOLFSSL_BIOs in use but don't free those in
15617
         * a chain */
15618
0
        if (ssl->biord != NULL) {
15619
0
            if (ssl->biord != ssl->biowr) {
15620
0
                if (ssl->biowr != NULL && ssl->biowr->prev != NULL)
15621
0
                    wolfSSL_BIO_free(ssl->biowr);
15622
0
                ssl->biowr = NULL;
15623
0
            }
15624
0
            if (ssl->biord->prev != NULL)
15625
0
                wolfSSL_BIO_free(ssl->biord);
15626
0
            ssl->biord = NULL;
15627
0
        }
15628
        /* set flag obviously */
15629
0
        if (rd && !(rd->flags & WOLFSSL_BIO_FLAG_READ))
15630
0
            rd->flags |= WOLFSSL_BIO_FLAG_READ;
15631
0
        if (wr && !(wr->flags & WOLFSSL_BIO_FLAG_WRITE))
15632
0
            wr->flags |= WOLFSSL_BIO_FLAG_WRITE;
15633
15634
0
        ssl->biord = rd;
15635
0
        ssl->biowr = wr;
15636
15637
        /* set SSL to use BIO callbacks instead */
15638
0
        if (((ssl->cbioFlag & WOLFSSL_CBIO_RECV) == 0)) {
15639
0
            ssl->CBIORecv = BioReceive;
15640
0
        }
15641
0
        if (((ssl->cbioFlag & WOLFSSL_CBIO_SEND) == 0)) {
15642
0
            ssl->CBIOSend = BioSend;
15643
0
        }
15644
15645
        /* User programs should always retry reading from these BIOs */
15646
0
        if (rd) {
15647
            /* User writes to rd */
15648
0
            BIO_set_retry_write(rd);
15649
0
        }
15650
0
        if (wr) {
15651
            /* User reads from wr */
15652
0
            BIO_set_retry_read(wr);
15653
0
        }
15654
0
    }
15655
#endif /* !NO_BIO */
15656
#endif /* OPENSSL_EXTRA */
15657
15658
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
15659
    void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
15660
                                       WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
15661
0
    {
15662
0
        WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
15663
0
        if (ctx != NULL) {
15664
0
            wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
15665
0
            ctx->ca_names = names;
15666
0
        }
15667
0
    }
15668
15669
    void wolfSSL_set_client_CA_list(WOLFSSL* ssl,
15670
                                       WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
15671
0
    {
15672
0
        WOLFSSL_ENTER("wolfSSL_set_client_CA_list");
15673
0
        if (ssl != NULL) {
15674
0
            if (ssl->ca_names != ssl->ctx->ca_names)
15675
0
                wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
15676
0
            ssl->ca_names = names;
15677
0
        }
15678
0
    }
15679
15680
    #ifdef OPENSSL_EXTRA
15681
    /* registers client cert callback, called during handshake if server
15682
       requests client auth but user has not loaded client cert/key */
15683
    void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb)
15684
0
    {
15685
0
        WOLFSSL_ENTER("wolfSSL_CTX_set_client_cert_cb");
15686
15687
0
        if (ctx != NULL) {
15688
0
            ctx->CBClientCert = cb;
15689
0
        }
15690
0
    }
15691
15692
    void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx,
15693
        CertSetupCallback cb, void *arg)
15694
0
    {
15695
0
        WOLFSSL_ENTER("wolfSSL_CTX_set_cert_cb");
15696
0
        if (ctx == NULL)
15697
0
            return;
15698
15699
0
        ctx->certSetupCb = cb;
15700
0
        ctx->certSetupCbArg = arg;
15701
0
    }
15702
15703
    /**
15704
     * Internal wrapper for calling certSetupCb
15705
     * @param ssl The SSL/TLS Object
15706
     * @return 0 on success
15707
     */
15708
    int CertSetupCbWrapper(WOLFSSL* ssl)
15709
0
    {
15710
0
        int ret = 0;
15711
0
        if (ssl->ctx->certSetupCb != NULL) {
15712
0
            WOLFSSL_MSG("Calling user cert setup callback");
15713
0
            ret = ssl->ctx->certSetupCb(ssl, ssl->ctx->certSetupCbArg);
15714
0
            if (ret == 1) {
15715
0
                WOLFSSL_MSG("User cert callback returned success");
15716
0
                ret = 0;
15717
0
            }
15718
0
            else if (ret == 0) {
15719
0
                SendAlert(ssl, alert_fatal, internal_error);
15720
0
                ret = CLIENT_CERT_CB_ERROR;
15721
0
            }
15722
0
            else if (ret < 0) {
15723
0
                ret = WOLFSSL_ERROR_WANT_X509_LOOKUP;
15724
0
            }
15725
0
            else {
15726
0
                WOLFSSL_MSG("Unexpected user callback return");
15727
0
                ret = CLIENT_CERT_CB_ERROR;
15728
0
            }
15729
0
        }
15730
0
        return ret;
15731
0
    }
15732
    #endif /* OPENSSL_EXTRA */
15733
15734
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || HAVE_WEBSERVER */
15735
15736
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA)
15737
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
15738
            const WOLFSSL_CTX *ctx)
15739
0
    {
15740
0
        WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list");
15741
15742
0
        if (ctx == NULL) {
15743
0
            WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get_client_CA_list");
15744
0
            return NULL;
15745
0
        }
15746
15747
0
        return ctx->ca_names;
15748
0
    }
15749
15750
    /* returns the CA's set on server side or the CA's sent from server when
15751
     * on client side */
15752
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list(
15753
            const WOLFSSL* ssl)
15754
0
    {
15755
0
        WOLFSSL_ENTER("wolfSSL_get_client_CA_list");
15756
15757
0
        if (ssl == NULL) {
15758
0
            WOLFSSL_MSG("Bad argument passed to wolfSSL_get_client_CA_list");
15759
0
            return NULL;
15760
0
        }
15761
15762
0
        return SSL_CA_NAMES(ssl);
15763
0
    }
15764
15765
    #if !defined(NO_CERTS)
15766
    int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
15767
0
    {
15768
0
        WOLFSSL_X509_NAME *nameCopy = NULL;
15769
15770
0
        WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
15771
15772
0
        if (ctx == NULL || x509 == NULL){
15773
0
            WOLFSSL_MSG("Bad argument");
15774
0
            return WOLFSSL_FAILURE;
15775
0
        }
15776
15777
0
        if (ctx->ca_names == NULL) {
15778
0
            ctx->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
15779
0
            if (ctx->ca_names == NULL) {
15780
0
                WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
15781
0
                return WOLFSSL_FAILURE;
15782
0
            }
15783
0
        }
15784
15785
0
        nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(x509));
15786
0
        if (nameCopy == NULL) {
15787
0
            WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
15788
0
            return WOLFSSL_FAILURE;
15789
0
        }
15790
15791
0
        if (wolfSSL_sk_X509_NAME_push(ctx->ca_names, nameCopy) != WOLFSSL_SUCCESS) {
15792
0
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
15793
0
            wolfSSL_X509_NAME_free(nameCopy);
15794
0
            return WOLFSSL_FAILURE;
15795
0
        }
15796
15797
0
        return WOLFSSL_SUCCESS;
15798
0
    }
15799
    #endif
15800
15801
    #ifndef NO_BIO
15802
        #if !defined(NO_RSA) && !defined(NO_CERTS)
15803
        WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
15804
0
        {
15805
            /* The webserver build is using this to load a CA into the server
15806
             * for client authentication as an option. Have this return NULL in
15807
             * that case. If OPENSSL_EXTRA is enabled, go ahead and include
15808
             * the function. */
15809
0
        #ifdef OPENSSL_EXTRA
15810
0
            WOLFSSL_STACK *list = NULL;
15811
0
            WOLFSSL_BIO* bio = NULL;
15812
0
            WOLFSSL_X509 *cert = NULL;
15813
0
            WOLFSSL_X509_NAME *nameCopy = NULL;
15814
0
            unsigned long err = WOLFSSL_FAILURE;
15815
15816
0
            WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
15817
15818
0
            bio = wolfSSL_BIO_new_file(fname, "rb");
15819
0
            if (bio == NULL) {
15820
0
                WOLFSSL_MSG("wolfSSL_BIO_new_file error");
15821
0
                goto cleanup;
15822
0
            }
15823
15824
0
            list = wolfSSL_sk_X509_NAME_new(NULL);
15825
0
            if (list == NULL) {
15826
0
                WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
15827
0
                goto cleanup;
15828
0
            }
15829
15830
            /* Read each certificate in the chain out of the file. */
15831
0
            while (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
15832
                /* Need a persistent copy of the subject name. */
15833
0
                nameCopy = wolfSSL_X509_NAME_dup(
15834
0
                        wolfSSL_X509_get_subject_name(cert));
15835
0
                if (nameCopy == NULL) {
15836
0
                    WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
15837
0
                    goto cleanup;
15838
0
                }
15839
                /*
15840
                * Original cert will be freed so make sure not to try to access
15841
                * it in the future.
15842
                */
15843
0
                nameCopy->x509 = NULL;
15844
15845
0
                if (wolfSSL_sk_X509_NAME_push(list, nameCopy) !=
15846
0
                        WOLFSSL_SUCCESS) {
15847
0
                    WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
15848
                    /* Do free in loop because nameCopy is now responsibility
15849
                     * of list to free and adding jumps to cleanup after this
15850
                     * might result in a double free. */
15851
0
                    wolfSSL_X509_NAME_free(nameCopy);
15852
0
                    goto cleanup;
15853
0
                }
15854
15855
0
                wolfSSL_X509_free(cert);
15856
0
                cert = NULL;
15857
0
            }
15858
15859
0
            CLEAR_ASN_NO_PEM_HEADER_ERROR(err);
15860
15861
0
            err = WOLFSSL_SUCCESS;
15862
0
cleanup:
15863
0
            wolfSSL_X509_free(cert);
15864
0
            wolfSSL_BIO_free(bio);
15865
0
            if (err != WOLFSSL_SUCCESS) {
15866
                /* We failed so return NULL */
15867
0
                wolfSSL_sk_X509_NAME_pop_free(list, NULL);
15868
0
                list = NULL;
15869
0
            }
15870
0
            return list;
15871
        #else
15872
            (void)fname;
15873
            return NULL;
15874
        #endif
15875
0
        }
15876
        #endif
15877
    #endif /* !NO_BIO */
15878
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA */
15879
15880
#ifdef OPENSSL_EXTRA
15881
15882
    #ifndef NO_WOLFSSL_STUB
15883
    int wolfSSL_CTX_set_default_verify_paths(WOLFSSL_CTX* ctx)
15884
0
    {
15885
        /* TODO:, not needed in goahead */
15886
0
        (void)ctx;
15887
0
        WOLFSSL_STUB("SSL_CTX_set_default_verify_paths");
15888
0
        return SSL_NOT_IMPLEMENTED;
15889
0
    }
15890
    #endif
15891
15892
    #if defined(WOLFCRYPT_HAVE_SRP) && !defined(NO_SHA256) \
15893
        && !defined(WC_NO_RNG)
15894
    static const byte srp_N[] = {
15895
        0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6, 0x9C, 0x33, 0xF8,
15896
        0x0A, 0xFA, 0x8F, 0xC5, 0xE8, 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF,
15897
        0x3C, 0x0B, 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76, 0xD6,
15898
        0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3, 0x38, 0x3B, 0x48, 0x13,
15899
        0xD6, 0x92, 0xC6, 0xE0, 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B,
15900
        0xE4, 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1, 0x5D, 0xC7,
15901
        0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6, 0xCE, 0x8E, 0xF4, 0xAD, 0x69,
15902
        0xB1, 0x5D, 0x49, 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
15903
        0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC, 0x68, 0xED, 0xBC,
15904
        0x3C, 0x05, 0x72, 0x6C, 0xC0, 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E,
15905
        0xAA, 0x9A, 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B, 0x9F,
15906
        0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
15907
    };
15908
    static const byte srp_g[] = {
15909
        0x02
15910
    };
15911
15912
    int wolfSSL_CTX_set_srp_username(WOLFSSL_CTX* ctx, char* username)
15913
    {
15914
        int r = 0;
15915
        SrpSide srp_side = SRP_CLIENT_SIDE;
15916
        byte salt[SRP_SALT_SIZE];
15917
15918
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_username");
15919
        if (ctx == NULL || ctx->srp == NULL || username==NULL)
15920
            return SSL_FAILURE;
15921
15922
        if (ctx->method->side == WOLFSSL_SERVER_END){
15923
            srp_side = SRP_SERVER_SIDE;
15924
        } else if (ctx->method->side == WOLFSSL_CLIENT_END){
15925
            srp_side = SRP_CLIENT_SIDE;
15926
        } else {
15927
            WOLFSSL_MSG("Init CTX failed");
15928
            return SSL_FAILURE;
15929
        }
15930
15931
        if (wc_SrpInit(ctx->srp, SRP_TYPE_SHA256, srp_side) < 0) {
15932
            WOLFSSL_MSG("Init SRP CTX failed");
15933
            XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP);
15934
            ctx->srp = NULL;
15935
            return SSL_FAILURE;
15936
        }
15937
        r = wc_SrpSetUsername(ctx->srp, (const byte*)username,
15938
                              (word32)XSTRLEN(username));
15939
        if (r < 0) {
15940
            WOLFSSL_MSG("fail to set srp username.");
15941
            return SSL_FAILURE;
15942
        }
15943
15944
        /* if wolfSSL_CTX_set_srp_password has already been called, */
15945
        /* execute wc_SrpSetPassword here */
15946
        if (ctx->srp_password != NULL) {
15947
            WC_RNG rng;
15948
            if (wc_InitRng(&rng) < 0){
15949
                WOLFSSL_MSG("wc_InitRng failed");
15950
                return SSL_FAILURE;
15951
            }
15952
            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
15953
            r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
15954
            wc_FreeRng(&rng);
15955
            if (r <  0) {
15956
                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
15957
                return SSL_FAILURE;
15958
            }
15959
15960
            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
15961
                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
15962
                                salt, sizeof(salt)/sizeof(salt[0])) < 0) {
15963
                WOLFSSL_MSG("wc_SrpSetParam failed");
15964
                return SSL_FAILURE;
15965
            }
15966
            r = wc_SrpSetPassword(ctx->srp,
15967
                     (const byte*)ctx->srp_password,
15968
                     (word32)XSTRLEN((char *)ctx->srp_password));
15969
            if (r < 0) {
15970
                WOLFSSL_MSG("fail to set srp password.");
15971
                return SSL_FAILURE;
15972
            }
15973
15974
            XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP);
15975
            ctx->srp_password = NULL;
15976
        }
15977
15978
        return WOLFSSL_SUCCESS;
15979
    }
15980
15981
    int wolfSSL_CTX_set_srp_password(WOLFSSL_CTX* ctx, char* password)
15982
    {
15983
        int r;
15984
        byte salt[SRP_SALT_SIZE];
15985
15986
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_password");
15987
        if (ctx == NULL || ctx->srp == NULL || password == NULL)
15988
            return SSL_FAILURE;
15989
15990
        if (ctx->srp->user != NULL) {
15991
            WC_RNG rng;
15992
            if (wc_InitRng(&rng) < 0) {
15993
                WOLFSSL_MSG("wc_InitRng failed");
15994
                return SSL_FAILURE;
15995
            }
15996
            XMEMSET(salt, 0, sizeof(salt)/sizeof(salt[0]));
15997
            r = wc_RNG_GenerateBlock(&rng, salt, sizeof(salt)/sizeof(salt[0]));
15998
            wc_FreeRng(&rng);
15999
            if (r <  0) {
16000
                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
16001
                return SSL_FAILURE;
16002
            }
16003
            if (wc_SrpSetParams(ctx->srp, srp_N, sizeof(srp_N)/sizeof(srp_N[0]),
16004
                                srp_g, sizeof(srp_g)/sizeof(srp_g[0]),
16005
                                salt, sizeof(salt)/sizeof(salt[0])) < 0){
16006
                WOLFSSL_MSG("wc_SrpSetParam failed");
16007
                wc_FreeRng(&rng);
16008
                return SSL_FAILURE;
16009
            }
16010
            r = wc_SrpSetPassword(ctx->srp, (const byte*)password,
16011
                                  (word32)XSTRLEN(password));
16012
            if (r < 0) {
16013
                WOLFSSL_MSG("wc_SrpSetPassword failed.");
16014
                wc_FreeRng(&rng);
16015
                return SSL_FAILURE;
16016
            }
16017
            if (ctx->srp_password != NULL){
16018
                XFREE(ctx->srp_password,NULL,
16019
                      DYNAMIC_TYPE_SRP);
16020
                ctx->srp_password = NULL;
16021
            }
16022
            wc_FreeRng(&rng);
16023
        } else {
16024
            /* save password for wolfSSL_set_srp_username */
16025
            if (ctx->srp_password != NULL)
16026
                XFREE(ctx->srp_password,ctx->heap, DYNAMIC_TYPE_SRP);
16027
16028
            ctx->srp_password = (byte*)XMALLOC(XSTRLEN(password) + 1, ctx->heap,
16029
                                               DYNAMIC_TYPE_SRP);
16030
            if (ctx->srp_password == NULL){
16031
                WOLFSSL_MSG("memory allocation error");
16032
                return SSL_FAILURE;
16033
            }
16034
            XMEMCPY(ctx->srp_password, password, XSTRLEN(password) + 1);
16035
        }
16036
        return WOLFSSL_SUCCESS;
16037
    }
16038
16039
    /**
16040
     * The modulus passed to wc_SrpSetParams in ssl.c is constant so check
16041
     * that the requested strength is less than or equal to the size of the
16042
     * static modulus size.
16043
     * @param ctx Not used
16044
     * @param strength Minimum number of bits for the modulus
16045
     * @return 1 if strength is less than or equal to static modulus
16046
     *         0 if strength is greater than static modulus
16047
     */
16048
    int  wolfSSL_CTX_set_srp_strength(WOLFSSL_CTX *ctx, int strength)
16049
    {
16050
        (void)ctx;
16051
        WOLFSSL_ENTER("wolfSSL_CTX_set_srp_strength");
16052
        if (strength > (int)(sizeof(srp_N)*8)) {
16053
            WOLFSSL_MSG("Bad Parameter");
16054
            return WOLFSSL_FAILURE;
16055
        }
16056
        return WOLFSSL_SUCCESS;
16057
    }
16058
16059
    char* wolfSSL_get_srp_username(WOLFSSL *ssl)
16060
    {
16061
        if (ssl && ssl->ctx && ssl->ctx->srp) {
16062
            return (char*) ssl->ctx->srp->user;
16063
        }
16064
        return NULL;
16065
    }
16066
    #endif /* WOLFCRYPT_HAVE_SRP && !NO_SHA256 && !WC_NO_RNG */
16067
16068
    /* keyblock size in bytes or -1 */
16069
    int wolfSSL_get_keyblock_size(WOLFSSL* ssl)
16070
0
    {
16071
0
        if (ssl == NULL)
16072
0
            return WOLFSSL_FATAL_ERROR;
16073
16074
0
        return 2 * (ssl->specs.key_size + ssl->specs.iv_size +
16075
0
                    ssl->specs.hash_size);
16076
0
    }
16077
16078
#endif /* OPENSSL_EXTRA */
16079
16080
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
16081
16082
    /* store keys returns WOLFSSL_SUCCESS or -1 on error */
16083
    int wolfSSL_get_keys(WOLFSSL* ssl, unsigned char** ms, unsigned int* msLen,
16084
                                     unsigned char** sr, unsigned int* srLen,
16085
                                     unsigned char** cr, unsigned int* crLen)
16086
0
    {
16087
0
        if (ssl == NULL || ssl->arrays == NULL)
16088
0
            return WOLFSSL_FATAL_ERROR;
16089
16090
0
        *ms = ssl->arrays->masterSecret;
16091
0
        *sr = ssl->arrays->serverRandom;
16092
0
        *cr = ssl->arrays->clientRandom;
16093
16094
0
        *msLen = SECRET_LEN;
16095
0
        *srLen = RAN_LEN;
16096
0
        *crLen = RAN_LEN;
16097
16098
0
        return WOLFSSL_SUCCESS;
16099
0
    }
16100
16101
    void wolfSSL_set_accept_state(WOLFSSL* ssl)
16102
0
    {
16103
0
        WOLFSSL_ENTER("wolfSSL_set_accept_state");
16104
16105
0
        if (ssl == NULL)
16106
0
            return;
16107
16108
0
        if (ssl->options.side == WOLFSSL_CLIENT_END) {
16109
0
    #ifdef HAVE_ECC
16110
0
        #ifdef WOLFSSL_SMALL_STACK
16111
0
            ecc_key* key = NULL;
16112
        #else
16113
            ecc_key key[1];
16114
        #endif
16115
0
            word32 idx = 0;
16116
16117
0
        #ifdef WOLFSSL_SMALL_STACK
16118
0
            key = (ecc_key*)XMALLOC(sizeof(ecc_key), ssl->heap,
16119
0
                                    DYNAMIC_TYPE_ECC);
16120
0
            if (key == NULL) {
16121
0
                WOLFSSL_MSG("Error allocating memory for ecc_key");
16122
0
            }
16123
0
        #endif
16124
0
            if (ssl->options.haveStaticECC && ssl->buffers.key != NULL) {
16125
0
                if (wc_ecc_init(key) >= 0) {
16126
0
                    if (wc_EccPrivateKeyDecode(ssl->buffers.key->buffer, &idx,
16127
0
                            key, ssl->buffers.key->length) != 0) {
16128
0
                        ssl->options.haveECDSAsig = 0;
16129
0
                        ssl->options.haveECC = 0;
16130
0
                        ssl->options.haveStaticECC = 0;
16131
0
                    }
16132
0
                    wc_ecc_free(key);
16133
0
                }
16134
0
            }
16135
0
        #ifdef WOLFSSL_SMALL_STACK
16136
0
            XFREE(key, ssl->heap, DYNAMIC_TYPE_ECC);
16137
0
        #endif
16138
0
    #endif
16139
16140
0
    #ifndef NO_DH
16141
0
            if (!ssl->options.haveDH && ssl->ctx->haveDH) {
16142
0
                ssl->buffers.serverDH_P = ssl->ctx->serverDH_P;
16143
0
                ssl->buffers.serverDH_G = ssl->ctx->serverDH_G;
16144
0
                ssl->options.haveDH = 1;
16145
0
            }
16146
0
    #endif
16147
0
        }
16148
16149
0
        if (InitSSL_Side(ssl, WOLFSSL_SERVER_END) != WOLFSSL_SUCCESS) {
16150
0
            WOLFSSL_MSG("Error initializing server side");
16151
0
        }
16152
0
    }
16153
16154
#endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */
16155
16156
    /* return true if connection established */
16157
    int wolfSSL_is_init_finished(WOLFSSL* ssl)
16158
0
    {
16159
0
        if (ssl == NULL)
16160
0
            return 0;
16161
16162
0
        if (ssl->options.handShakeState == HANDSHAKE_DONE)
16163
0
            return 1;
16164
16165
0
        return 0;
16166
0
    }
16167
16168
#ifdef OPENSSL_EXTRA
16169
    void wolfSSL_CTX_set_tmp_rsa_callback(WOLFSSL_CTX* ctx,
16170
                                      WOLFSSL_RSA*(*f)(WOLFSSL*, int, int))
16171
0
    {
16172
        /* wolfSSL verifies all these internally */
16173
0
        (void)ctx;
16174
0
        (void)f;
16175
0
    }
16176
16177
16178
    void wolfSSL_set_shutdown(WOLFSSL* ssl, int opt)
16179
0
    {
16180
0
        WOLFSSL_ENTER("wolfSSL_set_shutdown");
16181
0
        if(ssl==NULL) {
16182
0
            WOLFSSL_MSG("Shutdown not set. ssl is null");
16183
0
            return;
16184
0
        }
16185
16186
0
        ssl->options.sentNotify =  (opt&WOLFSSL_SENT_SHUTDOWN) > 0;
16187
0
        ssl->options.closeNotify = (opt&WOLFSSL_RECEIVED_SHUTDOWN) > 0;
16188
0
    }
16189
#endif
16190
16191
    long wolfSSL_CTX_get_options(WOLFSSL_CTX* ctx)
16192
0
    {
16193
0
        WOLFSSL_ENTER("wolfSSL_CTX_get_options");
16194
0
        WOLFSSL_MSG("wolfSSL options are set through API calls and macros");
16195
0
        if(ctx == NULL)
16196
0
            return BAD_FUNC_ARG;
16197
0
        return ctx->mask;
16198
0
    }
16199
16200
    static long wolf_set_options(long old_op, long op);
16201
    long wolfSSL_CTX_set_options(WOLFSSL_CTX* ctx, long opt)
16202
0
    {
16203
0
        WOLFSSL_ENTER("SSL_CTX_set_options");
16204
16205
0
        if (ctx == NULL)
16206
0
            return BAD_FUNC_ARG;
16207
16208
0
        ctx->mask = wolf_set_options(ctx->mask, opt);
16209
16210
0
        return ctx->mask;
16211
0
    }
16212
16213
    long wolfSSL_CTX_clear_options(WOLFSSL_CTX* ctx, long opt)
16214
0
    {
16215
0
        WOLFSSL_ENTER("SSL_CTX_clear_options");
16216
0
        if(ctx == NULL)
16217
0
            return BAD_FUNC_ARG;
16218
0
        ctx->mask &= ~opt;
16219
0
        return ctx->mask;
16220
0
    }
16221
16222
#ifdef OPENSSL_EXTRA
16223
16224
    int wolfSSL_set_rfd(WOLFSSL* ssl, int rfd)
16225
0
    {
16226
0
        WOLFSSL_ENTER("SSL_set_rfd");
16227
0
        ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
16228
16229
0
        ssl->IOCB_ReadCtx  = &ssl->rfd;
16230
16231
    #ifdef WOLFSSL_DTLS
16232
        if (ssl->options.dtls) {
16233
            ssl->IOCB_ReadCtx = &ssl->buffers.dtlsCtx;
16234
            ssl->buffers.dtlsCtx.rfd = rfd;
16235
        }
16236
    #endif
16237
16238
0
        return WOLFSSL_SUCCESS;
16239
0
    }
16240
16241
16242
    int wolfSSL_set_wfd(WOLFSSL* ssl, int wfd)
16243
0
    {
16244
0
        WOLFSSL_ENTER("SSL_set_wfd");
16245
0
        ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
16246
16247
0
        ssl->IOCB_WriteCtx  = &ssl->wfd;
16248
16249
0
        return WOLFSSL_SUCCESS;
16250
0
    }
16251
#endif /* OPENSSL_EXTRA */
16252
16253
#if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
16254
16255
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
16256
    /**
16257
     * Implemented in a similar way that ngx_ssl_ocsp_validate does it when
16258
     * SSL_get0_verified_chain is not available.
16259
     * @param ssl WOLFSSL object to extract certs from
16260
     * @return Stack of verified certs
16261
     */
16262
    WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
16263
    {
16264
        WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
16265
        WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
16266
        WOLFSSL_X509* peerCert = NULL;
16267
16268
        WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
16269
16270
        if (ssl == NULL || ssl->ctx == NULL) {
16271
            WOLFSSL_MSG("Bad parameter");
16272
            return NULL;
16273
        }
16274
16275
        peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl);
16276
        if (peerCert == NULL) {
16277
            WOLFSSL_MSG("wolfSSL_get_peer_certificate error");
16278
            return NULL;
16279
        }
16280
        /* wolfSSL_get_peer_certificate returns a copy. We want the internal
16281
         * member so that we don't have to worry about free'ing it. We call
16282
         * wolfSSL_get_peer_certificate so that we don't have to worry about
16283
         * setting up the internal pointer. */
16284
        wolfSSL_X509_free(peerCert);
16285
        peerCert = (WOLFSSL_X509*)&ssl->peerCert;
16286
        chain = wolfSSL_get_peer_cert_chain(ssl);
16287
        if (chain == NULL) {
16288
            WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
16289
            return NULL;
16290
        }
16291
        storeCtx = wolfSSL_X509_STORE_CTX_new();
16292
        if (storeCtx == NULL) {
16293
            WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
16294
            return NULL;
16295
        }
16296
        if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl),
16297
                peerCert, chain) != WOLFSSL_SUCCESS) {
16298
            WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
16299
            wolfSSL_X509_STORE_CTX_free(storeCtx);
16300
            return NULL;
16301
        }
16302
        if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
16303
            WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
16304
            wolfSSL_X509_STORE_CTX_free(storeCtx);
16305
            return NULL;
16306
        }
16307
        wolfSSL_X509_STORE_CTX_free(storeCtx);
16308
        return chain;
16309
    }
16310
#endif /* SESSION_CERTS && OPENSSL_EXTRA */
16311
16312
    WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(WOLFSSL_CTX* ctx)
16313
0
    {
16314
0
        if (ctx == NULL) {
16315
0
            return NULL;
16316
0
        }
16317
16318
0
        if (ctx->x509_store_pt != NULL)
16319
0
            return ctx->x509_store_pt;
16320
0
        return &ctx->x509_store;
16321
0
    }
16322
16323
    void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
16324
0
    {
16325
0
        WOLFSSL_ENTER("wolfSSL_CTX_set_cert_store");
16326
0
        if (ctx == NULL || str == NULL || ctx->cm == str->cm) {
16327
0
            return;
16328
0
        }
16329
16330
0
        if (wolfSSL_CertManager_up_ref(str->cm) != WOLFSSL_SUCCESS) {
16331
0
            WOLFSSL_MSG("wolfSSL_CertManager_up_ref error");
16332
0
            return;
16333
0
        }
16334
        /* free cert manager if have one */
16335
0
        if (ctx->cm != NULL) {
16336
0
            wolfSSL_CertManagerFree(ctx->cm);
16337
0
        }
16338
0
        ctx->cm               = str->cm;
16339
0
        ctx->x509_store.cm    = str->cm;
16340
16341
        /* free existing store if it exists */
16342
0
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
16343
0
        ctx->x509_store.cache = str->cache;
16344
0
        ctx->x509_store_pt    = str; /* take ownership of store and free it
16345
                                        with CTX free */
16346
0
        ctx->cm->x509_store_p = ctx->x509_store_pt;/* CTX has onwership
16347
                                                    and free it with CTX free*/
16348
0
    }
16349
16350
16351
    int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
16352
0
    {
16353
0
        WOLFSSL_ENTER("wolfSSL_set0_verify_cert_store");
16354
16355
0
        if (ssl == NULL || str == NULL) {
16356
0
            WOLFSSL_MSG("Bad parameter");
16357
0
            return WOLFSSL_FAILURE;
16358
0
        }
16359
16360
        /* NO-OP when setting existing store */
16361
0
        if (str == SSL_STORE(ssl))
16362
0
            return WOLFSSL_SUCCESS;
16363
16364
        /* free existing store if it exists */
16365
0
        wolfSSL_X509_STORE_free(ssl->x509_store_pt);
16366
0
        if (str == ssl->ctx->x509_store_pt)
16367
0
            ssl->x509_store_pt = NULL; /* if setting ctx store then just revert
16368
                                          to using that instead */
16369
0
        else
16370
0
            ssl->x509_store_pt = str; /* take ownership of store and free it
16371
                                         with SSL free */
16372
0
        return WOLFSSL_SUCCESS;
16373
0
    }
16374
16375
16376
    int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
16377
0
    {
16378
0
        WOLFSSL_ENTER("wolfSSL_set1_verify_cert_store");
16379
16380
0
        if (ssl == NULL || str == NULL) {
16381
0
            WOLFSSL_MSG("Bad parameter");
16382
0
            return WOLFSSL_FAILURE;
16383
0
        }
16384
16385
        /* NO-OP when setting existing store */
16386
0
        if (str == SSL_STORE(ssl))
16387
0
            return WOLFSSL_SUCCESS;
16388
16389
0
        if (wolfSSL_X509_STORE_up_ref(str) != WOLFSSL_SUCCESS) {
16390
0
            WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
16391
0
            return WOLFSSL_FAILURE;
16392
0
        }
16393
16394
        /* free existing store if it exists */
16395
0
        wolfSSL_X509_STORE_free(ssl->x509_store_pt);
16396
0
        if (str == ssl->ctx->x509_store_pt)
16397
0
            ssl->x509_store_pt = NULL; /* if setting ctx store then just revert
16398
                                          to using that instead */
16399
0
        else
16400
0
            ssl->x509_store_pt = str; /* take ownership of store and free it
16401
                                         with SSL free */
16402
0
        return WOLFSSL_SUCCESS;
16403
0
    }
16404
#endif /* !NO_CERTS && (OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL) */
16405
16406
#ifdef WOLFSSL_ENCRYPTED_KEYS
16407
16408
    void wolfSSL_CTX_set_default_passwd_cb_userdata(WOLFSSL_CTX* ctx,
16409
                                                   void* userdata)
16410
0
    {
16411
0
        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb_userdata");
16412
0
        if (ctx)
16413
0
            ctx->passwd_userdata = userdata;
16414
0
    }
16415
16416
16417
    void wolfSSL_CTX_set_default_passwd_cb(WOLFSSL_CTX* ctx, wc_pem_password_cb*
16418
                                           cb)
16419
0
    {
16420
0
        WOLFSSL_ENTER("SSL_CTX_set_default_passwd_cb");
16421
0
        if (ctx)
16422
0
            ctx->passwd_cb = cb;
16423
0
    }
16424
16425
    wc_pem_password_cb* wolfSSL_CTX_get_default_passwd_cb(WOLFSSL_CTX *ctx)
16426
0
    {
16427
0
        if (ctx == NULL || ctx->passwd_cb == NULL) {
16428
0
            return NULL;
16429
0
        }
16430
16431
0
        return ctx->passwd_cb;
16432
0
    }
16433
16434
16435
    void* wolfSSL_CTX_get_default_passwd_cb_userdata(WOLFSSL_CTX *ctx)
16436
0
    {
16437
0
        if (ctx == NULL) {
16438
0
            return NULL;
16439
0
        }
16440
16441
0
        return ctx->passwd_userdata;
16442
0
    }
16443
16444
#endif /* WOLFSSL_ENCRYPTED_KEYS */
16445
16446
16447
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
16448
    int wolfSSL_num_locks(void)
16449
0
    {
16450
0
        return 0;
16451
0
    }
16452
16453
    void wolfSSL_set_locking_callback(void (*f)(int, int, const char*, int))
16454
0
    {
16455
0
        WOLFSSL_ENTER("wolfSSL_set_locking_callback");
16456
16457
0
        if (wc_SetMutexCb(f) != 0) {
16458
0
            WOLFSSL_MSG("Error when setting mutex call back");
16459
0
        }
16460
0
    }
16461
16462
16463
    typedef unsigned long (idCb)(void);
16464
    static idCb* inner_idCb = NULL;
16465
16466
    unsigned long wolfSSL_thread_id(void)
16467
0
    {
16468
0
        if (inner_idCb != NULL) {
16469
0
            return inner_idCb();
16470
0
        }
16471
0
        else {
16472
0
            return 0;
16473
0
        }
16474
0
    }
16475
16476
16477
    void wolfSSL_set_id_callback(unsigned long (*f)(void))
16478
0
    {
16479
0
        inner_idCb = f;
16480
0
    }
16481
16482
    unsigned long wolfSSL_ERR_get_error(void)
16483
0
    {
16484
0
        int ret;
16485
16486
0
        WOLFSSL_ENTER("wolfSSL_ERR_get_error");
16487
16488
0
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
16489
0
        ret = wc_PullErrorNode(NULL, NULL, NULL);
16490
0
        if (ret < 0) {
16491
0
            if (ret == BAD_STATE_E) {
16492
0
                ret = 0; /* no errors in queue */
16493
0
            }
16494
0
            else {
16495
0
                WOLFSSL_MSG("Error with pulling error node!");
16496
0
                WOLFSSL_LEAVE("wolfSSL_ERR_get_error", ret);
16497
0
                ret = 0 - ret; /* return absolute value of error */
16498
                /* panic and try to clear out nodes */
16499
0
                wc_ClearErrorNodes();
16500
0
            }
16501
0
        }
16502
0
        else {
16503
0
            wc_RemoveErrorNode(0);
16504
0
        }
16505
16506
0
        return ret;
16507
#else
16508
16509
        (void)ret;
16510
16511
        return (unsigned long)(0 - NOT_COMPILED_IN);
16512
#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
16513
0
    }
16514
16515
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
16516
#ifndef NO_BIO
16517
    /* print out and clear all errors */
16518
    void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
16519
0
    {
16520
0
        const char* file = NULL;
16521
0
        const char* reason = NULL;
16522
0
        int ret;
16523
0
        int line = 0;
16524
0
        char buf[WOLFSSL_MAX_ERROR_SZ * 2];
16525
16526
0
        WOLFSSL_ENTER("wolfSSL_ERR_print_errors");
16527
16528
0
        if (bio == NULL) {
16529
0
            WOLFSSL_MSG("BIO passed in was null");
16530
0
            return;
16531
0
        }
16532
16533
0
        do {
16534
0
        ret = wc_PeekErrorNode(0, &file, &reason, &line);
16535
0
        if (ret >= 0) {
16536
0
            const char* r = wolfSSL_ERR_reason_error_string(0 - ret);
16537
0
            if (XSNPRINTF(buf, sizeof(buf),
16538
0
                          "error:%d:wolfSSL library:%s:%s:%d\n",
16539
0
                          ret, r, file, line)
16540
0
                >= (int)sizeof(buf))
16541
0
            {
16542
0
                WOLFSSL_MSG("Buffer overrun formatting error message");
16543
0
            }
16544
0
            wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf));
16545
0
            wc_RemoveErrorNode(0);
16546
0
        }
16547
0
        } while (ret >= 0);
16548
0
        if (wolfSSL_BIO_write(bio, "", 1) != 1) {
16549
0
            WOLFSSL_MSG("Issue writing final string terminator");
16550
0
        }
16551
0
    }
16552
#endif /* !NO_BIO */
16553
#endif /* WOLFSSL_HAVE_ERROR_QUEUE */
16554
16555
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
16556
16557
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
16558
    defined(HAVE_SECRET_CALLBACK)
16559
#if !defined(NO_WOLFSSL_SERVER)
16560
/* Return the amount of random bytes copied over or error case.
16561
 * ssl : ssl struct after handshake
16562
 * out : buffer to hold random bytes
16563
 * outSz : either 0 (return max buffer sz) or size of out buffer
16564
 */
16565
size_t wolfSSL_get_server_random(const WOLFSSL *ssl, unsigned char *out,
16566
                                                                   size_t outSz)
16567
0
{
16568
0
    size_t size;
16569
16570
    /* return max size of buffer */
16571
0
    if (outSz == 0) {
16572
0
        return RAN_LEN;
16573
0
    }
16574
16575
0
    if (ssl == NULL || out == NULL) {
16576
0
        return 0;
16577
0
    }
16578
16579
0
    if (ssl->arrays == NULL) {
16580
0
        WOLFSSL_MSG("Arrays struct not saved after handshake");
16581
0
        return 0;
16582
0
    }
16583
16584
0
    if (outSz > RAN_LEN) {
16585
0
        size = RAN_LEN;
16586
0
    }
16587
0
    else {
16588
0
        size = outSz;
16589
0
    }
16590
16591
0
    XMEMCPY(out, ssl->arrays->serverRandom, size);
16592
0
    return size;
16593
0
}
16594
#endif /* !NO_WOLFSSL_SERVER */
16595
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
16596
16597
#ifdef OPENSSL_EXTRA
16598
#if !defined(NO_WOLFSSL_SERVER)
16599
/* Used to get the peer ephemeral public key sent during the connection
16600
 * NOTE: currently wolfSSL_KeepHandshakeResources(WOLFSSL* ssl) must be called
16601
 *       before the ephemeral key is stored.
16602
 * return WOLFSSL_SUCCESS on success */
16603
int wolfSSL_get_server_tmp_key(const WOLFSSL* ssl, WOLFSSL_EVP_PKEY** pkey)
16604
0
{
16605
0
    WOLFSSL_EVP_PKEY* ret = NULL;
16606
16607
0
    WOLFSSL_ENTER("wolfSSL_get_server_tmp_key");
16608
16609
0
    if (ssl == NULL || pkey == NULL) {
16610
0
        WOLFSSL_MSG("Bad argument passed in");
16611
0
        return WOLFSSL_FAILURE;
16612
0
    }
16613
16614
0
#ifdef HAVE_ECC
16615
0
    if (ssl->peerEccKey != NULL) {
16616
0
        unsigned char* der;
16617
0
        const unsigned char* pt;
16618
0
        unsigned int   derSz = 0;
16619
0
        int sz;
16620
16621
0
        PRIVATE_KEY_UNLOCK();
16622
0
        if (wc_ecc_export_x963(ssl->peerEccKey, NULL, &derSz) !=
16623
0
                LENGTH_ONLY_E) {
16624
0
            WOLFSSL_MSG("get ecc der size failed");
16625
0
            PRIVATE_KEY_LOCK();
16626
0
            return WOLFSSL_FAILURE;
16627
0
        }
16628
0
        PRIVATE_KEY_LOCK();
16629
16630
0
        derSz += MAX_SEQ_SZ + (2 * MAX_ALGO_SZ) + MAX_SEQ_SZ + TRAILING_ZERO;
16631
0
        der = (unsigned char*)XMALLOC(derSz, ssl->heap, DYNAMIC_TYPE_KEY);
16632
0
        if (der == NULL) {
16633
0
            WOLFSSL_MSG("Memory error");
16634
0
            return WOLFSSL_FAILURE;
16635
0
        }
16636
16637
0
        if ((sz = wc_EccPublicKeyToDer(ssl->peerEccKey, der, derSz, 1)) <= 0) {
16638
0
            WOLFSSL_MSG("get ecc der failed");
16639
0
            XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
16640
0
            return WOLFSSL_FAILURE;
16641
0
        }
16642
0
        pt = der; /* in case pointer gets advanced */
16643
0
        ret = wolfSSL_d2i_PUBKEY(NULL, &pt, sz);
16644
0
        XFREE(der, ssl->heap, DYNAMIC_TYPE_KEY);
16645
0
    }
16646
0
#endif
16647
16648
0
    *pkey = ret;
16649
0
#ifdef HAVE_ECC
16650
0
    if (ret != NULL)
16651
0
        return WOLFSSL_SUCCESS;
16652
0
    else
16653
0
#endif
16654
0
        return WOLFSSL_FAILURE;
16655
0
}
16656
16657
#endif /* !NO_WOLFSSL_SERVER */
16658
16659
/**
16660
 * This function checks if any compiled in protocol versions are
16661
 * left enabled after calls to set_min or set_max API.
16662
 * @param major The SSL/TLS major version
16663
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
16664
 *         protocol versions are left enabled.
16665
 */
16666
static int CheckSslMethodVersion(byte major, unsigned long options)
16667
0
{
16668
0
    int sanityConfirmed = 0;
16669
16670
0
    (void)options;
16671
16672
0
    switch (major) {
16673
0
    #ifndef NO_TLS
16674
0
        case SSLv3_MAJOR:
16675
            #ifdef WOLFSSL_ALLOW_SSLV3
16676
                if (!(options & WOLFSSL_OP_NO_SSLv3)) {
16677
                    sanityConfirmed = 1;
16678
                }
16679
            #endif
16680
0
            #ifndef NO_OLD_TLS
16681
0
                if (!(options & WOLFSSL_OP_NO_TLSv1))
16682
0
                    sanityConfirmed = 1;
16683
0
                if (!(options & WOLFSSL_OP_NO_TLSv1_1))
16684
0
                    sanityConfirmed = 1;
16685
0
            #endif
16686
0
            #ifndef WOLFSSL_NO_TLS12
16687
0
                if (!(options & WOLFSSL_OP_NO_TLSv1_2))
16688
0
                    sanityConfirmed = 1;
16689
0
            #endif
16690
0
            #ifdef WOLFSSL_TLS13
16691
0
                if (!(options & WOLFSSL_OP_NO_TLSv1_3))
16692
0
                    sanityConfirmed = 1;
16693
0
            #endif
16694
0
            break;
16695
0
    #endif
16696
    #ifdef WOLFSSL_DTLS
16697
        case DTLS_MAJOR:
16698
            sanityConfirmed = 1;
16699
            break;
16700
    #endif
16701
0
        default:
16702
0
            WOLFSSL_MSG("Invalid major version");
16703
0
            return WOLFSSL_FAILURE;
16704
0
    }
16705
0
    if (!sanityConfirmed) {
16706
0
        WOLFSSL_MSG("All compiled in TLS versions disabled");
16707
0
        return WOLFSSL_FAILURE;
16708
0
    }
16709
0
    return WOLFSSL_SUCCESS;
16710
0
}
16711
16712
/**
16713
 * protoVerTbl holds (D)TLS version numbers in ascending order.
16714
 * Except DTLS versions, the newer version is located in the latter part of
16715
 * the table. This table is referred by wolfSSL_CTX_set_min_proto_version and
16716
 * wolfSSL_CTX_set_max_proto_version.
16717
 */
16718
static const int protoVerTbl[] = {
16719
    SSL3_VERSION,
16720
    TLS1_VERSION,
16721
    TLS1_1_VERSION,
16722
    TLS1_2_VERSION,
16723
    TLS1_3_VERSION,
16724
    DTLS1_VERSION,
16725
    DTLS1_2_VERSION
16726
};
16727
/* number of protocol versions listed in protoVerTbl */
16728
0
#define NUMBER_OF_PROTOCOLS (sizeof(protoVerTbl)/sizeof(int))
16729
16730
/**
16731
 * wolfSSL_CTX_set_min_proto_version attempts to set the minimum protocol
16732
 * version to use by SSL objects created from this WOLFSSL_CTX.
16733
 * This API guarantees that a version of SSL/TLS lower than specified
16734
 * here will not be allowed. If the version specified is not compiled in
16735
 * then this API sets the lowest compiled in protocol version.
16736
 * This API also accept 0 as version, to set the minimum version automatically.
16737
 * CheckSslMethodVersion() is called to check if any remaining protocol versions
16738
 * are enabled.
16739
 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
16740
 * @param version Any of the following
16741
 *          * 0
16742
 *          * SSL3_VERSION
16743
 *          * TLS1_VERSION
16744
 *          * TLS1_1_VERSION
16745
 *          * TLS1_2_VERSION
16746
 *          * TLS1_3_VERSION
16747
 *          * DTLS1_VERSION
16748
 *          * DTLS1_2_VERSION
16749
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
16750
 *         protocol versions are left enabled.
16751
 */
16752
static int Set_CTX_min_proto_version(WOLFSSL_CTX* ctx, int version)
16753
0
{
16754
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version_ex");
16755
16756
0
    if (ctx == NULL) {
16757
0
        return WOLFSSL_FAILURE;
16758
0
    }
16759
16760
0
    switch (version) {
16761
0
#ifndef NO_TLS
16762
0
        case SSL3_VERSION:
16763
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
16764
            ctx->minDowngrade = SSLv3_MINOR;
16765
            break;
16766
#endif
16767
0
        case TLS1_VERSION:
16768
        #ifdef WOLFSSL_ALLOW_TLSV10
16769
            ctx->minDowngrade = TLSv1_MINOR;
16770
            break;
16771
        #endif
16772
0
        case TLS1_1_VERSION:
16773
0
        #ifndef NO_OLD_TLS
16774
0
            ctx->minDowngrade = TLSv1_1_MINOR;
16775
0
            break;
16776
0
        #endif
16777
0
        case TLS1_2_VERSION:
16778
0
        #ifndef WOLFSSL_NO_TLS12
16779
0
            ctx->minDowngrade = TLSv1_2_MINOR;
16780
0
            break;
16781
0
        #endif
16782
0
        case TLS1_3_VERSION:
16783
0
        #ifdef WOLFSSL_TLS13
16784
0
            ctx->minDowngrade = TLSv1_3_MINOR;
16785
0
            break;
16786
0
        #endif
16787
0
#endif
16788
#ifdef WOLFSSL_DTLS
16789
        case DTLS1_VERSION:
16790
    #ifndef NO_OLD_TLS
16791
            ctx->minDowngrade = DTLS_MINOR;
16792
            break;
16793
    #endif
16794
        case DTLS1_2_VERSION:
16795
            ctx->minDowngrade = DTLSv1_2_MINOR;
16796
            break;
16797
#endif
16798
0
        default:
16799
0
            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
16800
0
            return WOLFSSL_FAILURE;
16801
0
    }
16802
16803
0
    switch (version) {
16804
0
#ifndef NO_TLS
16805
0
    case TLS1_3_VERSION:
16806
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
16807
0
        FALL_THROUGH;
16808
0
    case TLS1_2_VERSION:
16809
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
16810
0
        FALL_THROUGH;
16811
0
    case TLS1_1_VERSION:
16812
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
16813
0
        FALL_THROUGH;
16814
0
    case TLS1_VERSION:
16815
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_SSLv3);
16816
0
        break;
16817
0
    case SSL3_VERSION:
16818
0
    case SSL2_VERSION:
16819
        /* Nothing to do here */
16820
0
        break;
16821
0
#endif
16822
#ifdef WOLFSSL_DTLS
16823
    case DTLS1_VERSION:
16824
    case DTLS1_2_VERSION:
16825
        break;
16826
#endif
16827
0
    default:
16828
0
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
16829
0
        return WOLFSSL_FAILURE;
16830
0
    }
16831
16832
0
    return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
16833
0
}
16834
16835
/* Sets the min protocol version allowed with WOLFSSL_CTX
16836
 * returns WOLFSSL_SUCCESS on success */
16837
int wolfSSL_CTX_set_min_proto_version(WOLFSSL_CTX* ctx, int version)
16838
0
{
16839
0
    int ret;
16840
0
    int proto    = 0;
16841
0
    int maxProto = 0;
16842
0
    int i;
16843
0
    int idx = 0;
16844
16845
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_min_proto_version");
16846
16847
0
    if (ctx == NULL) {
16848
0
        return WOLFSSL_FAILURE;
16849
0
    }
16850
0
    if (version != 0) {
16851
0
        proto = version;
16852
0
        ctx->minProto = 0; /* turn min proto flag off */
16853
0
        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
16854
0
            if (protoVerTbl[i] == version) {
16855
0
                break;
16856
0
            }
16857
0
        }
16858
0
    }
16859
0
    else {
16860
        /* when 0 is specified as version, try to find out the min version */
16861
0
        for (i = 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
16862
0
            ret = Set_CTX_min_proto_version(ctx, protoVerTbl[i]);
16863
0
            if (ret == WOLFSSL_SUCCESS) {
16864
0
                proto = protoVerTbl[i];
16865
0
                ctx->minProto = 1; /* turn min proto flag on */
16866
0
                break;
16867
0
            }
16868
0
        }
16869
0
    }
16870
16871
    /* check case where max > min , if so then clear the NO_* options
16872
     * i is the index into the table for proto version used, see if the max
16873
     * proto version index found is smaller */
16874
0
    maxProto = wolfSSL_CTX_get_max_proto_version(ctx);
16875
0
    for (idx = 0; (unsigned)idx < NUMBER_OF_PROTOCOLS; idx++) {
16876
0
        if (protoVerTbl[idx] == maxProto) {
16877
0
            break;
16878
0
        }
16879
0
    }
16880
0
    if (idx < i) {
16881
0
        wolfSSL_CTX_clear_options(ctx, WOLFSSL_OP_NO_TLSv1 |
16882
0
                WOLFSSL_OP_NO_TLSv1_1 | WOLFSSL_OP_NO_TLSv1_2 |
16883
0
                WOLFSSL_OP_NO_TLSv1_3);
16884
0
    }
16885
16886
0
    ret = Set_CTX_min_proto_version(ctx, proto);
16887
0
    return ret;
16888
0
}
16889
16890
/**
16891
 * wolfSSL_CTX_set_max_proto_version attempts to set the maximum protocol
16892
 * version to use by SSL objects created from this WOLFSSL_CTX.
16893
 * This API guarantees that a version of SSL/TLS higher than specified
16894
 * here will not be allowed. If the version specified is not compiled in
16895
 * then this API sets the highest compiled in protocol version.
16896
 * This API also accept 0 as version, to set the maximum version automatically.
16897
 * CheckSslMethodVersion() is called to check if any remaining protocol versions
16898
 * are enabled.
16899
 * @param ctx The wolfSSL CONTEXT factory for spawning SSL/TLS objects
16900
 * @param ver Any of the following
16901
 *          * 0
16902
 *          * SSL3_VERSION
16903
 *          * TLS1_VERSION
16904
 *          * TLS1_1_VERSION
16905
 *          * TLS1_2_VERSION
16906
 *          * TLS1_3_VERSION
16907
 *          * DTLS1_VERSION
16908
 *          * DTLS1_2_VERSION
16909
 * @return WOLFSSL_SUCCESS on valid settings and WOLFSSL_FAILURE when no
16910
 *         protocol versions are left enabled.
16911
 */
16912
static int Set_CTX_max_proto_version(WOLFSSL_CTX* ctx, int ver)
16913
0
{
16914
0
    WOLFSSL_ENTER("Set_CTX_max_proto_version");
16915
16916
0
    if (!ctx || !ctx->method) {
16917
0
        WOLFSSL_MSG("Bad parameter");
16918
0
        return WOLFSSL_FAILURE;
16919
0
    }
16920
16921
0
    switch (ver) {
16922
0
    case SSL2_VERSION:
16923
0
        WOLFSSL_MSG("wolfSSL does not support SSLv2");
16924
0
        return WOLFSSL_FAILURE;
16925
0
#ifndef NO_TLS
16926
0
    case SSL3_VERSION:
16927
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1);
16928
0
        FALL_THROUGH;
16929
0
    case TLS1_VERSION:
16930
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_1);
16931
0
        FALL_THROUGH;
16932
0
    case TLS1_1_VERSION:
16933
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_2);
16934
0
        FALL_THROUGH;
16935
0
    case TLS1_2_VERSION:
16936
0
        wolfSSL_CTX_set_options(ctx, WOLFSSL_OP_NO_TLSv1_3);
16937
0
        FALL_THROUGH;
16938
0
    case TLS1_3_VERSION:
16939
        /* Nothing to do here */
16940
0
        break;
16941
0
#endif
16942
#ifdef WOLFSSL_DTLS
16943
    case DTLS1_VERSION:
16944
    case DTLS1_2_VERSION:
16945
        break;
16946
#endif
16947
0
    default:
16948
0
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
16949
0
        return WOLFSSL_FAILURE;
16950
0
    }
16951
16952
0
    return CheckSslMethodVersion(ctx->method->version.major, ctx->mask);
16953
0
}
16954
16955
16956
/* Sets the max protocol version allowed with WOLFSSL_CTX
16957
 * returns WOLFSSL_SUCCESS on success */
16958
int wolfSSL_CTX_set_max_proto_version(WOLFSSL_CTX* ctx, int version)
16959
0
{
16960
0
    int i;
16961
0
    int ret = WOLFSSL_FAILURE;
16962
0
    int minProto;
16963
16964
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_max_proto_version");
16965
16966
0
    if (ctx == NULL) {
16967
0
        return ret;
16968
0
    }
16969
16970
    /* clear out flags and reset min protocol version */
16971
0
    minProto = wolfSSL_CTX_get_min_proto_version(ctx);
16972
0
    wolfSSL_CTX_clear_options(ctx,
16973
0
            WOLFSSL_OP_NO_TLSv1 | WOLFSSL_OP_NO_TLSv1_1 |
16974
0
            WOLFSSL_OP_NO_TLSv1_2 | WOLFSSL_OP_NO_TLSv1_3);
16975
0
    wolfSSL_CTX_set_min_proto_version(ctx, minProto);
16976
0
    if (version != 0) {
16977
0
        ctx->maxProto = 0; /* turn max proto flag off */
16978
0
        return Set_CTX_max_proto_version(ctx, version);
16979
0
    }
16980
16981
    /* when 0 is specified as version, try to find out the min version from
16982
     * the bottom to top of the protoverTbl.
16983
     */
16984
0
    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
16985
0
        ret = Set_CTX_max_proto_version(ctx, protoVerTbl[i]);
16986
0
        if (ret == WOLFSSL_SUCCESS) {
16987
0
            ctx->maxProto = 1; /* turn max proto flag on */
16988
0
            break;
16989
0
        }
16990
0
    }
16991
16992
0
    return ret;
16993
0
}
16994
16995
16996
static int Set_SSL_min_proto_version(WOLFSSL* ssl, int ver)
16997
0
{
16998
0
    WOLFSSL_ENTER("Set_SSL_min_proto_version");
16999
17000
0
    if (ssl == NULL) {
17001
0
        return WOLFSSL_FAILURE;
17002
0
    }
17003
17004
0
    switch (ver) {
17005
0
#ifndef NO_TLS
17006
0
        case SSL3_VERSION:
17007
#if defined(WOLFSSL_ALLOW_SSLV3) && !defined(NO_OLD_TLS)
17008
            ssl->options.minDowngrade = SSLv3_MINOR;
17009
            break;
17010
#endif
17011
0
        case TLS1_VERSION:
17012
        #ifdef WOLFSSL_ALLOW_TLSV10
17013
            ssl->options.minDowngrade = TLSv1_MINOR;
17014
            break;
17015
        #endif
17016
0
        case TLS1_1_VERSION:
17017
0
        #ifndef NO_OLD_TLS
17018
0
            ssl->options.minDowngrade = TLSv1_1_MINOR;
17019
0
            break;
17020
0
        #endif
17021
0
        case TLS1_2_VERSION:
17022
0
        #ifndef WOLFSSL_NO_TLS12
17023
0
            ssl->options.minDowngrade = TLSv1_2_MINOR;
17024
0
            break;
17025
0
        #endif
17026
0
        case TLS1_3_VERSION:
17027
0
        #ifdef WOLFSSL_TLS13
17028
0
            ssl->options.minDowngrade = TLSv1_3_MINOR;
17029
0
            break;
17030
0
        #endif
17031
0
#endif
17032
#ifdef WOLFSSL_DTLS
17033
        case DTLS1_VERSION:
17034
    #ifndef NO_OLD_TLS
17035
            ssl->options.minDowngrade = DTLS_MINOR;
17036
            break;
17037
    #endif
17038
        case DTLS1_2_VERSION:
17039
            ssl->options.minDowngrade = DTLSv1_2_MINOR;
17040
            break;
17041
#endif
17042
0
        default:
17043
0
            WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17044
0
            return WOLFSSL_FAILURE;
17045
0
    }
17046
17047
0
    switch (ver) {
17048
0
#ifndef NO_TLS
17049
0
    case TLS1_3_VERSION:
17050
0
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
17051
0
        FALL_THROUGH;
17052
0
    case TLS1_2_VERSION:
17053
0
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
17054
0
        FALL_THROUGH;
17055
0
    case TLS1_1_VERSION:
17056
0
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
17057
0
        FALL_THROUGH;
17058
0
    case TLS1_VERSION:
17059
0
        ssl->options.mask |= WOLFSSL_OP_NO_SSLv3;
17060
0
        break;
17061
0
    case SSL3_VERSION:
17062
0
    case SSL2_VERSION:
17063
        /* Nothing to do here */
17064
0
        break;
17065
0
#endif
17066
#ifdef WOLFSSL_DTLS
17067
    case DTLS1_VERSION:
17068
    case DTLS1_2_VERSION:
17069
        break;
17070
#endif
17071
0
    default:
17072
0
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17073
0
        return WOLFSSL_FAILURE;
17074
0
    }
17075
17076
0
    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
17077
0
}
17078
17079
int wolfSSL_set_min_proto_version(WOLFSSL* ssl, int version)
17080
0
{
17081
0
    int i;
17082
0
    int ret = WOLFSSL_FAILURE;;
17083
17084
0
    WOLFSSL_ENTER("wolfSSL_set_min_proto_version");
17085
17086
0
    if (ssl == NULL) {
17087
0
        return WOLFSSL_FAILURE;
17088
0
    }
17089
0
    if (version != 0) {
17090
0
        return Set_SSL_min_proto_version(ssl, version);
17091
0
    }
17092
17093
    /* when 0 is specified as version, try to find out the min version */
17094
0
    for (i= 0; (unsigned)i < NUMBER_OF_PROTOCOLS; i++) {
17095
0
        ret = Set_SSL_min_proto_version(ssl, protoVerTbl[i]);
17096
0
        if (ret == WOLFSSL_SUCCESS)
17097
0
            break;
17098
0
    }
17099
17100
0
    return ret;
17101
0
}
17102
17103
static int Set_SSL_max_proto_version(WOLFSSL* ssl, int ver)
17104
0
{
17105
17106
0
    WOLFSSL_ENTER("Set_SSL_max_proto_version");
17107
17108
0
    if (!ssl) {
17109
0
        WOLFSSL_MSG("Bad parameter");
17110
0
        return WOLFSSL_FAILURE;
17111
0
    }
17112
17113
0
    switch (ver) {
17114
0
    case SSL2_VERSION:
17115
0
        WOLFSSL_MSG("wolfSSL does not support SSLv2");
17116
0
        return WOLFSSL_FAILURE;
17117
0
#ifndef NO_TLS
17118
0
    case SSL3_VERSION:
17119
0
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1;
17120
0
        FALL_THROUGH;
17121
0
    case TLS1_VERSION:
17122
0
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_1;
17123
0
        FALL_THROUGH;
17124
0
    case TLS1_1_VERSION:
17125
0
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_2;
17126
0
        FALL_THROUGH;
17127
0
    case TLS1_2_VERSION:
17128
0
        ssl->options.mask |= WOLFSSL_OP_NO_TLSv1_3;
17129
0
        FALL_THROUGH;
17130
0
    case TLS1_3_VERSION:
17131
        /* Nothing to do here */
17132
0
        break;
17133
0
#endif
17134
#ifdef WOLFSSL_DTLS
17135
    case DTLS1_VERSION:
17136
    case DTLS1_2_VERSION:
17137
        break;
17138
#endif
17139
0
    default:
17140
0
        WOLFSSL_MSG("Unrecognized protocol version or not compiled in");
17141
0
        return WOLFSSL_FAILURE;
17142
0
    }
17143
17144
0
    return CheckSslMethodVersion(ssl->version.major, ssl->options.mask);
17145
0
}
17146
17147
int wolfSSL_set_max_proto_version(WOLFSSL* ssl, int version)
17148
0
{
17149
0
    int i;
17150
0
    int ret = WOLFSSL_FAILURE;;
17151
17152
0
    WOLFSSL_ENTER("wolfSSL_set_max_proto_version");
17153
17154
0
    if (ssl == NULL) {
17155
0
        return WOLFSSL_FAILURE;
17156
0
    }
17157
0
    if (version != 0) {
17158
0
        return Set_SSL_max_proto_version(ssl, version);
17159
0
    }
17160
17161
    /* when 0 is specified as version, try to find out the min version from
17162
     * the bottom to top of the protoverTbl.
17163
     */
17164
0
    for (i = NUMBER_OF_PROTOCOLS -1; i >= 0; i--) {
17165
0
        ret = Set_SSL_max_proto_version(ssl, protoVerTbl[i]);
17166
0
        if (ret == WOLFSSL_SUCCESS)
17167
0
            break;
17168
0
    }
17169
17170
0
    return ret;
17171
0
}
17172
17173
static int GetMinProtoVersion(int minDowngrade)
17174
0
{
17175
0
    int ret;
17176
17177
0
    switch (minDowngrade) {
17178
0
#ifndef NO_OLD_TLS
17179
    #ifdef WOLFSSL_ALLOW_SSLV3
17180
        case SSLv3_MINOR:
17181
            ret = SSL3_VERSION;
17182
            break;
17183
    #endif
17184
    #ifdef WOLFSSL_ALLOW_TLSV10
17185
        case TLSv1_MINOR:
17186
            ret = TLS1_VERSION;
17187
            break;
17188
    #endif
17189
0
        case TLSv1_1_MINOR:
17190
0
            ret = TLS1_1_VERSION;
17191
0
            break;
17192
0
#endif
17193
0
#ifndef WOLFSSL_NO_TLS12
17194
0
        case TLSv1_2_MINOR:
17195
0
            ret = TLS1_2_VERSION;
17196
0
            break;
17197
0
#endif
17198
0
#ifdef WOLFSSL_TLS13
17199
0
        case TLSv1_3_MINOR:
17200
0
            ret = TLS1_3_VERSION;
17201
0
            break;
17202
0
#endif
17203
0
        default:
17204
0
            ret = 0;
17205
0
            break;
17206
0
    }
17207
17208
0
    return ret;
17209
0
}
17210
17211
WOLFSSL_API int wolfSSL_CTX_get_min_proto_version(WOLFSSL_CTX* ctx)
17212
0
{
17213
0
    int ret = 0;
17214
17215
0
    WOLFSSL_ENTER("wolfSSL_CTX_get_min_proto_version");
17216
17217
0
    if (ctx != NULL) {
17218
0
        if (ctx->minProto) {
17219
0
            ret = 0;
17220
0
        }
17221
0
        else {
17222
0
            ret = GetMinProtoVersion(ctx->minDowngrade);
17223
0
        }
17224
0
    }
17225
0
    else {
17226
0
        ret = GetMinProtoVersion(WOLFSSL_MIN_DOWNGRADE);
17227
0
    }
17228
17229
0
    WOLFSSL_LEAVE("wolfSSL_CTX_get_min_proto_version", ret);
17230
17231
0
    return ret;
17232
0
}
17233
17234
17235
/* returns the maximum allowed protocol version given the 'options' used
17236
 * returns WOLFSSL_FATAL_ERROR on no match */
17237
static int GetMaxProtoVersion(long options)
17238
0
{
17239
0
#ifndef NO_TLS
17240
0
#ifdef WOLFSSL_TLS13
17241
0
    if (!(options & WOLFSSL_OP_NO_TLSv1_3))
17242
0
        return TLS1_3_VERSION;
17243
0
#endif
17244
0
#ifndef WOLFSSL_NO_TLS12
17245
0
    if (!(options & WOLFSSL_OP_NO_TLSv1_2))
17246
0
        return TLS1_2_VERSION;
17247
0
#endif
17248
0
#ifndef NO_OLD_TLS
17249
0
    if (!(options & WOLFSSL_OP_NO_TLSv1_1))
17250
0
        return TLS1_1_VERSION;
17251
    #ifdef WOLFSSL_ALLOW_TLSV10
17252
    if (!(options & WOLFSSL_OP_NO_TLSv1))
17253
        return TLS1_VERSION;
17254
    #endif
17255
    #ifdef WOLFSSL_ALLOW_SSLV3
17256
    if (!(options & WOLFSSL_OP_NO_SSLv3))
17257
        return SSL3_VERSION;
17258
    #endif
17259
0
#endif
17260
#else
17261
    (void)options;
17262
#endif /* NO_TLS */
17263
0
    return WOLFSSL_FATAL_ERROR;
17264
0
}
17265
17266
17267
/* returns the maximum protocol version for 'ctx' */
17268
int wolfSSL_CTX_get_max_proto_version(WOLFSSL_CTX* ctx)
17269
0
{
17270
0
    int ret = 0;
17271
0
    long options = 0; /* default to nothing set */
17272
17273
0
    WOLFSSL_ENTER("wolfSSL_CTX_get_max_proto_version");
17274
17275
0
    if (ctx != NULL) {
17276
0
        options = wolfSSL_CTX_get_options(ctx);
17277
0
    }
17278
17279
0
    if ((ctx != NULL) && ctx->maxProto) {
17280
0
        ret = 0;
17281
0
    }
17282
0
    else {
17283
0
        ret = GetMaxProtoVersion(options);
17284
0
    }
17285
17286
0
    WOLFSSL_LEAVE("wolfSSL_CTX_get_max_proto_version", ret);
17287
17288
0
    if (ret == WOLFSSL_FATAL_ERROR) {
17289
0
        WOLFSSL_MSG("Error getting max proto version");
17290
0
        ret = 0; /* setting ret to 0 to match compat return */
17291
0
    }
17292
0
    return ret;
17293
0
}
17294
#endif /* OPENSSL_EXTRA */
17295
17296
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
17297
    defined(HAVE_SECRET_CALLBACK)
17298
#if !defined(NO_WOLFSSL_CLIENT)
17299
/* Return the amount of random bytes copied over or error case.
17300
 * ssl : ssl struct after handshake
17301
 * out : buffer to hold random bytes
17302
 * outSz : either 0 (return max buffer sz) or size of out buffer
17303
 */
17304
size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
17305
                                                                   size_t outSz)
17306
0
{
17307
0
    size_t size;
17308
17309
    /* return max size of buffer */
17310
0
    if (outSz == 0) {
17311
0
        return RAN_LEN;
17312
0
    }
17313
17314
0
    if (ssl == NULL || out == NULL) {
17315
0
        return 0;
17316
0
    }
17317
17318
0
    if (ssl->arrays == NULL) {
17319
0
        WOLFSSL_MSG("Arrays struct not saved after handshake");
17320
0
        return 0;
17321
0
    }
17322
17323
0
    if (outSz > RAN_LEN) {
17324
0
        size = RAN_LEN;
17325
0
    }
17326
0
    else {
17327
0
        size = outSz;
17328
0
    }
17329
17330
0
    XMEMCPY(out, ssl->arrays->clientRandom, size);
17331
0
    return size;
17332
0
}
17333
#endif /* !NO_WOLFSSL_CLIENT */
17334
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_SECRET_CALLBACK */
17335
17336
#ifdef OPENSSL_EXTRA
17337
    unsigned long wolfSSLeay(void)
17338
0
    {
17339
0
        return SSLEAY_VERSION_NUMBER;
17340
0
    }
17341
17342
    unsigned long wolfSSL_OpenSSL_version_num(void)
17343
0
    {
17344
0
        return OPENSSL_VERSION_NUMBER;
17345
0
    }
17346
17347
    const char* wolfSSLeay_version(int type)
17348
0
    {
17349
0
        (void)type;
17350
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
17351
        return wolfSSL_OpenSSL_version(type);
17352
#else
17353
0
        return wolfSSL_OpenSSL_version();
17354
0
#endif
17355
0
    }
17356
17357
17358
#ifndef NO_MD5
17359
    int wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5)
17360
56
    {
17361
56
        int ret;
17362
56
        typedef char md5_test[sizeof(MD5_CTX) >= sizeof(wc_Md5) ? 1 : -1];
17363
56
        (void)sizeof(md5_test);
17364
17365
56
        WOLFSSL_ENTER("MD5_Init");
17366
56
        ret = wc_InitMd5((wc_Md5*)md5);
17367
17368
        /* return 1 on success, 0 otherwise */
17369
56
        if (ret == 0)
17370
56
            return 1;
17371
17372
0
        return 0;
17373
56
    }
17374
17375
17376
    int wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input,
17377
                           unsigned long sz)
17378
921
    {
17379
921
        int ret;
17380
17381
921
        WOLFSSL_ENTER("wolfSSL_MD5_Update");
17382
921
        ret = wc_Md5Update((wc_Md5*)md5, (const byte*)input, (word32)sz);
17383
17384
        /* return 1 on success, 0 otherwise */
17385
921
        if (ret == 0)
17386
921
            return 1;
17387
17388
0
        return 0;
17389
921
    }
17390
17391
17392
    int wolfSSL_MD5_Final(byte* output, WOLFSSL_MD5_CTX* md5)
17393
56
    {
17394
56
        int ret;
17395
17396
56
        WOLFSSL_ENTER("MD5_Final");
17397
56
        ret = wc_Md5Final((wc_Md5*)md5, output);
17398
17399
        /* have to actually free the resources (if any) here, because the
17400
         * OpenSSL API doesn't include SHA*_Free().
17401
         */
17402
56
        wc_Md5Free((wc_Md5*)md5);
17403
17404
        /* return 1 on success, 0 otherwise */
17405
56
        if (ret == 0)
17406
56
            return 1;
17407
17408
0
        return 0;
17409
56
    }
17410
    /* Apply MD5 transformation to the data */
17411
    int wolfSSL_MD5_Transform(WOLFSSL_MD5_CTX* md5, const unsigned char* data)
17412
0
    {
17413
0
        int ret;
17414
17415
0
       WOLFSSL_ENTER("MD5_Transform");
17416
17417
       /* sanity check */
17418
0
       if (md5 == NULL || data == NULL) {
17419
0
            return 0;
17420
0
       }
17421
       #if defined(BIG_ENDIAN_ORDER)
17422
       {
17423
            ByteReverseWords((word32*)data, (word32*)data, WC_MD5_BLOCK_SIZE);
17424
       }
17425
       #endif
17426
17427
0
       ret = wc_Md5Transform((wc_Md5*)md5, data);
17428
17429
       /* return 1 on success, 0 otherwise */
17430
0
        if (ret == 0)
17431
0
            return 1;
17432
0
        else
17433
0
            return 0;
17434
0
    }
17435
17436
    unsigned char *wolfSSL_MD5(const unsigned char* data, size_t len,
17437
            unsigned char* hash)
17438
0
    {
17439
0
        static unsigned char out[WC_MD5_DIGEST_SIZE];
17440
17441
0
        WOLFSSL_ENTER("wolfSSL_MD5");
17442
17443
0
        if (hash == NULL)
17444
0
            hash = out;
17445
0
        if (wc_Md5Hash(data, (word32)len, hash) != 0) {
17446
0
            WOLFSSL_MSG("wc_Md5Hash error");
17447
0
            return NULL;
17448
0
        }
17449
0
        return hash;
17450
0
    }
17451
#endif /* !NO_MD5 */
17452
17453
17454
#ifndef NO_SHA
17455
    int wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha)
17456
108
    {
17457
108
        int ret;
17458
17459
108
        typedef char sha_test[sizeof(SHA_CTX) >= sizeof(wc_Sha) ? 1 : -1];
17460
108
        (void)sizeof(sha_test);
17461
17462
108
        WOLFSSL_ENTER("SHA_Init");
17463
108
        ret = wc_InitSha((wc_Sha*)sha);
17464
17465
        /* return 1 on success, 0 otherwise */
17466
108
        if (ret == 0)
17467
108
            return 1;
17468
17469
0
        return 0;
17470
108
    }
17471
17472
17473
    int wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input,
17474
                           unsigned long sz)
17475
3.28k
    {
17476
3.28k
        int ret;
17477
17478
3.28k
        WOLFSSL_ENTER("SHA_Update");
17479
3.28k
        ret = wc_ShaUpdate((wc_Sha*)sha, (const byte*)input, (word32)sz);
17480
17481
        /* return 1 on success, 0 otherwise */
17482
3.28k
        if (ret == 0)
17483
3.28k
            return 1;
17484
17485
0
        return 0;
17486
3.28k
    }
17487
17488
17489
    int wolfSSL_SHA_Final(byte* output, WOLFSSL_SHA_CTX* sha)
17490
108
    {
17491
108
        int ret;
17492
17493
108
        WOLFSSL_ENTER("SHA_Final");
17494
108
        ret = wc_ShaFinal((wc_Sha*)sha, output);
17495
17496
        /* have to actually free the resources (if any) here, because the
17497
         * OpenSSL API doesn't include SHA*_Free().
17498
         */
17499
108
        wc_ShaFree((wc_Sha*)sha);
17500
17501
        /* return 1 on success, 0 otherwise */
17502
108
        if (ret == 0)
17503
108
            return 1;
17504
17505
0
        return 0;
17506
108
    }
17507
17508
    #if defined(OPENSSL_EXTRA)
17509
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17510
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
17511
    /* Apply SHA1 transformation to the data */
17512
    int wolfSSL_SHA_Transform(WOLFSSL_SHA_CTX* sha,
17513
                                         const unsigned char* data)
17514
0
    {
17515
0
       int ret;
17516
17517
0
       WOLFSSL_ENTER("SHA_Transform");
17518
       /* sanity check */
17519
0
       if (sha == NULL || data == NULL) {
17520
0
            return 0;
17521
0
       }
17522
0
       #if defined(LITTLE_ENDIAN_ORDER)
17523
0
       {
17524
0
            ByteReverseWords((word32*)data, (word32*)data, WC_SHA_BLOCK_SIZE);
17525
0
       }
17526
0
       #endif
17527
0
       ret = wc_ShaTransform((wc_Sha*)sha, data);
17528
17529
       /* return 1 on success, 0 otherwise */
17530
0
        if (ret == 0)
17531
0
            return 1;
17532
0
        else
17533
0
            return 0;
17534
0
    }
17535
    #endif
17536
    #endif
17537
17538
    int wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha)
17539
0
    {
17540
0
        WOLFSSL_ENTER("SHA1_Init");
17541
0
        return SHA_Init(sha);
17542
0
    }
17543
17544
17545
    int wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input,
17546
                            unsigned long sz)
17547
0
    {
17548
0
        WOLFSSL_ENTER("SHA1_Update");
17549
0
        return SHA_Update(sha, input, sz);
17550
0
    }
17551
17552
17553
    int wolfSSL_SHA1_Final(byte* output, WOLFSSL_SHA_CTX* sha)
17554
0
    {
17555
0
        WOLFSSL_ENTER("SHA1_Final");
17556
0
        return SHA_Final(output, sha);
17557
0
    }
17558
    #if defined(OPENSSL_EXTRA)
17559
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17560
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
17561
    /* Apply SHA1 transformation to the data */
17562
    int wolfSSL_SHA1_Transform(WOLFSSL_SHA_CTX* sha,
17563
                                         const unsigned char* data)
17564
0
    {
17565
0
       WOLFSSL_ENTER("SHA1_Transform");
17566
0
       return (wolfSSL_SHA_Transform(sha, data));
17567
0
    }
17568
    #endif
17569
    #endif
17570
#endif /* !NO_SHA */
17571
17572
#ifdef WOLFSSL_SHA224
17573
17574
    int wolfSSL_SHA224_Init(WOLFSSL_SHA224_CTX* sha)
17575
53
    {
17576
53
        int ret;
17577
17578
53
        typedef char sha_test[sizeof(SHA224_CTX) >= sizeof(wc_Sha224) ? 1 : -1];
17579
53
        (void)sizeof(sha_test);
17580
17581
53
        WOLFSSL_ENTER("SHA224_Init");
17582
53
        ret = wc_InitSha224((wc_Sha224*)sha);
17583
17584
        /* return 1 on success, 0 otherwise */
17585
53
        if (ret == 0)
17586
53
            return 1;
17587
17588
0
        return 0;
17589
53
    }
17590
17591
17592
    int wolfSSL_SHA224_Update(WOLFSSL_SHA224_CTX* sha, const void* input,
17593
                           unsigned long sz)
17594
893
    {
17595
893
        int ret;
17596
17597
893
        WOLFSSL_ENTER("SHA224_Update");
17598
893
        ret = wc_Sha224Update((wc_Sha224*)sha, (const byte*)input, (word32)sz);
17599
17600
        /* return 1 on success, 0 otherwise */
17601
893
        if (ret == 0)
17602
893
            return 1;
17603
17604
0
        return 0;
17605
893
    }
17606
17607
17608
    int wolfSSL_SHA224_Final(byte* output, WOLFSSL_SHA224_CTX* sha)
17609
53
    {
17610
53
        int ret;
17611
17612
53
        WOLFSSL_ENTER("SHA224_Final");
17613
53
        ret = wc_Sha224Final((wc_Sha224*)sha, output);
17614
17615
        /* have to actually free the resources (if any) here, because the
17616
         * OpenSSL API doesn't include SHA*_Free().
17617
         */
17618
53
        wc_Sha224Free((wc_Sha224*)sha);
17619
17620
        /* return 1 on success, 0 otherwise */
17621
53
        if (ret == 0)
17622
53
            return 1;
17623
17624
0
        return 0;
17625
53
    }
17626
17627
#endif /* WOLFSSL_SHA224 */
17628
17629
17630
    int wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256)
17631
121
    {
17632
121
        int ret;
17633
17634
121
        typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(wc_Sha256) ? 1 : -1];
17635
121
        (void)sizeof(sha_test);
17636
17637
121
        WOLFSSL_ENTER("SHA256_Init");
17638
121
        ret = wc_InitSha256((wc_Sha256*)sha256);
17639
17640
        /* return 1 on success, 0 otherwise */
17641
121
        if (ret == 0)
17642
121
            return 1;
17643
17644
0
        return 0;
17645
121
    }
17646
17647
17648
    int wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input,
17649
                              unsigned long sz)
17650
2.56k
    {
17651
2.56k
        int ret;
17652
17653
2.56k
        WOLFSSL_ENTER("SHA256_Update");
17654
2.56k
        ret = wc_Sha256Update((wc_Sha256*)sha, (const byte*)input, (word32)sz);
17655
17656
        /* return 1 on success, 0 otherwise */
17657
2.56k
        if (ret == 0)
17658
2.56k
            return 1;
17659
17660
0
        return 0;
17661
2.56k
    }
17662
17663
17664
    int wolfSSL_SHA256_Final(byte* output, WOLFSSL_SHA256_CTX* sha)
17665
121
    {
17666
121
        int ret;
17667
17668
121
        WOLFSSL_ENTER("SHA256_Final");
17669
121
        ret = wc_Sha256Final((wc_Sha256*)sha, output);
17670
17671
        /* have to actually free the resources (if any) here, because the
17672
         * OpenSSL API doesn't include SHA*_Free().
17673
         */
17674
121
        wc_Sha256Free((wc_Sha256*)sha);
17675
17676
        /* return 1 on success, 0 otherwise */
17677
121
        if (ret == 0)
17678
121
            return 1;
17679
17680
0
        return 0;
17681
121
    }
17682
17683
    #if defined(OPENSSL_EXTRA)
17684
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17685
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) && \
17686
        !defined(WOLFSSL_DEVCRYPTO_HASH) && !defined(WOLFSSL_AFALG_HASH)
17687
    /* Apply SHA256 transformation to the data */
17688
    int wolfSSL_SHA256_Transform(WOLFSSL_SHA256_CTX* sha256,
17689
                                                const unsigned char* data)
17690
0
    {
17691
0
       int ret;
17692
17693
0
       WOLFSSL_ENTER("SHA256_Transform");
17694
       /* sanity check */
17695
0
       if (sha256 == NULL || data == NULL) {
17696
0
            return 0;
17697
0
       }
17698
0
       #if defined(LITTLE_ENDIAN_ORDER)
17699
0
       {
17700
0
            ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE);
17701
0
       }
17702
0
       #endif
17703
0
       ret = wc_Sha256Transform((wc_Sha256*)sha256, data);
17704
17705
       /* return 1 on success, 0 otherwise */
17706
0
        if (ret == 0)
17707
0
            return 1;
17708
0
        else
17709
0
            return 0;
17710
0
    }
17711
    #endif
17712
    #endif
17713
17714
#ifdef WOLFSSL_SHA384
17715
17716
    int wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha)
17717
38
    {
17718
38
        int ret;
17719
17720
38
        typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(wc_Sha384) ? 1 : -1];
17721
38
        (void)sizeof(sha_test);
17722
17723
38
        WOLFSSL_ENTER("SHA384_Init");
17724
38
        ret = wc_InitSha384((wc_Sha384*)sha);
17725
17726
        /* return 1 on success, 0 otherwise */
17727
38
        if (ret == 0)
17728
38
            return 1;
17729
17730
0
        return 0;
17731
38
    }
17732
17733
17734
    int wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input,
17735
                           unsigned long sz)
17736
826
    {
17737
826
        int ret;
17738
17739
826
        WOLFSSL_ENTER("SHA384_Update");
17740
826
        ret = wc_Sha384Update((wc_Sha384*)sha, (const byte*)input, (word32)sz);
17741
17742
        /* return 1 on success, 0 otherwise */
17743
826
        if (ret == 0)
17744
826
            return 1;
17745
17746
0
        return 0;
17747
826
    }
17748
17749
17750
    int wolfSSL_SHA384_Final(byte* output, WOLFSSL_SHA384_CTX* sha)
17751
38
    {
17752
38
        int ret;
17753
17754
38
        WOLFSSL_ENTER("SHA384_Final");
17755
38
        ret = wc_Sha384Final((wc_Sha384*)sha, output);
17756
17757
        /* have to actually free the resources (if any) here, because the
17758
         * OpenSSL API doesn't include SHA*_Free().
17759
         */
17760
38
        wc_Sha384Free((wc_Sha384*)sha);
17761
17762
        /* return 1 on success, 0 otherwise */
17763
38
        if (ret == 0)
17764
38
            return 1;
17765
17766
0
        return 0;
17767
38
    }
17768
17769
#endif /* WOLFSSL_SHA384 */
17770
17771
17772
#ifdef WOLFSSL_SHA512
17773
17774
    int wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha)
17775
83
    {
17776
83
        int ret;
17777
17778
83
        typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(wc_Sha512) ? 1 : -1];
17779
83
        (void)sizeof(sha_test);
17780
17781
83
        WOLFSSL_ENTER("SHA512_Init");
17782
83
        ret = wc_InitSha512((wc_Sha512*)sha);
17783
17784
        /* return 1 on success, 0 otherwise */
17785
83
        if (ret == 0)
17786
83
            return 1;
17787
17788
0
        return 0;
17789
83
    }
17790
17791
17792
    int wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input,
17793
                           unsigned long sz)
17794
3.49k
    {
17795
3.49k
        int ret;
17796
17797
3.49k
        WOLFSSL_ENTER("SHA512_Update");
17798
3.49k
        ret = wc_Sha512Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
17799
17800
        /* return 1 on success, 0 otherwise */
17801
3.49k
        if (ret == 0)
17802
3.49k
            return 1;
17803
17804
0
        return 0;
17805
3.49k
    }
17806
17807
17808
    int wolfSSL_SHA512_Final(byte* output, WOLFSSL_SHA512_CTX* sha)
17809
83
    {
17810
83
        int ret;
17811
17812
83
        WOLFSSL_ENTER("SHA512_Final");
17813
83
        ret = wc_Sha512Final((wc_Sha512*)sha, output);
17814
17815
        /* have to actually free the resources (if any) here, because the
17816
         * OpenSSL API doesn't include SHA*_Free().
17817
         */
17818
83
        wc_Sha512Free((wc_Sha512*)sha);
17819
17820
        /* return 1 on success, 0 otherwise */
17821
83
        if (ret == 0)
17822
83
            return 1;
17823
17824
0
        return 0;
17825
83
    }
17826
17827
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17828
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
17829
    /* Apply SHA512 transformation to the data */
17830
    int wolfSSL_SHA512_Transform(WOLFSSL_SHA512_CTX* sha512,
17831
                                          const unsigned char* data)
17832
0
    {
17833
0
       int ret;
17834
17835
0
       WOLFSSL_ENTER("SHA512_Transform");
17836
       /* sanity check */
17837
0
       if (sha512 == NULL || data == NULL) {
17838
0
            return WOLFSSL_FAILURE;
17839
0
       }
17840
17841
0
       ret = wc_Sha512Transform((wc_Sha512*)sha512, data);
17842
17843
       /* return 1 on success, 0 otherwise */
17844
0
        if (ret == 0)
17845
0
            return WOLFSSL_SUCCESS;
17846
0
        else
17847
0
            return WOLFSSL_FAILURE;
17848
0
    }
17849
    #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
17850
              (HAVE_FIPS_VERSION > 2)) */
17851
17852
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
17853
#if !defined(WOLFSSL_NOSHA512_224)
17854
    int wolfSSL_SHA512_224_Init(WOLFSSL_SHA512_224_CTX* sha)
17855
0
    {
17856
0
        int ret;
17857
17858
0
        WOLFSSL_ENTER("wolfSSL_SHA512_224_Init");
17859
0
        ret = wc_InitSha512_224((wc_Sha512*)sha);
17860
17861
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
17862
0
        if (ret == 0)
17863
0
            return WOLFSSL_SUCCESS;
17864
17865
0
        return WOLFSSL_FAILURE;
17866
0
    }
17867
17868
    int wolfSSL_SHA512_224_Update(WOLFSSL_SHA512_224_CTX* sha,
17869
                                        const void* input, unsigned long sz)
17870
0
    {
17871
0
        int ret;
17872
17873
0
        WOLFSSL_ENTER("wolfSSL_SHA512_224_Update");
17874
0
        ret = wc_Sha512_224Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
17875
17876
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
17877
0
        if (ret == 0)
17878
0
            return WOLFSSL_SUCCESS;
17879
17880
0
        return WOLFSSL_FAILURE;
17881
0
    }
17882
17883
    int wolfSSL_SHA512_224_Final(byte* output, WOLFSSL_SHA512_224_CTX* sha)
17884
0
    {
17885
0
        int ret;
17886
17887
0
        WOLFSSL_ENTER("wolfSSL_SHA512_224_Final");
17888
0
        ret = wc_Sha512_224Final((wc_Sha512*)sha, output);
17889
17890
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
17891
0
        if (ret == 0)
17892
0
            return WOLFSSL_SUCCESS;
17893
17894
0
        return WOLFSSL_FAILURE;
17895
0
    }
17896
17897
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17898
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
17899
    /* Apply SHA512 transformation to the data */
17900
    int wolfSSL_SHA512_224_Transform(WOLFSSL_SHA512_CTX* sha512,
17901
                                          const unsigned char* data)
17902
0
    {
17903
0
       int ret;
17904
17905
0
       WOLFSSL_ENTER("SHA512_224_Transform");
17906
       /* sanity check */
17907
0
       if (sha512 == NULL || data == NULL) {
17908
0
            return WOLFSSL_FAILURE;
17909
0
       }
17910
17911
0
       ret = wc_Sha512_224Transform((wc_Sha512*)sha512, data);
17912
17913
       /* return 1 on success, 0 otherwise */
17914
0
        if (ret == 0)
17915
0
            return WOLFSSL_SUCCESS;
17916
0
        else
17917
0
            return WOLFSSL_FAILURE;
17918
0
    }
17919
    #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
17920
              (HAVE_FIPS_VERSION > 2)) */
17921
17922
#endif /* !WOLFSSL_NOSHA512_224 */
17923
#if !defined(WOLFSSL_NOSHA512_256)
17924
    int wolfSSL_SHA512_256_Init(WOLFSSL_SHA512_256_CTX* sha)
17925
0
    {
17926
0
        int ret;
17927
17928
0
        WOLFSSL_ENTER("wolfSSL_SHA512_256_Init");
17929
0
        ret = wc_InitSha512_256((wc_Sha512*)sha);
17930
17931
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
17932
0
        if (ret == 0)
17933
0
            return WOLFSSL_SUCCESS;
17934
17935
0
        return WOLFSSL_FAILURE;
17936
0
    }
17937
17938
    int wolfSSL_SHA512_256_Update(WOLFSSL_SHA512_256_CTX* sha,
17939
                                        const void* input, unsigned long sz)
17940
0
    {
17941
0
        int ret;
17942
17943
0
        WOLFSSL_ENTER("wolfSSL_SHA512_256_Update");
17944
0
        ret = wc_Sha512_256Update((wc_Sha512*)sha, (const byte*)input, (word32)sz);
17945
17946
        /* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE otherwise */
17947
0
        if (ret == 0)
17948
0
            return WOLFSSL_SUCCESS;
17949
17950
0
        return WOLFSSL_FAILURE;
17951
0
    }
17952
17953
    int wolfSSL_SHA512_256_Final(byte* output, WOLFSSL_SHA512_256_CTX* sha)
17954
0
    {
17955
0
        int ret;
17956
17957
0
        WOLFSSL_ENTER("wolfSSL_SHA512_256_Final");
17958
0
        ret = wc_Sha512_256Final((wc_Sha512*)sha, output);
17959
17960
        /* return WOLFSSL_SUCCESS on success, 0 otherwise */
17961
0
        if (ret == 0)
17962
0
            return WOLFSSL_SUCCESS;
17963
17964
0
        return WOLFSSL_FAILURE;
17965
0
    }
17966
17967
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
17968
        (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2)))
17969
    /* Apply SHA512 transformation to the data */
17970
    int wolfSSL_SHA512_256_Transform(WOLFSSL_SHA512_CTX* sha512,
17971
                                          const unsigned char* data)
17972
0
    {
17973
0
       int ret;
17974
17975
0
       WOLFSSL_ENTER("SHA512_256_Transform");
17976
       /* sanity check */
17977
0
       if (sha512 == NULL || data == NULL) {
17978
0
            return WOLFSSL_FAILURE;
17979
0
       }
17980
17981
0
       ret = wc_Sha512_256Transform((wc_Sha512*)sha512, data);
17982
17983
       /* return 1 on success, 0 otherwise */
17984
0
        if (ret == 0)
17985
0
            return WOLFSSL_SUCCESS;
17986
0
        else
17987
0
            return WOLFSSL_FAILURE;
17988
0
    }
17989
    #endif /* !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \
17990
              (HAVE_FIPS_VERSION > 2)) */
17991
17992
#endif /* !WOLFSSL_NOSHA512_256 */
17993
#endif /* !HAVE_FIPS && !HAVE_SELFTEST */
17994
17995
#endif /* WOLFSSL_SHA512 */
17996
17997
#ifdef WOLFSSL_SHA3
17998
#ifndef WOLFSSL_NOSHA3_224
17999
18000
    int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha)
18001
0
    {
18002
0
        int ret;
18003
18004
0
        typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18005
0
        (void)sizeof(sha_test);
18006
18007
0
        WOLFSSL_ENTER("SHA3_224_Init");
18008
0
        ret = wc_InitSha3_224((wc_Sha3*)sha, NULL, INVALID_DEVID);
18009
18010
        /* return 1 on success, 0 otherwise */
18011
0
        if (ret == 0)
18012
0
            return 1;
18013
18014
0
        return 0;
18015
0
    }
18016
18017
18018
    int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha, const void* input,
18019
                           unsigned long sz)
18020
0
    {
18021
0
        int ret;
18022
18023
0
        WOLFSSL_ENTER("SHA3_224_Update");
18024
0
        ret = wc_Sha3_224_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18025
18026
        /* return 1 on success, 0 otherwise */
18027
0
        if (ret == 0)
18028
0
            return 1;
18029
18030
0
        return 0;
18031
0
    }
18032
18033
18034
    int wolfSSL_SHA3_224_Final(byte* output, WOLFSSL_SHA3_224_CTX* sha)
18035
0
    {
18036
0
        int ret;
18037
18038
0
        WOLFSSL_ENTER("SHA3_224_Final");
18039
0
        ret = wc_Sha3_224_Final((wc_Sha3*)sha, output);
18040
18041
        /* have to actually free the resources (if any) here, because the
18042
         * OpenSSL API doesn't include SHA*_Free().
18043
         */
18044
0
        wc_Sha3_224_Free((wc_Sha3*)sha);
18045
18046
        /* return 1 on success, 0 otherwise */
18047
0
        if (ret == 0)
18048
0
            return 1;
18049
18050
0
        return 0;
18051
0
    }
18052
18053
#endif /* WOLFSSL_NOSHA3_224 */
18054
18055
18056
#ifndef WOLFSSL_NOSHA3_256
18057
    int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256)
18058
0
    {
18059
0
        int ret;
18060
18061
0
        typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18062
0
        (void)sizeof(sha_test);
18063
18064
0
        WOLFSSL_ENTER("SHA3_256_Init");
18065
0
        ret = wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, INVALID_DEVID);
18066
18067
        /* return 1 on success, 0 otherwise */
18068
0
        if (ret == 0)
18069
0
            return 1;
18070
18071
0
        return 0;
18072
0
    }
18073
18074
18075
    int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha, const void* input,
18076
                              unsigned long sz)
18077
0
    {
18078
0
        int ret;
18079
18080
0
        WOLFSSL_ENTER("SHA3_256_Update");
18081
0
        ret = wc_Sha3_256_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18082
18083
        /* return 1 on success, 0 otherwise */
18084
0
        if (ret == 0)
18085
0
            return 1;
18086
18087
0
        return 0;
18088
0
    }
18089
18090
18091
    int wolfSSL_SHA3_256_Final(byte* output, WOLFSSL_SHA3_256_CTX* sha)
18092
0
    {
18093
0
        int ret;
18094
18095
0
        WOLFSSL_ENTER("SHA3_256_Final");
18096
0
        ret = wc_Sha3_256_Final((wc_Sha3*)sha, output);
18097
18098
        /* have to actually free the resources (if any) here, because the
18099
         * OpenSSL API doesn't include SHA*_Free().
18100
         */
18101
0
        wc_Sha3_256_Free((wc_Sha3*)sha);
18102
18103
        /* return 1 on success, 0 otherwise */
18104
0
        if (ret == 0)
18105
0
            return 1;
18106
18107
0
        return 0;
18108
0
    }
18109
#endif /* WOLFSSL_NOSHA3_256 */
18110
18111
18112
    int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha)
18113
0
    {
18114
0
        int ret;
18115
18116
0
        typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18117
0
        (void)sizeof(sha_test);
18118
18119
0
        WOLFSSL_ENTER("SHA3_384_Init");
18120
0
        ret = wc_InitSha3_384((wc_Sha3*)sha, NULL, INVALID_DEVID);
18121
18122
        /* return 1 on success, 0 otherwise */
18123
0
        if (ret == 0)
18124
0
            return 1;
18125
18126
0
        return 0;
18127
0
    }
18128
18129
18130
    int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha, const void* input,
18131
                           unsigned long sz)
18132
0
    {
18133
0
        int ret;
18134
18135
0
        WOLFSSL_ENTER("SHA3_384_Update");
18136
0
        ret = wc_Sha3_384_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18137
18138
        /* return 1 on success, 0 otherwise */
18139
0
        if (ret == 0)
18140
0
            return 1;
18141
18142
0
        return 0;
18143
0
    }
18144
18145
18146
    int wolfSSL_SHA3_384_Final(byte* output, WOLFSSL_SHA3_384_CTX* sha)
18147
0
    {
18148
0
        int ret;
18149
18150
0
        WOLFSSL_ENTER("SHA3_384_Final");
18151
0
        ret = wc_Sha3_384_Final((wc_Sha3*)sha, output);
18152
18153
        /* have to actually free the resources (if any) here, because the
18154
         * OpenSSL API doesn't include SHA*_Free().
18155
         */
18156
0
        wc_Sha3_384_Free((wc_Sha3*)sha);
18157
18158
        /* return 1 on success, 0 otherwise */
18159
0
        if (ret == 0)
18160
0
            return 1;
18161
18162
0
        return 0;
18163
0
    }
18164
18165
18166
18167
#ifndef WOLFSSL_NOSHA3_512
18168
18169
    int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha)
18170
0
    {
18171
0
        int ret;
18172
18173
0
        typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1];
18174
0
        (void)sizeof(sha_test);
18175
18176
0
        WOLFSSL_ENTER("SHA3_512_Init");
18177
0
        ret = wc_InitSha3_512((wc_Sha3*)sha, NULL, INVALID_DEVID);
18178
18179
        /* return 1 on success, 0 otherwise */
18180
0
        if (ret == 0)
18181
0
            return 1;
18182
18183
0
        return 0;
18184
0
    }
18185
18186
18187
    int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha, const void* input,
18188
                           unsigned long sz)
18189
0
    {
18190
0
        int ret;
18191
18192
0
        WOLFSSL_ENTER("SHA3_512_Update");
18193
0
        ret = wc_Sha3_512_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz);
18194
18195
        /* return 1 on success, 0 otherwise */
18196
0
        if (ret == 0)
18197
0
            return 1;
18198
18199
0
        return 0;
18200
0
    }
18201
18202
18203
    int wolfSSL_SHA3_512_Final(byte* output, WOLFSSL_SHA3_512_CTX* sha)
18204
0
    {
18205
0
        int ret;
18206
18207
0
        WOLFSSL_ENTER("SHA3_512_Final");
18208
0
        ret = wc_Sha3_512_Final((wc_Sha3*)sha, output);
18209
18210
        /* have to actually free the resources (if any) here, because the
18211
         * OpenSSL API doesn't include SHA*_Free().
18212
         */
18213
0
        wc_Sha3_512_Free((wc_Sha3*)sha);
18214
18215
        /* return 1 on success, 0 otherwise */
18216
0
        if (ret == 0)
18217
0
            return 1;
18218
18219
0
        return 0;
18220
0
    }
18221
18222
#endif /* WOLFSSL_NOSHA3_512 */
18223
#endif /* WOLFSSL_SHA3 */
18224
18225
    unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key,
18226
                                int key_len, const unsigned char* d, int n,
18227
                                unsigned char* md, unsigned int* md_len)
18228
0
    {
18229
0
        int type;
18230
0
        int mdlen;
18231
0
        unsigned char* ret = NULL;
18232
0
#ifdef WOLFSSL_SMALL_STACK
18233
0
        Hmac* hmac = NULL;
18234
#else
18235
        Hmac  hmac[1];
18236
#endif
18237
0
        void* heap = NULL;
18238
18239
0
        WOLFSSL_ENTER("wolfSSL_HMAC");
18240
0
        if (!md) {
18241
0
            WOLFSSL_MSG("Static buffer not supported, pass in md buffer");
18242
0
            return NULL;  /* no static buffer support */
18243
0
        }
18244
18245
0
#ifndef NO_MD5
18246
0
        if (XSTRCMP(evp_md, "MD5") == 0) {
18247
0
            type = WC_MD5;
18248
0
            mdlen = WC_MD5_DIGEST_SIZE;
18249
0
        } else
18250
0
#endif
18251
0
#ifdef WOLFSSL_SHA224
18252
0
        if (XSTRCMP(evp_md, "SHA224") == 0) {
18253
0
            type = WC_SHA224;
18254
0
            mdlen = WC_SHA224_DIGEST_SIZE;
18255
0
        } else
18256
0
#endif
18257
0
#ifndef NO_SHA256
18258
0
        if (XSTRCMP(evp_md, "SHA256") == 0) {
18259
0
            type = WC_SHA256;
18260
0
            mdlen = WC_SHA256_DIGEST_SIZE;
18261
0
        } else
18262
0
#endif
18263
0
#ifdef WOLFSSL_SHA384
18264
0
        if (XSTRCMP(evp_md, "SHA384") == 0) {
18265
0
            type = WC_SHA384;
18266
0
            mdlen = WC_SHA384_DIGEST_SIZE;
18267
0
        } else
18268
0
#endif
18269
0
#ifdef WOLFSSL_SHA512
18270
0
        if (XSTRCMP(evp_md, "SHA512") == 0) {
18271
0
            type = WC_SHA512;
18272
0
            mdlen = WC_SHA512_DIGEST_SIZE;
18273
0
        } else
18274
0
#endif
18275
0
#ifdef WOLFSSL_SHA3
18276
0
    #ifndef WOLFSSL_NOSHA3_224
18277
0
        if (XSTRCMP(evp_md, "SHA3_224") == 0) {
18278
0
            type = WC_SHA3_224;
18279
0
            mdlen = WC_SHA3_224_DIGEST_SIZE;
18280
0
        } else
18281
0
    #endif
18282
0
    #ifndef WOLFSSL_NOSHA3_256
18283
0
        if (XSTRCMP(evp_md, "SHA3_256") == 0) {
18284
0
            type = WC_SHA3_256;
18285
0
            mdlen = WC_SHA3_256_DIGEST_SIZE;
18286
0
        } else
18287
0
    #endif
18288
0
        if (XSTRCMP(evp_md, "SHA3_384") == 0) {
18289
0
            type = WC_SHA3_384;
18290
0
            mdlen = WC_SHA3_384_DIGEST_SIZE;
18291
0
        } else
18292
0
    #ifndef WOLFSSL_NOSHA3_512
18293
0
        if (XSTRCMP(evp_md, "SHA3_512") == 0) {
18294
0
            type = WC_SHA3_512;
18295
0
            mdlen = WC_SHA3_512_DIGEST_SIZE;
18296
0
        } else
18297
0
    #endif
18298
0
#endif
18299
0
#ifndef NO_SHA
18300
0
        if (XSTRCMP(evp_md, "SHA") == 0) {
18301
0
            type = WC_SHA;
18302
0
            mdlen = WC_SHA_DIGEST_SIZE;
18303
0
        } else
18304
0
#endif
18305
0
        {
18306
0
            return NULL;
18307
0
        }
18308
18309
0
    #ifdef WOLFSSL_SMALL_STACK
18310
0
        hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
18311
0
        if (hmac == NULL)
18312
0
            return NULL;
18313
0
    #endif
18314
18315
0
        if (wc_HmacInit(hmac, heap, INVALID_DEVID) == 0) {
18316
0
            if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) {
18317
0
                if (wc_HmacUpdate(hmac, d, n) == 0) {
18318
0
                    if (wc_HmacFinal(hmac, md) == 0) {
18319
0
                        if (md_len)
18320
0
                            *md_len = mdlen;
18321
0
                        ret = md;
18322
0
                    }
18323
0
                }
18324
0
            }
18325
0
            wc_HmacFree(hmac);
18326
0
        }
18327
18328
0
    #ifdef WOLFSSL_SMALL_STACK
18329
0
        XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
18330
0
    #endif
18331
18332
0
        (void)evp_md;
18333
0
        return ret;
18334
0
    }
18335
18336
#ifndef NO_DES3
18337
    /* 0 on ok */
18338
    int wolfSSL_DES_key_sched(WOLFSSL_const_DES_cblock* key,
18339
                              WOLFSSL_DES_key_schedule* schedule)
18340
0
    {
18341
0
        WOLFSSL_ENTER("wolfSSL_DES_key_sched");
18342
18343
0
        if (key == NULL || schedule == NULL) {
18344
0
            WOLFSSL_MSG("Null argument passed in");
18345
0
        }
18346
0
        else {
18347
0
            XMEMCPY(schedule, key, sizeof(WOLFSSL_const_DES_cblock));
18348
0
        }
18349
18350
0
        return 0;
18351
0
    }
18352
18353
18354
    /* intended to behave similar to Kerberos mit_des_cbc_cksum
18355
     * return the last 4 bytes of cipher text */
18356
    WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in,
18357
            WOLFSSL_DES_cblock* out, long length, WOLFSSL_DES_key_schedule* sc,
18358
            WOLFSSL_const_DES_cblock* iv)
18359
0
    {
18360
0
        WOLFSSL_DES_LONG ret;
18361
0
        unsigned char* tmp;
18362
0
        unsigned char* data   = (unsigned char*)in;
18363
0
        long           dataSz = length;
18364
0
        byte dynamicFlag = 0; /* when padding the buffer created needs free'd */
18365
18366
0
        WOLFSSL_ENTER("wolfSSL_DES_cbc_cksum");
18367
18368
0
        if (in == NULL || out == NULL || sc == NULL || iv == NULL) {
18369
0
            WOLFSSL_MSG("Bad argument passed in");
18370
0
            return 0;
18371
0
        }
18372
18373
        /* if input length is not a multiple of DES_BLOCK_SIZE pad with 0s */
18374
0
        if (dataSz % DES_BLOCK_SIZE) {
18375
0
            dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE);
18376
0
            data = (unsigned char*)XMALLOC(dataSz, NULL,
18377
0
                                           DYNAMIC_TYPE_TMP_BUFFER);
18378
0
            if (data == NULL) {
18379
0
                WOLFSSL_MSG("Issue creating temporary buffer");
18380
0
                return 0;
18381
0
            }
18382
0
            dynamicFlag = 1; /* set to free buffer at end */
18383
0
            XMEMCPY(data, in, length);
18384
0
            XMEMSET(data + length, 0, dataSz - length); /* padding */
18385
0
        }
18386
18387
0
        tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18388
0
        if (tmp == NULL) {
18389
0
            WOLFSSL_MSG("Issue creating temporary buffer");
18390
0
            if (dynamicFlag == 1) {
18391
0
                XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18392
0
            }
18393
0
            return 0;
18394
0
        }
18395
18396
0
        wolfSSL_DES_cbc_encrypt(data, tmp, dataSz, sc,
18397
0
                (WOLFSSL_DES_cblock*)iv, 1);
18398
0
        XMEMCPY((unsigned char*)out, tmp + (dataSz - DES_BLOCK_SIZE),
18399
0
                DES_BLOCK_SIZE);
18400
18401
0
        ret = (((*((unsigned char*)out + 4) & 0xFF) << 24)|
18402
0
               ((*((unsigned char*)out + 5) & 0xFF) << 16)|
18403
0
               ((*((unsigned char*)out + 6) & 0xFF) << 8) |
18404
0
               (*((unsigned char*)out + 7) & 0xFF));
18405
18406
0
        XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18407
0
        if (dynamicFlag == 1) {
18408
0
            XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
18409
0
        }
18410
18411
0
        return ret;
18412
0
    }
18413
18414
18415
    void wolfSSL_DES_cbc_encrypt(const unsigned char* input,
18416
                                 unsigned char* output, long length,
18417
                                 WOLFSSL_DES_key_schedule* schedule,
18418
                                 WOLFSSL_DES_cblock* ivec, int enc)
18419
0
    {
18420
0
        Des myDes;
18421
0
        byte lastblock[DES_BLOCK_SIZE];
18422
0
        int  lb_sz;
18423
0
        long  blk;
18424
18425
0
        WOLFSSL_ENTER("DES_cbc_encrypt");
18426
18427
        /* OpenSSL compat, no ret */
18428
0
        if (wc_Des_SetKey(&myDes, (const byte*)schedule, (const byte*)ivec,
18429
0
                !enc) != 0) {
18430
0
            WOLFSSL_MSG("wc_Des_SetKey return error.");
18431
0
            return;
18432
0
        }
18433
0
        lb_sz = length%DES_BLOCK_SIZE;
18434
0
        blk   = length/DES_BLOCK_SIZE;
18435
18436
0
        if (enc == DES_ENCRYPT){
18437
0
            wc_Des_CbcEncrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
18438
0
            if(lb_sz){
18439
0
                XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
18440
0
                XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
18441
0
                wc_Des_CbcEncrypt(&myDes, output+blk*DES_BLOCK_SIZE,
18442
0
                    lastblock, (word32)DES_BLOCK_SIZE);
18443
0
            }
18444
0
        }
18445
0
        else {
18446
0
            wc_Des_CbcDecrypt(&myDes, output, input, (word32)blk*DES_BLOCK_SIZE);
18447
0
            if(lb_sz){
18448
0
                wc_Des_CbcDecrypt(&myDes, lastblock, input+length-lb_sz, (word32)DES_BLOCK_SIZE);
18449
0
                XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
18450
0
            }
18451
0
        }
18452
0
    }
18453
18454
18455
    /* WOLFSSL_DES_key_schedule is a unsigned char array of size 8 */
18456
    void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input,
18457
                                      unsigned char* output, long sz,
18458
                                      WOLFSSL_DES_key_schedule* ks1,
18459
                                      WOLFSSL_DES_key_schedule* ks2,
18460
                                      WOLFSSL_DES_key_schedule* ks3,
18461
                                      WOLFSSL_DES_cblock* ivec, int enc)
18462
0
    {
18463
0
        int ret;
18464
0
        Des3 des;
18465
0
        byte key[24];/* EDE uses 24 size key */
18466
0
        byte lastblock[DES_BLOCK_SIZE];
18467
0
        int  lb_sz;
18468
0
        long  blk;
18469
18470
0
        WOLFSSL_ENTER("wolfSSL_DES_ede3_cbc_encrypt");
18471
18472
0
        XMEMSET(key, 0, sizeof(key));
18473
0
        XMEMCPY(key, *ks1, DES_BLOCK_SIZE);
18474
0
        XMEMCPY(&key[DES_BLOCK_SIZE], *ks2, DES_BLOCK_SIZE);
18475
0
        XMEMCPY(&key[DES_BLOCK_SIZE * 2], *ks3, DES_BLOCK_SIZE);
18476
0
        lb_sz = sz%DES_BLOCK_SIZE;
18477
0
        blk   = sz/DES_BLOCK_SIZE;
18478
18479
        /* OpenSSL compat, no ret */
18480
0
        (void)wc_Des3Init(&des, NULL, INVALID_DEVID);
18481
18482
0
        if (enc == DES_ENCRYPT) {
18483
0
            if (wc_Des3_SetKey(&des, key, (const byte*)ivec,
18484
0
                    DES_ENCRYPTION) == 0) {
18485
0
                ret = wc_Des3_CbcEncrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
18486
            #if defined(WOLFSSL_ASYNC_CRYPT)
18487
                ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18488
            #endif
18489
0
                (void)ret; /* ignore return codes for processing */
18490
0
                if(lb_sz){
18491
0
                    XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
18492
0
                    XMEMCPY(lastblock, input+sz-lb_sz, lb_sz);
18493
0
                    ret = wc_Des3_CbcEncrypt(&des, output+blk*DES_BLOCK_SIZE,
18494
0
                        lastblock, (word32)DES_BLOCK_SIZE);
18495
                #if defined(WOLFSSL_ASYNC_CRYPT)
18496
                    ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18497
                #endif
18498
0
                    (void)ret; /* ignore return codes for processing */
18499
0
                }
18500
0
            }
18501
0
        }
18502
0
        else {
18503
0
            if (wc_Des3_SetKey(&des, key, (const byte*)ivec,
18504
0
                    DES_DECRYPTION) == 0) {
18505
0
                ret = wc_Des3_CbcDecrypt(&des, output, input, (word32)blk*DES_BLOCK_SIZE);
18506
            #if defined(WOLFSSL_ASYNC_CRYPT)
18507
                ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18508
            #endif
18509
0
                (void)ret; /* ignore return codes for processing */
18510
0
                if(lb_sz){
18511
0
                    ret = wc_Des3_CbcDecrypt(&des, lastblock, input+sz-lb_sz, (word32)DES_BLOCK_SIZE);
18512
                #if defined(WOLFSSL_ASYNC_CRYPT)
18513
                    ret = wc_AsyncWait(ret, &des.asyncDev, WC_ASYNC_FLAG_NONE);
18514
                #endif
18515
0
                    (void)ret; /* ignore return codes for processing */
18516
0
                    XMEMCPY(output+sz-lb_sz, lastblock, lb_sz);
18517
0
                }
18518
0
            }
18519
0
        }
18520
0
        wc_Des3Free(&des);
18521
0
    }
18522
18523
18524
    /* correctly sets ivec for next call */
18525
    void wolfSSL_DES_ncbc_encrypt(const unsigned char* input,
18526
                     unsigned char* output, long length,
18527
                     WOLFSSL_DES_key_schedule* schedule, WOLFSSL_DES_cblock* ivec,
18528
                     int enc)
18529
0
    {
18530
0
        Des myDes;
18531
0
        byte lastblock[DES_BLOCK_SIZE];
18532
0
        int  lb_sz;
18533
0
        long idx = length;
18534
0
        long blk;
18535
18536
0
        WOLFSSL_ENTER("DES_ncbc_encrypt");
18537
18538
        /* OpenSSL compat, no ret */
18539
0
        if (wc_Des_SetKey(&myDes, (const byte*)schedule,
18540
0
                         (const byte*)ivec, !enc) != 0) {
18541
0
            WOLFSSL_MSG("wc_Des_SetKey return error.");
18542
0
            return;
18543
0
        }
18544
18545
0
        lb_sz = length%DES_BLOCK_SIZE;
18546
0
        blk   = length/DES_BLOCK_SIZE;
18547
0
        idx  -= sizeof(DES_cblock);
18548
0
        if (lb_sz) {
18549
0
            idx += DES_BLOCK_SIZE - lb_sz;
18550
0
        }
18551
0
        if (enc == DES_ENCRYPT){
18552
0
            wc_Des_CbcEncrypt(&myDes, output, input,
18553
0
                    (word32)blk * DES_BLOCK_SIZE);
18554
0
            if (lb_sz){
18555
0
                XMEMSET(lastblock, 0, DES_BLOCK_SIZE);
18556
0
                XMEMCPY(lastblock, input+length-lb_sz, lb_sz);
18557
0
                wc_Des_CbcEncrypt(&myDes, output + blk * DES_BLOCK_SIZE,
18558
0
                    lastblock, (word32)DES_BLOCK_SIZE);
18559
0
            }
18560
0
            XMEMCPY(ivec, output + idx, sizeof(DES_cblock));
18561
0
        } else {
18562
0
            WOLFSSL_DES_cblock tmp;
18563
0
            XMEMCPY(tmp, input + idx, sizeof(DES_cblock));
18564
0
            wc_Des_CbcDecrypt(&myDes, output, input,
18565
0
                    (word32)blk * DES_BLOCK_SIZE);
18566
0
            if (lb_sz){
18567
0
                wc_Des_CbcDecrypt(&myDes, lastblock, input + length - lb_sz,
18568
0
                        (word32)DES_BLOCK_SIZE);
18569
0
                XMEMCPY(output+length-lb_sz, lastblock, lb_sz);
18570
0
            }
18571
0
            XMEMCPY(ivec, tmp, sizeof(WOLFSSL_DES_cblock));
18572
0
        }
18573
18574
0
    }
18575
18576
#endif /* NO_DES3 */
18577
18578
    void wolfSSL_ERR_free_strings(void)
18579
0
    {
18580
        /* handled internally */
18581
0
    }
18582
18583
    void wolfSSL_cleanup_all_ex_data(void)
18584
0
    {
18585
        /* nothing to do here */
18586
0
    }
18587
18588
#endif /* OPENSSL_EXTRA */
18589
18590
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
18591
    void wolfSSL_ERR_clear_error(void)
18592
0
    {
18593
0
        WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
18594
0
        wc_ClearErrorNodes();
18595
0
    }
18596
#endif
18597
18598
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
18599
    int wolfSSL_clear(WOLFSSL* ssl)
18600
0
    {
18601
0
        WOLFSSL_ENTER("wolfSSL_clear");
18602
18603
0
        if (ssl == NULL) {
18604
0
            return WOLFSSL_FAILURE;
18605
0
        }
18606
18607
0
        if (!ssl->options.handShakeDone) {
18608
            /* Only reset the session if we didn't complete a handshake */
18609
0
            wolfSSL_SESSION_free(ssl->session);
18610
0
            ssl->session = wolfSSL_NewSession(ssl->heap);
18611
0
            if (ssl->session == NULL) {
18612
0
                return WOLFSSL_FAILURE;
18613
0
            }
18614
0
        }
18615
18616
        /* reset option bits */
18617
0
        ssl->options.isClosed = 0;
18618
0
        ssl->options.connReset = 0;
18619
0
        ssl->options.sentNotify = 0;
18620
0
        ssl->options.closeNotify = 0;
18621
0
        ssl->options.sendVerify = 0;
18622
0
        ssl->options.serverState = NULL_STATE;
18623
0
        ssl->options.clientState = NULL_STATE;
18624
0
        ssl->options.connectState = CONNECT_BEGIN;
18625
0
        ssl->options.acceptState  = ACCEPT_BEGIN;
18626
0
        ssl->options.handShakeState  = NULL_STATE;
18627
0
        ssl->options.handShakeDone = 0;
18628
0
        ssl->options.processReply = 0; /* doProcessInit */
18629
0
        ssl->options.havePeerVerify = 0;
18630
0
        ssl->options.havePeerCert = 0;
18631
0
        ssl->options.peerAuthGood = 0;
18632
0
        ssl->options.tls1_3 = 0;
18633
0
        ssl->options.haveSessionId = 0;
18634
0
        ssl->options.tls = 0;
18635
0
        ssl->options.tls1_1 = 0;
18636
0
        ssl->options.noPskDheKe = 0;
18637
0
    #ifdef HAVE_SESSION_TICKET
18638
0
        #ifdef WOLFSSL_TLS13
18639
0
        ssl->options.ticketsSent = 0;
18640
0
        #endif
18641
0
        ssl->options.rejectTicket = 0;
18642
0
    #endif
18643
    #ifdef WOLFSSL_EARLY_DATA
18644
        ssl->earlyData = no_early_data;
18645
        ssl->earlyDataSz = 0;
18646
    #endif
18647
18648
0
    #if defined(HAVE_TLS_EXTENSIONS) && !defined(NO_TLS)
18649
0
        TLSX_FreeAll(ssl->extensions, ssl->heap);
18650
0
        ssl->extensions = NULL;
18651
0
    #endif
18652
18653
0
        ssl->keys.encryptionOn = 0;
18654
0
        XMEMSET(&ssl->msgsReceived, 0, sizeof(ssl->msgsReceived));
18655
18656
0
        if (InitHandshakeHashes(ssl) != 0)
18657
0
            return WOLFSSL_FAILURE;
18658
18659
0
#ifdef KEEP_PEER_CERT
18660
0
        FreeX509(&ssl->peerCert);
18661
0
        InitX509(&ssl->peerCert, 0, ssl->heap);
18662
0
#endif
18663
18664
#ifdef WOLFSSL_QUIC
18665
        wolfSSL_quic_clear(ssl);
18666
#endif
18667
18668
0
        return WOLFSSL_SUCCESS;
18669
0
    }
18670
18671
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
18672
18673
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
18674
    long wolfSSL_CTX_set_mode(WOLFSSL_CTX* ctx, long mode)
18675
0
    {
18676
        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
18677
18678
0
        WOLFSSL_ENTER("SSL_CTX_set_mode");
18679
0
        switch(mode) {
18680
0
            case SSL_MODE_ENABLE_PARTIAL_WRITE:
18681
0
                ctx->partialWrite = 1;
18682
0
                break;
18683
0
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
18684
0
            case SSL_MODE_RELEASE_BUFFERS:
18685
0
                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
18686
0
                break;
18687
0
            #endif
18688
0
            case SSL_MODE_AUTO_RETRY:
18689
0
                ctx->autoRetry = 1;
18690
0
                break;
18691
0
            default:
18692
0
                WOLFSSL_MSG("Mode Not Implemented");
18693
0
        }
18694
18695
        /* SSL_MODE_AUTO_RETRY
18696
         * Should not return -1 with renegotiation on read/write */
18697
18698
0
        return mode;
18699
0
    }
18700
18701
    long wolfSSL_CTX_clear_mode(WOLFSSL_CTX* ctx, long mode)
18702
0
    {
18703
        /* WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is wolfSSL default mode */
18704
18705
0
        WOLFSSL_ENTER("SSL_CTX_set_mode");
18706
0
        switch(mode) {
18707
0
            case SSL_MODE_ENABLE_PARTIAL_WRITE:
18708
0
                ctx->partialWrite = 0;
18709
0
                break;
18710
0
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
18711
0
            case SSL_MODE_RELEASE_BUFFERS:
18712
0
                WOLFSSL_MSG("SSL_MODE_RELEASE_BUFFERS not implemented.");
18713
0
                break;
18714
0
            #endif
18715
0
            case SSL_MODE_AUTO_RETRY:
18716
0
                ctx->autoRetry = 0;
18717
0
                break;
18718
0
            default:
18719
0
                WOLFSSL_MSG("Mode Not Implemented");
18720
0
        }
18721
18722
        /* SSL_MODE_AUTO_RETRY
18723
         * Should not return -1 with renegotiation on read/write */
18724
18725
0
        return 0;
18726
0
    }
18727
#endif
18728
18729
#ifdef OPENSSL_EXTRA
18730
18731
    #ifndef NO_WOLFSSL_STUB
18732
    long wolfSSL_SSL_get_mode(WOLFSSL* ssl)
18733
0
    {
18734
        /* TODO: */
18735
0
        (void)ssl;
18736
0
        WOLFSSL_STUB("SSL_get_mode");
18737
0
        return 0;
18738
0
    }
18739
    #endif
18740
18741
    #ifndef NO_WOLFSSL_STUB
18742
    long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
18743
0
    {
18744
        /* TODO: */
18745
0
        (void)ctx;
18746
0
        WOLFSSL_STUB("SSL_CTX_get_mode");
18747
0
        return 0;
18748
0
    }
18749
    #endif
18750
18751
    #ifndef NO_WOLFSSL_STUB
18752
    void wolfSSL_CTX_set_default_read_ahead(WOLFSSL_CTX* ctx, int m)
18753
0
    {
18754
        /* TODO: maybe? */
18755
0
        (void)ctx;
18756
0
        (void)m;
18757
0
        WOLFSSL_STUB("SSL_CTX_set_default_read_ahead");
18758
0
    }
18759
    #endif
18760
18761
18762
    /* Storing app session context id, this value is inherited by WOLFSSL
18763
     * objects created from WOLFSSL_CTX. Any session that is imported with a
18764
     * different session context id will be rejected.
18765
     *
18766
     * ctx         structure to set context in
18767
     * sid_ctx     value of context to set
18768
     * sid_ctx_len length of sid_ctx buffer
18769
     *
18770
     * Returns WOLFSSL_SUCCESS in success case and SSL_FAILURE when failing
18771
     */
18772
    int wolfSSL_CTX_set_session_id_context(WOLFSSL_CTX* ctx,
18773
                                           const unsigned char* sid_ctx,
18774
                                           unsigned int sid_ctx_len)
18775
0
    {
18776
0
        WOLFSSL_ENTER("SSL_CTX_set_session_id_context");
18777
18778
        /* No application specific context needed for wolfSSL */
18779
0
        if (sid_ctx_len > ID_LEN || ctx == NULL || sid_ctx == NULL) {
18780
0
            return SSL_FAILURE;
18781
0
        }
18782
0
        XMEMCPY(ctx->sessionCtx, sid_ctx, sid_ctx_len);
18783
0
        ctx->sessionCtxSz = (byte)sid_ctx_len;
18784
18785
0
        return WOLFSSL_SUCCESS;
18786
0
    }
18787
18788
18789
18790
    /* Storing app session context id. Any session that is imported with a
18791
     * different session context id will be rejected.
18792
     *
18793
     * ssl  structure to set context in
18794
     * id   value of context to set
18795
     * len  length of sid_ctx buffer
18796
     *
18797
     * Returns WOLFSSL_SUCCESS in success case and SSL_FAILURE when failing
18798
     */
18799
    int wolfSSL_set_session_id_context(WOLFSSL* ssl, const unsigned char* id,
18800
                                   unsigned int len)
18801
0
    {
18802
0
        WOLFSSL_ENTER("wolfSSL_set_session_id_context");
18803
18804
0
        if (len > ID_LEN || ssl == NULL || id == NULL) {
18805
0
            return SSL_FAILURE;
18806
0
        }
18807
0
        XMEMCPY(ssl->sessionCtx, id, len);
18808
0
        ssl->sessionCtxSz = (byte)len;
18809
18810
0
        return WOLFSSL_SUCCESS;
18811
0
    }
18812
18813
18814
    long wolfSSL_CTX_sess_get_cache_size(WOLFSSL_CTX* ctx)
18815
0
    {
18816
0
        (void)ctx;
18817
0
        #ifndef NO_SESSION_CACHE
18818
0
            return (long)(SESSIONS_PER_ROW * SESSION_ROWS);
18819
        #else
18820
            return 0;
18821
        #endif
18822
0
    }
18823
18824
18825
    /* returns the unsigned error value and increments the pointer into the
18826
     * error queue.
18827
     *
18828
     * file  pointer to file name
18829
     * line  gets set to line number of error when not NULL
18830
     */
18831
    unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
18832
0
    {
18833
0
    #ifdef WOLFSSL_HAVE_ERROR_QUEUE
18834
0
        int ret = wc_PullErrorNode(file, NULL, line);
18835
0
        if (ret < 0) {
18836
0
            if (ret == BAD_STATE_E) return 0; /* no errors in queue */
18837
0
            WOLFSSL_MSG("Issue getting error node");
18838
0
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line", ret);
18839
0
            ret = 0 - ret; /* return absolute value of error */
18840
18841
            /* panic and try to clear out nodes */
18842
0
            wc_ClearErrorNodes();
18843
0
        }
18844
0
        return (unsigned long)ret;
18845
    #else
18846
        (void)file;
18847
        (void)line;
18848
18849
        return 0;
18850
    #endif
18851
0
    }
18852
18853
18854
#if (defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA)) && \
18855
    (!defined(_WIN32) && !defined(NO_ERROR_QUEUE))
18856
    static const char WOLFSSL_SYS_ACCEPT_T[]  = "accept";
18857
    static const char WOLFSSL_SYS_BIND_T[]    = "bind";
18858
    static const char WOLFSSL_SYS_CONNECT_T[] = "connect";
18859
    static const char WOLFSSL_SYS_FOPEN_T[]   = "fopen";
18860
    static const char WOLFSSL_SYS_FREAD_T[]   = "fread";
18861
    static const char WOLFSSL_SYS_GETADDRINFO_T[] = "getaddrinfo";
18862
    static const char WOLFSSL_SYS_GETSOCKOPT_T[]  = "getsockopt";
18863
    static const char WOLFSSL_SYS_GETSOCKNAME_T[] = "getsockname";
18864
    static const char WOLFSSL_SYS_GETHOSTBYNAME_T[] = "gethostbyname";
18865
    static const char WOLFSSL_SYS_GETNAMEINFO_T[]   = "getnameinfo";
18866
    static const char WOLFSSL_SYS_GETSERVBYNAME_T[] = "getservbyname";
18867
    static const char WOLFSSL_SYS_IOCTLSOCKET_T[]   = "ioctlsocket";
18868
    static const char WOLFSSL_SYS_LISTEN_T[]        = "listen";
18869
    static const char WOLFSSL_SYS_OPENDIR_T[]       = "opendir";
18870
    static const char WOLFSSL_SYS_SETSOCKOPT_T[]    = "setsockopt";
18871
    static const char WOLFSSL_SYS_SOCKET_T[]        = "socket";
18872
18873
    /* switch with int mapped to function name for compatibility */
18874
    static const char* wolfSSL_ERR_sys_func(int fun)
18875
0
    {
18876
0
        switch (fun) {
18877
0
            case WOLFSSL_SYS_ACCEPT:      return WOLFSSL_SYS_ACCEPT_T;
18878
0
            case WOLFSSL_SYS_BIND:        return WOLFSSL_SYS_BIND_T;
18879
0
            case WOLFSSL_SYS_CONNECT:     return WOLFSSL_SYS_CONNECT_T;
18880
0
            case WOLFSSL_SYS_FOPEN:       return WOLFSSL_SYS_FOPEN_T;
18881
0
            case WOLFSSL_SYS_FREAD:       return WOLFSSL_SYS_FREAD_T;
18882
0
            case WOLFSSL_SYS_GETADDRINFO: return WOLFSSL_SYS_GETADDRINFO_T;
18883
0
            case WOLFSSL_SYS_GETSOCKOPT:  return WOLFSSL_SYS_GETSOCKOPT_T;
18884
0
            case WOLFSSL_SYS_GETSOCKNAME: return WOLFSSL_SYS_GETSOCKNAME_T;
18885
0
            case WOLFSSL_SYS_GETHOSTBYNAME: return WOLFSSL_SYS_GETHOSTBYNAME_T;
18886
0
            case WOLFSSL_SYS_GETNAMEINFO: return WOLFSSL_SYS_GETNAMEINFO_T;
18887
0
            case WOLFSSL_SYS_GETSERVBYNAME: return WOLFSSL_SYS_GETSERVBYNAME_T;
18888
0
            case WOLFSSL_SYS_IOCTLSOCKET: return WOLFSSL_SYS_IOCTLSOCKET_T;
18889
0
            case WOLFSSL_SYS_LISTEN:      return WOLFSSL_SYS_LISTEN_T;
18890
0
            case WOLFSSL_SYS_OPENDIR:     return WOLFSSL_SYS_OPENDIR_T;
18891
0
            case WOLFSSL_SYS_SETSOCKOPT:  return WOLFSSL_SYS_SETSOCKOPT_T;
18892
0
            case WOLFSSL_SYS_SOCKET:      return WOLFSSL_SYS_SOCKET_T;
18893
0
            default:
18894
0
                return "NULL";
18895
0
        }
18896
0
    }
18897
#endif /* DEBUG_WOLFSSL */
18898
18899
18900
    void wolfSSL_ERR_put_error(int lib, int fun, int err, const char* file,
18901
            int line)
18902
0
    {
18903
0
        WOLFSSL_ENTER("wolfSSL_ERR_put_error");
18904
18905
        #if !defined(DEBUG_WOLFSSL) && !defined(OPENSSL_EXTRA)
18906
        (void)fun;
18907
        (void)err;
18908
        (void)file;
18909
        (void)line;
18910
        WOLFSSL_MSG("Not compiled in debug mode");
18911
        #elif defined(OPENSSL_EXTRA) && \
18912
                (defined(_WIN32) || defined(NO_ERROR_QUEUE))
18913
        (void)fun;
18914
        (void)file;
18915
        (void)line;
18916
        WOLFSSL_ERROR(err);
18917
        #else
18918
0
        WOLFSSL_ERROR_LINE(err, wolfSSL_ERR_sys_func(fun), (unsigned int)line,
18919
0
            file, NULL);
18920
0
        #endif
18921
0
        (void)lib;
18922
0
    }
18923
18924
18925
    /* Similar to wolfSSL_ERR_get_error_line but takes in a flags argument for
18926
     * more flexibility.
18927
     *
18928
     * file  output pointer to file where error happened
18929
     * line  output to line number of error
18930
     * data  output data. Is a string if ERR_TXT_STRING flag is used
18931
     * flags output format of output
18932
     *
18933
     * Returns the error value or 0 if no errors are in the queue
18934
     */
18935
    unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
18936
                                                  const char** data, int *flags)
18937
0
    {
18938
0
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
18939
0
        int ret;
18940
18941
0
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
18942
18943
0
        if (flags != NULL)
18944
0
            *flags = ERR_TXT_STRING; /* Clear the flags */
18945
18946
0
        ret = wc_PullErrorNode(file, data, line);
18947
0
        if (ret < 0) {
18948
0
            if (ret == BAD_STATE_E) return 0; /* no errors in queue */
18949
0
            WOLFSSL_MSG("Error with pulling error node!");
18950
0
            WOLFSSL_LEAVE("wolfSSL_ERR_get_error_line_data", ret);
18951
0
            ret = 0 - ret; /* return absolute value of error */
18952
18953
            /* panic and try to clear out nodes */
18954
0
            wc_ClearErrorNodes();
18955
0
        }
18956
18957
0
        return (unsigned long)ret;
18958
#else
18959
        WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
18960
        WOLFSSL_MSG("Error queue turned off, can not get error line");
18961
        (void)file;
18962
        (void)line;
18963
        (void)data;
18964
        (void)flags;
18965
        return 0;
18966
#endif
18967
0
    }
18968
18969
#endif /* OPENSSL_EXTRA */
18970
18971
18972
#if (defined(KEEP_PEER_CERT) && defined(SESSION_CERTS)) || \
18973
    (defined(OPENSSL_EXTRA) && defined(SESSION_CERTS))
18974
    /* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
18975
     *
18976
     * x509  WOLFSSL_X509 object to decode into.
18977
     * in    X509 DER data.
18978
     * len   Length of the X509 DER data.
18979
     * returns the new certificate on success, otherwise NULL.
18980
     */
18981
    static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
18982
    {
18983
        int          ret;
18984
    #ifdef WOLFSSL_SMALL_STACK
18985
        DecodedCert* cert;
18986
    #else
18987
        DecodedCert  cert[1];
18988
    #endif
18989
        if (x509 == NULL || in == NULL || len <= 0)
18990
            return BAD_FUNC_ARG;
18991
18992
    #ifdef WOLFSSL_SMALL_STACK
18993
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
18994
                                     DYNAMIC_TYPE_DCERT);
18995
        if (cert == NULL)
18996
            return MEMORY_E;
18997
    #endif
18998
18999
        /* Create a DecodedCert object and copy fields into WOLFSSL_X509 object.
19000
         */
19001
        InitDecodedCert(cert, (byte*)in, len, NULL);
19002
        if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) == 0) {
19003
        /* Check if x509 was not previously initialized by wolfSSL_X509_new() */
19004
            if (x509->dynamicMemory != TRUE)
19005
                InitX509(x509, 0, NULL);
19006
            ret = CopyDecodedToX509(x509, cert);
19007
            FreeDecodedCert(cert);
19008
        }
19009
    #ifdef WOLFSSL_SMALL_STACK
19010
        XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
19011
    #endif
19012
19013
        return ret;
19014
    }
19015
#endif /* (KEEP_PEER_CERT & SESSION_CERTS) || (OPENSSL_EXTRA & SESSION_CERTS) */
19016
19017
19018
#ifdef KEEP_PEER_CERT
19019
    WOLFSSL_ABI
19020
    WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
19021
0
    {
19022
0
        WOLFSSL_X509* ret = NULL;
19023
0
        WOLFSSL_ENTER("SSL_get_peer_certificate");
19024
0
        if (ssl != NULL) {
19025
0
            if (ssl->peerCert.issuer.sz)
19026
0
                ret = wolfSSL_X509_dup(&ssl->peerCert);
19027
#ifdef SESSION_CERTS
19028
            else if (ssl->session->chain.count > 0) {
19029
                if (DecodeToX509(&ssl->peerCert, ssl->session->chain.certs[0].buffer,
19030
                        ssl->session->chain.certs[0].length) == 0) {
19031
                    ret = wolfSSL_X509_dup(&ssl->peerCert);
19032
                }
19033
            }
19034
#endif
19035
0
        }
19036
0
        WOLFSSL_LEAVE("SSL_get_peer_certificate", ret != NULL);
19037
0
        return ret;
19038
0
    }
19039
19040
#endif /* KEEP_PEER_CERT */
19041
19042
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
19043
/* Return stack of peer certs.
19044
 * Caller does not need to free return. The stack is Free'd when WOLFSSL* ssl is.
19045
 */
19046
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
19047
{
19048
    WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
19049
19050
    if (ssl == NULL)
19051
        return NULL;
19052
19053
    /* Try to populate if NULL or empty */
19054
    if (ssl->peerCertChain == NULL ||
19055
            wolfSSL_sk_X509_num(ssl->peerCertChain) == 0)
19056
        wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl);
19057
    return ssl->peerCertChain;
19058
}
19059
19060
#ifndef WOLFSSL_QT
19061
static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
19062
        WOLFSSL_X509 *x);
19063
/**
19064
 * Recursively push the issuer CA chain onto the stack
19065
 * @param cm The cert manager that is queried for the issuer
19066
 * @param x  This cert's issuer will be queried in cm
19067
 * @param sk The issuer is pushed onto this stack
19068
 * @return WOLFSSL_SUCCESS on success
19069
 *         WOLFSSL_FAILURE on no issuer found
19070
 *         WOLFSSL_FATAL_ERROR on a fatal error
19071
 */
19072
static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm,
19073
        WOLFSSL_X509 *x, WOLFSSL_STACK* sk)
19074
{
19075
    WOLFSSL_X509* issuer[MAX_CHAIN_DEPTH];
19076
    int i;
19077
    int push = 1;
19078
    int ret = WOLFSSL_SUCCESS;
19079
19080
    for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
19081
        if (x509GetIssuerFromCM(&issuer[i], cm, x)
19082
                != WOLFSSL_SUCCESS)
19083
            break;
19084
        x = issuer[i];
19085
    }
19086
    if (i == 0) /* No further chain found */
19087
        return WOLFSSL_FAILURE;
19088
    i--;
19089
    for (; i >= 0; i--) {
19090
        if (push) {
19091
            if (wolfSSL_sk_X509_push(sk, issuer[i]) != WOLFSSL_SUCCESS) {
19092
                wolfSSL_X509_free(issuer[i]);
19093
                ret = WOLFSSL_FATAL_ERROR;
19094
                push = 0; /* Free the rest of the unpushed certs */
19095
            }
19096
        }
19097
        else {
19098
            wolfSSL_X509_free(issuer[i]);
19099
        }
19100
    }
19101
    return ret;
19102
}
19103
#endif /* !WOLFSSL_QT */
19104
19105
/* Builds up and creates a stack of peer certificates for ssl->peerCertChain
19106
    based off of the ssl session chain. Attempts to place CA certificates
19107
    at the bottom of the stack. Returns stack of WOLFSSL_X509 certs or
19108
    NULL on failure */
19109
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
19110
{
19111
    WOLFSSL_STACK* sk;
19112
    WOLFSSL_X509* x509;
19113
    int i = 0;
19114
    int ret;
19115
19116
    WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
19117
    if ((ssl == NULL) || (ssl->session->chain.count == 0))
19118
        return NULL;
19119
19120
    sk = wolfSSL_sk_X509_new();
19121
    i = ssl->session->chain.count-1;
19122
    for (; i >= 0; i--) {
19123
        x509 = wolfSSL_X509_new();
19124
        if (x509 == NULL) {
19125
            WOLFSSL_MSG("Error Creating X509");
19126
            wolfSSL_sk_X509_pop_free(sk, NULL);
19127
            return NULL;
19128
        }
19129
        ret = DecodeToX509(x509, ssl->session->chain.certs[i].buffer,
19130
                             ssl->session->chain.certs[i].length);
19131
#if !defined(WOLFSSL_QT)
19132
        if (ret == 0 && i == ssl->session->chain.count-1) {
19133
            /* On the last element in the chain try to add the CA chain
19134
             * first if we have one for this cert */
19135
            if (PushCAx509Chain(SSL_CM(ssl), x509, sk)
19136
                    == WOLFSSL_FATAL_ERROR) {
19137
                ret = WOLFSSL_FATAL_ERROR;
19138
            }
19139
        }
19140
#endif
19141
19142
        if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) != WOLFSSL_SUCCESS) {
19143
            WOLFSSL_MSG("Error decoding cert");
19144
            wolfSSL_X509_free(x509);
19145
            wolfSSL_sk_X509_pop_free(sk, NULL);
19146
            return NULL;
19147
        }
19148
    }
19149
19150
    if (sk == NULL) {
19151
        WOLFSSL_MSG("Null session chain");
19152
    }
19153
#if defined(OPENSSL_ALL)
19154
    else if (ssl->options.side == WOLFSSL_SERVER_END) {
19155
        /* to be compliant with openssl
19156
           first element is kept as peer cert on server side.*/
19157
        wolfSSL_sk_X509_shift(sk);
19158
    }
19159
#endif
19160
    if (ssl->peerCertChain != NULL)
19161
        wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
19162
    /* This is Free'd when ssl is Free'd */
19163
    ssl->peerCertChain = sk;
19164
    return sk;
19165
}
19166
#endif /* SESSION_CERTS && OPENSSL_EXTRA */
19167
19168
#ifndef NO_CERTS
19169
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
19170
19171
/* create a generic wolfSSL stack node
19172
 * returns a new WOLFSSL_STACK structure on success */
19173
WOLFSSL_STACK* wolfSSL_sk_new_node(void* heap)
19174
0
{
19175
0
    WOLFSSL_STACK* sk;
19176
0
    WOLFSSL_ENTER("wolfSSL_sk_new_node");
19177
19178
0
    sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), heap,
19179
0
                                                          DYNAMIC_TYPE_OPENSSL);
19180
0
    if (sk != NULL) {
19181
0
        XMEMSET(sk, 0, sizeof(*sk));
19182
0
        sk->heap = heap;
19183
0
    }
19184
19185
0
    return sk;
19186
0
}
19187
19188
/* free's node but does not free internal data such as in->data.x509 */
19189
void wolfSSL_sk_free_node(WOLFSSL_STACK* in)
19190
0
{
19191
0
    if (in != NULL) {
19192
0
        XFREE(in, in->heap, DYNAMIC_TYPE_OPENSSL);
19193
0
    }
19194
0
}
19195
19196
/* pushes node "in" onto "stack" and returns pointer to the new stack on success
19197
 * also handles internal "num" for number of nodes on stack
19198
 * return WOLFSSL_SUCCESS on success
19199
 */
19200
int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in)
19201
0
{
19202
0
    if (stack == NULL || in == NULL) {
19203
0
        return WOLFSSL_FAILURE;
19204
0
    }
19205
19206
0
    if (*stack == NULL) {
19207
0
        in->num = 1;
19208
0
        *stack = in;
19209
0
        return WOLFSSL_SUCCESS;
19210
0
    }
19211
19212
0
    in->num  = (*stack)->num + 1;
19213
0
    in->next = *stack;
19214
0
    *stack   = in;
19215
0
    return WOLFSSL_SUCCESS;
19216
0
}
19217
19218
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19219
static WC_INLINE int compare_WOLFSSL_CIPHER(
19220
    WOLFSSL_CIPHER *a,
19221
    WOLFSSL_CIPHER *b)
19222
0
{
19223
0
    if ((a->cipherSuite0 == b->cipherSuite0) &&
19224
0
        (a->cipherSuite == b->cipherSuite) &&
19225
0
        (a->ssl == b->ssl) &&
19226
0
        (XMEMCMP(a->description, b->description, sizeof a->description) == 0) &&
19227
0
        (a->offset == b->offset) &&
19228
0
        (a->in_stack == b->in_stack) &&
19229
0
        (a->bits == b->bits))
19230
0
        return 0;
19231
0
    else
19232
0
        return -1;
19233
0
}
19234
#endif /* OPENSSL_ALL || WOLFSSL_QT */
19235
19236
19237
/* return 1 on success 0 on fail */
19238
int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data)
19239
0
{
19240
0
    WOLFSSL_STACK* node;
19241
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19242
0
    WOLFSSL_CIPHER ciph;
19243
0
#endif
19244
0
    WOLFSSL_ENTER("wolfSSL_sk_push");
19245
19246
0
    if (!sk) {
19247
0
        return WOLFSSL_FAILURE;
19248
0
    }
19249
19250
    /* Check if empty data */
19251
0
    switch (sk->type) {
19252
0
        case STACK_TYPE_CIPHER:
19253
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19254
            /* check if entire struct is zero */
19255
0
            XMEMSET(&ciph, 0, sizeof(WOLFSSL_CIPHER));
19256
0
            if (compare_WOLFSSL_CIPHER(&sk->data.cipher, &ciph) == 0) {
19257
0
                sk->data.cipher = *(WOLFSSL_CIPHER*)data;
19258
0
                sk->num = 1;
19259
0
                if (sk->hash_fn) {
19260
0
                    sk->hash = sk->hash_fn(&sk->data.cipher);
19261
0
                }
19262
0
                return WOLFSSL_SUCCESS;
19263
0
            }
19264
0
            break;
19265
0
#endif
19266
0
        case STACK_TYPE_X509:
19267
0
        case STACK_TYPE_GEN_NAME:
19268
0
        case STACK_TYPE_BIO:
19269
0
        case STACK_TYPE_OBJ:
19270
0
        case STACK_TYPE_STRING:
19271
0
        case STACK_TYPE_ACCESS_DESCRIPTION:
19272
0
        case STACK_TYPE_X509_EXT:
19273
0
        case STACK_TYPE_X509_REQ_ATTR:
19274
0
        case STACK_TYPE_NULL:
19275
0
        case STACK_TYPE_X509_NAME:
19276
0
        case STACK_TYPE_X509_NAME_ENTRY:
19277
0
        case STACK_TYPE_CONF_VALUE:
19278
0
        case STACK_TYPE_X509_INFO:
19279
0
        case STACK_TYPE_BY_DIR_entry:
19280
0
        case STACK_TYPE_BY_DIR_hash:
19281
0
        case STACK_TYPE_X509_OBJ:
19282
0
        case STACK_TYPE_DIST_POINT:
19283
0
        case STACK_TYPE_X509_CRL:
19284
0
        default:
19285
            /* All other types are pointers */
19286
0
            if (!sk->data.generic) {
19287
0
                sk->data.generic = (void*)data;
19288
0
                sk->num = 1;
19289
0
#ifdef OPENSSL_ALL
19290
0
                if (sk->hash_fn) {
19291
0
                    sk->hash = sk->hash_fn(sk->data.generic);
19292
0
                }
19293
0
#endif
19294
0
                return WOLFSSL_SUCCESS;
19295
0
            }
19296
0
            break;
19297
0
    }
19298
19299
    /* stack already has value(s) create a new node and add more */
19300
0
    node = wolfSSL_sk_new_node(sk->heap);
19301
0
    if (!node) {
19302
0
        WOLFSSL_MSG("Memory error");
19303
0
        return WOLFSSL_FAILURE;
19304
0
    }
19305
19306
    /* push new x509 onto head of stack */
19307
0
    node->next      = sk->next;
19308
0
    node->type      = sk->type;
19309
0
    sk->next        = node;
19310
0
    sk->num        += 1;
19311
19312
0
#ifdef OPENSSL_ALL
19313
0
    node->comp = sk->comp;
19314
0
    node->hash_fn = sk->hash_fn;
19315
0
    node->hash = sk->hash;
19316
0
    sk->hash = 0;
19317
0
#endif
19318
0
    switch (sk->type) {
19319
0
        case STACK_TYPE_CIPHER:
19320
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
19321
0
            node->data.cipher = sk->data.cipher;
19322
0
            sk->data.cipher = *(WOLFSSL_CIPHER*)data;
19323
0
            if (sk->hash_fn) {
19324
0
                sk->hash = sk->hash_fn(&sk->data.cipher);
19325
0
            }
19326
0
            break;
19327
0
#endif
19328
0
        case STACK_TYPE_X509:
19329
0
        case STACK_TYPE_GEN_NAME:
19330
0
        case STACK_TYPE_BIO:
19331
0
        case STACK_TYPE_OBJ:
19332
0
        case STACK_TYPE_STRING:
19333
0
        case STACK_TYPE_ACCESS_DESCRIPTION:
19334
0
        case STACK_TYPE_X509_EXT:
19335
0
        case STACK_TYPE_X509_REQ_ATTR:
19336
0
        case STACK_TYPE_NULL:
19337
0
        case STACK_TYPE_X509_NAME:
19338
0
        case STACK_TYPE_X509_NAME_ENTRY:
19339
0
        case STACK_TYPE_CONF_VALUE:
19340
0
        case STACK_TYPE_X509_INFO:
19341
0
        case STACK_TYPE_BY_DIR_entry:
19342
0
        case STACK_TYPE_BY_DIR_hash:
19343
0
        case STACK_TYPE_X509_OBJ:
19344
0
        case STACK_TYPE_DIST_POINT:
19345
0
        case STACK_TYPE_X509_CRL:
19346
0
        default:
19347
            /* All other types are pointers */
19348
0
            node->data.generic = sk->data.generic;
19349
0
            sk->data.generic = (void*)data;
19350
0
#ifdef OPENSSL_ALL
19351
0
            if (sk->hash_fn) {
19352
0
                sk->hash = sk->hash_fn(sk->data.generic);
19353
0
            }
19354
0
#endif
19355
0
            break;
19356
0
    }
19357
19358
0
    return WOLFSSL_SUCCESS;
19359
0
}
19360
19361
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
19362
19363
#ifdef OPENSSL_EXTRA
19364
19365
/* returns the node at index "idx", NULL if not found */
19366
WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx)
19367
0
{
19368
0
    int i;
19369
0
    WOLFSSL_STACK* ret = NULL;
19370
0
    WOLFSSL_STACK* current;
19371
19372
0
    current = sk;
19373
0
    for (i = 0; i <= idx && current != NULL; i++) {
19374
0
        if (i == idx) {
19375
0
            ret = current;
19376
0
            break;
19377
0
        }
19378
0
        current = current->next;
19379
0
    }
19380
0
    return ret;
19381
0
}
19382
19383
19384
#endif /* OPENSSL_EXTRA */
19385
19386
#ifdef OPENSSL_EXTRA
19387
19388
#if defined(OPENSSL_ALL)
19389
19390
void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data)
19391
0
{
19392
0
    unsigned long hash;
19393
19394
0
    WOLFSSL_ENTER("wolfSSL_lh_retrieve");
19395
19396
0
    if (!sk || !data) {
19397
0
        WOLFSSL_MSG("Bad parameters");
19398
0
        return NULL;
19399
0
    }
19400
19401
0
    if (!sk->hash_fn) {
19402
0
        WOLFSSL_MSG("No hash function defined");
19403
0
        return NULL;
19404
0
    }
19405
19406
0
    hash = sk->hash_fn(data);
19407
19408
0
    while (sk) {
19409
        /* Calc hash if not done so yet */
19410
0
        if (!sk->hash) {
19411
0
            switch (sk->type) {
19412
0
                case STACK_TYPE_CIPHER:
19413
0
                    sk->hash = sk->hash_fn(&sk->data.cipher);
19414
0
                    break;
19415
0
                case STACK_TYPE_X509:
19416
0
                case STACK_TYPE_GEN_NAME:
19417
0
                case STACK_TYPE_BIO:
19418
0
                case STACK_TYPE_OBJ:
19419
0
                case STACK_TYPE_STRING:
19420
0
                case STACK_TYPE_ACCESS_DESCRIPTION:
19421
0
                case STACK_TYPE_X509_EXT:
19422
0
                case STACK_TYPE_X509_REQ_ATTR:
19423
0
                case STACK_TYPE_NULL:
19424
0
                case STACK_TYPE_X509_NAME:
19425
0
                case STACK_TYPE_X509_NAME_ENTRY:
19426
0
                case STACK_TYPE_CONF_VALUE:
19427
0
                case STACK_TYPE_X509_INFO:
19428
0
                case STACK_TYPE_BY_DIR_entry:
19429
0
                case STACK_TYPE_BY_DIR_hash:
19430
0
                case STACK_TYPE_X509_OBJ:
19431
0
                case STACK_TYPE_DIST_POINT:
19432
0
                case STACK_TYPE_X509_CRL:
19433
0
                default:
19434
0
                    sk->hash = sk->hash_fn(sk->data.generic);
19435
0
                    break;
19436
0
            }
19437
0
        }
19438
0
        if (sk->hash == hash) {
19439
0
            switch (sk->type) {
19440
0
                case STACK_TYPE_CIPHER:
19441
0
                    return &sk->data.cipher;
19442
0
                case STACK_TYPE_X509:
19443
0
                case STACK_TYPE_GEN_NAME:
19444
0
                case STACK_TYPE_BIO:
19445
0
                case STACK_TYPE_OBJ:
19446
0
                case STACK_TYPE_STRING:
19447
0
                case STACK_TYPE_ACCESS_DESCRIPTION:
19448
0
                case STACK_TYPE_X509_EXT:
19449
0
                case STACK_TYPE_X509_REQ_ATTR:
19450
0
                case STACK_TYPE_NULL:
19451
0
                case STACK_TYPE_X509_NAME:
19452
0
                case STACK_TYPE_X509_NAME_ENTRY:
19453
0
                case STACK_TYPE_CONF_VALUE:
19454
0
                case STACK_TYPE_X509_INFO:
19455
0
                case STACK_TYPE_BY_DIR_entry:
19456
0
                case STACK_TYPE_BY_DIR_hash:
19457
0
                case STACK_TYPE_X509_OBJ:
19458
0
                case STACK_TYPE_DIST_POINT:
19459
0
                case STACK_TYPE_X509_CRL:
19460
0
                default:
19461
0
                    return sk->data.generic;
19462
0
            }
19463
0
        }
19464
0
        sk = sk->next;
19465
0
    }
19466
19467
0
    return NULL;
19468
0
}
19469
19470
#endif /* OPENSSL_ALL */
19471
19472
#endif /* OPENSSL_EXTRA */
19473
19474
/* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
19475
   KEEP_OUR_CERT is to insure ability for returning ssl certificate */
19476
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
19477
    defined(KEEP_OUR_CERT)
19478
WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
19479
0
{
19480
0
    if (ssl == NULL) {
19481
0
        return NULL;
19482
0
    }
19483
19484
0
    if (ssl->buffers.weOwnCert) {
19485
0
        if (ssl->ourCert == NULL) {
19486
0
            if (ssl->buffers.certificate == NULL) {
19487
0
                WOLFSSL_MSG("Certificate buffer not set!");
19488
0
                return NULL;
19489
0
            }
19490
0
            #ifndef WOLFSSL_X509_STORE_CERTS
19491
0
            ssl->ourCert = wolfSSL_X509_d2i(NULL,
19492
0
                                              ssl->buffers.certificate->buffer,
19493
0
                                              ssl->buffers.certificate->length);
19494
0
            #endif
19495
0
        }
19496
0
        return ssl->ourCert;
19497
0
    }
19498
0
    else { /* if cert not owned get parent ctx cert or return null */
19499
0
        if (ssl->ctx) {
19500
0
            if (ssl->ctx->ourCert == NULL) {
19501
0
                if (ssl->ctx->certificate == NULL) {
19502
0
                    WOLFSSL_MSG("Ctx Certificate buffer not set!");
19503
0
                    return NULL;
19504
0
                }
19505
0
                #ifndef WOLFSSL_X509_STORE_CERTS
19506
0
                ssl->ctx->ourCert = wolfSSL_X509_d2i(NULL,
19507
0
                                               ssl->ctx->certificate->buffer,
19508
0
                                               ssl->ctx->certificate->length);
19509
0
                #endif
19510
0
                ssl->ctx->ownOurCert = 1;
19511
0
            }
19512
0
            return ssl->ctx->ourCert;
19513
0
        }
19514
0
    }
19515
19516
0
    return NULL;
19517
0
}
19518
19519
WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx)
19520
0
{
19521
0
    if (ctx) {
19522
0
        if (ctx->ourCert == NULL) {
19523
0
            if (ctx->certificate == NULL) {
19524
0
                WOLFSSL_MSG("Ctx Certificate buffer not set!");
19525
0
                return NULL;
19526
0
            }
19527
0
            #ifndef WOLFSSL_X509_STORE_CERTS
19528
0
            ctx->ourCert = wolfSSL_X509_d2i(NULL,
19529
0
                                           ctx->certificate->buffer,
19530
0
                                           ctx->certificate->length);
19531
0
            #endif
19532
0
            ctx->ownOurCert = 1;
19533
0
        }
19534
0
        return ctx->ourCert;
19535
0
    }
19536
0
    return NULL;
19537
0
}
19538
#endif /* OPENSSL_EXTRA && KEEP_OUR_CERT */
19539
#endif /* NO_CERTS */
19540
19541
19542
#if !defined(NO_ASN) && (defined(OPENSSL_EXTRA) || \
19543
        defined(OPENSSL_EXTRA_X509_SMALL))
19544
void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj)
19545
0
{
19546
0
    if (obj == NULL) {
19547
0
        return;
19548
0
    }
19549
0
    if ((obj->obj != NULL) && ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0)) {
19550
#ifdef WOLFSSL_DEBUG_OPENSSL
19551
        WOLFSSL_MSG("Freeing ASN1 data");
19552
#endif
19553
0
        XFREE((void*)obj->obj, obj->heap, DYNAMIC_TYPE_ASN1);
19554
0
        obj->obj = NULL;
19555
0
    }
19556
0
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
19557
0
    if (obj->pathlen != NULL) {
19558
0
        wolfSSL_ASN1_INTEGER_free(obj->pathlen);
19559
0
        obj->pathlen = NULL;
19560
0
    }
19561
0
    #endif
19562
0
    if ((obj->dynamic & WOLFSSL_ASN1_DYNAMIC) != 0) {
19563
#ifdef WOLFSSL_DEBUG_OPENSSL
19564
        WOLFSSL_MSG("Freeing ASN1 OBJECT");
19565
#endif
19566
0
        XFREE(obj, NULL, DYNAMIC_TYPE_ASN1);
19567
0
    }
19568
0
}
19569
19570
WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void)
19571
0
{
19572
0
    WOLFSSL_ASN1_OBJECT* obj;
19573
19574
0
    obj = (WOLFSSL_ASN1_OBJECT*)XMALLOC(sizeof(WOLFSSL_ASN1_OBJECT), NULL,
19575
0
                                        DYNAMIC_TYPE_ASN1);
19576
0
    if (obj == NULL) {
19577
0
        return NULL;
19578
0
    }
19579
19580
0
    XMEMSET(obj, 0, sizeof(WOLFSSL_ASN1_OBJECT));
19581
0
    obj->d.ia5 = &(obj->d.ia5_internal);
19582
0
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
19583
0
    obj->d.iPAddress = &(obj->d.iPAddress_internal);
19584
0
#endif
19585
0
    obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
19586
0
    return obj;
19587
0
}
19588
19589
WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_dup(WOLFSSL_ASN1_OBJECT* obj)
19590
0
{
19591
0
    WOLFSSL_ASN1_OBJECT* dupl = NULL;
19592
19593
0
    WOLFSSL_ENTER("wolfSSL_ASN1_OBJECT_dup");
19594
19595
0
    if (!obj) {
19596
0
        WOLFSSL_MSG("Bad parameter");
19597
0
        return NULL;
19598
0
    }
19599
0
    dupl = wolfSSL_ASN1_OBJECT_new();
19600
0
    if (!dupl) {
19601
0
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error");
19602
0
        return NULL;
19603
0
    }
19604
    /* Copy data */
19605
0
    XMEMCPY(dupl->sName, obj->sName, WOLFSSL_MAX_SNAME);
19606
0
    dupl->type = obj->type;
19607
0
    dupl->grp = obj->grp;
19608
0
    dupl->nid = obj->nid;
19609
0
    dupl->objSz = obj->objSz;
19610
0
    if (obj->obj) {
19611
0
        dupl->obj = (const unsigned char*)XMALLOC(
19612
0
                obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
19613
0
        if (!dupl->obj) {
19614
0
            WOLFSSL_MSG("ASN1 obj malloc error");
19615
0
            wolfSSL_ASN1_OBJECT_free(dupl);
19616
0
            return NULL;
19617
0
        }
19618
0
        XMEMCPY((byte*)dupl->obj, obj->obj, obj->objSz);
19619
0
        dupl->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
19620
0
    }
19621
0
    return dupl;
19622
0
}
19623
#endif /* !NO_ASN && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */
19624
19625
#ifndef NO_ASN
19626
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
19627
/* Creates and returns a new WOLFSSL_CIPHER stack. */
19628
WOLFSSL_STACK* wolfSSL_sk_new_asn1_obj(void)
19629
0
{
19630
0
    WOLFSSL_STACK* sk;
19631
0
    WOLFSSL_ENTER("wolfSSL_sk_new_asn1_obj");
19632
19633
0
    sk = wolfSSL_sk_new_null();
19634
0
    if (sk == NULL)
19635
0
        return NULL;
19636
0
    sk->type = STACK_TYPE_OBJ;
19637
19638
0
    return sk;
19639
0
}
19640
19641
/* return 1 on success 0 on fail */
19642
int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
19643
                                              WOLFSSL_ASN1_OBJECT* obj)
19644
0
{
19645
0
    WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_push");
19646
19647
0
    if (sk == NULL || obj == NULL) {
19648
0
        return WOLFSSL_FAILURE;
19649
0
    }
19650
19651
0
    return wolfSSL_sk_push(sk, obj);
19652
0
}
19653
19654
19655
WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop(
19656
                                        WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
19657
0
{
19658
0
    WOLFSSL_STACK* node;
19659
0
    WOLFSSL_ASN1_OBJECT* obj;
19660
19661
0
    if (sk == NULL) {
19662
0
        return NULL;
19663
0
    }
19664
19665
0
    node = sk->next;
19666
0
    obj = sk->data.obj;
19667
19668
0
    if (node != NULL) { /* update sk and remove node from stack */
19669
0
        sk->data.obj = node->data.obj;
19670
0
        sk->next = node->next;
19671
0
        XFREE(node, NULL, DYNAMIC_TYPE_ASN1);
19672
0
    }
19673
0
    else { /* last obj in stack */
19674
0
        sk->data.obj = NULL;
19675
0
    }
19676
19677
0
    if (sk->num > 0) {
19678
0
        sk->num -= 1;
19679
0
    }
19680
19681
0
    return obj;
19682
0
}
19683
19684
19685
/* Free the structure for ASN1_OBJECT stack
19686
 *
19687
 * sk  stack to free nodes in
19688
 */
19689
void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk)
19690
0
{
19691
0
    wolfSSL_sk_free(sk);
19692
0
}
19693
19694
/* Free's all nodes in ASN1_OBJECT stack.
19695
 * This is different then wolfSSL_ASN1_OBJECT_free in that it allows for
19696
 * choosing the function to use when freeing an ASN1_OBJECT stack.
19697
 *
19698
 * sk  stack to free nodes in
19699
 * f   X509 free function
19700
 */
19701
void wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
19702
                                     void (*f) (WOLFSSL_ASN1_OBJECT*))
19703
0
{
19704
0
    WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_pop_free");
19705
0
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
19706
0
}
19707
19708
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
19709
#endif /* !NO_ASN */
19710
19711
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
19712
#ifndef NO_ASN
19713
19714
int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in)
19715
0
{
19716
    /*
19717
       ASN1_STRING_to_UTF8() converts the string in to UTF8 format,
19718
       the converted data is allocated in a buffer in *out.
19719
       The length of out is returned or a negative error code.
19720
       The buffer *out should be free using OPENSSL_free().
19721
       */
19722
0
    unsigned char* buf;
19723
0
    unsigned char* inPtr;
19724
0
    int inLen;
19725
19726
0
    if (!out || !in) {
19727
0
        return -1;
19728
0
    }
19729
19730
0
    inPtr = wolfSSL_ASN1_STRING_data(in);
19731
0
    inLen = wolfSSL_ASN1_STRING_length(in);
19732
0
    if (!inPtr || inLen < 0) {
19733
0
        return -1;
19734
0
    }
19735
0
    buf = (unsigned char*)XMALLOC(inLen + 1, NULL, DYNAMIC_TYPE_OPENSSL);
19736
0
    if (!buf) {
19737
0
        return -1;
19738
0
    }
19739
0
    XMEMCPY(buf, inPtr, inLen + 1);
19740
0
    *out = buf;
19741
0
    return inLen;
19742
0
}
19743
#endif /* !NO_ASN */
19744
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
19745
19746
#if defined(OPENSSL_EXTRA)
19747
#ifndef NO_ASN
19748
19749
int wolfSSL_ASN1_UNIVERSALSTRING_to_string(WOLFSSL_ASN1_STRING *s)
19750
0
{
19751
0
    char *idx;
19752
0
    char *copy;
19753
0
    WOLFSSL_ENTER("wolfSSL_ASN1_UNIVERSALSTRING_to_string");
19754
19755
0
    if (!s) {
19756
0
        WOLFSSL_MSG("Bad parameter");
19757
0
        return WOLFSSL_FAILURE;
19758
0
    }
19759
19760
0
    if (s->type != V_ASN1_UNIVERSALSTRING) {
19761
0
        WOLFSSL_MSG("Input is not a universal string");
19762
0
        return WOLFSSL_FAILURE;
19763
0
    }
19764
19765
0
    if ((s->length % 4) != 0) {
19766
0
        WOLFSSL_MSG("Input string must be divisible by 4");
19767
0
        return WOLFSSL_FAILURE;
19768
0
    }
19769
19770
0
    for (idx = s->data; idx < s->data + s->length; idx += 4)
19771
0
        if ((idx[0] != '\0') || (idx[1] != '\0') || (idx[2] != '\0'))
19772
0
            break;
19773
19774
0
    if (idx != s->data + s->length) {
19775
0
        WOLFSSL_MSG("Wrong string format");
19776
0
        return WOLFSSL_FAILURE;
19777
0
    }
19778
19779
0
    for (copy = idx = s->data; idx < s->data + s->length; idx += 4)
19780
0
        *copy++ = idx[3];
19781
0
    *copy = '\0';
19782
0
    s->length /= 4;
19783
0
    s->type = V_ASN1_PRINTABLESTRING;
19784
0
    return WOLFSSL_SUCCESS;
19785
0
}
19786
19787
/* Returns string representation of ASN1_STRING */
19788
char* wolfSSL_i2s_ASN1_STRING(WOLFSSL_v3_ext_method *method,
19789
    const WOLFSSL_ASN1_STRING *s)
19790
0
{
19791
0
    int i;
19792
0
    int tmpSz = 100;
19793
0
    int valSz = 5;
19794
0
    char* tmp;
19795
0
    char val[5];
19796
0
    unsigned char* str;
19797
19798
0
    WOLFSSL_ENTER("wolfSSL_i2s_ASN1_STRING");
19799
0
    (void)method;
19800
19801
0
    if(s == NULL || s->data == NULL) {
19802
0
        WOLFSSL_MSG("Bad Function Argument");
19803
0
        return NULL;
19804
0
    }
19805
0
    str = (unsigned char*)XMALLOC(s->length, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19806
0
    if (str == NULL) {
19807
0
        WOLFSSL_MSG("Memory Error");
19808
0
        return NULL;
19809
0
    }
19810
0
    XMEMCPY(str, (unsigned char*)s->data, s->length);
19811
19812
0
    tmp = (char*)XMALLOC(tmpSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19813
0
    if (tmp == NULL) {
19814
0
        WOLFSSL_MSG("Memory Error");
19815
0
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19816
0
        return NULL;
19817
0
    }
19818
0
    XMEMSET(tmp, 0, tmpSz);
19819
19820
0
    for (i = 0; i < tmpSz && i < (s->length - 1); i++) {
19821
0
        if (XSNPRINTF(val, valSz, "%02X:", str[i])
19822
0
            >= valSz)
19823
0
        {
19824
0
            WOLFSSL_MSG("Buffer overrun");
19825
0
            XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19826
0
            return NULL;
19827
0
        }
19828
0
        XSTRNCAT(tmp, val, valSz);
19829
0
    }
19830
0
    if (XSNPRINTF(val, valSz, "%02X", str[i])
19831
0
        >= valSz)
19832
0
    {
19833
0
        WOLFSSL_MSG("Buffer overrun");
19834
0
        XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19835
0
        return NULL;
19836
0
    }
19837
19838
0
    XSTRNCAT(tmp, val, valSz);
19839
0
    XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER);
19840
19841
0
    return tmp;
19842
0
}
19843
#endif /* NO_ASN */
19844
#endif /* OPENSSL_EXTRA */
19845
19846
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
19847
void wolfSSL_set_connect_state(WOLFSSL* ssl)
19848
0
{
19849
0
    WOLFSSL_ENTER("wolfSSL_set_connect_state");
19850
0
    if (ssl == NULL) {
19851
0
        WOLFSSL_MSG("WOLFSSL struct pointer passed in was null");
19852
0
        return;
19853
0
    }
19854
19855
0
    #ifndef NO_DH
19856
    /* client creates its own DH parameters on handshake */
19857
0
    if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
19858
0
        XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap,
19859
0
            DYNAMIC_TYPE_PUBLIC_KEY);
19860
0
    }
19861
0
    ssl->buffers.serverDH_P.buffer = NULL;
19862
0
    if (ssl->buffers.serverDH_G.buffer && ssl->buffers.weOwnDH) {
19863
0
        XFREE(ssl->buffers.serverDH_G.buffer, ssl->heap,
19864
0
            DYNAMIC_TYPE_PUBLIC_KEY);
19865
0
    }
19866
0
    ssl->buffers.serverDH_G.buffer = NULL;
19867
0
    #endif
19868
19869
0
    if (InitSSL_Side(ssl, WOLFSSL_CLIENT_END) != WOLFSSL_SUCCESS) {
19870
0
        WOLFSSL_MSG("Error initializing client side");
19871
0
    }
19872
0
}
19873
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
19874
19875
19876
int wolfSSL_get_shutdown(const WOLFSSL* ssl)
19877
0
{
19878
0
    int isShutdown = 0;
19879
19880
0
    WOLFSSL_ENTER("wolfSSL_get_shutdown");
19881
19882
0
    if (ssl) {
19883
0
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
19884
0
        if (ssl->options.handShakeState == NULL_STATE) {
19885
            /* The SSL object was possibly cleared with wolfSSL_clear after
19886
             * a successful shutdown. Simulate a response for a full
19887
             * bidirectional shutdown. */
19888
0
            isShutdown = WOLFSSL_SENT_SHUTDOWN | WOLFSSL_RECEIVED_SHUTDOWN;
19889
0
        }
19890
0
        else
19891
0
#endif
19892
0
        {
19893
            /* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent   *
19894
             * WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
19895
0
            if (ssl->options.sentNotify)
19896
0
                isShutdown |= WOLFSSL_SENT_SHUTDOWN;
19897
0
            if (ssl->options.closeNotify||ssl->options.connReset)
19898
0
                isShutdown |= WOLFSSL_RECEIVED_SHUTDOWN;
19899
0
        }
19900
19901
0
    }
19902
0
    return isShutdown;
19903
0
}
19904
19905
19906
int wolfSSL_session_reused(WOLFSSL* ssl)
19907
0
{
19908
0
    int resuming = 0;
19909
0
    WOLFSSL_ENTER("wolfSSL_session_reused");
19910
0
    if (ssl)
19911
0
        resuming = ssl->options.resuming;
19912
0
    WOLFSSL_LEAVE("wolfSSL_session_reused", resuming);
19913
0
    return resuming;
19914
0
}
19915
19916
/* return a new malloc'd session with default settings on success */
19917
WOLFSSL_SESSION* wolfSSL_NewSession(void* heap)
19918
0
{
19919
0
    WOLFSSL_SESSION* ret = NULL;
19920
19921
0
    ret = (WOLFSSL_SESSION*)XMALLOC(sizeof(WOLFSSL_SESSION), heap,
19922
0
            DYNAMIC_TYPE_SESSION);
19923
0
    if (ret != NULL) {
19924
0
        XMEMSET(ret, 0, sizeof(WOLFSSL_SESSION));
19925
0
    #ifndef SINGLE_THREADED
19926
0
        if (wc_InitMutex(&ret->refMutex) != 0) {
19927
0
            WOLFSSL_MSG("Error setting up session reference mutex");
19928
0
            XFREE(ret, ret->heap, DYNAMIC_TYPE_SESSION);
19929
0
            return NULL;
19930
0
        }
19931
0
    #endif
19932
0
        ret->refCount = 1;
19933
0
#ifndef NO_SESSION_CACHE
19934
0
        ret->cacheRow = INVALID_SESSION_ROW; /* not in cache */
19935
0
#endif
19936
0
        ret->type = WOLFSSL_SESSION_TYPE_HEAP;
19937
0
        ret->heap = heap;
19938
#ifdef WOLFSSL_CHECK_MEM_ZERO
19939
        wc_MemZero_Add("SESSION master secret", ret->masterSecret, SECRET_LEN);
19940
        wc_MemZero_Add("SESSION id", ret->sessionID, ID_LEN);
19941
#endif
19942
0
    #ifdef HAVE_SESSION_TICKET
19943
0
        ret->ticket = ret->staticTicket;
19944
0
    #endif
19945
#ifdef HAVE_STUNNEL
19946
        /* stunnel has this funny mechanism of storing the "is_authenticated"
19947
         * session info in the session ex data. This is basically their
19948
         * default so let's just hard code it. */
19949
        if (wolfSSL_SESSION_set_ex_data(ret, 0, (void *)(-1))
19950
                != WOLFSSL_SUCCESS) {
19951
            WOLFSSL_MSG("Error setting up ex data for stunnel");
19952
            XFREE(ret, NULL, DYNAMIC_TYPE_SESSION);
19953
            return NULL;
19954
        }
19955
#endif
19956
#ifdef HAVE_EX_DATA
19957
        ret->ownExData = 1;
19958
#endif
19959
0
    }
19960
0
    return ret;
19961
0
}
19962
19963
19964
WOLFSSL_SESSION* wolfSSL_SESSION_new_ex(void* heap)
19965
0
{
19966
0
    return wolfSSL_NewSession(heap);
19967
0
}
19968
19969
WOLFSSL_SESSION* wolfSSL_SESSION_new(void)
19970
0
{
19971
0
    return wolfSSL_SESSION_new_ex(NULL);
19972
0
}
19973
19974
/* add one to session reference count
19975
 * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error */
19976
int wolfSSL_SESSION_up_ref(WOLFSSL_SESSION* session)
19977
0
{
19978
0
    session = ClientSessionToSession(session);
19979
19980
0
    if (session == NULL || session->type != WOLFSSL_SESSION_TYPE_HEAP)
19981
0
        return WOLFSSL_FAILURE;
19982
19983
0
#ifndef SINGLE_THREADED
19984
0
    if (wc_LockMutex(&session->refMutex) != 0) {
19985
0
        WOLFSSL_MSG("Failed to lock session mutex");
19986
0
        return WOLFSSL_FAILURE;
19987
0
    }
19988
0
#endif
19989
0
    session->refCount++;
19990
0
#ifndef SINGLE_THREADED
19991
0
    wc_UnLockMutex(&session->refMutex);
19992
0
#endif
19993
0
    return WOLFSSL_SUCCESS;
19994
0
}
19995
19996
/**
19997
 * Deep copy the contents from input to output.
19998
 * @param input         The source of the copy.
19999
 * @param output        The destination of the copy.
20000
 * @param avoidSysCalls If true, then system calls will be avoided or an error
20001
 *                      will be returned if it is not possible to proceed
20002
 *                      without a system call. This is useful for fetching
20003
 *                      sessions from cache. When a cache row is locked, we
20004
 *                      don't want to block other threads with long running
20005
 *                      system calls.
20006
 * @return              WOLFSSL_SUCCESS on success
20007
 *                      WOLFSSL_FAILURE on failure
20008
 */
20009
int wolfSSL_DupSession(const WOLFSSL_SESSION* input, WOLFSSL_SESSION* output,
20010
        int avoidSysCalls)
20011
0
{
20012
0
#ifdef HAVE_SESSION_TICKET
20013
0
    int   ticLenAlloc = 0;
20014
0
    byte *ticBuff = NULL;
20015
0
#endif
20016
0
    const size_t copyOffset = OFFSETOF(WOLFSSL_SESSION, heap) + sizeof(input->heap);
20017
0
    int ret = WOLFSSL_SUCCESS;
20018
20019
0
    (void)avoidSysCalls;
20020
20021
0
    input = ClientSessionToSession(input);
20022
0
    output = ClientSessionToSession(output);
20023
20024
0
    if (input == NULL || output == NULL || input == output) {
20025
0
        WOLFSSL_MSG("input or output are null or same");
20026
0
        return WOLFSSL_FAILURE;
20027
0
    }
20028
20029
0
#ifdef HAVE_SESSION_TICKET
20030
0
    if (output->ticket != output->staticTicket) {
20031
0
        ticBuff = output->ticket;
20032
0
        ticLenAlloc = output->ticketLenAlloc;
20033
0
    }
20034
0
#endif
20035
20036
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
20037
    if (output->peer != NULL) {
20038
        if (avoidSysCalls) {
20039
            WOLFSSL_MSG("Can't free cert when avoiding syscalls");
20040
            return WOLFSSL_FAILURE;
20041
        }
20042
        wolfSSL_X509_free(output->peer);
20043
        output->peer = NULL;
20044
    }
20045
#endif
20046
20047
0
    XMEMCPY((byte*)output + copyOffset, (byte*)input + copyOffset,
20048
0
            sizeof(WOLFSSL_SESSION) - copyOffset);
20049
20050
    /* Set sane values for copy */
20051
0
#ifndef NO_SESSION_CACHE
20052
0
    if (output->type != WOLFSSL_SESSION_TYPE_CACHE)
20053
0
        output->cacheRow = INVALID_SESSION_ROW;
20054
0
#endif
20055
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
20056
    if (input->peer != NULL && input->peer->dynamicMemory) {
20057
        if (wolfSSL_X509_up_ref(input->peer) != WOLFSSL_SUCCESS) {
20058
            WOLFSSL_MSG("Can't increase peer cert ref count");
20059
            output->peer = NULL;
20060
        }
20061
    }
20062
    else if (!avoidSysCalls)
20063
        output->peer = wolfSSL_X509_dup(input->peer);
20064
    else
20065
        /* output->peer is not that important to copy */
20066
        output->peer = NULL;
20067
#endif
20068
0
#ifdef HAVE_SESSION_TICKET
20069
0
    if (input->ticketLen > SESSION_TICKET_LEN) {
20070
        /* Need dynamic buffer */
20071
0
        if (ticBuff == NULL || ticLenAlloc < input->ticketLen) {
20072
            /* allocate new one */
20073
0
            byte* tmp;
20074
0
            if (avoidSysCalls) {
20075
0
                WOLFSSL_MSG("Failed to allocate memory for ticket when avoiding"
20076
0
                        " syscalls");
20077
0
                output->ticket = ticBuff;
20078
0
                output->ticketLenAlloc = (word16) ticLenAlloc;
20079
0
                output->ticketLen = 0;
20080
0
                ret = WOLFSSL_FAILURE;
20081
0
            }
20082
0
            else {
20083
0
                tmp = (byte*)XREALLOC(ticBuff, input->ticketLen,
20084
0
                        output->heap, DYNAMIC_TYPE_SESSION_TICK);
20085
0
                if (tmp == NULL) {
20086
0
                    WOLFSSL_MSG("Failed to allocate memory for ticket");
20087
0
                    XFREE(ticBuff, output->heap, DYNAMIC_TYPE_SESSION_TICK);
20088
0
                    output->ticket = NULL;
20089
0
                    output->ticketLen = 0;
20090
0
                    output->ticketLenAlloc = 0;
20091
0
                    ret = WOLFSSL_FAILURE;
20092
0
                }
20093
0
                else {
20094
0
                    ticBuff = tmp;
20095
0
                    ticLenAlloc = input->ticketLen;
20096
0
                }
20097
0
            }
20098
0
        }
20099
0
        if (ticBuff != NULL && ret == WOLFSSL_SUCCESS) {
20100
0
            XMEMCPY(ticBuff, input->ticket, input->ticketLen);
20101
0
            output->ticket = ticBuff;
20102
0
            output->ticketLenAlloc = (word16) ticLenAlloc;
20103
0
        }
20104
0
    }
20105
0
    else {
20106
        /* Default ticket to non dynamic */
20107
0
        if (avoidSysCalls) {
20108
            /* Try to use ticBuf if available. Caller can later move it to
20109
             * the static buffer. */
20110
0
            if (ticBuff != NULL) {
20111
0
                if (ticLenAlloc >= input->ticketLen) {
20112
0
                    output->ticket = output->staticTicket;
20113
0
                    output->ticketLenAlloc = 0;
20114
0
                }
20115
0
                else {
20116
0
                    WOLFSSL_MSG("ticket dynamic buffer too small but we are "
20117
0
                                "avoiding system calls");
20118
0
                    ret = WOLFSSL_FAILURE;
20119
0
                    output->ticket = ticBuff;
20120
0
                    output->ticketLenAlloc = (word16) ticLenAlloc;
20121
0
                    output->ticketLen = 0;
20122
0
                }
20123
0
            }
20124
0
            else {
20125
0
                output->ticket = output->staticTicket;
20126
0
                output->ticketLenAlloc = 0;
20127
0
            }
20128
0
        }
20129
0
        else {
20130
0
            if (ticBuff != NULL)
20131
0
                XFREE(ticBuff, output->heap, DYNAMIC_TYPE_SESSION_TICK);
20132
0
            output->ticket = output->staticTicket;
20133
0
            output->ticketLenAlloc = 0;
20134
0
        }
20135
0
        if (input->ticketLenAlloc > 0 && ret == WOLFSSL_SUCCESS) {
20136
            /* Shouldn't happen as session should have placed this in
20137
             * the static buffer */
20138
0
            XMEMCPY(output->ticket, input->ticket,
20139
0
                    input->ticketLen);
20140
0
        }
20141
0
    }
20142
0
    ticBuff = NULL;
20143
0
#endif /* HAVE_SESSION_TICKET */
20144
0
    return ret;
20145
0
}
20146
20147
WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session)
20148
0
{
20149
0
#ifdef HAVE_EXT_CACHE
20150
0
    WOLFSSL_SESSION* copy;
20151
20152
0
    WOLFSSL_ENTER("wolfSSL_SESSION_dup");
20153
20154
0
    session = ClientSessionToSession(session);
20155
0
    if (session == NULL)
20156
0
        return NULL;
20157
20158
0
#ifdef HAVE_SESSION_TICKET
20159
0
    if (session->ticketLenAlloc > 0 && !session->ticket) {
20160
0
        WOLFSSL_MSG("Session dynamic flag is set but ticket pointer is null");
20161
0
        return NULL;
20162
0
    }
20163
0
#endif
20164
20165
0
    copy = wolfSSL_NewSession(session->heap);
20166
0
    if (copy != NULL &&
20167
0
            wolfSSL_DupSession(session, copy, 0) != WOLFSSL_SUCCESS) {
20168
0
        wolfSSL_FreeSession(NULL, copy);
20169
0
        copy = NULL;
20170
0
    }
20171
0
    return copy;
20172
#else
20173
    WOLFSSL_MSG("wolfSSL_SESSION_dup feature not compiled in");
20174
    (void)session;
20175
    return NULL;
20176
#endif /* HAVE_EXT_CACHE */
20177
0
}
20178
20179
void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
20180
0
{
20181
0
    session = ClientSessionToSession(session);
20182
0
    if (session == NULL)
20183
0
        return;
20184
20185
0
    (void)ctx;
20186
20187
    /* refCount will always be 1 or more if created externally.
20188
     * Internal cache sessions don't initialize a refMutex. */
20189
0
    if (session->refCount > 0) {
20190
0
#ifndef SINGLE_THREADED
20191
0
        if (wc_LockMutex(&session->refMutex) != 0) {
20192
0
            WOLFSSL_MSG("Failed to lock session mutex");
20193
0
            return;
20194
0
        }
20195
0
#endif
20196
0
        if (session->refCount > 1) {
20197
0
            session->refCount--;
20198
0
#ifndef SINGLE_THREADED
20199
0
            wc_UnLockMutex(&session->refMutex);
20200
0
#endif
20201
0
            return;
20202
0
        }
20203
0
#ifndef SINGLE_THREADED
20204
0
        wc_UnLockMutex(&session->refMutex);
20205
0
        wc_FreeMutex(&session->refMutex);
20206
0
#endif
20207
0
    }
20208
20209
0
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
20210
0
    if (ctx != NULL && ctx->rem_sess_cb
20211
#ifdef HAVE_EX_DATA
20212
            && session->ownExData /* This will be true if we are not using the
20213
                                   * internal cache so it will get called for
20214
                                   * externally cached sessions as well. */
20215
#endif
20216
0
    ) {
20217
0
        ctx->rem_sess_cb(ctx, session);
20218
0
    }
20219
0
#endif
20220
20221
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
20222
    wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
20223
#endif
20224
20225
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
20226
    if (session->peer) {
20227
        wolfSSL_X509_free(session->peer);
20228
        session->peer = NULL;
20229
    }
20230
#endif
20231
20232
0
#ifdef HAVE_SESSION_TICKET
20233
0
    if (session->ticketLenAlloc > 0) {
20234
0
        XFREE(session->ticket, session->heap, DYNAMIC_TYPE_SESSION_TICK);
20235
0
    }
20236
0
#endif
20237
20238
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
20239
    wolfSSL_CRYPTO_cleanup_ex_data(&session->ex_data);
20240
#endif
20241
20242
    /* Make sure masterSecret is zeroed. */
20243
0
    ForceZero(session->masterSecret, SECRET_LEN);
20244
    /* Session ID is sensitive information too. */
20245
0
    ForceZero(session->sessionID, ID_LEN);
20246
20247
0
    if (session->type == WOLFSSL_SESSION_TYPE_HEAP) {
20248
0
        XFREE(session, session->heap, DYNAMIC_TYPE_SESSION);
20249
0
    }
20250
0
}
20251
20252
void wolfSSL_SESSION_free(WOLFSSL_SESSION* session)
20253
0
{
20254
0
    session = ClientSessionToSession(session);
20255
0
    wolfSSL_FreeSession(NULL, session);
20256
0
}
20257
20258
#ifndef NO_SESSION_CACHE
20259
int wolfSSL_CTX_add_session(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session)
20260
0
{
20261
0
    int    error = 0;
20262
0
    const byte* id = NULL;
20263
0
    byte idSz = 0;
20264
20265
0
    WOLFSSL_ENTER("wolfSSL_CTX_add_session");
20266
20267
0
    session = ClientSessionToSession(session);
20268
0
    if (session == NULL)
20269
0
        return WOLFSSL_FAILURE;
20270
20271
    /* Session cache is global */
20272
0
    (void)ctx;
20273
20274
0
    id = session->sessionID;
20275
0
    idSz = session->sessionIDSz;
20276
0
    if (session->haveAltSessionID) {
20277
0
        id = session->altSessionID;
20278
0
        idSz = ID_LEN;
20279
0
    }
20280
20281
0
    error = AddSessionToCache(ctx, session, id, idSz,
20282
0
            NULL, session->side,
20283
0
#ifdef HAVE_SESSION_TICKET
20284
0
            session->ticketLen > 0,
20285
#else
20286
            0,
20287
#endif
20288
0
            NULL);
20289
20290
0
    return error == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
20291
0
}
20292
#endif
20293
20294
#if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE)
20295
20296
/**
20297
* set cipher to WOLFSSL_SESSION from WOLFSSL_CIPHER
20298
* @param session  a pointer to WOLFSSL_SESSION structure
20299
* @param cipher   a function pointer to WOLFSSL_CIPHER
20300
* @return WOLFSSL_SUCCESS on success, otherwise WOLFSSL_FAILURE
20301
*/
20302
int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session,
20303
                                            const WOLFSSL_CIPHER* cipher)
20304
0
{
20305
0
    WOLFSSL_ENTER("wolfSSL_SESSION_set_cipher");
20306
20307
0
    session = ClientSessionToSession(session);
20308
    /* sanity check */
20309
0
    if (session == NULL || cipher == NULL) {
20310
0
        WOLFSSL_MSG("bad argument");
20311
0
        return WOLFSSL_FAILURE;
20312
0
    }
20313
0
    session->cipherSuite0 = cipher->cipherSuite0;
20314
0
    session->cipherSuite  = cipher->cipherSuite;
20315
20316
0
    WOLFSSL_LEAVE("wolfSSL_SESSION_set_cipher", WOLFSSL_SUCCESS);
20317
0
    return WOLFSSL_SUCCESS;
20318
0
}
20319
#endif /* OPENSSL_EXTRA || HAVE_EXT_CACHE */
20320
20321
20322
/* helper function that takes in a protocol version struct and returns string */
20323
static const char* wolfSSL_internal_get_version(const ProtocolVersion* version)
20324
0
{
20325
0
    WOLFSSL_ENTER("wolfSSL_get_version");
20326
20327
0
    if (version == NULL) {
20328
0
        return "Bad arg";
20329
0
    }
20330
20331
0
    if (version->major == SSLv3_MAJOR) {
20332
0
        switch (version->minor) {
20333
0
            case SSLv3_MINOR :
20334
0
                return "SSLv3";
20335
0
            case TLSv1_MINOR :
20336
0
                return "TLSv1";
20337
0
            case TLSv1_1_MINOR :
20338
0
                return "TLSv1.1";
20339
0
            case TLSv1_2_MINOR :
20340
0
                return "TLSv1.2";
20341
0
            case TLSv1_3_MINOR :
20342
0
                return "TLSv1.3";
20343
0
            default:
20344
0
                return "unknown";
20345
0
        }
20346
0
    }
20347
#ifdef WOLFSSL_DTLS
20348
    else if (version->major == DTLS_MAJOR) {
20349
        switch (version->minor) {
20350
            case DTLS_MINOR :
20351
                return "DTLS";
20352
            case DTLSv1_2_MINOR :
20353
                return "DTLSv1.2";
20354
            case DTLSv1_3_MINOR :
20355
                return "DTLSv1.3";
20356
            default:
20357
                return "unknown";
20358
        }
20359
    }
20360
#endif /* WOLFSSL_DTLS */
20361
0
    return "unknown";
20362
0
}
20363
20364
20365
const char* wolfSSL_get_version(const WOLFSSL* ssl)
20366
0
{
20367
0
    if (ssl == NULL) {
20368
0
        WOLFSSL_MSG("Bad argument");
20369
0
        return "unknown";
20370
0
    }
20371
20372
0
    return wolfSSL_internal_get_version(&ssl->version);
20373
0
}
20374
20375
20376
/* current library version */
20377
const char* wolfSSL_lib_version(void)
20378
0
{
20379
0
    return LIBWOLFSSL_VERSION_STRING;
20380
0
}
20381
20382
#ifdef OPENSSL_EXTRA
20383
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
20384
const char* wolfSSL_OpenSSL_version(int a)
20385
{
20386
    (void)a;
20387
    return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
20388
}
20389
#else
20390
const char* wolfSSL_OpenSSL_version(void)
20391
0
{
20392
0
    return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
20393
0
}
20394
#endif /* WOLFSSL_QT */
20395
#endif
20396
20397
20398
/* current library version in hex */
20399
word32 wolfSSL_lib_version_hex(void)
20400
0
{
20401
0
    return LIBWOLFSSL_VERSION_HEX;
20402
0
}
20403
20404
20405
int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl)
20406
0
{
20407
0
    WOLFSSL_ENTER("SSL_get_current_cipher_suite");
20408
0
    if (ssl)
20409
0
        return (ssl->options.cipherSuite0 << 8) | ssl->options.cipherSuite;
20410
0
    return 0;
20411
0
}
20412
20413
WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
20414
0
{
20415
0
    WOLFSSL_ENTER("SSL_get_current_cipher");
20416
0
    if (ssl) {
20417
0
        ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
20418
0
        ssl->cipher.cipherSuite  = ssl->options.cipherSuite;
20419
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
20420
0
        ssl->cipher.bits = ssl->specs.key_size * 8;
20421
0
#endif
20422
0
        return &ssl->cipher;
20423
0
    }
20424
0
    else
20425
0
        return NULL;
20426
0
}
20427
20428
20429
const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher)
20430
0
{
20431
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_name");
20432
20433
0
    if (cipher == NULL) {
20434
0
        return NULL;
20435
0
    }
20436
20437
0
    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS) && \
20438
0
        !defined(WOLFSSL_QT)
20439
0
        return GetCipherNameIana(cipher->cipherSuite0, cipher->cipherSuite);
20440
    #else
20441
        return wolfSSL_get_cipher_name_from_suite(cipher->cipherSuite0,
20442
                cipher->cipherSuite);
20443
    #endif
20444
0
}
20445
20446
const char*  wolfSSL_CIPHER_get_version(const WOLFSSL_CIPHER* cipher)
20447
0
{
20448
0
    WOLFSSL_ENTER("SSL_CIPHER_get_version");
20449
20450
0
    if (cipher == NULL || cipher->ssl == NULL) {
20451
0
        return NULL;
20452
0
    }
20453
20454
0
    return wolfSSL_get_version(cipher->ssl);
20455
0
}
20456
20457
const char* wolfSSL_SESSION_CIPHER_get_name(const WOLFSSL_SESSION* session)
20458
0
{
20459
0
    session = ClientSessionToSession(session);
20460
0
    if (session == NULL) {
20461
0
        return NULL;
20462
0
    }
20463
20464
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
20465
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
20466
0
    #if !defined(WOLFSSL_CIPHER_INTERNALNAME) && !defined(NO_ERROR_STRINGS)
20467
0
        return GetCipherNameIana(session->cipherSuite0, session->cipherSuite);
20468
    #else
20469
        return GetCipherNameInternal(session->cipherSuite0, session->cipherSuite);
20470
    #endif
20471
#else
20472
    return NULL;
20473
#endif
20474
0
}
20475
20476
const char* wolfSSL_get_cipher(WOLFSSL* ssl)
20477
0
{
20478
0
    WOLFSSL_ENTER("wolfSSL_get_cipher");
20479
0
    return wolfSSL_CIPHER_get_name(wolfSSL_get_current_cipher(ssl));
20480
0
}
20481
20482
/* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */
20483
const char* wolfSSL_get_cipher_name(WOLFSSL* ssl)
20484
0
{
20485
    /* get access to cipher_name_idx in internal.c */
20486
0
    return wolfSSL_get_cipher_name_internal(ssl);
20487
0
}
20488
20489
const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0,
20490
    const byte cipherSuite)
20491
0
{
20492
0
    return GetCipherNameInternal(cipherSuite0, cipherSuite);
20493
0
}
20494
20495
const char* wolfSSL_get_cipher_name_iana_from_suite(const byte cipherSuite0,
20496
        const byte cipherSuite)
20497
0
{
20498
0
    return GetCipherNameIana(cipherSuite0, cipherSuite);
20499
0
}
20500
20501
int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0,
20502
0
                                       byte* cipherSuite, int *flags) {
20503
0
    if ((name == NULL) ||
20504
0
        (cipherSuite0 == NULL) ||
20505
0
        (cipherSuite == NULL) ||
20506
0
        (flags == NULL))
20507
0
        return BAD_FUNC_ARG;
20508
0
    return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, flags);
20509
0
}
20510
20511
20512
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
20513
/* Creates and returns a new WOLFSSL_CIPHER stack. */
20514
WOLFSSL_STACK* wolfSSL_sk_new_cipher(void)
20515
0
{
20516
0
    WOLFSSL_STACK* sk;
20517
0
    WOLFSSL_ENTER("wolfSSL_sk_new_cipher");
20518
20519
0
    sk = wolfSSL_sk_new_null();
20520
0
    if (sk == NULL)
20521
0
        return NULL;
20522
0
    sk->type = STACK_TYPE_CIPHER;
20523
20524
0
    return sk;
20525
0
}
20526
20527
/* return 1 on success 0 on fail */
20528
int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk,
20529
                                                      WOLFSSL_CIPHER* cipher)
20530
0
{
20531
0
    return wolfSSL_sk_push(sk, cipher);
20532
0
}
20533
20534
#ifndef NO_WOLFSSL_STUB
20535
WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
20536
0
{
20537
0
    WOLFSSL_STUB("wolfSSL_sk_CIPHER_pop");
20538
0
    (void)sk;
20539
0
    return NULL;
20540
0
}
20541
#endif /* NO_WOLFSSL_STUB */
20542
#endif /* WOLFSSL_QT || OPENSSL_ALL */
20543
20544
word32 wolfSSL_CIPHER_get_id(const WOLFSSL_CIPHER* cipher)
20545
0
{
20546
0
    word16 cipher_id = 0;
20547
20548
0
    WOLFSSL_ENTER("SSL_CIPHER_get_id");
20549
20550
0
    if (cipher && cipher->ssl) {
20551
0
        cipher_id = (cipher->ssl->options.cipherSuite0 << 8) |
20552
0
                     cipher->ssl->options.cipherSuite;
20553
0
    }
20554
20555
0
    return cipher_id;
20556
0
}
20557
20558
const WOLFSSL_CIPHER* wolfSSL_get_cipher_by_value(word16 value)
20559
0
{
20560
0
    const WOLFSSL_CIPHER* cipher = NULL;
20561
0
    byte cipherSuite0, cipherSuite;
20562
0
    WOLFSSL_ENTER("SSL_get_cipher_by_value");
20563
20564
    /* extract cipher id information */
20565
0
    cipherSuite =   (value       & 0xFF);
20566
0
    cipherSuite0 = ((value >> 8) & 0xFF);
20567
20568
    /* TODO: lookup by cipherSuite0 / cipherSuite */
20569
0
    (void)cipherSuite0;
20570
0
    (void)cipherSuite;
20571
20572
0
    return cipher;
20573
0
}
20574
20575
20576
#if defined(OPENSSL_EXTRA)
20577
/* Free the structure for WOLFSSL_CIPHER stack
20578
 *
20579
 * sk  stack to free nodes in
20580
 */
20581
void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
20582
0
{
20583
0
    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free");
20584
20585
0
    wolfSSL_sk_free(sk);
20586
0
}
20587
#endif /* OPENSSL_ALL */
20588
20589
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
20590
                                                                 !defined(NO_DH)
20591
#ifdef HAVE_FFDHE
20592
static const char* wolfssl_ffdhe_name(word16 group)
20593
0
{
20594
0
    const char* str = NULL;
20595
0
    switch (group) {
20596
0
        case WOLFSSL_FFDHE_2048:
20597
0
            str = "FFDHE_2048";
20598
0
            break;
20599
0
        case WOLFSSL_FFDHE_3072:
20600
0
            str = "FFDHE_3072";
20601
0
            break;
20602
0
        case WOLFSSL_FFDHE_4096:
20603
0
            str = "FFDHE_4096";
20604
0
            break;
20605
0
        case WOLFSSL_FFDHE_6144:
20606
0
            str = "FFDHE_6144";
20607
0
            break;
20608
0
        case WOLFSSL_FFDHE_8192:
20609
0
            str = "FFDHE_8192";
20610
0
            break;
20611
0
        default:
20612
0
            break;
20613
0
    }
20614
0
    return str;
20615
0
}
20616
#endif
20617
/* Return the name of the curve used for key exchange as a printable string.
20618
 *
20619
 * ssl  The SSL/TLS object.
20620
 * returns NULL if ECDH was not used, otherwise the name as a string.
20621
 */
20622
const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
20623
0
{
20624
0
    const char* cName = NULL;
20625
20626
0
    if (ssl == NULL)
20627
0
        return NULL;
20628
20629
#if defined(WOLFSSL_TLS13) && defined(HAVE_PQC)
20630
    /* Check for post-quantum groups. Return now because we do not want the ECC
20631
     * check to override this result in the case of a hybrid. */
20632
    if (IsAtLeastTLSv1_3(ssl->version)) {
20633
        switch (ssl->namedGroup) {
20634
#ifdef HAVE_LIBOQS
20635
        case WOLFSSL_KYBER_LEVEL1:
20636
            return "KYBER_LEVEL1";
20637
        case WOLFSSL_KYBER_LEVEL3:
20638
            return "KYBER_LEVEL3";
20639
        case WOLFSSL_KYBER_LEVEL5:
20640
            return "KYBER_LEVEL5";
20641
        case WOLFSSL_NTRU_HPS_LEVEL1:
20642
            return "NTRU_HPS_LEVEL1";
20643
        case WOLFSSL_NTRU_HPS_LEVEL3:
20644
            return "NTRU_HPS_LEVEL3";
20645
        case WOLFSSL_NTRU_HPS_LEVEL5:
20646
            return "NTRU_HPS_LEVEL5";
20647
        case WOLFSSL_NTRU_HRSS_LEVEL3:
20648
            return "NTRU_HRSS_LEVEL3";
20649
        case WOLFSSL_SABER_LEVEL1:
20650
            return "SABER_LEVEL1";
20651
        case WOLFSSL_SABER_LEVEL3:
20652
            return "SABER_LEVEL3";
20653
        case WOLFSSL_SABER_LEVEL5:
20654
            return "SABER_LEVEL5";
20655
        case WOLFSSL_KYBER_90S_LEVEL1:
20656
            return "KYBER_90S_LEVEL1";
20657
        case WOLFSSL_KYBER_90S_LEVEL3:
20658
            return "KYBER_90S_LEVEL3";
20659
        case WOLFSSL_KYBER_90S_LEVEL5:
20660
            return "KYBER_90S_LEVEL5";
20661
        case WOLFSSL_P256_NTRU_HPS_LEVEL1:
20662
            return "P256_NTRU_HPS_LEVEL1";
20663
        case WOLFSSL_P384_NTRU_HPS_LEVEL3:
20664
            return "P384_NTRU_HPS_LEVEL3";
20665
        case WOLFSSL_P521_NTRU_HPS_LEVEL5:
20666
            return "P521_NTRU_HPS_LEVEL5";
20667
        case WOLFSSL_P384_NTRU_HRSS_LEVEL3:
20668
            return "P384_NTRU_HRSS_LEVEL3";
20669
        case WOLFSSL_P256_SABER_LEVEL1:
20670
            return "P256_SABER_LEVEL1";
20671
        case WOLFSSL_P384_SABER_LEVEL3:
20672
            return "P384_SABER_LEVEL3";
20673
        case WOLFSSL_P521_SABER_LEVEL5:
20674
            return "P521_SABER_LEVEL5";
20675
        case WOLFSSL_P256_KYBER_LEVEL1:
20676
            return "P256_KYBER_LEVEL1";
20677
        case WOLFSSL_P384_KYBER_LEVEL3:
20678
            return "P384_KYBER_LEVEL3";
20679
        case WOLFSSL_P521_KYBER_LEVEL5:
20680
            return "P521_KYBER_LEVEL5";
20681
        case WOLFSSL_P256_KYBER_90S_LEVEL1:
20682
            return "P256_KYBER_90S_LEVEL1";
20683
        case WOLFSSL_P384_KYBER_90S_LEVEL3:
20684
            return "P384_KYBER_90S_LEVEL3";
20685
        case WOLFSSL_P521_KYBER_90S_LEVEL5:
20686
            return "P521_KYBER_90S_LEVEL5";
20687
#elif defined(HAVE_PQM4)
20688
        case WOLFSSL_KYBER_LEVEL1:
20689
            return "KYBER_LEVEL1";
20690
#endif
20691
        }
20692
    }
20693
20694
#endif /* WOLFSSL_TLS13 && HAVE_PQC */
20695
0
#ifdef HAVE_FFDHE
20696
0
    if (ssl->namedGroup != 0) {
20697
0
        cName = wolfssl_ffdhe_name(ssl->namedGroup);
20698
0
    }
20699
0
#endif
20700
20701
0
#ifdef HAVE_CURVE25519
20702
0
    if (ssl->ecdhCurveOID == ECC_X25519_OID && cName == NULL) {
20703
0
        cName = "X25519";
20704
0
    }
20705
0
#endif
20706
20707
0
#ifdef HAVE_CURVE448
20708
0
    if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
20709
0
        cName = "X448";
20710
0
    }
20711
0
#endif
20712
20713
0
#ifdef HAVE_ECC
20714
0
    if (ssl->ecdhCurveOID != 0 && cName == NULL) {
20715
0
        cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
20716
0
                                NULL));
20717
0
    }
20718
0
#endif
20719
20720
0
    return cName;
20721
0
}
20722
#endif
20723
20724
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
20725
    defined(OPENSSL_EXTRA_X509_SMALL)
20726
20727
    /* Creates a new WOLFSSL_ASN1_STRING structure.
20728
     *
20729
     * returns a pointer to the new structure created on success or NULL if fail
20730
     */
20731
    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new(void)
20732
0
    {
20733
0
        WOLFSSL_ASN1_STRING* asn1;
20734
20735
#ifdef WOLFSSL_DEBUG_OPENSSL
20736
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_new");
20737
#endif
20738
20739
0
        asn1 = (WOLFSSL_ASN1_STRING*)XMALLOC(sizeof(WOLFSSL_ASN1_STRING), NULL,
20740
0
                DYNAMIC_TYPE_OPENSSL);
20741
0
        if (asn1 != NULL) {
20742
0
            XMEMSET(asn1, 0, sizeof(WOLFSSL_ASN1_STRING));
20743
0
        }
20744
20745
0
        return asn1; /* no check for null because error case is returning null*/
20746
0
    }
20747
20748
    /**
20749
     * Used to duplicate a passed in WOLFSSL_ASN1_STRING*
20750
     * @param asn1 WOLFSSL_ASN1_STRING* to be duplicated
20751
     * @return WOLFSSL_ASN1_STRING* the duplicate struct or NULL on error
20752
     */
20753
    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_dup(WOLFSSL_ASN1_STRING* asn1)
20754
0
    {
20755
0
        WOLFSSL_ASN1_STRING* dupl = NULL;
20756
20757
0
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_dup");
20758
0
        if (!asn1) {
20759
0
            WOLFSSL_MSG("Bad parameter");
20760
0
            return NULL;
20761
0
        }
20762
20763
0
        dupl = wolfSSL_ASN1_STRING_new();
20764
0
        if (!dupl) {
20765
0
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_new error");
20766
0
            return NULL;
20767
0
        }
20768
20769
0
        dupl->type = asn1->type;
20770
0
        dupl->flags = asn1->flags;
20771
20772
0
        if (wolfSSL_ASN1_STRING_set(dupl, asn1->data, asn1->length)
20773
0
                != WOLFSSL_SUCCESS) {
20774
0
            WOLFSSL_MSG("wolfSSL_ASN1_STRING_set error");
20775
0
            wolfSSL_ASN1_STRING_free(dupl);
20776
0
            return NULL;
20777
0
        }
20778
20779
0
        return dupl;
20780
0
    }
20781
20782
20783
    /* used to free a WOLFSSL_ASN1_STRING structure */
20784
    void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1)
20785
0
    {
20786
#ifdef WOLFSSL_DEBUG_OPENSSL
20787
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_free");
20788
#endif
20789
20790
0
        if (asn1 != NULL) {
20791
0
            if (asn1->length > 0 && asn1->data != NULL && asn1->isDynamic) {
20792
0
                XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
20793
0
            }
20794
0
            XFREE(asn1, NULL, DYNAMIC_TYPE_OPENSSL);
20795
0
        }
20796
0
    }
20797
20798
    int wolfSSL_ASN1_STRING_cmp(const WOLFSSL_ASN1_STRING *a, const WOLFSSL_ASN1_STRING *b)
20799
0
    {
20800
0
        int i;
20801
0
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_cmp");
20802
20803
0
        if (!a || !b) {
20804
0
            return WOLFSSL_FATAL_ERROR;
20805
0
        }
20806
20807
0
        if (a->length != b->length) {
20808
0
            return a->length - b->length;
20809
0
        }
20810
20811
0
        if ((i = XMEMCMP(a->data, b->data, a->length)) != 0) {
20812
0
            return i;
20813
0
        }
20814
20815
0
        return a->type - b->type;
20816
0
    }
20817
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
20818
20819
#if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \
20820
    defined(OPENSSL_EXTRA_X509_SMALL))
20821
20822
    int wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING* dest,
20823
                            const WOLFSSL_ASN1_STRING* src)
20824
0
    {
20825
0
        if (src == NULL || dest == NULL) {
20826
0
            return WOLFSSL_FAILURE;
20827
0
        }
20828
0
        dest->type = src->type;
20829
0
        if(wolfSSL_ASN1_STRING_set(dest, src->data, src->length)
20830
0
                    != WOLFSSL_SUCCESS) {
20831
0
                return WOLFSSL_FAILURE;
20832
0
        }
20833
0
        dest->flags = src->flags;
20834
20835
0
        return WOLFSSL_SUCCESS;
20836
0
    }
20837
    /* Creates a new WOLFSSL_ASN1_STRING structure given the input type.
20838
     *
20839
     * type is the type of set when WOLFSSL_ASN1_STRING is created
20840
     *
20841
     * returns a pointer to the new structure created on success or NULL if fail
20842
     */
20843
    WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type)
20844
0
    {
20845
0
        WOLFSSL_ASN1_STRING* asn1;
20846
20847
#ifdef WOLFSSL_DEBUG_OPENSSL
20848
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type_new");
20849
#endif
20850
20851
0
        asn1 = wolfSSL_ASN1_STRING_new();
20852
0
        if (asn1 == NULL) {
20853
0
            return NULL;
20854
0
        }
20855
0
        asn1->type = type;
20856
20857
0
        return asn1;
20858
0
    }
20859
20860
20861
/******************************************************************************
20862
* wolfSSL_ASN1_STRING_type - returns the type of <asn1>
20863
*
20864
* RETURNS:
20865
* returns the type set for <asn1>. Otherwise, returns WOLFSSL_FAILURE.
20866
*/
20867
    int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1)
20868
0
    {
20869
20870
#ifdef WOLFSSL_DEBUG_OPENSSL
20871
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type");
20872
#endif
20873
20874
0
        if (asn1 == NULL) {
20875
0
            return WOLFSSL_FAILURE;
20876
0
        }
20877
20878
0
        return asn1->type;
20879
0
    }
20880
20881
#endif /* !NO_CERTS && OPENSSL_EXTRA */
20882
20883
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
20884
    defined(OPENSSL_EXTRA_X509_SMALL)
20885
    /* if dataSz is negative then use XSTRLEN to find length of data
20886
     * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
20887
    /* `data` can be NULL and only buffer will be allocated */
20888
    int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data,
20889
            int dataSz)
20890
0
    {
20891
0
        int sz;
20892
20893
#ifdef WOLFSSL_DEBUG_OPENSSL
20894
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_set");
20895
#endif
20896
20897
0
        if (asn1 == NULL || (data == NULL && dataSz < 0)) {
20898
0
            return WOLFSSL_FAILURE;
20899
0
        }
20900
20901
0
        if (dataSz < 0) {
20902
0
            sz = (int)XSTRLEN((const char*)data);
20903
0
        }
20904
0
        else {
20905
0
            sz = dataSz;
20906
0
        }
20907
20908
0
        if (sz < 0) {
20909
0
            return WOLFSSL_FAILURE;
20910
0
        }
20911
20912
        /* free any existing data before copying */
20913
0
        if (asn1->data != NULL && asn1->isDynamic) {
20914
0
            XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
20915
0
            asn1->data = NULL;
20916
0
        }
20917
20918
0
        if (sz + 1 > CTC_NAME_SIZE) { /* account for null char */
20919
            /* create new data buffer and copy over */
20920
0
            asn1->data = (char*)XMALLOC(sz + 1, NULL, DYNAMIC_TYPE_OPENSSL);
20921
0
            if (asn1->data == NULL) {
20922
0
                return WOLFSSL_FAILURE;
20923
0
            }
20924
0
            asn1->isDynamic = 1;
20925
0
        }
20926
0
        else {
20927
0
            XMEMSET(asn1->strData, 0, CTC_NAME_SIZE);
20928
0
            asn1->data = asn1->strData;
20929
0
            asn1->isDynamic = 0;
20930
0
        }
20931
0
        if (data != NULL) {
20932
0
            XMEMCPY(asn1->data, data, sz);
20933
0
            asn1->data[sz] = '\0';
20934
0
        }
20935
0
        asn1->length = sz;
20936
20937
0
        return WOLFSSL_SUCCESS;
20938
0
    }
20939
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
20940
20941
#ifndef NO_CERTS
20942
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
20943
    const unsigned char* wolfSSL_ASN1_STRING_get0_data(
20944
                                            const WOLFSSL_ASN1_STRING* asn)
20945
0
    {
20946
0
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_get0_data");
20947
20948
0
        if (asn) {
20949
0
            return (const unsigned char*)asn->data;
20950
0
        } else {
20951
0
            return NULL;
20952
0
        }
20953
0
    }
20954
    unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn)
20955
0
    {
20956
#ifdef WOLFSSL_DEBUG_OPENSSL
20957
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_data");
20958
#endif
20959
20960
0
        if (asn) {
20961
0
            return (unsigned char*)asn->data;
20962
0
        }
20963
0
        else {
20964
0
            return NULL;
20965
0
        }
20966
0
    }
20967
20968
20969
    int wolfSSL_ASN1_STRING_length(WOLFSSL_ASN1_STRING* asn)
20970
0
    {
20971
#ifdef WOLFSSL_DEBUG_OPENSSL
20972
        WOLFSSL_ENTER("wolfSSL_ASN1_STRING_length");
20973
#endif
20974
20975
0
        if (asn) {
20976
0
            return asn->length;
20977
0
        }
20978
0
        else {
20979
0
            return 0;
20980
0
        }
20981
0
    }
20982
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
20983
20984
#ifdef OPENSSL_EXTRA
20985
#ifndef NO_WOLFSSL_STUB
20986
    WOLFSSL_ASN1_STRING* wolfSSL_d2i_DISPLAYTEXT(WOLFSSL_ASN1_STRING **asn,
20987
                                             const unsigned char **in, long len)
20988
0
    {
20989
0
        WOLFSSL_STUB("d2i_DISPLAYTEXT");
20990
0
        (void)asn;
20991
0
        (void)in;
20992
0
        (void)len;
20993
0
        return NULL;
20994
0
    }
20995
#endif
20996
20997
#endif /* OPENSSL_EXTRA */
20998
20999
#endif /* !NO_CERTS */
21000
21001
#ifdef OPENSSL_EXTRA
21002
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21003
/* return authentication NID corresponding to cipher suite
21004
 * @param cipher a pointer to WOLFSSL_CIPHER
21005
 * return NID if found, NID_undef if not found
21006
 */
21007
int wolfSSL_CIPHER_get_auth_nid(const WOLFSSL_CIPHER* cipher)
21008
0
{
21009
0
    static const struct authnid {
21010
0
        const char* alg_name;
21011
0
        const int  nid;
21012
0
    } authnid_tbl[] = {
21013
0
        {"RSA",     NID_auth_rsa},
21014
0
        {"PSK",     NID_auth_psk},
21015
0
        {"SRP",     NID_auth_srp},
21016
0
        {"ECDSA",   NID_auth_ecdsa},
21017
0
        {"None",    NID_auth_null},
21018
0
        {NULL,      NID_undef}
21019
0
    };
21020
21021
0
    const struct authnid* sa;
21022
0
    const char* authStr;
21023
0
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21024
21025
0
    if (GetCipherSegment(cipher, n) == NULL) {
21026
0
        WOLFSSL_MSG("no suitable cipher name found");
21027
0
        return NID_undef;
21028
0
    }
21029
21030
0
    authStr = GetCipherAuthStr(n);
21031
21032
0
    if (authStr != NULL) {
21033
0
        for(sa = authnid_tbl; sa->alg_name != NULL; sa++) {
21034
0
            if (XSTRCMP(sa->alg_name, authStr) == 0) {
21035
0
                return sa->nid;
21036
0
            }
21037
0
        }
21038
0
    }
21039
21040
0
    return NID_undef;
21041
0
}
21042
/* return cipher NID corresponding to cipher suite
21043
 * @param cipher a pointer to WOLFSSL_CIPHER
21044
 * return NID if found, NID_undef if not found
21045
 */
21046
int wolfSSL_CIPHER_get_cipher_nid(const WOLFSSL_CIPHER* cipher)
21047
0
{
21048
0
    static const struct ciphernid {
21049
0
        const char* alg_name;
21050
0
        const int  nid;
21051
0
    } ciphernid_tbl[] = {
21052
0
        {"AESGCM(256)",             NID_aes_256_gcm},
21053
0
        {"AESGCM(128)",             NID_aes_128_gcm},
21054
0
        {"AESCCM(128)",             NID_aes_128_ccm},
21055
0
        {"AES(128)",                NID_aes_128_cbc},
21056
0
        {"AES(256)",                NID_aes_256_cbc},
21057
0
        {"CAMELLIA(256)",           NID_camellia_256_cbc},
21058
0
        {"CAMELLIA(128)",           NID_camellia_128_cbc},
21059
0
        {"RC4",                     NID_rc4},
21060
0
        {"3DES",                    NID_des_ede3_cbc},
21061
0
        {"CHACHA20/POLY1305(256)",  NID_chacha20_poly1305},
21062
0
        {"None",                    NID_undef},
21063
0
        {NULL,                      NID_undef}
21064
0
    };
21065
21066
0
    const struct ciphernid* c;
21067
0
    const char* encStr;
21068
0
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21069
21070
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_cipher_nid");
21071
21072
0
    if (GetCipherSegment(cipher, n) == NULL) {
21073
0
        WOLFSSL_MSG("no suitable cipher name found");
21074
0
        return NID_undef;
21075
0
    }
21076
21077
0
    encStr = GetCipherEncStr(n);
21078
21079
0
    if (encStr != NULL) {
21080
0
        for(c = ciphernid_tbl; c->alg_name != NULL; c++) {
21081
0
            if (XSTRCMP(c->alg_name, encStr) == 0) {
21082
0
                return c->nid;
21083
0
            }
21084
0
        }
21085
0
    }
21086
21087
0
    return NID_undef;
21088
0
}
21089
/* return digest NID corresponding to cipher suite
21090
 * @param cipher a pointer to WOLFSSL_CIPHER
21091
 * return NID if found, NID_undef if not found
21092
 */
21093
int wolfSSL_CIPHER_get_digest_nid(const WOLFSSL_CIPHER* cipher)
21094
0
{
21095
0
    static const struct macnid {
21096
0
        const char* alg_name;
21097
0
        const int  nid;
21098
0
    } macnid_tbl[] = {
21099
0
        {"SHA1",    NID_sha1},
21100
0
        {"SHA256",  NID_sha256},
21101
0
        {"SHA384",  NID_sha384},
21102
0
        {NULL,      NID_undef}
21103
0
    };
21104
21105
0
    const struct macnid* mc;
21106
0
    const char* name;
21107
0
    const char* macStr;
21108
0
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21109
0
    (void)name;
21110
21111
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_digest_nid");
21112
21113
0
    if ((name = GetCipherSegment(cipher, n)) == NULL) {
21114
0
        WOLFSSL_MSG("no suitable cipher name found");
21115
0
        return NID_undef;
21116
0
    }
21117
21118
    /* in MD5 case, NID will be NID_md5 */
21119
0
    if (XSTRSTR(name, "MD5") != NULL) {
21120
0
        return NID_md5;
21121
0
    }
21122
21123
0
    macStr = GetCipherMacStr(n);
21124
21125
0
    if (macStr != NULL) {
21126
0
        for(mc = macnid_tbl; mc->alg_name != NULL; mc++) {
21127
0
            if (XSTRCMP(mc->alg_name, macStr) == 0) {
21128
0
                return mc->nid;
21129
0
            }
21130
0
        }
21131
0
    }
21132
21133
0
    return NID_undef;
21134
0
}
21135
/* return key exchange NID corresponding to cipher suite
21136
 * @param cipher a pointer to WOLFSSL_CIPHER
21137
 * return NID if found, NID_undef if not found
21138
 */
21139
int wolfSSL_CIPHER_get_kx_nid(const WOLFSSL_CIPHER* cipher)
21140
0
{
21141
0
    static const struct kxnid {
21142
0
        const char* name;
21143
0
        const int  nid;
21144
0
    } kxnid_table[] = {
21145
0
        {"ECDHEPSK",  NID_kx_ecdhe_psk},
21146
0
        {"ECDH",      NID_kx_ecdhe},
21147
0
        {"DHEPSK",    NID_kx_dhe_psk},
21148
0
        {"DH",        NID_kx_dhe},
21149
0
        {"RSAPSK",    NID_kx_rsa_psk},
21150
0
        {"SRP",       NID_kx_srp},
21151
0
        {"EDH",       NID_kx_dhe},
21152
0
        {"RSA",       NID_kx_rsa},
21153
0
        {NULL,        NID_undef}
21154
0
    };
21155
21156
0
    const struct kxnid* k;
21157
0
    const char* keaStr;
21158
0
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21159
21160
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_kx_nid");
21161
21162
0
    if (GetCipherSegment(cipher, n) == NULL) {
21163
0
        WOLFSSL_MSG("no suitable cipher name found");
21164
0
        return NID_undef;
21165
0
    }
21166
21167
    /* in TLS 1.3 case, NID will be NID_kx_any */
21168
0
    if (XSTRCMP(n[0], "TLS13") == 0) {
21169
0
        return NID_kx_any;
21170
0
    }
21171
21172
0
    keaStr = GetCipherKeaStr(n);
21173
21174
0
    if (keaStr != NULL) {
21175
0
        for(k = kxnid_table; k->name != NULL; k++) {
21176
0
            if (XSTRCMP(k->name, keaStr) == 0) {
21177
0
                return k->nid;
21178
0
            }
21179
0
        }
21180
0
    }
21181
21182
0
    return NID_undef;
21183
0
}
21184
/* check if cipher suite is AEAD
21185
 * @param cipher a pointer to WOLFSSL_CIPHER
21186
 * return 1 if cipher is AEAD, 0 otherwise
21187
 */
21188
int wolfSSL_CIPHER_is_aead(const WOLFSSL_CIPHER* cipher)
21189
0
{
21190
0
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21191
21192
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_is_aead");
21193
21194
0
    if (GetCipherSegment(cipher, n) == NULL) {
21195
0
        WOLFSSL_MSG("no suitable cipher name found");
21196
0
        return NID_undef;
21197
0
    }
21198
21199
0
    return IsCipherAEAD(n);
21200
0
}
21201
/* Creates cipher->description based on cipher->offset
21202
 * cipher->offset is set in wolfSSL_get_ciphers_compat when it is added
21203
 * to a stack of ciphers.
21204
 * @param [in] cipher: A cipher from a stack of ciphers.
21205
 * return WOLFSSL_SUCCESS if cipher->description is set, else WOLFSSL_FAILURE
21206
 */
21207
int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher)
21208
0
{
21209
0
    int strLen;
21210
0
    unsigned long offset;
21211
0
    char* dp;
21212
0
    const char* name;
21213
0
    const char *keaStr, *authStr, *encStr, *macStr, *protocol;
21214
0
    char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}};
21215
0
    int len = MAX_DESCRIPTION_SZ-1;
21216
0
    const CipherSuiteInfo* cipher_names;
21217
0
    ProtocolVersion pv;
21218
0
    WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description");
21219
21220
0
    if (cipher == NULL)
21221
0
        return WOLFSSL_FAILURE;
21222
21223
0
    dp = cipher->description;
21224
0
    if (dp == NULL)
21225
0
        return WOLFSSL_FAILURE;
21226
21227
0
    cipher_names = GetCipherNames();
21228
21229
0
    offset = cipher->offset;
21230
0
    if (offset >= (unsigned long)GetCipherNamesSize())
21231
0
        return WOLFSSL_FAILURE;
21232
0
    pv.major = cipher_names[offset].major;
21233
0
    pv.minor = cipher_names[offset].minor;
21234
0
    protocol = wolfSSL_internal_get_version(&pv);
21235
21236
0
    if ((name = GetCipherSegment(cipher, n)) == NULL) {
21237
0
        WOLFSSL_MSG("no suitable cipher name found");
21238
0
        return WOLFSSL_FAILURE;
21239
0
    }
21240
21241
    /* keaStr */
21242
0
    keaStr = GetCipherKeaStr(n);
21243
    /* authStr */
21244
0
    authStr = GetCipherAuthStr(n);
21245
    /* encStr */
21246
0
    encStr = GetCipherEncStr(n);
21247
0
    if ((cipher->bits = SetCipherBits(encStr)) == WOLFSSL_FAILURE) {
21248
0
       WOLFSSL_MSG("Cipher Bits Not Set.");
21249
0
    }
21250
    /* macStr */
21251
0
    macStr = GetCipherMacStr(n);
21252
21253
21254
    /* Build up the string by copying onto the end. */
21255
0
    XSTRNCPY(dp, name, len);
21256
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21257
0
    len -= strLen; dp += strLen;
21258
21259
0
    XSTRNCPY(dp, " ", len);
21260
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21261
0
    len -= strLen; dp += strLen;
21262
0
    XSTRNCPY(dp, protocol, len);
21263
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21264
0
    len -= strLen; dp += strLen;
21265
21266
0
    XSTRNCPY(dp, " Kx=", len);
21267
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21268
0
    len -= strLen; dp += strLen;
21269
0
    XSTRNCPY(dp, keaStr, len);
21270
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21271
0
    len -= strLen; dp += strLen;
21272
21273
0
    XSTRNCPY(dp, " Au=", len);
21274
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21275
0
    len -= strLen; dp += strLen;
21276
0
    XSTRNCPY(dp, authStr, len);
21277
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21278
0
    len -= strLen; dp += strLen;
21279
21280
0
    XSTRNCPY(dp, " Enc=", len);
21281
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21282
0
    len -= strLen; dp += strLen;
21283
0
    XSTRNCPY(dp, encStr, len);
21284
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21285
0
    len -= strLen; dp += strLen;
21286
21287
0
    XSTRNCPY(dp, " Mac=", len);
21288
0
    dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp);
21289
0
    len -= strLen; dp += strLen;
21290
0
    XSTRNCPY(dp, macStr, len);
21291
0
    dp[len-1] = '\0';
21292
21293
0
    return WOLFSSL_SUCCESS;
21294
0
}
21295
#endif /* OPENSSL_ALL || WOLFSSL_QT */
21296
21297
static WC_INLINE const char* wolfssl_kea_to_string(int kea)
21298
0
{
21299
0
    const char* keaStr;
21300
21301
0
    switch (kea) {
21302
0
        case no_kea:
21303
0
            keaStr = "None";
21304
0
            break;
21305
0
#ifndef NO_RSA
21306
0
        case rsa_kea:
21307
0
            keaStr = "RSA";
21308
0
            break;
21309
0
#endif
21310
0
#ifndef NO_DH
21311
0
        case diffie_hellman_kea:
21312
0
            keaStr = "DHE";
21313
0
            break;
21314
0
#endif
21315
0
        case fortezza_kea:
21316
0
            keaStr = "FZ";
21317
0
            break;
21318
#ifndef NO_PSK
21319
        case psk_kea:
21320
            keaStr = "PSK";
21321
            break;
21322
    #ifndef NO_DH
21323
        case dhe_psk_kea:
21324
            keaStr = "DHEPSK";
21325
            break;
21326
    #endif
21327
    #ifdef HAVE_ECC
21328
        case ecdhe_psk_kea:
21329
            keaStr = "ECDHEPSK";
21330
            break;
21331
    #endif
21332
#endif
21333
0
#ifdef HAVE_ECC
21334
0
        case ecc_diffie_hellman_kea:
21335
0
            keaStr = "ECDHE";
21336
0
            break;
21337
0
        case ecc_static_diffie_hellman_kea:
21338
0
            keaStr = "ECDH";
21339
0
            break;
21340
0
#endif
21341
0
        default:
21342
0
            keaStr = "unknown";
21343
0
            break;
21344
0
    }
21345
21346
0
    return keaStr;
21347
0
}
21348
21349
static WC_INLINE const char* wolfssl_sigalg_to_string(int sig_algo)
21350
0
{
21351
0
    const char* authStr;
21352
21353
0
    switch (sig_algo) {
21354
0
        case anonymous_sa_algo:
21355
0
            authStr = "None";
21356
0
            break;
21357
0
#ifndef NO_RSA
21358
0
        case rsa_sa_algo:
21359
0
            authStr = "RSA";
21360
0
            break;
21361
0
    #ifdef WC_RSA_PSS
21362
0
        case rsa_pss_sa_algo:
21363
0
            authStr = "RSA-PSS";
21364
0
            break;
21365
0
    #endif
21366
0
#endif
21367
#ifndef NO_DSA
21368
        case dsa_sa_algo:
21369
            authStr = "DSA";
21370
            break;
21371
#endif
21372
0
#ifdef HAVE_ECC
21373
0
        case ecc_dsa_sa_algo:
21374
0
            authStr = "ECDSA";
21375
0
            break;
21376
0
#endif
21377
0
#ifdef HAVE_ED25519
21378
0
        case ed25519_sa_algo:
21379
0
            authStr = "Ed25519";
21380
0
            break;
21381
0
#endif
21382
0
#ifdef HAVE_ED448
21383
0
        case ed448_sa_algo:
21384
0
            authStr = "Ed448";
21385
0
            break;
21386
0
#endif
21387
0
        default:
21388
0
            authStr = "unknown";
21389
0
            break;
21390
0
    }
21391
21392
0
    return authStr;
21393
0
}
21394
21395
static WC_INLINE const char* wolfssl_cipher_to_string(int cipher, int key_size)
21396
0
{
21397
0
    const char* encStr;
21398
21399
0
    (void)key_size;
21400
21401
0
    switch (cipher) {
21402
0
        case wolfssl_cipher_null:
21403
0
            encStr = "None";
21404
0
            break;
21405
0
#ifndef NO_RC4
21406
0
        case wolfssl_rc4:
21407
0
            encStr = "RC4(128)";
21408
0
            break;
21409
0
#endif
21410
0
#ifndef NO_DES3
21411
0
        case wolfssl_triple_des:
21412
0
            encStr = "3DES(168)";
21413
0
            break;
21414
0
#endif
21415
0
#ifndef NO_AES
21416
0
        case wolfssl_aes:
21417
0
            if (key_size == 128)
21418
0
                encStr = "AES(128)";
21419
0
            else if (key_size == 256)
21420
0
                encStr = "AES(256)";
21421
0
            else
21422
0
                encStr = "AES(?)";
21423
0
            break;
21424
0
    #ifdef HAVE_AESGCM
21425
0
        case wolfssl_aes_gcm:
21426
0
            if (key_size == 128)
21427
0
                encStr = "AESGCM(128)";
21428
0
            else if (key_size == 256)
21429
0
                encStr = "AESGCM(256)";
21430
0
            else
21431
0
                encStr = "AESGCM(?)";
21432
0
            break;
21433
0
    #endif
21434
0
    #ifdef HAVE_AESCCM
21435
0
        case wolfssl_aes_ccm:
21436
0
            if (key_size == 128)
21437
0
                encStr = "AESCCM(128)";
21438
0
            else if (key_size == 256)
21439
0
                encStr = "AESCCM(256)";
21440
0
            else
21441
0
                encStr = "AESCCM(?)";
21442
0
            break;
21443
0
    #endif
21444
0
#endif
21445
0
#ifdef HAVE_CHACHA
21446
0
        case wolfssl_chacha:
21447
0
            encStr = "CHACHA20/POLY1305(256)";
21448
0
            break;
21449
0
#endif
21450
0
#ifdef HAVE_CAMELLIA
21451
0
        case wolfssl_camellia:
21452
0
            if (key_size == 128)
21453
0
                encStr = "Camellia(128)";
21454
0
            else if (key_size == 256)
21455
0
                encStr = "Camellia(256)";
21456
0
            else
21457
0
                encStr = "Camellia(?)";
21458
0
            break;
21459
0
#endif
21460
0
        default:
21461
0
            encStr = "unknown";
21462
0
            break;
21463
0
    }
21464
21465
0
    return encStr;
21466
0
}
21467
21468
static WC_INLINE const char* wolfssl_mac_to_string(int mac)
21469
0
{
21470
0
    const char* macStr;
21471
21472
0
    switch (mac) {
21473
0
        case no_mac:
21474
0
            macStr = "None";
21475
0
            break;
21476
0
#ifndef NO_MD5
21477
0
        case md5_mac:
21478
0
            macStr = "MD5";
21479
0
            break;
21480
0
#endif
21481
0
#ifndef NO_SHA
21482
0
        case sha_mac:
21483
0
            macStr = "SHA1";
21484
0
            break;
21485
0
#endif
21486
#ifdef HAVE_SHA224
21487
        case sha224_mac:
21488
            macStr = "SHA224";
21489
            break;
21490
#endif
21491
0
#ifndef NO_SHA256
21492
0
        case sha256_mac:
21493
0
            macStr = "SHA256";
21494
0
            break;
21495
0
#endif
21496
#ifdef HAVE_SHA384
21497
        case sha384_mac:
21498
            macStr = "SHA384";
21499
            break;
21500
#endif
21501
#ifdef HAVE_SHA512
21502
        case sha512_mac:
21503
            macStr = "SHA512";
21504
            break;
21505
#endif
21506
0
        default:
21507
0
            macStr = "unknown";
21508
0
            break;
21509
0
    }
21510
21511
0
    return macStr;
21512
0
}
21513
21514
char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
21515
                                 int len)
21516
0
{
21517
0
    char *ret = in;
21518
0
    const char *keaStr, *authStr, *encStr, *macStr;
21519
0
    size_t strLen;
21520
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_description");
21521
21522
0
    if (cipher == NULL || in == NULL)
21523
0
        return NULL;
21524
21525
0
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
21526
    /* if cipher is in the stack from wolfSSL_get_ciphers_compat then
21527
     * Return the description based on cipher_names[cipher->offset]
21528
     */
21529
0
    if (cipher->in_stack == TRUE) {
21530
0
        wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher);
21531
0
        XSTRNCPY(in,cipher->description,len);
21532
0
        return ret;
21533
0
    }
21534
0
#endif
21535
21536
    /* Get the cipher description based on the SSL session cipher */
21537
0
    keaStr = wolfssl_kea_to_string(cipher->ssl->specs.kea);
21538
0
    authStr = wolfssl_sigalg_to_string(cipher->ssl->specs.sig_algo);
21539
0
    encStr = wolfssl_cipher_to_string(cipher->ssl->specs.bulk_cipher_algorithm,
21540
0
                                      cipher->ssl->specs.key_size);
21541
0
    macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm);
21542
21543
    /* Build up the string by copying onto the end. */
21544
0
    XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len);
21545
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21546
21547
0
    XSTRNCPY(in, " ", len);
21548
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21549
0
    XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len);
21550
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21551
21552
0
    XSTRNCPY(in, " Kx=", len);
21553
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21554
0
    XSTRNCPY(in, keaStr, len);
21555
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21556
21557
0
    XSTRNCPY(in, " Au=", len);
21558
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21559
0
    XSTRNCPY(in, authStr, len);
21560
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21561
21562
0
    XSTRNCPY(in, " Enc=", len);
21563
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21564
0
    XSTRNCPY(in, encStr, len);
21565
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21566
21567
0
    XSTRNCPY(in, " Mac=", len);
21568
0
    in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen;
21569
0
    XSTRNCPY(in, macStr, len);
21570
0
    in[len-1] = '\0';
21571
21572
0
    return ret;
21573
0
}
21574
21575
21576
#ifndef NO_WOLFSSL_STUB
21577
int wolfSSL_OCSP_parse_url(char* url, char** host, char** port, char** path,
21578
                   int* ssl)
21579
0
{
21580
0
    (void)url;
21581
0
    (void)host;
21582
0
    (void)port;
21583
0
    (void)path;
21584
0
    (void)ssl;
21585
0
    WOLFSSL_STUB("OCSP_parse_url");
21586
0
    return 0;
21587
0
}
21588
#endif
21589
21590
#ifndef NO_MD4
21591
21592
void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX* md4)
21593
83
{
21594
    /* make sure we have a big enough buffer */
21595
83
    typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
21596
83
    (void) sizeof(ok);
21597
21598
83
    WOLFSSL_ENTER("MD4_Init");
21599
83
    wc_InitMd4((Md4*)md4);
21600
83
}
21601
21602
21603
void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX* md4, const void* data,
21604
                       unsigned long len)
21605
2.39k
{
21606
2.39k
    WOLFSSL_ENTER("MD4_Update");
21607
2.39k
    wc_Md4Update((Md4*)md4, (const byte*)data, (word32)len);
21608
2.39k
}
21609
21610
21611
void wolfSSL_MD4_Final(unsigned char* digest, WOLFSSL_MD4_CTX* md4)
21612
83
{
21613
83
    WOLFSSL_ENTER("MD4_Final");
21614
83
    wc_Md4Final((Md4*)md4, digest);
21615
83
}
21616
21617
#endif /* NO_MD4 */
21618
21619
#ifndef NO_WOLFSSL_STUB
21620
void wolfSSL_RAND_screen(void)
21621
0
{
21622
0
    WOLFSSL_STUB("RAND_screen");
21623
0
}
21624
#endif
21625
21626
21627
21628
int wolfSSL_RAND_load_file(const char* fname, long len)
21629
0
{
21630
0
    (void)fname;
21631
    /* wolfCrypt provides enough entropy internally or will report error */
21632
0
    if (len == -1)
21633
0
        return 1024;
21634
0
    else
21635
0
        return (int)len;
21636
0
}
21637
21638
21639
#ifndef NO_WOLFSSL_STUB
21640
WOLFSSL_COMP_METHOD* wolfSSL_COMP_zlib(void)
21641
0
{
21642
0
    WOLFSSL_STUB("COMP_zlib");
21643
0
    return 0;
21644
0
}
21645
#endif
21646
21647
#ifndef NO_WOLFSSL_STUB
21648
WOLFSSL_COMP_METHOD* wolfSSL_COMP_rle(void)
21649
0
{
21650
0
    WOLFSSL_STUB("COMP_rle");
21651
0
    return 0;
21652
0
}
21653
#endif
21654
21655
#ifndef NO_WOLFSSL_STUB
21656
int wolfSSL_COMP_add_compression_method(int method, void* data)
21657
0
{
21658
0
    (void)method;
21659
0
    (void)data;
21660
0
    WOLFSSL_STUB("COMP_add_compression_method");
21661
0
    return 0;
21662
0
}
21663
#endif
21664
21665
/*  wolfSSL_set_dynlock_create_callback
21666
 *  CRYPTO_set_dynlock_create_callback has been deprecated since openSSL 1.0.1.
21667
 *  This function exists for compatibility purposes because wolfSSL satisfies
21668
 *  thread safety without relying on the callback.
21669
 */
21670
void wolfSSL_set_dynlock_create_callback(WOLFSSL_dynlock_value* (*f)(
21671
                                                          const char*, int))
21672
0
{
21673
0
    WOLFSSL_STUB("CRYPTO_set_dynlock_create_callback");
21674
0
    (void)f;
21675
0
}
21676
/*  wolfSSL_set_dynlock_lock_callback
21677
 *  CRYPTO_set_dynlock_lock_callback has been deprecated since openSSL 1.0.1.
21678
 *  This function exists for compatibility purposes because wolfSSL satisfies
21679
 *  thread safety without relying on the callback.
21680
 */
21681
void wolfSSL_set_dynlock_lock_callback(
21682
             void (*f)(int, WOLFSSL_dynlock_value*, const char*, int))
21683
0
{
21684
0
    WOLFSSL_STUB("CRYPTO_set_set_dynlock_lock_callback");
21685
0
    (void)f;
21686
0
}
21687
/*  wolfSSL_set_dynlock_destroy_callback
21688
 *  CRYPTO_set_dynlock_destroy_callback has been deprecated since openSSL 1.0.1.
21689
 *  This function exists for compatibility purposes because wolfSSL satisfies
21690
 *  thread safety without relying on the callback.
21691
 */
21692
void wolfSSL_set_dynlock_destroy_callback(
21693
                  void (*f)(WOLFSSL_dynlock_value*, const char*, int))
21694
0
{
21695
0
    WOLFSSL_STUB("CRYPTO_set_set_dynlock_destroy_callback");
21696
0
    (void)f;
21697
0
}
21698
21699
21700
#endif /* OPENSSL_EXTRA */
21701
21702
#ifdef OPENSSL_EXTRA
21703
#ifndef NO_CERTS
21704
21705
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
21706
/* Copies unencrypted DER key buffer into "der". If "der" is null then the size
21707
 * of buffer needed is returned. If *der == NULL then it allocates a buffer.
21708
 * NOTE: This also advances the "der" pointer to be at the end of buffer.
21709
 *
21710
 * Returns size of key buffer on success
21711
 */
21712
int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der)
21713
0
{
21714
0
    return wolfSSL_EVP_PKEY_get_der(key, der);
21715
0
}
21716
21717
int wolfSSL_i2d_PublicKey(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
21718
0
{
21719
0
    return wolfSSL_EVP_PKEY_get_der(key, der);
21720
0
}
21721
#endif /* !NO_ASN && !NO_PWDBASED */
21722
21723
#endif /* !NO_CERTS */
21724
#endif /* OPENSSL_EXTRA */
21725
21726
#ifdef OPENSSL_EXTRA
21727
21728
/******************************************************************************
21729
* wolfSSL_CTX_set1_param - set a pointer to the SSL verification parameters
21730
*
21731
* RETURNS:
21732
*   WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
21733
*   Note: Returns WOLFSSL_SUCCESS, in case either parameter is NULL,
21734
*   same as openssl.
21735
*/
21736
int wolfSSL_CTX_set1_param(WOLFSSL_CTX* ctx, WOLFSSL_X509_VERIFY_PARAM *vpm)
21737
0
{
21738
0
    if (ctx == NULL || vpm == NULL)
21739
0
        return WOLFSSL_SUCCESS;
21740
21741
0
    return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, vpm);
21742
0
}
21743
21744
/******************************************************************************
21745
* wolfSSL_CTX/_get0_param - return a pointer to the SSL verification parameters
21746
*
21747
* RETURNS:
21748
* returns pointer to the SSL verification parameters on success,
21749
* otherwise returns NULL
21750
*/
21751
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_CTX_get0_param(WOLFSSL_CTX* ctx)
21752
0
{
21753
0
    if (ctx == NULL) {
21754
0
        return NULL;
21755
0
    }
21756
21757
0
    return ctx->param;
21758
0
}
21759
21760
WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl)
21761
0
{
21762
0
    if (ssl == NULL) {
21763
0
        return NULL;
21764
0
    }
21765
0
    return ssl->param;
21766
0
}
21767
21768
#endif /* OPENSSL_EXTRA */
21769
21770
#if defined(OPENSSL_EXTRA)
21771
int wolfSSL_i2d_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER* a, unsigned char** out)
21772
0
{
21773
0
    int ret = 0;
21774
0
    word32 idx = 0;
21775
0
    int len;
21776
0
    int preAlloc = 1;
21777
21778
0
    WOLFSSL_ENTER("wolfSSL_i2d_ASN1_INTEGER");
21779
21780
0
    if (a == NULL || a->data == NULL || a->length <= 0 || out == NULL) {
21781
0
        WOLFSSL_MSG("Bad parameter.");
21782
0
        ret = WOLFSSL_FATAL_ERROR;
21783
0
    }
21784
21785
0
    if (ret == 0 && *out == NULL) {
21786
0
        preAlloc = 0;
21787
0
        *out = (unsigned char*)XMALLOC(a->length, NULL, DYNAMIC_TYPE_ASN1);
21788
0
        if (*out == NULL) {
21789
0
            WOLFSSL_MSG("Failed to allocate output buffer.");
21790
0
            ret = WOLFSSL_FATAL_ERROR;
21791
0
        }
21792
0
    }
21793
0
    if (ret == 0) {
21794
        /*
21795
         * A WOLFSSL_ASN1_INTEGER stores the DER buffer of the integer in its
21796
         * "data" field, but it's only the magnitude of the number (i.e. the
21797
         * sign isn't encoded). The "negative" field is 1 if the value should
21798
         * be interpreted as negative and 0 otherwise. If the value is negative,
21799
         * we need to output the 2's complement of the value in the DER output.
21800
         */
21801
0
        XMEMCPY(*out, a->data, a->length);
21802
0
        if (a->negative) {
21803
0
            if (GetLength(a->data, &idx, &len, a->length) < 0) {
21804
0
                ret = WOLFSSL_FATAL_ERROR;
21805
0
            }
21806
0
            else {
21807
0
                ++idx;
21808
0
                for (; (int)idx < a->length; ++idx) {
21809
0
                    (*out)[idx] = ~(*out)[idx];
21810
0
                }
21811
0
                do {
21812
0
                    --idx;
21813
0
                    ++(*out)[idx];
21814
0
                } while ((*out)[idx] == 0);
21815
0
            }
21816
0
        }
21817
0
    }
21818
0
    if (ret == 0) {
21819
0
        ret = a->length;
21820
0
        if (preAlloc) {
21821
0
            *out += a->length;
21822
0
        }
21823
0
    }
21824
21825
0
    WOLFSSL_LEAVE("wolfSSL_i2d_ASN1_INTEGER", ret);
21826
21827
0
    return ret;
21828
0
}
21829
21830
WOLFSSL_ASN1_INTEGER* wolfSSL_d2i_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER** a,
21831
                                               const unsigned char** in,
21832
                                               long inSz)
21833
0
{
21834
0
    WOLFSSL_ASN1_INTEGER* ret = NULL;
21835
0
    int err = 0;
21836
0
    word32 idx = 0;
21837
0
    int len;
21838
21839
0
    WOLFSSL_ENTER("wolfSSL_d2i_ASN1_INTEGER");
21840
21841
0
    if (in == NULL || *in == NULL || inSz <= 0) {
21842
0
        WOLFSSL_MSG("Bad parameter");
21843
0
        err = 1;
21844
0
    }
21845
21846
0
    if (err == 0 && (*in)[0] != ASN_INTEGER) {
21847
0
        WOLFSSL_MSG("Tag doesn't indicate integer type.");
21848
0
        err = 1;
21849
0
    }
21850
0
    if (err == 0) {
21851
0
        ret = wolfSSL_ASN1_INTEGER_new();
21852
0
        if (ret == NULL) {
21853
0
            err = 1;
21854
0
        }
21855
0
        else {
21856
0
            ret->type = V_ASN1_INTEGER;
21857
0
        }
21858
0
    }
21859
0
    if (err == 0 && inSz > (long)sizeof(ret->intData)) {
21860
0
        ret->data = (unsigned char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_ASN1);
21861
0
        if (ret->data == NULL) {
21862
0
            err = 1;
21863
0
        }
21864
0
        else {
21865
0
            ret->isDynamic = 1;
21866
0
            ret->dataMax = (word32)inSz;
21867
0
        }
21868
0
    }
21869
0
    if (err == 0) {
21870
0
        XMEMCPY(ret->data, *in, inSz);
21871
0
        ret->length = (word32)inSz;
21872
        /* Advance to the end of the length field.*/
21873
0
        if (GetLength(*in, &idx, &len, (word32)inSz) < 0) {
21874
0
            err = 1;
21875
0
        }
21876
0
        else {
21877
            /* See 2's complement comment in wolfSSL_d2i_ASN1_INTEGER. */
21878
0
            ret->negative = (*in)[idx+1] & 0x80;
21879
0
            if (ret->negative) {
21880
0
                ++idx;
21881
0
                for (; (int)idx < inSz; ++idx) {
21882
0
                    ret->data[idx] = ~ret->data[idx];
21883
0
                }
21884
0
                do {
21885
0
                    --idx;
21886
0
                    ++ret->data[idx];
21887
0
                } while (ret->data[idx] == 0);
21888
0
                ret->type |= V_ASN1_NEG_INTEGER;
21889
0
            }
21890
0
            if (a != NULL) {
21891
0
                *a = ret;
21892
0
            }
21893
0
        }
21894
0
    }
21895
21896
0
    if (err != 0) {
21897
0
        wolfSSL_ASN1_INTEGER_free(ret);
21898
0
        ret = NULL;
21899
0
    }
21900
21901
0
    return ret;
21902
0
}
21903
#endif /* OPENSSL_EXTRA */
21904
21905
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
21906
/* Used to create a new WOLFSSL_ASN1_INTEGER structure.
21907
 * returns a pointer to new structure on success and NULL on failure
21908
 */
21909
WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void)
21910
446
{
21911
446
    WOLFSSL_ASN1_INTEGER* a;
21912
21913
446
    a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL,
21914
446
                                       DYNAMIC_TYPE_OPENSSL);
21915
446
    if (a == NULL) {
21916
0
        return NULL;
21917
0
    }
21918
21919
446
    XMEMSET(a, 0, sizeof(WOLFSSL_ASN1_INTEGER));
21920
446
    a->data    = a->intData;
21921
446
    a->isDynamic = 0;
21922
446
    a->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
21923
446
    a->length  = 0;
21924
446
    return a;
21925
446
}
21926
21927
21928
/* free's internal elements of WOLFSSL_ASN1_INTEGER and free's "in" itself */
21929
void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in)
21930
446
{
21931
446
    if (in != NULL) {
21932
446
        if (in->isDynamic) {
21933
139
            XFREE(in->data, NULL, DYNAMIC_TYPE_OPENSSL);
21934
139
        }
21935
446
        XFREE(in, NULL, DYNAMIC_TYPE_OPENSSL);
21936
446
    }
21937
446
}
21938
21939
21940
/* Duplicate all WOLFSSL_ASN1_INTEGER members from src to dup
21941
 *  src : WOLFSSL_ASN1_INTEGER to duplicate
21942
 *  Returns pointer to duplicate WOLFSSL_ASN1_INTEGER
21943
 */
21944
WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER* src)
21945
0
{
21946
0
    WOLFSSL_ASN1_INTEGER* copy;
21947
0
    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_dup");
21948
0
    if (!src)
21949
0
        return NULL;
21950
21951
0
    copy = wolfSSL_ASN1_INTEGER_new();
21952
21953
0
    if (copy == NULL)
21954
0
        return NULL;
21955
21956
0
    copy->negative  = src->negative;
21957
0
    copy->dataMax   = src->dataMax;
21958
0
    copy->isDynamic = src->isDynamic;
21959
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
21960
0
    copy->length    = src->length;
21961
0
#endif
21962
0
    XSTRNCPY((char*)copy->intData,(const char*)src->intData,WOLFSSL_ASN1_INTEGER_MAX);
21963
21964
0
    if (copy->isDynamic && src->data && copy->dataMax) {
21965
0
        copy->data = (unsigned char*)
21966
0
            XMALLOC(src->dataMax,NULL,DYNAMIC_TYPE_OPENSSL);
21967
0
        if (copy->data == NULL) {
21968
0
            wolfSSL_ASN1_INTEGER_free(copy);
21969
0
            return NULL;
21970
0
        }
21971
0
        XMEMCPY(copy->data, src->data, copy->dataMax);
21972
0
    }
21973
0
    return copy;
21974
0
}
21975
21976
21977
/* sets the value of WOLFSSL_ASN1_INTEGER a to the long value v. */
21978
int wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v)
21979
0
{
21980
0
    int ret = WOLFSSL_SUCCESS; /* return 1 for success and 0 for failure */
21981
0
    int j;
21982
0
    unsigned int i = 0;
21983
0
    unsigned char tmp[sizeof(long)+1] = {0};
21984
0
    int pad = 0;
21985
21986
0
    if (a != NULL) {
21987
        /* dynamically create data buffer, +2 for type and length */
21988
0
        a->data = (unsigned char*)XMALLOC((sizeof(long)+1) + 2, NULL,
21989
0
                DYNAMIC_TYPE_OPENSSL);
21990
0
        if (a->data == NULL) {
21991
0
            wolfSSL_ASN1_INTEGER_free(a);
21992
0
            ret = WOLFSSL_FAILURE;
21993
0
        }
21994
0
        else {
21995
0
            a->dataMax   = (int)(sizeof(long)+1) + 2;
21996
0
            a->isDynamic = 1;
21997
0
        }
21998
0
    }
21999
0
    else {
22000
        /* Invalid parameter */
22001
0
        ret = WOLFSSL_FAILURE;
22002
0
    }
22003
22004
22005
0
    if (ret != WOLFSSL_FAILURE) {
22006
        /* Set type */
22007
0
        a->data[i++] = ASN_INTEGER;
22008
22009
        /* Check for negative */
22010
0
        if (v < 0) {
22011
0
            a->negative = 1;
22012
0
            v *= -1;
22013
0
        }
22014
22015
        /* Create char buffer */
22016
0
        for (j = 0; j < (int)sizeof(long); j++) {
22017
0
            if (v == 0) {
22018
0
                break;
22019
0
            }
22020
0
            tmp[j] = (unsigned char)(v & 0xff);
22021
0
            v >>= 8;
22022
0
        }
22023
22024
        /* 0 pad to indicate positive number when top bit set. */
22025
0
        if ((!a->negative) && (j > 0) && (tmp[j-1] & 0x80)) {
22026
0
            pad = 1;
22027
0
        }
22028
        /* Set length */
22029
0
        a->data[i++] = (unsigned char)(((j == 0) ? ++j : j) + pad);
22030
        /* +2 for type and length */
22031
0
        a->length = j + pad + 2;
22032
22033
        /* Add padding if required. */
22034
0
        if (pad) {
22035
0
            a->data[i++] = 0;
22036
0
        }
22037
        /* Copy to data */
22038
0
        for (; j > 0; j--) {
22039
0
            a->data[i++] = tmp[j-1];
22040
0
        }
22041
0
    }
22042
22043
0
    return ret;
22044
0
}
22045
22046
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
22047
22048
#if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \
22049
    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
22050
#ifndef NO_ASN_TIME
22051
#ifndef NO_BIO
22052
int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime)
22053
0
{
22054
0
    char buf[MAX_TIME_STRING_SZ];
22055
0
    int  ret = WOLFSSL_SUCCESS;
22056
22057
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_print");
22058
22059
0
    if (bio == NULL || asnTime == NULL) {
22060
0
        WOLFSSL_MSG("NULL function argument");
22061
0
        return WOLFSSL_FAILURE;
22062
0
    }
22063
22064
0
    if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)asnTime, buf,
22065
0
                sizeof(buf)) == NULL) {
22066
0
        XMEMSET(buf, 0, MAX_TIME_STRING_SZ);
22067
0
        XSTRNCPY(buf, "Bad time value", sizeof(buf)-1);
22068
0
        ret = WOLFSSL_FAILURE;
22069
0
    }
22070
22071
0
    if (wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf)) <= 0) {
22072
0
        WOLFSSL_MSG("Unable to write to bio");
22073
0
        return WOLFSSL_FAILURE;
22074
0
    }
22075
22076
0
    return ret;
22077
0
}
22078
#endif /* !NO_BIO */
22079
22080
char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len)
22081
0
{
22082
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string");
22083
22084
0
    if (t == NULL || buf == NULL || len < 5) {
22085
0
        WOLFSSL_MSG("Bad argument");
22086
0
        return NULL;
22087
0
    }
22088
22089
0
    if (t->length > len) {
22090
0
        WOLFSSL_MSG("Length of date is longer then buffer");
22091
0
        return NULL;
22092
0
    }
22093
22094
0
    if (!GetTimeString(t->data, t->type, buf, len)) {
22095
0
        return NULL;
22096
0
    }
22097
22098
0
    return buf;
22099
0
}
22100
22101
/* Converts a WOLFSSL_ASN1_TIME to a struct tm. Returns WOLFSSL_SUCCESS on
22102
 * success and WOLFSSL_FAILURE on failure. */
22103
static int Asn1TimeToTm(WOLFSSL_ASN1_TIME* asnTime, struct tm* tm)
22104
0
{
22105
0
    unsigned char* asn1TimeBuf;
22106
0
    int asn1TimeBufLen;
22107
0
    int i = 0;
22108
0
    int bytesNeeded = 11;
22109
22110
0
    if (asnTime == NULL) {
22111
0
        WOLFSSL_MSG("asnTime is NULL");
22112
0
        return WOLFSSL_FAILURE;
22113
0
    }
22114
0
    if (tm == NULL) {
22115
0
        WOLFSSL_MSG("tm is NULL");
22116
0
        return WOLFSSL_FAILURE;
22117
0
    }
22118
22119
0
    asn1TimeBuf = wolfSSL_ASN1_TIME_get_data(asnTime);
22120
0
    if (asn1TimeBuf == NULL) {
22121
0
        WOLFSSL_MSG("Failed to get WOLFSSL_ASN1_TIME buffer.");
22122
0
        return WOLFSSL_FAILURE;
22123
0
    }
22124
0
    asn1TimeBufLen = wolfSSL_ASN1_TIME_get_length(asnTime);
22125
0
    if (asn1TimeBufLen <= 0) {
22126
0
        WOLFSSL_MSG("Failed to get WOLFSSL_ASN1_TIME buffer length.");
22127
0
        return WOLFSSL_FAILURE;
22128
0
    }
22129
0
    XMEMSET(tm, 0, sizeof(struct tm));
22130
22131
    /* Convert ASN1_time to struct tm */
22132
    /* Check type */
22133
0
    if (asnTime->type == ASN_UTC_TIME) {
22134
        /* 2-digit year */
22135
0
        bytesNeeded += 2;
22136
0
        if (bytesNeeded > asn1TimeBufLen) {
22137
0
            WOLFSSL_MSG("WOLFSSL_ASN1_TIME buffer length is invalid.");
22138
0
            return WOLFSSL_FAILURE;
22139
0
        }
22140
0
        if (asn1TimeBuf[bytesNeeded-1] != 'Z') {
22141
0
            WOLFSSL_MSG("Expecting UTC time.");
22142
0
            return WOLFSSL_FAILURE;
22143
0
        }
22144
22145
0
        tm->tm_year = (asn1TimeBuf[i] - '0') * 10; i++;
22146
0
        tm->tm_year += asn1TimeBuf[i] - '0'; i++;
22147
0
        if (tm->tm_year < 70) {
22148
0
            tm->tm_year += 100;
22149
0
        }
22150
0
    }
22151
0
    else if (asnTime->type == ASN_GENERALIZED_TIME) {
22152
        /* 4-digit year */
22153
0
        bytesNeeded += 4;
22154
0
        if (bytesNeeded > asn1TimeBufLen) {
22155
0
            WOLFSSL_MSG("WOLFSSL_ASN1_TIME buffer length is invalid.");
22156
0
            return WOLFSSL_FAILURE;
22157
0
        }
22158
0
        if (asn1TimeBuf[bytesNeeded-1] != 'Z') {
22159
0
            WOLFSSL_MSG("Expecting UTC time.");
22160
0
            return WOLFSSL_FAILURE;
22161
0
        }
22162
22163
0
        tm->tm_year = (asn1TimeBuf[i] - '0') * 1000; i++;
22164
0
        tm->tm_year += (asn1TimeBuf[i] - '0') * 100; i++;
22165
0
        tm->tm_year += (asn1TimeBuf[i] - '0') * 10; i++;
22166
0
        tm->tm_year += asn1TimeBuf[i] - '0'; i++;
22167
0
        tm->tm_year -= 1900;
22168
0
    }
22169
0
    else {
22170
0
        WOLFSSL_MSG("asnTime->type is invalid.");
22171
0
        return WOLFSSL_FAILURE;
22172
0
    }
22173
22174
0
    tm->tm_mon = (asn1TimeBuf[i] - '0') * 10; i++;
22175
0
    tm->tm_mon += (asn1TimeBuf[i] - '0') - 1; i++; /* January is 0 not 1 */
22176
0
    tm->tm_mday = (asn1TimeBuf[i] - '0') * 10; i++;
22177
0
    tm->tm_mday += (asn1TimeBuf[i] - '0'); i++;
22178
0
    tm->tm_hour = (asn1TimeBuf[i] - '0') * 10; i++;
22179
0
    tm->tm_hour += (asn1TimeBuf[i] - '0'); i++;
22180
0
    tm->tm_min = (asn1TimeBuf[i] - '0') * 10; i++;
22181
0
    tm->tm_min += (asn1TimeBuf[i] - '0'); i++;
22182
0
    tm->tm_sec = (asn1TimeBuf[i] - '0') * 10; i++;
22183
0
    tm->tm_sec += (asn1TimeBuf[i] - '0');
22184
22185
0
#ifdef XMKTIME
22186
    /* Call XMKTIME on tm to get the tm_wday and tm_yday fields populated. */
22187
0
    XMKTIME(tm);
22188
0
#endif
22189
22190
0
    return WOLFSSL_SUCCESS;
22191
0
}
22192
22193
int wolfSSL_ASN1_TIME_to_tm(const WOLFSSL_ASN1_TIME* asnTime, struct tm* tm)
22194
0
{
22195
0
    time_t currentTime;
22196
0
    struct tm *tmpTs;
22197
0
#if defined(NEED_TMP_TIME)
22198
    /* for use with gmtime_r */
22199
0
    struct tm tmpTimeStorage;
22200
0
    tmpTs = &tmpTimeStorage;
22201
#else
22202
    tmpTs = NULL;
22203
#endif
22204
0
    (void)tmpTs;
22205
22206
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_tm");
22207
22208
    /* If asnTime is NULL, then the current time is converted. */
22209
0
    if (asnTime == NULL) {
22210
0
        if (tm == NULL) {
22211
0
            WOLFSSL_MSG("asnTime and tm are both NULL");
22212
0
            return WOLFSSL_FAILURE;
22213
0
        }
22214
22215
0
        currentTime = wc_Time(0);
22216
0
        if (currentTime <= 0) {
22217
0
            WOLFSSL_MSG("Failed to get current time.");
22218
0
            return WOLFSSL_FAILURE;
22219
0
        }
22220
22221
0
        tm = XGMTIME(&currentTime, tmpTs);
22222
0
        if (tm == NULL) {
22223
0
            WOLFSSL_MSG("Failed to convert current time to UTC.");
22224
0
            return WOLFSSL_FAILURE;
22225
0
        }
22226
22227
0
        return WOLFSSL_SUCCESS;
22228
0
    }
22229
22230
    /* If tm is NULL this function performs a format check on asnTime only. */
22231
0
    if (tm == NULL) {
22232
0
        return wolfSSL_ASN1_TIME_check(asnTime);
22233
0
    }
22234
22235
0
    return Asn1TimeToTm((WOLFSSL_ASN1_TIME*)asnTime, tm);
22236
0
}
22237
#endif /* !NO_ASN_TIME */
22238
#endif /* WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
22239
    OPENSSL_EXTRA*/
22240
22241
22242
#ifdef OPENSSL_EXTRA
22243
22244
int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER* a,
22245
                             const WOLFSSL_ASN1_INTEGER* b)
22246
0
{
22247
0
    int ret = 0;
22248
22249
0
    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_cmp");
22250
22251
0
    if (a == NULL || b == NULL) {
22252
0
        WOLFSSL_MSG("Bad parameter.");
22253
0
        ret = WOLFSSL_FATAL_ERROR;
22254
0
    }
22255
22256
0
    if (ret == 0 && ((a->length != b->length) ||
22257
0
                     ((a->negative == 0) != (b->negative == 0)))) {
22258
0
        ret = WOLFSSL_FATAL_ERROR;
22259
0
    }
22260
0
    if (ret == 0) {
22261
0
        ret = XMEMCMP(a->data, b->data, a->length);
22262
0
    }
22263
22264
0
    WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_cmp", ret);
22265
22266
0
    return ret;
22267
0
}
22268
22269
long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* a)
22270
0
{
22271
0
    long ret = 1;
22272
0
    WOLFSSL_BIGNUM* bn = NULL;
22273
22274
0
    WOLFSSL_ENTER("ASN1_INTEGER_get");
22275
22276
0
    if (a == NULL) {
22277
        /* OpenSSL returns 0 when a is NULL and -1 if there is an error. Quoting
22278
         * the documentation:
22279
         *
22280
         * "ASN1_INTEGER_get() also returns the value of a but it returns 0 if a
22281
         * is NULL and -1 on error (which is ambiguous because -1 is a
22282
         * legitimate value for an ASN1_INTEGER). New applications should use
22283
         * ASN1_INTEGER_get_int64() instead."
22284
         * */
22285
0
        ret = 0;
22286
0
    }
22287
22288
0
    if (ret > 0) {
22289
0
        bn = wolfSSL_ASN1_INTEGER_to_BN(a, NULL);
22290
0
        if (bn == NULL) {
22291
0
            ret = -1;
22292
0
        }
22293
0
    }
22294
0
    if (ret > 0) {
22295
0
        ret = wolfSSL_BN_get_word(bn);
22296
0
        if (a->negative == 1) {
22297
0
            ret = -ret;
22298
0
        }
22299
0
    }
22300
22301
0
    if (bn != NULL) {
22302
0
        wolfSSL_BN_free(bn);
22303
0
    }
22304
22305
0
    WOLFSSL_LEAVE("ASN1_INTEGER_get", (int)ret);
22306
22307
0
    return ret;
22308
0
}
22309
22310
#endif /* OPENSSL_EXTRA */
22311
22312
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
22313
/* Gets an index to store SSL structure at.
22314
 *
22315
 * Returns positive index on success and negative values on failure
22316
 */
22317
int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
22318
0
{
22319
0
    WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
22320
22321
    /* store SSL at index 0 */
22322
0
    return 0;
22323
0
}
22324
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
22325
22326
#ifdef OPENSSL_EXTRA
22327
/* Sets a function callback that will send information about the state of all
22328
 * WOLFSSL objects that have been created by the WOLFSSL_CTX structure passed
22329
 * in.
22330
 *
22331
 * ctx WOLFSSL_CTX structure to set callback function in
22332
 * f   callback function to use
22333
 */
22334
void wolfSSL_CTX_set_info_callback(WOLFSSL_CTX* ctx,
22335
       void (*f)(const WOLFSSL* ssl, int type, int val))
22336
0
{
22337
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_info_callback");
22338
0
    if (ctx == NULL) {
22339
0
        WOLFSSL_MSG("Bad function argument");
22340
0
    }
22341
0
    else {
22342
0
        ctx->CBIS = f;
22343
0
    }
22344
0
}
22345
22346
22347
unsigned long wolfSSL_ERR_peek_error(void)
22348
0
{
22349
0
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error");
22350
22351
0
    return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL);
22352
0
}
22353
22354
int wolfSSL_ERR_GET_LIB(unsigned long err)
22355
0
{
22356
0
    unsigned long value;
22357
22358
0
    value = (err & 0xFFFFFFL);
22359
0
    switch (value) {
22360
0
    case -SSL_R_HTTP_REQUEST:
22361
0
        return ERR_LIB_SSL;
22362
0
    case PEM_R_NO_START_LINE:
22363
0
    case PEM_R_PROBLEMS_GETTING_PASSWORD:
22364
0
    case PEM_R_BAD_PASSWORD_READ:
22365
0
    case PEM_R_BAD_DECRYPT:
22366
0
        return ERR_LIB_PEM;
22367
0
    case EVP_R_BAD_DECRYPT:
22368
0
    case EVP_R_BN_DECODE_ERROR:
22369
0
    case EVP_R_DECODE_ERROR:
22370
0
    case EVP_R_PRIVATE_KEY_DECODE_ERROR:
22371
0
        return ERR_LIB_EVP;
22372
0
    case ASN1_R_HEADER_TOO_LONG:
22373
0
        return ERR_LIB_ASN1;
22374
0
    default:
22375
0
        return 0;
22376
0
    }
22377
0
}
22378
22379
/* This function is to find global error values that are the same through out
22380
 * all library version. With wolfSSL having only one set of error codes the
22381
 * return value is pretty straight forward. The only thing needed is all wolfSSL
22382
 * error values are typically negative.
22383
 *
22384
 * Returns the error reason
22385
 */
22386
int wolfSSL_ERR_GET_REASON(unsigned long err)
22387
0
{
22388
0
    int ret = (int)err;
22389
22390
0
    WOLFSSL_ENTER("wolfSSL_ERR_GET_REASON");
22391
22392
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
22393
    /* Nginx looks for this error to know to stop parsing certificates. */
22394
0
    if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
22395
0
        return PEM_R_NO_START_LINE;
22396
0
    if (err == ((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
22397
0
        return SSL_R_HTTP_REQUEST;
22398
0
#endif
22399
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
22400
    if (err == ((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
22401
        return ASN1_R_HEADER_TOO_LONG;
22402
#endif
22403
22404
    /* check if error value is in range of wolfSSL errors */
22405
0
    ret = 0 - ret; /* setting as negative value */
22406
    /* wolfCrypt range is less than MAX (-100)
22407
       wolfSSL range is MIN (-300) and lower */
22408
0
    if (ret < MAX_CODE_E && ret > MIN_CODE_E) {
22409
0
        return ret;
22410
0
    }
22411
0
    else {
22412
0
        WOLFSSL_MSG("Not in range of typical error values");
22413
0
        ret = (int)err;
22414
0
    }
22415
22416
0
    return ret;
22417
0
}
22418
22419
/* returns a string that describes the alert
22420
 *
22421
 * alertID the alert value to look up
22422
 */
22423
const char* wolfSSL_alert_type_string_long(int alertID)
22424
0
{
22425
0
    WOLFSSL_ENTER("wolfSSL_alert_type_string_long");
22426
22427
0
    return AlertTypeToString(alertID);
22428
0
}
22429
22430
22431
const char* wolfSSL_alert_desc_string_long(int alertID)
22432
0
{
22433
0
    WOLFSSL_ENTER("wolfSSL_alert_desc_string_long");
22434
22435
0
    return AlertTypeToString(alertID);
22436
0
}
22437
22438
#define STATE_STRINGS_PROTO(s) \
22439
0
    {                          \
22440
0
        {"SSLv3 " s,           \
22441
0
         "SSLv3 " s,           \
22442
0
         "SSLv3 " s},          \
22443
0
        {"TLSv1 " s,           \
22444
0
         "TLSv1 " s,           \
22445
0
         "TLSv1 " s},          \
22446
0
        {"TLSv1_1 " s,         \
22447
0
         "TLSv1_1 " s,         \
22448
0
         "TLSv1_1 " s},        \
22449
0
        {"TLSv1_2 " s,         \
22450
0
         "TLSv1_2 " s,         \
22451
0
         "TLSv1_2 " s},        \
22452
0
        {"TLSv1_3 " s,         \
22453
0
         "TLSv1_3 " s,         \
22454
0
         "TLSv1_3 " s},        \
22455
0
        {"DTLSv1 " s,          \
22456
0
         "DTLSv1 " s,          \
22457
0
         "DTLSv1 " s},         \
22458
0
        {"DTLSv1_2 " s,        \
22459
0
         "DTLSv1_2 " s,        \
22460
0
         "DTLSv1_2 " s},       \
22461
0
        {"DTLSv1_3 " s,        \
22462
0
         "DTLSv1_3 " s,        \
22463
0
         "DTLSv1_3 " s},       \
22464
0
    }
22465
22466
#define STATE_STRINGS_PROTO_RW(s) \
22467
0
    {                             \
22468
0
        {"SSLv3 read " s,         \
22469
0
         "SSLv3 write " s,        \
22470
0
         "SSLv3 " s},             \
22471
0
        {"TLSv1 read " s,         \
22472
0
         "TLSv1 write " s,        \
22473
0
         "TLSv1 " s},             \
22474
0
        {"TLSv1_1 read " s,       \
22475
0
         "TLSv1_1 write " s,      \
22476
0
         "TLSv1_1 " s},           \
22477
0
        {"TLSv1_2 read " s,       \
22478
0
         "TLSv1_2 write " s,      \
22479
0
         "TLSv1_2 " s},           \
22480
0
        {"TLSv1_3 read " s,       \
22481
0
         "TLSv1_3 write " s,      \
22482
0
         "TLSv1_3 " s},           \
22483
0
        {"DTLSv1 read " s,        \
22484
0
         "DTLSv1 write " s,       \
22485
0
         "DTLSv1 " s},            \
22486
0
        {"DTLSv1_2 read " s,      \
22487
0
         "DTLSv1_2 write " s,     \
22488
0
         "DTLSv1_2 " s},          \
22489
0
        {"DTLSv1_3 read " s,      \
22490
0
         "DTLSv1_3 write " s,     \
22491
0
         "DTLSv1_3 " s},          \
22492
0
    }
22493
22494
/* Gets the current state of the WOLFSSL structure
22495
 *
22496
 * ssl WOLFSSL structure to get state of
22497
 *
22498
 * Returns a human readable string of the WOLFSSL structure state
22499
 */
22500
const char* wolfSSL_state_string_long(const WOLFSSL* ssl)
22501
0
{
22502
22503
0
    static const char* OUTPUT_STR[24][8][3] = {
22504
0
        STATE_STRINGS_PROTO("Initialization"),
22505
0
        STATE_STRINGS_PROTO_RW("Server Hello Request"),
22506
0
        STATE_STRINGS_PROTO_RW("Server Hello Verify Request"),
22507
0
        STATE_STRINGS_PROTO_RW("Server Hello Retry Request"),
22508
0
        STATE_STRINGS_PROTO_RW("Server Hello"),
22509
0
        STATE_STRINGS_PROTO_RW("Server Certificate Status"),
22510
0
        STATE_STRINGS_PROTO_RW("Server Encrypted Extensions"),
22511
0
        STATE_STRINGS_PROTO_RW("Server Session Ticket"),
22512
0
        STATE_STRINGS_PROTO_RW("Server Certificate Request"),
22513
0
        STATE_STRINGS_PROTO_RW("Server Cert"),
22514
0
        STATE_STRINGS_PROTO_RW("Server Key Exchange"),
22515
0
        STATE_STRINGS_PROTO_RW("Server Hello Done"),
22516
0
        STATE_STRINGS_PROTO_RW("Server Change CipherSpec"),
22517
0
        STATE_STRINGS_PROTO_RW("Server Finished"),
22518
0
        STATE_STRINGS_PROTO_RW("server Key Update"),
22519
0
        STATE_STRINGS_PROTO_RW("Client Hello"),
22520
0
        STATE_STRINGS_PROTO_RW("Client Key Exchange"),
22521
0
        STATE_STRINGS_PROTO_RW("Client Cert"),
22522
0
        STATE_STRINGS_PROTO_RW("Client Change CipherSpec"),
22523
0
        STATE_STRINGS_PROTO_RW("Client Certificate Verify"),
22524
0
        STATE_STRINGS_PROTO_RW("Client End Of Early Data"),
22525
0
        STATE_STRINGS_PROTO_RW("Client Finished"),
22526
0
        STATE_STRINGS_PROTO_RW("Client Key Update"),
22527
0
        STATE_STRINGS_PROTO("Handshake Done"),
22528
0
    };
22529
0
    enum ProtocolVer {
22530
0
        SSL_V3 = 0,
22531
0
        TLS_V1,
22532
0
        TLS_V1_1,
22533
0
        TLS_V1_2,
22534
0
        TLS_V1_3,
22535
0
        DTLS_V1,
22536
0
        DTLS_V1_2,
22537
0
        DTLS_V1_3,
22538
0
        UNKNOWN = 100
22539
0
    };
22540
22541
0
    enum IOMode {
22542
0
        SS_READ = 0,
22543
0
        SS_WRITE,
22544
0
        SS_NEITHER
22545
0
    };
22546
22547
0
    enum SslState {
22548
0
        ss_null_state = 0,
22549
0
        ss_server_hellorequest,
22550
0
        ss_server_helloverify,
22551
0
        ss_server_helloretryrequest,
22552
0
        ss_server_hello,
22553
0
        ss_server_certificatestatus,
22554
0
        ss_server_encryptedextensions,
22555
0
        ss_server_sessionticket,
22556
0
        ss_server_certrequest,
22557
0
        ss_server_cert,
22558
0
        ss_server_keyexchange,
22559
0
        ss_server_hellodone,
22560
0
        ss_server_changecipherspec,
22561
0
        ss_server_finished,
22562
0
        ss_server_keyupdate,
22563
0
        ss_client_hello,
22564
0
        ss_client_keyexchange,
22565
0
        ss_client_cert,
22566
0
        ss_client_changecipherspec,
22567
0
        ss_client_certverify,
22568
0
        ss_client_endofearlydata,
22569
0
        ss_client_finished,
22570
0
        ss_client_keyupdate,
22571
0
        ss_handshake_done
22572
0
    };
22573
22574
0
    int protocol = 0;
22575
0
    int cbmode = 0;
22576
0
    int state = 0;
22577
22578
0
    WOLFSSL_ENTER("wolfSSL_state_string_long");
22579
0
    if (ssl == NULL) {
22580
0
        WOLFSSL_MSG("Null argument passed in");
22581
0
        return NULL;
22582
0
    }
22583
22584
    /* Get state of callback */
22585
0
    if (ssl->cbmode == SSL_CB_MODE_WRITE) {
22586
0
        cbmode =  SS_WRITE;
22587
0
    }
22588
0
    else if (ssl->cbmode == SSL_CB_MODE_READ) {
22589
0
        cbmode =  SS_READ;
22590
0
    }
22591
0
    else {
22592
0
        cbmode =  SS_NEITHER;
22593
0
    }
22594
22595
    /* Get protocol version */
22596
0
    switch (ssl->version.major) {
22597
0
        case SSLv3_MAJOR:
22598
0
            switch (ssl->version.minor) {
22599
0
                case SSLv3_MINOR:
22600
0
                    protocol = SSL_V3;
22601
0
                    break;
22602
0
                case TLSv1_MINOR:
22603
0
                    protocol = TLS_V1;
22604
0
                    break;
22605
0
                case TLSv1_1_MINOR:
22606
0
                    protocol = TLS_V1_1;
22607
0
                    break;
22608
0
                case TLSv1_2_MINOR:
22609
0
                    protocol = TLS_V1_2;
22610
0
                    break;
22611
0
                case TLSv1_3_MINOR:
22612
0
                    protocol = TLS_V1_3;
22613
0
                    break;
22614
0
                default:
22615
0
                    protocol = UNKNOWN;
22616
0
            }
22617
0
            break;
22618
0
        case DTLS_MAJOR:
22619
0
            switch (ssl->version.minor) {
22620
0
                case DTLS_MINOR:
22621
0
                    protocol = DTLS_V1;
22622
0
                    break;
22623
0
                case DTLSv1_2_MINOR:
22624
0
                    protocol = DTLS_V1_2;
22625
0
                    break;
22626
0
                case DTLSv1_3_MINOR:
22627
0
                    protocol = DTLS_V1_3;
22628
0
                    break;
22629
0
                default:
22630
0
                    protocol = UNKNOWN;
22631
0
            }
22632
0
            break;
22633
0
    default:
22634
0
        protocol = UNKNOWN;
22635
0
    }
22636
22637
    /* accept process */
22638
0
    if (ssl->cbmode == SSL_CB_MODE_READ) {
22639
0
        state = ssl->cbtype;
22640
0
        switch (state) {
22641
0
            case hello_request:
22642
0
                state = ss_server_hellorequest;
22643
0
                break;
22644
0
            case client_hello:
22645
0
                state = ss_client_hello;
22646
0
                break;
22647
0
            case server_hello:
22648
0
                state = ss_server_hello;
22649
0
                break;
22650
0
            case hello_verify_request:
22651
0
                state = ss_server_helloverify;
22652
0
                break;
22653
0
            case session_ticket:
22654
0
                state = ss_server_sessionticket;
22655
0
                break;
22656
0
            case end_of_early_data:
22657
0
                state = ss_client_endofearlydata;
22658
0
                break;
22659
0
            case hello_retry_request:
22660
0
                state = ss_server_helloretryrequest;
22661
0
                break;
22662
0
            case encrypted_extensions:
22663
0
                state = ss_server_encryptedextensions;
22664
0
                break;
22665
0
            case certificate:
22666
0
                if (ssl->options.side == WOLFSSL_SERVER_END)
22667
0
                    state = ss_client_cert;
22668
0
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
22669
0
                    state = ss_server_cert;
22670
0
                else {
22671
0
                    WOLFSSL_MSG("Unknown State");
22672
0
                    state = ss_null_state;
22673
0
                }
22674
0
                break;
22675
0
            case server_key_exchange:
22676
0
                state = ss_server_keyexchange;
22677
0
                break;
22678
0
            case certificate_request:
22679
0
                state = ss_server_certrequest;
22680
0
                break;
22681
0
            case server_hello_done:
22682
0
                state = ss_server_hellodone;
22683
0
                break;
22684
0
            case certificate_verify:
22685
0
                state = ss_client_certverify;
22686
0
                break;
22687
0
            case client_key_exchange:
22688
0
                state = ss_client_keyexchange;
22689
0
                break;
22690
0
            case finished:
22691
0
                if (ssl->options.side == WOLFSSL_SERVER_END)
22692
0
                    state = ss_client_finished;
22693
0
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
22694
0
                    state = ss_server_finished;
22695
0
                else {
22696
0
                    WOLFSSL_MSG("Unknown State");
22697
0
                    state = ss_null_state;
22698
0
                }
22699
0
                break;
22700
0
            case certificate_status:
22701
0
                state = ss_server_certificatestatus;
22702
0
                break;
22703
0
            case key_update:
22704
0
                if (ssl->options.side == WOLFSSL_SERVER_END)
22705
0
                    state = ss_client_keyupdate;
22706
0
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
22707
0
                    state = ss_server_keyupdate;
22708
0
                else {
22709
0
                    WOLFSSL_MSG("Unknown State");
22710
0
                    state = ss_null_state;
22711
0
                }
22712
0
                break;
22713
0
            case change_cipher_hs:
22714
0
                if (ssl->options.side == WOLFSSL_SERVER_END)
22715
0
                    state = ss_client_changecipherspec;
22716
0
                else if (ssl->options.side == WOLFSSL_CLIENT_END)
22717
0
                    state = ss_server_changecipherspec;
22718
0
                else {
22719
0
                    WOLFSSL_MSG("Unknown State");
22720
0
                    state = ss_null_state;
22721
0
                }
22722
0
                break;
22723
0
            default:
22724
0
                WOLFSSL_MSG("Unknown State");
22725
0
                state = ss_null_state;
22726
0
        }
22727
0
    }
22728
0
    else {
22729
        /* Send process */
22730
0
        if (ssl->options.side == WOLFSSL_SERVER_END)
22731
0
            state = ssl->options.serverState;
22732
0
        else
22733
0
            state = ssl->options.clientState;
22734
22735
0
        switch (state) {
22736
0
            case SERVER_HELLOVERIFYREQUEST_COMPLETE:
22737
0
                state = ss_server_helloverify;
22738
0
                break;
22739
0
            case SERVER_HELLO_RETRY_REQUEST_COMPLETE:
22740
0
                state = ss_server_helloretryrequest;
22741
0
                break;
22742
0
            case SERVER_HELLO_COMPLETE:
22743
0
                state = ss_server_hello;
22744
0
                break;
22745
0
            case SERVER_ENCRYPTED_EXTENSIONS_COMPLETE:
22746
0
                state = ss_server_encryptedextensions;
22747
0
                break;
22748
0
            case SERVER_CERT_COMPLETE:
22749
0
                state = ss_server_cert;
22750
0
                break;
22751
0
            case SERVER_KEYEXCHANGE_COMPLETE:
22752
0
                state = ss_server_keyexchange;
22753
0
                break;
22754
0
            case SERVER_HELLODONE_COMPLETE:
22755
0
                state = ss_server_hellodone;
22756
0
                break;
22757
0
            case SERVER_CHANGECIPHERSPEC_COMPLETE:
22758
0
                state = ss_server_changecipherspec;
22759
0
                break;
22760
0
            case SERVER_FINISHED_COMPLETE:
22761
0
                state = ss_server_finished;
22762
0
                break;
22763
0
            case CLIENT_HELLO_RETRY:
22764
0
            case CLIENT_HELLO_COMPLETE:
22765
0
                state = ss_client_hello;
22766
0
                break;
22767
0
            case CLIENT_KEYEXCHANGE_COMPLETE:
22768
0
                state = ss_client_keyexchange;
22769
0
                break;
22770
0
            case CLIENT_CHANGECIPHERSPEC_COMPLETE:
22771
0
                state = ss_client_changecipherspec;
22772
0
                break;
22773
0
            case CLIENT_FINISHED_COMPLETE:
22774
0
                state = ss_client_finished;
22775
0
                break;
22776
0
            case HANDSHAKE_DONE:
22777
0
                state = ss_handshake_done;
22778
0
                break;
22779
0
            default:
22780
0
                WOLFSSL_MSG("Unknown State");
22781
0
                state = ss_null_state;
22782
0
        }
22783
0
    }
22784
22785
0
    if (protocol == UNKNOWN) {
22786
0
        WOLFSSL_MSG("Unknown protocol");
22787
0
        return "";
22788
0
    }
22789
0
    else {
22790
0
        return OUTPUT_STR[state][protocol][cbmode];
22791
0
    }
22792
0
}
22793
22794
/*
22795
 * Sets default PEM callback password if null is passed into
22796
 * the callback parameter of a PEM_read_bio_* function.
22797
 *
22798
 * Returns callback phrase size on success or WOLFSSL_FAILURE otherwise.
22799
 */
22800
int wolfSSL_PEM_def_callback(char* name, int num, int w, void* key)
22801
0
{
22802
0
    int sz;
22803
0
    (void)w;
22804
0
    WOLFSSL_ENTER("wolfSSL_PEM_def_callback");
22805
22806
    /* We assume that the user passes a default password as userdata */
22807
0
    if (key) {
22808
0
        sz = (int)XSTRLEN((const char*)key);
22809
0
        sz = (sz > num) ? num : sz;
22810
0
        XMEMCPY(name, key, sz);
22811
0
        return sz;
22812
0
    } else {
22813
0
        WOLFSSL_MSG("Error, default password cannot be created.");
22814
0
        return WOLFSSL_FAILURE;
22815
0
    }
22816
0
}
22817
22818
#endif /* OPENSSL_EXTRA */
22819
22820
static long wolf_set_options(long old_op, long op)
22821
0
{
22822
    /* if SSL_OP_ALL then turn all bug workarounds on */
22823
0
    if ((op & WOLFSSL_OP_ALL) == WOLFSSL_OP_ALL) {
22824
0
        WOLFSSL_MSG("\tSSL_OP_ALL");
22825
0
    }
22826
22827
    /* by default cookie exchange is on with DTLS */
22828
0
    if ((op & WOLFSSL_OP_COOKIE_EXCHANGE) == WOLFSSL_OP_COOKIE_EXCHANGE) {
22829
0
        WOLFSSL_MSG("\tSSL_OP_COOKIE_EXCHANGE : on by default");
22830
0
    }
22831
22832
0
    if ((op & WOLFSSL_OP_NO_SSLv2) == WOLFSSL_OP_NO_SSLv2) {
22833
0
        WOLFSSL_MSG("\tWOLFSSL_OP_NO_SSLv2 : wolfSSL does not support SSLv2");
22834
0
    }
22835
22836
0
#ifdef SSL_OP_NO_TLSv1_3
22837
0
    if ((op & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
22838
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_3");
22839
0
    }
22840
0
#endif
22841
22842
0
    if ((op & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
22843
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_2");
22844
0
    }
22845
22846
0
    if ((op & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
22847
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1_1");
22848
0
    }
22849
22850
0
    if ((op & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
22851
0
        WOLFSSL_MSG("\tSSL_OP_NO_TLSv1");
22852
0
    }
22853
22854
0
    if ((op & WOLFSSL_OP_NO_SSLv3) == WOLFSSL_OP_NO_SSLv3) {
22855
0
        WOLFSSL_MSG("\tSSL_OP_NO_SSLv3");
22856
0
    }
22857
22858
0
    if ((op & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) ==
22859
0
            WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
22860
0
        WOLFSSL_MSG("\tWOLFSSL_OP_CIPHER_SERVER_PREFERENCE");
22861
0
    }
22862
22863
0
    if ((op & WOLFSSL_OP_NO_COMPRESSION) == WOLFSSL_OP_NO_COMPRESSION) {
22864
    #ifdef HAVE_LIBZ
22865
        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION");
22866
    #else
22867
0
        WOLFSSL_MSG("SSL_OP_NO_COMPRESSION: compression not compiled in");
22868
0
    #endif
22869
0
    }
22870
22871
0
    return old_op | op;
22872
0
}
22873
22874
long wolfSSL_set_options(WOLFSSL* ssl, long op)
22875
0
{
22876
0
    word16 haveRSA = 1;
22877
0
    word16 havePSK = 0;
22878
0
    int    keySz   = 0;
22879
22880
0
    WOLFSSL_ENTER("wolfSSL_set_options");
22881
22882
0
    if (ssl == NULL) {
22883
0
        return 0;
22884
0
    }
22885
22886
0
    ssl->options.mask = wolf_set_options(ssl->options.mask, op);
22887
22888
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3) == WOLFSSL_OP_NO_TLSv1_3) {
22889
0
        if (ssl->version.minor == TLSv1_3_MINOR)
22890
0
            ssl->version.minor = TLSv1_2_MINOR;
22891
0
    }
22892
22893
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2) == WOLFSSL_OP_NO_TLSv1_2) {
22894
0
        if (ssl->version.minor == TLSv1_2_MINOR)
22895
0
            ssl->version.minor = TLSv1_1_MINOR;
22896
0
    }
22897
22898
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1) == WOLFSSL_OP_NO_TLSv1_1) {
22899
0
        if (ssl->version.minor == TLSv1_1_MINOR)
22900
0
            ssl->version.minor = TLSv1_MINOR;
22901
0
    }
22902
22903
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_TLSv1) == WOLFSSL_OP_NO_TLSv1) {
22904
0
        if (ssl->version.minor == TLSv1_MINOR)
22905
0
            ssl->version.minor = SSLv3_MINOR;
22906
0
    }
22907
22908
0
    if ((ssl->options.mask & WOLFSSL_OP_NO_COMPRESSION)
22909
0
        == WOLFSSL_OP_NO_COMPRESSION) {
22910
    #ifdef HAVE_LIBZ
22911
        ssl->options.usingCompression = 0;
22912
    #endif
22913
0
    }
22914
22915
    /* in the case of a version change the cipher suites should be reset */
22916
#ifndef NO_PSK
22917
    havePSK = ssl->options.havePSK;
22918
#endif
22919
#ifdef NO_RSA
22920
    haveRSA = 0;
22921
#endif
22922
0
#ifndef NO_CERTS
22923
0
    keySz = ssl->buffers.keySz;
22924
0
#endif
22925
22926
0
    if (ssl->suites != NULL && ssl->options.side != WOLFSSL_NEITHER_END)
22927
0
        InitSuites(ssl->suites, ssl->version, keySz, haveRSA, havePSK,
22928
0
                   ssl->options.haveDH, ssl->options.haveECDSAsig,
22929
0
                   ssl->options.haveECC, TRUE, ssl->options.haveStaticECC,
22930
0
                   ssl->options.haveFalconSig, ssl->options.haveDilithiumSig,
22931
0
                   ssl->options.haveAnon, TRUE, ssl->options.side);
22932
22933
0
    return ssl->options.mask;
22934
0
}
22935
22936
22937
long wolfSSL_get_options(const WOLFSSL* ssl)
22938
0
{
22939
0
    WOLFSSL_ENTER("wolfSSL_get_options");
22940
0
    if(ssl == NULL)
22941
0
        return WOLFSSL_FAILURE;
22942
0
    return ssl->options.mask;
22943
0
}
22944
22945
#if defined(HAVE_SECURE_RENEGOTIATION) \
22946
        || defined(HAVE_SERVER_RENEGOTIATION_INFO)
22947
/* clears the counter for number of renegotiations done
22948
 * returns the current count before it is cleared */
22949
long wolfSSL_clear_num_renegotiations(WOLFSSL *s)
22950
0
{
22951
0
    long total;
22952
22953
0
    WOLFSSL_ENTER("wolfSSL_clear_num_renegotiations");
22954
0
    if (s == NULL)
22955
0
        return 0;
22956
22957
0
    total = s->secure_rene_count;
22958
0
    s->secure_rene_count = 0;
22959
0
    return total;
22960
0
}
22961
22962
22963
/* return the number of renegotiations since wolfSSL_new */
22964
long wolfSSL_total_renegotiations(WOLFSSL *s)
22965
0
{
22966
0
    WOLFSSL_ENTER("wolfSSL_total_renegotiations");
22967
0
    return wolfSSL_num_renegotiations(s);
22968
0
}
22969
22970
22971
/* return the number of renegotiations since wolfSSL_new */
22972
long wolfSSL_num_renegotiations(WOLFSSL* s)
22973
0
{
22974
0
    if (s == NULL) {
22975
0
        return 0;
22976
0
    }
22977
22978
0
    return s->secure_rene_count;
22979
0
}
22980
22981
22982
/* Is there a renegotiation currently in progress? */
22983
int  wolfSSL_SSL_renegotiate_pending(WOLFSSL *s)
22984
0
{
22985
0
    return s && s->options.handShakeDone &&
22986
0
            s->options.handShakeState != HANDSHAKE_DONE ? 1 : 0;
22987
0
}
22988
#endif /* HAVE_SECURE_RENEGOTIATION || HAVE_SERVER_RENEGOTIATION_INFO */
22989
22990
#ifdef OPENSSL_EXTRA
22991
22992
long wolfSSL_clear_options(WOLFSSL* ssl, long opt)
22993
0
{
22994
0
    WOLFSSL_ENTER("SSL_clear_options");
22995
0
    if(ssl == NULL)
22996
0
        return WOLFSSL_FAILURE;
22997
0
    ssl->options.mask &= ~opt;
22998
0
    return ssl->options.mask;
22999
0
}
23000
23001
#ifdef HAVE_PK_CALLBACKS
23002
long wolfSSL_set_tlsext_debug_arg(WOLFSSL* ssl, void *arg)
23003
{
23004
    if (ssl == NULL) {
23005
        return WOLFSSL_FAILURE;
23006
    }
23007
23008
    ssl->loggingCtx = arg;
23009
    return WOLFSSL_SUCCESS;
23010
}
23011
#endif /* HAVE_PK_CALLBACKS */
23012
23013
#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
23014
const unsigned char *SSL_SESSION_get0_id_context(const WOLFSSL_SESSION *sess, unsigned int *sid_ctx_length)
23015
0
{
23016
0
    sess = ClientSessionToSession(sess);
23017
0
    return wolfSSL_SESSION_get_id((WOLFSSL_SESSION *)sess, sid_ctx_length);
23018
0
}
23019
#endif
23020
23021
/*** TBD ***/
23022
#ifndef NO_WOLFSSL_STUB
23023
WOLFSSL_API int wolfSSL_sk_SSL_COMP_zero(WOLFSSL_STACK* st)
23024
0
{
23025
0
    (void)st;
23026
0
    WOLFSSL_STUB("wolfSSL_sk_SSL_COMP_zero");
23027
    /* wolfSSL_set_options(ssl, SSL_OP_NO_COMPRESSION); */
23028
0
    return WOLFSSL_FAILURE;
23029
0
}
23030
#endif
23031
23032
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
23033
long wolfSSL_set_tlsext_status_type(WOLFSSL *s, int type)
23034
{
23035
    WOLFSSL_ENTER("wolfSSL_set_tlsext_status_type");
23036
23037
    if (s == NULL){
23038
        return BAD_FUNC_ARG;
23039
    }
23040
23041
    if (type == TLSEXT_STATUSTYPE_ocsp){
23042
        int r = TLSX_UseCertificateStatusRequest(&s->extensions, (byte)type, 0, s,
23043
                                                             s->heap, s->devId);
23044
        return (long)r;
23045
    } else {
23046
        WOLFSSL_MSG(
23047
       "SSL_set_tlsext_status_type only supports TLSEXT_STATUSTYPE_ocsp type.");
23048
        return SSL_FAILURE;
23049
    }
23050
23051
}
23052
23053
long wolfSSL_get_tlsext_status_type(WOLFSSL *s)
23054
{
23055
    TLSX* extension;
23056
23057
    if (s == NULL)
23058
        return WOLFSSL_FATAL_ERROR;
23059
    extension = TLSX_Find(s->extensions, TLSX_STATUS_REQUEST);
23060
    return extension != NULL ? TLSEXT_STATUSTYPE_ocsp : WOLFSSL_FATAL_ERROR;
23061
}
23062
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
23063
23064
#ifndef NO_WOLFSSL_STUB
23065
WOLFSSL_API long wolfSSL_get_tlsext_status_exts(WOLFSSL *s, void *arg)
23066
0
{
23067
0
    (void)s;
23068
0
    (void)arg;
23069
0
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_exts");
23070
0
    return WOLFSSL_FAILURE;
23071
0
}
23072
#endif
23073
23074
/*** TBD ***/
23075
#ifndef NO_WOLFSSL_STUB
23076
WOLFSSL_API long wolfSSL_set_tlsext_status_exts(WOLFSSL *s, void *arg)
23077
0
{
23078
0
    (void)s;
23079
0
    (void)arg;
23080
0
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_exts");
23081
0
    return WOLFSSL_FAILURE;
23082
0
}
23083
#endif
23084
23085
/*** TBD ***/
23086
#ifndef NO_WOLFSSL_STUB
23087
WOLFSSL_API long wolfSSL_get_tlsext_status_ids(WOLFSSL *s, void *arg)
23088
0
{
23089
0
    (void)s;
23090
0
    (void)arg;
23091
0
    WOLFSSL_STUB("wolfSSL_get_tlsext_status_ids");
23092
0
    return WOLFSSL_FAILURE;
23093
0
}
23094
#endif
23095
23096
/*** TBD ***/
23097
#ifndef NO_WOLFSSL_STUB
23098
WOLFSSL_API long wolfSSL_set_tlsext_status_ids(WOLFSSL *s, void *arg)
23099
0
{
23100
0
    (void)s;
23101
0
    (void)arg;
23102
0
    WOLFSSL_STUB("wolfSSL_set_tlsext_status_ids");
23103
0
    return WOLFSSL_FAILURE;
23104
0
}
23105
#endif
23106
23107
/*** TBD ***/
23108
#ifndef NO_WOLFSSL_STUB
23109
WOLFSSL_API int SSL_SESSION_set1_id(WOLFSSL_SESSION *s, const unsigned char *sid, unsigned int sid_len)
23110
0
{
23111
0
    (void)s;
23112
0
    (void)sid;
23113
0
    (void)sid_len;
23114
0
    WOLFSSL_STUB("SSL_SESSION_set1_id");
23115
0
    return WOLFSSL_FAILURE;
23116
0
}
23117
#endif
23118
23119
#ifndef NO_WOLFSSL_STUB
23120
/*** TBD ***/
23121
WOLFSSL_API int SSL_SESSION_set1_id_context(WOLFSSL_SESSION *s, const unsigned char *sid_ctx, unsigned int sid_ctx_len)
23122
0
{
23123
0
    (void)s;
23124
0
    (void)sid_ctx;
23125
0
    (void)sid_ctx_len;
23126
0
    WOLFSSL_STUB("SSL_SESSION_set1_id_context");
23127
0
    return WOLFSSL_FAILURE;
23128
0
}
23129
#endif
23130
23131
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
23132
    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
23133
/**
23134
 * Set `a` in a smart way.
23135
 *
23136
 * @param a Object to set
23137
 * @param type The type of object in value
23138
 * @param value Object to set
23139
 */
23140
void wolfSSL_ASN1_TYPE_set(WOLFSSL_ASN1_TYPE *a, int type, void *value)
23141
0
{
23142
0
    if (!a) {
23143
0
        return;
23144
0
    }
23145
0
    switch (type) {
23146
0
        case V_ASN1_NULL:
23147
0
            a->value.ptr = (char *)value;
23148
0
            break;
23149
0
        case V_ASN1_SEQUENCE:
23150
0
            a->value.asn1_string = (WOLFSSL_ASN1_STRING*)value;
23151
0
            break;
23152
0
        case V_ASN1_OBJECT:
23153
0
            a->value.object = (WOLFSSL_ASN1_OBJECT*)value;
23154
0
            break;
23155
0
        case V_ASN1_UTCTIME:
23156
0
            a->value.utctime = (WOLFSSL_ASN1_TIME*)value;
23157
0
            break;
23158
0
        case V_ASN1_GENERALIZEDTIME:
23159
0
            a->value.generalizedtime = (WOLFSSL_ASN1_TIME*)value;
23160
0
            break;
23161
0
        default:
23162
0
            WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
23163
0
            return;
23164
0
    }
23165
0
    a->type = type;
23166
0
}
23167
23168
#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY || WOLFSSL_WPAS */
23169
23170
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
23171
    || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS) \
23172
    || defined(OPENSSL_EXTRA)
23173
/**
23174
 * Allocate a new WOLFSSL_ASN1_TYPE object.
23175
 *
23176
 * @return New zero'ed WOLFSSL_ASN1_TYPE object
23177
 */
23178
WOLFSSL_ASN1_TYPE* wolfSSL_ASN1_TYPE_new(void)
23179
0
{
23180
0
    WOLFSSL_ASN1_TYPE* ret = (WOLFSSL_ASN1_TYPE*)XMALLOC(sizeof(WOLFSSL_ASN1_TYPE),
23181
0
                                                        NULL, DYNAMIC_TYPE_OPENSSL);
23182
0
    if (!ret)
23183
0
        return NULL;
23184
0
    XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TYPE));
23185
0
    return ret;
23186
0
}
23187
23188
/**
23189
 * Free WOLFSSL_ASN1_TYPE and all its members.
23190
 *
23191
 * @param at Object to free
23192
 */
23193
void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at)
23194
0
{
23195
0
    if (at) {
23196
0
        switch (at->type) {
23197
0
            case V_ASN1_OBJECT:
23198
0
                wolfSSL_ASN1_OBJECT_free(at->value.object);
23199
0
                break;
23200
0
            case V_ASN1_UTCTIME:
23201
0
            #ifndef NO_ASN_TIME
23202
0
                wolfSSL_ASN1_TIME_free(at->value.utctime);
23203
0
            #endif
23204
0
                break;
23205
0
            case V_ASN1_GENERALIZEDTIME:
23206
0
            #ifndef NO_ASN_TIME
23207
0
                wolfSSL_ASN1_TIME_free(at->value.generalizedtime);
23208
0
            #endif
23209
0
                break;
23210
0
            case V_ASN1_UTF8STRING:
23211
0
            case V_ASN1_PRINTABLESTRING:
23212
0
            case V_ASN1_T61STRING:
23213
0
            case V_ASN1_IA5STRING:
23214
0
            case V_ASN1_UNIVERSALSTRING:
23215
0
            case V_ASN1_SEQUENCE:
23216
0
                wolfSSL_ASN1_STRING_free(at->value.asn1_string);
23217
0
                break;
23218
0
            default:
23219
0
                WOLFSSL_MSG("Unknown or unsupported ASN1_TYPE");
23220
0
                break;
23221
0
        }
23222
0
        XFREE(at, NULL, DYNAMIC_TYPE_OPENSSL);
23223
0
    }
23224
0
}
23225
#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY || WOLFSSL_WPAS
23226
        || OPENSSL_EXTRA */
23227
23228
23229
23230
#ifndef NO_WOLFSSL_STUB
23231
/*** TBD ***/
23232
WOLFSSL_API WOLFSSL_EVP_PKEY *wolfSSL_get_privatekey(const WOLFSSL *ssl)
23233
0
{
23234
0
    (void)ssl;
23235
0
    WOLFSSL_STUB("SSL_get_privatekey");
23236
0
    return NULL;
23237
0
}
23238
#endif
23239
23240
/**
23241
 * Get a textual representation of given WOLFSSL_ASN1_OBJECT then write it to
23242
 * buf at most buf_len bytes.
23243
 *
23244
 * params
23245
 * - buf: buffer where the textual representation is to be written to
23246
 * - buf_len: buffer size in bytes
23247
 * - a: WOLFSSL_ASN1_OBJECT
23248
 *
23249
 * return the string length written on success, WOLFSSL_FAILURE on failure.
23250
 */
23251
WOLFSSL_API int wolfSSL_i2t_ASN1_OBJECT(char *buf, int buf_len,
23252
                                                WOLFSSL_ASN1_OBJECT *a)
23253
0
{
23254
0
    WOLFSSL_ENTER("wolfSSL_i2t_ASN1_OBJECT");
23255
0
    return wolfSSL_OBJ_obj2txt(buf, buf_len, a, 0);
23256
0
}
23257
23258
WOLFSSL_ASN1_OBJECT *wolfSSL_d2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
23259
                                             const unsigned char **der,
23260
                                             long length)
23261
0
{
23262
0
    const unsigned char *d;
23263
0
    long len;
23264
0
    int tag, cls;
23265
0
    WOLFSSL_ASN1_OBJECT* ret = NULL;
23266
23267
0
    WOLFSSL_ENTER("wolfSSL_d2i_ASN1_OBJECT");
23268
23269
0
    if (!der || !*der || length <= 0) {
23270
0
        WOLFSSL_MSG("Bad parameter");
23271
0
        return NULL;
23272
0
    }
23273
23274
0
    d = *der;
23275
23276
0
    if (wolfSSL_ASN1_get_object(&d, &len, &tag, &cls, length) & 0x80) {
23277
0
        WOLFSSL_MSG("wolfSSL_ASN1_get_object error");
23278
0
        return NULL;
23279
0
    }
23280
    /* d now points to value */
23281
23282
0
    if (tag != ASN_OBJECT_ID) {
23283
0
        WOLFSSL_MSG("Not an ASN object");
23284
0
        return NULL;
23285
0
    }
23286
23287
0
    ret = wolfSSL_c2i_ASN1_OBJECT(a, &d, len);
23288
0
    if (ret)
23289
0
        *der = d;
23290
0
    return ret;
23291
0
}
23292
23293
/**
23294
 * Parse an ASN1 encoded input and output information about the parsed object
23295
 * @param in    ASN1 encoded data. *in is moved to the value of the ASN1 object
23296
 * @param len   Length of parsed ASN1 object
23297
 * @param tag   Tag value of parsed ASN1 object
23298
 * @param cls   Class of parsed ASN1 object
23299
 * @param inLen Length of *in buffer
23300
 * @return int  Depends on which bits are set in the returned int:
23301
 *              0x80 an error occurred during parsing
23302
 *              0x20 parsed object is constructed
23303
 *              0x01 the parsed object length is infinite
23304
 */
23305
int wolfSSL_ASN1_get_object(const unsigned char **in, long *len, int *tag,
23306
                            int *cls, long inLen)
23307
0
{
23308
0
    word32 inOutIdx = 0;
23309
0
    int l;
23310
0
    byte t;
23311
0
    int ret = 0x80;
23312
23313
0
    WOLFSSL_ENTER("wolfSSL_ASN1_get_object");
23314
23315
0
    if (!in || !*in || !len || !tag || !cls || inLen == 0) {
23316
0
        WOLFSSL_MSG("Bad parameter");
23317
0
        return ret;
23318
0
    }
23319
23320
0
    if (GetASNTag(*in, &inOutIdx, &t, (word32)inLen) != 0) {
23321
0
        WOLFSSL_MSG("GetASNTag error");
23322
0
        return ret;
23323
0
    }
23324
23325
0
    if (GetLength(*in, &inOutIdx, &l, (word32)inLen) < 0) {
23326
0
        WOLFSSL_MSG("GetLength error");
23327
0
        return ret;
23328
0
    }
23329
23330
0
    *tag = t & 0x1F; /* Tag number is 5 lsb */
23331
0
    *cls = t & 0xC0; /* Class is 2 msb */
23332
0
    *len = l;
23333
0
    ret = t & ASN_CONSTRUCTED;
23334
23335
0
    if (l > (int)(inLen - inOutIdx)) {
23336
        /* Still return other values but indicate error in msb */
23337
0
        ret |= 0x80;
23338
0
    }
23339
23340
0
    *in += inOutIdx;
23341
0
    return ret;
23342
0
}
23343
23344
WOLFSSL_ASN1_OBJECT *wolfSSL_c2i_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT **a,
23345
        const unsigned char **pp, long len)
23346
0
{
23347
0
    WOLFSSL_ASN1_OBJECT* ret = NULL;
23348
23349
0
    WOLFSSL_ENTER("wolfSSL_c2i_ASN1_OBJECT");
23350
23351
0
    if (!pp || !*pp || len <= 0) {
23352
0
        WOLFSSL_MSG("Bad parameter");
23353
0
        return NULL;
23354
0
    }
23355
23356
0
    if (!(ret = wolfSSL_ASN1_OBJECT_new())) {
23357
0
        WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_new error");
23358
0
        return NULL;
23359
0
    }
23360
23361
0
    ret->obj = (const unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
23362
0
    if (!ret->obj) {
23363
0
        WOLFSSL_MSG("error allocating asn data memory");
23364
0
        wolfSSL_ASN1_OBJECT_free(ret);
23365
0
        return NULL;
23366
0
    }
23367
23368
0
    XMEMCPY((byte*)ret->obj, *pp, len);
23369
0
    ret->objSz = (unsigned int)len;
23370
0
    ret->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA;
23371
23372
0
    *pp += len;
23373
23374
0
    if (a)
23375
0
        *a = ret;
23376
0
    return ret;
23377
0
}
23378
23379
#ifndef NO_BIO
23380
/* Return number of bytes written to BIO on success. 0 on failure. */
23381
WOLFSSL_API int wolfSSL_i2a_ASN1_OBJECT(WOLFSSL_BIO *bp,
23382
                                        WOLFSSL_ASN1_OBJECT *a)
23383
0
{
23384
0
    int length = 0;
23385
0
    word32 idx = 0;
23386
0
    const char null_str[] = "NULL";
23387
23388
0
    WOLFSSL_ENTER("wolfSSL_i2a_ASN1_OBJECT");
23389
23390
0
    if (bp == NULL)
23391
0
        return WOLFSSL_FAILURE;
23392
23393
0
    if (a == NULL) {
23394
        /* Write "NULL" */
23395
0
        if (wolfSSL_BIO_write(bp, null_str, (int)XSTRLEN(null_str)) ==
23396
0
                (int)XSTRLEN(null_str)) {
23397
0
            return (int)XSTRLEN(null_str);
23398
0
        }
23399
0
        else {
23400
0
            return WOLFSSL_FAILURE;
23401
0
        }
23402
0
    }
23403
23404
23405
0
    if ((a->obj == NULL) || (a->obj[idx++] != ASN_OBJECT_ID)) {
23406
0
        WOLFSSL_MSG("Bad ASN1 Object");
23407
0
        return WOLFSSL_FAILURE;
23408
0
    }
23409
23410
0
    if (GetLength((const byte*)a->obj, &idx, &length,
23411
0
                   a->objSz) < 0 || length < 0) {
23412
0
        return WOLFSSL_FAILURE;
23413
0
    }
23414
23415
0
    if (wolfSSL_BIO_write(bp, a->obj + idx, length) == (int)length) {
23416
0
        return length;
23417
0
    }
23418
23419
0
    return WOLFSSL_FAILURE;
23420
0
}
23421
#endif /* !NO_BIO */
23422
23423
/* Returns object data for an ASN1_OBJECT */
23424
/* If pp is NULL then only the size is returned */
23425
/* If pp has pointer to pointer then its used directly */
23426
/* If pp has pointer to pointer that is NULL then new variable is allocated */
23427
/* Failure returns WOLFSSL_FAILURE (0) */
23428
int wolfSSL_i2d_ASN1_OBJECT(WOLFSSL_ASN1_OBJECT *a, unsigned char **pp)
23429
0
{
23430
0
    byte *p;
23431
23432
0
    WOLFSSL_ENTER("wolfSSL_i2d_ASN1_OBJECT");
23433
23434
0
    if (!a || !a->obj) {
23435
0
        WOLFSSL_MSG("Bad parameters");
23436
0
        return WOLFSSL_FAILURE;
23437
0
    }
23438
23439
0
    if (!pp)
23440
0
        return a->objSz;
23441
23442
0
    if (*pp)
23443
0
        p = *pp;
23444
0
    else {
23445
0
        p = (byte*)XMALLOC(a->objSz, NULL, DYNAMIC_TYPE_OPENSSL);
23446
0
        if (!p) {
23447
0
            WOLFSSL_MSG("Bad malloc");
23448
0
            return WOLFSSL_FAILURE;
23449
0
        }
23450
0
    }
23451
23452
0
    XMEMCPY(p, a->obj, a->objSz);
23453
0
    *pp = p + a->objSz;
23454
0
    return a->objSz;
23455
0
}
23456
23457
#ifndef NO_WOLFSSL_STUB
23458
/*** TBD ***/
23459
WOLFSSL_API void SSL_CTX_set_tmp_dh_callback(WOLFSSL_CTX *ctx, WOLFSSL_DH *(*dh) (WOLFSSL *ssl, int is_export, int keylength))
23460
0
{
23461
0
    (void)ctx;
23462
0
    (void)dh;
23463
0
    WOLFSSL_STUB("SSL_CTX_set_tmp_dh_callback");
23464
0
}
23465
#endif
23466
23467
#ifndef NO_WOLFSSL_STUB
23468
/*** TBD ***/
23469
WOLFSSL_API WOLF_STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
23470
0
{
23471
0
    WOLFSSL_STUB("SSL_COMP_get_compression_methods");
23472
0
    return NULL;
23473
0
}
23474
#endif
23475
23476
23477
int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p)
23478
0
{
23479
0
    WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_num");
23480
0
    if (p == NULL) {
23481
0
        return WOLFSSL_FATAL_ERROR;
23482
0
    }
23483
0
    return (int)p->num;
23484
0
}
23485
23486
WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_sk_SSL_CIPHER_value(WOLFSSL_STACK* sk, int i)
23487
0
{
23488
0
    WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_value");
23489
0
    return (WOLFSSL_CIPHER*)wolfSSL_sk_value(sk, i);
23490
0
}
23491
23492
#if !defined(NETOS)
23493
WOLFSSL_API void ERR_load_SSL_strings(void)
23494
0
{
23495
23496
0
}
23497
#endif
23498
23499
#ifdef HAVE_OCSP
23500
WOLFSSL_API long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp)
23501
0
{
23502
0
    if (s == NULL || resp == NULL)
23503
0
        return 0;
23504
23505
0
    *resp = s->ocspResp;
23506
0
    return s->ocspRespSz;
23507
0
}
23508
23509
WOLFSSL_API long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, int len)
23510
0
{
23511
0
    if (s == NULL)
23512
0
        return WOLFSSL_FAILURE;
23513
23514
0
    s->ocspResp   = resp;
23515
0
    s->ocspRespSz = len;
23516
23517
0
    return WOLFSSL_SUCCESS;
23518
0
}
23519
#endif /* HAVE_OCSP */
23520
23521
#ifdef HAVE_MAX_FRAGMENT
23522
#ifndef NO_WOLFSSL_CLIENT
23523
/**
23524
 * Set max fragment tls extension
23525
 * @param c a pointer to WOLFSSL_CTX object
23526
 * @param mode maximum fragment length mode
23527
 * @return 1 on success, otherwise 0 or negative error code
23528
 */
23529
WOLFSSL_API int wolfSSL_CTX_set_tlsext_max_fragment_length(WOLFSSL_CTX *c,
23530
                                                            unsigned char mode)
23531
{
23532
    if (c == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
23533
        return BAD_FUNC_ARG;
23534
23535
    return wolfSSL_CTX_UseMaxFragment(c, mode);
23536
}
23537
/**
23538
 * Set max fragment tls extension
23539
 * @param c a pointer to WOLFSSL object
23540
 * @param mode maximum fragment length mode
23541
 * @return 1 on success, otherwise 0 or negative error code
23542
 */
23543
WOLFSSL_API int wolfSSL_set_tlsext_max_fragment_length(WOLFSSL *s,
23544
                                                            unsigned char mode)
23545
{
23546
    if (s == NULL || (mode < WOLFSSL_MFL_2_9 || mode > WOLFSSL_MFL_2_12 ))
23547
        return BAD_FUNC_ARG;
23548
23549
    return wolfSSL_UseMaxFragment(s, mode);
23550
}
23551
#endif /* NO_WOLFSSL_CLIENT */
23552
#endif /* HAVE_MAX_FRAGMENT */
23553
23554
#endif /* OPENSSL_EXTRA */
23555
23556
#ifdef WOLFSSL_HAVE_TLS_UNIQUE
23557
WOLFSSL_API size_t wolfSSL_get_finished(const WOLFSSL *ssl, void *buf, size_t count)
23558
0
{
23559
0
    byte len = 0;
23560
23561
0
    WOLFSSL_ENTER("SSL_get_finished");
23562
23563
0
    if (!ssl || !buf || count < TLS_FINISHED_SZ) {
23564
0
        WOLFSSL_MSG("Bad parameter");
23565
0
        return WOLFSSL_FAILURE;
23566
0
    }
23567
23568
0
    if (ssl->options.side == WOLFSSL_SERVER_END) {
23569
0
        len = ssl->serverFinished_len;
23570
0
        XMEMCPY(buf, ssl->serverFinished, len);
23571
0
    }
23572
0
    else {
23573
0
        len = ssl->clientFinished_len;
23574
0
        XMEMCPY(buf, ssl->clientFinished, len);
23575
0
    }
23576
0
    return len;
23577
0
}
23578
23579
WOLFSSL_API size_t wolfSSL_get_peer_finished(const WOLFSSL *ssl, void *buf, size_t count)
23580
0
{
23581
0
    byte len = 0;
23582
0
    WOLFSSL_ENTER("SSL_get_peer_finished");
23583
23584
0
    if (!ssl || !buf || count < TLS_FINISHED_SZ) {
23585
0
        WOLFSSL_MSG("Bad parameter");
23586
0
        return WOLFSSL_FAILURE;
23587
0
    }
23588
23589
0
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
23590
0
        len = ssl->serverFinished_len;
23591
0
        XMEMCPY(buf, ssl->serverFinished, len);
23592
0
    }
23593
0
    else {
23594
0
        len = ssl->clientFinished_len;
23595
0
        XMEMCPY(buf, ssl->clientFinished, len);
23596
0
    }
23597
23598
0
    return len;
23599
0
}
23600
#endif /* WOLFSSL_HAVE_TLS_UNIQUE */
23601
23602
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
23603
long wolfSSL_get_verify_result(const WOLFSSL *ssl)
23604
0
{
23605
0
    if (ssl == NULL) {
23606
0
        return WOLFSSL_FAILURE;
23607
0
    }
23608
23609
0
    return ssl->peerVerifyRet;
23610
0
}
23611
#endif
23612
23613
#ifdef OPENSSL_EXTRA
23614
23615
#ifndef NO_WOLFSSL_STUB
23616
/* shows the number of accepts attempted by CTX in it's lifetime */
23617
long wolfSSL_CTX_sess_accept(WOLFSSL_CTX* ctx)
23618
0
{
23619
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept");
23620
0
    (void)ctx;
23621
0
    return 0;
23622
0
}
23623
#endif
23624
23625
#ifndef NO_WOLFSSL_STUB
23626
/* shows the number of connects attempted CTX in it's lifetime */
23627
long wolfSSL_CTX_sess_connect(WOLFSSL_CTX* ctx)
23628
0
{
23629
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect");
23630
0
    (void)ctx;
23631
0
    return 0;
23632
0
}
23633
#endif
23634
23635
23636
#ifndef NO_WOLFSSL_STUB
23637
/* shows the number of accepts completed by CTX in it's lifetime */
23638
long wolfSSL_CTX_sess_accept_good(WOLFSSL_CTX* ctx)
23639
0
{
23640
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_good");
23641
0
    (void)ctx;
23642
0
    return 0;
23643
0
}
23644
#endif
23645
23646
23647
#ifndef NO_WOLFSSL_STUB
23648
/* shows the number of connects completed by CTX in it's lifetime */
23649
long wolfSSL_CTX_sess_connect_good(WOLFSSL_CTX* ctx)
23650
0
{
23651
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_good");
23652
0
    (void)ctx;
23653
0
    return 0;
23654
0
}
23655
#endif
23656
23657
23658
#ifndef NO_WOLFSSL_STUB
23659
/* shows the number of renegotiation accepts attempted by CTX */
23660
long wolfSSL_CTX_sess_accept_renegotiate(WOLFSSL_CTX* ctx)
23661
0
{
23662
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_accept_renegotiate");
23663
0
    (void)ctx;
23664
0
    return 0;
23665
0
}
23666
#endif
23667
23668
23669
#ifndef NO_WOLFSSL_STUB
23670
/* shows the number of renegotiation accepts attempted by CTX */
23671
long wolfSSL_CTX_sess_connect_renegotiate(WOLFSSL_CTX* ctx)
23672
0
{
23673
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_connect_renegotiate");
23674
0
    (void)ctx;
23675
0
    return 0;
23676
0
}
23677
#endif
23678
23679
23680
#ifndef NO_WOLFSSL_STUB
23681
long wolfSSL_CTX_sess_hits(WOLFSSL_CTX* ctx)
23682
0
{
23683
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_hits");
23684
0
    (void)ctx;
23685
0
    return 0;
23686
0
}
23687
#endif
23688
23689
23690
#ifndef NO_WOLFSSL_STUB
23691
long wolfSSL_CTX_sess_cb_hits(WOLFSSL_CTX* ctx)
23692
0
{
23693
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_cb_hits");
23694
0
    (void)ctx;
23695
0
    return 0;
23696
0
}
23697
#endif
23698
23699
23700
#ifndef NO_WOLFSSL_STUB
23701
long wolfSSL_CTX_sess_cache_full(WOLFSSL_CTX* ctx)
23702
0
{
23703
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_cache_full");
23704
0
    (void)ctx;
23705
0
    return 0;
23706
0
}
23707
#endif
23708
23709
23710
#ifndef NO_WOLFSSL_STUB
23711
long wolfSSL_CTX_sess_misses(WOLFSSL_CTX* ctx)
23712
0
{
23713
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_misses");
23714
0
    (void)ctx;
23715
0
    return 0;
23716
0
}
23717
#endif
23718
23719
23720
#ifndef NO_WOLFSSL_STUB
23721
long wolfSSL_CTX_sess_timeouts(WOLFSSL_CTX* ctx)
23722
0
{
23723
0
    WOLFSSL_STUB("wolfSSL_CTX_sess_timeouts");
23724
0
    (void)ctx;
23725
0
    return 0;
23726
0
}
23727
#endif
23728
23729
23730
/* Return the total number of sessions */
23731
long wolfSSL_CTX_sess_number(WOLFSSL_CTX* ctx)
23732
0
{
23733
0
    word32 total = 0;
23734
23735
0
    WOLFSSL_ENTER("wolfSSL_CTX_sess_number");
23736
0
    (void)ctx;
23737
23738
#if defined(WOLFSSL_SESSION_STATS) && !defined(NO_SESSION_CACHE)
23739
    if (wolfSSL_get_session_stats(NULL, &total, NULL, NULL) != WOLFSSL_SUCCESS) {
23740
        WOLFSSL_MSG("Error getting session stats");
23741
    }
23742
#else
23743
0
    WOLFSSL_MSG("Please use macro WOLFSSL_SESSION_STATS for session stats");
23744
0
#endif
23745
23746
0
    return (long)total;
23747
0
}
23748
23749
23750
#ifndef NO_CERTS
23751
long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
23752
0
{
23753
0
    byte* chain = NULL;
23754
0
    long  chainSz = 0;
23755
0
    int   derSz;
23756
0
    const byte* der;
23757
0
    int   ret;
23758
0
    int   idx = 0;
23759
0
    DerBuffer *derBuffer = NULL;
23760
23761
0
    WOLFSSL_ENTER("wolfSSL_CTX_add_extra_chain_cert");
23762
23763
0
    if (ctx == NULL || x509 == NULL) {
23764
0
        WOLFSSL_MSG("Bad Argument");
23765
0
        return WOLFSSL_FAILURE;
23766
0
    }
23767
23768
0
    der = wolfSSL_X509_get_der(x509, &derSz);
23769
0
    if (der == NULL || derSz <= 0) {
23770
0
        WOLFSSL_MSG("Error getting X509 DER");
23771
0
        return WOLFSSL_FAILURE;
23772
0
    }
23773
23774
0
    if (ctx->certificate == NULL) {
23775
0
        WOLFSSL_ENTER("wolfSSL_use_certificate_chain_buffer_format");
23776
23777
        /* Process buffer makes first certificate the leaf. */
23778
0
        ret = ProcessBuffer(ctx, der, derSz, WOLFSSL_FILETYPE_ASN1, CERT_TYPE,
23779
0
                            NULL, NULL, 1, GET_VERIFY_SETTING_CTX(ctx));
23780
0
        if (ret != WOLFSSL_SUCCESS) {
23781
0
            WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
23782
0
            return WOLFSSL_FAILURE;
23783
0
        }
23784
0
    }
23785
0
    else {
23786
        /* TODO: Do this elsewhere. */
23787
0
        ret = AllocDer(&derBuffer, derSz, CERT_TYPE, ctx->heap);
23788
0
        if (ret != 0) {
23789
0
            WOLFSSL_MSG("Memory Error");
23790
0
            return WOLFSSL_FAILURE;
23791
0
        }
23792
0
        XMEMCPY(derBuffer->buffer, der, derSz);
23793
0
        ret = AddCA(ctx->cm, &derBuffer, WOLFSSL_USER_CA,
23794
0
            GET_VERIFY_SETTING_CTX(ctx));
23795
0
        if (ret != WOLFSSL_SUCCESS) {
23796
0
            WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret);
23797
0
            return WOLFSSL_FAILURE;
23798
0
        }
23799
23800
        /* adding cert to existing chain */
23801
0
        if (ctx->certChain != NULL && ctx->certChain->length > 0) {
23802
0
            chainSz += ctx->certChain->length;
23803
0
        }
23804
0
        chainSz += OPAQUE24_LEN + derSz;
23805
23806
0
        chain = (byte*)XMALLOC(chainSz, ctx->heap, DYNAMIC_TYPE_DER);
23807
0
        if (chain == NULL) {
23808
0
            WOLFSSL_MSG("Memory Error");
23809
0
            return WOLFSSL_FAILURE;
23810
0
        }
23811
23812
0
        if (ctx->certChain != NULL && ctx->certChain->length > 0) {
23813
0
            XMEMCPY(chain, ctx->certChain->buffer, ctx->certChain->length);
23814
0
            idx = ctx->certChain->length;
23815
0
        }
23816
0
        c32to24(derSz, chain + idx);
23817
0
        idx += OPAQUE24_LEN;
23818
0
        XMEMCPY(chain + idx, der, derSz);
23819
0
        idx += derSz;
23820
0
#ifdef WOLFSSL_TLS13
23821
0
        ctx->certChainCnt++;
23822
0
#endif
23823
23824
0
        FreeDer(&ctx->certChain);
23825
0
        ret = AllocDer(&ctx->certChain, idx, CERT_TYPE, ctx->heap);
23826
0
        if (ret == 0) {
23827
0
            XMEMCPY(ctx->certChain->buffer, chain, idx);
23828
0
        }
23829
0
    }
23830
23831
    /* on success WOLFSSL_X509 memory is responsibility of ctx */
23832
0
    wolfSSL_X509_free(x509);
23833
0
    if (chain != NULL)
23834
0
        XFREE(chain, ctx->heap, DYNAMIC_TYPE_DER);
23835
23836
0
    return WOLFSSL_SUCCESS;
23837
0
}
23838
23839
23840
long wolfSSL_CTX_set_tlsext_status_arg(WOLFSSL_CTX* ctx, void* arg)
23841
0
{
23842
0
    if (ctx == NULL || ctx->cm == NULL) {
23843
0
        return WOLFSSL_FAILURE;
23844
0
    }
23845
23846
0
    ctx->cm->ocspIOCtx = arg;
23847
0
    return WOLFSSL_SUCCESS;
23848
0
}
23849
23850
#endif /* NO_CERTS */
23851
23852
23853
/* Get the session cache mode for CTX
23854
 *
23855
 * ctx  WOLFSSL_CTX struct to get cache mode from
23856
 *
23857
 * Returns a bit mask that has the session cache mode */
23858
WOLFSSL_API long wolfSSL_CTX_get_session_cache_mode(WOLFSSL_CTX* ctx)
23859
0
{
23860
0
    long m = 0;
23861
23862
0
    WOLFSSL_ENTER("SSL_CTX_set_session_cache_mode");
23863
23864
0
    if (ctx == NULL) {
23865
0
        return m;
23866
0
    }
23867
23868
0
    if (ctx->sessionCacheOff != 1) {
23869
0
        m |= SSL_SESS_CACHE_SERVER;
23870
0
    }
23871
23872
0
    if (ctx->sessionCacheFlushOff == 1) {
23873
0
        m |= SSL_SESS_CACHE_NO_AUTO_CLEAR;
23874
0
    }
23875
23876
0
#ifdef HAVE_EXT_CACHE
23877
0
    if (ctx->internalCacheOff == 1) {
23878
0
        m |= SSL_SESS_CACHE_NO_INTERNAL_STORE;
23879
0
    }
23880
0
    if (ctx->internalCacheLookupOff == 1) {
23881
0
        m |= SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;
23882
0
    }
23883
0
#endif
23884
23885
0
    return m;
23886
0
}
23887
23888
23889
int wolfSSL_get_read_ahead(const WOLFSSL* ssl)
23890
0
{
23891
0
    if (ssl == NULL) {
23892
0
        return WOLFSSL_FAILURE;
23893
0
    }
23894
23895
0
    return ssl->readAhead;
23896
0
}
23897
23898
23899
int wolfSSL_set_read_ahead(WOLFSSL* ssl, int v)
23900
0
{
23901
0
    if (ssl == NULL) {
23902
0
        return WOLFSSL_FAILURE;
23903
0
    }
23904
23905
0
    ssl->readAhead = (byte)v;
23906
23907
0
    return WOLFSSL_SUCCESS;
23908
0
}
23909
23910
23911
int wolfSSL_CTX_get_read_ahead(WOLFSSL_CTX* ctx)
23912
0
{
23913
0
    if (ctx == NULL) {
23914
0
        return WOLFSSL_FAILURE;
23915
0
    }
23916
23917
0
    return ctx->readAhead;
23918
0
}
23919
23920
23921
int wolfSSL_CTX_set_read_ahead(WOLFSSL_CTX* ctx, int v)
23922
0
{
23923
0
    if (ctx == NULL) {
23924
0
        return WOLFSSL_FAILURE;
23925
0
    }
23926
23927
0
    ctx->readAhead = (byte)v;
23928
23929
0
    return WOLFSSL_SUCCESS;
23930
0
}
23931
23932
23933
long wolfSSL_CTX_set_tlsext_opaque_prf_input_callback_arg(WOLFSSL_CTX* ctx,
23934
        void* arg)
23935
0
{
23936
0
    if (ctx == NULL) {
23937
0
        return WOLFSSL_FAILURE;
23938
0
    }
23939
23940
0
    ctx->userPRFArg = arg;
23941
0
    return WOLFSSL_SUCCESS;
23942
0
}
23943
23944
23945
#ifndef NO_DES3
23946
/* 0 on success */
23947
int wolfSSL_DES_set_key(WOLFSSL_const_DES_cblock* myDes,
23948
                                               WOLFSSL_DES_key_schedule* key)
23949
0
{
23950
#ifdef WOLFSSL_CHECK_DESKEY
23951
    return wolfSSL_DES_set_key_checked(myDes, key);
23952
#else
23953
0
    wolfSSL_DES_set_key_unchecked(myDes, key);
23954
0
    return 0;
23955
0
#endif
23956
0
}
23957
23958
23959
23960
/* return true in fail case (1) */
23961
static int DES_check(word32 mask, word32 mask2, unsigned char* key)
23962
0
{
23963
0
    word32 value[2];
23964
23965
    /* sanity check on length made in wolfSSL_DES_set_key_checked */
23966
0
    value[0] = mask;
23967
0
    value[1] = mask2;
23968
0
    return (XMEMCMP(value, key, sizeof(value)) == 0)? 1: 0;
23969
0
}
23970
23971
23972
/* check that the key is odd parity and is not a weak key
23973
 * returns -1 if parity is wrong, -2 if weak/null key and 0 on success */
23974
int wolfSSL_DES_set_key_checked(WOLFSSL_const_DES_cblock* myDes,
23975
                                               WOLFSSL_DES_key_schedule* key)
23976
0
{
23977
0
    if (myDes == NULL || key == NULL) {
23978
0
        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_set_key_checked");
23979
0
        return -2;
23980
0
    }
23981
0
    else {
23982
0
        word32 sz = sizeof(WOLFSSL_DES_key_schedule);
23983
23984
        /* sanity check before call to DES_check */
23985
0
        if (sz != (sizeof(word32) * 2)) {
23986
0
            WOLFSSL_MSG("Unexpected WOLFSSL_DES_key_schedule size");
23987
0
            return -2;
23988
0
        }
23989
23990
        /* check odd parity */
23991
0
        if (wolfSSL_DES_check_key_parity(myDes) != 1) {
23992
0
            WOLFSSL_MSG("Odd parity test fail");
23993
0
            return -1;
23994
0
        }
23995
23996
0
        if (wolfSSL_DES_is_weak_key(myDes) == 1) {
23997
0
            WOLFSSL_MSG("Weak key found");
23998
0
            return -2;
23999
0
        }
24000
24001
        /* passed tests, now copy over key */
24002
0
        XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
24003
24004
0
        return 0;
24005
0
    }
24006
0
}
24007
24008
24009
/* check is not weak. Weak key list from Nist "Recommendation for the Triple
24010
 * Data Encryption Algorithm (TDEA) Block Cipher"
24011
 *
24012
 * returns 1 if is weak 0 if not
24013
 */
24014
int wolfSSL_DES_is_weak_key(WOLFSSL_const_DES_cblock* key)
24015
0
{
24016
0
    word32 mask, mask2;
24017
24018
0
    WOLFSSL_ENTER("wolfSSL_DES_is_weak_key");
24019
24020
0
    if (key == NULL) {
24021
0
        WOLFSSL_MSG("NULL key passed in");
24022
0
        return 1;
24023
0
    }
24024
24025
0
    mask = 0x01010101; mask2 = 0x01010101;
24026
0
    if (DES_check(mask, mask2, *key)) {
24027
0
        WOLFSSL_MSG("Weak key found");
24028
0
        return 1;
24029
0
    }
24030
24031
0
    mask = 0xFEFEFEFE; mask2 = 0xFEFEFEFE;
24032
0
    if (DES_check(mask, mask2, *key)) {
24033
0
        WOLFSSL_MSG("Weak key found");
24034
0
        return 1;
24035
0
    }
24036
24037
0
    mask = 0xE0E0E0E0; mask2 = 0xF1F1F1F1;
24038
0
    if (DES_check(mask, mask2, *key)) {
24039
0
        WOLFSSL_MSG("Weak key found");
24040
0
        return 1;
24041
0
    }
24042
24043
0
    mask = 0x1F1F1F1F; mask2 = 0x0E0E0E0E;
24044
0
    if (DES_check(mask, mask2, *key)) {
24045
0
        WOLFSSL_MSG("Weak key found");
24046
0
        return 1;
24047
0
    }
24048
24049
    /* semi-weak *key check (list from same Nist paper) */
24050
0
    mask  = 0x011F011F; mask2 = 0x010E010E;
24051
0
    if (DES_check(mask, mask2, *key) ||
24052
0
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24053
0
        WOLFSSL_MSG("Weak key found");
24054
0
        return 1;
24055
0
    }
24056
24057
0
    mask  = 0x01E001E0; mask2 = 0x01F101F1;
24058
0
    if (DES_check(mask, mask2, *key) ||
24059
0
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24060
0
        WOLFSSL_MSG("Weak key found");
24061
0
        return 1;
24062
0
    }
24063
24064
0
    mask  = 0x01FE01FE; mask2 = 0x01FE01FE;
24065
0
    if (DES_check(mask, mask2, *key) ||
24066
0
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24067
0
        WOLFSSL_MSG("Weak key found");
24068
0
        return 1;
24069
0
    }
24070
24071
0
    mask  = 0x1FE01FE0; mask2 = 0x0EF10EF1;
24072
0
    if (DES_check(mask, mask2, *key) ||
24073
0
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24074
0
        WOLFSSL_MSG("Weak key found");
24075
0
        return 1;
24076
0
    }
24077
24078
0
    mask  = 0x1FFE1FFE; mask2 = 0x0EFE0EFE;
24079
0
    if (DES_check(mask, mask2, *key) ||
24080
0
       DES_check(ByteReverseWord32(mask), ByteReverseWord32(mask2), *key)) {
24081
0
        WOLFSSL_MSG("Weak key found");
24082
0
        return 1;
24083
0
    }
24084
24085
0
    return 0;
24086
0
}
24087
24088
24089
void wolfSSL_DES_set_key_unchecked(WOLFSSL_const_DES_cblock* myDes,
24090
                                               WOLFSSL_DES_key_schedule* key)
24091
0
{
24092
0
    if (myDes != NULL && key != NULL) {
24093
0
        XMEMCPY(key, myDes, sizeof(WOLFSSL_const_DES_cblock));
24094
0
    }
24095
0
}
24096
24097
24098
/* Sets the parity of the DES key for use */
24099
void wolfSSL_DES_set_odd_parity(WOLFSSL_DES_cblock* myDes)
24100
0
{
24101
0
    word32 i;
24102
0
    word32 sz = sizeof(WOLFSSL_DES_cblock);
24103
24104
0
    WOLFSSL_ENTER("wolfSSL_DES_set_odd_parity");
24105
24106
0
    for (i = 0; i < sz; i++) {
24107
0
        unsigned char c = (*myDes)[i];
24108
0
        if ((
24109
0
            ((c >> 1) & 0x01) ^
24110
0
            ((c >> 2) & 0x01) ^
24111
0
            ((c >> 3) & 0x01) ^
24112
0
            ((c >> 4) & 0x01) ^
24113
0
            ((c >> 5) & 0x01) ^
24114
0
            ((c >> 6) & 0x01) ^
24115
0
            ((c >> 7) & 0x01)) == (c & 0x01)) {
24116
0
            WOLFSSL_MSG("Flipping parity bit");
24117
0
            (*myDes)[i] = c ^ 0x01;
24118
0
        }
24119
0
    }
24120
0
}
24121
24122
int wolfSSL_DES_check_key_parity(WOLFSSL_DES_cblock *myDes)
24123
0
{
24124
0
    word32 i;
24125
0
    word32 sz = sizeof(WOLFSSL_DES_cblock);
24126
24127
0
    WOLFSSL_ENTER("wolfSSL_DES_check_key_parity");
24128
24129
0
    for (i = 0; i < sz; i++) {
24130
0
        unsigned char c = (*myDes)[i];
24131
0
        if ((
24132
0
            ((c >> 1) & 0x01) ^
24133
0
            ((c >> 2) & 0x01) ^
24134
0
            ((c >> 3) & 0x01) ^
24135
0
            ((c >> 4) & 0x01) ^
24136
0
            ((c >> 5) & 0x01) ^
24137
0
            ((c >> 6) & 0x01) ^
24138
0
            ((c >> 7) & 0x01)) == (c & 0x01)) {
24139
0
            return 0;
24140
0
        }
24141
0
    }
24142
0
    return 1;
24143
0
}
24144
24145
#ifdef WOLFSSL_DES_ECB
24146
/* Encrypt or decrypt input message desa with key and get output in desb.
24147
 * if enc is DES_ENCRYPT,input message is encrypted or
24148
 * if enc is DES_DECRYPT,input message is decrypted.
24149
 * */
24150
void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa,
24151
             WOLFSSL_DES_cblock* desb, WOLFSSL_DES_key_schedule* key, int enc)
24152
0
{
24153
0
    Des myDes;
24154
24155
0
    WOLFSSL_ENTER("wolfSSL_DES_ecb_encrypt");
24156
24157
0
    if (desa == NULL || key == NULL || desb == NULL ||
24158
0
        (enc != DES_ENCRYPT && enc != DES_DECRYPT)) {
24159
0
        WOLFSSL_MSG("Bad argument passed to wolfSSL_DES_ecb_encrypt");
24160
0
    } else {
24161
0
        if (wc_Des_SetKey(&myDes, (const byte*) key,
24162
0
                           (const byte*) NULL, !enc) != 0) {
24163
0
            WOLFSSL_MSG("wc_Des_SetKey return error.");
24164
0
            return;
24165
0
        }
24166
0
        if (enc == DES_ENCRYPT){
24167
0
            if (wc_Des_EcbEncrypt(&myDes, (byte*) desb, (const byte*) desa,
24168
0
                        sizeof(WOLFSSL_DES_cblock)) != 0){
24169
0
                WOLFSSL_MSG("wc_Des_EcbEncrypt return error.");
24170
0
            }
24171
0
        } else {
24172
0
            if (wc_Des_EcbDecrypt(&myDes, (byte*) desb, (const byte*) desa,
24173
0
                        sizeof(WOLFSSL_DES_cblock)) != 0){
24174
0
                WOLFSSL_MSG("wc_Des_EcbDecrpyt return error.");
24175
0
            }
24176
0
        }
24177
0
    }
24178
0
}
24179
#endif
24180
#endif /* NO_DES3 */
24181
24182
#ifndef NO_RC4
24183
/* Set the key state for Arc4 structure.
24184
 *
24185
 * key  Arc4 structure to use
24186
 * len  length of data buffer
24187
 * data initial state to set Arc4 structure
24188
 */
24189
void wolfSSL_RC4_set_key(WOLFSSL_RC4_KEY* key, int len,
24190
        const unsigned char* data)
24191
0
{
24192
0
    typedef char rc4_test[sizeof(WOLFSSL_RC4_KEY) >= sizeof(Arc4) ? 1 : -1];
24193
0
    (void)sizeof(rc4_test);
24194
24195
0
    WOLFSSL_ENTER("wolfSSL_RC4_set_key");
24196
24197
0
    if (key == NULL || len < 0) {
24198
0
        WOLFSSL_MSG("bad argument passed in");
24199
0
        return;
24200
0
    }
24201
24202
0
    XMEMSET(key, 0, sizeof(WOLFSSL_RC4_KEY));
24203
0
    wc_Arc4SetKey((Arc4*)key, data, (word32)len);
24204
0
}
24205
24206
24207
/* Encrypt/decrypt with Arc4 structure.
24208
 *
24209
 * len length of buffer to encrypt/decrypt (in/out)
24210
 * in  buffer to encrypt/decrypt
24211
 * out results of encryption/decryption
24212
 */
24213
void wolfSSL_RC4(WOLFSSL_RC4_KEY* key, size_t len,
24214
        const unsigned char* in, unsigned char* out)
24215
0
{
24216
0
    WOLFSSL_ENTER("wolfSSL_RC4");
24217
24218
0
    if (key == NULL || in == NULL || out == NULL) {
24219
0
        WOLFSSL_MSG("Bad argument passed in");
24220
0
        return;
24221
0
    }
24222
24223
0
    wc_Arc4Process((Arc4*)key, out, in, (word32)len);
24224
0
}
24225
#endif /* NO_RC4 */
24226
24227
#ifndef NO_AES
24228
24229
#ifdef WOLFSSL_AES_DIRECT
24230
/* AES encrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
24231
 *
24232
 * input  Data to encrypt
24233
 * output Encrypted data after done
24234
 * key    AES key to use for encryption
24235
 */
24236
void wolfSSL_AES_encrypt(const unsigned char* input, unsigned char* output,
24237
        AES_KEY *key)
24238
0
{
24239
0
    WOLFSSL_ENTER("wolfSSL_AES_encrypt");
24240
24241
0
    if (input == NULL || output == NULL || key == NULL) {
24242
0
        WOLFSSL_MSG("Null argument passed in");
24243
0
        return;
24244
0
    }
24245
24246
0
#if !defined(HAVE_SELFTEST) && \
24247
0
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
24248
0
    if (wc_AesEncryptDirect((Aes*)key, output, input) != 0) {
24249
0
        WOLFSSL_MSG("wc_AesEncryptDirect failed");
24250
0
        return;
24251
0
    }
24252
#else
24253
    wc_AesEncryptDirect((Aes*)key, output, input);
24254
#endif
24255
0
}
24256
24257
24258
/* AES decrypt direct, it is expected to be blocks of AES_BLOCK_SIZE for input.
24259
 *
24260
 * input  Data to decrypt
24261
 * output Decrypted data after done
24262
 * key    AES key to use for encryption
24263
 */
24264
void wolfSSL_AES_decrypt(const unsigned char* input, unsigned char* output,
24265
        AES_KEY *key)
24266
0
{
24267
0
    WOLFSSL_ENTER("wolfSSL_AES_decrypt");
24268
24269
0
    if (input == NULL || output == NULL || key == NULL) {
24270
0
        WOLFSSL_MSG("Null argument passed in");
24271
0
        return;
24272
0
    }
24273
24274
0
#if !defined(HAVE_SELFTEST) && \
24275
0
    (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
24276
0
    if (wc_AesDecryptDirect((Aes*)key, output, input) != 0) {
24277
0
        WOLFSSL_MSG("wc_AesDecryptDirect failed");
24278
0
        return;
24279
0
    }
24280
#else
24281
    wc_AesDecryptDirect((Aes*)key, output, input);
24282
#endif
24283
0
}
24284
#endif /* WOLFSSL_AES_DIRECT */
24285
24286
/* Setup of an AES key to use for encryption.
24287
 *
24288
 * key  key in bytes to use for encryption
24289
 * bits size of key in bits
24290
 * aes  AES structure to initialize
24291
 */
24292
int wolfSSL_AES_set_encrypt_key(const unsigned char *key, const int bits,
24293
        AES_KEY *aes)
24294
0
{
24295
0
    typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
24296
0
    (void)sizeof(aes_test);
24297
24298
0
    WOLFSSL_ENTER("wolfSSL_AES_set_encrypt_key");
24299
24300
0
    if (key == NULL || aes == NULL) {
24301
0
        WOLFSSL_MSG("Null argument passed in");
24302
0
        return -1;
24303
0
    }
24304
24305
0
    XMEMSET(aes, 0, sizeof(AES_KEY));
24306
0
    if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_ENCRYPT) != 0) {
24307
0
        WOLFSSL_MSG("Error in setting AES key");
24308
0
        return -1;
24309
0
    }
24310
0
    return 0;
24311
0
}
24312
24313
24314
/* Setup of an AES key to use for decryption.
24315
 *
24316
 * key  key in bytes to use for decryption
24317
 * bits size of key in bits
24318
 * aes  AES structure to initialize
24319
 */
24320
int wolfSSL_AES_set_decrypt_key(const unsigned char *key, const int bits,
24321
        AES_KEY *aes)
24322
0
{
24323
0
    typedef char aes_test[sizeof(AES_KEY) >= sizeof(Aes) ? 1 : -1];
24324
0
    (void)sizeof(aes_test);
24325
24326
0
    WOLFSSL_ENTER("wolfSSL_AES_set_decrypt_key");
24327
24328
0
    if (key == NULL || aes == NULL) {
24329
0
        WOLFSSL_MSG("Null argument passed in");
24330
0
        return -1;
24331
0
    }
24332
24333
0
    XMEMSET(aes, 0, sizeof(AES_KEY));
24334
0
    if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, AES_DECRYPT) != 0) {
24335
0
        WOLFSSL_MSG("Error in setting AES key");
24336
0
        return -1;
24337
0
    }
24338
0
    return 0;
24339
0
}
24340
24341
24342
#ifdef HAVE_AES_ECB
24343
/* Encrypt/decrypt a 16 byte block of data using the key passed in.
24344
 *
24345
 * in  buffer to encrypt/decrypt
24346
 * out buffer to hold result of encryption/decryption
24347
 * key AES structure to use with encryption/decryption
24348
 * enc AES_ENCRPT for encryption and AES_DECRYPT for decryption
24349
 */
24350
void wolfSSL_AES_ecb_encrypt(const unsigned char *in, unsigned char* out,
24351
                             AES_KEY *key, const int enc)
24352
0
{
24353
0
    Aes* aes;
24354
24355
0
    WOLFSSL_ENTER("wolfSSL_AES_ecb_encrypt");
24356
24357
0
    if (key == NULL || in == NULL || out == NULL) {
24358
0
        WOLFSSL_MSG("Error, Null argument passed in");
24359
0
        return;
24360
0
    }
24361
24362
0
    aes = (Aes*)key;
24363
0
    if (enc == AES_ENCRYPT) {
24364
0
        if (wc_AesEcbEncrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
24365
0
            WOLFSSL_MSG("Error with AES CBC encrypt");
24366
0
        }
24367
0
    }
24368
0
    else {
24369
0
    #ifdef HAVE_AES_DECRYPT
24370
0
        if (wc_AesEcbDecrypt(aes, out, in, AES_BLOCK_SIZE) != 0) {
24371
0
            WOLFSSL_MSG("Error with AES CBC decrypt");
24372
0
        }
24373
    #else
24374
        WOLFSSL_MSG("AES decryption not compiled in");
24375
    #endif
24376
0
    }
24377
0
}
24378
#endif /* HAVE_AES_ECB */
24379
24380
#ifdef HAVE_AES_CBC
24381
/* Encrypt data using key and iv passed in. iv gets updated to most recent iv
24382
 * state after encryption/decryption.
24383
 *
24384
 * in  buffer to encrypt/decrypt
24385
 * out buffer to hold result of encryption/decryption
24386
 * len length of input buffer
24387
 * key AES structure to use with encryption/decryption
24388
 * iv  iv to use with operation
24389
 * enc 1 for encryption and 0 for decryption
24390
 */
24391
void wolfSSL_AES_cbc_encrypt(const unsigned char *in, unsigned char* out,
24392
        size_t len, AES_KEY *key, unsigned char* iv, const int enc)
24393
0
{
24394
0
    Aes* aes;
24395
24396
0
    WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
24397
24398
0
    if (key == NULL || in == NULL || out == NULL || iv == NULL || len == 0) {
24399
0
        WOLFSSL_MSG("Error, Null argument passed in");
24400
0
        return;
24401
0
    }
24402
24403
0
    aes = (Aes*)key;
24404
0
    if (wc_AesSetIV(aes, (const byte*)iv) != 0) {
24405
0
        WOLFSSL_MSG("Error with setting iv");
24406
0
        return;
24407
0
    }
24408
24409
0
    if (enc == AES_ENCRYPT) {
24410
0
        if (wc_AesCbcEncrypt(aes, out, in, (word32)len) != 0) {
24411
0
            WOLFSSL_MSG("Error with AES CBC encrypt");
24412
0
            return;
24413
0
        }
24414
0
    }
24415
0
    else {
24416
0
        if (wc_AesCbcDecrypt(aes, out, in, (word32)len) != 0) {
24417
0
            WOLFSSL_MSG("Error with AES CBC decrypt");
24418
0
            return;
24419
0
        }
24420
0
    }
24421
24422
    /* to be compatible copy iv to iv buffer after completing operation */
24423
0
    XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
24424
0
}
24425
#endif /* HAVE_AES_CBC */
24426
24427
24428
/* Encrypt data using CFB mode with key and iv passed in. iv gets updated to
24429
 * most recent iv state after encryption/decryption.
24430
 *
24431
 * in  buffer to encrypt/decrypt
24432
 * out buffer to hold result of encryption/decryption
24433
 * len length of input buffer
24434
 * key AES structure to use with encryption/decryption
24435
 * iv  iv to use with operation
24436
 * num contains the amount of block used
24437
 * enc AES_ENCRYPT for encryption and AES_DECRYPT for decryption
24438
 */
24439
void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out,
24440
        size_t len, AES_KEY *key, unsigned char* iv, int* num,
24441
        const int enc)
24442
0
{
24443
#ifndef WOLFSSL_AES_CFB
24444
    WOLFSSL_MSG("CFB mode not enabled please use macro WOLFSSL_AES_CFB");
24445
    (void)in;
24446
    (void)out;
24447
    (void)len;
24448
    (void)key;
24449
    (void)iv;
24450
    (void)num;
24451
    (void)enc;
24452
24453
    return;
24454
#else
24455
0
    Aes* aes;
24456
24457
0
    WOLFSSL_ENTER("wolfSSL_AES_cbc_encrypt");
24458
0
    if (key == NULL || in == NULL || out == NULL || iv == NULL) {
24459
0
        WOLFSSL_MSG("Error, Null argument passed in");
24460
0
        return;
24461
0
    }
24462
24463
0
    aes = (Aes*)key;
24464
24465
    /*
24466
     * We copy the IV directly into reg here because using wc_AesSetIV will
24467
     * clear the leftover bytes field "left", and this function relies on the
24468
     * leftover bytes being preserved between calls.
24469
     */
24470
0
    XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
24471
24472
0
    if (enc == AES_ENCRYPT) {
24473
0
        if (wc_AesCfbEncrypt(aes, out, in, (word32)len) != 0) {
24474
0
            WOLFSSL_MSG("Error with AES CBC encrypt");
24475
0
            return;
24476
0
        }
24477
0
    }
24478
0
    else {
24479
0
        if (wc_AesCfbDecrypt(aes, out, in, (word32)len) != 0) {
24480
0
            WOLFSSL_MSG("Error with AES CBC decrypt");
24481
0
            return;
24482
0
        }
24483
0
    }
24484
24485
    /* to be compatible copy iv to iv buffer after completing operation */
24486
0
    XMEMCPY(iv, (byte*)(aes->reg), AES_BLOCK_SIZE);
24487
24488
    /* store number of left over bytes to num */
24489
0
    *num = (aes->left)? AES_BLOCK_SIZE - aes->left : 0;
24490
0
#endif /* WOLFSSL_AES_CFB */
24491
0
}
24492
24493
/* wc_AesKey*Wrap_ex API not available in FIPS and SELFTEST */
24494
#if defined(HAVE_AES_KEYWRAP) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
24495
int wolfSSL_AES_wrap_key(AES_KEY *key, const unsigned char *iv,
24496
                 unsigned char *out,
24497
                 const unsigned char *in, unsigned int inlen)
24498
0
{
24499
0
    int ret;
24500
24501
0
    WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
24502
24503
0
    if (out == NULL || in == NULL) {
24504
0
        WOLFSSL_MSG("Error, Null argument passed in");
24505
0
        return WOLFSSL_FAILURE;
24506
0
    }
24507
24508
0
    ret = wc_AesKeyWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv);
24509
24510
0
    return ret < 0 ? WOLFSSL_FAILURE : ret;
24511
0
}
24512
24513
int wolfSSL_AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
24514
                   unsigned char *out,
24515
                   const unsigned char *in, unsigned int inlen)
24516
0
{
24517
0
    int ret;
24518
24519
0
    WOLFSSL_ENTER("wolfSSL_AES_wrap_key");
24520
24521
0
    if (out == NULL || in == NULL) {
24522
0
        WOLFSSL_MSG("Error, Null argument passed in");
24523
0
        return WOLFSSL_FAILURE;
24524
0
    }
24525
24526
0
    ret = wc_AesKeyUnWrap_ex((Aes*)key, in, inlen, out, inlen + KEYWRAP_BLOCK_SIZE, iv);
24527
24528
0
    return ret < 0 ? WOLFSSL_FAILURE : ret;
24529
0
}
24530
#endif /* HAVE_AES_KEYWRAP && !HAVE_FIPS && !HAVE_SELFTEST */
24531
24532
#ifdef HAVE_CTS
24533
/*
24534
 * Ciphertext stealing interface compatible with RFC2040 and RFC3962.
24535
 */
24536
size_t wolfSSL_CRYPTO_cts128_encrypt(const unsigned char *in,
24537
        unsigned char *out, size_t len, const void *key,
24538
        unsigned char *iv, WOLFSSL_CBC128_CB cbc)
24539
0
{
24540
0
    byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
24541
0
    int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
24542
0
    WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_encrypt");
24543
24544
0
    if (in == NULL || out == NULL || len < WOLFSSL_CTS128_BLOCK_SZ ||
24545
0
            cbc == NULL) {
24546
0
        WOLFSSL_MSG("Bad parameter");
24547
0
        return WOLFSSL_FAILURE;
24548
0
    }
24549
24550
0
    if (lastBlkLen == 0)
24551
0
        lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
24552
24553
    /* Encrypt data up to last block */
24554
0
    (*cbc)(in, out, len - lastBlkLen, key, iv, AES_ENCRYPT);
24555
24556
    /* Move to last block */
24557
0
    in += len - lastBlkLen;
24558
0
    out += len - lastBlkLen;
24559
24560
    /* RFC2040: Pad Pn with zeros at the end to create P of length BB. */
24561
0
    XMEMCPY(lastBlk, in, lastBlkLen);
24562
0
    XMEMSET(lastBlk + lastBlkLen, 0, WOLFSSL_CTS128_BLOCK_SZ - lastBlkLen);
24563
    /* RFC2040: Select the first Ln bytes of En-1 to create Cn */
24564
0
    XMEMCPY(out, out - WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
24565
0
    (*cbc)(lastBlk, out - WOLFSSL_CTS128_BLOCK_SZ, WOLFSSL_CTS128_BLOCK_SZ,
24566
0
            key, iv, AES_ENCRYPT);
24567
24568
0
    return len;
24569
0
}
24570
24571
size_t wolfSSL_CRYPTO_cts128_decrypt(const unsigned char *in,
24572
        unsigned char *out, size_t len, const void *key,
24573
        unsigned char *iv, WOLFSSL_CBC128_CB cbc)
24574
0
{
24575
0
    byte lastBlk[WOLFSSL_CTS128_BLOCK_SZ];
24576
0
    byte prevBlk[WOLFSSL_CTS128_BLOCK_SZ];
24577
0
    int lastBlkLen = len % WOLFSSL_CTS128_BLOCK_SZ;
24578
0
    WOLFSSL_ENTER("wolfSSL_CRYPTO_cts128_decrypt");
24579
24580
0
    if (in == NULL || out == NULL || len <= WOLFSSL_CTS128_BLOCK_SZ ||
24581
0
            cbc == NULL) {
24582
0
        WOLFSSL_MSG("Bad parameter");
24583
0
        return WOLFSSL_FAILURE;
24584
0
    }
24585
24586
0
    if (lastBlkLen == 0)
24587
0
        lastBlkLen = WOLFSSL_CTS128_BLOCK_SZ;
24588
24589
    /* Decrypt up to last two blocks */
24590
0
    (*cbc)(in, out, len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ, key, iv,
24591
0
            AES_DECRYPTION);
24592
24593
    /* Move to last two blocks */
24594
0
    in += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
24595
0
    out += len - lastBlkLen - WOLFSSL_CTS128_BLOCK_SZ;
24596
24597
    /* RFC2040: Decrypt Cn-1 to create Dn.
24598
     * Use 0 buffer as IV to do straight decryption.
24599
     * This places the Cn-1 block at lastBlk */
24600
0
    XMEMSET(lastBlk, 0, WOLFSSL_CTS128_BLOCK_SZ);
24601
0
    (*cbc)(in, prevBlk, WOLFSSL_CTS128_BLOCK_SZ, key, lastBlk, AES_DECRYPT);
24602
    /* RFC2040: Append the tail (BB minus Ln) bytes of Xn to Cn
24603
     *          to create En. */
24604
0
    XMEMCPY(prevBlk, in + WOLFSSL_CTS128_BLOCK_SZ, lastBlkLen);
24605
    /* Cn and Cn-1 can now be decrypted */
24606
0
    (*cbc)(prevBlk, out, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT);
24607
0
    (*cbc)(lastBlk, lastBlk, WOLFSSL_CTS128_BLOCK_SZ, key, iv, AES_DECRYPT);
24608
0
    XMEMCPY(out + WOLFSSL_CTS128_BLOCK_SZ, lastBlk, lastBlkLen);
24609
0
    return len;
24610
0
}
24611
#endif /* HAVE_CTS */
24612
#endif /* NO_AES */
24613
24614
#ifndef NO_ASN_TIME
24615
#ifndef NO_BIO
24616
int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
24617
0
{
24618
0
    WOLFSSL_ENTER("ASN1_UTCTIME_print");
24619
0
    if (bio == NULL || a == NULL) {
24620
0
        return WOLFSSL_FAILURE;
24621
0
    }
24622
0
    if (a->type != ASN_UTC_TIME) {
24623
0
        WOLFSSL_MSG("Error, not UTC_TIME");
24624
0
        return WOLFSSL_FAILURE;
24625
0
    }
24626
24627
0
    return wolfSSL_ASN1_TIME_print(bio, a);
24628
0
}
24629
24630
#endif /* !NO_BIO */
24631
24632
/* Checks the ASN1 syntax of "a"
24633
 * returns WOLFSSL_SUCCESS (1)  if correct otherwise WOLFSSL_FAILURE (0) */
24634
int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a)
24635
0
{
24636
0
    char buf[MAX_TIME_STRING_SZ];
24637
24638
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_check");
24639
24640
    /* if can parse the WOLFSSL_ASN1_TIME passed in then consider syntax good */
24641
0
    if (wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)a, buf,
24642
0
                MAX_TIME_STRING_SZ) == NULL) {
24643
0
        return WOLFSSL_FAILURE;
24644
0
    }
24645
0
    return WOLFSSL_SUCCESS;
24646
0
}
24647
24648
/*
24649
 * Convert time to Unix time (GMT).
24650
 */
24651
static long long TimeToUnixTime(int sec, int min, int hour, int mday, int mon,
24652
                                int year)
24653
0
{
24654
    /* Number of cumulative days from the previous months, starting from
24655
     * beginning of January. */
24656
0
    static const int monthDaysCumulative [12] = {
24657
0
        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
24658
0
    };
24659
0
    int leapDays = year;
24660
24661
0
    if (mon <= 1) {
24662
0
        --leapDays;
24663
0
    }
24664
0
    leapDays = leapDays / 4 - leapDays / 100 + leapDays / 400 - 1969 / 4 +
24665
0
               1969 / 100 - 1969 / 400;
24666
24667
0
    return ((((long long) (year - 1970) * 365 + leapDays +
24668
0
           monthDaysCumulative[mon] + mday - 1) * 24 + hour) * 60 + min) * 60 +
24669
0
           sec;
24670
0
}
24671
24672
int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from,
24673
    const WOLFSSL_ASN1_TIME *to)
24674
0
{
24675
0
    const int SECS_PER_DAY = 24 * 60 * 60;
24676
0
    struct tm fromTm_s, *fromTmGmt = &fromTm_s;
24677
0
    struct tm toTm_s, *toTmGmt = &toTm_s;
24678
0
    time_t currTime;
24679
0
    long long fromSecs;
24680
0
    long long toSecs;
24681
0
    double diffSecs;
24682
0
    struct tm *tmpTs;
24683
0
#if defined(NEED_TMP_TIME)
24684
    /* for use with gmtime_r */
24685
0
    struct tm tmpTimeStorage;
24686
0
    tmpTs = &tmpTimeStorage;
24687
#else
24688
    tmpTs = NULL;
24689
#endif
24690
0
    (void)tmpTs;
24691
24692
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_diff");
24693
24694
0
    if (days == NULL) {
24695
0
        WOLFSSL_MSG("days is NULL");
24696
0
        return WOLFSSL_FAILURE;
24697
0
    }
24698
0
    if (secs == NULL) {
24699
0
        WOLFSSL_MSG("secs is NULL");
24700
0
        return WOLFSSL_FAILURE;
24701
0
    }
24702
24703
0
    if (from == NULL && to == NULL) {
24704
0
        *days = 0;
24705
0
        *secs = 0;
24706
0
        return WOLFSSL_SUCCESS;
24707
0
    }
24708
24709
0
    if (from == NULL) {
24710
0
        currTime = wc_Time(0);
24711
0
        fromTmGmt = XGMTIME(&currTime, tmpTs);
24712
0
        if (fromTmGmt == NULL) {
24713
0
            WOLFSSL_MSG("XGMTIME for from time failed.");
24714
0
            return WOLFSSL_FAILURE;
24715
0
        }
24716
0
    }
24717
0
    else if (wolfSSL_ASN1_TIME_to_tm(from, fromTmGmt) != WOLFSSL_SUCCESS) {
24718
0
        WOLFSSL_MSG("Failed to convert from time to struct tm.");
24719
0
        return WOLFSSL_FAILURE;
24720
0
    }
24721
24722
    /* We use TimeToUnixTime here instead of XMKTIME to avoid the Year 2038
24723
     * Problem on platforms where time_t is 32 bits. struct tm stores the year
24724
     * as years since 1900, so we add 1900 to the year. */
24725
0
    fromSecs = TimeToUnixTime(fromTmGmt->tm_sec, fromTmGmt->tm_min,
24726
0
                          fromTmGmt->tm_hour, fromTmGmt->tm_mday,
24727
0
                          fromTmGmt->tm_mon, fromTmGmt->tm_year + 1900);
24728
24729
0
    if (to == NULL) {
24730
0
        currTime = wc_Time(0);
24731
0
        toTmGmt = XGMTIME(&currTime, tmpTs);
24732
0
        if (toTmGmt == NULL) {
24733
0
            WOLFSSL_MSG("XGMTIME for to time failed.");
24734
0
            return WOLFSSL_FAILURE;
24735
0
        }
24736
0
    }
24737
0
    else if (wolfSSL_ASN1_TIME_to_tm(to, toTmGmt) != WOLFSSL_SUCCESS) {
24738
0
        WOLFSSL_MSG("Failed to convert to time to struct tm.");
24739
0
        return WOLFSSL_FAILURE;
24740
0
    }
24741
24742
0
    toSecs = TimeToUnixTime(toTmGmt->tm_sec, toTmGmt->tm_min, toTmGmt->tm_hour,
24743
0
                        toTmGmt->tm_mday, toTmGmt->tm_mon,
24744
0
                        toTmGmt->tm_year + 1900);
24745
24746
0
    diffSecs = (double)(toSecs - fromSecs);
24747
0
    *days = (int) (diffSecs / SECS_PER_DAY);
24748
0
    *secs = (int) (diffSecs - (((double)*days) * SECS_PER_DAY));
24749
24750
0
    return WOLFSSL_SUCCESS;
24751
0
}
24752
24753
int wolfSSL_ASN1_TIME_compare(const WOLFSSL_ASN1_TIME *a,
24754
                              const WOLFSSL_ASN1_TIME *b)
24755
0
{
24756
0
    int ret;
24757
0
    int days;
24758
0
    int secs;
24759
24760
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_compare");
24761
24762
0
    if (wolfSSL_ASN1_TIME_diff(&days, &secs, a, b) != WOLFSSL_SUCCESS) {
24763
0
        WOLFSSL_MSG("Failed to get time difference.");
24764
0
        ret = -2;
24765
0
    }
24766
0
    else {
24767
0
        if (days == 0 && secs == 0) {
24768
            /* a and b are the same time. */
24769
0
            ret = 0;
24770
0
        }
24771
0
        else if (days >= 0 && secs >= 0) {
24772
            /* a is before b. */
24773
0
            ret = -1;
24774
0
        }
24775
0
        else if (days <= 0 && secs <= 0) {
24776
            /* a is after b. */
24777
0
            ret = 1;
24778
0
        }
24779
0
        else {
24780
0
            WOLFSSL_MSG("Incoherent time difference.");
24781
0
            ret = -2;
24782
0
        }
24783
0
    }
24784
24785
0
    WOLFSSL_LEAVE("wolfSSL_ASN1_TIME_compare", ret);
24786
24787
0
    return ret;
24788
0
}
24789
#endif /* !NO_ASN_TIME */
24790
24791
#ifndef NO_WOLFSSL_STUB
24792
WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_t t)
24793
0
{
24794
0
    WOLFSSL_STUB("wolfSSL_ASN1_TIME_set");
24795
0
    (void)s;
24796
0
    (void)t;
24797
0
    return s;
24798
0
}
24799
#endif /* !NO_WOLFSSL_STUB */
24800
24801
int wolfSSL_ASN1_TIME_set_string(WOLFSSL_ASN1_TIME *s, const char *str)
24802
0
{
24803
0
    int slen;
24804
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_set_string");
24805
24806
0
    if (!str) {
24807
0
        WOLFSSL_MSG("Bad parameter");
24808
0
        return WOLFSSL_FAILURE;
24809
0
    }
24810
0
    slen = (int)XSTRLEN(str)+1;
24811
0
    if (slen > CTC_DATE_SIZE) {
24812
0
        WOLFSSL_MSG("Date string too long");
24813
0
        return WOLFSSL_FAILURE;
24814
0
    }
24815
0
    if (s) {
24816
0
        XMEMCPY(s->data, str, slen);
24817
0
        s->length = slen - 1; /* do not include null terminator in length */
24818
0
        s->type = slen == ASN_UTC_TIME_SIZE ? V_ASN1_UTCTIME :
24819
0
            V_ASN1_GENERALIZEDTIME;
24820
0
    }
24821
0
    return WOLFSSL_SUCCESS;
24822
0
}
24823
24824
#ifndef NO_BIO
24825
24826
/* Return the month as a string.
24827
 *
24828
 * n  The number of the month as a two characters (1 based).
24829
 * returns the month as a string.
24830
 */
24831
static WC_INLINE const char* MonthStr(const char* n)
24832
0
{
24833
0
    static const char monthStr[12][4] = {
24834
0
            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
24835
0
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
24836
0
    return monthStr[(n[0] - '0') * 10 + (n[1] - '0') - 1];
24837
0
}
24838
24839
int wolfSSL_ASN1_GENERALIZEDTIME_print(WOLFSSL_BIO* bio,
24840
    const WOLFSSL_ASN1_GENERALIZEDTIME* asnTime)
24841
0
{
24842
0
    const char* p;
24843
0
    WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_print");
24844
24845
0
    if (bio == NULL || asnTime == NULL)
24846
0
        return BAD_FUNC_ARG;
24847
24848
0
    if (asnTime->type != ASN_GENERALIZED_TIME) {
24849
0
        WOLFSSL_MSG("Error, not GENERALIZED_TIME");
24850
0
        return WOLFSSL_FAILURE;
24851
0
    }
24852
0
    p = (const char *)(asnTime->data);
24853
    /* GetTimeString not always available. */
24854
0
    if (wolfSSL_BIO_write(bio, MonthStr(p + 4), 3) <= 0)
24855
0
        return WOLFSSL_FAILURE;
24856
0
    if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
24857
0
        return WOLFSSL_FAILURE;
24858
24859
    /* Day */
24860
0
    if (wolfSSL_BIO_write(bio, p + 6, 2) <= 0)
24861
0
        return WOLFSSL_FAILURE;
24862
0
    if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
24863
0
        return WOLFSSL_FAILURE;
24864
24865
    /* Hour */
24866
0
    if (wolfSSL_BIO_write(bio, p + 8, 2) <= 0)
24867
0
        return WOLFSSL_FAILURE;
24868
0
    if (wolfSSL_BIO_write(bio, ":", 1) <= 0)
24869
0
        return WOLFSSL_FAILURE;
24870
24871
    /* Min */
24872
0
    if (wolfSSL_BIO_write(bio, p + 10, 2) <= 0)
24873
0
        return WOLFSSL_FAILURE;
24874
0
    if (wolfSSL_BIO_write(bio, ":", 1) <= 0)
24875
0
        return WOLFSSL_FAILURE;
24876
24877
    /* Secs */
24878
0
    if (wolfSSL_BIO_write(bio, p + 12, 2) <= 0)
24879
0
        return WOLFSSL_FAILURE;
24880
0
    if (wolfSSL_BIO_write(bio, " ", 1) <= 0)
24881
0
        return WOLFSSL_FAILURE;
24882
0
    if (wolfSSL_BIO_write(bio, p, 4) <= 0)
24883
0
        return WOLFSSL_FAILURE;
24884
24885
0
    return 0;
24886
0
}
24887
#endif /* !NO_BIO */
24888
24889
void wolfSSL_ASN1_GENERALIZEDTIME_free(WOLFSSL_ASN1_TIME* asn1Time)
24890
0
{
24891
0
    WOLFSSL_ENTER("wolfSSL_ASN1_GENERALIZEDTIME_free");
24892
0
    if (asn1Time == NULL)
24893
0
        return;
24894
0
    XMEMSET(asn1Time->data, 0, sizeof(asn1Time->data));
24895
0
}
24896
24897
#endif /* OPENSSL_EXTRA */
24898
24899
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
24900
int wolfSSL_sk_num(const WOLFSSL_STACK* sk)
24901
0
{
24902
0
    WOLFSSL_ENTER("wolfSSL_sk_num");
24903
0
    if (sk == NULL)
24904
0
        return 0;
24905
0
    return (int)sk->num;
24906
0
}
24907
24908
void* wolfSSL_sk_value(const WOLFSSL_STACK* sk, int i)
24909
0
{
24910
0
    WOLFSSL_ENTER("wolfSSL_sk_value");
24911
24912
0
    for (; sk != NULL && i > 0; i--)
24913
0
        sk = sk->next;
24914
0
    if (sk == NULL)
24915
0
        return NULL;
24916
24917
0
    switch (sk->type) {
24918
0
        case STACK_TYPE_X509:
24919
0
            return (void*)sk->data.x509;
24920
0
        case STACK_TYPE_GEN_NAME:
24921
0
            return (void*)sk->data.gn;
24922
0
        case STACK_TYPE_BIO:
24923
0
            return (void*)sk->data.bio;
24924
0
        case STACK_TYPE_OBJ:
24925
0
            return (void*)sk->data.obj;
24926
0
        case STACK_TYPE_STRING:
24927
0
            return (void*)sk->data.string;
24928
0
        case STACK_TYPE_CIPHER:
24929
0
            return (void*)&sk->data.cipher;
24930
0
        case STACK_TYPE_ACCESS_DESCRIPTION:
24931
0
            return (void*)sk->data.access;
24932
0
        case STACK_TYPE_X509_EXT:
24933
0
            return (void*)sk->data.ext;
24934
0
        case STACK_TYPE_X509_REQ_ATTR:
24935
0
            return (void*)sk->data.generic;
24936
0
        case STACK_TYPE_NULL:
24937
0
            return (void*)sk->data.generic;
24938
0
        case STACK_TYPE_X509_NAME:
24939
0
            return (void*)sk->data.name;
24940
0
        case STACK_TYPE_X509_NAME_ENTRY:
24941
0
            return (void*)sk->data.name_entry;
24942
0
        case STACK_TYPE_CONF_VALUE:
24943
0
    #ifdef OPENSSL_EXTRA
24944
0
            return (void*)sk->data.conf;
24945
    #else
24946
            return NULL;
24947
    #endif
24948
0
        case STACK_TYPE_X509_INFO:
24949
0
            return (void*)sk->data.info;
24950
0
        case STACK_TYPE_BY_DIR_entry:
24951
0
            return (void*)sk->data.dir_entry;
24952
0
        case STACK_TYPE_BY_DIR_hash:
24953
0
            return (void*)sk->data.dir_hash;
24954
0
        case STACK_TYPE_X509_OBJ:
24955
0
            return (void*)sk->data.x509_obj;
24956
0
        case STACK_TYPE_DIST_POINT:
24957
0
            return (void*)sk->data.dp;
24958
0
        case STACK_TYPE_X509_CRL:
24959
0
            return (void*)sk->data.crl;
24960
0
        default:
24961
0
            return (void*)sk->data.generic;
24962
0
    }
24963
0
}
24964
24965
/* copies over data of "in" to "out" */
24966
static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out)
24967
0
{
24968
0
    if (in == NULL || out == NULL)
24969
0
        return;
24970
24971
0
    *out = *in;
24972
0
}
24973
24974
WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk)
24975
0
{
24976
24977
0
    WOLFSSL_STACK* ret = NULL;
24978
0
    WOLFSSL_STACK* last = NULL;
24979
24980
0
    WOLFSSL_ENTER("wolfSSL_sk_dup");
24981
24982
0
    while (sk) {
24983
0
        WOLFSSL_STACK* cur = wolfSSL_sk_new_node(sk->heap);
24984
24985
0
        if (!cur) {
24986
0
            WOLFSSL_MSG("wolfSSL_sk_new_node error");
24987
0
            goto error;
24988
0
        }
24989
24990
0
        if (!ret) {
24991
            /* Set first node */
24992
0
            ret = cur;
24993
0
        }
24994
24995
0
        if (last) {
24996
0
            last->next = cur;
24997
0
        }
24998
24999
0
        XMEMCPY(cur, sk, sizeof(WOLFSSL_STACK));
25000
25001
        /* We will allocate new memory for this */
25002
0
        XMEMSET(&cur->data, 0, sizeof(cur->data));
25003
0
        cur->next = NULL;
25004
25005
0
        switch (sk->type) {
25006
0
            case STACK_TYPE_X509:
25007
0
                if (!sk->data.x509)
25008
0
                    break;
25009
0
                cur->data.x509 = wolfSSL_X509_dup(sk->data.x509);
25010
0
                if (!cur->data.x509) {
25011
0
                    WOLFSSL_MSG("wolfSSL_X509_dup error");
25012
0
                    goto error;
25013
0
                }
25014
0
                break;
25015
0
            case STACK_TYPE_CIPHER:
25016
0
                wolfSSL_CIPHER_copy(&sk->data.cipher, &cur->data.cipher);
25017
0
                break;
25018
0
            case STACK_TYPE_GEN_NAME:
25019
0
                if (!sk->data.gn)
25020
0
                    break;
25021
0
                cur->data.gn = wolfSSL_GENERAL_NAME_dup(sk->data.gn);
25022
0
                if (!cur->data.gn) {
25023
0
                    WOLFSSL_MSG("wolfSSL_GENERAL_NAME_new error");
25024
0
                    goto error;
25025
0
                }
25026
0
                break;
25027
0
            case STACK_TYPE_OBJ:
25028
0
                if (!sk->data.obj)
25029
0
                    break;
25030
0
                cur->data.obj = wolfSSL_ASN1_OBJECT_dup(sk->data.obj);
25031
0
                if (!cur->data.obj) {
25032
0
                    WOLFSSL_MSG("wolfSSL_ASN1_OBJECT_dup error");
25033
0
                    goto error;
25034
0
                }
25035
0
                break;
25036
0
            case STACK_TYPE_BIO:
25037
0
            case STACK_TYPE_STRING:
25038
0
            case STACK_TYPE_ACCESS_DESCRIPTION:
25039
0
            case STACK_TYPE_X509_EXT:
25040
0
            case STACK_TYPE_X509_REQ_ATTR:
25041
0
            case STACK_TYPE_NULL:
25042
0
            case STACK_TYPE_X509_NAME:
25043
0
            case STACK_TYPE_X509_NAME_ENTRY:
25044
0
            case STACK_TYPE_CONF_VALUE:
25045
0
            case STACK_TYPE_X509_INFO:
25046
0
            case STACK_TYPE_BY_DIR_entry:
25047
0
            case STACK_TYPE_BY_DIR_hash:
25048
0
            case STACK_TYPE_X509_OBJ:
25049
0
            case STACK_TYPE_DIST_POINT:
25050
0
            case STACK_TYPE_X509_CRL:
25051
0
            default:
25052
0
                WOLFSSL_MSG("Unsupported stack type");
25053
0
                goto error;
25054
0
        }
25055
25056
0
        sk = sk->next;
25057
0
        last = cur;
25058
0
    }
25059
0
    return ret;
25060
25061
0
error:
25062
0
    if (ret) {
25063
0
        wolfSSL_sk_GENERAL_NAME_free(ret);
25064
0
    }
25065
0
    return NULL;
25066
0
}
25067
25068
/* Free the just the stack structure */
25069
void wolfSSL_sk_free(WOLFSSL_STACK* sk)
25070
0
{
25071
0
    WOLFSSL_ENTER("wolfSSL_sk_free");
25072
25073
0
    while (sk != NULL) {
25074
0
        WOLFSSL_STACK* next = sk->next;
25075
0
        XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
25076
0
        sk = next;
25077
0
    }
25078
0
}
25079
25080
/* Frees each node in the stack and frees the stack.
25081
 */
25082
void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk,
25083
    void (*f) (void*))
25084
0
{
25085
0
    WOLFSSL_ENTER("wolfSSL_sk_GENERIC_pop_free");
25086
0
    wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f);
25087
0
}
25088
25089
/* return 1 on success 0 on fail */
25090
int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic)
25091
0
{
25092
0
    WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push");
25093
25094
0
    return wolfSSL_sk_push(sk, generic);
25095
0
}
25096
void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk)
25097
0
{
25098
0
    wolfSSL_sk_free(sk);
25099
0
}
25100
25101
/* Free all nodes in a stack including the pushed objects */
25102
void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk,
25103
                                                       wolfSSL_sk_freefunc func)
25104
0
{
25105
0
    WOLFSSL_ENTER("wolfSSL_sk_pop_free");
25106
25107
0
    if (sk == NULL) {
25108
        /* pop_free can be called with NULL, do not print bad argument */
25109
0
        return;
25110
0
    }
25111
    #if defined(WOLFSSL_QT)
25112
    /* In Qt v15.5, it calls OPENSSL_sk_free(xxx, OPENSSL_sk_free).
25113
    *  By using OPENSSL_sk_free for free causes access violation.
25114
    *  Therefore, switching free func to wolfSSL_ACCESS_DESCRIPTION_free
25115
    *  is needed even the func isn't NULL.
25116
    */
25117
    if (sk->type == STACK_TYPE_ACCESS_DESCRIPTION) {
25118
        func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free;
25119
    }
25120
    #endif
25121
0
    if (func == NULL) {
25122
0
        switch(sk->type) {
25123
0
            case STACK_TYPE_ACCESS_DESCRIPTION:
25124
0
            #if defined(OPENSSL_ALL)
25125
0
                func = (wolfSSL_sk_freefunc)wolfSSL_ACCESS_DESCRIPTION_free;
25126
0
            #endif
25127
0
                break;
25128
0
            case STACK_TYPE_X509:
25129
0
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_free;
25130
0
                break;
25131
0
            case STACK_TYPE_X509_OBJ:
25132
0
            #ifdef OPENSSL_ALL
25133
0
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_OBJECT_free;
25134
0
            #endif
25135
0
                break;
25136
0
            case STACK_TYPE_OBJ:
25137
0
                func = (wolfSSL_sk_freefunc)wolfSSL_ASN1_OBJECT_free;
25138
0
                break;
25139
0
            case STACK_TYPE_DIST_POINT:
25140
0
            #ifdef OPENSSL_EXTRA
25141
0
                func = (wolfSSL_sk_freefunc)wolfSSL_DIST_POINT_free;
25142
0
            #endif
25143
0
                break;
25144
0
            case STACK_TYPE_GEN_NAME:
25145
0
                func = (wolfSSL_sk_freefunc)wolfSSL_GENERAL_NAME_free;
25146
0
                break;
25147
0
            case STACK_TYPE_STRING:
25148
0
            #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
25149
0
                defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
25150
0
                func = (wolfSSL_sk_freefunc)wolfSSL_WOLFSSL_STRING_free;
25151
0
            #endif
25152
0
                break;
25153
0
            case STACK_TYPE_X509_NAME:
25154
0
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
25155
0
                && !defined(WOLFCRYPT_ONLY)
25156
0
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_free;
25157
0
            #endif
25158
0
                break;
25159
0
            case STACK_TYPE_X509_NAME_ENTRY:
25160
0
            #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) \
25161
0
                && !defined(WOLFCRYPT_ONLY)
25162
0
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_NAME_ENTRY_free;
25163
0
            #endif
25164
0
                break;
25165
0
            case STACK_TYPE_X509_EXT:
25166
0
            #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
25167
0
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_EXTENSION_free;
25168
0
            #endif
25169
0
                break;
25170
0
            case STACK_TYPE_X509_REQ_ATTR:
25171
            #if defined(OPENSSL_ALL) && \
25172
                (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_REQ))
25173
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_ATTRIBUTE_free;
25174
            #endif
25175
0
                break;
25176
0
            case STACK_TYPE_CONF_VALUE:
25177
0
            #if defined(OPENSSL_ALL)
25178
0
                func = (wolfSSL_sk_freefunc)wolfSSL_X509V3_conf_free;
25179
0
            #endif
25180
0
                break;
25181
0
            case STACK_TYPE_X509_INFO:
25182
0
            #if defined(OPENSSL_ALL)
25183
0
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_INFO_free;
25184
0
            #endif
25185
0
                break;
25186
0
            case STACK_TYPE_BIO:
25187
0
#if !defined(NO_BIO) && defined(OPENSSL_EXTRA)
25188
0
                func = (wolfSSL_sk_freefunc)wolfSSL_BIO_vfree;
25189
0
#endif
25190
0
                break;
25191
0
            case STACK_TYPE_BY_DIR_entry:
25192
0
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
25193
0
                func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_entry_free;
25194
0
#endif
25195
0
                break;
25196
0
            case STACK_TYPE_BY_DIR_hash:
25197
0
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
25198
0
                func = (wolfSSL_sk_freefunc)wolfSSL_BY_DIR_HASH_free;
25199
0
#endif
25200
0
                break;
25201
0
            case STACK_TYPE_X509_CRL:
25202
#if defined(HAVE_CRL) && (defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL))
25203
                func = (wolfSSL_sk_freefunc)wolfSSL_X509_CRL_free;
25204
#endif
25205
0
                break;
25206
0
            case STACK_TYPE_CIPHER:
25207
0
            case STACK_TYPE_NULL:
25208
0
            default:
25209
0
                break;
25210
0
        }
25211
0
    }
25212
25213
0
    while (sk != NULL) {
25214
0
        WOLFSSL_STACK* next = sk->next;
25215
25216
0
        if (func != NULL) {
25217
0
            if (sk->type != STACK_TYPE_CIPHER)
25218
0
                func(sk->data.generic);
25219
0
        }
25220
0
        XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
25221
0
        sk = next;
25222
0
    }
25223
0
}
25224
25225
/* Creates and returns a new null stack. */
25226
WOLFSSL_STACK* wolfSSL_sk_new_null(void)
25227
0
{
25228
0
    WOLFSSL_STACK* sk;
25229
0
    WOLFSSL_ENTER("wolfSSL_sk_new_null");
25230
25231
0
    sk = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
25232
0
                                 DYNAMIC_TYPE_OPENSSL);
25233
0
    if (sk == NULL) {
25234
0
        WOLFSSL_MSG("WOLFSSL_STACK memory error");
25235
0
        return NULL;
25236
0
    }
25237
25238
0
    XMEMSET(sk, 0, sizeof(WOLFSSL_STACK));
25239
0
    sk->type = STACK_TYPE_NULL;
25240
25241
0
    return sk;
25242
0
}
25243
25244
int wolfSSL_sk_SSL_COMP_num(WOLF_STACK_OF(WOLFSSL_COMP)* sk)
25245
0
{
25246
0
    if (sk == NULL)
25247
0
        return 0;
25248
0
    return (int)sk->num;
25249
0
}
25250
25251
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
25252
25253
#if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
25254
        defined(HAVE_EXT_CACHE))
25255
/* stunnel 4.28 needs
25256
 *
25257
 * Callback that is called if a session tries to resume but could not find
25258
 * the session to resume it.
25259
 */
25260
void wolfSSL_CTX_sess_set_get_cb(WOLFSSL_CTX* ctx,
25261
                    WOLFSSL_SESSION*(*f)(WOLFSSL*, const unsigned char*, int, int*))
25262
0
{
25263
0
    if (ctx == NULL)
25264
0
        return;
25265
25266
0
#ifdef HAVE_EXT_CACHE
25267
0
    ctx->get_sess_cb = f;
25268
#else
25269
    (void)f;
25270
#endif
25271
0
}
25272
25273
void wolfSSL_CTX_sess_set_new_cb(WOLFSSL_CTX* ctx,
25274
                             int (*f)(WOLFSSL*, WOLFSSL_SESSION*))
25275
0
{
25276
0
    if (ctx == NULL)
25277
0
        return;
25278
25279
0
#ifdef HAVE_EXT_CACHE
25280
0
    ctx->new_sess_cb = f;
25281
#else
25282
    (void)f;
25283
#endif
25284
0
}
25285
25286
void wolfSSL_CTX_sess_set_remove_cb(WOLFSSL_CTX* ctx, void (*f)(WOLFSSL_CTX*,
25287
                                                        WOLFSSL_SESSION*))
25288
0
{
25289
0
    if (ctx == NULL)
25290
0
        return;
25291
25292
0
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
25293
0
    ctx->rem_sess_cb = f;
25294
#else
25295
    (void)f;
25296
#endif
25297
0
}
25298
25299
25300
/*
25301
 *
25302
 * Note: It is expected that the importing and exporting function have been
25303
 *       built with the same settings. For example if session tickets was
25304
 *       enabled with the wolfSSL library exporting a session then it is
25305
 *       expected to be turned on with the wolfSSL library importing the session.
25306
 */
25307
int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p)
25308
0
{
25309
0
    int size = 0;
25310
0
#ifdef HAVE_EXT_CACHE
25311
0
    int idx = 0;
25312
#ifdef SESSION_CERTS
25313
    int i;
25314
#endif
25315
0
    unsigned char *data;
25316
25317
0
    WOLFSSL_ENTER("wolfSSL_i2d_SSL_SESSION");
25318
25319
0
    sess = ClientSessionToSession(sess);
25320
0
    if (sess == NULL) {
25321
0
        return BAD_FUNC_ARG;
25322
0
    }
25323
25324
    /* side | bornOn | timeout | sessionID len | sessionID | masterSecret |
25325
     * haveEMS  */
25326
0
    size += OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN +
25327
0
            sess->sessionIDSz + SECRET_LEN + OPAQUE8_LEN;
25328
    /* altSessionID */
25329
0
    size += OPAQUE8_LEN + (sess->haveAltSessionID ? ID_LEN : 0);
25330
#ifdef SESSION_CERTS
25331
    /* Peer chain */
25332
    size += OPAQUE8_LEN;
25333
    for (i = 0; i < sess->chain.count; i++)
25334
        size += OPAQUE16_LEN + sess->chain.certs[i].length;
25335
#endif
25336
0
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
25337
0
                               defined(HAVE_SESSION_TICKET))
25338
    /* Protocol version */
25339
0
    size += OPAQUE16_LEN;
25340
0
#endif
25341
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
25342
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
25343
    /* cipher suite */
25344
0
    size += OPAQUE16_LEN;
25345
0
#endif
25346
0
#ifndef NO_CLIENT_CACHE
25347
    /* ServerID len | ServerID */
25348
0
    size += OPAQUE16_LEN + sess->idLen;
25349
0
#endif
25350
0
#ifdef OPENSSL_EXTRA
25351
    /* session context ID len | session context ID */
25352
0
    size += OPAQUE8_LEN + sess->sessionCtxSz;
25353
0
#endif
25354
0
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
25355
    /* peerVerifyRet */
25356
0
    size += OPAQUE8_LEN;
25357
0
#endif
25358
0
#ifdef WOLFSSL_TLS13
25359
    /* namedGroup */
25360
0
    size += OPAQUE16_LEN;
25361
0
#endif
25362
0
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
25363
0
#ifdef WOLFSSL_TLS13
25364
    /* ticketSeen | ticketAdd */
25365
0
    size += OPAQUE32_LEN + OPAQUE32_LEN;
25366
    /* ticketNonce */
25367
0
    size += OPAQUE8_LEN + sess->ticketNonce.len;
25368
0
#endif
25369
#ifdef WOLFSSL_EARLY_DATA
25370
    size += OPAQUE32_LEN;
25371
#endif
25372
0
#endif
25373
0
#ifdef HAVE_SESSION_TICKET
25374
    /* ticket len | ticket */
25375
0
    size += OPAQUE16_LEN + sess->ticketLen;
25376
0
#endif
25377
25378
0
    if (p != NULL) {
25379
0
        if (*p == NULL)
25380
0
            *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL);
25381
0
        if (*p == NULL)
25382
0
            return 0;
25383
0
        data = *p;
25384
25385
0
        data[idx++] = sess->side;
25386
0
        c32toa(sess->bornOn, data + idx); idx += OPAQUE32_LEN;
25387
0
        c32toa(sess->timeout, data + idx); idx += OPAQUE32_LEN;
25388
0
        data[idx++] = sess->sessionIDSz;
25389
0
        XMEMCPY(data + idx, sess->sessionID, sess->sessionIDSz);
25390
0
        idx += sess->sessionIDSz;
25391
0
        XMEMCPY(data + idx, sess->masterSecret, SECRET_LEN); idx += SECRET_LEN;
25392
0
        data[idx++] = (byte)sess->haveEMS;
25393
0
        data[idx++] = sess->haveAltSessionID ? ID_LEN : 0;
25394
0
        if (sess->haveAltSessionID) {
25395
0
            XMEMCPY(data + idx, sess->altSessionID, ID_LEN);
25396
0
            idx += ID_LEN;
25397
0
        }
25398
#ifdef SESSION_CERTS
25399
        data[idx++] = (byte)sess->chain.count;
25400
        for (i = 0; i < sess->chain.count; i++) {
25401
            c16toa((word16)sess->chain.certs[i].length, data + idx);
25402
            idx += OPAQUE16_LEN;
25403
            XMEMCPY(data + idx, sess->chain.certs[i].buffer,
25404
                    sess->chain.certs[i].length);
25405
            idx += sess->chain.certs[i].length;
25406
        }
25407
#endif
25408
0
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
25409
0
                               defined(HAVE_SESSION_TICKET))
25410
0
        data[idx++] = sess->version.major;
25411
0
        data[idx++] = sess->version.minor;
25412
0
#endif
25413
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
25414
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
25415
0
        data[idx++] = sess->cipherSuite0;
25416
0
        data[idx++] = sess->cipherSuite;
25417
0
#endif
25418
0
#ifndef NO_CLIENT_CACHE
25419
0
        c16toa(sess->idLen, data + idx); idx += OPAQUE16_LEN;
25420
0
        XMEMCPY(data + idx, sess->serverID, sess->idLen);
25421
0
        idx += sess->idLen;
25422
0
#endif
25423
0
#ifdef OPENSSL_EXTRA
25424
0
        data[idx++] = sess->sessionCtxSz;
25425
0
        XMEMCPY(data + idx, sess->sessionCtx, sess->sessionCtxSz);
25426
0
        idx += sess->sessionCtxSz;
25427
0
#endif
25428
0
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
25429
0
        data[idx++] = sess->peerVerifyRet;
25430
0
#endif
25431
0
#ifdef WOLFSSL_TLS13
25432
0
        c16toa(sess->namedGroup, data + idx);
25433
0
        idx += OPAQUE16_LEN;
25434
0
#endif
25435
0
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
25436
0
#ifdef WOLFSSL_TLS13
25437
0
    c32toa(sess->ticketSeen, data + idx);
25438
0
    idx += OPAQUE32_LEN;
25439
0
    c32toa(sess->ticketAdd, data + idx);
25440
0
    idx += OPAQUE32_LEN;
25441
0
    data[idx++] = sess->ticketNonce.len;
25442
0
    XMEMCPY(data + idx, sess->ticketNonce.data, sess->ticketNonce.len);
25443
0
    idx += sess->ticketNonce.len;
25444
0
#endif
25445
#ifdef WOLFSSL_EARLY_DATA
25446
        c32toa(sess->maxEarlyDataSz, data + idx);
25447
        idx += OPAQUE32_LEN;
25448
#endif
25449
0
#endif
25450
0
#ifdef HAVE_SESSION_TICKET
25451
0
        c16toa(sess->ticketLen, data + idx); idx += OPAQUE16_LEN;
25452
0
        XMEMCPY(data + idx, sess->ticket, sess->ticketLen);
25453
0
        idx += sess->ticketLen;
25454
0
#endif
25455
0
    }
25456
0
#endif
25457
25458
0
    (void)sess;
25459
0
    (void)p;
25460
0
#ifdef HAVE_EXT_CACHE
25461
0
    (void)idx;
25462
0
#endif
25463
25464
0
    return size;
25465
0
}
25466
25467
25468
/* TODO: no function to free new session.
25469
 *
25470
 * Note: It is expected that the importing and exporting function have been
25471
 *       built with the same settings. For example if session tickets was
25472
 *       enabled with the wolfSSL library exporting a session then it is
25473
 *       expected to be turned on with the wolfSSL library importing the session.
25474
 */
25475
WOLFSSL_SESSION* wolfSSL_d2i_SSL_SESSION(WOLFSSL_SESSION** sess,
25476
                                const unsigned char** p, long i)
25477
0
{
25478
0
    WOLFSSL_SESSION* s = NULL;
25479
0
    int ret = 0;
25480
0
#if defined(HAVE_EXT_CACHE)
25481
0
    int idx;
25482
0
    byte* data;
25483
#ifdef SESSION_CERTS
25484
    int j;
25485
    word16 length;
25486
#endif
25487
0
#endif /* HAVE_EXT_CACHE */
25488
25489
0
    (void)p;
25490
0
    (void)i;
25491
0
    (void)ret;
25492
0
    (void)sess;
25493
25494
0
#ifdef HAVE_EXT_CACHE
25495
0
    if (p == NULL || *p == NULL)
25496
0
        return NULL;
25497
25498
0
    s = wolfSSL_SESSION_new();
25499
0
    if (s == NULL)
25500
0
        return NULL;
25501
25502
0
    idx = 0;
25503
0
    data = (byte*)*p;
25504
25505
    /* side | bornOn | timeout | sessionID len */
25506
0
    if (i < OPAQUE8_LEN + OPAQUE32_LEN + OPAQUE32_LEN + OPAQUE8_LEN) {
25507
0
        ret = BUFFER_ERROR;
25508
0
        goto end;
25509
0
    }
25510
0
    s->side = data[idx++];
25511
0
    ato32(data + idx, &s->bornOn); idx += OPAQUE32_LEN;
25512
0
    ato32(data + idx, &s->timeout); idx += OPAQUE32_LEN;
25513
0
    s->sessionIDSz = data[idx++];
25514
25515
    /* sessionID | secret | haveEMS | haveAltSessionID */
25516
0
    if (i - idx < s->sessionIDSz + SECRET_LEN + OPAQUE8_LEN + OPAQUE8_LEN) {
25517
0
        ret = BUFFER_ERROR;
25518
0
        goto end;
25519
0
    }
25520
0
    XMEMCPY(s->sessionID, data + idx, s->sessionIDSz);
25521
0
    idx  += s->sessionIDSz;
25522
0
    XMEMCPY(s->masterSecret, data + idx, SECRET_LEN); idx += SECRET_LEN;
25523
0
    s->haveEMS = data[idx++];
25524
0
    if (data[idx] != ID_LEN && data[idx] != 0) {
25525
0
        ret = BUFFER_ERROR;
25526
0
        goto end;
25527
0
    }
25528
0
    s->haveAltSessionID = data[idx++] == ID_LEN;
25529
25530
    /* altSessionID */
25531
0
    if (s->haveAltSessionID) {
25532
0
        if (i - idx < ID_LEN) {
25533
0
            ret = BUFFER_ERROR;
25534
0
            goto end;
25535
0
        }
25536
0
        XMEMCPY(s->altSessionID, data + idx, ID_LEN); idx += ID_LEN;
25537
0
    }
25538
25539
#ifdef SESSION_CERTS
25540
    /* Certificate chain */
25541
    if (i - idx == 0) {
25542
        ret = BUFFER_ERROR;
25543
        goto end;
25544
    }
25545
    s->chain.count = data[idx++];
25546
    for (j = 0; j < s->chain.count; j++) {
25547
        if (i - idx < OPAQUE16_LEN) {
25548
            ret = BUFFER_ERROR;
25549
            goto end;
25550
        }
25551
        ato16(data + idx, &length); idx += OPAQUE16_LEN;
25552
        s->chain.certs[j].length = length;
25553
        if (i - idx < length) {
25554
            ret = BUFFER_ERROR;
25555
            goto end;
25556
        }
25557
        XMEMCPY(s->chain.certs[j].buffer, data + idx, length);
25558
        idx += length;
25559
    }
25560
#endif
25561
0
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
25562
0
                               defined(HAVE_SESSION_TICKET))
25563
    /* Protocol Version */
25564
0
    if (i - idx < OPAQUE16_LEN) {
25565
0
        ret = BUFFER_ERROR;
25566
0
        goto end;
25567
0
    }
25568
0
    s->version.major = data[idx++];
25569
0
    s->version.minor = data[idx++];
25570
0
#endif
25571
0
#if defined(SESSION_CERTS) || !defined(NO_RESUME_SUITE_CHECK) || \
25572
0
                        (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
25573
    /* Cipher suite */
25574
0
    if (i - idx < OPAQUE16_LEN) {
25575
0
        ret = BUFFER_ERROR;
25576
0
        goto end;
25577
0
    }
25578
0
    s->cipherSuite0 = data[idx++];
25579
0
    s->cipherSuite = data[idx++];
25580
0
#endif
25581
0
#ifndef NO_CLIENT_CACHE
25582
    /* ServerID len */
25583
0
    if (i - idx < OPAQUE16_LEN) {
25584
0
        ret = BUFFER_ERROR;
25585
0
        goto end;
25586
0
    }
25587
0
    ato16(data + idx, &s->idLen); idx += OPAQUE16_LEN;
25588
25589
    /* ServerID */
25590
0
    if (i - idx < s->idLen) {
25591
0
        ret = BUFFER_ERROR;
25592
0
        goto end;
25593
0
    }
25594
0
    XMEMCPY(s->serverID, data + idx, s->idLen); idx += s->idLen;
25595
0
#endif
25596
0
#ifdef OPENSSL_EXTRA
25597
    /* byte for length of session context ID */
25598
0
    if (i - idx < OPAQUE8_LEN) {
25599
0
        ret = BUFFER_ERROR;
25600
0
        goto end;
25601
0
    }
25602
0
    s->sessionCtxSz = data[idx++];
25603
25604
    /* app session context ID */
25605
0
    if (i - idx < s->sessionCtxSz) {
25606
0
        ret = BUFFER_ERROR;
25607
0
        goto end;
25608
0
    }
25609
0
    XMEMCPY(s->sessionCtx, data + idx, s->sessionCtxSz); idx += s->sessionCtxSz;
25610
0
#endif
25611
0
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
25612
    /* byte for peerVerifyRet */
25613
0
    if (i - idx < OPAQUE8_LEN) {
25614
0
        ret = BUFFER_ERROR;
25615
0
        goto end;
25616
0
    }
25617
0
    s->peerVerifyRet = data[idx++];
25618
0
#endif
25619
0
#ifdef WOLFSSL_TLS13
25620
0
    if (i - idx < OPAQUE16_LEN) {
25621
0
        ret = BUFFER_ERROR;
25622
0
        goto end;
25623
0
    }
25624
0
    ato16(data + idx, &s->namedGroup);
25625
0
    idx += OPAQUE16_LEN;
25626
0
#endif
25627
0
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
25628
0
#ifdef WOLFSSL_TLS13
25629
0
    if (i - idx < (OPAQUE32_LEN * 2)) {
25630
0
        ret = BUFFER_ERROR;
25631
0
        goto end;
25632
0
    }
25633
0
    ato32(data + idx, &s->ticketSeen);
25634
0
    idx += OPAQUE32_LEN;
25635
0
    ato32(data + idx, &s->ticketAdd);
25636
0
    idx += OPAQUE32_LEN;
25637
0
    if (i - idx < OPAQUE8_LEN) {
25638
0
        ret = BUFFER_ERROR;
25639
0
        goto end;
25640
0
    }
25641
0
    s->ticketNonce.len = data[idx++];
25642
25643
0
    if (i - idx < s->ticketNonce.len) {
25644
0
        ret = BUFFER_ERROR;
25645
0
        goto end;
25646
0
    }
25647
0
    XMEMCPY(s->ticketNonce.data, data + idx, s->ticketNonce.len);
25648
0
    idx += s->ticketNonce.len;
25649
0
#endif
25650
#ifdef WOLFSSL_EARLY_DATA
25651
    if (i - idx < OPAQUE32_LEN) {
25652
        ret = BUFFER_ERROR;
25653
        goto end;
25654
    }
25655
    ato32(data + idx, &s->maxEarlyDataSz);
25656
    idx += OPAQUE32_LEN;
25657
#endif
25658
0
#endif
25659
0
#ifdef HAVE_SESSION_TICKET
25660
    /* ticket len */
25661
0
    if (i - idx < OPAQUE16_LEN) {
25662
0
        ret = BUFFER_ERROR;
25663
0
        goto end;
25664
0
    }
25665
0
    ato16(data + idx, &s->ticketLen); idx += OPAQUE16_LEN;
25666
25667
    /* Dispose of ol dynamic ticket and ensure space for new ticket. */
25668
0
    if (s->ticketLenAlloc > 0) {
25669
0
        XFREE(s->ticket, NULL, DYNAMIC_TYPE_SESSION_TICK);
25670
0
    }
25671
0
    if (s->ticketLen <= SESSION_TICKET_LEN)
25672
0
        s->ticket = s->staticTicket;
25673
0
    else {
25674
0
        s->ticket = (byte*)XMALLOC(s->ticketLen, NULL,
25675
0
                                   DYNAMIC_TYPE_SESSION_TICK);
25676
0
        if (s->ticket == NULL) {
25677
0
            ret = MEMORY_ERROR;
25678
0
            goto end;
25679
0
        }
25680
0
        s->ticketLenAlloc = (word16)s->ticketLen;
25681
0
    }
25682
25683
    /* ticket */
25684
0
    if (i - idx < s->ticketLen) {
25685
0
        ret = BUFFER_ERROR;
25686
0
        goto end;
25687
0
    }
25688
0
    XMEMCPY(s->ticket, data + idx, s->ticketLen); idx += s->ticketLen;
25689
0
#endif
25690
0
    (void)idx;
25691
25692
0
    if (sess != NULL) {
25693
0
        *sess = s;
25694
0
    }
25695
25696
0
    *p += idx;
25697
25698
0
end:
25699
0
    if (ret != 0 && (sess == NULL || *sess != s)) {
25700
0
        wolfSSL_SESSION_free(s);
25701
0
        s = NULL;
25702
0
    }
25703
0
#endif /* HAVE_EXT_CACHE */
25704
0
    return s;
25705
0
}
25706
25707
/* Check if there is a session ticket associated with this WOLFSSL_SESSION.
25708
 *
25709
 * sess - pointer to WOLFSSL_SESSION struct
25710
 *
25711
 * Returns 1 if has session ticket, otherwise 0 */
25712
int wolfSSL_SESSION_has_ticket(const WOLFSSL_SESSION* sess)
25713
0
{
25714
0
    WOLFSSL_ENTER("wolfSSL_SESSION_has_ticket");
25715
0
#ifdef HAVE_SESSION_TICKET
25716
0
    sess = ClientSessionToSession(sess);
25717
0
    if (sess) {
25718
0
        if ((sess->ticketLen > 0) && (sess->ticket != NULL)) {
25719
0
            return WOLFSSL_SUCCESS;
25720
0
        }
25721
0
    }
25722
#else
25723
    (void)sess;
25724
#endif
25725
0
    return WOLFSSL_FAILURE;
25726
0
}
25727
25728
unsigned long wolfSSL_SESSION_get_ticket_lifetime_hint(
25729
                  const WOLFSSL_SESSION* sess)
25730
0
{
25731
0
    WOLFSSL_ENTER("wolfSSL_SESSION_get_ticket_lifetime_hint");
25732
0
    sess = ClientSessionToSession(sess);
25733
0
    if (sess) {
25734
0
        return sess->timeout;
25735
0
    }
25736
0
    return 0;
25737
0
}
25738
25739
long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION* sess)
25740
0
{
25741
0
    long timeout = 0;
25742
0
    WOLFSSL_ENTER("wolfSSL_SESSION_get_timeout");
25743
0
    sess = ClientSessionToSession(sess);
25744
0
    if (sess)
25745
0
        timeout = sess->timeout;
25746
0
    return timeout;
25747
0
}
25748
25749
25750
long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION* sess)
25751
0
{
25752
0
    long bornOn = 0;
25753
0
    WOLFSSL_ENTER("wolfSSL_SESSION_get_time");
25754
0
    sess = ClientSessionToSession(sess);
25755
0
    if (sess)
25756
0
        bornOn = sess->bornOn;
25757
0
    return bornOn;
25758
0
}
25759
25760
long wolfSSL_SSL_SESSION_set_timeout(WOLFSSL_SESSION* ses, long t)
25761
0
{
25762
0
    word32 tmptime;
25763
25764
0
    ses = ClientSessionToSession(ses);
25765
0
    if (ses == NULL || t < 0) {
25766
0
        return BAD_FUNC_ARG;
25767
0
    }
25768
25769
0
    tmptime = t & 0xFFFFFFFF;
25770
0
    ses->timeout = tmptime;
25771
25772
0
    return WOLFSSL_SUCCESS;
25773
0
}
25774
25775
#endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
25776
25777
#ifdef OPENSSL_EXTRA
25778
25779
#if defined(HAVE_EX_DATA) && !defined(NO_FILESYSTEM)
25780
int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
25781
{
25782
    int ret = WOLFSSL_FATAL_ERROR;
25783
25784
    WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
25785
    if (ssl != NULL && fname != NULL)
25786
    {
25787
    #ifdef WOLFSSL_SMALL_STACK
25788
        byte           staticBuffer[1]; /* force heap usage */
25789
    #else
25790
        byte           staticBuffer[FILE_BUFFER_SIZE];
25791
    #endif
25792
        byte*          myBuffer  = staticBuffer;
25793
        int            dynamic   = 0;
25794
        XFILE          file;
25795
        long           sz        = 0;
25796
        WOLFSSL_CTX*   ctx       = ssl->ctx;
25797
        WOLFSSL_X509*  peer_cert = &ssl->peerCert;
25798
        DerBuffer*     fileDer = NULL;
25799
25800
        file = XFOPEN(fname, "rb");
25801
        if (file == XBADFILE)
25802
            return WOLFSSL_BAD_FILE;
25803
25804
        if (XFSEEK(file, 0, XSEEK_END) != 0) {
25805
            XFCLOSE(file);
25806
            return WOLFSSL_BAD_FILE;
25807
        }
25808
        sz = XFTELL(file);
25809
        XREWIND(file);
25810
25811
        if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
25812
            WOLFSSL_MSG("cmp_peer_cert_to_file size error");
25813
            XFCLOSE(file);
25814
            return WOLFSSL_BAD_FILE;
25815
        }
25816
25817
        if (sz > (long)sizeof(staticBuffer)) {
25818
            WOLFSSL_MSG("Getting dynamic buffer");
25819
            myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
25820
            dynamic = 1;
25821
        }
25822
25823
        if ((myBuffer != NULL) &&
25824
            (sz > 0) &&
25825
            (XFREAD(myBuffer, 1, sz, file) == (size_t)sz) &&
25826
            (PemToDer(myBuffer, (long)sz, CERT_TYPE,
25827
                      &fileDer, ctx->heap, NULL, NULL) == 0) &&
25828
            (fileDer->length != 0) &&
25829
            (fileDer->length == peer_cert->derCert->length) &&
25830
            (XMEMCMP(peer_cert->derCert->buffer, fileDer->buffer,
25831
                                                fileDer->length) == 0))
25832
        {
25833
            ret = 0;
25834
        }
25835
25836
        FreeDer(&fileDer);
25837
25838
        if (dynamic)
25839
            XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE);
25840
25841
        XFCLOSE(file);
25842
    }
25843
25844
    return ret;
25845
}
25846
#endif
25847
#endif /* OPENSSL_EXTRA */
25848
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
25849
const WOLFSSL_ObjectInfo wolfssl_object_info[] = {
25850
#ifndef NO_CERTS
25851
    /* oidCertExtType */
25852
    { NID_basic_constraints, BASIC_CA_OID, oidCertExtType, "basicConstraints",
25853
                                                "X509v3 Basic Constraints"},
25854
    { NID_subject_alt_name, ALT_NAMES_OID, oidCertExtType, "subjectAltName",
25855
                                         "X509v3 Subject Alternative Name"},
25856
    { NID_crl_distribution_points, CRL_DIST_OID, oidCertExtType, "crlDistributionPoints",
25857
                                          "X509v3 CRL Distribution Points"},
25858
    { NID_info_access, AUTH_INFO_OID, oidCertExtType, "authorityInfoAccess",
25859
                                            "Authority Information Access"},
25860
    { NID_authority_key_identifier, AUTH_KEY_OID, oidCertExtType,
25861
               "authorityKeyIdentifier", "X509v3 Authority Key Identifier"},
25862
    { NID_subject_key_identifier, SUBJ_KEY_OID, oidCertExtType,
25863
                   "subjectKeyIdentifier", "X509v3 Subject Key Identifier"},
25864
    { NID_key_usage, KEY_USAGE_OID, oidCertExtType, "keyUsage",
25865
                                                        "X509v3 Key Usage"},
25866
    { NID_inhibit_any_policy, INHIBIT_ANY_OID, oidCertExtType,
25867
                           "inhibitAnyPolicy", "X509v3 Inhibit Any Policy"},
25868
    { NID_ext_key_usage, EXT_KEY_USAGE_OID, oidCertExtType,
25869
                           "extendedKeyUsage", "X509v3 Extended Key Usage"},
25870
    { NID_name_constraints, NAME_CONS_OID, oidCertExtType,
25871
                              "nameConstraints", "X509v3 Name Constraints"},
25872
    { NID_certificate_policies, CERT_POLICY_OID, oidCertExtType,
25873
                      "certificatePolicies", "X509v3 Certificate Policies"},
25874
25875
    /* oidCertAuthInfoType */
25876
    { NID_ad_OCSP, AIA_OCSP_OID, oidCertAuthInfoType, "OCSP",
25877
                                            "OCSP"},
25878
    { NID_ad_ca_issuers, AIA_CA_ISSUER_OID, oidCertAuthInfoType,
25879
                                                 "caIssuers", "CA Issuers"},
25880
25881
    /* oidCertPolicyType */
25882
    { NID_any_policy, CP_ANY_OID, oidCertPolicyType, "anyPolicy",
25883
                                                       "X509v3 Any Policy"},
25884
25885
    /* oidCertAltNameType */
25886
    { NID_hw_name_oid, HW_NAME_OID, oidCertAltNameType, "Hardware name",""},
25887
25888
    /* oidCertKeyUseType */
25889
    { NID_anyExtendedKeyUsage, EKU_ANY_OID, oidCertKeyUseType,
25890
                           "anyExtendedKeyUsage", "Any Extended Key Usage"},
25891
    { EKU_SERVER_AUTH_OID, EKU_SERVER_AUTH_OID, oidCertKeyUseType,
25892
                             "serverAuth", "TLS Web Server Authentication"},
25893
    { EKU_CLIENT_AUTH_OID, EKU_CLIENT_AUTH_OID, oidCertKeyUseType,
25894
                             "clientAuth", "TLS Web Client Authentication"},
25895
    { EKU_OCSP_SIGN_OID, EKU_OCSP_SIGN_OID, oidCertKeyUseType,
25896
                                             "OCSPSigning", "OCSP Signing"},
25897
25898
    /* oidCertNameType */
25899
    { NID_commonName, NID_commonName, oidCertNameType, "CN", "commonName"},
25900
    { NID_surname, NID_surname, oidCertNameType, "SN", "surname"},
25901
    { NID_serialNumber, NID_serialNumber, oidCertNameType, "serialNumber",
25902
                                                            "serialNumber"},
25903
    { NID_userId, NID_userId, oidCertNameType, "UID", "userid"},
25904
    { NID_countryName, NID_countryName, oidCertNameType, "C", "countryName"},
25905
    { NID_localityName, NID_localityName, oidCertNameType, "L", "localityName"},
25906
    { NID_stateOrProvinceName, NID_stateOrProvinceName, oidCertNameType, "ST",
25907
                                                        "stateOrProvinceName"},
25908
    { NID_streetAddress, NID_streetAddress, oidCertNameType, "street",
25909
                                                        "streetAddress"},
25910
    { NID_organizationName, NID_organizationName, oidCertNameType, "O",
25911
                                                        "organizationName"},
25912
    { NID_organizationalUnitName, NID_organizationalUnitName, oidCertNameType,
25913
                                                "OU", "organizationalUnitName"},
25914
    { NID_emailAddress, NID_emailAddress, oidCertNameType, "emailAddress",
25915
                                                            "emailAddress"},
25916
    { NID_domainComponent, NID_domainComponent, oidCertNameType, "DC",
25917
                                                            "domainComponent"},
25918
    { NID_favouriteDrink, NID_favouriteDrink, oidCertNameType, "favouriteDrink",
25919
                                                            "favouriteDrink"},
25920
    { NID_businessCategory, NID_businessCategory, oidCertNameType, "businessCategory",
25921
                                                            "businessCategory"},
25922
    { NID_jurisdictionCountryName, NID_jurisdictionCountryName, oidCertNameType, "jurisdictionC",
25923
                                                            "jurisdictionCountryName"},
25924
    { NID_jurisdictionStateOrProvinceName, NID_jurisdictionStateOrProvinceName,
25925
            oidCertNameType, "jurisdictionST", "jurisdictionStateOrProvinceName"},
25926
    { NID_postalCode, NID_postalCode, oidCertNameType, "postalCode", "postalCode"},
25927
    { NID_userId, NID_userId, oidCertNameType, "UID", "userId"},
25928
25929
#ifdef WOLFSSL_CERT_REQ
25930
    { NID_pkcs9_challengePassword, CHALLENGE_PASSWORD_OID,
25931
            oidCsrAttrType, "challengePassword", "challengePassword"},
25932
    { NID_pkcs9_contentType, PKCS9_CONTENT_TYPE_OID,
25933
        oidCsrAttrType, "contentType", "contentType" },
25934
    { NID_pkcs9_unstructuredName, UNSTRUCTURED_NAME_OID,
25935
        oidCsrAttrType, "unstructuredName", "unstructuredName" },
25936
    { NID_name, NAME_OID, oidCsrAttrType, "name", "name" },
25937
    { NID_surname, SURNAME_OID,
25938
        oidCsrAttrType, "surname", "surname" },
25939
    { NID_givenName, GIVEN_NAME_OID,
25940
        oidCsrAttrType, "givenName", "givenName" },
25941
    { NID_initials, INITIALS_OID,
25942
        oidCsrAttrType, "initials", "initials" },
25943
    { NID_dnQualifier, DNQUALIFIER_OID,
25944
        oidCsrAttrType, "dnQualifer", "dnQualifier" },
25945
#endif
25946
#endif
25947
#ifdef OPENSSL_EXTRA /* OPENSSL_EXTRA_X509_SMALL only needs the above */
25948
        /* oidHashType */
25949
    #ifdef WOLFSSL_MD2
25950
        { NID_md2, MD2h, oidHashType, "MD2", "md2"},
25951
    #endif
25952
    #ifdef WOLFSSL_MD5
25953
        { NID_md5, MD5h, oidHashType, "MD5", "md5"},
25954
    #endif
25955
    #ifndef NO_SHA
25956
        { NID_sha1, SHAh, oidHashType, "SHA1", "sha1"},
25957
    #endif
25958
    #ifdef WOLFSSL_SHA224
25959
        { NID_sha224, SHA224h, oidHashType, "SHA224", "sha224"},
25960
    #endif
25961
    #ifndef NO_SHA256
25962
        { NID_sha256, SHA256h, oidHashType, "SHA256", "sha256"},
25963
    #endif
25964
    #ifdef WOLFSSL_SHA384
25965
        { NID_sha384, SHA384h, oidHashType, "SHA384", "sha384"},
25966
    #endif
25967
    #ifdef WOLFSSL_SHA512
25968
        { NID_sha512, SHA512h, oidHashType, "SHA512", "sha512"},
25969
    #endif
25970
    #ifdef WOLFSSL_SHA3
25971
        #ifndef WOLFSSL_NOSHA3_224
25972
        { NID_sha3_224, SHA3_224h, oidHashType, "SHA3-224", "sha3-224"},
25973
        #endif
25974
        #ifndef WOLFSSL_NOSHA3_256
25975
        { NID_sha3_256, SHA3_256h, oidHashType, "SHA3-256", "sha3-256"},
25976
        #endif
25977
        #ifndef WOLFSSL_NOSHA3_384
25978
        { NID_sha3_384, SHA3_384h, oidHashType, "SHA3-384", "sha3-384"},
25979
        #endif
25980
        #ifndef WOLFSSL_NOSHA3_512
25981
        { NID_sha3_512, SHA3_512h, oidHashType, "SHA3-512", "sha3-512"},
25982
        #endif
25983
    #endif /* WOLFSSL_SHA3 */
25984
        /* oidSigType */
25985
    #ifndef NO_DSA
25986
        #ifndef NO_SHA
25987
        { NID_dsaWithSHA1, CTC_SHAwDSA, oidSigType, "DSA-SHA1", "dsaWithSHA1"},
25988
        { NID_dsa_with_SHA256, CTC_SHA256wDSA, oidSigType, "dsa_with_SHA256",
25989
                                                        "dsa_with_SHA256"},
25990
        #endif
25991
    #endif /* NO_DSA */
25992
    #ifndef NO_RSA
25993
        #ifdef WOLFSSL_MD2
25994
        { NID_md2WithRSAEncryption, CTC_MD2wRSA, oidSigType, "RSA-MD2",
25995
                                                        "md2WithRSAEncryption"},
25996
        #endif
25997
        #ifndef NO_MD5
25998
        { NID_md5WithRSAEncryption, CTC_MD5wRSA, oidSigType, "RSA-MD5",
25999
                                                        "md5WithRSAEncryption"},
26000
        #endif
26001
        #ifndef NO_SHA
26002
        { NID_sha1WithRSAEncryption, CTC_SHAwRSA, oidSigType, "RSA-SHA1",
26003
                                                       "sha1WithRSAEncryption"},
26004
        #endif
26005
        #ifdef WOLFSSL_SHA224
26006
        { NID_sha224WithRSAEncryption, CTC_SHA224wRSA, oidSigType, "RSA-SHA224",
26007
                                                     "sha224WithRSAEncryption"},
26008
        #endif
26009
        #ifndef NO_SHA256
26010
        { NID_sha256WithRSAEncryption, CTC_SHA256wRSA, oidSigType, "RSA-SHA256",
26011
                                                     "sha256WithRSAEncryption"},
26012
        #endif
26013
        #ifdef WOLFSSL_SHA384
26014
        { NID_sha384WithRSAEncryption, CTC_SHA384wRSA, oidSigType, "RSA-SHA384",
26015
                                                     "sha384WithRSAEncryption"},
26016
        #endif
26017
        #ifdef WOLFSSL_SHA512
26018
        { NID_sha512WithRSAEncryption, CTC_SHA512wRSA, oidSigType, "RSA-SHA512",
26019
                                                     "sha512WithRSAEncryption"},
26020
        #endif
26021
        #ifdef WOLFSSL_SHA3
26022
        #ifndef WOLFSSL_NOSHA3_224
26023
        { NID_RSA_SHA3_224, CTC_SHA3_224wRSA, oidSigType, "RSA-SHA3-224",
26024
                                                     "sha3-224WithRSAEncryption"},
26025
        #endif
26026
        #ifndef WOLFSSL_NOSHA3_256
26027
        { NID_RSA_SHA3_256, CTC_SHA3_256wRSA, oidSigType, "RSA-SHA3-256",
26028
                                                     "sha3-256WithRSAEncryption"},
26029
        #endif
26030
        #ifndef WOLFSSL_NOSHA3_384
26031
        { NID_RSA_SHA3_384, CTC_SHA3_384wRSA, oidSigType, "RSA-SHA3-384",
26032
                                                     "sha3-384WithRSAEncryption"},
26033
        #endif
26034
        #ifndef WOLFSSL_NOSHA3_512
26035
        { NID_RSA_SHA3_512, CTC_SHA3_512wRSA, oidSigType, "RSA-SHA3-512",
26036
                                                     "sha3-512WithRSAEncryption"},
26037
        #endif
26038
        #endif
26039
    #endif /* NO_RSA */
26040
    #ifdef HAVE_ECC
26041
        #ifndef NO_SHA
26042
        { NID_ecdsa_with_SHA1, CTC_SHAwECDSA, oidSigType, "ecdsa-with-SHA1", "shaWithECDSA"},
26043
        #endif
26044
        #ifdef WOLFSSL_SHA224
26045
        { NID_ecdsa_with_SHA224, CTC_SHA224wECDSA, oidSigType, "ecdsa-with-SHA224","sha224WithECDSA"},
26046
        #endif
26047
        #ifndef NO_SHA256
26048
        { NID_ecdsa_with_SHA256, CTC_SHA256wECDSA, oidSigType, "ecdsa-with-SHA256","sha256WithECDSA"},
26049
        #endif
26050
        #ifdef WOLFSSL_SHA384
26051
        { NID_ecdsa_with_SHA384, CTC_SHA384wECDSA, oidSigType, "ecdsa-with-SHA384","sha384WithECDSA"},
26052
        #endif
26053
        #ifdef WOLFSSL_SHA512
26054
        { NID_ecdsa_with_SHA512, CTC_SHA512wECDSA, oidSigType, "ecdsa-with-SHA512","sha512WithECDSA"},
26055
        #endif
26056
        #ifdef WOLFSSL_SHA3
26057
        #ifndef WOLFSSL_NOSHA3_224
26058
        { NID_ecdsa_with_SHA3_224, CTC_SHA3_224wECDSA, oidSigType, "id-ecdsa-with-SHA3-224",
26059
                "ecdsa_with_SHA3-224"},
26060
        #endif
26061
        #ifndef WOLFSSL_NOSHA3_256
26062
        { NID_ecdsa_with_SHA3_256, CTC_SHA3_256wECDSA, oidSigType, "id-ecdsa-with-SHA3-256",
26063
                "ecdsa_with_SHA3-256"},
26064
        #endif
26065
        #ifndef WOLFSSL_NOSHA3_384
26066
        { NID_ecdsa_with_SHA3_384, CTC_SHA3_384wECDSA, oidSigType, "id-ecdsa-with-SHA3-384",
26067
                "ecdsa_with_SHA3-384"},
26068
        #endif
26069
        #ifndef WOLFSSL_NOSHA3_512
26070
        { NID_ecdsa_with_SHA3_512, CTC_SHA3_512wECDSA, oidSigType, "id-ecdsa-with-SHA3-512",
26071
                "ecdsa_with_SHA3-512"},
26072
        #endif
26073
        #endif
26074
    #endif /* HAVE_ECC */
26075
26076
        /* oidKeyType */
26077
    #ifndef NO_DSA
26078
        { NID_dsa, DSAk, oidKeyType, "DSA", "dsaEncryption"},
26079
    #endif /* NO_DSA */
26080
    #ifndef NO_RSA
26081
        { NID_rsaEncryption, RSAk, oidKeyType, "rsaEncryption", "rsaEncryption"},
26082
    #endif /* NO_RSA */
26083
    #ifdef HAVE_ECC
26084
        { NID_X9_62_id_ecPublicKey, ECDSAk, oidKeyType, "id-ecPublicKey",
26085
                                                        "id-ecPublicKey"},
26086
    #endif /* HAVE_ECC */
26087
    #ifndef NO_DH
26088
        { NID_dhKeyAgreement, DHk, oidKeyType, "dhKeyAgreement", "dhKeyAgreement"},
26089
    #endif
26090
    #ifdef HAVE_ED448
26091
        { NID_ED448, ED448k,  oidKeyType, "ED448", "ED448"},
26092
    #endif
26093
    #ifdef HAVE_ED25519
26094
        { NID_ED25519, ED25519k,  oidKeyType, "ED25519", "ED25519"},
26095
    #endif
26096
    #ifdef HAVE_PQC
26097
    #ifdef HAVE_FALCON
26098
        { CTC_FALCON_LEVEL1, FALCON_LEVEL1k,  oidKeyType, "Falcon Level 1",
26099
                                                          "Falcon Level 1"},
26100
        { CTC_FALCON_LEVEL5, FALCON_LEVEL5k,  oidKeyType, "Falcon Level 5",
26101
                                                          "Falcon Level 5"},
26102
    #endif /* HAVE_FALCON */
26103
    #ifdef HAVE_DILITHIUM
26104
        { CTC_DILITHIUM_LEVEL2, DILITHIUM_LEVEL2k,  oidKeyType,
26105
          "Dilithium Level 2", "Dilithium Level 2"},
26106
        { CTC_DILITHIUM_LEVEL3, DILITHIUM_LEVEL3k,  oidKeyType,
26107
          "Dilithium Level 3", "Dilithium Level 3"},
26108
        { CTC_DILITHIUM_LEVEL5, DILITHIUM_LEVEL5k,  oidKeyType,
26109
          "Dilithium Level 5", "Dilithium Level 5"},
26110
        { CTC_DILITHIUM_AES_LEVEL2, DILITHIUM_AES_LEVEL2k,  oidKeyType,
26111
          "Dilithium AES Level 2", "Dilithium AES Level 2"},
26112
        { CTC_DILITHIUM_AES_LEVEL3, DILITHIUM_AES_LEVEL3k,  oidKeyType,
26113
          "Dilithium AES Level 3", "Dilithium AES Level 3"},
26114
        { CTC_DILITHIUM_AES_LEVEL5, DILITHIUM_AES_LEVEL5k,  oidKeyType,
26115
          "Dilithium AES Level 5", "Dilithium AES Level 5"},
26116
    #endif /* HAVE_DILITHIUM */
26117
    #endif /* HAVE_PQC */
26118
26119
        /* oidCurveType */
26120
    #ifdef HAVE_ECC
26121
        { NID_X9_62_prime192v1, ECC_SECP192R1_OID, oidCurveType, "prime192v1", "prime192v1"},
26122
        { NID_X9_62_prime192v2, ECC_PRIME192V2_OID, oidCurveType, "prime192v2", "prime192v2"},
26123
        { NID_X9_62_prime192v3, ECC_PRIME192V3_OID, oidCurveType, "prime192v3", "prime192v3"},
26124
26125
        { NID_X9_62_prime239v1, ECC_PRIME239V1_OID, oidCurveType, "prime239v1", "prime239v1"},
26126
        { NID_X9_62_prime239v2, ECC_PRIME239V2_OID, oidCurveType, "prime239v2", "prime239v2"},
26127
        { NID_X9_62_prime239v3, ECC_PRIME239V3_OID, oidCurveType, "prime239v3", "prime239v3"},
26128
26129
        { NID_X9_62_prime256v1, ECC_SECP256R1_OID, oidCurveType, "prime256v1", "prime256v1"},
26130
26131
        { NID_secp112r1, ECC_SECP112R1_OID,  oidCurveType, "secp112r1", "secp112r1"},
26132
        { NID_secp112r2, ECC_SECP112R2_OID,  oidCurveType, "secp112r2", "secp112r2"},
26133
26134
        { NID_secp128r1, ECC_SECP128R1_OID,  oidCurveType, "secp128r1", "secp128r1"},
26135
        { NID_secp128r2, ECC_SECP128R2_OID,  oidCurveType, "secp128r2", "secp128r2"},
26136
26137
        { NID_secp160r1, ECC_SECP160R1_OID,  oidCurveType, "secp160r1", "secp160r1"},
26138
        { NID_secp160r2, ECC_SECP160R2_OID,  oidCurveType, "secp160r2", "secp160r2"},
26139
26140
        { NID_secp224r1, ECC_SECP224R1_OID,  oidCurveType, "secp224r1", "secp224r1"},
26141
        { NID_secp384r1, ECC_SECP384R1_OID,  oidCurveType, "secp384r1", "secp384r1"},
26142
        { NID_secp521r1, ECC_SECP521R1_OID,  oidCurveType, "secp521r1", "secp521r1"},
26143
26144
        { NID_secp160k1, ECC_SECP160K1_OID,  oidCurveType, "secp160k1", "secp160k1"},
26145
        { NID_secp192k1, ECC_SECP192K1_OID,  oidCurveType, "secp192k1", "secp192k1"},
26146
        { NID_secp224k1, ECC_SECP224K1_OID,  oidCurveType, "secp224k1", "secp224k1"},
26147
        { NID_secp256k1, ECC_SECP256K1_OID,  oidCurveType, "secp256k1", "secp256k1"},
26148
26149
        { NID_brainpoolP160r1, ECC_BRAINPOOLP160R1_OID,  oidCurveType, "brainpoolP160r1", "brainpoolP160r1"},
26150
        { NID_brainpoolP192r1, ECC_BRAINPOOLP192R1_OID,  oidCurveType, "brainpoolP192r1", "brainpoolP192r1"},
26151
        { NID_brainpoolP224r1, ECC_BRAINPOOLP224R1_OID,  oidCurveType, "brainpoolP224r1", "brainpoolP224r1"},
26152
        { NID_brainpoolP256r1, ECC_BRAINPOOLP256R1_OID,  oidCurveType, "brainpoolP256r1", "brainpoolP256r1"},
26153
        { NID_brainpoolP320r1, ECC_BRAINPOOLP320R1_OID,  oidCurveType, "brainpoolP320r1", "brainpoolP320r1"},
26154
        { NID_brainpoolP384r1, ECC_BRAINPOOLP384R1_OID,  oidCurveType, "brainpoolP384r1", "brainpoolP384r1"},
26155
        { NID_brainpoolP512r1, ECC_BRAINPOOLP512R1_OID,  oidCurveType, "brainpoolP512r1", "brainpoolP512r1"},
26156
    #endif /* HAVE_ECC */
26157
26158
        /* oidBlkType */
26159
    #ifdef WOLFSSL_AES_128
26160
        { AES128CBCb, AES128CBCb, oidBlkType, "AES-128-CBC", "aes-128-cbc"},
26161
    #endif
26162
    #ifdef WOLFSSL_AES_192
26163
        { AES192CBCb, AES192CBCb, oidBlkType, "AES-192-CBC", "aes-192-cbc"},
26164
    #endif
26165
    #ifdef WOLFSSL_AES_256
26166
        { AES256CBCb, AES256CBCb, oidBlkType, "AES-256-CBC", "aes-256-cbc"},
26167
    #endif
26168
    #ifndef NO_DES3
26169
        { NID_des, DESb, oidBlkType, "DES-CBC", "des-cbc"},
26170
        { NID_des3, DES3b, oidBlkType, "DES-EDE3-CBC", "des-ede3-cbc"},
26171
    #endif /* !NO_DES3 */
26172
    #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
26173
        { NID_chacha20_poly1305, NID_chacha20_poly1305, oidBlkType, "ChaCha20-Poly1305", "chacha20-poly1305"},
26174
    #endif
26175
26176
        /* oidOcspType */
26177
    #ifdef HAVE_OCSP
26178
        { NID_id_pkix_OCSP_basic, OCSP_BASIC_OID, oidOcspType, "basicOCSPResponse",
26179
                                                         "Basic OCSP Response"},
26180
        { OCSP_NONCE_OID, OCSP_NONCE_OID, oidOcspType, "Nonce",
26181
                                                                  "OCSP Nonce"},
26182
    #endif /* HAVE_OCSP */
26183
26184
    #ifndef NO_PWDBASED
26185
        /* oidKdfType */
26186
        { PBKDF2_OID, PBKDF2_OID, oidKdfType, "PBKDFv2", "PBKDF2"},
26187
26188
        /* oidPBEType */
26189
        { PBE_SHA1_RC4_128, PBE_SHA1_RC4_128, oidPBEType,
26190
                                 "PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4"},
26191
        { PBE_SHA1_DES, PBE_SHA1_DES, oidPBEType, "PBE-SHA1-DES",
26192
                                                       "pbeWithSHA1AndDES-CBC"},
26193
        { PBE_SHA1_DES3, PBE_SHA1_DES3, oidPBEType, "PBE-SHA1-3DES",
26194
                                            "pbeWithSHA1And3-KeyTripleDES-CBC"},
26195
    #endif
26196
26197
        /* oidKeyWrapType */
26198
    #ifdef WOLFSSL_AES_128
26199
        { AES128_WRAP, AES128_WRAP, oidKeyWrapType, "AES-128 wrap", "aes128-wrap"},
26200
    #endif
26201
    #ifdef WOLFSSL_AES_192
26202
        { AES192_WRAP, AES192_WRAP, oidKeyWrapType, "AES-192 wrap", "aes192-wrap"},
26203
    #endif
26204
    #ifdef WOLFSSL_AES_256
26205
        { AES256_WRAP, AES256_WRAP, oidKeyWrapType, "AES-256 wrap", "aes256-wrap"},
26206
    #endif
26207
26208
    #ifndef NO_PKCS7
26209
        #ifndef NO_DH
26210
        /* oidCmsKeyAgreeType */
26211
            #ifndef NO_SHA
26212
        { dhSinglePass_stdDH_sha1kdf_scheme, dhSinglePass_stdDH_sha1kdf_scheme,
26213
                oidCmsKeyAgreeType, "dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme"},
26214
            #endif
26215
            #ifdef WOLFSSL_SHA224
26216
        { dhSinglePass_stdDH_sha224kdf_scheme,
26217
                dhSinglePass_stdDH_sha224kdf_scheme, oidCmsKeyAgreeType,
26218
                "dhSinglePass-stdDH-sha224kdf-scheme", "dhSinglePass-stdDH-sha224kdf-scheme"},
26219
            #endif
26220
            #ifndef NO_SHA256
26221
        { dhSinglePass_stdDH_sha256kdf_scheme,
26222
                        dhSinglePass_stdDH_sha256kdf_scheme, oidCmsKeyAgreeType,
26223
                        "dhSinglePass-stdDH-sha256kdf-scheme", "dhSinglePass-stdDH-sha256kdf-scheme"},
26224
            #endif
26225
            #ifdef WOLFSSL_SHA384
26226
        { dhSinglePass_stdDH_sha384kdf_scheme,
26227
                        dhSinglePass_stdDH_sha384kdf_scheme, oidCmsKeyAgreeType,
26228
                        "dhSinglePass-stdDH-sha384kdf-scheme", "dhSinglePass-stdDH-sha384kdf-scheme"},
26229
            #endif
26230
            #ifdef WOLFSSL_SHA512
26231
        { dhSinglePass_stdDH_sha512kdf_scheme,
26232
                        dhSinglePass_stdDH_sha512kdf_scheme, oidCmsKeyAgreeType,
26233
                        "dhSinglePass-stdDH-sha512kdf-scheme", "dhSinglePass-stdDH-sha512kdf-scheme"},
26234
            #endif
26235
        #endif
26236
    #endif
26237
    #if defined(WOLFSSL_APACHE_HTTPD)
26238
        /* "1.3.6.1.5.5.7.8.7" */
26239
        { NID_id_on_dnsSRV, NID_id_on_dnsSRV, oidCertNameType,
26240
            WOLFSSL_SN_DNS_SRV, WOLFSSL_LN_DNS_SRV },
26241
26242
        /* "1.3.6.1.4.1.311.20.2.3" */
26243
        { NID_ms_upn, WOLFSSL_MS_UPN_SUM, oidCertExtType, WOLFSSL_SN_MS_UPN,
26244
            WOLFSSL_LN_MS_UPN },
26245
26246
        /* "1.3.6.1.5.5.7.1.24" */
26247
        { NID_tlsfeature, WOLFSSL_TLS_FEATURE_SUM, oidTlsExtType,
26248
            WOLFSSL_SN_TLS_FEATURE, WOLFSSL_LN_TLS_FEATURE },
26249
    #endif
26250
#endif /* OPENSSL_EXTRA */
26251
};
26252
26253
#define WOLFSSL_OBJECT_INFO_SZ \
26254
0
                (sizeof(wolfssl_object_info) / sizeof(*wolfssl_object_info))
26255
const size_t wolfssl_object_info_sz = WOLFSSL_OBJECT_INFO_SZ;
26256
#endif
26257
26258
#ifdef OPENSSL_EXTRA
26259
26260
WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFSSL_ASN1_INTEGER *ai)
26261
446
{
26262
446
    WOLFSSL_ASN1_INTEGER* a;
26263
446
    int len;
26264
446
    const int extraTagSz = MAX_LENGTH_SZ + 1;
26265
446
    byte intTag[MAX_LENGTH_SZ + 1];
26266
446
    int idx = 0;
26267
446
    WOLFSSL_ENTER("wolfSSL_BN_to_ASN1_INTEGER");
26268
26269
446
    if (ai == NULL) {
26270
446
        a = wolfSSL_ASN1_INTEGER_new();
26271
26272
446
        if (a == NULL)
26273
0
            return NULL;
26274
26275
446
        a->type = V_ASN1_INTEGER;
26276
446
    }
26277
0
    else {
26278
0
        a = ai;
26279
0
    }
26280
446
    if (a) {
26281
446
        if (wolfSSL_BN_is_negative(bn) && !wolfSSL_BN_is_zero(bn)) {
26282
2
            a->type |= V_ASN1_NEG_INTEGER;
26283
2
            a->negative = 1;
26284
2
        }
26285
26286
446
        len = wolfSSL_BN_num_bytes(bn);
26287
446
        if (len == 0)
26288
180
            len = 1;
26289
26290
        /* allocate buffer */
26291
446
        if (len + extraTagSz > (int)sizeof(a->intData)) {
26292
            /* create new data buffer and copy over */
26293
139
            a->data = (byte*)XMALLOC(len + extraTagSz, NULL,
26294
139
                    DYNAMIC_TYPE_OPENSSL);
26295
139
            if (a->data == NULL) {
26296
0
                if (a != ai)
26297
0
                    wolfSSL_ASN1_INTEGER_free(a);
26298
0
                return NULL;
26299
0
            }
26300
139
            a->isDynamic = 1;
26301
139
        }
26302
307
        else {
26303
307
            XMEMSET(a->intData, 0, sizeof(a->intData));
26304
307
            a->data = a->intData;
26305
307
            a->isDynamic = 0;
26306
307
        }
26307
26308
        /* populate data */
26309
446
        if (wolfSSL_BN_is_zero(bn)) {
26310
180
            a->data[0] = 0;
26311
180
        }
26312
266
        else {
26313
266
            len = wolfSSL_BN_bn2bin(bn, a->data);
26314
266
            if (len < 0) {
26315
0
                wolfSSL_ASN1_INTEGER_free(a);
26316
0
                return NULL;
26317
0
            }
26318
266
        }
26319
446
        a->length = len;
26320
26321
        /* Write ASN tag */
26322
446
        idx = SetASNInt(a->length, a->data[0], intTag);
26323
446
        XMEMMOVE(a->data + idx, a->data, a->length);
26324
446
        XMEMCPY(a->data, intTag, idx);
26325
446
        a->dataMax = a->length += idx;
26326
446
    }
26327
26328
446
    return a;
26329
446
}
26330
26331
#ifdef OPENSSL_ALL
26332
void *wolfSSL_ASN1_item_new(const WOLFSSL_ASN1_ITEM *tpl)
26333
0
{
26334
0
    void *ret = NULL;
26335
0
    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
26336
0
    size_t i;
26337
0
    WOLFSSL_ENTER("wolfSSL_ASN1_item_new");
26338
0
    if (!tpl) {
26339
0
        return NULL;
26340
0
    }
26341
0
    if (!(ret = (void *)XMALLOC(tpl->size, NULL, DYNAMIC_TYPE_OPENSSL))) {
26342
0
        return NULL;
26343
0
    }
26344
0
    XMEMSET(ret, 0, tpl->size);
26345
0
    for (member = tpl->members, i = 0; i < tpl->mcount;
26346
0
            member++, i++) {
26347
0
        switch (member->type) {
26348
0
            case WOLFSSL_X509_ALGOR_ASN1:
26349
0
            {
26350
0
                WOLFSSL_X509_ALGOR* algor = wolfSSL_X509_ALGOR_new();
26351
0
                if (!algor) {
26352
0
                    goto error;
26353
0
                }
26354
0
                *(WOLFSSL_X509_ALGOR**)(((byte*)ret) + member->offset) = algor;
26355
0
                break;
26356
0
            }
26357
0
            case WOLFSSL_ASN1_BIT_STRING_ASN1:
26358
0
            {
26359
0
                WOLFSSL_ASN1_BIT_STRING* bit_str = wolfSSL_ASN1_BIT_STRING_new();
26360
0
                if (!bit_str) {
26361
0
                    goto error;
26362
0
                }
26363
0
                *(WOLFSSL_ASN1_BIT_STRING**)(((byte*)ret) + member->offset) = bit_str;
26364
0
                break;
26365
0
            }
26366
0
            default:
26367
0
                WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_new");
26368
0
                goto error;
26369
0
        }
26370
0
    }
26371
0
    return ret;
26372
0
error:
26373
0
    wolfSSL_ASN1_item_free(ret, tpl);
26374
0
    return NULL;
26375
0
}
26376
26377
void wolfSSL_ASN1_item_free(void *val, const WOLFSSL_ASN1_ITEM *tpl)
26378
0
{
26379
0
    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
26380
0
    size_t i;
26381
0
    WOLFSSL_ENTER("wolfSSL_ASN1_item_free");
26382
0
    if (val) {
26383
0
        for (member = tpl->members, i = 0; i < tpl->mcount;
26384
0
                member++, i++) {
26385
0
            switch (member->type) {
26386
0
                case WOLFSSL_X509_ALGOR_ASN1:
26387
0
                {
26388
0
                    WOLFSSL_X509_ALGOR* algor = *(WOLFSSL_X509_ALGOR**)
26389
0
                                                 (((byte*)val) + member->offset);
26390
0
                    if (algor) {
26391
0
                        wolfSSL_X509_ALGOR_free(algor);
26392
0
                    }
26393
0
                    break;
26394
0
                }
26395
0
                case WOLFSSL_ASN1_BIT_STRING_ASN1:
26396
0
                {
26397
0
                    WOLFSSL_ASN1_BIT_STRING* bit_str = *(WOLFSSL_ASN1_BIT_STRING**)
26398
0
                                                        (((byte*)val) + member->offset);
26399
0
                    if (bit_str) {
26400
0
                        wolfSSL_ASN1_BIT_STRING_free(bit_str);
26401
0
                    }
26402
0
                    break;
26403
0
                }
26404
0
                default:
26405
0
                    WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_free");
26406
0
            }
26407
0
        }
26408
0
        XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL);
26409
0
    }
26410
0
}
26411
26412
0
#define bufLenOrNull(buf, len) ((buf) ? (buf) + (len) : NULL)
26413
26414
static int i2dProcessMembers(const void *src, byte *buf,
26415
                          const WOLFSSL_ASN1_TEMPLATE *members, size_t mcount)
26416
0
{
26417
0
    const WOLFSSL_ASN1_TEMPLATE *member = NULL;
26418
0
    int len = 0, ret;
26419
0
    size_t i;
26420
0
    WOLFSSL_ENTER("processMembers");
26421
0
    for (member = members, i = 0; i < mcount; member++, i++) {
26422
0
        switch (member->type) {
26423
0
            case WOLFSSL_X509_ALGOR_ASN1:
26424
0
            {
26425
0
                word32 oid = 0;
26426
0
                word32 idx = 0;
26427
0
                const WOLFSSL_X509_ALGOR* algor = *(const WOLFSSL_X509_ALGOR**)
26428
0
                                                   (((byte*)src) + member->offset);
26429
0
                if (!algor->algorithm) {
26430
0
                    WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
26431
0
                    return WOLFSSL_FAILURE;
26432
0
                }
26433
26434
0
                if (GetObjectId(algor->algorithm->obj, &idx, &oid,
26435
0
                        algor->algorithm->grp, algor->algorithm->objSz) < 0) {
26436
0
                    WOLFSSL_MSG("Issue getting OID of object");
26437
0
                    return -1;
26438
0
                }
26439
26440
0
                ret = SetAlgoID(oid, bufLenOrNull(buf, len),
26441
0
                                algor->algorithm->grp, 0);
26442
0
                if (!ret) {
26443
0
                    return WOLFSSL_FAILURE;
26444
0
                }
26445
0
                len += ret;
26446
0
                break;
26447
0
            }
26448
0
            case WOLFSSL_ASN1_BIT_STRING_ASN1:
26449
0
            {
26450
0
                const WOLFSSL_ASN1_BIT_STRING* bit_str;
26451
0
                bit_str = *(const WOLFSSL_ASN1_BIT_STRING**)
26452
0
                           (((byte*)src) + member->offset);
26453
0
                len += SetBitString(bit_str->length, 0, bufLenOrNull(buf, len));
26454
0
                if (buf && bit_str->data) {
26455
0
                    XMEMCPY(buf + len, bit_str->data, bit_str->length);
26456
0
                }
26457
0
                len += bit_str->length;
26458
0
                break;
26459
0
            }
26460
0
            default:
26461
0
                WOLFSSL_MSG("Type not support in processMembers");
26462
0
                WOLFSSL_LEAVE("processMembers", WOLFSSL_FAILURE);
26463
0
                return WOLFSSL_FAILURE;
26464
0
        }
26465
0
    }
26466
0
    WOLFSSL_LEAVE("processMembers", len);
26467
0
    return len;
26468
0
}
26469
26470
static int wolfSSL_ASN1_item_i2d_1(const void *src, byte *buf,
26471
                                       const WOLFSSL_ASN1_ITEM *tpl, int *len)
26472
0
{
26473
0
    *len = 0;
26474
26475
0
    switch (tpl->type) {
26476
0
        case ASN_SEQUENCE:
26477
0
        {
26478
0
            int seq_len = i2dProcessMembers(src, NULL, tpl->members,
26479
0
                                         tpl->mcount);
26480
0
            if (seq_len == WOLFSSL_FAILURE)
26481
0
                return WOLFSSL_FAILURE;
26482
0
            *len += SetSequence(seq_len, bufLenOrNull(buf, *len));
26483
0
            if (buf) {
26484
0
                if (i2dProcessMembers(src, bufLenOrNull(buf, *len), tpl->members,
26485
0
                                      tpl->mcount) != seq_len) {
26486
0
                    WOLFSSL_MSG("Inconsistent sequence length");
26487
0
                    return WOLFSSL_FAILURE;
26488
0
                }
26489
0
            }
26490
0
            *len += seq_len;
26491
0
            break;
26492
0
        }
26493
0
        default:
26494
0
            WOLFSSL_MSG("Type not supported in wolfSSL_ASN1_item_i2d");
26495
0
            return WOLFSSL_FAILURE;
26496
0
    }
26497
26498
0
    return WOLFSSL_SUCCESS;
26499
0
}
26500
26501
int wolfSSL_ASN1_item_i2d(const void *src, byte **dest,
26502
                          const WOLFSSL_ASN1_ITEM *tpl)
26503
0
{
26504
0
    int len;
26505
0
    byte *buf = NULL;
26506
26507
0
    WOLFSSL_ENTER("wolfSSL_ASN1_item_i2d");
26508
26509
0
    if ((src == NULL) || (tpl == NULL))
26510
0
        goto error;
26511
26512
0
    if (wolfSSL_ASN1_item_i2d_1(src, NULL, tpl, &len) != WOLFSSL_SUCCESS)
26513
0
        goto error;
26514
26515
0
    if (dest == NULL) {
26516
0
        WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_SUCCESS);
26517
0
        return len;
26518
0
    }
26519
26520
0
    if (*dest == NULL) {
26521
0
        buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
26522
0
        if (buf == NULL)
26523
0
            goto error;
26524
0
    } else
26525
0
        buf = *dest;
26526
26527
0
    if (wolfSSL_ASN1_item_i2d_1(src, buf, tpl, &len) != WOLFSSL_SUCCESS)
26528
0
        goto error;
26529
26530
0
    if (*dest == NULL)
26531
0
        *dest = buf;
26532
0
    else {
26533
        /* XXX *dest length is not checked because the user is responsible
26534
         * for providing a long enough buffer
26535
         */
26536
0
        XMEMCPY(*dest, buf, len);
26537
0
    }
26538
26539
0
    WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", len);
26540
0
    return len;
26541
0
error:
26542
0
    if (buf) {
26543
0
        XFREE(buf, NULL, DYNAMIC_TYPE_ASN1);
26544
0
    }
26545
0
    WOLFSSL_LEAVE("wolfSSL_ASN1_item_i2d", WOLFSSL_FAILURE);
26546
0
    return WOLFSSL_FAILURE;
26547
0
}
26548
26549
#endif /* OPENSSL_ALL */
26550
26551
#endif /* OPENSSL_EXTRA */
26552
26553
#ifdef OPENSSL_EXTRA
26554
WOLFSSL_HMAC_CTX* wolfSSL_HMAC_CTX_new(void)
26555
783
{
26556
783
    WOLFSSL_HMAC_CTX* hmac_ctx = (WOLFSSL_HMAC_CTX*)XMALLOC(
26557
783
        sizeof(WOLFSSL_HMAC_CTX), NULL, DYNAMIC_TYPE_OPENSSL);
26558
783
    if (hmac_ctx != NULL) {
26559
783
        XMEMSET(hmac_ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
26560
783
    }
26561
783
    return hmac_ctx;
26562
783
}
26563
26564
int wolfSSL_HMAC_CTX_Init(WOLFSSL_HMAC_CTX* ctx)
26565
0
{
26566
0
    WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init");
26567
26568
0
    if (ctx != NULL) {
26569
        /* wc_HmacSetKey sets up ctx->hmac */
26570
0
        XMEMSET(ctx, 0, sizeof(WOLFSSL_HMAC_CTX));
26571
0
    }
26572
26573
0
    return WOLFSSL_SUCCESS;
26574
0
}
26575
26576
26577
int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key,
26578
                             int keylen, const EVP_MD* type, WOLFSSL_ENGINE* e)
26579
118
{
26580
118
    WOLFSSL_ENTER("wolfSSL_HMAC_Init_ex");
26581
26582
    /* WOLFSSL_ENGINE not used, call wolfSSL_HMAC_Init */
26583
118
    (void)e;
26584
118
    return wolfSSL_HMAC_Init(ctx, key, keylen, type);
26585
118
}
26586
26587
26588
/* helper function for Deep copy of internal wolfSSL hmac structure
26589
 * returns WOLFSSL_SUCCESS on success */
26590
int wolfSSL_HmacCopy(Hmac* des, Hmac* src)
26591
1.80k
{
26592
1.80k
    void* heap;
26593
1.80k
    int ret;
26594
26595
1.80k
#ifndef HAVE_FIPS
26596
1.80k
    heap = src->heap;
26597
#else
26598
    heap = NULL;
26599
#endif
26600
1.80k
    if (wc_HmacInit(des, heap, 0) != 0) {
26601
0
        return WOLFSSL_FAILURE;
26602
0
    }
26603
26604
    /* requires that hash structures have no dynamic parts to them */
26605
1.80k
    switch (src->macType) {
26606
0
    #ifndef NO_MD5
26607
191
        case WC_MD5:
26608
191
            ret = wc_Md5Copy(&src->hash.md5, &des->hash.md5);
26609
191
            break;
26610
0
    #endif /* !NO_MD5 */
26611
26612
0
    #ifndef NO_SHA
26613
225
        case WC_SHA:
26614
225
            ret = wc_ShaCopy(&src->hash.sha, &des->hash.sha);
26615
225
            break;
26616
0
    #endif /* !NO_SHA */
26617
26618
0
    #ifdef WOLFSSL_SHA224
26619
371
        case WC_SHA224:
26620
371
            ret = wc_Sha224Copy(&src->hash.sha224, &des->hash.sha224);
26621
371
            break;
26622
0
    #endif /* WOLFSSL_SHA224 */
26623
26624
0
    #ifndef NO_SHA256
26625
336
        case WC_SHA256:
26626
336
            ret = wc_Sha256Copy(&src->hash.sha256, &des->hash.sha256);
26627
336
            break;
26628
0
    #endif /* !NO_SHA256 */
26629
26630
0
    #ifdef WOLFSSL_SHA384
26631
203
        case WC_SHA384:
26632
203
            ret = wc_Sha384Copy(&src->hash.sha384, &des->hash.sha384);
26633
203
            break;
26634
0
    #endif /* WOLFSSL_SHA384 */
26635
0
    #ifdef WOLFSSL_SHA512
26636
324
        case WC_SHA512:
26637
324
            ret = wc_Sha512Copy(&src->hash.sha512, &des->hash.sha512);
26638
324
            break;
26639
0
    #endif /* WOLFSSL_SHA512 */
26640
0
#ifdef WOLFSSL_SHA3
26641
0
    #ifndef WOLFSSL_NOSHA3_224
26642
0
        case WC_SHA3_224:
26643
0
            ret = wc_Sha3_224_Copy(&src->hash.sha3, &des->hash.sha3);
26644
0
            break;
26645
0
    #endif /* WOLFSSL_NO_SHA3_224 */
26646
0
    #ifndef WOLFSSL_NOSHA3_256
26647
0
        case WC_SHA3_256:
26648
0
            ret = wc_Sha3_256_Copy(&src->hash.sha3, &des->hash.sha3);
26649
0
            break;
26650
0
    #endif /* WOLFSSL_NO_SHA3_256 */
26651
0
    #ifndef WOLFSSL_NOSHA3_384
26652
0
        case WC_SHA3_384:
26653
0
            ret = wc_Sha3_384_Copy(&src->hash.sha3, &des->hash.sha3);
26654
0
            break;
26655
0
    #endif /* WOLFSSL_NO_SHA3_384 */
26656
0
    #ifndef WOLFSSL_NOSHA3_512
26657
0
        case WC_SHA3_512:
26658
0
            ret = wc_Sha3_512_Copy(&src->hash.sha3, &des->hash.sha3);
26659
0
            break;
26660
0
    #endif /* WOLFSSL_NO_SHA3_512 */
26661
0
#endif /* WOLFSSL_SHA3 */
26662
26663
153
        default:
26664
153
            return WOLFSSL_FAILURE;
26665
1.80k
    }
26666
26667
1.65k
    if (ret != 0)
26668
0
        return WOLFSSL_FAILURE;
26669
26670
1.65k
    XMEMCPY((byte*)des->ipad, (byte*)src->ipad, WC_HMAC_BLOCK_SIZE);
26671
1.65k
    XMEMCPY((byte*)des->opad, (byte*)src->opad, WC_HMAC_BLOCK_SIZE);
26672
1.65k
    XMEMCPY((byte*)des->innerHash, (byte*)src->innerHash, WC_MAX_DIGEST_SIZE);
26673
1.65k
#ifndef HAVE_FIPS
26674
1.65k
    des->heap    = heap;
26675
1.65k
#endif
26676
1.65k
    des->macType = src->macType;
26677
1.65k
    des->innerHashKeyed = src->innerHashKeyed;
26678
26679
#ifdef WOLFSSL_ASYNC_CRYPT
26680
    XMEMCPY(&des->asyncDev, &src->asyncDev, sizeof(WC_ASYNC_DEV));
26681
    des->keyLen = src->keyLen;
26682
    #ifdef HAVE_CAVIUM
26683
        des->data = (byte*)XMALLOC(src->dataLen, des->heap,
26684
                DYNAMIC_TYPE_HMAC);
26685
        if (des->data == NULL) {
26686
            return BUFFER_E;
26687
        }
26688
        XMEMCPY(des->data, src->data, src->dataLen);
26689
        des->dataLen = src->dataLen;
26690
    #endif /* HAVE_CAVIUM */
26691
#endif /* WOLFSSL_ASYNC_CRYPT */
26692
1.65k
        return WOLFSSL_SUCCESS;
26693
1.65k
}
26694
26695
26696
/* Deep copy of information from src to des structure
26697
 *
26698
 * des destination to copy information to
26699
 * src structure to get information from
26700
 *
26701
 * Returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on error
26702
 */
26703
int wolfSSL_HMAC_CTX_copy(WOLFSSL_HMAC_CTX* des, WOLFSSL_HMAC_CTX* src)
26704
654
{
26705
654
    WOLFSSL_ENTER("wolfSSL_HMAC_CTX_copy");
26706
26707
654
    if (des == NULL || src == NULL) {
26708
0
        return WOLFSSL_FAILURE;
26709
0
    }
26710
26711
654
    des->type = src->type;
26712
654
    XMEMCPY((byte *)&des->save_ipad, (byte *)&src->hmac.ipad,
26713
654
                                        WC_HMAC_BLOCK_SIZE);
26714
654
    XMEMCPY((byte *)&des->save_opad, (byte *)&src->hmac.opad,
26715
654
                                        WC_HMAC_BLOCK_SIZE);
26716
26717
654
    return wolfSSL_HmacCopy(&des->hmac, &src->hmac);
26718
654
}
26719
26720
26721
#if defined(HAVE_FIPS) && \
26722
    (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
26723
26724
static int _HMAC_Init(Hmac* hmac, int type, void* heap)
26725
{
26726
    int ret = 0;
26727
26728
    switch (type) {
26729
    #ifndef NO_MD5
26730
        case WC_MD5:
26731
            ret = wc_InitMd5(&hmac->hash.md5);
26732
            break;
26733
    #endif /* !NO_MD5 */
26734
26735
    #ifndef NO_SHA
26736
        case WC_SHA:
26737
            ret = wc_InitSha(&hmac->hash.sha);
26738
            break;
26739
    #endif /* !NO_SHA */
26740
26741
    #ifdef WOLFSSL_SHA224
26742
        case WC_SHA224:
26743
            ret = wc_InitSha224(&hmac->hash.sha224);
26744
            break;
26745
    #endif /* WOLFSSL_SHA224 */
26746
26747
    #ifndef NO_SHA256
26748
        case WC_SHA256:
26749
            ret = wc_InitSha256(&hmac->hash.sha256);
26750
            break;
26751
    #endif /* !NO_SHA256 */
26752
26753
    #ifdef WOLFSSL_SHA384
26754
        case WC_SHA384:
26755
            ret = wc_InitSha384(&hmac->hash.sha384);
26756
            break;
26757
    #endif /* WOLFSSL_SHA384 */
26758
    #ifdef WOLFSSL_SHA512
26759
        case WC_SHA512:
26760
            ret = wc_InitSha512(&hmac->hash.sha512);
26761
            break;
26762
    #endif /* WOLFSSL_SHA512 */
26763
26764
    #ifdef WOLFSSL_SHA3
26765
        case WC_SHA3_224:
26766
            ret = wc_InitSha3_224(&hmac->hash.sha3, heap, INVALID_DEVID);
26767
            break;
26768
        case WC_SHA3_256:
26769
            ret = wc_InitSha3_256(&hmac->hash.sha3, heap, INVALID_DEVID);
26770
            break;
26771
        case WC_SHA3_384:
26772
            ret = wc_InitSha3_384(&hmac->hash.sha3, heap, INVALID_DEVID);
26773
            break;
26774
        case WC_SHA3_512:
26775
            ret = wc_InitSha3_512(&hmac->hash.sha3, heap, INVALID_DEVID);
26776
            break;
26777
    #endif
26778
26779
        default:
26780
            ret = BAD_FUNC_ARG;
26781
            break;
26782
    }
26783
26784
    (void)heap;
26785
26786
    return ret;
26787
}
26788
26789
#else
26790
0
    #define _HMAC_Init _InitHmac
26791
#endif
26792
26793
26794
int wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen,
26795
                  const EVP_MD* type)
26796
118
{
26797
118
    int hmac_error = 0;
26798
118
    void* heap = NULL;
26799
118
    int inited;
26800
26801
118
    WOLFSSL_MSG("wolfSSL_HMAC_Init");
26802
26803
118
    if (ctx == NULL) {
26804
0
        WOLFSSL_MSG("no ctx on init");
26805
0
        return WOLFSSL_FAILURE;
26806
0
    }
26807
26808
118
#ifndef HAVE_FIPS
26809
118
    heap = ctx->hmac.heap;
26810
118
#endif
26811
26812
118
    if (type) {
26813
118
        WOLFSSL_MSG("init has type");
26814
26815
118
#ifndef NO_MD5
26816
118
        if (XSTRNCMP(type, "MD5", 3) == 0) {
26817
10
            WOLFSSL_MSG("md5 hmac");
26818
10
            ctx->type = WC_MD5;
26819
10
        }
26820
108
        else
26821
108
#endif
26822
108
#ifdef WOLFSSL_SHA224
26823
108
        if (XSTRNCMP(type, "SHA224", 6) == 0) {
26824
19
            WOLFSSL_MSG("sha224 hmac");
26825
19
            ctx->type = WC_SHA224;
26826
19
        }
26827
89
        else
26828
89
#endif
26829
89
#ifndef NO_SHA256
26830
89
        if (XSTRNCMP(type, "SHA256", 6) == 0) {
26831
37
            WOLFSSL_MSG("sha256 hmac");
26832
37
            ctx->type = WC_SHA256;
26833
37
        }
26834
52
        else
26835
52
#endif
26836
52
#ifdef WOLFSSL_SHA384
26837
52
        if (XSTRNCMP(type, "SHA384", 6) == 0) {
26838
16
            WOLFSSL_MSG("sha384 hmac");
26839
16
            ctx->type = WC_SHA384;
26840
16
        }
26841
36
        else
26842
36
#endif
26843
36
#ifdef WOLFSSL_SHA512
26844
36
        if (XSTRNCMP(type, "SHA512", 6) == 0) {
26845
21
            WOLFSSL_MSG("sha512 hmac");
26846
21
            ctx->type = WC_SHA512;
26847
21
        }
26848
15
        else
26849
15
#endif
26850
15
#ifdef WOLFSSL_SHA3
26851
15
    #ifndef WOLFSSL_NOSHA3_224
26852
15
        if (XSTRNCMP(type, "SHA3_224", 8) == 0) {
26853
0
            WOLFSSL_MSG("sha3_224 hmac");
26854
0
            ctx->type = WC_SHA3_224;
26855
0
        }
26856
15
        else
26857
15
    #endif
26858
15
    #ifndef WOLFSSL_NOSHA3_256
26859
15
        if (XSTRNCMP(type, "SHA3_256", 8) == 0) {
26860
0
            WOLFSSL_MSG("sha3_256 hmac");
26861
0
            ctx->type = WC_SHA3_256;
26862
0
        }
26863
15
        else
26864
15
    #endif
26865
15
        if (XSTRNCMP(type, "SHA3_384", 8) == 0) {
26866
0
            WOLFSSL_MSG("sha3_384 hmac");
26867
0
            ctx->type = WC_SHA3_384;
26868
0
        }
26869
15
        else
26870
15
    #ifndef WOLFSSL_NOSHA3_512
26871
15
        if (XSTRNCMP(type, "SHA3_512", 8) == 0) {
26872
0
            WOLFSSL_MSG("sha3_512 hmac");
26873
0
            ctx->type = WC_SHA3_512;
26874
0
        }
26875
15
        else
26876
15
    #endif
26877
15
#endif
26878
26879
15
#ifndef NO_SHA
26880
        /* has to be last since would pick or 256, 384, or 512 too */
26881
15
        if (XSTRNCMP(type, "SHA", 3) == 0) {
26882
14
            WOLFSSL_MSG("sha hmac");
26883
14
            ctx->type = WC_SHA;
26884
14
        }
26885
1
        else
26886
1
#endif
26887
1
        {
26888
1
            WOLFSSL_MSG("bad init type");
26889
1
            return WOLFSSL_FAILURE;
26890
1
        }
26891
118
    }
26892
26893
    /* Check if init has been called before */
26894
117
    inited = (ctx->hmac.macType != WC_HASH_TYPE_NONE);
26895
    /* Free if needed */
26896
117
    if (inited) {
26897
0
        wc_HmacFree(&ctx->hmac);
26898
0
    }
26899
117
    if (key != NULL) {
26900
106
        WOLFSSL_MSG("keying hmac");
26901
26902
106
        if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
26903
106
            hmac_error = wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key,
26904
106
                                       (word32)keylen);
26905
106
            if (hmac_error < 0){
26906
                /* in FIPS mode a key < 14 characters will fail here */
26907
0
                WOLFSSL_MSG("hmac set key error");
26908
0
                WOLFSSL_ERROR(hmac_error);
26909
0
                wc_HmacFree(&ctx->hmac);
26910
0
                return WOLFSSL_FAILURE;
26911
0
            }
26912
106
            XMEMCPY((byte *)&ctx->save_ipad, (byte *)&ctx->hmac.ipad,
26913
106
                                        WC_HMAC_BLOCK_SIZE);
26914
106
            XMEMCPY((byte *)&ctx->save_opad, (byte *)&ctx->hmac.opad,
26915
106
                                        WC_HMAC_BLOCK_SIZE);
26916
106
        }
26917
        /* OpenSSL compat, no error */
26918
106
    }
26919
11
    else if (!inited) {
26920
11
        return WOLFSSL_FAILURE;
26921
11
    }
26922
0
    else if (ctx->type >= 0) { /* MD5 == 0 */
26923
0
        WOLFSSL_MSG("recover hmac");
26924
0
        if (wc_HmacInit(&ctx->hmac, NULL, INVALID_DEVID) == 0) {
26925
0
            ctx->hmac.macType = (byte)ctx->type;
26926
0
            ctx->hmac.innerHashKeyed = 0;
26927
0
            XMEMCPY((byte *)&ctx->hmac.ipad, (byte *)&ctx->save_ipad,
26928
0
                                       WC_HMAC_BLOCK_SIZE);
26929
0
            XMEMCPY((byte *)&ctx->hmac.opad, (byte *)&ctx->save_opad,
26930
0
                                       WC_HMAC_BLOCK_SIZE);
26931
0
            if ((hmac_error = _HMAC_Init(&ctx->hmac, ctx->hmac.macType, heap))
26932
0
                    !=0) {
26933
0
                WOLFSSL_MSG("hmac init error");
26934
0
                WOLFSSL_ERROR(hmac_error);
26935
0
                return WOLFSSL_FAILURE;
26936
0
            }
26937
0
        }
26938
0
    }
26939
26940
106
    (void)hmac_error;
26941
26942
106
    return WOLFSSL_SUCCESS;
26943
117
}
26944
26945
26946
int wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data,
26947
                    int len)
26948
621
{
26949
621
    int hmac_error = 0;
26950
26951
621
    WOLFSSL_MSG("wolfSSL_HMAC_Update");
26952
26953
621
    if (ctx == NULL) {
26954
0
        WOLFSSL_MSG("no ctx");
26955
0
        return WOLFSSL_FAILURE;
26956
0
    }
26957
26958
621
    if (data) {
26959
153
        WOLFSSL_MSG("updating hmac");
26960
153
        hmac_error = wc_HmacUpdate(&ctx->hmac, data, (word32)len);
26961
153
        if (hmac_error < 0){
26962
0
            WOLFSSL_MSG("hmac update error");
26963
0
            return WOLFSSL_FAILURE;
26964
0
        }
26965
153
    }
26966
26967
621
    return WOLFSSL_SUCCESS;
26968
621
}
26969
26970
26971
int wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash,
26972
                   unsigned int* len)
26973
106
{
26974
106
    int hmac_error;
26975
26976
106
    WOLFSSL_MSG("wolfSSL_HMAC_Final");
26977
26978
    /* "len" parameter is optional. */
26979
106
    if (ctx == NULL || hash == NULL) {
26980
0
        WOLFSSL_MSG("invalid parameter");
26981
0
        return WOLFSSL_FAILURE;
26982
0
    }
26983
26984
106
    WOLFSSL_MSG("final hmac");
26985
106
    hmac_error = wc_HmacFinal(&ctx->hmac, hash);
26986
106
    if (hmac_error < 0){
26987
0
        WOLFSSL_MSG("final hmac error");
26988
0
        return WOLFSSL_FAILURE;
26989
0
    }
26990
26991
106
    if (len) {
26992
106
        WOLFSSL_MSG("setting output len");
26993
106
        switch (ctx->type) {
26994
0
            #ifndef NO_MD5
26995
10
            case WC_MD5:
26996
10
                *len = WC_MD5_DIGEST_SIZE;
26997
10
                break;
26998
0
            #endif
26999
27000
0
            #ifndef NO_SHA
27001
14
            case WC_SHA:
27002
14
                *len = WC_SHA_DIGEST_SIZE;
27003
14
                break;
27004
0
            #endif
27005
27006
0
            #ifdef WOLFSSL_SHA224
27007
17
            case WC_SHA224:
27008
17
                *len = WC_SHA224_DIGEST_SIZE;
27009
17
                break;
27010
0
            #endif
27011
27012
0
            #ifndef NO_SHA256
27013
32
            case WC_SHA256:
27014
32
                *len = WC_SHA256_DIGEST_SIZE;
27015
32
                break;
27016
0
            #endif
27017
27018
0
            #ifdef WOLFSSL_SHA384
27019
16
            case WC_SHA384:
27020
16
                *len = WC_SHA384_DIGEST_SIZE;
27021
16
                break;
27022
0
            #endif
27023
27024
0
            #ifdef WOLFSSL_SHA512
27025
17
            case WC_SHA512:
27026
17
                *len = WC_SHA512_DIGEST_SIZE;
27027
17
                break;
27028
0
            #endif
27029
27030
0
        #ifdef WOLFSSL_SHA3
27031
0
            #ifndef WOLFSSL_NOSHA3_224
27032
0
            case WC_SHA3_224:
27033
0
                *len = WC_SHA3_224_DIGEST_SIZE;
27034
0
                break;
27035
0
            #endif
27036
0
            #ifndef WOLFSSL_NOSHA3_256
27037
0
            case WC_SHA3_256:
27038
0
                *len = WC_SHA3_256_DIGEST_SIZE;
27039
0
                break;
27040
0
            #endif
27041
0
            #ifndef WOLFSSL_NOSHA3_384
27042
0
            case WC_SHA3_384:
27043
0
                *len = WC_SHA3_384_DIGEST_SIZE;
27044
0
                break;
27045
0
            #endif
27046
0
            #ifndef WOLFSSL_NOSHA3_512
27047
0
            case WC_SHA3_512:
27048
0
                *len = WC_SHA3_512_DIGEST_SIZE;
27049
0
                break;
27050
0
            #endif
27051
0
        #endif
27052
27053
0
            default:
27054
0
                WOLFSSL_MSG("bad hmac type");
27055
0
                return WOLFSSL_FAILURE;
27056
106
        }
27057
106
    }
27058
27059
106
    return WOLFSSL_SUCCESS;
27060
106
}
27061
27062
27063
int wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx)
27064
912
{
27065
912
    WOLFSSL_MSG("wolfSSL_HMAC_cleanup");
27066
27067
912
    if (ctx) {
27068
912
        wc_HmacFree(&ctx->hmac);
27069
912
    }
27070
27071
912
    return WOLFSSL_SUCCESS;
27072
912
}
27073
27074
void wolfSSL_HMAC_CTX_cleanup(WOLFSSL_HMAC_CTX* ctx)
27075
783
{
27076
783
    if (ctx) {
27077
783
        wolfSSL_HMAC_cleanup(ctx);
27078
783
    }
27079
783
}
27080
27081
void wolfSSL_HMAC_CTX_free(WOLFSSL_HMAC_CTX* ctx)
27082
783
{
27083
783
    if (ctx) {
27084
783
        wolfSSL_HMAC_CTX_cleanup(ctx);
27085
783
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27086
783
    }
27087
783
}
27088
27089
size_t wolfSSL_HMAC_size(const WOLFSSL_HMAC_CTX *ctx)
27090
0
{
27091
0
    if (!ctx) {
27092
0
        return 0;
27093
0
    }
27094
27095
0
    return (size_t)wc_HashGetDigestSize((enum wc_HashType)ctx->hmac.macType);
27096
0
}
27097
27098
const WOLFSSL_EVP_MD *wolfSSL_HMAC_CTX_get_md(const WOLFSSL_HMAC_CTX *ctx)
27099
0
{
27100
0
    if (!ctx) {
27101
0
        return NULL;
27102
0
    }
27103
27104
0
    return wolfSSL_macType2EVP_md((enum wc_HashType)ctx->type);
27105
0
}
27106
27107
#if defined(WOLFSSL_CMAC) && defined(OPENSSL_EXTRA) && \
27108
    defined(WOLFSSL_AES_DIRECT)
27109
WOLFSSL_CMAC_CTX* wolfSSL_CMAC_CTX_new(void)
27110
0
{
27111
0
    WOLFSSL_CMAC_CTX* ctx = NULL;
27112
27113
0
    ctx = (WOLFSSL_CMAC_CTX*)XMALLOC(sizeof(WOLFSSL_CMAC_CTX), NULL,
27114
0
                                     DYNAMIC_TYPE_OPENSSL);
27115
0
    if (ctx != NULL) {
27116
0
        ctx->internal = (Cmac*)XMALLOC(sizeof(Cmac), NULL, DYNAMIC_TYPE_CMAC);
27117
0
        if (ctx->internal == NULL) {
27118
0
            XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27119
0
            ctx = NULL;
27120
0
        }
27121
0
    }
27122
0
    if (ctx != NULL) {
27123
0
        ctx->cctx = wolfSSL_EVP_CIPHER_CTX_new();
27124
0
        if (ctx->cctx == NULL) {
27125
0
            XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
27126
0
            XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27127
0
            ctx = NULL;
27128
0
        }
27129
0
    }
27130
27131
0
    return ctx;
27132
0
}
27133
27134
void wolfSSL_CMAC_CTX_free(WOLFSSL_CMAC_CTX *ctx)
27135
0
{
27136
0
    if (ctx != NULL) {
27137
0
        if (ctx->internal != NULL) {
27138
0
            XFREE(ctx->internal, NULL, DYNAMIC_TYPE_CMAC);
27139
0
        }
27140
0
        if (ctx->cctx != NULL) {
27141
0
            wolfSSL_EVP_CIPHER_CTX_free(ctx->cctx);
27142
0
        }
27143
0
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
27144
0
    }
27145
0
}
27146
27147
WOLFSSL_EVP_CIPHER_CTX* wolfSSL_CMAC_CTX_get0_cipher_ctx(WOLFSSL_CMAC_CTX* ctx)
27148
0
{
27149
0
    WOLFSSL_EVP_CIPHER_CTX* cctx = NULL;
27150
27151
0
    if (ctx != NULL) {
27152
0
        cctx = ctx->cctx;
27153
0
    }
27154
27155
0
    return cctx;
27156
0
}
27157
27158
int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keyLen,
27159
                      const WOLFSSL_EVP_CIPHER* cipher, WOLFSSL_ENGINE* engine)
27160
0
{
27161
0
    int ret = WOLFSSL_SUCCESS;
27162
27163
0
    (void)engine;
27164
27165
0
    WOLFSSL_ENTER("wolfSSL_CMAC_Init");
27166
27167
0
    if (ctx == NULL || cipher == NULL || (
27168
0
            cipher != EVP_AES_128_CBC &&
27169
0
            cipher != EVP_AES_192_CBC &&
27170
0
            cipher != EVP_AES_256_CBC)) {
27171
0
        ret = WOLFSSL_FAILURE;
27172
0
    }
27173
27174
0
    if (ret == WOLFSSL_SUCCESS) {
27175
0
        ret = wc_InitCmac((Cmac*)ctx->internal, (const byte*)key,
27176
0
                          (word32)keyLen, WC_CMAC_AES, NULL);
27177
0
        if (ret != 0) {
27178
0
            ret = WOLFSSL_FAILURE;
27179
0
        }
27180
0
        else {
27181
0
            ret = WOLFSSL_SUCCESS;
27182
0
        }
27183
0
    }
27184
0
    if (ret == WOLFSSL_SUCCESS) {
27185
0
        ret = wolfSSL_EVP_CipherInit(ctx->cctx, cipher, (const byte*)key, NULL,
27186
0
                                     1);
27187
0
    }
27188
27189
0
    WOLFSSL_LEAVE("wolfSSL_CMAC_Init", ret);
27190
27191
0
    return ret;
27192
0
}
27193
27194
int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len)
27195
0
{
27196
0
    int ret = WOLFSSL_SUCCESS;
27197
27198
0
    WOLFSSL_ENTER("wolfSSL_CMAC_Update");
27199
27200
0
    if (ctx == NULL || ctx->internal == NULL) {
27201
0
        ret = WOLFSSL_FAILURE;
27202
0
    }
27203
27204
0
    if (ret == WOLFSSL_SUCCESS) {
27205
0
        if (data) {
27206
0
            ret = wc_CmacUpdate((Cmac*)ctx->internal, (const byte*)data,
27207
0
                                (word32)len);
27208
0
            if (ret != 0){
27209
0
                ret = WOLFSSL_FAILURE;
27210
0
            }
27211
0
            else {
27212
0
                ret = WOLFSSL_SUCCESS;
27213
0
            }
27214
0
        }
27215
0
    }
27216
27217
0
    WOLFSSL_LEAVE("wolfSSL_CMAC_Update", ret);
27218
27219
0
    return ret;
27220
0
}
27221
27222
int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out,
27223
                       size_t* len)
27224
0
{
27225
0
    int ret = WOLFSSL_SUCCESS;
27226
0
    int blockSize;
27227
27228
0
    WOLFSSL_ENTER("wolfSSL_CMAC_Final");
27229
27230
0
    if (ctx == NULL || ctx->cctx == NULL || ctx->internal == NULL ||
27231
0
                                                                  len == NULL) {
27232
0
        ret = WOLFSSL_FAILURE;
27233
0
    }
27234
27235
0
    if (ret == WOLFSSL_SUCCESS) {
27236
0
        blockSize = EVP_CIPHER_CTX_block_size(ctx->cctx);
27237
0
        if (blockSize <= 0) {
27238
0
            ret = WOLFSSL_FAILURE;
27239
0
        }
27240
0
        else {
27241
0
            *len = blockSize;
27242
0
        }
27243
0
    }
27244
0
    if (ret == WOLFSSL_SUCCESS) {
27245
0
        word32 len32 = (word32)*len;
27246
27247
0
        ret = wc_CmacFinal((Cmac*)ctx->internal, out, &len32);
27248
0
        *len = (size_t)len32;
27249
0
        if (ret != 0) {
27250
0
            ret = WOLFSSL_FAILURE;
27251
0
        }
27252
0
        else {
27253
0
            ret = WOLFSSL_SUCCESS;
27254
0
        }
27255
0
    }
27256
27257
0
    WOLFSSL_LEAVE("wolfSSL_CMAC_Final", ret);
27258
27259
0
    return ret;
27260
0
}
27261
#endif /* WOLFSSL_CMAC && OPENSSL_EXTRA && WOLFSSL_AES_DIRECT */
27262
#endif /* OPENSSL_EXTRA */
27263
27264
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
27265
/* Free the dynamically allocated data.
27266
 *
27267
 * p  Pointer to dynamically allocated memory.
27268
 */
27269
void wolfSSL_OPENSSL_free(void* p)
27270
897
{
27271
897
    WOLFSSL_MSG("wolfSSL_OPENSSL_free");
27272
27273
897
    XFREE(p, NULL, DYNAMIC_TYPE_OPENSSL);
27274
897
}
27275
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
27276
27277
#ifdef OPENSSL_EXTRA
27278
27279
void *wolfSSL_OPENSSL_malloc(size_t a)
27280
0
{
27281
0
    return (void *)XMALLOC(a, NULL, DYNAMIC_TYPE_OPENSSL);
27282
0
}
27283
27284
int wolfSSL_OPENSSL_hexchar2int(unsigned char c)
27285
0
{
27286
    /* 'char' is unsigned on some platforms. */
27287
0
    return (int)(signed char)HexCharToByte((char)c);
27288
0
}
27289
27290
unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len)
27291
0
{
27292
0
    unsigned char* targetBuf;
27293
0
    int srcDigitHigh = 0;
27294
0
    int srcDigitLow = 0;
27295
0
    size_t srcLen;
27296
0
    size_t srcIdx = 0;
27297
0
    long targetIdx = 0;
27298
27299
0
    srcLen = XSTRLEN(str);
27300
0
    targetBuf = (unsigned char*)XMALLOC(srcLen / 2, NULL, DYNAMIC_TYPE_OPENSSL);
27301
0
    if (targetBuf == NULL) {
27302
0
        return NULL;
27303
0
    }
27304
27305
0
    while (srcIdx < srcLen) {
27306
0
        if (str[srcIdx] == ':') {
27307
0
            srcIdx++;
27308
0
            continue;
27309
0
        }
27310
27311
0
        srcDigitHigh = wolfSSL_OPENSSL_hexchar2int(str[srcIdx++]);
27312
0
        srcDigitLow = wolfSSL_OPENSSL_hexchar2int(str[srcIdx++]);
27313
0
        if (srcDigitHigh < 0 || srcDigitLow < 0) {
27314
0
            WOLFSSL_MSG("Invalid hex character.");
27315
0
            XFREE(targetBuf, NULL, DYNAMIC_TYPE_OPENSSL);
27316
0
            return NULL;
27317
0
        }
27318
27319
0
        targetBuf[targetIdx++] = (unsigned char)((srcDigitHigh << 4) | srcDigitLow);
27320
0
    }
27321
27322
0
    if (len != NULL)
27323
0
        *len = targetIdx;
27324
27325
0
    return targetBuf;
27326
0
}
27327
27328
int wolfSSL_OPENSSL_init_ssl(word64 opts, const OPENSSL_INIT_SETTINGS *settings)
27329
0
{
27330
0
    (void)opts;
27331
0
    (void)settings;
27332
0
    return wolfSSL_library_init();
27333
0
}
27334
27335
int wolfSSL_OPENSSL_init_crypto(word64 opts, const OPENSSL_INIT_SETTINGS* settings)
27336
0
{
27337
0
    (void)opts;
27338
0
    (void)settings;
27339
0
    return wolfSSL_library_init();
27340
0
}
27341
27342
#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER)
27343
27344
int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
27345
                  unsigned char* passwd, int passwdSz, byte **cipherInfo,
27346
                  int maxDerSz)
27347
0
{
27348
0
    int ret, paddingSz;
27349
0
    word32 idx, cipherInfoSz;
27350
0
#ifdef WOLFSSL_SMALL_STACK
27351
0
    EncryptedInfo* info = NULL;
27352
#else
27353
    EncryptedInfo  info[1];
27354
#endif
27355
27356
0
    WOLFSSL_ENTER("EncryptDerKey");
27357
27358
0
    if (der == NULL || derSz == NULL || cipher == NULL ||
27359
0
        passwd == NULL || cipherInfo == NULL)
27360
0
        return BAD_FUNC_ARG;
27361
27362
0
#ifdef WOLFSSL_SMALL_STACK
27363
0
    info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
27364
0
                                   DYNAMIC_TYPE_ENCRYPTEDINFO);
27365
0
    if (info == NULL) {
27366
0
        WOLFSSL_MSG("malloc failed");
27367
0
        return WOLFSSL_FAILURE;
27368
0
    }
27369
0
#endif
27370
27371
0
    XMEMSET(info, 0, sizeof(EncryptedInfo));
27372
27373
    /* set the cipher name on info */
27374
0
    XSTRNCPY(info->name, cipher, NAME_SZ-1);
27375
0
    info->name[NAME_SZ-1] = '\0'; /* null term */
27376
27377
0
    ret = wc_EncryptedInfoGet(info, info->name);
27378
0
    if (ret != 0) {
27379
0
        WOLFSSL_MSG("unsupported cipher");
27380
0
    #ifdef WOLFSSL_SMALL_STACK
27381
0
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27382
0
    #endif
27383
0
        return WOLFSSL_FAILURE;
27384
0
    }
27385
27386
    /* Generate a random salt */
27387
0
    if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != WOLFSSL_SUCCESS) {
27388
0
        WOLFSSL_MSG("generate iv failed");
27389
0
#ifdef WOLFSSL_SMALL_STACK
27390
0
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27391
0
#endif
27392
0
        return WOLFSSL_FAILURE;
27393
0
    }
27394
27395
    /* add the padding before encryption */
27396
0
    paddingSz = ((*derSz)/info->ivSz + 1) * info->ivSz - (*derSz);
27397
0
    if (paddingSz == 0)
27398
0
        paddingSz = info->ivSz;
27399
0
    if (maxDerSz < *derSz + paddingSz) {
27400
0
        WOLFSSL_MSG("not enough DER buffer allocated");
27401
0
#ifdef WOLFSSL_SMALL_STACK
27402
0
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27403
0
#endif
27404
0
        return WOLFSSL_FAILURE;
27405
0
    }
27406
0
    XMEMSET(der+(*derSz), (byte)paddingSz, paddingSz);
27407
0
    (*derSz) += paddingSz;
27408
27409
    /* encrypt buffer */
27410
0
    if (wc_BufferKeyEncrypt(info, der, *derSz, passwd, passwdSz, WC_MD5) != 0) {
27411
0
        WOLFSSL_MSG("encrypt key failed");
27412
0
#ifdef WOLFSSL_SMALL_STACK
27413
0
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27414
0
#endif
27415
0
        return WOLFSSL_FAILURE;
27416
0
    }
27417
27418
    /* create cipher info : 'cipher_name,Salt(hex)' */
27419
0
    cipherInfoSz = (word32)(2*info->ivSz + XSTRLEN(info->name) + 2);
27420
0
    *cipherInfo = (byte*)XMALLOC(cipherInfoSz, NULL,
27421
0
                                DYNAMIC_TYPE_STRING);
27422
0
    if (*cipherInfo == NULL) {
27423
0
        WOLFSSL_MSG("malloc failed");
27424
0
#ifdef WOLFSSL_SMALL_STACK
27425
0
        XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27426
0
#endif
27427
0
        return WOLFSSL_FAILURE;
27428
0
    }
27429
0
    XSTRLCPY((char*)*cipherInfo, info->name, cipherInfoSz);
27430
0
    XSTRLCAT((char*)*cipherInfo, ",", cipherInfoSz);
27431
27432
0
    idx = (word32)XSTRLEN((char*)*cipherInfo);
27433
0
    cipherInfoSz -= idx;
27434
0
    ret = Base16_Encode(info->iv, info->ivSz, *cipherInfo+idx, &cipherInfoSz);
27435
27436
0
#ifdef WOLFSSL_SMALL_STACK
27437
0
    XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
27438
0
#endif
27439
0
    if (ret != 0) {
27440
0
        WOLFSSL_MSG("Base16_Encode failed");
27441
0
        XFREE(*cipherInfo, NULL, DYNAMIC_TYPE_STRING);
27442
0
        return WOLFSSL_FAILURE;
27443
0
    }
27444
27445
0
    return WOLFSSL_SUCCESS;
27446
0
}
27447
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
27448
27449
#ifndef NO_BIO
27450
static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
27451
0
{
27452
0
    int ret;
27453
0
    int pemSz;
27454
0
    byte* pemBuf;
27455
0
    int derSz = 0;
27456
0
    byte* derBuf = NULL;
27457
27458
0
    if (bio == NULL || key == NULL) {
27459
0
        WOLFSSL_MSG("Bad parameters");
27460
0
        return WOLFSSL_FAILURE;
27461
0
    }
27462
27463
0
    switch (key->type) {
27464
0
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
27465
0
        case EVP_PKEY_RSA:
27466
0
            if ((derSz = wolfSSL_RSA_To_Der(key->rsa, &derBuf, 1, bio->heap))
27467
0
                    < 0) {
27468
0
                WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
27469
0
                break;
27470
0
            }
27471
0
            break;
27472
0
#endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
27473
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
27474
        defined(WOLFSSL_CERT_GEN))
27475
        case EVP_PKEY_DSA:
27476
            if (key->dsa == NULL) {
27477
                WOLFSSL_MSG("key->dsa is null");
27478
                break;
27479
            }
27480
            derSz = MAX_DSA_PUBKEY_SZ;
27481
            derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
27482
            if (derBuf == NULL) {
27483
                WOLFSSL_MSG("malloc failed");
27484
                break;
27485
            }
27486
            /* Key to DER */
27487
            derSz = wc_DsaKeyToPublicDer((DsaKey*)key->dsa->internal, derBuf,
27488
                    derSz);
27489
            if (derSz < 0) {
27490
                WOLFSSL_MSG("wc_DsaKeyToDer failed");
27491
                break;
27492
            }
27493
            break;
27494
#endif /* !NO_DSA && !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
27495
0
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
27496
0
        case EVP_PKEY_EC:
27497
0
        {
27498
0
            if (key->ecc == NULL) {
27499
0
                WOLFSSL_MSG("key->ecc is null");
27500
0
                break;
27501
0
            }
27502
0
            derSz = wc_EccPublicKeyDerSize((ecc_key*)key->ecc->internal, 1);
27503
0
            if (derSz <= 0) {
27504
0
                WOLFSSL_MSG("wc_EccPublicKeyDerSize failed");
27505
0
                break;
27506
0
            }
27507
0
            derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
27508
0
            if (derBuf == NULL) {
27509
0
                WOLFSSL_MSG("malloc failed");
27510
0
                break;
27511
0
            }
27512
0
            derSz = wc_EccPublicKeyToDer((ecc_key*)key->ecc->internal, derBuf,
27513
0
                    derSz, 1);
27514
0
            if (derSz < 0) {
27515
0
                WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
27516
0
                break;
27517
0
            }
27518
0
            break;
27519
0
        }
27520
0
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT */
27521
0
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
27522
0
        case EVP_PKEY_DH:
27523
0
            WOLFSSL_MSG("Writing DH PUBKEY not supported!");
27524
0
            break;
27525
0
#endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */
27526
0
        default:
27527
0
            WOLFSSL_MSG("Unknown Key type!");
27528
0
            break;
27529
0
    }
27530
27531
0
    if (derBuf == NULL || derSz <= 0) {
27532
0
        if (derBuf != NULL)
27533
0
            XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
27534
0
        return WOLFSSL_FAILURE;
27535
0
    }
27536
27537
0
    pemSz = wc_DerToPem(derBuf, derSz, NULL, 0, PUBLICKEY_TYPE);
27538
0
    if (pemSz < 0) {
27539
0
        WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz);
27540
0
        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
27541
0
        return WOLFSSL_FAILURE;
27542
0
    }
27543
27544
0
    pemBuf = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
27545
0
    if (pemBuf == NULL) {
27546
0
        WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz);
27547
0
        XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
27548
0
        return WOLFSSL_FAILURE;
27549
0
    }
27550
27551
0
    ret = wc_DerToPem(derBuf, derSz, pemBuf, pemSz, PUBLICKEY_TYPE);
27552
0
    XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
27553
0
    if (ret < 0) {
27554
0
        WOLFSSL_LEAVE("pem_write_bio_pubkey", ret);
27555
0
        XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
27556
0
        return WOLFSSL_FAILURE;
27557
0
    }
27558
27559
0
    ret = wolfSSL_BIO_write(bio, pemBuf, pemSz);
27560
0
    XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
27561
0
    if (ret != pemSz) {
27562
0
        WOLFSSL_MSG("Unable to write full PEM to BIO");
27563
0
        return WOLFSSL_FAILURE;
27564
0
    }
27565
27566
0
    return WOLFSSL_SUCCESS;
27567
0
}
27568
27569
/* Takes a public key and writes it out to a WOLFSSL_BIO
27570
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
27571
 */
27572
int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
27573
0
{
27574
0
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
27575
27576
0
    return pem_write_bio_pubkey(bio, key);
27577
0
}
27578
27579
/* Takes a private key and writes it out to a WOLFSSL_BIO
27580
 * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
27581
 */
27582
int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
27583
                                     const WOLFSSL_EVP_CIPHER* cipher,
27584
                                     unsigned char* passwd, int len,
27585
                                     wc_pem_password_cb* cb, void* arg)
27586
0
{
27587
0
    byte* keyDer;
27588
0
    int pemSz;
27589
0
    int type;
27590
0
    int ret;
27591
0
    byte* tmp;
27592
27593
0
    (void)cipher;
27594
0
    (void)passwd;
27595
0
    (void)len;
27596
0
    (void)cb;
27597
0
    (void)arg;
27598
27599
0
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PrivateKey");
27600
27601
0
    if (bio == NULL || key == NULL) {
27602
0
        WOLFSSL_MSG("Bad Function Arguments");
27603
0
        return WOLFSSL_FAILURE;
27604
0
    }
27605
27606
0
    keyDer = (byte*)key->pkey.ptr;
27607
27608
0
    switch (key->type) {
27609
0
#ifndef NO_RSA
27610
0
        case EVP_PKEY_RSA:
27611
0
            type = PRIVATEKEY_TYPE;
27612
0
            break;
27613
0
#endif
27614
27615
#ifndef NO_DSA
27616
        case EVP_PKEY_DSA:
27617
            type = DSA_PRIVATEKEY_TYPE;
27618
            break;
27619
#endif
27620
27621
0
#ifdef HAVE_ECC
27622
0
        case EVP_PKEY_EC:
27623
0
            type = ECC_PRIVATEKEY_TYPE;
27624
0
            break;
27625
0
#endif
27626
27627
0
#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL))
27628
0
        case EVP_PKEY_DH:
27629
0
            type = DH_PRIVATEKEY_TYPE;
27630
0
            break;
27631
0
#endif
27632
27633
0
        default:
27634
0
            WOLFSSL_MSG("Unknown Key type!");
27635
0
            type = PRIVATEKEY_TYPE;
27636
0
    }
27637
27638
0
    pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type);
27639
0
    if (pemSz < 0) {
27640
0
        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz);
27641
0
        return WOLFSSL_FAILURE;
27642
0
    }
27643
0
    tmp = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
27644
0
    if (tmp == NULL) {
27645
0
        return MEMORY_E;
27646
0
    }
27647
27648
0
    ret = wc_DerToPem(keyDer, key->pkey_sz, tmp, pemSz, type);
27649
0
    if (ret < 0) {
27650
0
        WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret);
27651
0
        XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
27652
0
        return WOLFSSL_FAILURE;
27653
0
    }
27654
27655
0
    ret = wolfSSL_BIO_write(bio, tmp, pemSz);
27656
0
    XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
27657
0
    if (ret != pemSz) {
27658
0
        WOLFSSL_MSG("Unable to write full PEM to BIO");
27659
0
        return WOLFSSL_FAILURE;
27660
0
    }
27661
27662
0
    return WOLFSSL_SUCCESS;
27663
0
}
27664
#endif /* !NO_BIO */
27665
27666
/* Colon separated list of <public key>+<digest> algorithms.
27667
 * Replaces list in context.
27668
 */
27669
int wolfSSL_CTX_set1_sigalgs_list(WOLFSSL_CTX* ctx, const char* list)
27670
0
{
27671
0
    WOLFSSL_MSG("wolfSSL_CTX_set1_sigalg_list");
27672
27673
0
    if (ctx == NULL || list == NULL) {
27674
0
        WOLFSSL_MSG("Bad function arguments");
27675
0
        return WOLFSSL_FAILURE;
27676
0
    }
27677
27678
    /* alloc/init on demand only */
27679
0
    if (ctx->suites == NULL) {
27680
0
        ctx->suites = (Suites*)XMALLOC(sizeof(Suites), ctx->heap,
27681
0
                                       DYNAMIC_TYPE_SUITES);
27682
0
        if (ctx->suites == NULL) {
27683
0
            WOLFSSL_MSG("Memory alloc for Suites failed");
27684
0
            return WOLFSSL_FAILURE;
27685
0
        }
27686
0
        XMEMSET(ctx->suites, 0, sizeof(Suites));
27687
0
    }
27688
27689
0
    return SetSuitesHashSigAlgo(ctx->suites, list);
27690
0
}
27691
27692
/* Colon separated list of <public key>+<digest> algorithms.
27693
 * Replaces list in SSL.
27694
 */
27695
int wolfSSL_set1_sigalgs_list(WOLFSSL* ssl, const char* list)
27696
0
{
27697
0
    WOLFSSL_MSG("wolfSSL_set1_sigalg_list");
27698
27699
0
    if (ssl == NULL) {
27700
0
        WOLFSSL_MSG("Bad function arguments");
27701
0
        return WOLFSSL_FAILURE;
27702
0
    }
27703
27704
#ifdef SINGLE_THREADED
27705
    if (ssl->ctx->suites == ssl->suites) {
27706
        ssl->suites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap,
27707
                                       DYNAMIC_TYPE_SUITES);
27708
        if (ssl->suites == NULL) {
27709
            WOLFSSL_MSG("Suites Memory error");
27710
            return MEMORY_E;
27711
        }
27712
        *ssl->suites = *ssl->ctx->suites;
27713
        ssl->options.ownSuites = 1;
27714
    }
27715
#endif
27716
0
    if (ssl == NULL || list == NULL) {
27717
0
        WOLFSSL_MSG("Bad function arguments");
27718
0
        return WOLFSSL_FAILURE;
27719
0
    }
27720
27721
0
    return SetSuitesHashSigAlgo(ssl->suites, list);
27722
0
}
27723
27724
struct WOLFSSL_HashSigInfo {
27725
    int hashAlgo;
27726
    int sigAlgo;
27727
    int nid;
27728
}  wolfssl_hash_sig_info[] =
27729
{
27730
#ifndef NO_RSA
27731
    #ifndef NO_SHA256
27732
        { sha256_mac, rsa_sa_algo, CTC_SHA256wRSA },
27733
    #endif
27734
    #ifdef WOLFSSL_SHA384
27735
        { sha384_mac, rsa_sa_algo, CTC_SHA384wRSA },
27736
    #endif
27737
    #ifdef WOLFSSL_SHA512
27738
        { sha512_mac, rsa_sa_algo, CTC_SHA512wRSA },
27739
    #endif
27740
    #ifdef WOLFSSL_SHA224
27741
        { sha224_mac, rsa_sa_algo, CTC_SHA224wRSA },
27742
    #endif
27743
    #ifndef NO_SHA
27744
        { sha_mac,    rsa_sa_algo, CTC_SHAwRSA },
27745
    #endif
27746
    #ifdef WC_RSA_PSS
27747
        #ifndef NO_SHA256
27748
            { sha256_mac, rsa_pss_sa_algo, CTC_SHA256wRSA },
27749
        #endif
27750
        #ifdef WOLFSSL_SHA384
27751
            { sha384_mac, rsa_pss_sa_algo, CTC_SHA384wRSA },
27752
        #endif
27753
        #ifdef WOLFSSL_SHA512
27754
            { sha512_mac, rsa_pss_sa_algo, CTC_SHA512wRSA },
27755
        #endif
27756
        #ifdef WOLFSSL_SHA224
27757
            { sha224_mac, rsa_pss_sa_algo, CTC_SHA224wRSA },
27758
        #endif
27759
    #endif
27760
#endif
27761
#ifdef HAVE_ECC
27762
    #ifndef NO_SHA256
27763
        { sha256_mac, ecc_dsa_sa_algo, CTC_SHA256wECDSA },
27764
    #endif
27765
    #ifdef WOLFSSL_SHA384
27766
        { sha384_mac, ecc_dsa_sa_algo, CTC_SHA384wECDSA },
27767
    #endif
27768
    #ifdef WOLFSSL_SHA512
27769
        { sha512_mac, ecc_dsa_sa_algo, CTC_SHA512wECDSA },
27770
    #endif
27771
    #ifdef WOLFSSL_SHA224
27772
        { sha224_mac, ecc_dsa_sa_algo, CTC_SHA224wECDSA },
27773
    #endif
27774
    #ifndef NO_SHA
27775
        { sha_mac,    ecc_dsa_sa_algo, CTC_SHAwECDSA },
27776
    #endif
27777
#endif
27778
#ifdef HAVE_ED25519
27779
    { no_mac, ed25519_sa_algo, CTC_ED25519 },
27780
#endif
27781
#ifdef HAVE_ED448
27782
    { no_mac, ed448_sa_algo, CTC_ED448 },
27783
#endif
27784
#ifdef HAVE_PQC
27785
#ifdef HAVE_FALCON
27786
    { no_mac, falcon_level1_sa_algo, CTC_FALCON_LEVEL1 },
27787
    { no_mac, falcon_level5_sa_algo, CTC_FALCON_LEVEL5 },
27788
#endif /* HAVE_FALCON */
27789
#ifdef HAVE_DILITHIUM
27790
    { no_mac, dilithium_level2_sa_algo, CTC_DILITHIUM_LEVEL2 },
27791
    { no_mac, dilithium_level3_sa_algo, CTC_DILITHIUM_LEVEL3 },
27792
    { no_mac, dilithium_level5_sa_algo, CTC_DILITHIUM_LEVEL5 },
27793
    { no_mac, dilithium_aes_level2_sa_algo, CTC_DILITHIUM_AES_LEVEL2 },
27794
    { no_mac, dilithium_aes_level3_sa_algo, CTC_DILITHIUM_AES_LEVEL3 },
27795
    { no_mac, dilithium_aes_level5_sa_algo, CTC_DILITHIUM_AES_LEVEL5 },
27796
#endif /* HAVE_DILITHIUM */
27797
#endif /* HAVE_PQC */
27798
#ifndef NO_DSA
27799
    #ifndef NO_SHA
27800
        { sha_mac,    dsa_sa_algo, CTC_SHAwDSA },
27801
    #endif
27802
#endif
27803
};
27804
#define WOLFSSL_HASH_SIG_INFO_SZ \
27805
0
    (int)(sizeof(wolfssl_hash_sig_info)/sizeof(*wolfssl_hash_sig_info))
27806
27807
int wolfSSL_get_signature_nid(WOLFSSL *ssl, int* nid)
27808
0
{
27809
0
    int i;
27810
0
    int ret = WOLFSSL_FAILURE;
27811
27812
0
    WOLFSSL_MSG("wolfSSL_get_signature_nid");
27813
27814
0
    if (ssl == NULL) {
27815
0
        WOLFSSL_MSG("Bad function arguments");
27816
0
        return WOLFSSL_FAILURE;
27817
0
    }
27818
27819
0
    for (i = 0; i < WOLFSSL_HASH_SIG_INFO_SZ; i++) {
27820
0
        if (ssl->suites->hashAlgo == wolfssl_hash_sig_info[i].hashAlgo &&
27821
0
                     ssl->suites->sigAlgo == wolfssl_hash_sig_info[i].sigAlgo) {
27822
0
            *nid = wolfssl_hash_sig_info[i].nid;
27823
0
            ret = WOLFSSL_SUCCESS;
27824
0
            break;
27825
0
        }
27826
0
    }
27827
27828
0
    return ret;
27829
0
}
27830
27831
#ifdef HAVE_ECC
27832
27833
#if defined(WOLFSSL_TLS13) && defined(HAVE_SUPPORTED_CURVES)
27834
static int populate_groups(int* groups, int max_count, char *list)
27835
0
{
27836
0
    char *end;
27837
0
    int len;
27838
0
    int count = 0;
27839
0
    const WOLF_EC_NIST_NAME* nist_name;
27840
27841
0
    if (!groups || !list) {
27842
0
        return -1;
27843
0
    }
27844
27845
0
    for (end = list; ; list = ++end) {
27846
0
        if (count > max_count) {
27847
0
            WOLFSSL_MSG("Too many curves in list");
27848
0
            return -1;
27849
0
        }
27850
0
        while (*end != ':' && *end != '\0') end++;
27851
0
        len = (int)(end - list); /* end points to char after end
27852
                                  * of curve name so no need for -1 */
27853
0
        if ((len < kNistCurves_MIN_NAME_LEN) ||
27854
0
                (len > kNistCurves_MAX_NAME_LEN)) {
27855
0
            WOLFSSL_MSG("Unrecognized curve name in list");
27856
0
            return -1;
27857
0
        }
27858
0
        for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) {
27859
0
            if (len == nist_name->name_len &&
27860
0
                    XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) {
27861
0
                break;
27862
0
            }
27863
0
        }
27864
0
        if (!nist_name->name) {
27865
0
            WOLFSSL_MSG("Unrecognized curve name in list");
27866
0
            return -1;
27867
0
        }
27868
0
        groups[count++] = nist_name->nid;
27869
0
        if (*end == '\0') break;
27870
0
    }
27871
27872
0
    return count;
27873
0
}
27874
27875
int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list)
27876
0
{
27877
0
    int groups[WOLFSSL_MAX_GROUP_COUNT];
27878
0
    int count;
27879
27880
0
    if (!ctx || !list) {
27881
0
        return WOLFSSL_FAILURE;
27882
0
    }
27883
27884
0
    if ((count = populate_groups(groups,
27885
0
            WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
27886
0
        return WOLFSSL_FAILURE;
27887
0
    }
27888
27889
0
    return wolfSSL_CTX_set1_groups(ctx, groups, count);
27890
0
}
27891
27892
int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list)
27893
0
{
27894
0
    int groups[WOLFSSL_MAX_GROUP_COUNT];
27895
0
    int count;
27896
27897
0
    if (!ssl || !list) {
27898
0
        return WOLFSSL_FAILURE;
27899
0
    }
27900
27901
0
    if ((count = populate_groups(groups,
27902
0
            WOLFSSL_MAX_GROUP_COUNT, list)) == -1) {
27903
0
        return WOLFSSL_FAILURE;
27904
0
    }
27905
27906
0
    return wolfSSL_set1_groups(ssl, groups, count);
27907
0
}
27908
#endif /* WOLFSSL_TLS13 */
27909
27910
#endif /* HAVE_ECC */
27911
27912
#ifndef NO_BIO
27913
/* Number of bytes to read from a file at a time. */
27914
0
#define PEM_READ_FILE_CHUNK_SZ  100
27915
27916
static int pem_read_bio_file(WOLFSSL_BIO* bio, char** pem)
27917
0
{
27918
0
    int ret   = 0;
27919
0
    int idx   = 0;
27920
0
    int sz    = PEM_READ_FILE_CHUNK_SZ; /* read from file by chunks */
27921
0
    int memSz = 0;
27922
0
    char* mem = NULL;
27923
0
    char* tmp;
27924
27925
    /* Allocate a chunk to read into. */
27926
0
    tmp = (char*)XMALLOC(sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
27927
0
    if (tmp == NULL) {
27928
0
        WOLFSSL_MSG("Memory error");
27929
0
        ret = MEMORY_E;
27930
0
    }
27931
27932
0
    while (ret == 0 && (sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) {
27933
0
        char* newMem;
27934
27935
        /* sanity check for signed overflow */
27936
0
        if (memSz + sz < 0) {
27937
0
            break;
27938
0
        }
27939
27940
        /* Reallocate to make space for read data. */
27941
0
        newMem = (char*)XREALLOC(mem, memSz + sz, bio->heap,
27942
0
                DYNAMIC_TYPE_OPENSSL);
27943
0
        if (newMem == NULL) {
27944
0
            WOLFSSL_MSG("Memory error");
27945
0
            ret = MEMORY_E;
27946
0
            break;
27947
0
        }
27948
0
        mem = newMem;
27949
27950
        /* Copy in new data. */
27951
0
        XMEMCPY(mem + idx, tmp, sz);
27952
0
        memSz += sz;
27953
0
        idx   += sz;
27954
0
        sz = PEM_READ_FILE_CHUNK_SZ; /* read another chunk from file */
27955
0
    }
27956
27957
0
    XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
27958
0
    tmp = NULL;
27959
27960
0
    if (ret == 0) {
27961
        /* Check data was read. */
27962
0
        if (memSz <= 0) {
27963
0
            WOLFSSL_MSG("No data to read from bio");
27964
0
            ret = BUFFER_E;
27965
0
        }
27966
0
        else {
27967
            /* Return size of data read. */
27968
0
            ret = memSz;
27969
0
        }
27970
0
    }
27971
    /* Dispose of any allocated memory on error. */
27972
0
    if (ret < 0) {
27973
0
        XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
27974
0
        mem = NULL;
27975
0
    }
27976
27977
0
    *pem = mem;
27978
0
    return ret;
27979
0
}
27980
27981
static int pem_read_bio_pending(WOLFSSL_BIO* bio, int pendingSz, char** pem)
27982
0
{
27983
0
    int ret = 0;
27984
0
    char* mem;
27985
27986
    /* Allocate buffer to hold pending data. */
27987
0
    mem = (char*)XMALLOC(pendingSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
27988
0
    if (mem == NULL) {
27989
0
        WOLFSSL_MSG("Memory error");
27990
0
        ret = MEMORY_E;
27991
0
    }
27992
0
    else if ((ret = wolfSSL_BIO_read(bio, mem, pendingSz)) <= 0) {
27993
        /* Pending data not read. */
27994
0
        XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
27995
0
        mem = NULL;
27996
0
        ret = MEMORY_E;
27997
0
    }
27998
27999
0
    *pem = mem;
28000
0
    return ret;
28001
0
}
28002
28003
static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
28004
                            void* pass, int keyType, int* eccFlag,
28005
                            DerBuffer** der)
28006
0
{
28007
0
#ifdef WOLFSSL_SMALL_STACK
28008
0
    EncryptedInfo* info = NULL;
28009
#else
28010
    EncryptedInfo info[1];
28011
#endif /* WOLFSSL_SMALL_STACK */
28012
0
    wc_pem_password_cb* localCb = NULL;
28013
0
    char* mem = NULL;
28014
0
    int ret;
28015
28016
0
    if (cb != NULL) {
28017
0
        localCb = cb;
28018
0
    }
28019
0
    else if (pass != NULL) {
28020
0
        localCb = wolfSSL_PEM_def_callback;
28021
0
    }
28022
28023
0
    if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
28024
0
        ret = pem_read_bio_pending(bio, ret, &mem);
28025
0
    }
28026
0
    else if (bio->type == WOLFSSL_BIO_FILE) {
28027
0
        ret = pem_read_bio_file(bio, &mem);
28028
0
    }
28029
0
    else {
28030
0
        WOLFSSL_MSG("No data to read from bio");
28031
0
        ret = NOT_COMPILED_IN;
28032
0
    }
28033
28034
0
#ifdef WOLFSSL_SMALL_STACK
28035
0
    if (ret >= 0) {
28036
0
        info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
28037
0
                                       DYNAMIC_TYPE_TMP_BUFFER);
28038
0
        if (info == NULL) {
28039
0
            WOLFSSL_MSG("Error getting memory for EncryptedInfo structure");
28040
0
            XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
28041
0
            mem = NULL;
28042
0
            ret = MEMORY_E;
28043
0
        }
28044
0
    }
28045
0
#endif /* WOLFSSL_SMALL_STACK */
28046
28047
0
    if (ret >= 0) {
28048
0
        int memSz = ret;
28049
28050
0
        XMEMSET(info, 0, sizeof(EncryptedInfo));
28051
0
        info->passwd_cb       = localCb;
28052
0
        info->passwd_userdata = pass;
28053
28054
        /* Do not strip PKCS8 header */
28055
0
        ret = PemToDer((const unsigned char*)mem, memSz, keyType, der, NULL,
28056
0
            info, eccFlag);
28057
0
        if (ret < 0) {
28058
0
            WOLFSSL_MSG("Bad PEM To DER");
28059
0
        }
28060
        /* Write left over data back to BIO if not a file BIO */
28061
0
        else if ((memSz - (int)info->consumed) > 0 &&
28062
0
                 bio->type != WOLFSSL_BIO_FILE) {
28063
0
            if (wolfSSL_BIO_write(bio, mem + (int)info->consumed,
28064
0
                                  memSz - (int)info->consumed) <= 0) {
28065
0
                WOLFSSL_MSG("Unable to advance bio read pointer");
28066
0
            }
28067
0
        }
28068
0
    }
28069
28070
0
#ifdef WOLFSSL_SMALL_STACK
28071
0
    XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28072
0
#endif
28073
0
    XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
28074
28075
0
    return ret;
28076
0
}
28077
28078
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
28079
                                                  WOLFSSL_EVP_PKEY** key,
28080
                                                  wc_pem_password_cb* cb,
28081
                                                  void* pass)
28082
0
{
28083
0
    WOLFSSL_EVP_PKEY* pkey = NULL;
28084
0
    DerBuffer*         der = NULL;
28085
0
    int             keyFormat = 0;
28086
0
    int                 type = -1;
28087
28088
0
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PrivateKey");
28089
28090
0
    if (bio == NULL)
28091
0
        return pkey;
28092
28093
0
    if (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE, &keyFormat,
28094
0
                                                                   &der) >= 0) {
28095
0
        const unsigned char* ptr = der->buffer;
28096
28097
0
        if (keyFormat) {
28098
            /* keyFormat is Key_Sum enum */
28099
0
            if (keyFormat == RSAk)
28100
0
                type = EVP_PKEY_RSA;
28101
0
            else if (keyFormat == ECDSAk)
28102
0
                type = EVP_PKEY_EC;
28103
0
            else if (keyFormat == DSAk)
28104
0
                type = EVP_PKEY_DSA;
28105
0
            else if (keyFormat == DHk)
28106
0
                type = EVP_PKEY_DH;
28107
0
        }
28108
0
        else {
28109
            /* Default to RSA if format is not set */
28110
0
            type = EVP_PKEY_RSA;
28111
0
        }
28112
28113
        /* handle case where reuse is attempted */
28114
0
        if (key != NULL && *key != NULL)
28115
0
            pkey = *key;
28116
28117
0
        wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length);
28118
0
        if (pkey == NULL) {
28119
0
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
28120
0
        }
28121
0
    }
28122
28123
0
    FreeDer(&der);
28124
28125
0
    if (key != NULL && pkey != NULL)
28126
0
        *key = pkey;
28127
28128
0
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PrivateKey", 0);
28129
28130
0
    return pkey;
28131
0
}
28132
28133
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
28134
                                              WOLFSSL_EVP_PKEY **key,
28135
                                              wc_pem_password_cb *cb,
28136
                                              void *pass)
28137
0
{
28138
0
    WOLFSSL_EVP_PKEY* pkey = NULL;
28139
0
    DerBuffer*        der = NULL;
28140
0
    int               keyFormat = 0;
28141
28142
0
    WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
28143
28144
0
    if (bio == NULL)
28145
0
        return pkey;
28146
28147
0
    if (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE, &keyFormat, &der) >= 0) {
28148
0
        const unsigned char* ptr = der->buffer;
28149
28150
        /* handle case where reuse is attempted */
28151
0
        if (key != NULL && *key != NULL)
28152
0
            pkey = *key;
28153
28154
0
        wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length);
28155
0
        if (pkey == NULL) {
28156
0
            WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
28157
0
        }
28158
0
    }
28159
28160
0
    FreeDer(&der);
28161
28162
0
    if (key != NULL && pkey != NULL)
28163
0
        *key = pkey;
28164
28165
0
    WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
28166
28167
0
    return pkey;
28168
0
}
28169
28170
#if !defined(NO_FILESYSTEM)
28171
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **x,
28172
                                          wc_pem_password_cb *cb, void *u)
28173
0
{
28174
0
    int err = 0;
28175
0
    WOLFSSL_EVP_PKEY* ret = NULL;
28176
0
    WOLFSSL_BIO* bio = NULL;
28177
28178
0
    WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
28179
28180
0
    if (fp == XBADFILE) {
28181
0
        err = 1;
28182
0
    }
28183
0
    if (err == 0) {
28184
0
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
28185
0
        err = bio == NULL;
28186
0
    }
28187
0
    if (err == 0) {
28188
0
        err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS;
28189
0
    }
28190
0
    if (err == 0) {
28191
0
        ret = wolfSSL_PEM_read_bio_PUBKEY(bio, x, cb, u);
28192
0
    }
28193
28194
0
    if (bio != NULL) {
28195
0
        wolfSSL_BIO_free(bio);
28196
0
    }
28197
28198
0
    WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
28199
28200
0
    return ret;
28201
0
}
28202
#endif /* NO_FILESYSTEM */
28203
#endif /* !NO_BIO */
28204
#endif /* OPENSSL_EXTRA */
28205
28206
#ifdef WOLFSSL_ALT_CERT_CHAINS
28207
int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
28208
{
28209
    int isUsing = 0;
28210
    if (ssl)
28211
        isUsing = ssl->options.usingAltCertChain;
28212
    return isUsing;
28213
}
28214
#endif /* WOLFSSL_ALT_CERT_CHAINS */
28215
28216
28217
#ifdef SESSION_CERTS
28218
28219
#ifdef WOLFSSL_ALT_CERT_CHAINS
28220
/* Get peer's alternate certificate chain */
28221
WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
28222
{
28223
    WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
28224
    if (ssl)
28225
        return &ssl->session->altChain;
28226
28227
    return 0;
28228
}
28229
#endif /* WOLFSSL_ALT_CERT_CHAINS */
28230
28231
28232
/* Get peer's certificate chain */
28233
WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
28234
{
28235
    WOLFSSL_ENTER("wolfSSL_get_peer_chain");
28236
    if (ssl)
28237
        return &ssl->session->chain;
28238
28239
    return 0;
28240
}
28241
28242
28243
/* Get peer's certificate chain total count */
28244
int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
28245
{
28246
    WOLFSSL_ENTER("wolfSSL_get_chain_count");
28247
    if (chain)
28248
        return chain->count;
28249
28250
    return 0;
28251
}
28252
28253
28254
/* Get peer's ASN.1 DER certificate at index (idx) length in bytes */
28255
int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
28256
{
28257
    WOLFSSL_ENTER("wolfSSL_get_chain_length");
28258
    if (chain)
28259
        return chain->certs[idx].length;
28260
28261
    return 0;
28262
}
28263
28264
28265
/* Get peer's ASN.1 DER certificate at index (idx) */
28266
byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
28267
{
28268
    WOLFSSL_ENTER("wolfSSL_get_chain_cert");
28269
    if (chain)
28270
        return chain->certs[idx].buffer;
28271
28272
    return 0;
28273
}
28274
28275
28276
/* Get peer's wolfSSL X509 certificate at index (idx) */
28277
WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
28278
{
28279
    int          ret;
28280
    WOLFSSL_X509* x509 = NULL;
28281
#ifdef WOLFSSL_SMALL_STACK
28282
    DecodedCert* cert = NULL;
28283
#else
28284
    DecodedCert  cert[1];
28285
#endif
28286
28287
    WOLFSSL_ENTER("wolfSSL_get_chain_X509");
28288
    if (chain != NULL) {
28289
    #ifdef WOLFSSL_SMALL_STACK
28290
        cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
28291
                                                       DYNAMIC_TYPE_DCERT);
28292
        if (cert != NULL)
28293
    #endif
28294
        {
28295
            InitDecodedCert(cert, chain->certs[idx].buffer,
28296
                                  chain->certs[idx].length, NULL);
28297
28298
            if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL)) != 0) {
28299
                WOLFSSL_MSG("Failed to parse cert");
28300
            }
28301
            else {
28302
                x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
28303
                                                             DYNAMIC_TYPE_X509);
28304
                if (x509 == NULL) {
28305
                    WOLFSSL_MSG("Failed alloc X509");
28306
                }
28307
                else {
28308
                    InitX509(x509, 1, NULL);
28309
28310
                    if ((ret = CopyDecodedToX509(x509, cert)) != 0) {
28311
                        WOLFSSL_MSG("Failed to copy decoded");
28312
                        wolfSSL_X509_free(x509);
28313
                        x509 = NULL;
28314
                    }
28315
                }
28316
            }
28317
28318
            FreeDecodedCert(cert);
28319
        #ifdef WOLFSSL_SMALL_STACK
28320
            XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
28321
        #endif
28322
        }
28323
    }
28324
    (void)ret;
28325
28326
    return x509;
28327
}
28328
28329
28330
/* Get peer's PEM certificate at index (idx), output to buffer if inLen big
28331
   enough else return error (-1). If buffer is NULL only calculate
28332
   outLen. Output length is in *outLen WOLFSSL_SUCCESS on ok */
28333
int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
28334
                               unsigned char* buf, int inLen, int* outLen)
28335
{
28336
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
28337
    const char* header = NULL;
28338
    const char* footer = NULL;
28339
    int headerLen;
28340
    int footerLen;
28341
    int i;
28342
    int err;
28343
    word32 szNeeded = 0;
28344
28345
    WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
28346
    if (!chain || !outLen || idx < 0 || idx >= wolfSSL_get_chain_count(chain))
28347
        return BAD_FUNC_ARG;
28348
28349
    err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer);
28350
    if (err != 0)
28351
        return err;
28352
28353
    headerLen = (int)XSTRLEN(header);
28354
    footerLen = (int)XSTRLEN(footer);
28355
28356
    /* Null output buffer return size needed in outLen */
28357
    if(!buf) {
28358
        if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length,
28359
                    NULL, &szNeeded) != LENGTH_ONLY_E)
28360
            return WOLFSSL_FAILURE;
28361
        *outLen = szNeeded + headerLen + footerLen;
28362
        return LENGTH_ONLY_E;
28363
    }
28364
28365
    /* don't even try if inLen too short */
28366
    if (inLen < headerLen + footerLen + chain->certs[idx].length)
28367
        return BAD_FUNC_ARG;
28368
28369
    /* header */
28370
    if (XMEMCPY(buf, header, headerLen) == NULL)
28371
        return WOLFSSL_FATAL_ERROR;
28372
28373
    i = headerLen;
28374
28375
    /* body */
28376
    *outLen = inLen;  /* input to Base64_Encode */
28377
    if ( (err = Base64_Encode(chain->certs[idx].buffer,
28378
                       chain->certs[idx].length, buf + i, (word32*)outLen)) < 0)
28379
        return err;
28380
    i += *outLen;
28381
28382
    /* footer */
28383
    if ( (i + footerLen) > inLen)
28384
        return BAD_FUNC_ARG;
28385
    if (XMEMCPY(buf + i, footer, footerLen) == NULL)
28386
        return WOLFSSL_FATAL_ERROR;
28387
    *outLen += headerLen + footerLen;
28388
28389
    return WOLFSSL_SUCCESS;
28390
#else
28391
    (void)chain;
28392
    (void)idx;
28393
    (void)buf;
28394
    (void)inLen;
28395
    (void)outLen;
28396
    return WOLFSSL_FAILURE;
28397
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
28398
}
28399
28400
28401
/* get session ID */
28402
WOLFSSL_ABI
28403
const byte* wolfSSL_get_sessionID(const WOLFSSL_SESSION* session)
28404
{
28405
    WOLFSSL_ENTER("wolfSSL_get_sessionID");
28406
    session = ClientSessionToSession(session);
28407
    if (session)
28408
        return session->sessionID;
28409
28410
    return NULL;
28411
}
28412
28413
28414
#endif /* SESSION_CERTS */
28415
28416
#ifdef HAVE_FUZZER
28417
void wolfSSL_SetFuzzerCb(WOLFSSL* ssl, CallbackFuzzer cbf, void* fCtx)
28418
{
28419
    if (ssl) {
28420
        ssl->fuzzerCb  = cbf;
28421
        ssl->fuzzerCtx = fCtx;
28422
    }
28423
}
28424
#endif
28425
28426
#ifndef NO_CERTS
28427
#ifdef  HAVE_PK_CALLBACKS
28428
28429
#ifdef HAVE_ECC
28430
void  wolfSSL_CTX_SetEccKeyGenCb(WOLFSSL_CTX* ctx, CallbackEccKeyGen cb)
28431
{
28432
    if (ctx)
28433
        ctx->EccKeyGenCb = cb;
28434
}
28435
void  wolfSSL_SetEccKeyGenCtx(WOLFSSL* ssl, void *ctx)
28436
{
28437
    if (ssl)
28438
        ssl->EccKeyGenCtx = ctx;
28439
}
28440
void* wolfSSL_GetEccKeyGenCtx(WOLFSSL* ssl)
28441
{
28442
    if (ssl)
28443
        return ssl->EccKeyGenCtx;
28444
28445
    return NULL;
28446
}
28447
void  wolfSSL_CTX_SetEccSignCtx(WOLFSSL_CTX* ctx, void *userCtx)
28448
{
28449
    if (ctx)
28450
        ctx->EccSignCtx = userCtx;
28451
}
28452
void* wolfSSL_CTX_GetEccSignCtx(WOLFSSL_CTX* ctx)
28453
{
28454
    if (ctx)
28455
        return ctx->EccSignCtx;
28456
28457
    return NULL;
28458
}
28459
28460
WOLFSSL_ABI
28461
void  wolfSSL_CTX_SetEccSignCb(WOLFSSL_CTX* ctx, CallbackEccSign cb)
28462
{
28463
    if (ctx)
28464
        ctx->EccSignCb = cb;
28465
}
28466
void  wolfSSL_SetEccSignCtx(WOLFSSL* ssl, void *ctx)
28467
{
28468
    if (ssl)
28469
        ssl->EccSignCtx = ctx;
28470
}
28471
void* wolfSSL_GetEccSignCtx(WOLFSSL* ssl)
28472
{
28473
    if (ssl)
28474
        return ssl->EccSignCtx;
28475
28476
    return NULL;
28477
}
28478
28479
void  wolfSSL_CTX_SetEccVerifyCb(WOLFSSL_CTX* ctx, CallbackEccVerify cb)
28480
{
28481
    if (ctx)
28482
        ctx->EccVerifyCb = cb;
28483
}
28484
void  wolfSSL_SetEccVerifyCtx(WOLFSSL* ssl, void *ctx)
28485
{
28486
    if (ssl)
28487
        ssl->EccVerifyCtx = ctx;
28488
}
28489
void* wolfSSL_GetEccVerifyCtx(WOLFSSL* ssl)
28490
{
28491
    if (ssl)
28492
        return ssl->EccVerifyCtx;
28493
28494
    return NULL;
28495
}
28496
28497
void wolfSSL_CTX_SetEccSharedSecretCb(WOLFSSL_CTX* ctx, CallbackEccSharedSecret cb)
28498
{
28499
    if (ctx)
28500
        ctx->EccSharedSecretCb = cb;
28501
}
28502
void  wolfSSL_SetEccSharedSecretCtx(WOLFSSL* ssl, void *ctx)
28503
{
28504
    if (ssl)
28505
        ssl->EccSharedSecretCtx = ctx;
28506
}
28507
void* wolfSSL_GetEccSharedSecretCtx(WOLFSSL* ssl)
28508
{
28509
    if (ssl)
28510
        return ssl->EccSharedSecretCtx;
28511
28512
    return NULL;
28513
}
28514
#endif /* HAVE_ECC */
28515
28516
#ifdef HAVE_ED25519
28517
void  wolfSSL_CTX_SetEd25519SignCb(WOLFSSL_CTX* ctx, CallbackEd25519Sign cb)
28518
{
28519
    if (ctx)
28520
        ctx->Ed25519SignCb = cb;
28521
}
28522
void  wolfSSL_SetEd25519SignCtx(WOLFSSL* ssl, void *ctx)
28523
{
28524
    if (ssl)
28525
        ssl->Ed25519SignCtx = ctx;
28526
}
28527
void* wolfSSL_GetEd25519SignCtx(WOLFSSL* ssl)
28528
{
28529
    if (ssl)
28530
        return ssl->Ed25519SignCtx;
28531
28532
    return NULL;
28533
}
28534
28535
void  wolfSSL_CTX_SetEd25519VerifyCb(WOLFSSL_CTX* ctx, CallbackEd25519Verify cb)
28536
{
28537
    if (ctx)
28538
        ctx->Ed25519VerifyCb = cb;
28539
}
28540
void  wolfSSL_SetEd25519VerifyCtx(WOLFSSL* ssl, void *ctx)
28541
{
28542
    if (ssl)
28543
        ssl->Ed25519VerifyCtx = ctx;
28544
}
28545
void* wolfSSL_GetEd25519VerifyCtx(WOLFSSL* ssl)
28546
{
28547
    if (ssl)
28548
        return ssl->Ed25519VerifyCtx;
28549
28550
    return NULL;
28551
}
28552
#endif /* HAVE_ED25519 */
28553
28554
#ifdef HAVE_CURVE25519
28555
void wolfSSL_CTX_SetX25519KeyGenCb(WOLFSSL_CTX* ctx,
28556
        CallbackX25519KeyGen cb)
28557
{
28558
    if (ctx)
28559
        ctx->X25519KeyGenCb = cb;
28560
}
28561
void  wolfSSL_SetX25519KeyGenCtx(WOLFSSL* ssl, void *ctx)
28562
{
28563
    if (ssl)
28564
        ssl->X25519KeyGenCtx = ctx;
28565
}
28566
void* wolfSSL_GetX25519KeyGenCtx(WOLFSSL* ssl)
28567
{
28568
    if (ssl)
28569
        return ssl->X25519KeyGenCtx;
28570
28571
    return NULL;
28572
}
28573
28574
void wolfSSL_CTX_SetX25519SharedSecretCb(WOLFSSL_CTX* ctx,
28575
        CallbackX25519SharedSecret cb)
28576
{
28577
    if (ctx)
28578
        ctx->X25519SharedSecretCb = cb;
28579
}
28580
void  wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx)
28581
{
28582
    if (ssl)
28583
        ssl->X25519SharedSecretCtx = ctx;
28584
}
28585
void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
28586
{
28587
    if (ssl)
28588
        return ssl->X25519SharedSecretCtx;
28589
28590
    return NULL;
28591
}
28592
#endif /* HAVE_CURVE25519 */
28593
28594
#ifdef HAVE_ED448
28595
void  wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX* ctx, CallbackEd448Sign cb)
28596
{
28597
    if (ctx)
28598
        ctx->Ed448SignCb = cb;
28599
}
28600
void  wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx)
28601
{
28602
    if (ssl)
28603
        ssl->Ed448SignCtx = ctx;
28604
}
28605
void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl)
28606
{
28607
    if (ssl)
28608
        return ssl->Ed448SignCtx;
28609
28610
    return NULL;
28611
}
28612
28613
void  wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX* ctx, CallbackEd448Verify cb)
28614
{
28615
    if (ctx)
28616
        ctx->Ed448VerifyCb = cb;
28617
}
28618
void  wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx)
28619
{
28620
    if (ssl)
28621
        ssl->Ed448VerifyCtx = ctx;
28622
}
28623
void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl)
28624
{
28625
    if (ssl)
28626
        return ssl->Ed448VerifyCtx;
28627
28628
    return NULL;
28629
}
28630
#endif /* HAVE_ED448 */
28631
28632
#ifdef HAVE_CURVE448
28633
void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX* ctx,
28634
        CallbackX448KeyGen cb)
28635
{
28636
    if (ctx)
28637
        ctx->X448KeyGenCb = cb;
28638
}
28639
void  wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx)
28640
{
28641
    if (ssl)
28642
        ssl->X448KeyGenCtx = ctx;
28643
}
28644
void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl)
28645
{
28646
    if (ssl)
28647
        return ssl->X448KeyGenCtx;
28648
28649
    return NULL;
28650
}
28651
28652
void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX* ctx,
28653
        CallbackX448SharedSecret cb)
28654
{
28655
    if (ctx)
28656
        ctx->X448SharedSecretCb = cb;
28657
}
28658
void  wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx)
28659
{
28660
    if (ssl)
28661
        ssl->X448SharedSecretCtx = ctx;
28662
}
28663
void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl)
28664
{
28665
    if (ssl)
28666
        return ssl->X448SharedSecretCtx;
28667
28668
    return NULL;
28669
}
28670
#endif /* HAVE_CURVE448 */
28671
28672
#ifndef NO_RSA
28673
void  wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
28674
{
28675
    if (ctx)
28676
        ctx->RsaSignCb = cb;
28677
}
28678
void  wolfSSL_CTX_SetRsaSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
28679
{
28680
    if (ctx)
28681
        ctx->RsaSignCheckCb = cb;
28682
}
28683
void  wolfSSL_SetRsaSignCtx(WOLFSSL* ssl, void *ctx)
28684
{
28685
    if (ssl)
28686
        ssl->RsaSignCtx = ctx;
28687
}
28688
void* wolfSSL_GetRsaSignCtx(WOLFSSL* ssl)
28689
{
28690
    if (ssl)
28691
        return ssl->RsaSignCtx;
28692
28693
    return NULL;
28694
}
28695
28696
28697
void  wolfSSL_CTX_SetRsaVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaVerify cb)
28698
{
28699
    if (ctx)
28700
        ctx->RsaVerifyCb = cb;
28701
}
28702
void  wolfSSL_SetRsaVerifyCtx(WOLFSSL* ssl, void *ctx)
28703
{
28704
    if (ssl)
28705
        ssl->RsaVerifyCtx = ctx;
28706
}
28707
void* wolfSSL_GetRsaVerifyCtx(WOLFSSL* ssl)
28708
{
28709
    if (ssl)
28710
        return ssl->RsaVerifyCtx;
28711
28712
    return NULL;
28713
}
28714
28715
#ifdef WC_RSA_PSS
28716
void  wolfSSL_CTX_SetRsaPssSignCb(WOLFSSL_CTX* ctx, CallbackRsaPssSign cb)
28717
{
28718
    if (ctx)
28719
        ctx->RsaPssSignCb = cb;
28720
}
28721
void  wolfSSL_CTX_SetRsaPssSignCheckCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
28722
{
28723
    if (ctx)
28724
        ctx->RsaPssSignCheckCb = cb;
28725
}
28726
void  wolfSSL_SetRsaPssSignCtx(WOLFSSL* ssl, void *ctx)
28727
{
28728
    if (ssl)
28729
        ssl->RsaPssSignCtx = ctx;
28730
}
28731
void* wolfSSL_GetRsaPssSignCtx(WOLFSSL* ssl)
28732
{
28733
    if (ssl)
28734
        return ssl->RsaPssSignCtx;
28735
28736
    return NULL;
28737
}
28738
28739
void  wolfSSL_CTX_SetRsaPssVerifyCb(WOLFSSL_CTX* ctx, CallbackRsaPssVerify cb)
28740
{
28741
    if (ctx)
28742
        ctx->RsaPssVerifyCb = cb;
28743
}
28744
void  wolfSSL_SetRsaPssVerifyCtx(WOLFSSL* ssl, void *ctx)
28745
{
28746
    if (ssl)
28747
        ssl->RsaPssVerifyCtx = ctx;
28748
}
28749
void* wolfSSL_GetRsaPssVerifyCtx(WOLFSSL* ssl)
28750
{
28751
    if (ssl)
28752
        return ssl->RsaPssVerifyCtx;
28753
28754
    return NULL;
28755
}
28756
#endif /* WC_RSA_PSS */
28757
28758
void  wolfSSL_CTX_SetRsaEncCb(WOLFSSL_CTX* ctx, CallbackRsaEnc cb)
28759
{
28760
    if (ctx)
28761
        ctx->RsaEncCb = cb;
28762
}
28763
void  wolfSSL_SetRsaEncCtx(WOLFSSL* ssl, void *ctx)
28764
{
28765
    if (ssl)
28766
        ssl->RsaEncCtx = ctx;
28767
}
28768
void* wolfSSL_GetRsaEncCtx(WOLFSSL* ssl)
28769
{
28770
    if (ssl)
28771
        return ssl->RsaEncCtx;
28772
28773
    return NULL;
28774
}
28775
28776
void  wolfSSL_CTX_SetRsaDecCb(WOLFSSL_CTX* ctx, CallbackRsaDec cb)
28777
{
28778
    if (ctx)
28779
        ctx->RsaDecCb = cb;
28780
}
28781
void  wolfSSL_SetRsaDecCtx(WOLFSSL* ssl, void *ctx)
28782
{
28783
    if (ssl)
28784
        ssl->RsaDecCtx = ctx;
28785
}
28786
void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl)
28787
{
28788
    if (ssl)
28789
        return ssl->RsaDecCtx;
28790
28791
    return NULL;
28792
}
28793
#endif /* NO_RSA */
28794
28795
/* callback for premaster secret generation */
28796
void  wolfSSL_CTX_SetGenPreMasterCb(WOLFSSL_CTX* ctx, CallbackGenPreMaster cb)
28797
{
28798
    if (ctx)
28799
        ctx->GenPreMasterCb = cb;
28800
}
28801
/* Set premaster secret generation callback context */
28802
void  wolfSSL_SetGenPreMasterCtx(WOLFSSL* ssl, void *ctx)
28803
{
28804
    if (ssl)
28805
        ssl->GenPreMasterCtx = ctx;
28806
}
28807
/* Get premaster secret generation callback context */
28808
void* wolfSSL_GetGenPreMasterCtx(WOLFSSL* ssl)
28809
{
28810
    if (ssl)
28811
        return ssl->GenPreMasterCtx;
28812
28813
    return NULL;
28814
}
28815
28816
/* callback for master secret generation */
28817
void  wolfSSL_CTX_SetGenMasterSecretCb(WOLFSSL_CTX* ctx, CallbackGenMasterSecret cb)
28818
{
28819
    if (ctx)
28820
        ctx->GenMasterCb = cb;
28821
}
28822
/* Set master secret generation callback context */
28823
void  wolfSSL_SetGenMasterSecretCtx(WOLFSSL* ssl, void *ctx)
28824
{
28825
    if (ssl)
28826
        ssl->GenMasterCtx = ctx;
28827
}
28828
/* Get master secret generation callback context */
28829
void* wolfSSL_GetGenMasterSecretCtx(WOLFSSL* ssl)
28830
{
28831
    if (ssl)
28832
        return ssl->GenMasterCtx;
28833
28834
    return NULL;
28835
}
28836
28837
/* callback for session key generation */
28838
void  wolfSSL_CTX_SetGenSessionKeyCb(WOLFSSL_CTX* ctx, CallbackGenSessionKey cb)
28839
{
28840
    if (ctx)
28841
        ctx->GenSessionKeyCb = cb;
28842
}
28843
/* Set session key generation callback context */
28844
void  wolfSSL_SetGenSessionKeyCtx(WOLFSSL* ssl, void *ctx)
28845
{
28846
    if (ssl)
28847
        ssl->GenSessionKeyCtx = ctx;
28848
}
28849
/* Get session key generation callback context */
28850
void* wolfSSL_GetGenSessionKeyCtx(WOLFSSL* ssl)
28851
{
28852
    if (ssl)
28853
        return ssl->GenSessionKeyCtx;
28854
28855
    return NULL;
28856
}
28857
28858
/* callback for setting encryption keys */
28859
void  wolfSSL_CTX_SetEncryptKeysCb(WOLFSSL_CTX* ctx, CallbackEncryptKeys cb)
28860
{
28861
    if (ctx)
28862
        ctx->EncryptKeysCb = cb;
28863
}
28864
/* Set encryption keys callback context */
28865
void  wolfSSL_SetEncryptKeysCtx(WOLFSSL* ssl, void *ctx)
28866
{
28867
    if (ssl)
28868
        ssl->EncryptKeysCtx = ctx;
28869
}
28870
/* Get encryption keys callback context */
28871
void* wolfSSL_GetEncryptKeysCtx(WOLFSSL* ssl)
28872
{
28873
    if (ssl)
28874
        return ssl->EncryptKeysCtx;
28875
28876
    return NULL;
28877
}
28878
28879
/* callback for Tls finished */
28880
/* the callback can be used to build TLS Finished message if enabled */
28881
void  wolfSSL_CTX_SetTlsFinishedCb(WOLFSSL_CTX* ctx, CallbackTlsFinished cb)
28882
{
28883
    if (ctx)
28884
        ctx->TlsFinishedCb = cb;
28885
}
28886
/* Set Tls finished callback context */
28887
void  wolfSSL_SetTlsFinishedCtx(WOLFSSL* ssl, void *ctx)
28888
{
28889
    if (ssl)
28890
        ssl->TlsFinishedCtx = ctx;
28891
}
28892
/* Get Tls finished callback context */
28893
void* wolfSSL_GetTlsFinishedCtx(WOLFSSL* ssl)
28894
{
28895
    if (ssl)
28896
        return ssl->TlsFinishedCtx;
28897
28898
    return NULL;
28899
}
28900
#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
28901
/* callback for verify data */
28902
void  wolfSSL_CTX_SetVerifyMacCb(WOLFSSL_CTX* ctx, CallbackVerifyMac cb)
28903
{
28904
    if (ctx)
28905
        ctx->VerifyMacCb = cb;
28906
}
28907
28908
/* Set set keys callback context */
28909
void  wolfSSL_SetVerifyMacCtx(WOLFSSL* ssl, void *ctx)
28910
{
28911
    if (ssl)
28912
        ssl->VerifyMacCtx = ctx;
28913
}
28914
/* Get set  keys callback context */
28915
void* wolfSSL_GetVerifyMacCtx(WOLFSSL* ssl)
28916
{
28917
    if (ssl)
28918
        return ssl->VerifyMacCtx;
28919
28920
    return NULL;
28921
}
28922
#endif /* !WOLFSSL_NO_TLS12 && !WOLFSSL_AEAD_ONLY */
28923
28924
#endif /* HAVE_PK_CALLBACKS */
28925
#endif /* NO_CERTS */
28926
28927
#if defined(HAVE_PK_CALLBACKS) && !defined(NO_DH)
28928
void wolfSSL_CTX_SetDhAgreeCb(WOLFSSL_CTX* ctx, CallbackDhAgree cb)
28929
{
28930
    if (ctx)
28931
        ctx->DhAgreeCb = cb;
28932
}
28933
void wolfSSL_SetDhAgreeCtx(WOLFSSL* ssl, void *ctx)
28934
{
28935
    if (ssl)
28936
        ssl->DhAgreeCtx = ctx;
28937
}
28938
void* wolfSSL_GetDhAgreeCtx(WOLFSSL* ssl)
28939
{
28940
    if (ssl)
28941
        return ssl->DhAgreeCtx;
28942
28943
    return NULL;
28944
}
28945
#endif /* HAVE_PK_CALLBACKS && !NO_DH */
28946
28947
#if defined(HAVE_PK_CALLBACKS) && defined(HAVE_HKDF)
28948
28949
void wolfSSL_CTX_SetHKDFExtractCb(WOLFSSL_CTX* ctx, CallbackHKDFExtract cb)
28950
{
28951
    if (ctx)
28952
        ctx->HkdfExtractCb = cb;
28953
}
28954
28955
void wolfSSL_SetHKDFExtractCtx(WOLFSSL* ssl, void *ctx)
28956
{
28957
    if (ssl)
28958
        ssl->HkdfExtractCtx = ctx;
28959
}
28960
28961
void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl)
28962
{
28963
    if (ssl)
28964
        return ssl->HkdfExtractCtx;
28965
28966
    return NULL;
28967
}
28968
#endif /* HAVE_PK_CALLBACKS && HAVE_HKDF */
28969
28970
#ifdef WOLFSSL_HAVE_WOLFSCEP
28971
    /* Used by autoconf to see if wolfSCEP is available */
28972
    void wolfSSL_wolfSCEP(void) {}
28973
#endif
28974
28975
28976
#ifdef WOLFSSL_HAVE_CERT_SERVICE
28977
    /* Used by autoconf to see if cert service is available */
28978
    void wolfSSL_cert_service(void) {}
28979
#endif
28980
28981
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
28982
    !defined(WOLFCRYPT_ONLY)
28983
#ifndef NO_CERTS
28984
28985
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
28986
/* Convert ASN1 input string into canonical ASN1 string                     */
28987
/*  , which has the following rules:                                        */
28988
/*   convert to UTF8                                                        */
28989
/*   convert to lower case                                                  */
28990
/*   multi-spaces collapsed                                                 */
28991
/* @param  asn_out a pointer to ASN1_STRING to be converted                 */
28992
/* @param  asn_in  a pointer to input ASN1_STRING                           */
28993
/* @return WOLFSSL_SUCCESS on successful converted, otherwise <=0 error code*/
28994
int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out,
28995
                              const WOLFSSL_ASN1_STRING* asn_in)
28996
0
{
28997
0
    char* dst;
28998
0
    char* src;
28999
0
    int i, len;
29000
29001
0
    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_canon");
29002
29003
    /* sanity check */
29004
0
    if (asn_out == NULL || asn_in == NULL) {
29005
0
        WOLFSSL_MSG("invalid function arguments");
29006
0
        return BAD_FUNC_ARG;
29007
0
    }
29008
29009
0
    switch (asn_in->type) {
29010
0
        case MBSTRING_UTF8:
29011
0
        case V_ASN1_PRINTABLESTRING:
29012
0
             break;
29013
0
        default:
29014
0
           WOLFSSL_MSG("just copy string");
29015
0
           return wolfSSL_ASN1_STRING_copy(asn_out, asn_in);
29016
0
    }
29017
    /* type is set as UTF8 */
29018
0
    asn_out->type = MBSTRING_UTF8;
29019
0
    asn_out->length = wolfSSL_ASN1_STRING_to_UTF8(
29020
0
        (unsigned char**)&asn_out->data, (WOLFSSL_ASN1_STRING*)asn_in);
29021
29022
0
    if (asn_out->length < 0) {
29023
0
        return WOLFSSL_FAILURE;
29024
0
    }
29025
    /* point to the last */
29026
0
    dst = asn_out->data + asn_out->length;
29027
    /* point to the start */
29028
0
    src = asn_out->data;
29029
29030
0
    len = asn_out->length;
29031
29032
    /* trimming spaces at the head and tail */
29033
0
    dst--;
29034
0
    for (; (len > 0 && XISSPACE(*dst)); len--) {
29035
0
        dst--;
29036
0
    }
29037
0
    for (; (len > 0 && XISSPACE(*src)); len--) {
29038
0
        src++;
29039
0
    }
29040
29041
    /* point to the start */
29042
0
    dst = asn_out->data;
29043
29044
0
    for (i = 0; i < len; dst++, i++) {
29045
0
        if (!XISASCII(*src)) {
29046
            /* keep non-ascii code */
29047
0
            *dst = *src++;
29048
0
        } else if (XISSPACE(*src)) {
29049
0
            *dst = 0x20; /* space */
29050
            /* remove the rest of spaces */
29051
0
            while (XISSPACE(*++src) && i++ < len);
29052
0
        } else {
29053
0
            *dst = (char)XTOLOWER((unsigned char)*src++);
29054
0
        }
29055
0
    }
29056
    /* put actual length */
29057
0
    asn_out->length = (int)(dst - asn_out->data);
29058
0
    return WOLFSSL_SUCCESS;
29059
0
}
29060
29061
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
29062
#if !defined(NO_FILESYSTEM)
29063
#ifndef NO_BIO
29064
    WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp,
29065
        WOLFSSL_EVP_PKEY **x, wc_pem_password_cb *cb, void *u)
29066
0
    {
29067
0
        int err = 0;
29068
0
        WOLFSSL_EVP_PKEY* ret = NULL;
29069
0
        WOLFSSL_BIO* bio = NULL;
29070
29071
0
        WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
29072
29073
0
        if (fp == XBADFILE) {
29074
0
            err = 1;
29075
0
        }
29076
0
        if (err == 0) {
29077
0
            bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
29078
0
            err = bio == NULL;
29079
0
        }
29080
0
        if (err == 0) {
29081
0
            err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS;
29082
0
        }
29083
0
        if (err == 0) {
29084
0
            ret = wolfSSL_PEM_read_bio_PrivateKey(bio, x, cb, u);
29085
0
        }
29086
29087
0
        if (bio != NULL) {
29088
0
            wolfSSL_BIO_free(bio);
29089
0
        }
29090
29091
0
        return ret;
29092
0
    }
29093
#endif
29094
#endif
29095
#endif
29096
29097
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL*/
29098
29099
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
29100
29101
0
    #define PEM_BEGIN              "-----BEGIN "
29102
0
    #define PEM_BEGIN_SZ           11
29103
0
    #define PEM_END                "-----END "
29104
0
    #define PEM_END_SZ             9
29105
    #define PEM_HDR_FIN            "-----"
29106
0
    #define PEM_HDR_FIN_SZ         5
29107
0
    #define PEM_HDR_FIN_EOL_NEWLINE   "-----\n"
29108
    #define PEM_HDR_FIN_EOL_NULL_TERM "-----\0"
29109
0
    #define PEM_HDR_FIN_EOL_SZ     6
29110
29111
#ifndef NO_BIO
29112
29113
    int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header,
29114
                             unsigned char **data, long *len)
29115
0
    {
29116
0
        int ret = WOLFSSL_SUCCESS;
29117
0
        char pem[256];
29118
0
        int pemLen;
29119
0
        char* p;
29120
0
        char* nameStr = NULL;
29121
0
        int nameLen = 0;
29122
0
        char* headerStr = NULL;
29123
0
        int headerLen;
29124
0
        int headerFound = 0;
29125
0
        unsigned char* der = NULL;
29126
0
        word32 derLen = 0;
29127
29128
0
        if (bio == NULL || name == NULL || header == NULL || data == NULL ||
29129
0
                                                                  len == NULL) {
29130
0
            return WOLFSSL_FAILURE;
29131
0
        }
29132
29133
        /* Find header line. */
29134
0
        pem[sizeof(pem) - 1] = '\0';
29135
0
        while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
29136
0
            if (XSTRNCMP(pem, PEM_BEGIN, PEM_BEGIN_SZ) == 0)
29137
0
                break;
29138
0
        }
29139
0
        if (pemLen <= 0)
29140
0
            ret = WOLFSSL_FAILURE;
29141
        /* Have a header line. */
29142
0
        if (ret == WOLFSSL_SUCCESS) {
29143
0
            while (pem[pemLen - 1] == '\r' || pem[pemLen - 1] == '\n')
29144
0
                pemLen--;
29145
0
            pem[pemLen] = '\0';
29146
0
            if (XSTRNCMP(pem + pemLen - PEM_HDR_FIN_SZ, PEM_HDR_FIN,
29147
0
                                                         PEM_HDR_FIN_SZ) != 0) {
29148
0
                ret = WOLFSSL_FAILURE;
29149
0
            }
29150
0
        }
29151
29152
        /* Get out name. */
29153
0
        if (ret == WOLFSSL_SUCCESS) {
29154
0
            nameLen = pemLen - PEM_BEGIN_SZ - PEM_HDR_FIN_SZ;
29155
0
            nameStr = (char*)XMALLOC(nameLen + 1, NULL,
29156
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29157
0
            if (nameStr == NULL)
29158
0
                ret = WOLFSSL_FAILURE;
29159
0
        }
29160
0
        if (ret == WOLFSSL_SUCCESS) {
29161
0
            XSTRNCPY(nameStr, pem + PEM_BEGIN_SZ, nameLen);
29162
0
            nameStr[nameLen] = '\0';
29163
29164
            /* Get header of PEM - encryption header. */
29165
0
            headerLen = 0;
29166
0
            while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
29167
0
                while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
29168
0
                                                     pem[pemLen - 1] == '\n')) {
29169
0
                    pemLen--;
29170
0
                }
29171
0
                pem[pemLen++] = '\n';
29172
0
                pem[pemLen] = '\0';
29173
29174
                /* Header separator is a blank line. */
29175
0
                if (pem[0] == '\n') {
29176
0
                    headerFound = 1;
29177
0
                    break;
29178
0
                }
29179
29180
                /* Didn't find a blank line - no header. */
29181
0
                if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0) {
29182
0
                    der = (unsigned char*)headerStr;
29183
0
                    derLen = headerLen;
29184
                    /* Empty header - empty string. */
29185
0
                    headerStr = (char*)XMALLOC(1, NULL,
29186
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29187
0
                    if (headerStr == NULL)
29188
0
                        ret = WOLFSSL_FAILURE;
29189
0
                    else
29190
0
                        headerStr[0] = '\0';
29191
0
                    break;
29192
0
                }
29193
29194
0
                p = (char*)XREALLOC(headerStr, headerLen + pemLen + 1, NULL,
29195
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29196
0
                if (p == NULL) {
29197
0
                    ret = WOLFSSL_FAILURE;
29198
0
                    break;
29199
0
                }
29200
29201
0
                headerStr = p;
29202
0
                XMEMCPY(headerStr + headerLen, pem, pemLen + 1);
29203
0
                headerLen += pemLen;
29204
0
            }
29205
0
            if (pemLen <= 0)
29206
0
                ret = WOLFSSL_FAILURE;
29207
0
        }
29208
29209
        /* Get body of PEM - if there was a header */
29210
0
        if (ret == WOLFSSL_SUCCESS && headerFound) {
29211
0
            derLen = 0;
29212
0
            while ((pemLen = wolfSSL_BIO_gets(bio, pem, sizeof(pem) - 1)) > 0) {
29213
0
                while (pemLen > 0 && (pem[pemLen - 1] == '\r' ||
29214
0
                                                     pem[pemLen - 1] == '\n')) {
29215
0
                    pemLen--;
29216
0
                }
29217
0
                pem[pemLen++] = '\n';
29218
0
                pem[pemLen] = '\0';
29219
29220
0
                if (XSTRNCMP(pem, PEM_END, PEM_END_SZ) == 0)
29221
0
                    break;
29222
29223
0
                p = (char*)XREALLOC(der, derLen + pemLen + 1, NULL,
29224
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
29225
0
                if (p == NULL) {
29226
0
                    ret = WOLFSSL_FAILURE;
29227
0
                    break;
29228
0
                }
29229
29230
0
                der = (unsigned char*)p;
29231
0
                XMEMCPY(der + derLen, pem, pemLen + 1);
29232
0
                derLen += pemLen;
29233
0
            }
29234
0
            if (pemLen <= 0)
29235
0
                ret = WOLFSSL_FAILURE;
29236
0
        }
29237
29238
        /* Check trailer. */
29239
0
        if (ret == WOLFSSL_SUCCESS) {
29240
0
            if (XSTRNCMP(pem + PEM_END_SZ, nameStr, nameLen) != 0)
29241
0
                ret = WOLFSSL_FAILURE;
29242
0
        }
29243
0
        if (ret == WOLFSSL_SUCCESS) {
29244
0
            if (XSTRNCMP(pem + PEM_END_SZ + nameLen,
29245
0
                    PEM_HDR_FIN_EOL_NEWLINE,
29246
0
                    PEM_HDR_FIN_EOL_SZ) != 0 &&
29247
0
                XSTRNCMP(pem + PEM_END_SZ + nameLen,
29248
0
                        PEM_HDR_FIN_EOL_NULL_TERM,
29249
0
                        PEM_HDR_FIN_EOL_SZ) != 0) {
29250
0
                ret = WOLFSSL_FAILURE;
29251
0
            }
29252
0
        }
29253
29254
        /* Base64 decode body. */
29255
0
        if (ret == WOLFSSL_SUCCESS) {
29256
0
            if (Base64_Decode(der, derLen, der, &derLen) != 0)
29257
0
                ret = WOLFSSL_FAILURE;
29258
0
        }
29259
29260
0
        if (ret == WOLFSSL_SUCCESS) {
29261
0
            *name = nameStr;
29262
0
            *header = headerStr;
29263
0
            *data = der;
29264
0
            *len = derLen;
29265
0
            nameStr = NULL;
29266
0
            headerStr = NULL;
29267
0
            der = NULL;
29268
0
        }
29269
29270
0
        if (nameStr != NULL)
29271
0
            XFREE(nameStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29272
0
        if (headerStr != NULL)
29273
0
            XFREE(headerStr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29274
0
        if (der != NULL)
29275
0
            XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29276
29277
0
        return ret;
29278
0
    }
29279
29280
    int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name,
29281
                              const char *header, const unsigned char *data,
29282
                              long len)
29283
0
    {
29284
0
        int err = 0;
29285
0
        int outSz = 0;
29286
0
        int nameLen;
29287
0
        int headerLen;
29288
0
        byte* pem = NULL;
29289
0
        word32 pemLen;
29290
0
        word32 derLen = (word32)len;
29291
29292
0
        if (bio == NULL || name == NULL || header == NULL || data == NULL)
29293
0
            return 0;
29294
29295
0
        nameLen = (int)XSTRLEN(name);
29296
0
        headerLen = (int)XSTRLEN(header);
29297
29298
0
        pemLen = (derLen + 2) / 3 * 4;
29299
0
        pemLen += (pemLen + 63) / 64;
29300
29301
0
        pem = (byte*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29302
0
        err = pem == NULL;
29303
0
        if (!err)
29304
0
            err = Base64_Encode(data, derLen, pem, &pemLen) != 0;
29305
29306
0
        if (!err) {
29307
0
            err = wolfSSL_BIO_write(bio, PEM_BEGIN, PEM_BEGIN_SZ) !=
29308
0
                                                              (int)PEM_BEGIN_SZ;
29309
0
        }
29310
0
        if (!err)
29311
0
            err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
29312
0
        if (!err) {
29313
0
            err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
29314
0
                    PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
29315
0
        }
29316
0
        if (!err && headerLen > 0) {
29317
0
            err = wolfSSL_BIO_write(bio, header, headerLen) != headerLen;
29318
            /* Blank line after a header and before body. */
29319
0
            if (!err)
29320
0
                err = wolfSSL_BIO_write(bio, "\n", 1) != 1;
29321
0
            headerLen++;
29322
0
        }
29323
0
        if (!err)
29324
0
            err = wolfSSL_BIO_write(bio, pem, pemLen) != (int)pemLen;
29325
0
        if (!err)
29326
0
            err = wolfSSL_BIO_write(bio, PEM_END, PEM_END_SZ) !=
29327
0
                                                                (int)PEM_END_SZ;
29328
0
        if (!err)
29329
0
            err = wolfSSL_BIO_write(bio, name, nameLen) != nameLen;
29330
0
        if (!err) {
29331
0
            err = wolfSSL_BIO_write(bio, PEM_HDR_FIN_EOL_NEWLINE,
29332
0
                    PEM_HDR_FIN_EOL_SZ) != (int)PEM_HDR_FIN_EOL_SZ;
29333
0
        }
29334
29335
0
        if (!err) {
29336
0
            outSz = PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ + headerLen +
29337
0
                             pemLen + PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ;
29338
0
        }
29339
29340
0
        if (pem != NULL)
29341
0
            XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29342
29343
0
        return outSz;
29344
0
    }
29345
29346
#if !defined(NO_FILESYSTEM)
29347
    int wolfSSL_PEM_read(XFILE fp, char **name, char **header,
29348
                         unsigned char **data, long *len)
29349
0
    {
29350
0
        int ret;
29351
0
        WOLFSSL_BIO* bio;
29352
29353
0
        if (name == NULL || header == NULL || data == NULL || len == NULL)
29354
0
            return WOLFSSL_FAILURE;
29355
29356
0
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
29357
0
        if (bio == NULL)
29358
0
            return 0;
29359
29360
0
        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
29361
0
            wolfSSL_BIO_free(bio);
29362
0
            bio = NULL;
29363
0
        }
29364
29365
0
        ret = wolfSSL_PEM_read_bio(bio, name, header, data, len);
29366
29367
0
        if (bio != NULL)
29368
0
            wolfSSL_BIO_free(bio);
29369
29370
0
        return ret;
29371
0
    }
29372
29373
    int wolfSSL_PEM_write(XFILE fp, const char *name, const char *header,
29374
                          const unsigned char *data, long len)
29375
0
    {
29376
0
        int ret;
29377
0
        WOLFSSL_BIO* bio;
29378
29379
0
        if (name == NULL || header == NULL || data == NULL)
29380
0
            return 0;
29381
29382
0
        bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
29383
0
        if (bio == NULL)
29384
0
            return 0;
29385
29386
0
        if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
29387
0
            wolfSSL_BIO_free(bio);
29388
0
            bio = NULL;
29389
0
        }
29390
29391
0
        ret = wolfSSL_PEM_write_bio(bio, name, header, data, len);
29392
29393
0
        if (bio != NULL)
29394
0
            wolfSSL_BIO_free(bio);
29395
29396
0
        return ret;
29397
0
    }
29398
#endif
29399
#endif /* !NO_BIO */
29400
29401
    int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header,
29402
                                        EncryptedInfo* cipher)
29403
0
    {
29404
0
        if (header == NULL || cipher == NULL)
29405
0
            return WOLFSSL_FAILURE;
29406
29407
0
        XMEMSET(cipher, 0, sizeof(*cipher));
29408
29409
0
        if (wc_EncryptedInfoParse(cipher, &header, XSTRLEN(header)) != 0)
29410
0
            return WOLFSSL_FAILURE;
29411
29412
0
        return WOLFSSL_SUCCESS;
29413
0
    }
29414
29415
    int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data,
29416
                              long* len, wc_pem_password_cb* callback,
29417
                              void* ctx)
29418
0
    {
29419
0
        int ret = WOLFSSL_SUCCESS;
29420
0
        char password[NAME_SZ];
29421
0
        int passwordSz;
29422
29423
0
        if (cipher == NULL || data == NULL || len == NULL || callback == NULL)
29424
0
            return WOLFSSL_FAILURE;
29425
29426
0
        passwordSz = callback(password, sizeof(password), PEM_PASS_READ, ctx);
29427
0
        if (passwordSz < 0)
29428
0
            ret = WOLFSSL_FAILURE;
29429
29430
0
        if (ret == WOLFSSL_SUCCESS) {
29431
0
            if (wc_BufferKeyDecrypt(cipher, data, (word32)*len, (byte*)password,
29432
0
                                                     passwordSz, WC_MD5) != 0) {
29433
0
                ret = WOLFSSL_FAILURE;
29434
0
            }
29435
0
        }
29436
29437
0
        if (passwordSz > 0)
29438
0
            XMEMSET(password, 0, passwordSz);
29439
29440
0
        return ret;
29441
0
    }
29442
29443
#ifndef NO_BIO
29444
    /*
29445
     * bp : bio to read X509 from
29446
     * x  : x509 to write to
29447
     * cb : password call back for reading PEM
29448
     * u  : password
29449
     * _AUX is for working with a trusted X509 certificate
29450
     */
29451
    WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX(WOLFSSL_BIO *bp,
29452
                               WOLFSSL_X509 **x, wc_pem_password_cb *cb,
29453
                               void *u)
29454
0
    {
29455
0
        WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509");
29456
29457
        /* AUX info is; trusted/rejected uses, friendly name, private key id,
29458
         * and potentially a stack of "other" info. wolfSSL does not store
29459
         * friendly name or private key id yet in WOLFSSL_X509 for human
29460
         * readability and does not support extra trusted/rejected uses for
29461
         * root CA. */
29462
0
        return wolfSSL_PEM_read_bio_X509(bp, x, cb, u);
29463
0
    }
29464
#endif /* !NO_BIO */
29465
29466
29467
#endif /* OPENSSL_EXTRA || OPENSSL_ALL */
29468
#endif /* !NO_CERTS */
29469
29470
    /* NID variables are dependent on compatibility header files currently
29471
     *
29472
     * returns a pointer to a new WOLFSSL_ASN1_OBJECT struct on success and NULL
29473
     *         on fail
29474
     */
29475
29476
    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj(int id)
29477
0
    {
29478
0
        return wolfSSL_OBJ_nid2obj_ex(id, NULL);
29479
0
    }
29480
29481
29482
    WOLFSSL_LOCAL WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_nid2obj_ex(int id,
29483
                                                WOLFSSL_ASN1_OBJECT* arg_obj)
29484
0
    {
29485
0
        word32 oidSz = 0;
29486
0
        int nid = 0;
29487
0
        const byte* oid;
29488
0
        word32 type = 0;
29489
0
        WOLFSSL_ASN1_OBJECT* obj = arg_obj;
29490
0
        byte objBuf[MAX_OID_SZ + MAX_LENGTH_SZ + 1]; /* +1 for object tag */
29491
0
        word32 objSz = 0;
29492
0
        const char* sName = NULL;
29493
0
        int i;
29494
29495
#ifdef WOLFSSL_DEBUG_OPENSSL
29496
        WOLFSSL_ENTER("wolfSSL_OBJ_nid2obj()");
29497
#endif
29498
29499
0
        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
29500
0
            if (wolfssl_object_info[i].nid == id) {
29501
0
                nid = id;
29502
0
                id = wolfssl_object_info[i].id;
29503
0
                sName = wolfssl_object_info[i].sName;
29504
0
                type = wolfssl_object_info[i].type;
29505
0
                break;
29506
0
            }
29507
0
        }
29508
0
        if (i == (int)WOLFSSL_OBJECT_INFO_SZ) {
29509
0
            WOLFSSL_MSG("NID not in table");
29510
        #ifdef WOLFSSL_QT
29511
            sName = NULL;
29512
            type = id;
29513
        #else
29514
0
            return NULL;
29515
0
        #endif
29516
0
        }
29517
29518
0
    #ifdef HAVE_ECC
29519
0
         if (type == 0 && wc_ecc_get_oid(id, &oid, &oidSz) > 0) {
29520
0
             type = oidCurveType;
29521
0
         }
29522
0
    #endif /* HAVE_ECC */
29523
29524
0
        if (sName != NULL) {
29525
0
            if (XSTRLEN(sName) > WOLFSSL_MAX_SNAME - 1) {
29526
0
                WOLFSSL_MSG("Attempted short name is too large");
29527
0
                return NULL;
29528
0
            }
29529
0
        }
29530
29531
0
        oid = OidFromId(id, type, &oidSz);
29532
29533
        /* set object ID to buffer */
29534
0
        if (obj == NULL){
29535
0
            obj = wolfSSL_ASN1_OBJECT_new();
29536
0
            if (obj == NULL) {
29537
0
                WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
29538
0
                return NULL;
29539
0
            }
29540
0
        }
29541
0
        obj->nid     = nid;
29542
0
        obj->type    = id;
29543
0
        obj->grp     = type;
29544
29545
0
        obj->sName[0] = '\0';
29546
0
        if (sName != NULL) {
29547
0
            XMEMCPY(obj->sName, (char*)sName, XSTRLEN((char*)sName));
29548
0
        }
29549
29550
0
        objBuf[0] = ASN_OBJECT_ID; objSz++;
29551
0
        objSz += SetLength(oidSz, objBuf + 1);
29552
0
        if (oidSz) {
29553
0
            XMEMCPY(objBuf + objSz, oid, oidSz);
29554
0
            objSz     += oidSz;
29555
0
        }
29556
29557
0
        if (obj->objSz == 0 || objSz != obj->objSz) {
29558
0
            obj->objSz = objSz;
29559
0
            if(((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) ||
29560
0
                                                           (obj->obj == NULL)) {
29561
0
                if (obj->obj != NULL)
29562
0
                    XFREE((byte*)obj->obj, NULL, DYNAMIC_TYPE_ASN1);
29563
0
                obj->obj = (byte*)XMALLOC(obj->objSz, NULL, DYNAMIC_TYPE_ASN1);
29564
0
                if (obj->obj == NULL) {
29565
0
                    wolfSSL_ASN1_OBJECT_free(obj);
29566
0
                    return NULL;
29567
0
                }
29568
0
                obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ;
29569
0
            }
29570
0
            else {
29571
0
                obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA ;
29572
0
            }
29573
0
        }
29574
0
        XMEMCPY((byte*)obj->obj, objBuf, obj->objSz);
29575
29576
0
        (void)type;
29577
29578
0
        return obj;
29579
0
    }
29580
29581
    static const char* oid_translate_num_to_str(const char* oid)
29582
0
    {
29583
0
        const struct oid_dict {
29584
0
            const char* num;
29585
0
            const char* desc;
29586
0
        } oid_dict[] = {
29587
0
            { "2.5.29.37.0",       "Any Extended Key Usage" },
29588
0
            { "1.3.6.1.5.5.7.3.1", "TLS Web Server Authentication" },
29589
0
            { "1.3.6.1.5.5.7.3.2", "TLS Web Client Authentication" },
29590
0
            { "1.3.6.1.5.5.7.3.3", "Code Signing" },
29591
0
            { "1.3.6.1.5.5.7.3.4", "E-mail Protection" },
29592
0
            { "1.3.6.1.5.5.7.3.8", "Time Stamping" },
29593
0
            { "1.3.6.1.5.5.7.3.9", "OCSP Signing" },
29594
0
            { NULL, NULL }
29595
0
        };
29596
0
        const struct oid_dict* idx;
29597
29598
0
        for (idx = oid_dict; idx->num != NULL; idx++) {
29599
0
            if (!XSTRCMP(oid, idx->num)) {
29600
0
                return idx->desc;
29601
0
            }
29602
0
        }
29603
0
        return NULL;
29604
0
    }
29605
29606
    static int wolfssl_obj2txt_numeric(char *buf, int bufLen,
29607
                                       const WOLFSSL_ASN1_OBJECT *a)
29608
0
    {
29609
0
        int bufSz;
29610
0
        int    length;
29611
0
        word32 idx = 0;
29612
0
        byte   tag;
29613
29614
0
        if (GetASNTag(a->obj, &idx, &tag, a->objSz) != 0) {
29615
0
            return WOLFSSL_FAILURE;
29616
0
        }
29617
29618
0
        if (tag != ASN_OBJECT_ID) {
29619
0
            WOLFSSL_MSG("Bad ASN1 Object");
29620
0
            return WOLFSSL_FAILURE;
29621
0
        }
29622
29623
0
        if (GetLength((const byte*)a->obj, &idx, &length,
29624
0
                       a->objSz) < 0 || length < 0) {
29625
0
            return ASN_PARSE_E;
29626
0
        }
29627
29628
0
        if (bufLen < MAX_OID_STRING_SZ) {
29629
0
            bufSz = bufLen - 1;
29630
0
        }
29631
0
        else {
29632
0
            bufSz = MAX_OID_STRING_SZ;
29633
0
        }
29634
29635
0
        if ((bufSz = DecodePolicyOID(buf, (word32)bufSz, a->obj + idx,
29636
0
                    (word32)length)) <= 0) {
29637
0
            WOLFSSL_MSG("Error decoding OID");
29638
0
            return WOLFSSL_FAILURE;
29639
0
        }
29640
29641
0
        buf[bufSz] = '\0';
29642
29643
0
        return bufSz;
29644
0
    }
29645
29646
    /* If no_name is one then use numerical form, otherwise short name.
29647
     *
29648
     * Returns the buffer size on success, WOLFSSL_FAILURE on error
29649
     */
29650
    int wolfSSL_OBJ_obj2txt(char *buf, int bufLen, const WOLFSSL_ASN1_OBJECT *a,
29651
                            int no_name)
29652
0
    {
29653
0
        int bufSz;
29654
0
        const char* desc;
29655
0
        const char* name;
29656
29657
0
        WOLFSSL_ENTER("wolfSSL_OBJ_obj2txt()");
29658
29659
0
        if (buf == NULL || bufLen <= 1 || a == NULL) {
29660
0
            WOLFSSL_MSG("Bad input argument");
29661
0
            return WOLFSSL_FAILURE;
29662
0
        }
29663
29664
0
        if (no_name == 1) {
29665
0
            return wolfssl_obj2txt_numeric(buf, bufLen, a);
29666
0
        }
29667
29668
        /* return long name unless using x509small, then return short name */
29669
#if defined(OPENSSL_EXTRA_X509_SMALL) && !defined(OPENSSL_EXTRA)
29670
        name = a->sName;
29671
#else
29672
0
        name = wolfSSL_OBJ_nid2ln(wolfSSL_OBJ_obj2nid(a));
29673
0
#endif
29674
29675
0
        if (name == NULL) {
29676
0
            WOLFSSL_MSG("Name not found");
29677
0
            bufSz = 0;
29678
0
        }
29679
0
        else if (XSTRLEN(name) + 1 < (word32)bufLen - 1) {
29680
0
            bufSz = (int)XSTRLEN(name);
29681
0
        }
29682
0
        else {
29683
0
            bufSz = bufLen - 1;
29684
0
        }
29685
0
        if (bufSz) {
29686
0
            XMEMCPY(buf, name, bufSz);
29687
0
        }
29688
0
        else if (a->type == GEN_DNS || a->type == GEN_EMAIL ||
29689
0
                 a->type == GEN_URI) {
29690
0
            bufSz = (int)XSTRLEN((const char*)a->obj);
29691
0
            XMEMCPY(buf, a->obj, min(bufSz, bufLen));
29692
0
        }
29693
0
        else if ((bufSz = wolfssl_obj2txt_numeric(buf, bufLen, a)) > 0) {
29694
0
            if ((desc = oid_translate_num_to_str(buf))) {
29695
0
                bufSz = (int)XSTRLEN(desc);
29696
0
                bufSz = min(bufSz, bufLen - 1);
29697
0
                XMEMCPY(buf, desc, bufSz);
29698
0
            }
29699
0
        }
29700
29701
0
        buf[bufSz] = '\0';
29702
29703
0
        return bufSz;
29704
0
    }
29705
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
29706
29707
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
29708
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
29709
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
29710
    defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS_SMALL)
29711
    /* Returns the long name that corresponds with an ASN1_OBJECT nid value.
29712
     *  n : NID value of ASN1_OBJECT to search */
29713
    const char* wolfSSL_OBJ_nid2ln(int n)
29714
0
    {
29715
0
        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
29716
0
        size_t i;
29717
0
        WOLFSSL_ENTER("wolfSSL_OBJ_nid2ln");
29718
0
        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
29719
0
            if (obj_info->nid == n) {
29720
0
                return obj_info->lName;
29721
0
            }
29722
0
        }
29723
0
        WOLFSSL_MSG("NID not found in table");
29724
0
        return NULL;
29725
0
    }
29726
#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
29727
          WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY, WOLFSSL_WPAS_SMALL */
29728
29729
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
29730
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
29731
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
29732
    defined(WOLFSSL_HAPROXY)
29733
    char wolfSSL_CTX_use_certificate(WOLFSSL_CTX *ctx, WOLFSSL_X509 *x)
29734
0
    {
29735
0
        int ret;
29736
29737
0
        WOLFSSL_ENTER("wolfSSL_CTX_use_certificate");
29738
0
        if (!ctx || !x || !x->derCert) {
29739
0
            WOLFSSL_MSG("Bad parameter");
29740
0
            return WOLFSSL_FAILURE;
29741
0
        }
29742
29743
0
        FreeDer(&ctx->certificate); /* Make sure previous is free'd */
29744
0
        ret = AllocDer(&ctx->certificate, x->derCert->length, CERT_TYPE,
29745
0
                       ctx->heap);
29746
0
        if (ret != 0)
29747
0
            return WOLFSSL_FAILURE;
29748
29749
0
        XMEMCPY(ctx->certificate->buffer, x->derCert->buffer,
29750
0
                x->derCert->length);
29751
0
#ifdef KEEP_OUR_CERT
29752
0
        if (ctx->ourCert != NULL && ctx->ownOurCert) {
29753
0
            wolfSSL_X509_free(ctx->ourCert);
29754
0
        }
29755
0
        #ifndef WOLFSSL_X509_STORE_CERTS
29756
0
        ctx->ourCert = x;
29757
0
        if (wolfSSL_X509_up_ref(x) != 1) {
29758
0
            return WOLFSSL_FAILURE;
29759
0
        }
29760
        #else
29761
        ctx->ourCert = wolfSSL_X509_d2i(NULL, x->derCert->buffer,x->derCert->length);
29762
        if(ctx->ourCert == NULL){
29763
            return WOLFSSL_FAILURE;
29764
        }
29765
        #endif
29766
29767
        /* We own the cert because either we up its reference counter
29768
         * or we create our own copy of the cert object. */
29769
0
        ctx->ownOurCert = 1;
29770
0
#endif
29771
29772
        /* Update the available options with public keys. */
29773
0
        switch (x->pubKeyOID) {
29774
0
    #ifndef NO_RSA
29775
0
        #ifdef WC_RSA_PSS
29776
0
            case RSAPSSk:
29777
0
        #endif
29778
0
            case RSAk:
29779
0
                ctx->haveRSA = 1;
29780
0
                break;
29781
0
    #endif
29782
0
        #ifdef HAVE_ED25519
29783
0
            case ED25519k:
29784
0
        #endif
29785
0
        #ifdef HAVE_ED448
29786
0
            case ED448k:
29787
0
        #endif
29788
0
            case ECDSAk:
29789
0
                ctx->haveECC = 1;
29790
0
        #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
29791
0
                ctx->pkCurveOID = x->pkCurveOID;
29792
0
        #endif
29793
0
                break;
29794
0
        }
29795
29796
0
        return WOLFSSL_SUCCESS;
29797
0
    }
29798
29799
    static int PushCertToDerBuffer(DerBuffer** inOutDer, int weOwn,
29800
            byte* cert, word32 certSz, void* heap)
29801
0
    {
29802
0
        int ret;
29803
0
        DerBuffer* inChain = NULL;
29804
0
        DerBuffer* der = NULL;
29805
0
        word32 len = 0;
29806
0
        if (inOutDer == NULL)
29807
0
            return BAD_FUNC_ARG;
29808
0
        inChain = *inOutDer;
29809
0
        if (inChain != NULL)
29810
0
            len = inChain->length;
29811
0
        ret = AllocDer(&der, len + CERT_HEADER_SZ + certSz, CERT_TYPE,
29812
0
                heap);
29813
0
        if (ret != 0) {
29814
0
            WOLFSSL_MSG("AllocDer error");
29815
0
            return ret;
29816
0
        }
29817
0
        if (inChain != NULL)
29818
0
            XMEMCPY(der->buffer, inChain->buffer, len);
29819
0
        c32to24(certSz, der->buffer + len);
29820
0
        XMEMCPY(der->buffer + len + CERT_HEADER_SZ, cert, certSz);
29821
0
        if (weOwn)
29822
0
            FreeDer(inOutDer);
29823
0
        *inOutDer = der;
29824
0
        return WOLFSSL_SUCCESS;
29825
0
    }
29826
29827
    /**
29828
     * wolfSSL_CTX_add1_chain_cert makes a copy of the cert so we free it
29829
     * on success
29830
     */
29831
    int wolfSSL_CTX_add0_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
29832
0
    {
29833
0
        WOLFSSL_ENTER("wolfSSL_CTX_add0_chain_cert");
29834
0
        if (wolfSSL_CTX_add1_chain_cert(ctx, x509) != WOLFSSL_SUCCESS) {
29835
0
            return WOLFSSL_FAILURE;
29836
0
        }
29837
0
        wolfSSL_X509_free(x509);
29838
0
        return WOLFSSL_SUCCESS;
29839
0
    }
29840
29841
    int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
29842
0
    {
29843
0
        int ret;
29844
0
        WOLFSSL_ENTER("wolfSSL_CTX_add1_chain_cert");
29845
0
        if (ctx == NULL || x509 == NULL || x509->derCert == NULL) {
29846
0
            return WOLFSSL_FAILURE;
29847
0
        }
29848
29849
0
        if (ctx->certificate == NULL)
29850
0
            ret = (int)wolfSSL_CTX_use_certificate(ctx, x509);
29851
0
        else {
29852
0
            if (wolfSSL_X509_up_ref(x509) != WOLFSSL_SUCCESS) {
29853
0
                WOLFSSL_MSG("wolfSSL_X509_up_ref error");
29854
0
                return WOLFSSL_FAILURE;
29855
0
            }
29856
0
            ret = wolfSSL_CTX_load_verify_buffer(ctx, x509->derCert->buffer,
29857
0
                x509->derCert->length, WOLFSSL_FILETYPE_ASN1);
29858
0
            if (ret == WOLFSSL_SUCCESS) {
29859
                /* push to ctx->certChain */
29860
0
                ret = PushCertToDerBuffer(&ctx->certChain, 1,
29861
0
                    x509->derCert->buffer, x509->derCert->length, ctx->heap);
29862
0
            }
29863
            /* Store cert to free it later */
29864
0
            if (ret == WOLFSSL_SUCCESS && ctx->x509Chain == NULL) {
29865
0
                ctx->x509Chain = wolfSSL_sk_X509_new();
29866
0
                if (ctx->x509Chain == NULL) {
29867
0
                    WOLFSSL_MSG("wolfSSL_sk_X509_new error");
29868
0
                    ret =  WOLFSSL_FAILURE;
29869
0
                }
29870
0
            }
29871
0
            if (ret == WOLFSSL_SUCCESS &&
29872
0
                    wolfSSL_sk_X509_push(ctx->x509Chain, x509)
29873
0
                        != WOLFSSL_SUCCESS) {
29874
0
                WOLFSSL_MSG("wolfSSL_sk_X509_push error");
29875
0
                ret = WOLFSSL_FAILURE;
29876
0
            }
29877
0
            if (ret != WOLFSSL_SUCCESS)
29878
0
                wolfSSL_X509_free(x509); /* Decrease ref counter */
29879
0
        }
29880
29881
0
        return (ret == WOLFSSL_SUCCESS) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
29882
0
    }
29883
29884
#ifdef KEEP_OUR_CERT
29885
    int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
29886
0
    {
29887
0
        int ret;
29888
29889
0
        WOLFSSL_ENTER("wolfSSL_add0_chain_cert");
29890
29891
0
        if (ssl == NULL || ssl->ctx == NULL || x509 == NULL ||
29892
0
                x509->derCert == NULL)
29893
0
            return WOLFSSL_FAILURE;
29894
29895
0
        if (ssl->buffers.certificate == NULL) {
29896
0
            ret = wolfSSL_use_certificate(ssl, x509);
29897
            /* Store cert to free it later */
29898
0
            if (ret == WOLFSSL_SUCCESS) {
29899
0
                if (ssl->buffers.weOwnCert)
29900
0
                    wolfSSL_X509_free(ssl->ourCert);
29901
0
                ssl->ourCert = x509;
29902
0
                ssl->buffers.weOwnCert = 1;
29903
0
            }
29904
0
        }
29905
0
        else {
29906
0
            ret = PushCertToDerBuffer(&ssl->buffers.certChain,
29907
0
                    ssl->buffers.weOwnCertChain, x509->derCert->buffer,
29908
0
                    x509->derCert->length, ssl->heap);
29909
0
            if (ret == WOLFSSL_SUCCESS) {
29910
0
                ssl->buffers.weOwnCertChain = 1;
29911
                /* Store cert to free it later */
29912
0
                if (ssl->ourCertChain == NULL) {
29913
0
                    ssl->ourCertChain = wolfSSL_sk_X509_new();
29914
0
                    if (ssl->ourCertChain == NULL) {
29915
0
                        WOLFSSL_MSG("wolfSSL_sk_X509_new error");
29916
0
                        return WOLFSSL_FAILURE;
29917
0
                    }
29918
0
                }
29919
0
                if (wolfSSL_sk_X509_push(ssl->ourCertChain, x509)
29920
0
                        != WOLFSSL_SUCCESS) {
29921
0
                    WOLFSSL_MSG("wolfSSL_sk_X509_push error");
29922
0
                    return WOLFSSL_FAILURE;
29923
0
                }
29924
0
            }
29925
0
        }
29926
0
        return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
29927
0
    }
29928
29929
    int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509)
29930
0
    {
29931
0
        int ret;
29932
29933
0
        WOLFSSL_ENTER("wolfSSL_add1_chain_cert");
29934
0
        if (ssl == NULL || ssl->ctx == NULL || x509 == NULL ||
29935
0
                x509->derCert == NULL)
29936
0
            return WOLFSSL_FAILURE;
29937
29938
0
        if (wolfSSL_X509_up_ref(x509) != WOLFSSL_SUCCESS) {
29939
0
            WOLFSSL_MSG("wolfSSL_X509_up_ref error");
29940
0
            return WOLFSSL_FAILURE;
29941
0
        }
29942
0
        ret = wolfSSL_add0_chain_cert(ssl, x509);
29943
        /* Decrease ref counter on error */
29944
0
        if (ret != WOLFSSL_SUCCESS)
29945
0
            wolfSSL_X509_free(x509);
29946
0
        return ret;
29947
0
    }
29948
#endif
29949
29950
    /* Return the corresponding short name for the nid <n>.
29951
     * or NULL if short name can't be found.
29952
     */
29953
0
    const char * wolfSSL_OBJ_nid2sn(int n) {
29954
0
        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
29955
0
        size_t i;
29956
0
        WOLFSSL_ENTER("wolfSSL_OBJ_nid2sn");
29957
29958
0
        if (n == NID_md5) {
29959
            /* NID_surname == NID_md5 and NID_surname comes before NID_md5 in
29960
             * wolfssl_object_info. As a result, the loop below will incorrectly
29961
             * return "SN" instead of "MD5." NID_surname isn't the true OpenSSL
29962
             * NID, but other functions rely on this table and modifying it to
29963
             * conform with OpenSSL's NIDs isn't trivial. */
29964
0
             return "MD5";
29965
0
        }
29966
0
        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
29967
0
            if (obj_info->nid == n) {
29968
0
                return obj_info->sName;
29969
0
            }
29970
0
        }
29971
0
        WOLFSSL_MSG("SN not found");
29972
0
        return NULL;
29973
0
    }
29974
29975
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
29976
0
    int wolfSSL_OBJ_sn2nid(const char *sn) {
29977
0
        WOLFSSL_ENTER("wolfSSL_OBJ_sn2nid");
29978
0
        if (sn == NULL)
29979
0
            return NID_undef;
29980
0
        return wc_OBJ_sn2nid(sn);
29981
0
    }
29982
#endif
29983
29984
    size_t wolfSSL_OBJ_length(const WOLFSSL_ASN1_OBJECT* o)
29985
0
    {
29986
0
        size_t ret = 0;
29987
0
        int err = 0;
29988
0
        word32 idx = 0;
29989
0
        int len = 0;
29990
29991
0
        WOLFSSL_ENTER("wolfSSL_OBJ_length");
29992
29993
0
        if (o == NULL || o->obj == NULL) {
29994
0
            WOLFSSL_MSG("Bad argument.");
29995
0
            err = 1;
29996
0
        }
29997
29998
0
        if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
29999
0
            WOLFSSL_MSG("Error parsing ASN.1 header.");
30000
0
            err = 1;
30001
0
        }
30002
0
        if (err == 0) {
30003
0
            ret = len;
30004
0
        }
30005
30006
0
        WOLFSSL_LEAVE("wolfSSL_OBJ_length", (int)ret);
30007
30008
0
        return ret;
30009
0
    }
30010
30011
    const unsigned char* wolfSSL_OBJ_get0_data(const WOLFSSL_ASN1_OBJECT* o)
30012
0
    {
30013
0
        const unsigned char* ret = NULL;
30014
0
        int err = 0;
30015
0
        word32 idx = 0;
30016
0
        int len = 0;
30017
30018
0
        WOLFSSL_ENTER("wolfSSL_OBJ_get0_data");
30019
30020
0
        if (o == NULL || o->obj == NULL) {
30021
0
            WOLFSSL_MSG("Bad argument.");
30022
0
            err = 1;
30023
0
        }
30024
30025
0
        if (err == 0 && GetASNObjectId(o->obj, &idx, &len, o->objSz)) {
30026
0
            WOLFSSL_MSG("Error parsing ASN.1 header.");
30027
0
            err = 1;
30028
0
        }
30029
0
        if (err == 0) {
30030
0
            ret = o->obj + idx;
30031
0
        }
30032
30033
0
        return ret;
30034
0
    }
30035
30036
30037
    /* Gets the NID value that corresponds with the ASN1 object.
30038
     *
30039
     * o ASN1 object to get NID of
30040
     *
30041
     * Return NID on success and a negative value on failure
30042
     */
30043
    int wolfSSL_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o)
30044
0
    {
30045
0
        word32 oid = 0;
30046
0
        word32 idx = 0;
30047
0
        int ret;
30048
30049
#ifdef WOLFSSL_DEBUG_OPENSSL
30050
        WOLFSSL_ENTER("wolfSSL_OBJ_obj2nid");
30051
#endif
30052
30053
0
        if (o == NULL) {
30054
0
            return -1;
30055
0
        }
30056
30057
        #ifdef WOLFSSL_QT
30058
        if (o->grp == oidCertExtType) {
30059
            /* If nid is an unknown extension, return NID_undef */
30060
            if (wolfSSL_OBJ_nid2sn(o->nid) == NULL)
30061
                return NID_undef;
30062
        }
30063
        #endif
30064
30065
0
        if (o->nid > 0)
30066
0
            return o->nid;
30067
0
        if ((ret = GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz)) < 0) {
30068
0
            if (ret == ASN_OBJECT_ID_E) {
30069
                /* Put ASN object tag in front and try again */
30070
0
                int len = SetObjectId(o->objSz, NULL) + o->objSz;
30071
0
                byte* buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30072
0
                if (!buf) {
30073
0
                    WOLFSSL_MSG("malloc error");
30074
0
                    return -1;
30075
0
                }
30076
0
                idx = SetObjectId(o->objSz, buf);
30077
0
                XMEMCPY(buf + idx, o->obj, o->objSz);
30078
0
                idx = 0;
30079
0
                ret = GetObjectId(buf, &idx, &oid, o->grp, len);
30080
0
                XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30081
0
                if (ret < 0) {
30082
0
                    WOLFSSL_MSG("Issue getting OID of object");
30083
0
                    return -1;
30084
0
                }
30085
0
            }
30086
0
            else {
30087
0
                WOLFSSL_MSG("Issue getting OID of object");
30088
0
                return -1;
30089
0
            }
30090
0
        }
30091
30092
0
        return oid2nid(oid, o->grp);
30093
0
    }
30094
30095
    /* Return the corresponding NID for the long name <ln>
30096
     * or NID_undef if NID can't be found.
30097
     */
30098
    int wolfSSL_OBJ_ln2nid(const char *ln)
30099
0
    {
30100
0
        const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info;
30101
0
        size_t i, lnlen;
30102
0
        WOLFSSL_ENTER("wolfSSL_OBJ_ln2nid");
30103
0
        if (ln && (lnlen = XSTRLEN(ln)) > 0) {
30104
            /* Accept input like "/commonName=" */
30105
0
            if (ln[0] == '/') {
30106
0
                ln++;
30107
0
                lnlen--;
30108
0
            }
30109
0
            if (lnlen) {
30110
0
                if (ln[lnlen-1] == '=') {
30111
0
                    lnlen--;
30112
0
                }
30113
0
                for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++, obj_info++) {
30114
0
                    if (lnlen == XSTRLEN(obj_info->lName) &&
30115
0
                            XSTRNCMP(ln, obj_info->lName, lnlen) == 0) {
30116
0
                        return obj_info->nid;
30117
0
                    }
30118
0
                }
30119
0
            }
30120
0
        }
30121
0
        return NID_undef;
30122
0
    }
30123
30124
    /* compares two objects, return 0 if equal */
30125
    int wolfSSL_OBJ_cmp(const WOLFSSL_ASN1_OBJECT* a,
30126
                        const WOLFSSL_ASN1_OBJECT* b)
30127
0
    {
30128
0
        WOLFSSL_ENTER("wolfSSL_OBJ_cmp");
30129
30130
0
        if (a && b && a->obj && b->obj) {
30131
0
            if (a->objSz == b->objSz) {
30132
0
                return XMEMCMP(a->obj, b->obj, a->objSz);
30133
0
            }
30134
0
            else if (a->type == EXT_KEY_USAGE_OID ||
30135
0
                     b->type == EXT_KEY_USAGE_OID) {
30136
                /* Special case for EXT_KEY_USAGE_OID so that
30137
                 * cmp will be treated as a substring search */
30138
                /* Used in libest to check for id-kp-cmcRA in
30139
                 * EXT_KEY_USAGE extension */
30140
0
                unsigned int idx;
30141
0
                const byte* s; /* shorter */
30142
0
                unsigned int sLen;
30143
0
                const byte* l; /* longer */
30144
0
                unsigned int lLen;
30145
0
                if (a->objSz > b->objSz) {
30146
0
                    s = b->obj; sLen = b->objSz;
30147
0
                    l = a->obj; lLen = a->objSz;
30148
0
                }
30149
0
                else {
30150
0
                    s = a->obj; sLen = a->objSz;
30151
0
                    l = b->obj; lLen = b->objSz;
30152
0
                }
30153
0
                for (idx = 0; idx <= lLen - sLen; idx++) {
30154
0
                    if (XMEMCMP(l + idx, s, sLen) == 0) {
30155
                        /* Found substring */
30156
0
                        return 0;
30157
0
                    }
30158
0
                }
30159
0
            }
30160
0
        }
30161
30162
0
        return WOLFSSL_FATAL_ERROR;
30163
0
    }
30164
#endif /* OPENSSL_EXTRA, HAVE_LIGHTY, WOLFSSL_MYSQL_COMPATIBLE, HAVE_STUNNEL,
30165
          WOLFSSL_NGINX, HAVE_POCO_LIB, WOLFSSL_HAPROXY */
30166
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
30167
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
30168
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
30169
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
30170
    /* Gets the NID value that is related to the OID string passed in. Example
30171
     * string would be "2.5.29.14" for subject key ID.
30172
     *
30173
     * returns NID value on success and NID_undef on error
30174
     */
30175
    int wolfSSL_OBJ_txt2nid(const char* s)
30176
0
    {
30177
0
        unsigned int i;
30178
    #ifdef WOLFSSL_CERT_EXT
30179
        int ret;
30180
        unsigned int sum = 0;
30181
        unsigned int outSz = MAX_OID_SZ;
30182
        unsigned char out[MAX_OID_SZ];
30183
    #endif
30184
30185
0
        WOLFSSL_ENTER("OBJ_txt2nid");
30186
30187
0
        if (s == NULL) {
30188
0
            return NID_undef;
30189
0
        }
30190
30191
    #ifdef WOLFSSL_CERT_EXT
30192
        ret = EncodePolicyOID(out, &outSz, s, NULL);
30193
        if (ret == 0) {
30194
            /* sum OID */
30195
            for (i = 0; i < outSz; i++) {
30196
                sum += out[i];
30197
            }
30198
        }
30199
    #endif /* WOLFSSL_CERT_EXT */
30200
30201
        /* get the group that the OID's sum is in
30202
         * @TODO possible conflict with multiples */
30203
0
        for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
30204
0
            int len;
30205
        #ifdef WOLFSSL_CERT_EXT
30206
            if (ret == 0) {
30207
                if (wolfssl_object_info[i].id == (int)sum) {
30208
                    return wolfssl_object_info[i].nid;
30209
                }
30210
            }
30211
        #endif
30212
30213
            /* try as a short name */
30214
0
            len = (int)XSTRLEN(s);
30215
0
            if ((int)XSTRLEN(wolfssl_object_info[i].sName) == len &&
30216
0
                XSTRNCMP(wolfssl_object_info[i].sName, s, len) == 0) {
30217
0
                return wolfssl_object_info[i].nid;
30218
0
            }
30219
30220
            /* try as a long name */
30221
0
            if ((int)XSTRLEN(wolfssl_object_info[i].lName) == len &&
30222
0
                XSTRNCMP(wolfssl_object_info[i].lName, s, len) == 0) {
30223
0
                return wolfssl_object_info[i].nid;
30224
0
            }
30225
0
        }
30226
30227
0
        return NID_undef;
30228
0
    }
30229
#endif
30230
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
30231
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
30232
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
30233
    defined(WOLFSSL_HAPROXY)
30234
30235
    /* Creates new ASN1_OBJECT from short name, long name, or text
30236
     * representation of oid. If no_name is 0, then short name, long name, and
30237
     * numerical value of oid are interpreted. If no_name is 1, then only the
30238
     * numerical value of the oid is interpreted.
30239
     *
30240
     * Returns pointer to ASN1_OBJECT on success, or NULL on error.
30241
     */
30242
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
30243
    WOLFSSL_ASN1_OBJECT* wolfSSL_OBJ_txt2obj(const char* s, int no_name)
30244
    {
30245
        int i, ret;
30246
        int nid = NID_undef;
30247
        unsigned int outSz = MAX_OID_SZ;
30248
        unsigned char out[MAX_OID_SZ];
30249
        WOLFSSL_ASN1_OBJECT* obj;
30250
30251
        WOLFSSL_ENTER("wolfSSL_OBJ_txt2obj");
30252
30253
        if (s == NULL)
30254
            return NULL;
30255
30256
        /* If s is numerical value, try to sum oid */
30257
        ret = EncodePolicyOID(out, &outSz, s, NULL);
30258
        if (ret == 0 && outSz > 0) {
30259
            /* If numerical encode succeeded then just
30260
             * create object from that because sums are
30261
             * not unique and can cause confusion. */
30262
            obj = wolfSSL_ASN1_OBJECT_new();
30263
            if (obj == NULL) {
30264
                WOLFSSL_MSG("Issue creating WOLFSSL_ASN1_OBJECT struct");
30265
                return NULL;
30266
            }
30267
            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC;
30268
            obj->obj = (byte*)XMALLOC(1 + MAX_LENGTH_SZ + outSz, NULL,
30269
                    DYNAMIC_TYPE_ASN1);
30270
            if (obj->obj == NULL) {
30271
                wolfSSL_ASN1_OBJECT_free(obj);
30272
                return NULL;
30273
            }
30274
            obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA ;
30275
            i = SetObjectId(outSz, (byte*)obj->obj);
30276
            XMEMCPY((byte*)obj->obj + i, out, outSz);
30277
            obj->objSz = i + outSz;
30278
            return obj;
30279
        }
30280
30281
        /* TODO: update short names in wolfssl_object_info and check OID sums
30282
           are correct */
30283
        for (i = 0; i < (int)WOLFSSL_OBJECT_INFO_SZ; i++) {
30284
            /* Short name, long name, and numerical value are interpreted */
30285
            if (no_name == 0 &&
30286
                ((XSTRCMP(s, wolfssl_object_info[i].sName) == 0) ||
30287
                 (XSTRCMP(s, wolfssl_object_info[i].lName) == 0)))
30288
            {
30289
                    nid = wolfssl_object_info[i].nid;
30290
            }
30291
        }
30292
30293
        if (nid != NID_undef)
30294
            return wolfSSL_OBJ_nid2obj(nid);
30295
30296
        return NULL;
30297
    }
30298
#endif
30299
30300
    /* compatibility function. Its intended use is to remove OID's from an
30301
     * internal table that have been added with OBJ_create. wolfSSL manages its
30302
     * own internal OID values and does not currently support OBJ_create. */
30303
    void wolfSSL_OBJ_cleanup(void)
30304
0
    {
30305
0
        WOLFSSL_ENTER("wolfSSL_OBJ_cleanup()");
30306
0
    }
30307
30308
    #ifndef NO_WOLFSSL_STUB
30309
    int wolfSSL_OBJ_create(const char *oid, const char *sn, const char *ln)
30310
0
    {
30311
0
        (void)oid;
30312
0
        (void)sn;
30313
0
        (void)ln;
30314
0
        WOLFSSL_STUB("wolfSSL_OBJ_create");
30315
0
        return WOLFSSL_FAILURE;
30316
0
    }
30317
    #endif
30318
30319
    void wolfSSL_set_verify_depth(WOLFSSL *ssl, int depth)
30320
0
    {
30321
0
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
30322
0
        WOLFSSL_ENTER("wolfSSL_set_verify_depth");
30323
0
        ssl->options.verifyDepth = (byte)depth;
30324
0
    #endif
30325
0
    }
30326
30327
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
30328
    HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
30329
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
30330
    defined(HAVE_LIGHTY) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
30331
    defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
30332
    defined(HAVE_POCO_LIB) || defined(WOLFSSL_HAPROXY)
30333
    WOLFSSL_ASN1_OBJECT * wolfSSL_X509_NAME_ENTRY_get_object(WOLFSSL_X509_NAME_ENTRY *ne)
30334
0
    {
30335
0
        WOLFSSL_ASN1_OBJECT* obj = NULL;
30336
30337
#ifdef WOLFSSL_DEBUG_OPENSSL
30338
        WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_get_object");
30339
#endif
30340
0
        if (ne == NULL) return NULL;
30341
0
        obj = wolfSSL_OBJ_nid2obj_ex(ne->nid, ne->object);
30342
0
        if (obj != NULL) {
30343
0
            obj->nid = ne->nid;
30344
0
            return obj;
30345
0
        }
30346
0
        return NULL;
30347
0
    }
30348
30349
30350
#endif /* OPENSSL_ALL || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
30351
    HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
30352
30353
#ifdef OPENSSL_EXTRA
30354
30355
/* wolfSSL uses negative values for error states. This function returns an
30356
 * unsigned type so the value returned is the absolute value of the error.
30357
 */
30358
unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
30359
0
{
30360
0
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
30361
30362
0
    (void)line;
30363
0
    (void)file;
30364
0
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
30365
0
    {
30366
0
        int ret;
30367
30368
0
        if ((ret = wc_PeekErrorNode(-1, file, NULL, line)) < 0) {
30369
0
            WOLFSSL_MSG("Issue peeking at error node in queue");
30370
0
            return 0;
30371
0
        }
30372
0
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
30373
0
        if (ret == -ASN_NO_PEM_HEADER)
30374
0
            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
30375
0
    #endif
30376
    #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
30377
        if (ret == ASN1_R_HEADER_TOO_LONG) {
30378
            return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
30379
        }
30380
    #endif
30381
0
        return (unsigned long)ret;
30382
0
    }
30383
#else
30384
    return (unsigned long)(0 - NOT_COMPILED_IN);
30385
#endif
30386
0
}
30387
30388
30389
#ifndef NO_CERTS
30390
int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey)
30391
0
{
30392
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey");
30393
30394
0
    if (ctx == NULL || pkey == NULL) {
30395
0
        return WOLFSSL_FAILURE;
30396
0
    }
30397
30398
0
    switch (pkey->type) {
30399
0
#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) && !defined(NO_RSA)
30400
0
    case EVP_PKEY_RSA:
30401
0
        WOLFSSL_MSG("populating RSA key");
30402
0
        if (PopulateRSAEvpPkeyDer(pkey) != WOLFSSL_SUCCESS)
30403
0
            return WOLFSSL_FAILURE;
30404
0
        break;
30405
0
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA */
30406
#if !defined(HAVE_SELFTEST) && (defined(WOLFSSL_KEY_GEN) || \
30407
        defined(WOLFSSL_CERT_GEN)) && !defined(NO_DSA)
30408
    case EVP_PKEY_DSA:
30409
        break;
30410
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) && !NO_DSA */
30411
0
#ifdef HAVE_ECC
30412
0
    case EVP_PKEY_EC:
30413
0
        WOLFSSL_MSG("populating ECC key");
30414
0
        if (ECC_populate_EVP_PKEY(pkey, pkey->ecc)
30415
0
                != WOLFSSL_SUCCESS)
30416
0
            return WOLFSSL_FAILURE;
30417
0
        break;
30418
0
#endif
30419
0
    default:
30420
0
        return WOLFSSL_FAILURE;
30421
0
    }
30422
30423
0
    if (pkey->pkey.ptr != NULL) {
30424
        /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */
30425
0
        return wolfSSL_CTX_use_PrivateKey_buffer(ctx,
30426
0
                                       (const unsigned char*)pkey->pkey.ptr,
30427
0
                                       pkey->pkey_sz, SSL_FILETYPE_ASN1);
30428
0
    }
30429
30430
0
    WOLFSSL_MSG("wolfSSL private key not set");
30431
0
    return BAD_FUNC_ARG;
30432
0
}
30433
#endif /* !NO_CERTS */
30434
30435
#endif /* OPENSSL_EXTRA */
30436
30437
#if defined(HAVE_EX_DATA) && \
30438
   (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
30439
    defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || \
30440
    defined(HAVE_LIGHTY)) || defined(HAVE_EX_DATA) || \
30441
    defined(WOLFSSL_WPAS_SMALL)
30442
/**
30443
 * get_ex_new_index is a helper function for the following
30444
 * xx_get_ex_new_index functions:
30445
 *  - wolfSSL_CRYPTO_get_ex_new_index
30446
 *  - wolfSSL_CTX_get_ex_new_index
30447
 *  - wolfSSL_get_ex_new_index
30448
 * Issues a unique index number for the specified class-index.
30449
 * Returns an index number greater or equal to zero on success,
30450
 * -1 on failure.
30451
 */
30452
int wolfssl_get_ex_new_index(int class_index)
30453
{
30454
    /* index counter for each class index*/
30455
    static int ctx_idx = 0;
30456
    static int ssl_idx = 0;
30457
    static int ssl_session_idx = 0;
30458
    static int x509_idx = 0;
30459
30460
    int idx = -1;
30461
30462
    switch(class_index) {
30463
        case WOLF_CRYPTO_EX_INDEX_SSL:
30464
            idx = ssl_idx++;
30465
            break;
30466
        case WOLF_CRYPTO_EX_INDEX_SSL_CTX:
30467
            idx = ctx_idx++;
30468
            break;
30469
        case WOLF_CRYPTO_EX_INDEX_X509:
30470
            idx = x509_idx++;
30471
            break;
30472
        case WOLF_CRYPTO_EX_INDEX_SSL_SESSION:
30473
            idx = ssl_session_idx++;
30474
            break;
30475
30476
        /* following class indexes are not supoprted */
30477
        case WOLF_CRYPTO_EX_INDEX_X509_STORE:
30478
        case WOLF_CRYPTO_EX_INDEX_X509_STORE_CTX:
30479
        case WOLF_CRYPTO_EX_INDEX_DH:
30480
        case WOLF_CRYPTO_EX_INDEX_DSA:
30481
        case WOLF_CRYPTO_EX_INDEX_EC_KEY:
30482
        case WOLF_CRYPTO_EX_INDEX_RSA:
30483
        case WOLF_CRYPTO_EX_INDEX_ENGINE:
30484
        case WOLF_CRYPTO_EX_INDEX_UI:
30485
        case WOLF_CRYPTO_EX_INDEX_BIO:
30486
        case WOLF_CRYPTO_EX_INDEX_APP:
30487
        case WOLF_CRYPTO_EX_INDEX_UI_METHOD:
30488
        case WOLF_CRYPTO_EX_INDEX_DRBG:
30489
        default:
30490
            break;
30491
    }
30492
    return idx;
30493
}
30494
#endif /* HAVE_EX_DATA || WOLFSSL_WPAS_SMALL */
30495
30496
#if defined(HAVE_EX_DATA) || defined(WOLFSSL_WPAS_SMALL)
30497
void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx)
30498
{
30499
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
30500
#ifdef HAVE_EX_DATA
30501
    if(ctx != NULL) {
30502
        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
30503
    }
30504
#else
30505
    (void)ctx;
30506
    (void)idx;
30507
#endif
30508
    return NULL;
30509
}
30510
30511
int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b,
30512
                                void* c)
30513
{
30514
30515
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_new_index");
30516
30517
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(idx, arg, a, b, c);
30518
30519
    return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_CTX);
30520
}
30521
30522
/* Return the index that can be used for the WOLFSSL structure to store
30523
 * application data.
30524
 *
30525
 */
30526
int wolfSSL_get_ex_new_index(long argValue, void* arg,
30527
        WOLFSSL_CRYPTO_EX_new* cb1, WOLFSSL_CRYPTO_EX_dup* cb2,
30528
        WOLFSSL_CRYPTO_EX_free* cb3)
30529
{
30530
    WOLFSSL_ENTER("wolfSSL_get_ex_new_index");
30531
30532
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(argValue, arg, cb1, cb2, cb3);
30533
30534
    return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL);
30535
}
30536
30537
30538
int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data)
30539
{
30540
    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data");
30541
    #ifdef HAVE_EX_DATA
30542
    if (ctx != NULL)
30543
    {
30544
        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
30545
    }
30546
    #else
30547
    (void)ctx;
30548
    (void)idx;
30549
    (void)data;
30550
    #endif
30551
    return WOLFSSL_FAILURE;
30552
}
30553
30554
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
30555
int wolfSSL_CTX_set_ex_data_with_cleanup(
30556
    WOLFSSL_CTX* ctx,
30557
    int idx,
30558
    void* data,
30559
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
30560
{
30561
    WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data_with_cleanup");
30562
    if (ctx != NULL)
30563
    {
30564
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx, data,
30565
                                                       cleanup_routine);
30566
    }
30567
    return WOLFSSL_FAILURE;
30568
}
30569
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
30570
30571
#endif /* defined(HAVE_EX_DATA) || defined(WOLFSSL_WPAS_SMALL) */
30572
30573
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
30574
30575
/* Returns char* to app data stored in ex[0].
30576
 *
30577
 * ssl WOLFSSL structure to get app data from
30578
 */
30579
void* wolfSSL_get_app_data(const WOLFSSL *ssl)
30580
0
{
30581
    /* checkout exdata stuff... */
30582
0
    WOLFSSL_ENTER("wolfSSL_get_app_data");
30583
30584
0
    return wolfSSL_get_ex_data(ssl, 0);
30585
0
}
30586
30587
30588
/* Set ex array 0 to have app data
30589
 *
30590
 * ssl WOLFSSL struct to set app data in
30591
 * arg data to be stored
30592
 *
30593
 * Returns WOLFSSL_SUCCESS on success and SSL_FAILURE on failure
30594
 */
30595
0
int wolfSSL_set_app_data(WOLFSSL *ssl, void* arg) {
30596
0
    WOLFSSL_ENTER("wolfSSL_set_app_data");
30597
30598
0
    return wolfSSL_set_ex_data(ssl, 0, arg);
30599
0
}
30600
30601
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
30602
30603
#if defined(HAVE_EX_DATA) || defined(OPENSSL_EXTRA) || \
30604
    defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
30605
30606
int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data)
30607
0
{
30608
0
    WOLFSSL_ENTER("wolfSSL_set_ex_data");
30609
#ifdef HAVE_EX_DATA
30610
    if (ssl != NULL)
30611
    {
30612
        return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data);
30613
    }
30614
#else
30615
0
    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
30616
0
    (void)ssl;
30617
0
    (void)idx;
30618
0
    (void)data;
30619
0
#endif
30620
0
    return WOLFSSL_FAILURE;
30621
0
}
30622
30623
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
30624
int wolfSSL_set_ex_data_with_cleanup(
30625
    WOLFSSL* ssl,
30626
    int idx,
30627
    void* data,
30628
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
30629
{
30630
    WOLFSSL_ENTER("wolfSSL_set_ex_data_with_cleanup");
30631
    if (ssl != NULL)
30632
    {
30633
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ssl->ex_data, idx, data,
30634
                                                       cleanup_routine);
30635
    }
30636
    return WOLFSSL_FAILURE;
30637
}
30638
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
30639
30640
void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx)
30641
0
{
30642
0
    WOLFSSL_ENTER("wolfSSL_get_ex_data");
30643
#ifdef HAVE_EX_DATA
30644
    if (ssl != NULL) {
30645
        return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx);
30646
    }
30647
#else
30648
0
    WOLFSSL_MSG("HAVE_EX_DATA macro is not defined");
30649
0
    (void)ssl;
30650
0
    (void)idx;
30651
0
#endif
30652
0
    return 0;
30653
0
}
30654
30655
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL || WOLFSSL_WPAS_SMALL */
30656
30657
#if defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) \
30658
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)
30659
30660
#if defined(OPENSSL_EXTRA) && !defined(NO_DH)
30661
/* Initialize ctx->dh with dh's params. Return WOLFSSL_SUCCESS on ok */
30662
long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh)
30663
0
{
30664
0
    int pSz, gSz;
30665
0
    byte *p, *g;
30666
0
    int ret=0;
30667
30668
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_tmp_dh");
30669
30670
0
    if(!ctx || !dh)
30671
0
        return BAD_FUNC_ARG;
30672
30673
    /* Get needed size for p and g */
30674
0
    pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
30675
0
    gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
30676
30677
0
    if(pSz <= 0 || gSz <= 0)
30678
0
        return WOLFSSL_FATAL_ERROR;
30679
30680
0
    p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
30681
0
    if(!p)
30682
0
        return MEMORY_E;
30683
30684
0
    g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
30685
0
    if(!g) {
30686
0
        XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
30687
0
        return MEMORY_E;
30688
0
    }
30689
30690
0
    pSz = wolfSSL_BN_bn2bin(dh->p, p);
30691
0
    gSz = wolfSSL_BN_bn2bin(dh->g, g);
30692
30693
0
    if(pSz >= 0 && gSz >= 0) /* Conversion successful */
30694
0
        ret = wolfSSL_CTX_SetTmpDH(ctx, p, pSz, g, gSz);
30695
30696
0
    XFREE(p, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
30697
0
    XFREE(g, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
30698
30699
0
    return pSz > 0 && gSz > 0 ? ret : WOLFSSL_FATAL_ERROR;
30700
0
}
30701
#endif /* OPENSSL_EXTRA && !NO_DH */
30702
30703
30704
/* returns the enum value associated with handshake state
30705
 *
30706
 * ssl the WOLFSSL structure to get state of
30707
 */
30708
int wolfSSL_get_state(const WOLFSSL* ssl)
30709
0
{
30710
0
    WOLFSSL_ENTER("wolfSSL_get_state");
30711
30712
0
    if (ssl == NULL) {
30713
0
        WOLFSSL_MSG("Null argument passed in");
30714
0
        return SSL_FAILURE;
30715
0
    }
30716
30717
0
    return ssl->options.handShakeState;
30718
0
}
30719
#endif /* HAVE_LIGHTY || HAVE_STUNNEL || WOLFSSL_MYSQL_COMPATIBLE */
30720
30721
#ifdef OPENSSL_EXTRA
30722
void wolfSSL_certs_clear(WOLFSSL* ssl)
30723
0
{
30724
0
    WOLFSSL_ENTER("wolfSSL_certs_clear()");
30725
30726
0
    if (ssl == NULL)
30727
0
        return;
30728
30729
    /* ctx still owns certificate, certChain, key, dh, and cm */
30730
0
    if (ssl->buffers.weOwnCert)
30731
0
        FreeDer(&ssl->buffers.certificate);
30732
0
    ssl->buffers.certificate = NULL;
30733
0
    if (ssl->buffers.weOwnCertChain)
30734
0
        FreeDer(&ssl->buffers.certChain);
30735
0
    ssl->buffers.certChain = NULL;
30736
0
#ifdef WOLFSSL_TLS13
30737
0
    ssl->buffers.certChainCnt = 0;
30738
0
#endif
30739
0
    if (ssl->buffers.weOwnKey)
30740
0
        FreeDer(&ssl->buffers.key);
30741
0
    ssl->buffers.key      = NULL;
30742
0
    ssl->buffers.keyType  = 0;
30743
0
    ssl->buffers.keyId    = 0;
30744
0
    ssl->buffers.keyLabel = 0;
30745
0
    ssl->buffers.keySz    = 0;
30746
0
    ssl->buffers.keyDevId = 0;
30747
0
}
30748
#endif
30749
30750
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
30751
    || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
30752
30753
long wolfSSL_ctrl(WOLFSSL* ssl, int cmd, long opt, void* pt)
30754
0
{
30755
0
    WOLFSSL_ENTER("wolfSSL_ctrl");
30756
0
    if (ssl == NULL)
30757
0
        return BAD_FUNC_ARG;
30758
30759
0
    switch (cmd) {
30760
0
        #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
30761
0
        #ifdef HAVE_SNI
30762
0
        case SSL_CTRL_SET_TLSEXT_HOSTNAME:
30763
0
            WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TLSEXT_HOSTNAME.");
30764
0
            if (pt == NULL) {
30765
0
                WOLFSSL_MSG("Passed in NULL Host Name.");
30766
0
                break;
30767
0
            }
30768
0
            return wolfSSL_set_tlsext_host_name(ssl, (const char*) pt);
30769
0
        #endif /* HAVE_SNI */
30770
0
        #endif /* WOLFSSL_NGINX || WOLFSSL_QT || OPENSSL_ALL */
30771
0
        default:
30772
0
            WOLFSSL_MSG("Case not implemented.");
30773
0
    }
30774
0
    (void)opt;
30775
0
    (void)pt;
30776
0
    return WOLFSSL_FAILURE;
30777
0
}
30778
30779
long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
30780
0
{
30781
0
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
30782
0
    long ctrl_opt;
30783
0
#endif
30784
0
    long ret = WOLFSSL_SUCCESS;
30785
30786
0
    WOLFSSL_ENTER("wolfSSL_CTX_ctrl");
30787
0
    if (ctx == NULL)
30788
0
        return WOLFSSL_FAILURE;
30789
30790
0
    switch (cmd) {
30791
0
    case SSL_CTRL_CHAIN:
30792
#ifdef SESSION_CERTS
30793
    {
30794
        /*
30795
         * We don't care about opt here because a copy of the certificate is
30796
         * stored anyway so increasing the reference counter is not necessary.
30797
         * Just check to make sure that it is set to one of the correct values.
30798
         */
30799
        WOLF_STACK_OF(WOLFSSL_X509)* sk = (WOLF_STACK_OF(WOLFSSL_X509)*) pt;
30800
        WOLFSSL_X509* x509;
30801
        int i;
30802
        if (opt != 0 && opt != 1) {
30803
            ret = WOLFSSL_FAILURE;
30804
            break;
30805
        }
30806
        /* Clear certificate chain */
30807
        FreeDer(&ctx->certChain);
30808
        if (sk) {
30809
            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
30810
                x509 = wolfSSL_sk_X509_value(sk, i);
30811
                /* Prevent wolfSSL_CTX_add_extra_chain_cert from freeing cert */
30812
                if (wolfSSL_X509_up_ref(x509) != 1) {
30813
                    WOLFSSL_MSG("Error increasing reference count");
30814
                    continue;
30815
                }
30816
                if (wolfSSL_CTX_add_extra_chain_cert(ctx, x509) !=
30817
                        WOLFSSL_SUCCESS) {
30818
                    WOLFSSL_MSG("Error adding certificate to context");
30819
                    /* Decrease reference count on failure */
30820
                    wolfSSL_X509_free(x509);
30821
                }
30822
            }
30823
        }
30824
        /* Free previous chain */
30825
        wolfSSL_sk_X509_pop_free(ctx->x509Chain, NULL);
30826
        ctx->x509Chain = sk;
30827
        if (sk && opt == 1) {
30828
            /* up all refs when opt == 1 */
30829
            for (i = 0; i < wolfSSL_sk_X509_num(sk); i++) {
30830
                x509 = wolfSSL_sk_X509_value(sk, i);
30831
                if (wolfSSL_X509_up_ref(x509) != 1) {
30832
                    WOLFSSL_MSG("Error increasing reference count");
30833
                    continue;
30834
                }
30835
            }
30836
        }
30837
    }
30838
#else
30839
0
        WOLFSSL_MSG("Session certificates not compiled in");
30840
0
        ret = WOLFSSL_FAILURE;
30841
0
#endif
30842
0
        break;
30843
30844
0
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
30845
0
    case SSL_CTRL_OPTIONS:
30846
0
        WOLFSSL_MSG("Entering Case: SSL_CTRL_OPTIONS.");
30847
0
        ctrl_opt = wolfSSL_CTX_set_options(ctx, opt);
30848
30849
        #ifdef WOLFSSL_QT
30850
        /* Set whether to use client or server cipher preference */
30851
        if ((ctrl_opt & WOLFSSL_OP_CIPHER_SERVER_PREFERENCE)
30852
                     == WOLFSSL_OP_CIPHER_SERVER_PREFERENCE) {
30853
            WOLFSSL_MSG("Using Server's Cipher Preference.");
30854
            ctx->useClientOrder = FALSE;
30855
        } else {
30856
            WOLFSSL_MSG("Using Client's Cipher Preference.");
30857
            ctx->useClientOrder = TRUE;
30858
        }
30859
        #endif /* WOLFSSL_QT */
30860
30861
0
        return ctrl_opt;
30862
0
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
30863
0
    case SSL_CTRL_EXTRA_CHAIN_CERT:
30864
0
        WOLFSSL_MSG("Entering Case: SSL_CTRL_EXTRA_CHAIN_CERT.");
30865
0
        if (pt == NULL) {
30866
0
            WOLFSSL_MSG("Passed in x509 pointer NULL.");
30867
0
            ret = WOLFSSL_FAILURE;
30868
0
            break;
30869
0
        }
30870
0
        return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
30871
30872
0
#ifndef NO_DH
30873
0
    case SSL_CTRL_SET_TMP_DH:
30874
0
        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_DH.");
30875
0
        if (pt == NULL) {
30876
0
            WOLFSSL_MSG("Passed in DH pointer NULL.");
30877
0
            ret = WOLFSSL_FAILURE;
30878
0
            break;
30879
0
        }
30880
0
        return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
30881
0
#endif
30882
30883
0
#ifdef HAVE_ECC
30884
0
    case SSL_CTRL_SET_TMP_ECDH:
30885
0
        WOLFSSL_MSG("Entering Case: SSL_CTRL_SET_TMP_ECDH.");
30886
0
        if (pt == NULL) {
30887
0
            WOLFSSL_MSG("Passed in ECDH pointer NULL.");
30888
0
            ret = WOLFSSL_FAILURE;
30889
0
            break;
30890
0
        }
30891
0
        return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
30892
0
#endif
30893
0
    case SSL_CTRL_MODE:
30894
0
        wolfSSL_CTX_set_mode(ctx,opt);
30895
0
        break;
30896
0
    case SSL_CTRL_SET_MIN_PROTO_VERSION:
30897
0
        WOLFSSL_MSG("set min proto version");
30898
0
        return wolfSSL_CTX_set_min_proto_version(ctx, (int)opt);
30899
0
    case SSL_CTRL_SET_MAX_PROTO_VERSION:
30900
0
        WOLFSSL_MSG("set max proto version");
30901
0
        return wolfSSL_CTX_set_max_proto_version(ctx, (int)opt);
30902
0
    case SSL_CTRL_GET_MIN_PROTO_VERSION:
30903
0
        WOLFSSL_MSG("get min proto version");
30904
0
        return wolfSSL_CTX_get_min_proto_version(ctx);
30905
0
    case SSL_CTRL_GET_MAX_PROTO_VERSION:
30906
0
        WOLFSSL_MSG("get max proto version");
30907
0
        return wolfSSL_CTX_get_max_proto_version(ctx);
30908
0
    default:
30909
0
        WOLFSSL_MSG("CTX_ctrl cmd not implemented");
30910
0
        ret = WOLFSSL_FAILURE;
30911
0
        break;
30912
0
    }
30913
30914
0
    (void)ctx;
30915
0
    (void)cmd;
30916
0
    (void)opt;
30917
0
    (void)pt;
30918
0
    WOLFSSL_LEAVE("wolfSSL_CTX_ctrl", (int)ret);
30919
0
    return ret;
30920
0
}
30921
30922
#ifndef WOLFSSL_NO_STUB
30923
long wolfSSL_CTX_callback_ctrl(WOLFSSL_CTX* ctx, int cmd, void (*fp)(void))
30924
0
{
30925
0
    (void) ctx;
30926
0
    (void) cmd;
30927
0
    (void) fp;
30928
0
    WOLFSSL_STUB("wolfSSL_CTX_callback_ctrl");
30929
0
    return WOLFSSL_FAILURE;
30930
30931
0
}
30932
#endif /* WOLFSSL_NO_STUB */
30933
30934
#ifndef NO_WOLFSSL_STUB
30935
long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx)
30936
0
{
30937
0
    return wolfSSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0L, NULL);
30938
0
}
30939
#endif
30940
30941
/* Returns the verifyCallback from the ssl structure if successful.
30942
Returns NULL otherwise. */
30943
VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
30944
0
{
30945
0
    WOLFSSL_ENTER("wolfSSL_get_verify_callback()");
30946
0
    if (ssl) {
30947
0
        return ssl->verifyCallback;
30948
0
    }
30949
0
    return NULL;
30950
0
}
30951
30952
/* Adds the ASN1 certificate to the user ctx.
30953
Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
30954
int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz,
30955
                                                       const unsigned char *der)
30956
0
{
30957
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_certificate_ASN1()");
30958
0
    if (der != NULL && ctx != NULL) {
30959
0
        if (wolfSSL_CTX_use_certificate_buffer(ctx, der, derSz,
30960
0
                                      WOLFSSL_FILETYPE_ASN1) == WOLFSSL_SUCCESS) {
30961
0
            return WOLFSSL_SUCCESS;
30962
0
        }
30963
30964
0
    }
30965
0
    return WOLFSSL_FAILURE;
30966
0
}
30967
30968
30969
#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
30970
    !defined(NO_RSA) && !defined(HAVE_USER_RSA)
30971
/* Adds the rsa private key to the user ctx.
30972
Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/
30973
int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa)
30974
0
{
30975
0
    int ret;
30976
0
    int derSize;
30977
0
    unsigned char *maxDerBuf;
30978
0
    unsigned char* key = NULL;
30979
30980
0
    WOLFSSL_ENTER("wolfSSL_CTX_use_RSAPrivateKey()");
30981
30982
0
    if (ctx == NULL || rsa == NULL) {
30983
0
        WOLFSSL_MSG("one or more inputs were NULL");
30984
0
        return BAD_FUNC_ARG;
30985
0
    }
30986
0
    maxDerBuf = (unsigned char*)XMALLOC(4096, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30987
0
    if (maxDerBuf == NULL) {
30988
0
        WOLFSSL_MSG("Malloc failure");
30989
0
        return MEMORY_E;
30990
0
    }
30991
0
    key = maxDerBuf;
30992
    /* convert RSA struct to der encoded buffer and get the size */
30993
0
    if ((derSize = wolfSSL_i2d_RSAPrivateKey(rsa, &key)) <= 0) {
30994
0
        WOLFSSL_MSG("wolfSSL_i2d_RSAPrivateKey() failure");
30995
0
        XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
30996
0
        return WOLFSSL_FAILURE;
30997
0
    }
30998
0
    ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, (const unsigned char*)maxDerBuf,
30999
0
                                                    derSize, SSL_FILETYPE_ASN1);
31000
0
    if (ret != WOLFSSL_SUCCESS) {
31001
0
        WOLFSSL_MSG("wolfSSL_CTX_USE_PrivateKey_buffer() failure");
31002
0
        XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31003
0
        return WOLFSSL_FAILURE;
31004
0
    }
31005
0
    XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
31006
0
    return ret;
31007
0
}
31008
#endif /* NO_RSA && !HAVE_FAST_RSA */
31009
31010
31011
#ifndef NO_BIO
31012
/* Converts EVP_PKEY data from a bio buffer to a WOLFSSL_EVP_PKEY structure.
31013
Returns pointer to private EVP_PKEY struct upon success, NULL if there
31014
is a failure.*/
31015
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio,
31016
                                                         WOLFSSL_EVP_PKEY** out)
31017
0
{
31018
0
    unsigned char* mem = NULL;
31019
0
    int memSz = 0;
31020
0
    WOLFSSL_EVP_PKEY* key = NULL;
31021
0
    int i = 0, j = 0;
31022
0
    unsigned char* extraBioMem = NULL;
31023
0
    int extraBioMemSz = 0;
31024
0
    int derLength = 0;
31025
31026
0
    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_bio()");
31027
31028
0
    if (bio == NULL) {
31029
0
        return NULL;
31030
0
    }
31031
0
    (void)out;
31032
31033
0
    memSz = wolfSSL_BIO_get_len(bio);
31034
0
    if (memSz <= 0) {
31035
0
        WOLFSSL_MSG("wolfSSL_BIO_get_len() failure");
31036
0
        return NULL;
31037
0
    }
31038
31039
0
    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31040
0
    if (mem == NULL) {
31041
0
        WOLFSSL_MSG("Malloc failure");
31042
0
        return NULL;
31043
0
    }
31044
31045
0
    if (wolfSSL_BIO_read(bio, (unsigned char*)mem, memSz) == memSz) {
31046
        /* Determines key type and returns the new private EVP_PKEY object */
31047
0
        if ((key = wolfSSL_d2i_PrivateKey_EVP(NULL, &mem, (long)memSz)) == NULL) {
31048
0
            WOLFSSL_MSG("wolfSSL_d2i_PrivateKey_EVP() failure");
31049
0
            XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31050
0
            return NULL;
31051
0
        }
31052
31053
        /* Write extra data back into bio object if necessary. */
31054
0
        derLength = key->pkey_sz;
31055
0
        extraBioMemSz = (memSz - derLength);
31056
0
        if (extraBioMemSz > 0) {
31057
0
            extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL,
31058
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31059
0
            if (extraBioMem == NULL) {
31060
0
                WOLFSSL_MSG("Malloc failure");
31061
0
                XFREE((unsigned char*)extraBioMem, bio->heap,
31062
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31063
0
                XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31064
0
                return NULL;
31065
0
            }
31066
31067
0
            for (i = derLength; i < memSz; i++) {
31068
0
                *(extraBioMem + j) = *(mem + i);
31069
0
                j++;
31070
0
            }
31071
31072
0
            wolfSSL_BIO_write(bio, extraBioMem, extraBioMemSz);
31073
0
            if (wolfSSL_BIO_get_len(bio) <= 0) {
31074
0
                WOLFSSL_MSG("Failed to write memory to bio");
31075
0
                XFREE((unsigned char*)extraBioMem, bio->heap,
31076
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31077
0
                XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31078
0
                return NULL;
31079
0
            }
31080
0
            XFREE((unsigned char*)extraBioMem, bio->heap,
31081
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
31082
0
        }
31083
31084
0
        if (out != NULL) {
31085
0
            *out = key;
31086
0
        }
31087
0
    }
31088
0
    XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
31089
0
    return key;
31090
0
}
31091
#endif /* !NO_BIO */
31092
31093
#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT */
31094
31095
31096
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) || \
31097
    defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT) || defined(WOLFSSL_WPAS_SMALL)
31098
31099
/* Converts a DER encoded private key to a WOLFSSL_EVP_PKEY structure.
31100
 * returns a pointer to a new WOLFSSL_EVP_PKEY structure on success and NULL
31101
 * on fail */
31102
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out,
31103
                                                  unsigned char** in, long inSz)
31104
0
{
31105
0
    WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey_EVP");
31106
0
    return d2iGenericKey(out, (const unsigned char**)in, inSz, 1);
31107
0
}
31108
31109
#endif /* OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY || WOLFSSL_QT || WOLFSSL_WPAS_SMALL*/
31110
31111
31112
/* stunnel compatibility functions*/
31113
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
31114
                             defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
31115
                             defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
31116
void wolfSSL_ERR_remove_thread_state(void* pid)
31117
0
{
31118
0
    (void) pid;
31119
0
    return;
31120
0
}
31121
31122
#ifndef NO_FILESYSTEM
31123
/***TBD ***/
31124
void wolfSSL_print_all_errors_fp(XFILE fp)
31125
0
{
31126
0
    (void)fp;
31127
0
}
31128
#endif /* !NO_FILESYSTEM */
31129
31130
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX ||
31131
    HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH */
31132
31133
31134
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \
31135
    defined(HAVE_EX_DATA)
31136
31137
#if defined(HAVE_EX_DATA) && !defined(NO_SESSION_CACHE)
31138
static void SESSION_ex_data_cache_update(WOLFSSL_SESSION* session, int idx,
31139
        void* data, byte get, void** getRet, int* setRet)
31140
{
31141
    int row;
31142
    int i;
31143
    int error = 0;
31144
    SessionRow* sessRow = NULL;
31145
    const byte* id;
31146
    byte foundCache = 0;
31147
31148
    if (getRet != NULL)
31149
        *getRet = NULL;
31150
    if (setRet != NULL)
31151
        *setRet = WOLFSSL_FAILURE;
31152
31153
    id = session->sessionID;
31154
    if (session->haveAltSessionID)
31155
        id = session->altSessionID;
31156
31157
    row = (int)(HashObject(id, ID_LEN, &error) % SESSION_ROWS);
31158
    if (error != 0) {
31159
        WOLFSSL_MSG("Hash session failed");
31160
        return;
31161
    }
31162
31163
    sessRow = &SessionCache[row];
31164
    if (SESSION_ROW_LOCK(sessRow) != 0) {
31165
        WOLFSSL_MSG("Session row lock failed");
31166
        return;
31167
    }
31168
31169
    for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
31170
        if (XMEMCMP(id, sessRow->Sessions[i].sessionID, ID_LEN) == 0
31171
                && session->side == sessRow->Sessions[i].side) {
31172
            if (get) {
31173
                *getRet = wolfSSL_CRYPTO_get_ex_data(
31174
                        &sessRow->Sessions[i].ex_data, idx);
31175
            }
31176
            else {
31177
                *setRet = wolfSSL_CRYPTO_set_ex_data(
31178
                        &sessRow->Sessions[i].ex_data, idx, data);
31179
            }
31180
            foundCache = 1;
31181
            break;
31182
        }
31183
    }
31184
    SESSION_ROW_UNLOCK(sessRow);
31185
    /* If we don't have a session in cache then clear the ex_data and
31186
     * own it */
31187
    if (!foundCache) {
31188
        XMEMSET(&session->ex_data, 0, sizeof(WOLFSSL_CRYPTO_EX_DATA));
31189
        session->ownExData = 1;
31190
        if (!get) {
31191
            *setRet = wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx,
31192
                    data);
31193
        }
31194
    }
31195
31196
}
31197
#endif
31198
31199
int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data)
31200
0
{
31201
0
    int ret = WOLFSSL_FAILURE;
31202
0
    WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data");
31203
#ifdef HAVE_EX_DATA
31204
    session = ClientSessionToSession(session);
31205
    if (session != NULL) {
31206
#ifndef NO_SESSION_CACHE
31207
        if (!session->ownExData) {
31208
            /* Need to update in cache */
31209
            SESSION_ex_data_cache_update(session, idx, data, 0, NULL, &ret);
31210
        }
31211
        else
31212
#endif
31213
        {
31214
            ret = wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data);
31215
        }
31216
    }
31217
#else
31218
0
    (void)session;
31219
0
    (void)idx;
31220
0
    (void)data;
31221
0
#endif
31222
0
    return ret;
31223
0
}
31224
31225
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
31226
int wolfSSL_SESSION_set_ex_data_with_cleanup(
31227
    WOLFSSL_SESSION* session,
31228
    int idx,
31229
    void* data,
31230
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
31231
{
31232
    WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data_with_cleanup");
31233
    session = ClientSessionToSession(session);
31234
    if(session != NULL) {
31235
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&session->ex_data, idx,
31236
                                                       data, cleanup_routine);
31237
    }
31238
    return WOLFSSL_FAILURE;
31239
}
31240
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
31241
31242
void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx)
31243
0
{
31244
0
    void* ret = NULL;
31245
0
    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data");
31246
#ifdef HAVE_EX_DATA
31247
    session = ClientSessionToSession(session);
31248
    if (session != NULL) {
31249
#ifndef NO_SESSION_CACHE
31250
        if (!session->ownExData) {
31251
            /* Need to retrieve the data from the session cache */
31252
            SESSION_ex_data_cache_update((WOLFSSL_SESSION*)session, idx, NULL,
31253
                                         1, &ret, NULL);
31254
        }
31255
        else
31256
#endif
31257
        {
31258
            ret = wolfSSL_CRYPTO_get_ex_data(&session->ex_data, idx);
31259
        }
31260
    }
31261
#else
31262
0
    (void)session;
31263
0
    (void)idx;
31264
0
#endif
31265
0
    return ret;
31266
0
}
31267
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL || HAVE_EX_DATA */
31268
31269
/* Note: This is a huge section of API's - through
31270
 *       wolfSSL_X509_OBJECT_get0_X509_CRL */
31271
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \
31272
    (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \
31273
    defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \
31274
    defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB)))
31275
#ifdef HAVE_EX_DATA
31276
int wolfSSL_SESSION_get_ex_new_index(long idx, void* data, void* cb1,
31277
       void* cb2, CRYPTO_free_func* cb3)
31278
{
31279
    WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_new_index");
31280
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(idx, data, cb1, cb2, cb3);
31281
    return wolfssl_get_ex_new_index(WOLF_CRYPTO_EX_INDEX_SSL_SESSION);
31282
}
31283
#endif
31284
31285
#if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_DEBUG_MEMORY)
31286
static wolfSSL_OSSL_Malloc_cb  ossl_malloc  = NULL;
31287
static wolfSSL_OSSL_Free_cb    ossl_free    = NULL;
31288
static wolfSSL_OSSL_Realloc_cb ossl_realloc = NULL;
31289
31290
static void* OSSL_Malloc(size_t size)
31291
0
{
31292
0
    if (ossl_malloc != NULL)
31293
0
        return ossl_malloc(size, NULL, 0);
31294
0
    else
31295
0
        return NULL;
31296
0
}
31297
31298
static void  OSSL_Free(void *ptr)
31299
0
{
31300
0
    if (ossl_free != NULL)
31301
0
        ossl_free(ptr, NULL, 0);
31302
0
}
31303
31304
static void* OSSL_Realloc(void *ptr, size_t size)
31305
0
{
31306
0
    if (ossl_realloc != NULL)
31307
0
        return ossl_realloc(ptr, size, NULL, 0);
31308
0
    else
31309
0
        return NULL;
31310
0
}
31311
#endif /* USE_WOLFSSL_MEMORY && !WOLFSSL_DEBUG_MEMORY */
31312
31313
int wolfSSL_CRYPTO_set_mem_functions(
31314
        wolfSSL_OSSL_Malloc_cb  m,
31315
        wolfSSL_OSSL_Realloc_cb r,
31316
        wolfSSL_OSSL_Free_cb    f)
31317
0
{
31318
0
#ifdef USE_WOLFSSL_MEMORY
31319
#ifdef WOLFSSL_DEBUG_MEMORY
31320
    WOLFSSL_MSG("mem functions will receive function name instead of "
31321
                "file name");
31322
    if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)m, (wolfSSL_Free_cb)f,
31323
            (wolfSSL_Realloc_cb)r) == 0)
31324
        return WOLFSSL_SUCCESS;
31325
#else
31326
0
    WOLFSSL_MSG("wolfSSL was compiled without WOLFSSL_DEBUG_MEMORY. mem "
31327
0
                "functions will receive a NULL file name and 0 for the "
31328
0
                "line number.");
31329
0
    if (wolfSSL_SetAllocators(OSSL_Malloc, OSSL_Free, OSSL_Realloc) == 0) {
31330
0
        ossl_malloc = m;
31331
0
        ossl_free = f;
31332
0
        ossl_realloc = r;
31333
0
        return WOLFSSL_SUCCESS;
31334
0
    }
31335
0
#endif
31336
0
    else
31337
0
        return WOLFSSL_FAILURE;
31338
#else
31339
    (void)m;
31340
    (void)r;
31341
    (void)f;
31342
    WOLFSSL_MSG("wolfSSL allocator callback functions not compiled in");
31343
    return WOLFSSL_FAILURE;
31344
#endif
31345
0
}
31346
31347
int wolfSSL_ERR_load_ERR_strings(void)
31348
0
{
31349
0
    return WOLFSSL_SUCCESS;
31350
0
}
31351
31352
void wolfSSL_ERR_load_crypto_strings(void)
31353
0
{
31354
0
    WOLFSSL_ENTER("wolfSSL_ERR_load_crypto_strings");
31355
    /* Do nothing */
31356
0
    return;
31357
0
}
31358
31359
int wolfSSL_FIPS_mode(void)
31360
0
{
31361
#ifdef HAVE_FIPS
31362
    return 1;
31363
#else
31364
0
    return 0;
31365
0
#endif
31366
0
}
31367
31368
int wolfSSL_FIPS_mode_set(int r)
31369
0
{
31370
#ifdef HAVE_FIPS
31371
    if (r == 0) {
31372
        WOLFSSL_MSG("Cannot disable FIPS at runtime.");
31373
        return WOLFSSL_FAILURE;
31374
    }
31375
    return WOLFSSL_SUCCESS;
31376
#else
31377
0
    if (r == 0) {
31378
0
        return WOLFSSL_SUCCESS;
31379
0
    }
31380
0
    WOLFSSL_MSG("Cannot enable FIPS. This isn't the wolfSSL FIPS code.");
31381
0
    return WOLFSSL_FAILURE;
31382
0
#endif
31383
0
}
31384
31385
int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits)
31386
0
{
31387
0
    int ret = WOLFSSL_FAILURE;
31388
0
    WOLFSSL_ENTER("wolfSSL_CIPHER_get_bits");
31389
31390
0
    #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
31391
0
    (void)alg_bits;
31392
0
    if (c!= NULL)
31393
0
        ret = c->bits;
31394
    #else
31395
    if (c != NULL && c->ssl != NULL) {
31396
        ret = 8 * c->ssl->specs.key_size;
31397
        if (alg_bits != NULL) {
31398
            *alg_bits = ret;
31399
        }
31400
    }
31401
    #endif
31402
0
    return ret;
31403
0
}
31404
31405
/* returns value less than 0 on fail to match
31406
 * On a successful match the priority level found is returned
31407
 */
31408
int wolfSSL_sk_SSL_CIPHER_find(
31409
        WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, const WOLFSSL_CIPHER* toFind)
31410
0
{
31411
0
    WOLFSSL_STACK* next;
31412
0
    int i, sz;
31413
31414
0
    if (sk == NULL || toFind == NULL) {
31415
0
        return WOLFSSL_FATAL_ERROR;
31416
0
    }
31417
31418
0
    sz   = wolfSSL_sk_SSL_CIPHER_num(sk);
31419
0
    next = sk;
31420
0
    for (i = 0; i < sz && next != NULL; i++) {
31421
0
        if (next->data.cipher.cipherSuite0 == toFind->cipherSuite0 &&
31422
0
                next->data.cipher.cipherSuite == toFind->cipherSuite) {
31423
0
            return sz - i; /* reverse because stack pushed highest on first */
31424
0
        }
31425
0
        next = next->next;
31426
0
    }
31427
0
    return WOLFSSL_FATAL_ERROR;
31428
0
}
31429
31430
/* free's all nodes in the stack and there data */
31431
void wolfSSL_sk_SSL_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
31432
0
{
31433
0
    WOLFSSL_ENTER("wolfSSL_sk_SSL_CIPHER_free");
31434
0
    wolfSSL_sk_free(sk);
31435
0
}
31436
31437
#ifdef HAVE_SNI
31438
int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name)
31439
0
{
31440
0
    int ret;
31441
0
    WOLFSSL_ENTER("wolfSSL_set_tlsext_host_name");
31442
0
    ret = wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME,
31443
0
            host_name, (word16)XSTRLEN(host_name));
31444
0
    WOLFSSL_LEAVE("wolfSSL_set_tlsext_host_name", ret);
31445
0
    return ret;
31446
0
}
31447
31448
31449
#ifndef NO_WOLFSSL_SERVER
31450
const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type)
31451
0
{
31452
0
    void * serverName = NULL;
31453
0
    if (ssl == NULL)
31454
0
        return NULL;
31455
0
    TLSX_SNI_GetRequest(ssl->extensions, type, &serverName);
31456
0
    return (const char *)serverName;
31457
0
}
31458
#endif /* NO_WOLFSSL_SERVER */
31459
#endif /* HAVE_SNI */
31460
31461
WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
31462
0
{
31463
0
    if (ssl && ctx && SetSSL_CTX(ssl, ctx, 0) == WOLFSSL_SUCCESS)
31464
0
        return ssl->ctx;
31465
0
    return NULL;
31466
0
}
31467
31468
31469
VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
31470
0
{
31471
0
    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
31472
0
    if(ctx)
31473
0
        return ctx->verifyCallback;
31474
0
    return NULL;
31475
0
}
31476
31477
31478
#ifdef HAVE_SNI
31479
31480
void wolfSSL_CTX_set_servername_callback(WOLFSSL_CTX* ctx, CallbackSniRecv cb)
31481
0
{
31482
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_callback");
31483
0
    if (ctx)
31484
0
        ctx->sniRecvCb = cb;
31485
0
}
31486
31487
int wolfSSL_CTX_set_tlsext_servername_callback(WOLFSSL_CTX* ctx,
31488
                                               CallbackSniRecv cb)
31489
0
{
31490
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_tlsext_servername_callback");
31491
0
    if (ctx) {
31492
0
        ctx->sniRecvCb = cb;
31493
0
        return WOLFSSL_SUCCESS;
31494
0
    }
31495
0
    return WOLFSSL_FAILURE;
31496
0
}
31497
31498
int wolfSSL_CTX_set_servername_arg(WOLFSSL_CTX* ctx, void* arg)
31499
0
{
31500
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_servername_arg");
31501
0
    if (ctx) {
31502
0
        ctx->sniRecvCbArg = arg;
31503
0
        return WOLFSSL_SUCCESS;
31504
0
    }
31505
0
    return WOLFSSL_FAILURE;
31506
0
}
31507
31508
#endif /* HAVE_SNI */
31509
31510
31511
#ifndef NO_BIO
31512
0
void wolfSSL_ERR_load_BIO_strings(void) {
31513
0
    WOLFSSL_ENTER("ERR_load_BIO_strings");
31514
    /* do nothing */
31515
0
}
31516
#endif
31517
31518
#ifndef NO_WOLFSSL_STUB
31519
/* Set THREADID callback, return 1 on success, 0 on error */
31520
int wolfSSL_THREADID_set_callback(
31521
        void(*threadid_func)(WOLFSSL_CRYPTO_THREADID*))
31522
0
{
31523
0
    WOLFSSL_ENTER("wolfSSL_THREADID_set_callback");
31524
0
    WOLFSSL_STUB("CRYPTO_THREADID_set_callback");
31525
0
    (void)threadid_func;
31526
0
    return 1;
31527
0
}
31528
#endif
31529
31530
#ifndef NO_WOLFSSL_STUB
31531
void wolfSSL_THREADID_set_numeric(void* id, unsigned long val)
31532
0
{
31533
0
    WOLFSSL_ENTER("wolfSSL_THREADID_set_numeric");
31534
0
    WOLFSSL_STUB("CRYPTO_THREADID_set_numeric");
31535
0
    (void)id;
31536
0
    (void)val;
31537
0
    return;
31538
0
}
31539
#endif
31540
31541
#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX ||
31542
        * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH ||
31543
        * HAVE_SBLIM_SFCB)) */
31544
31545
31546
#if defined(OPENSSL_EXTRA)
31547
31548
int wolfSSL_CRYPTO_memcmp(const void *a, const void *b, size_t size)
31549
0
{
31550
0
    if (!a || !b)
31551
0
        return 0;
31552
0
    return ConstantCompare((const byte*)a, (const byte*)b, (int)size);
31553
0
}
31554
31555
unsigned long wolfSSL_ERR_peek_last_error(void)
31556
0
{
31557
0
    WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
31558
31559
0
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
31560
0
    {
31561
0
        int ret;
31562
31563
0
        if ((ret = wc_PeekErrorNode(-1, NULL, NULL, NULL)) < 0) {
31564
0
            WOLFSSL_MSG("Issue peeking at error node in queue");
31565
0
            return 0;
31566
0
        }
31567
0
        if (ret == -ASN_NO_PEM_HEADER)
31568
0
            return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
31569
    #if defined(WOLFSSL_PYTHON)
31570
        if (ret == ASN1_R_HEADER_TOO_LONG)
31571
            return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
31572
    #endif
31573
0
        return (unsigned long)ret;
31574
0
    }
31575
#else
31576
    return (unsigned long)(0 - NOT_COMPILED_IN);
31577
#endif
31578
0
}
31579
31580
#endif /* OPENSSL_EXTRA */
31581
31582
int wolfSSL_version(WOLFSSL* ssl)
31583
0
{
31584
0
    WOLFSSL_ENTER("wolfSSL_version");
31585
0
    if (ssl->version.major == SSLv3_MAJOR) {
31586
0
        switch (ssl->version.minor) {
31587
0
            case SSLv3_MINOR :
31588
0
                return SSL3_VERSION;
31589
0
            case TLSv1_MINOR :
31590
0
                return TLS1_VERSION;
31591
0
            case TLSv1_1_MINOR :
31592
0
                return TLS1_1_VERSION;
31593
0
            case TLSv1_2_MINOR :
31594
0
                return TLS1_2_VERSION;
31595
0
            case TLSv1_3_MINOR :
31596
0
                return TLS1_3_VERSION;
31597
0
            default:
31598
0
                return WOLFSSL_FAILURE;
31599
0
        }
31600
0
    }
31601
0
    else if (ssl->version.major == DTLS_MAJOR) {
31602
0
        switch (ssl->version.minor) {
31603
0
            case DTLS_MINOR :
31604
0
                return DTLS1_VERSION;
31605
0
            case DTLSv1_2_MINOR :
31606
0
                return DTLS1_2_VERSION;
31607
0
            default:
31608
0
                return WOLFSSL_FAILURE;
31609
0
        }
31610
0
    }
31611
0
    return WOLFSSL_FAILURE;
31612
0
}
31613
31614
WOLFSSL_CTX* wolfSSL_get_SSL_CTX(WOLFSSL* ssl)
31615
0
{
31616
0
    WOLFSSL_ENTER("wolfSSL_get_SSL_CTX");
31617
0
    return ssl->ctx;
31618
0
}
31619
31620
#if defined(OPENSSL_ALL) || \
31621
    defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
31622
    defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
31623
31624
const byte* wolfSSL_SESSION_get_id(const WOLFSSL_SESSION* sess,
31625
        unsigned int* idLen)
31626
0
{
31627
0
    WOLFSSL_ENTER("wolfSSL_SESSION_get_id");
31628
0
    sess = ClientSessionToSession(sess);
31629
0
    if (sess == NULL || idLen == NULL) {
31630
0
        WOLFSSL_MSG("Bad func args. Please provide idLen");
31631
0
        return NULL;
31632
0
    }
31633
0
    *idLen = sess->sessionIDSz;
31634
0
    return sess->sessionID;
31635
0
}
31636
31637
#if (defined(HAVE_SESSION_TICKET) || defined(SESSION_CERTS)) && \
31638
    !defined(NO_FILESYSTEM)
31639
31640
#ifndef NO_BIO
31641
31642
#if defined(SESSION_CERTS) || \
31643
   (defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET))
31644
/* returns a pointer to the protocol used by the session */
31645
static const char* wolfSSL_SESSION_get_protocol(const WOLFSSL_SESSION* in)
31646
0
{
31647
0
    in = ClientSessionToSession(in);
31648
0
    return wolfSSL_internal_get_version((ProtocolVersion*)&in->version);
31649
0
}
31650
#endif
31651
31652
/* returns true (non 0) if the session has EMS (extended master secret) */
31653
static int wolfSSL_SESSION_haveEMS(const WOLFSSL_SESSION* in)
31654
0
{
31655
0
    in = ClientSessionToSession(in);
31656
0
    if (in == NULL)
31657
0
        return 0;
31658
0
    return in->haveEMS;
31659
0
}
31660
31661
#if defined(HAVE_SESSION_TICKET)
31662
/* prints out the ticket to bio passed in
31663
 * return WOLFSSL_SUCCESS on success
31664
 */
31665
static int wolfSSL_SESSION_print_ticket(WOLFSSL_BIO* bio,
31666
        const WOLFSSL_SESSION* in, const char* tab)
31667
0
{
31668
0
    unsigned short i, j, z, sz;
31669
0
    short tag = 0;
31670
0
    byte* pt;
31671
31672
31673
0
    in = ClientSessionToSession(in);
31674
0
    if (in == NULL || bio == NULL) {
31675
0
        return BAD_FUNC_ARG;
31676
0
    }
31677
31678
0
    sz = in->ticketLen;
31679
0
    pt = in->ticket;
31680
31681
0
    if (wolfSSL_BIO_printf(bio, "%s\n", (sz == 0)? " NONE": "") <= 0)
31682
0
        return WOLFSSL_FAILURE;
31683
31684
0
    for (i = 0; i < sz;) {
31685
0
        char asc[16];
31686
31687
0
        if (sz - i < 16) {
31688
0
            if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag + (sz - i)) <= 0)
31689
0
                return WOLFSSL_FAILURE;
31690
0
        }
31691
0
        else {
31692
0
            if (wolfSSL_BIO_printf(bio, "%s%04X -", tab, tag) <= 0)
31693
0
                return WOLFSSL_FAILURE;
31694
0
        }
31695
0
        for (j = 0; i < sz && j < 8; j++,i++) {
31696
0
            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
31697
0
            if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
31698
0
                return WOLFSSL_FAILURE;
31699
0
        }
31700
31701
0
        if (i < sz) {
31702
0
            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
31703
0
            if (wolfSSL_BIO_printf(bio, "-%02X", pt[i]) <= 0)
31704
0
                return WOLFSSL_FAILURE;
31705
0
            j++;
31706
0
            i++;
31707
0
        }
31708
31709
0
        for (; i < sz && j < 16; j++,i++) {
31710
0
            asc[j] =  ((pt[i])&0x6f)>='A'?((pt[i])&0x6f):'.';
31711
0
            if (wolfSSL_BIO_printf(bio, " %02X", pt[i]) <= 0)
31712
0
                return WOLFSSL_FAILURE;
31713
0
        }
31714
31715
        /* pad out spacing */
31716
0
        for (z = j; z < 17; z++) {
31717
0
            if (wolfSSL_BIO_printf(bio, "   ") <= 0)
31718
0
                return WOLFSSL_FAILURE;
31719
0
        }
31720
31721
0
        for (z = 0; z < j; z++) {
31722
0
            if (wolfSSL_BIO_printf(bio, "%c", asc[z]) <= 0)
31723
0
                return WOLFSSL_FAILURE;
31724
0
        }
31725
0
        if (wolfSSL_BIO_printf(bio, "\n") <= 0)
31726
0
            return WOLFSSL_FAILURE;
31727
31728
0
        tag += 16;
31729
0
    }
31730
0
    return WOLFSSL_SUCCESS;
31731
0
}
31732
#endif /* HAVE_SESSION_TICKET */
31733
31734
31735
/* prints out the session information in human readable form
31736
 * return WOLFSSL_SUCCESS on success
31737
 */
31738
int wolfSSL_SESSION_print(WOLFSSL_BIO *bp, const WOLFSSL_SESSION *session)
31739
0
{
31740
0
    const unsigned char* pt;
31741
0
    unsigned char buf[SECRET_LEN];
31742
0
    unsigned int sz = 0, i;
31743
0
    int ret;
31744
31745
0
    session = ClientSessionToSession(session);
31746
0
    if (session == NULL) {
31747
0
        return WOLFSSL_FAILURE;
31748
0
    }
31749
31750
0
    if (wolfSSL_BIO_printf(bp, "%s\n", "SSL-Session:") <= 0)
31751
0
        return WOLFSSL_FAILURE;
31752
31753
0
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
31754
0
                               defined(HAVE_SESSION_TICKET))
31755
0
    if (wolfSSL_BIO_printf(bp, "    Protocol  : %s\n",
31756
0
            wolfSSL_SESSION_get_protocol(session)) <= 0)
31757
0
        return WOLFSSL_FAILURE;
31758
0
#endif
31759
31760
0
    if (wolfSSL_BIO_printf(bp, "    Cipher    : %s\n",
31761
0
            wolfSSL_SESSION_CIPHER_get_name(session)) <= 0)
31762
0
        return WOLFSSL_FAILURE;
31763
31764
0
    pt = wolfSSL_SESSION_get_id(session, &sz);
31765
0
    if (wolfSSL_BIO_printf(bp, "    Session-ID: ") <= 0)
31766
0
        return WOLFSSL_FAILURE;
31767
31768
0
    for (i = 0; i < sz; i++) {
31769
0
        if (wolfSSL_BIO_printf(bp, "%02X", pt[i]) <= 0)
31770
0
            return WOLFSSL_FAILURE;
31771
0
    }
31772
0
    if (wolfSSL_BIO_printf(bp, "\n") <= 0)
31773
0
        return WOLFSSL_FAILURE;
31774
31775
0
    if (wolfSSL_BIO_printf(bp, "    Session-ID-ctx: \n") <= 0)
31776
0
        return WOLFSSL_FAILURE;
31777
31778
0
    ret = wolfSSL_SESSION_get_master_key(session, buf, sizeof(buf));
31779
0
    if (wolfSSL_BIO_printf(bp, "    Master-Key: ") <= 0)
31780
0
        return WOLFSSL_FAILURE;
31781
31782
0
    if (ret > 0) {
31783
0
        sz = (unsigned int)ret;
31784
0
        for (i = 0; i < sz; i++) {
31785
0
            if (wolfSSL_BIO_printf(bp, "%02X", buf[i]) <= 0)
31786
0
                return WOLFSSL_FAILURE;
31787
0
        }
31788
0
    }
31789
0
    if (wolfSSL_BIO_printf(bp, "\n") <= 0)
31790
0
        return WOLFSSL_FAILURE;
31791
31792
    /* @TODO PSK identity hint and SRP */
31793
31794
0
    if (wolfSSL_BIO_printf(bp, "    TLS session ticket:") <= 0)
31795
0
        return WOLFSSL_FAILURE;
31796
31797
0
#ifdef HAVE_SESSION_TICKET
31798
0
    if (wolfSSL_SESSION_print_ticket(bp, session, "    ") != WOLFSSL_SUCCESS)
31799
0
        return WOLFSSL_FAILURE;
31800
0
#endif
31801
31802
0
#if !defined(NO_SESSION_CACHE) && (defined(OPENSSL_EXTRA) || \
31803
0
        defined(HAVE_EXT_CACHE))
31804
0
    if (wolfSSL_BIO_printf(bp, "    Start Time: %ld\n",
31805
0
                wolfSSL_SESSION_get_time(session)) <= 0)
31806
0
        return WOLFSSL_FAILURE;
31807
31808
0
    if (wolfSSL_BIO_printf(bp, "    Timeout   : %ld (sec)\n",
31809
0
            wolfSSL_SESSION_get_timeout(session)) <= 0)
31810
0
        return WOLFSSL_FAILURE;
31811
0
#endif /* !NO_SESSION_CACHE && OPENSSL_EXTRA || HAVE_EXT_CACHE */
31812
31813
    /* @TODO verify return code print */
31814
31815
0
    if (wolfSSL_BIO_printf(bp, "    Extended master secret: %s\n",
31816
0
            (wolfSSL_SESSION_haveEMS(session) == 0)? "no" : "yes") <= 0)
31817
0
        return WOLFSSL_FAILURE;
31818
31819
0
    return WOLFSSL_SUCCESS;
31820
0
}
31821
31822
#endif /* !NO_BIO */
31823
#endif /* (HAVE_SESSION_TICKET || SESSION_CERTS) && !NO_FILESYSTEM */
31824
31825
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
31826
31827
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && defined(HAVE_STUNNEL)) \
31828
    || defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
31829
31830
/* TODO: Doesn't currently track SSL_VERIFY_CLIENT_ONCE */
31831
0
int wolfSSL_get_verify_mode(const WOLFSSL* ssl) {
31832
0
    int mode = 0;
31833
0
    WOLFSSL_ENTER("wolfSSL_get_verify_mode");
31834
31835
0
    if (!ssl) {
31836
0
        return WOLFSSL_FAILURE;
31837
0
    }
31838
31839
0
    if (ssl->options.verifyNone) {
31840
0
        mode = WOLFSSL_VERIFY_NONE;
31841
0
    }
31842
0
    else {
31843
0
        if (ssl->options.verifyPeer) {
31844
0
            mode |= WOLFSSL_VERIFY_PEER;
31845
0
        }
31846
0
        if (ssl->options.failNoCert) {
31847
0
            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
31848
0
        }
31849
0
        if (ssl->options.failNoCertxPSK) {
31850
0
            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
31851
0
        }
31852
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
31853
        if (ssl->options.verifyPostHandshake) {
31854
            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
31855
        }
31856
#endif
31857
0
    }
31858
31859
0
    WOLFSSL_LEAVE("wolfSSL_get_verify_mode", mode);
31860
0
    return mode;
31861
0
}
31862
31863
int wolfSSL_CTX_get_verify_mode(const WOLFSSL_CTX* ctx)
31864
0
{
31865
0
    int mode = 0;
31866
0
    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
31867
31868
0
    if (!ctx) {
31869
0
        return WOLFSSL_FAILURE;
31870
0
    }
31871
31872
0
    if (ctx->verifyNone) {
31873
0
        mode = WOLFSSL_VERIFY_NONE;
31874
0
    }
31875
0
    else {
31876
0
        if (ctx->verifyPeer) {
31877
0
            mode |= WOLFSSL_VERIFY_PEER;
31878
0
        }
31879
0
        if (ctx->failNoCert) {
31880
0
            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
31881
0
        }
31882
0
        if (ctx->failNoCertxPSK) {
31883
0
            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
31884
0
        }
31885
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
31886
        if (ctx->verifyPostHandshake) {
31887
            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
31888
        }
31889
#endif
31890
0
    }
31891
31892
0
    WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
31893
0
    return mode;
31894
0
}
31895
31896
#endif
31897
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE25519)
31898
/* return 1 if success, 0 if error
31899
 * output keys are little endian format
31900
 */
31901
int wolfSSL_EC25519_generate_key(unsigned char *priv, unsigned int *privSz,
31902
                                 unsigned char *pub, unsigned int *pubSz)
31903
0
{
31904
#ifndef WOLFSSL_KEY_GEN
31905
    WOLFSSL_MSG("No Key Gen built in");
31906
    (void) priv;
31907
    (void) privSz;
31908
    (void) pub;
31909
    (void) pubSz;
31910
    return WOLFSSL_FAILURE;
31911
#else /* WOLFSSL_KEY_GEN */
31912
0
    int ret = WOLFSSL_FAILURE;
31913
0
    int initTmpRng = 0;
31914
0
    WC_RNG *rng = NULL;
31915
0
#ifdef WOLFSSL_SMALL_STACK
31916
0
    WC_RNG *tmpRNG = NULL;
31917
#else
31918
    WC_RNG tmpRNG[1];
31919
#endif
31920
31921
0
    WOLFSSL_ENTER("wolfSSL_EC25519_generate_key");
31922
31923
0
    if (priv == NULL || privSz == NULL || *privSz < CURVE25519_KEYSIZE ||
31924
0
        pub == NULL || pubSz == NULL || *pubSz < CURVE25519_KEYSIZE) {
31925
0
        WOLFSSL_MSG("Bad arguments");
31926
0
        return WOLFSSL_FAILURE;
31927
0
    }
31928
31929
0
#ifdef WOLFSSL_SMALL_STACK
31930
0
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
31931
0
    if (tmpRNG == NULL)
31932
0
        return WOLFSSL_FAILURE;
31933
0
#endif
31934
0
    if (wc_InitRng(tmpRNG) == 0) {
31935
0
        rng = tmpRNG;
31936
0
        initTmpRng = 1;
31937
0
    }
31938
0
    else {
31939
0
        WOLFSSL_MSG("Bad RNG Init, trying global");
31940
0
        if (initGlobalRNG == 0)
31941
0
            WOLFSSL_MSG("Global RNG no Init");
31942
0
        else
31943
0
            rng = &globalRNG;
31944
0
    }
31945
31946
0
    if (rng) {
31947
0
        curve25519_key key;
31948
31949
0
        if (wc_curve25519_init(&key) != MP_OKAY)
31950
0
            WOLFSSL_MSG("wc_curve25519_init failed");
31951
0
        else if (wc_curve25519_make_key(rng, CURVE25519_KEYSIZE, &key)!=MP_OKAY)
31952
0
            WOLFSSL_MSG("wc_curve25519_make_key failed");
31953
        /* export key pair */
31954
0
        else if (wc_curve25519_export_key_raw_ex(&key, priv, privSz, pub,
31955
0
                                                 pubSz, EC25519_LITTLE_ENDIAN)
31956
0
                 != MP_OKAY)
31957
0
            WOLFSSL_MSG("wc_curve25519_export_key_raw_ex failed");
31958
0
        else
31959
0
            ret = WOLFSSL_SUCCESS;
31960
31961
0
        wc_curve25519_free(&key);
31962
0
    }
31963
31964
0
    if (initTmpRng)
31965
0
        wc_FreeRng(tmpRNG);
31966
31967
0
#ifdef WOLFSSL_SMALL_STACK
31968
0
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
31969
0
#endif
31970
31971
0
    return ret;
31972
0
#endif /* WOLFSSL_KEY_GEN */
31973
0
}
31974
31975
/* return 1 if success, 0 if error
31976
 * input and output keys are little endian format
31977
 */
31978
int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz,
31979
                               const unsigned char *priv, unsigned int privSz,
31980
                               const unsigned char *pub, unsigned int pubSz)
31981
0
{
31982
#ifndef WOLFSSL_KEY_GEN
31983
    WOLFSSL_MSG("No Key Gen built in");
31984
    (void) shared;
31985
    (void) sharedSz;
31986
    (void) priv;
31987
    (void) privSz;
31988
    (void) pub;
31989
    (void) pubSz;
31990
    return WOLFSSL_FAILURE;
31991
#else /* WOLFSSL_KEY_GEN */
31992
0
    int ret = WOLFSSL_FAILURE;
31993
0
    curve25519_key privkey, pubkey;
31994
31995
0
    WOLFSSL_ENTER("wolfSSL_EC25519_shared_key");
31996
31997
0
    if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE25519_KEYSIZE ||
31998
0
        priv == NULL || privSz < CURVE25519_KEYSIZE ||
31999
0
        pub == NULL || pubSz < CURVE25519_KEYSIZE) {
32000
0
        WOLFSSL_MSG("Bad arguments");
32001
0
        return WOLFSSL_FAILURE;
32002
0
    }
32003
32004
    /* import private key */
32005
0
    if (wc_curve25519_init(&privkey) != MP_OKAY) {
32006
0
        WOLFSSL_MSG("wc_curve25519_init privkey failed");
32007
0
        return ret;
32008
0
    }
32009
0
    if (wc_curve25519_import_private_ex(priv, privSz, &privkey,
32010
0
                                        EC25519_LITTLE_ENDIAN) != MP_OKAY) {
32011
0
        WOLFSSL_MSG("wc_curve25519_import_private_ex failed");
32012
0
        wc_curve25519_free(&privkey);
32013
0
        return ret;
32014
0
    }
32015
32016
    /* import public key */
32017
0
    if (wc_curve25519_init(&pubkey) != MP_OKAY) {
32018
0
        WOLFSSL_MSG("wc_curve25519_init pubkey failed");
32019
0
        wc_curve25519_free(&privkey);
32020
0
        return ret;
32021
0
    }
32022
0
    if (wc_curve25519_import_public_ex(pub, pubSz, &pubkey,
32023
0
                                       EC25519_LITTLE_ENDIAN) != MP_OKAY) {
32024
0
        WOLFSSL_MSG("wc_curve25519_import_public_ex failed");
32025
0
        wc_curve25519_free(&privkey);
32026
0
        wc_curve25519_free(&pubkey);
32027
0
        return ret;
32028
0
    }
32029
32030
0
    if (wc_curve25519_shared_secret_ex(&privkey, &pubkey,
32031
0
                                       shared, sharedSz,
32032
0
                                       EC25519_LITTLE_ENDIAN) != MP_OKAY)
32033
0
        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
32034
0
    else
32035
0
        ret = WOLFSSL_SUCCESS;
32036
32037
0
    wc_curve25519_free(&privkey);
32038
0
    wc_curve25519_free(&pubkey);
32039
32040
0
    return ret;
32041
0
#endif /* WOLFSSL_KEY_GEN */
32042
0
}
32043
#endif /* OPENSSL_EXTRA && HAVE_CURVE25519 */
32044
32045
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519)
32046
/* return 1 if success, 0 if error
32047
 * output keys are little endian format
32048
 */
32049
int wolfSSL_ED25519_generate_key(unsigned char *priv, unsigned int *privSz,
32050
                                 unsigned char *pub, unsigned int *pubSz)
32051
0
{
32052
#ifndef WOLFSSL_KEY_GEN
32053
    WOLFSSL_MSG("No Key Gen built in");
32054
    (void) priv;
32055
    (void) privSz;
32056
    (void) pub;
32057
    (void) pubSz;
32058
    return WOLFSSL_FAILURE;
32059
#elif !defined(HAVE_ED25519_KEY_EXPORT)
32060
    WOLFSSL_MSG("No ED25519 key export built in");
32061
    (void) priv;
32062
    (void) privSz;
32063
    (void) pub;
32064
    (void) pubSz;
32065
    return WOLFSSL_FAILURE;
32066
#else /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
32067
0
    int ret = WOLFSSL_FAILURE;
32068
0
    int initTmpRng = 0;
32069
0
    WC_RNG *rng = NULL;
32070
0
#ifdef WOLFSSL_SMALL_STACK
32071
0
    WC_RNG *tmpRNG = NULL;
32072
#else
32073
    WC_RNG tmpRNG[1];
32074
#endif
32075
32076
0
    WOLFSSL_ENTER("wolfSSL_ED25519_generate_key");
32077
32078
0
    if (priv == NULL || privSz == NULL || *privSz < ED25519_PRV_KEY_SIZE ||
32079
0
        pub == NULL || pubSz == NULL || *pubSz < ED25519_PUB_KEY_SIZE) {
32080
0
        WOLFSSL_MSG("Bad arguments");
32081
0
        return WOLFSSL_FAILURE;
32082
0
    }
32083
32084
0
#ifdef WOLFSSL_SMALL_STACK
32085
0
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32086
0
    if (tmpRNG == NULL)
32087
0
        return WOLFSSL_FATAL_ERROR;
32088
0
#endif
32089
0
    if (wc_InitRng(tmpRNG) == 0) {
32090
0
        rng = tmpRNG;
32091
0
        initTmpRng = 1;
32092
0
    }
32093
0
    else {
32094
0
        WOLFSSL_MSG("Bad RNG Init, trying global");
32095
0
        if (initGlobalRNG == 0)
32096
0
            WOLFSSL_MSG("Global RNG no Init");
32097
0
        else
32098
0
            rng = &globalRNG;
32099
0
    }
32100
32101
0
    if (rng) {
32102
0
        ed25519_key key;
32103
32104
0
        if (wc_ed25519_init(&key) != MP_OKAY)
32105
0
            WOLFSSL_MSG("wc_ed25519_init failed");
32106
0
        else if (wc_ed25519_make_key(rng, ED25519_KEY_SIZE, &key)!=MP_OKAY)
32107
0
            WOLFSSL_MSG("wc_ed25519_make_key failed");
32108
        /* export private key */
32109
0
        else if (wc_ed25519_export_key(&key, priv, privSz, pub, pubSz)!=MP_OKAY)
32110
0
            WOLFSSL_MSG("wc_ed25519_export_key failed");
32111
0
        else
32112
0
            ret = WOLFSSL_SUCCESS;
32113
32114
0
        wc_ed25519_free(&key);
32115
0
    }
32116
32117
0
    if (initTmpRng)
32118
0
        wc_FreeRng(tmpRNG);
32119
32120
0
#ifdef WOLFSSL_SMALL_STACK
32121
0
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32122
0
#endif
32123
32124
0
    return ret;
32125
0
#endif /* WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_EXPORT */
32126
0
}
32127
32128
/* return 1 if success, 0 if error
32129
 * input and output keys are little endian format
32130
 * priv is a buffer containing private and public part of key
32131
 */
32132
int wolfSSL_ED25519_sign(const unsigned char *msg, unsigned int msgSz,
32133
                         const unsigned char *priv, unsigned int privSz,
32134
                         unsigned char *sig, unsigned int *sigSz)
32135
0
{
32136
#if !defined(HAVE_ED25519_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT)
32137
#if !defined(HAVE_ED25519_SIGN)
32138
    WOLFSSL_MSG("No ED25519 sign built in");
32139
#elif !defined(WOLFSSL_KEY_GEN)
32140
     WOLFSSL_MSG("No Key Gen built in");
32141
#elif !defined(HAVE_ED25519_KEY_IMPORT)
32142
     WOLFSSL_MSG("No ED25519 Key import built in");
32143
#endif
32144
    (void) msg;
32145
    (void) msgSz;
32146
    (void) priv;
32147
    (void) privSz;
32148
    (void) sig;
32149
    (void) sigSz;
32150
    return WOLFSSL_FAILURE;
32151
#else /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32152
0
    ed25519_key key;
32153
0
    int ret = WOLFSSL_FAILURE;
32154
32155
0
    WOLFSSL_ENTER("wolfSSL_ED25519_sign");
32156
32157
0
    if (priv == NULL || privSz != ED25519_PRV_KEY_SIZE ||
32158
0
        msg == NULL || sig == NULL || *sigSz < ED25519_SIG_SIZE) {
32159
0
        WOLFSSL_MSG("Bad arguments");
32160
0
        return WOLFSSL_FAILURE;
32161
0
    }
32162
32163
    /* import key */
32164
0
    if (wc_ed25519_init(&key) != MP_OKAY) {
32165
0
        WOLFSSL_MSG("wc_curve25519_init failed");
32166
0
        return ret;
32167
0
    }
32168
0
    if (wc_ed25519_import_private_key(priv, privSz/2,
32169
0
                                      priv+(privSz/2), ED25519_PUB_KEY_SIZE,
32170
0
                                      &key) != MP_OKAY){
32171
0
        WOLFSSL_MSG("wc_ed25519_import_private failed");
32172
0
        wc_ed25519_free(&key);
32173
0
        return ret;
32174
0
    }
32175
32176
0
    if (wc_ed25519_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
32177
0
        WOLFSSL_MSG("wc_curve25519_shared_secret_ex failed");
32178
0
    else
32179
0
        ret = WOLFSSL_SUCCESS;
32180
32181
0
    wc_ed25519_free(&key);
32182
32183
0
    return ret;
32184
0
#endif /* HAVE_ED25519_SIGN && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32185
0
}
32186
32187
/* return 1 if success, 0 if error
32188
 * input and output keys are little endian format
32189
 * pub is a buffer containing public part of key
32190
 */
32191
int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
32192
                           const unsigned char *pub, unsigned int pubSz,
32193
                           const unsigned char *sig, unsigned int sigSz)
32194
0
{
32195
#if !defined(HAVE_ED25519_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED25519_KEY_IMPORT)
32196
#if !defined(HAVE_ED25519_VERIFY)
32197
    WOLFSSL_MSG("No ED25519 verify built in");
32198
#elif !defined(WOLFSSL_KEY_GEN)
32199
     WOLFSSL_MSG("No Key Gen built in");
32200
#elif !defined(HAVE_ED25519_KEY_IMPORT)
32201
     WOLFSSL_MSG("No ED25519 Key import built in");
32202
#endif
32203
    (void) msg;
32204
    (void) msgSz;
32205
    (void) pub;
32206
    (void) pubSz;
32207
    (void) sig;
32208
    (void) sigSz;
32209
    return WOLFSSL_FAILURE;
32210
#else /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32211
0
    ed25519_key key;
32212
0
    int ret = WOLFSSL_FAILURE, check = 0;
32213
32214
0
    WOLFSSL_ENTER("wolfSSL_ED25519_verify");
32215
32216
0
    if (pub == NULL || pubSz != ED25519_PUB_KEY_SIZE ||
32217
0
        msg == NULL || sig == NULL || sigSz != ED25519_SIG_SIZE) {
32218
0
        WOLFSSL_MSG("Bad arguments");
32219
0
        return WOLFSSL_FAILURE;
32220
0
    }
32221
32222
    /* import key */
32223
0
    if (wc_ed25519_init(&key) != MP_OKAY) {
32224
0
        WOLFSSL_MSG("wc_curve25519_init failed");
32225
0
        return ret;
32226
0
    }
32227
0
    if (wc_ed25519_import_public(pub, pubSz, &key) != MP_OKAY){
32228
0
        WOLFSSL_MSG("wc_ed25519_import_public failed");
32229
0
        wc_ed25519_free(&key);
32230
0
        return ret;
32231
0
    }
32232
32233
0
    if ((ret = wc_ed25519_verify_msg((byte*)sig, sigSz, msg, msgSz,
32234
0
                                     &check, &key)) != MP_OKAY) {
32235
0
        WOLFSSL_MSG("wc_ed25519_verify_msg failed");
32236
0
    }
32237
0
    else if (!check)
32238
0
        WOLFSSL_MSG("wc_ed25519_verify_msg failed (signature invalid)");
32239
0
    else
32240
0
        ret = WOLFSSL_SUCCESS;
32241
32242
0
    wc_ed25519_free(&key);
32243
32244
0
    return ret;
32245
0
#endif /* HAVE_ED25519_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED25519_KEY_IMPORT */
32246
0
}
32247
32248
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
32249
32250
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
32251
/* return 1 if success, 0 if error
32252
 * output keys are little endian format
32253
 */
32254
int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
32255
                               unsigned char *pub, unsigned int *pubSz)
32256
0
{
32257
#ifndef WOLFSSL_KEY_GEN
32258
    WOLFSSL_MSG("No Key Gen built in");
32259
    (void) priv;
32260
    (void) privSz;
32261
    (void) pub;
32262
    (void) pubSz;
32263
    return WOLFSSL_FAILURE;
32264
#else /* WOLFSSL_KEY_GEN */
32265
0
    int ret = WOLFSSL_FAILURE;
32266
0
    int initTmpRng = 0;
32267
0
    WC_RNG *rng = NULL;
32268
0
#ifdef WOLFSSL_SMALL_STACK
32269
0
    WC_RNG *tmpRNG = NULL;
32270
#else
32271
    WC_RNG tmpRNG[1];
32272
#endif
32273
32274
0
    WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
32275
32276
0
    if (priv == NULL || privSz == NULL || *privSz < CURVE448_KEY_SIZE ||
32277
0
        pub == NULL || pubSz == NULL || *pubSz < CURVE448_KEY_SIZE) {
32278
0
        WOLFSSL_MSG("Bad arguments");
32279
0
        return WOLFSSL_FAILURE;
32280
0
    }
32281
32282
0
#ifdef WOLFSSL_SMALL_STACK
32283
0
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32284
0
    if (tmpRNG == NULL)
32285
0
        return WOLFSSL_FAILURE;
32286
0
#endif
32287
0
    if (wc_InitRng(tmpRNG) == 0) {
32288
0
        rng = tmpRNG;
32289
0
        initTmpRng = 1;
32290
0
    }
32291
0
    else {
32292
0
        WOLFSSL_MSG("Bad RNG Init, trying global");
32293
0
        if (initGlobalRNG == 0)
32294
0
            WOLFSSL_MSG("Global RNG no Init");
32295
0
        else
32296
0
            rng = &globalRNG;
32297
0
    }
32298
32299
0
    if (rng) {
32300
0
        curve448_key key;
32301
32302
0
        if (wc_curve448_init(&key) != MP_OKAY)
32303
0
            WOLFSSL_MSG("wc_curve448_init failed");
32304
0
        else if (wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key)!=MP_OKAY)
32305
0
            WOLFSSL_MSG("wc_curve448_make_key failed");
32306
        /* export key pair */
32307
0
        else if (wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
32308
0
                                               EC448_LITTLE_ENDIAN)
32309
0
                 != MP_OKAY)
32310
0
            WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
32311
0
        else
32312
0
            ret = WOLFSSL_SUCCESS;
32313
32314
0
        wc_curve448_free(&key);
32315
0
    }
32316
32317
0
    if (initTmpRng)
32318
0
        wc_FreeRng(tmpRNG);
32319
32320
0
#ifdef WOLFSSL_SMALL_STACK
32321
0
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32322
0
#endif
32323
32324
0
    return ret;
32325
0
#endif /* WOLFSSL_KEY_GEN */
32326
0
}
32327
32328
/* return 1 if success, 0 if error
32329
 * input and output keys are little endian format
32330
 */
32331
int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
32332
                             const unsigned char *priv, unsigned int privSz,
32333
                             const unsigned char *pub, unsigned int pubSz)
32334
0
{
32335
#ifndef WOLFSSL_KEY_GEN
32336
    WOLFSSL_MSG("No Key Gen built in");
32337
    (void) shared;
32338
    (void) sharedSz;
32339
    (void) priv;
32340
    (void) privSz;
32341
    (void) pub;
32342
    (void) pubSz;
32343
    return WOLFSSL_FAILURE;
32344
#else /* WOLFSSL_KEY_GEN */
32345
0
    int ret = WOLFSSL_FAILURE;
32346
0
    curve448_key privkey, pubkey;
32347
32348
0
    WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
32349
32350
0
    if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE448_KEY_SIZE ||
32351
0
            priv == NULL || privSz < CURVE448_KEY_SIZE ||
32352
0
            pub == NULL || pubSz < CURVE448_KEY_SIZE) {
32353
0
        WOLFSSL_MSG("Bad arguments");
32354
0
        return WOLFSSL_FAILURE;
32355
0
    }
32356
32357
    /* import private key */
32358
0
    if (wc_curve448_init(&privkey) != MP_OKAY) {
32359
0
        WOLFSSL_MSG("wc_curve448_init privkey failed");
32360
0
        return ret;
32361
0
    }
32362
0
    if (wc_curve448_import_private_ex(priv, privSz, &privkey,
32363
0
                                      EC448_LITTLE_ENDIAN) != MP_OKAY) {
32364
0
        WOLFSSL_MSG("wc_curve448_import_private_ex failed");
32365
0
        wc_curve448_free(&privkey);
32366
0
        return ret;
32367
0
    }
32368
32369
    /* import public key */
32370
0
    if (wc_curve448_init(&pubkey) != MP_OKAY) {
32371
0
        WOLFSSL_MSG("wc_curve448_init pubkey failed");
32372
0
        wc_curve448_free(&privkey);
32373
0
        return ret;
32374
0
    }
32375
0
    if (wc_curve448_import_public_ex(pub, pubSz, &pubkey,
32376
0
                                     EC448_LITTLE_ENDIAN) != MP_OKAY) {
32377
0
        WOLFSSL_MSG("wc_curve448_import_public_ex failed");
32378
0
        wc_curve448_free(&privkey);
32379
0
        wc_curve448_free(&pubkey);
32380
0
        return ret;
32381
0
    }
32382
32383
0
    if (wc_curve448_shared_secret_ex(&privkey, &pubkey, shared, sharedSz,
32384
0
                                     EC448_LITTLE_ENDIAN) != MP_OKAY)
32385
0
        WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
32386
0
    else
32387
0
        ret = WOLFSSL_SUCCESS;
32388
32389
0
    wc_curve448_free(&privkey);
32390
0
    wc_curve448_free(&pubkey);
32391
32392
0
    return ret;
32393
0
#endif /* WOLFSSL_KEY_GEN */
32394
0
}
32395
#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
32396
32397
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
32398
/* return 1 if success, 0 if error
32399
 * output keys are little endian format
32400
 */
32401
int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
32402
                               unsigned char *pub, unsigned int *pubSz)
32403
0
{
32404
#ifndef WOLFSSL_KEY_GEN
32405
    WOLFSSL_MSG("No Key Gen built in");
32406
    (void) priv;
32407
    (void) privSz;
32408
    (void) pub;
32409
    (void) pubSz;
32410
    return WOLFSSL_FAILURE;
32411
#elif !defined(HAVE_ED448_KEY_EXPORT)
32412
    WOLFSSL_MSG("No ED448 key export built in");
32413
    (void) priv;
32414
    (void) privSz;
32415
    (void) pub;
32416
    (void) pubSz;
32417
    return WOLFSSL_FAILURE;
32418
#else /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
32419
0
    int ret = WOLFSSL_FAILURE;
32420
0
    int initTmpRng = 0;
32421
0
    WC_RNG *rng = NULL;
32422
0
#ifdef WOLFSSL_SMALL_STACK
32423
0
    WC_RNG *tmpRNG = NULL;
32424
#else
32425
    WC_RNG tmpRNG[1];
32426
#endif
32427
32428
0
    WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
32429
32430
0
    if (priv == NULL || privSz == NULL || *privSz < ED448_PRV_KEY_SIZE ||
32431
0
            pub == NULL || pubSz == NULL || *pubSz < ED448_PUB_KEY_SIZE) {
32432
0
        WOLFSSL_MSG("Bad arguments");
32433
0
        return WOLFSSL_FAILURE;
32434
0
    }
32435
32436
0
#ifdef WOLFSSL_SMALL_STACK
32437
0
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
32438
0
    if (tmpRNG == NULL)
32439
0
        return WOLFSSL_FATAL_ERROR;
32440
0
#endif
32441
0
    if (wc_InitRng(tmpRNG) == 0) {
32442
0
        rng = tmpRNG;
32443
0
        initTmpRng = 1;
32444
0
    }
32445
0
    else {
32446
0
        WOLFSSL_MSG("Bad RNG Init, trying global");
32447
0
        if (initGlobalRNG == 0)
32448
0
            WOLFSSL_MSG("Global RNG no Init");
32449
0
        else
32450
0
            rng = &globalRNG;
32451
0
    }
32452
32453
0
    if (rng) {
32454
0
        ed448_key key;
32455
32456
0
        if (wc_ed448_init(&key) != MP_OKAY)
32457
0
            WOLFSSL_MSG("wc_ed448_init failed");
32458
0
        else if (wc_ed448_make_key(rng, ED448_KEY_SIZE, &key) != MP_OKAY)
32459
0
            WOLFSSL_MSG("wc_ed448_make_key failed");
32460
        /* export private key */
32461
0
        else if (wc_ed448_export_key(&key, priv, privSz, pub, pubSz) != MP_OKAY)
32462
0
            WOLFSSL_MSG("wc_ed448_export_key failed");
32463
0
        else
32464
0
            ret = WOLFSSL_SUCCESS;
32465
32466
0
        wc_ed448_free(&key);
32467
0
    }
32468
32469
0
    if (initTmpRng)
32470
0
        wc_FreeRng(tmpRNG);
32471
32472
0
#ifdef WOLFSSL_SMALL_STACK
32473
0
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
32474
0
#endif
32475
32476
0
    return ret;
32477
0
#endif /* WOLFSSL_KEY_GEN && HAVE_ED448_KEY_EXPORT */
32478
0
}
32479
32480
/* return 1 if success, 0 if error
32481
 * input and output keys are little endian format
32482
 * priv is a buffer containing private and public part of key
32483
 */
32484
int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
32485
                       const unsigned char *priv, unsigned int privSz,
32486
                       unsigned char *sig, unsigned int *sigSz)
32487
0
{
32488
#if !defined(HAVE_ED448_SIGN) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT)
32489
#if !defined(HAVE_ED448_SIGN)
32490
    WOLFSSL_MSG("No ED448 sign built in");
32491
#elif !defined(WOLFSSL_KEY_GEN)
32492
    WOLFSSL_MSG("No Key Gen built in");
32493
#elif !defined(HAVE_ED448_KEY_IMPORT)
32494
    WOLFSSL_MSG("No ED448 Key import built in");
32495
#endif
32496
    (void) msg;
32497
    (void) msgSz;
32498
    (void) priv;
32499
    (void) privSz;
32500
    (void) sig;
32501
    (void) sigSz;
32502
    return WOLFSSL_FAILURE;
32503
#else /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
32504
0
    ed448_key key;
32505
0
    int ret = WOLFSSL_FAILURE;
32506
32507
0
    WOLFSSL_ENTER("wolfSSL_ED448_sign");
32508
32509
0
    if (priv == NULL || privSz != ED448_PRV_KEY_SIZE || msg == NULL ||
32510
0
            sig == NULL || *sigSz < ED448_SIG_SIZE) {
32511
0
        WOLFSSL_MSG("Bad arguments");
32512
0
        return WOLFSSL_FAILURE;
32513
0
    }
32514
32515
    /* import key */
32516
0
    if (wc_ed448_init(&key) != MP_OKAY) {
32517
0
        WOLFSSL_MSG("wc_curve448_init failed");
32518
0
        return ret;
32519
0
    }
32520
0
    if (wc_ed448_import_private_key(priv, privSz/2, priv+(privSz/2),
32521
0
                                    ED448_PUB_KEY_SIZE, &key) != MP_OKAY){
32522
0
        WOLFSSL_MSG("wc_ed448_import_private failed");
32523
0
        wc_ed448_free(&key);
32524
0
        return ret;
32525
0
    }
32526
32527
0
    if (wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key, NULL, 0) != MP_OKAY)
32528
0
        WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
32529
0
    else
32530
0
        ret = WOLFSSL_SUCCESS;
32531
32532
0
    wc_ed448_free(&key);
32533
32534
0
    return ret;
32535
0
#endif /* HAVE_ED448_SIGN && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
32536
0
}
32537
32538
/* return 1 if success, 0 if error
32539
 * input and output keys are little endian format
32540
 * pub is a buffer containing public part of key
32541
 */
32542
int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
32543
                         const unsigned char *pub, unsigned int pubSz,
32544
                         const unsigned char *sig, unsigned int sigSz)
32545
0
{
32546
#if !defined(HAVE_ED448_VERIFY) || !defined(WOLFSSL_KEY_GEN) || !defined(HAVE_ED448_KEY_IMPORT)
32547
#if !defined(HAVE_ED448_VERIFY)
32548
    WOLFSSL_MSG("No ED448 verify built in");
32549
#elif !defined(WOLFSSL_KEY_GEN)
32550
    WOLFSSL_MSG("No Key Gen built in");
32551
#elif !defined(HAVE_ED448_KEY_IMPORT)
32552
    WOLFSSL_MSG("No ED448 Key import built in");
32553
#endif
32554
    (void) msg;
32555
    (void) msgSz;
32556
    (void) pub;
32557
    (void) pubSz;
32558
    (void) sig;
32559
    (void) sigSz;
32560
    return WOLFSSL_FAILURE;
32561
#else /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN && HAVE_ED448_KEY_IMPORT */
32562
0
    ed448_key key;
32563
0
    int ret = WOLFSSL_FAILURE, check = 0;
32564
32565
0
    WOLFSSL_ENTER("wolfSSL_ED448_verify");
32566
32567
0
    if (pub == NULL || pubSz != ED448_PUB_KEY_SIZE || msg == NULL ||
32568
0
            sig == NULL || sigSz != ED448_SIG_SIZE) {
32569
0
        WOLFSSL_MSG("Bad arguments");
32570
0
        return WOLFSSL_FAILURE;
32571
0
    }
32572
32573
    /* import key */
32574
0
    if (wc_ed448_init(&key) != MP_OKAY) {
32575
0
        WOLFSSL_MSG("wc_curve448_init failed");
32576
0
        return ret;
32577
0
    }
32578
0
    if (wc_ed448_import_public(pub, pubSz, &key) != MP_OKAY){
32579
0
        WOLFSSL_MSG("wc_ed448_import_public failed");
32580
0
        wc_ed448_free(&key);
32581
0
        return ret;
32582
0
    }
32583
32584
0
    if ((ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
32585
0
                                   &key, NULL, 0)) != MP_OKAY) {
32586
0
        WOLFSSL_MSG("wc_ed448_verify_msg failed");
32587
0
    }
32588
0
    else if (!check)
32589
0
        WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
32590
0
    else
32591
0
        ret = WOLFSSL_SUCCESS;
32592
32593
0
    wc_ed448_free(&key);
32594
32595
0
    return ret;
32596
0
#endif /* HAVE_ED448_VERIFY && WOLFSSL_KEY_GEN */
32597
0
}
32598
32599
#endif /* OPENSSL_EXTRA && HAVE_ED448 */
32600
32601
#ifdef WOLFSSL_JNI
32602
32603
int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
32604
{
32605
    WOLFSSL_ENTER("wolfSSL_set_jobject");
32606
    if (ssl != NULL)
32607
    {
32608
        ssl->jObjectRef = objPtr;
32609
        return WOLFSSL_SUCCESS;
32610
    }
32611
    return WOLFSSL_FAILURE;
32612
}
32613
32614
void* wolfSSL_get_jobject(WOLFSSL* ssl)
32615
{
32616
    WOLFSSL_ENTER("wolfSSL_get_jobject");
32617
    if (ssl != NULL)
32618
        return ssl->jObjectRef;
32619
    return NULL;
32620
}
32621
32622
#endif /* WOLFSSL_JNI */
32623
32624
32625
#ifdef WOLFSSL_ASYNC_CRYPT
32626
int wolfSSL_CTX_AsyncPoll(WOLFSSL_CTX* ctx, WOLF_EVENT** events, int maxEvents,
32627
    WOLF_EVENT_FLAG flags, int* eventCount)
32628
{
32629
    if (ctx == NULL) {
32630
        return BAD_FUNC_ARG;
32631
    }
32632
32633
    return wolfAsync_EventQueuePoll(&ctx->event_queue, NULL,
32634
                                        events, maxEvents, flags, eventCount);
32635
}
32636
32637
int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags)
32638
{
32639
    int ret, eventCount = 0;
32640
    WOLF_EVENT* events[1];
32641
32642
    if (ssl == NULL) {
32643
        return BAD_FUNC_ARG;
32644
    }
32645
32646
    ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl,
32647
        events, sizeof(events)/sizeof(events[0]), flags, &eventCount);
32648
    if (ret == 0) {
32649
        ret = eventCount;
32650
    }
32651
32652
    return ret;
32653
}
32654
#endif /* WOLFSSL_ASYNC_CRYPT */
32655
32656
#ifdef OPENSSL_EXTRA
32657
unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
32658
                                               const char **data, int *flags)
32659
0
{
32660
0
    WOLFSSL_ENTER("wolfSSL_ERR_peek_error_line_data");
32661
32662
0
    (void)line;
32663
0
    (void)file;
32664
32665
    /* No data or flags stored - error display only in Nginx. */
32666
0
    if (data != NULL) {
32667
0
        *data = "";
32668
0
    }
32669
0
    if (flags != NULL) {
32670
0
        *flags = 0;
32671
0
    }
32672
32673
0
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
32674
0
    {
32675
0
        int ret = 0;
32676
32677
0
        while (1) {
32678
0
            ret = wc_PeekErrorNode(0, file, NULL, line);
32679
0
            if (ret == BAD_MUTEX_E || ret == BAD_FUNC_ARG || ret == BAD_STATE_E) {
32680
0
                WOLFSSL_MSG("Issue peeking at error node in queue");
32681
0
                return 0;
32682
0
            }
32683
            /* OpenSSL uses positive error codes */
32684
0
            if (ret < 0) {
32685
0
                ret = -ret;
32686
0
            }
32687
32688
0
            if (ret == -ASN_NO_PEM_HEADER)
32689
0
                return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
32690
0
        #ifdef OPENSSL_ALL
32691
            /* PARSE_ERROR is returned if an HTTP request is detected. */
32692
0
            if (ret == -SSL_R_HTTP_REQUEST)
32693
0
                return (ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST;
32694
0
        #endif
32695
        #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
32696
            if (ret == ASN1_R_HEADER_TOO_LONG) {
32697
                return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
32698
            }
32699
        #endif
32700
0
            if (ret != -WANT_READ && ret != -WANT_WRITE &&
32701
0
                    ret != -ZERO_RETURN && ret != -WOLFSSL_ERROR_ZERO_RETURN &&
32702
0
                    ret != -SOCKET_PEER_CLOSED_E && ret != -SOCKET_ERROR_E)
32703
0
                break;
32704
32705
0
            wc_RemoveErrorNode(0);
32706
0
        }
32707
32708
0
        return (unsigned long)ret;
32709
0
    }
32710
#else
32711
    return (unsigned long)(0 - NOT_COMPILED_IN);
32712
#endif
32713
0
}
32714
#endif
32715
32716
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
32717
32718
#if !defined(WOLFSSL_USER_IO)
32719
/* converts an IPv6 or IPv4 address into an octet string for use with rfc3280
32720
 * example input would be "127.0.0.1" and the returned value would be 7F000001
32721
 */
32722
WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa)
32723
0
{
32724
0
    int ipaSz = WOLFSSL_IP4_ADDR_LEN;
32725
0
    char buf[WOLFSSL_IP6_ADDR_LEN + 1]; /* plus 1 for terminator */
32726
0
    int  af = WOLFSSL_IP4;
32727
0
    WOLFSSL_ASN1_STRING *ret = NULL;
32728
32729
0
    if (ipa == NULL)
32730
0
        return NULL;
32731
32732
0
    if (XSTRSTR(ipa, ":") != NULL) {
32733
0
        af = WOLFSSL_IP6;
32734
0
        ipaSz = WOLFSSL_IP6_ADDR_LEN;
32735
0
    }
32736
32737
0
    buf[WOLFSSL_IP6_ADDR_LEN] = '\0';
32738
0
    if (XINET_PTON(af, ipa, (void*)buf) != 1) {
32739
0
        WOLFSSL_MSG("Error parsing IP address");
32740
0
        return NULL;
32741
0
    }
32742
32743
0
    ret = wolfSSL_ASN1_STRING_new();
32744
0
    if (ret != NULL) {
32745
0
        if (wolfSSL_ASN1_STRING_set(ret, buf, ipaSz) != WOLFSSL_SUCCESS) {
32746
0
            WOLFSSL_MSG("Error setting the string");
32747
0
            wolfSSL_ASN1_STRING_free(ret);
32748
0
            ret = NULL;
32749
0
        }
32750
0
    }
32751
32752
0
    return ret;
32753
0
}
32754
#endif /* !WOLFSSL_USER_IO */
32755
32756
/* Is the specified cipher suite a fake one used an an extension proxy? */
32757
static WC_INLINE int SCSV_Check(byte suite0, byte suite)
32758
0
{
32759
0
    (void)suite0;
32760
0
    (void)suite;
32761
#ifdef HAVE_RENEGOTIATION_INDICATION
32762
    if (suite0 == CIPHER_BYTE && suite == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
32763
        return 1;
32764
#endif
32765
0
    return 0;
32766
0
}
32767
32768
static WC_INLINE int sslCipherMinMaxCheck(const WOLFSSL *ssl, byte suite0,
32769
        byte suite)
32770
0
{
32771
0
    const CipherSuiteInfo* cipher_names = GetCipherNames();
32772
0
    int cipherSz = GetCipherNamesSize();
32773
0
    int i;
32774
0
    for (i = 0; i < cipherSz; i++)
32775
0
        if (cipher_names[i].cipherSuite0 == suite0 &&
32776
0
                cipher_names[i].cipherSuite == suite)
32777
0
            break;
32778
0
    if (i == cipherSz)
32779
0
        return 1;
32780
    /* Check min version */
32781
0
    if (cipher_names[i].minor < ssl->options.minDowngrade) {
32782
0
        if (ssl->options.minDowngrade <= TLSv1_2_MINOR &&
32783
0
                cipher_names[i].minor >= TLSv1_MINOR)
32784
            /* 1.0 ciphersuites are in general available in 1.1 and
32785
             * 1.1 ciphersuites are in general available in 1.2 */
32786
0
            return 0;
32787
0
        return 1;
32788
0
    }
32789
    /* Check max version */
32790
0
    switch (cipher_names[i].minor) {
32791
0
    case SSLv3_MINOR :
32792
0
        return ssl->options.mask & WOLFSSL_OP_NO_SSLv3;
32793
0
    case TLSv1_MINOR :
32794
0
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1;
32795
0
    case TLSv1_1_MINOR :
32796
0
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_1;
32797
0
    case TLSv1_2_MINOR :
32798
0
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_2;
32799
0
    case TLSv1_3_MINOR :
32800
0
        return ssl->options.mask & WOLFSSL_OP_NO_TLSv1_3;
32801
0
    default:
32802
0
        WOLFSSL_MSG("Unrecognized minor version");
32803
0
        return 1;
32804
0
    }
32805
0
}
32806
32807
/* returns a pointer to internal cipher suite list. Should not be free'd by
32808
 * caller.
32809
 */
32810
WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl)
32811
0
{
32812
0
    WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL;
32813
0
    Suites* suites;
32814
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
32815
0
    const CipherSuiteInfo* cipher_names = GetCipherNames();
32816
0
    int cipherSz = GetCipherNamesSize();
32817
0
#endif
32818
32819
0
    WOLFSSL_ENTER("wolfSSL_get_ciphers_compat");
32820
0
    if (ssl == NULL || (ssl->suites == NULL && ssl->ctx->suites == NULL)) {
32821
0
        return NULL;
32822
0
    }
32823
32824
0
    if (ssl->suites != NULL) {
32825
0
        if (ssl->suites->suiteSz == 0 &&
32826
0
                InitSSL_Suites((WOLFSSL*)ssl) != WOLFSSL_SUCCESS) {
32827
0
            WOLFSSL_MSG("Suite initialization failure");
32828
0
            return NULL;
32829
0
        }
32830
0
        suites = ssl->suites;
32831
0
    }
32832
0
    else {
32833
0
        suites = ssl->ctx->suites;
32834
0
    }
32835
32836
    /* check if stack needs populated */
32837
0
    if (suites->stack == NULL) {
32838
0
        int i;
32839
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
32840
0
        int j;
32841
32842
        /* higher priority of cipher suite will be on top of stack */
32843
0
        for (i = suites->suiteSz - 2; i >=0; i-=2) {
32844
#else
32845
        for (i = 0; i < suites->suiteSz; i+=2) {
32846
#endif
32847
0
            WOLFSSL_STACK* add;
32848
32849
            /* A couple of suites are placeholders for special options,
32850
             * skip those. */
32851
0
            if (SCSV_Check(suites->suites[i], suites->suites[i+1])
32852
0
                    || sslCipherMinMaxCheck(ssl, suites->suites[i],
32853
0
                                            suites->suites[i+1])) {
32854
0
                continue;
32855
0
            }
32856
32857
0
            add = wolfSSL_sk_new_node(ssl->heap);
32858
0
            if (add != NULL) {
32859
0
                add->type = STACK_TYPE_CIPHER;
32860
0
                add->data.cipher.cipherSuite0 = suites->suites[i];
32861
0
                add->data.cipher.cipherSuite  = suites->suites[i+1];
32862
0
                add->data.cipher.ssl          = ssl;
32863
0
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
32864
0
                for (j = 0; j < cipherSz; j++) {
32865
0
                    if (cipher_names[j].cipherSuite0 ==
32866
0
                            add->data.cipher.cipherSuite0 &&
32867
0
                            cipher_names[j].cipherSuite ==
32868
0
                                    add->data.cipher.cipherSuite) {
32869
0
                        add->data.cipher.offset = j;
32870
0
                        break;
32871
0
                    }
32872
0
                }
32873
0
#endif
32874
0
                #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
32875
                /* in_stack is checked in wolfSSL_CIPHER_description */
32876
0
                add->data.cipher.in_stack     = 1;
32877
0
                #endif
32878
32879
0
                add->next = ret;
32880
0
                if (ret != NULL) {
32881
0
                    add->num = ret->num + 1;
32882
0
                }
32883
0
                else {
32884
0
                    add->num = 1;
32885
0
                }
32886
0
                ret = add;
32887
0
            }
32888
0
        }
32889
0
        suites->stack = ret;
32890
0
    }
32891
0
    return suites->stack;
32892
0
}
32893
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
32894
32895
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
32896
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || defined(HAVE_SECRET_CALLBACK)
32897
long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx)
32898
0
{
32899
0
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_get_timeout");
32900
32901
0
    if (ctx == NULL)
32902
0
        return 0;
32903
32904
0
    return ctx->timeout;
32905
0
}
32906
32907
32908
/* returns the time in seconds of the current timeout */
32909
long wolfSSL_get_timeout(WOLFSSL* ssl)
32910
0
{
32911
0
    WOLFSSL_ENTER("wolfSSL_get_timeout");
32912
32913
0
    if (ssl == NULL)
32914
0
        return 0;
32915
0
    return ssl->timeout;
32916
0
}
32917
#endif
32918
32919
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) \
32920
    || defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY)
32921
32922
#ifdef HAVE_ECC
32923
int wolfSSL_SSL_CTX_set_tmp_ecdh(WOLFSSL_CTX *ctx, WOLFSSL_EC_KEY *ecdh)
32924
0
{
32925
0
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_set_tmp_ecdh");
32926
32927
0
    if (ctx == NULL || ecdh == NULL)
32928
0
        return BAD_FUNC_ARG;
32929
32930
0
    ctx->ecdhCurveOID = ecdh->group->curve_oid;
32931
32932
0
    return WOLFSSL_SUCCESS;
32933
0
}
32934
#endif
32935
32936
/* Assumes that the session passed in is from the cache. */
32937
int wolfSSL_SSL_CTX_remove_session(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *s)
32938
0
{
32939
0
    WOLFSSL_ENTER("wolfSSL_SSL_CTX_remove_session");
32940
32941
0
    s = ClientSessionToSession(s);
32942
0
    if (ctx == NULL || s == NULL)
32943
0
        return BAD_FUNC_ARG;
32944
32945
0
#ifdef HAVE_EXT_CACHE
32946
0
    if (!ctx->internalCacheOff)
32947
0
#endif
32948
0
    {
32949
        /* Don't remove session just timeout session. */
32950
0
        s->timeout = 0;
32951
0
#ifndef NO_SESSION_CACHE
32952
        /* Clear the timeout in the cache */
32953
0
        {
32954
0
            int row;
32955
0
            int i;
32956
0
            SessionRow* sessRow = NULL;
32957
0
            WOLFSSL_SESSION *cacheSession;
32958
0
            const byte* id;
32959
0
            int ret = 0;
32960
32961
0
            id = s->sessionID;
32962
0
            if (s->haveAltSessionID)
32963
0
                id = s->altSessionID;
32964
32965
0
            row = (int)(HashObject(id, ID_LEN, &ret) % SESSION_ROWS);
32966
0
            if (ret != 0) {
32967
0
                WOLFSSL_MSG("Hash session failed");
32968
0
                return ret;
32969
0
            }
32970
32971
0
            sessRow = &SessionCache[row];
32972
0
            if (SESSION_ROW_LOCK(sessRow) != 0) {
32973
0
                WOLFSSL_MSG("Session row lock failed");
32974
0
                return BAD_MUTEX_E;
32975
0
            }
32976
32977
0
            for (i = 0; i < SESSIONS_PER_ROW && i < sessRow->totalCount; i++) {
32978
0
                cacheSession = &sessRow->Sessions[i];
32979
0
                if (XMEMCMP(id, cacheSession->sessionID, ID_LEN) == 0) {
32980
0
                    if (ctx->method->side != cacheSession->side)
32981
0
                        continue;
32982
0
                    cacheSession->timeout = 0;
32983
#ifdef HAVE_EX_DATA
32984
                    if (cacheSession->ownExData) {
32985
                        /* Most recent version of ex data is in cache. Copy it
32986
                         * over so the user can free it. */
32987
                        XMEMCPY(&s->ex_data, &cacheSession->ex_data,
32988
                                sizeof(WOLFSSL_CRYPTO_EX_DATA));
32989
                    }
32990
                    cacheSession->ownExData = 0; /* We clear below */
32991
                    s->ownExData = 1;
32992
#endif
32993
0
                    break;
32994
0
                }
32995
0
            }
32996
0
            SESSION_ROW_UNLOCK(sessRow);
32997
0
        }
32998
0
#endif
32999
0
    }
33000
33001
0
#if defined(HAVE_EXT_CACHE) || defined(HAVE_EX_DATA)
33002
0
    if (ctx->rem_sess_cb != NULL) {
33003
0
        ctx->rem_sess_cb(ctx, s);
33004
0
    }
33005
0
#endif
33006
33007
0
    return 0;
33008
0
}
33009
33010
#ifndef NO_BIO
33011
BIO *wolfSSL_SSL_get_rbio(const WOLFSSL *s)
33012
0
{
33013
0
    WOLFSSL_ENTER("wolfSSL_SSL_get_rbio");
33014
    /* Nginx sets the buffer size if the read BIO is different to write BIO.
33015
     * The setting buffer size doesn't do anything so return NULL for both.
33016
     */
33017
0
    if (s == NULL)
33018
0
        return NULL;
33019
33020
0
    return s->biord;
33021
0
}
33022
BIO *wolfSSL_SSL_get_wbio(const WOLFSSL *s)
33023
0
{
33024
0
    WOLFSSL_ENTER("wolfSSL_SSL_get_wbio");
33025
0
    (void)s;
33026
    /* Nginx sets the buffer size if the read BIO is different to write BIO.
33027
     * The setting buffer size doesn't do anything so return NULL for both.
33028
     */
33029
0
    if (s == NULL)
33030
0
        return NULL;
33031
33032
0
    return s->biowr;
33033
0
}
33034
#endif /* !NO_BIO */
33035
33036
int wolfSSL_SSL_do_handshake(WOLFSSL *s)
33037
0
{
33038
0
    WOLFSSL_ENTER("wolfSSL_SSL_do_handshake");
33039
33040
0
    if (s == NULL)
33041
0
        return WOLFSSL_FAILURE;
33042
33043
0
    if (s->options.side == WOLFSSL_CLIENT_END) {
33044
0
    #ifndef NO_WOLFSSL_CLIENT
33045
0
        return wolfSSL_connect(s);
33046
    #else
33047
        WOLFSSL_MSG("Client not compiled in");
33048
        return WOLFSSL_FAILURE;
33049
    #endif
33050
0
    }
33051
33052
0
#ifndef NO_WOLFSSL_SERVER
33053
0
    return wolfSSL_accept(s);
33054
#else
33055
    WOLFSSL_MSG("Server not compiled in");
33056
    return WOLFSSL_FAILURE;
33057
#endif
33058
0
}
33059
33060
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
33061
int wolfSSL_SSL_in_init(const WOLFSSL *ssl)
33062
#else
33063
int wolfSSL_SSL_in_init(WOLFSSL *ssl)
33064
#endif
33065
0
{
33066
0
    WOLFSSL_ENTER("SSL_in_init");
33067
33068
0
    if (ssl == NULL)
33069
0
        return WOLFSSL_FAILURE;
33070
33071
0
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
33072
0
        return ssl->options.connectState < SECOND_REPLY_DONE;
33073
0
    }
33074
0
    return ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
33075
0
}
33076
33077
int wolfSSL_SSL_in_connect_init(WOLFSSL* ssl)
33078
0
{
33079
0
    WOLFSSL_ENTER("SSL_connect_init");
33080
33081
0
    if (ssl == NULL)
33082
0
        return WOLFSSL_FAILURE;
33083
33084
0
    if (ssl->options.side == WOLFSSL_CLIENT_END) {
33085
0
        return ssl->options.connectState > CONNECT_BEGIN &&
33086
0
            ssl->options.connectState < SECOND_REPLY_DONE;
33087
0
    }
33088
33089
0
    return ssl->options.acceptState > ACCEPT_BEGIN &&
33090
0
        ssl->options.acceptState < ACCEPT_THIRD_REPLY_DONE;
33091
0
}
33092
33093
#ifndef NO_SESSION_CACHE
33094
33095
WOLFSSL_SESSION *wolfSSL_SSL_get0_session(const WOLFSSL *ssl)
33096
0
{
33097
0
    WOLFSSL_ENTER("wolfSSL_SSL_get0_session");
33098
33099
0
    return ssl->session;
33100
0
}
33101
33102
#endif /* NO_SESSION_CACHE */
33103
33104
#ifndef NO_BIO
33105
int wolfSSL_a2i_ASN1_INTEGER(WOLFSSL_BIO *bio, WOLFSSL_ASN1_INTEGER *asn1,
33106
        char *buf, int size)
33107
0
{
33108
0
    int readNextLine;
33109
0
    int lineLen;
33110
0
    int len;
33111
0
    byte isNumCheck;
33112
0
    word32 outLen;
33113
0
    const int extraTagSz = MAX_LENGTH_SZ + 1;
33114
0
    byte intTag[MAX_LENGTH_SZ + 1];
33115
0
    int idx = 0;
33116
33117
0
    WOLFSSL_ENTER("wolfSSL_a2i_ASN1_INTEGER");
33118
33119
0
    if (!bio || !asn1 || !buf || size <= 0) {
33120
0
        WOLFSSL_MSG("Bad parameter");
33121
0
        return WOLFSSL_FAILURE;
33122
0
    }
33123
33124
    /* Reset asn1 */
33125
0
    if (asn1->isDynamic && asn1->data) {
33126
0
        XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
33127
0
    }
33128
0
    XMEMSET(asn1->intData, 0, WOLFSSL_ASN1_INTEGER_MAX);
33129
0
    asn1->data = asn1->intData;
33130
0
    asn1->isDynamic = 0;
33131
0
    asn1->length = 0;
33132
0
    asn1->negative = 0;
33133
0
    asn1->type = V_ASN1_INTEGER;
33134
33135
0
    lineLen = wolfSSL_BIO_gets(bio, buf, size);
33136
0
    do {
33137
0
        readNextLine = 0;
33138
0
        if (lineLen <= 0) {
33139
0
            WOLFSSL_MSG("wolfSSL_BIO_gets error");
33140
0
            return WOLFSSL_FAILURE;
33141
0
        }
33142
0
        while (lineLen && (buf[lineLen-1] == '\n' || buf[lineLen-1] == '\r'))
33143
0
            lineLen--;
33144
0
        if (buf[lineLen-1] == '\\')
33145
0
            readNextLine = 1;
33146
        /* Ignore none-hex chars at the end of the line */
33147
0
        outLen = 1;
33148
0
        while (lineLen && Base16_Decode((byte*)buf + lineLen - 1, 1,
33149
0
                &isNumCheck, &outLen) == ASN_INPUT_E)
33150
0
            lineLen--;
33151
0
        if (!lineLen || lineLen % 2) {
33152
0
            WOLFSSL_MSG("Invalid line length");
33153
0
            return WOLFSSL_FAILURE;
33154
0
        }
33155
0
        len = asn1->length + (lineLen/2);
33156
        /* Check if it will fit in static memory and
33157
         * save space for the ASN tag in front */
33158
0
        if (len > (int)(WOLFSSL_ASN1_INTEGER_MAX - extraTagSz)) {
33159
            /* Allocate mem for data */
33160
0
            if (asn1->isDynamic) {
33161
0
                byte* tmp = (byte*)XREALLOC(asn1->data, len + extraTagSz, NULL,
33162
0
                        DYNAMIC_TYPE_OPENSSL);
33163
0
                if (!tmp) {
33164
0
                    WOLFSSL_MSG("realloc error");
33165
0
                    return WOLFSSL_FAILURE;
33166
0
                }
33167
0
                asn1->data = tmp;
33168
0
            }
33169
0
            else {
33170
                /* Up to this point asn1->data pointed to asn1->intData.
33171
                 * Now that the size has grown larger than intData can handle
33172
                 * the asn1 structure moves to a dynamic type with isDynamic
33173
                 * flag being set and asn1->data being malloc'd. */
33174
0
                asn1->data = (byte*)XMALLOC(len + extraTagSz, NULL,
33175
0
                        DYNAMIC_TYPE_OPENSSL);
33176
0
                if (!asn1->data) {
33177
0
                    WOLFSSL_MSG("malloc error");
33178
0
                    return WOLFSSL_FAILURE;
33179
0
                }
33180
0
                asn1->isDynamic = 1;
33181
0
                XMEMCPY(asn1->data, asn1->intData, asn1->length);
33182
0
            }
33183
0
        }
33184
0
        len = lineLen/2;
33185
0
        if (Base16_Decode((byte*)buf, lineLen, asn1->data + asn1->length,
33186
0
                (word32*)&len) != 0) {
33187
0
            WOLFSSL_MSG("Base16_Decode error");
33188
0
            return WOLFSSL_FAILURE;
33189
0
        }
33190
0
        asn1->length += len;
33191
0
    } while (readNextLine);
33192
33193
    /* Write ASN tag */
33194
0
    idx = SetASNInt(asn1->length, asn1->data[0], intTag);
33195
0
    XMEMMOVE(asn1->data + idx, asn1->data, asn1->length);
33196
0
    XMEMCPY(asn1->data, intTag, idx);
33197
0
    asn1->dataMax = asn1->length += idx;
33198
33199
0
    return WOLFSSL_SUCCESS;
33200
0
}
33201
33202
int wolfSSL_i2a_ASN1_INTEGER(BIO *bp, const WOLFSSL_ASN1_INTEGER *a)
33203
0
{
33204
0
    word32 idx = 1;
33205
0
    int len = 0;
33206
0
    byte buf[512];
33207
0
    word32 bufLen = 512;
33208
33209
0
    WOLFSSL_ENTER("wolfSSL_i2a_ASN1_INTEGER");
33210
33211
0
    if (bp == NULL || a == NULL)
33212
0
        return WOLFSSL_FAILURE;
33213
33214
    /* Skip ASN.1 INTEGER (type) byte. */
33215
0
    if (a->data[idx] == 0x80 || /* Indefinite length, can't determine length */
33216
0
            GetLength(a->data, &idx, &len, a->length) < 0) {
33217
0
        return 0;
33218
0
    }
33219
33220
    /* Zero length integer is the value zero. */
33221
0
    if (len == 0) {
33222
0
        return wolfSSL_BIO_write(bp, "00", 2);
33223
0
    }
33224
33225
0
    if (Base16_Encode(a->data + idx, len, buf, &bufLen) != 0 ||
33226
0
            bufLen == 0) {
33227
0
        return 0;
33228
0
    }
33229
33230
0
    return wolfSSL_BIO_write(bp, buf, bufLen - 1); /* Don't write out NULL char */
33231
0
}
33232
#endif /* !NO_BIO */
33233
33234
33235
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER)
33236
/* Expected return values from implementations of OpenSSL ticket key callback.
33237
 */
33238
#define TICKET_KEY_CB_RET_FAILURE    (-1)
33239
#define TICKET_KEY_CB_RET_NOT_FOUND   0
33240
0
#define TICKET_KEY_CB_RET_OK          1
33241
0
#define TICKET_KEY_CB_RET_RENEW       2
33242
33243
/* Implementation of session ticket encryption/decryption using OpenSSL
33244
 * callback to initialize the cipher and HMAC.
33245
 *
33246
 * ssl           The SSL/TLS object.
33247
 * keyName       The key name - used to identify the key to be used.
33248
 * iv            The IV to use.
33249
 * mac           The MAC of the encrypted data.
33250
 * enc           Encrypt ticket.
33251
 * encTicket     The ticket data.
33252
 * encTicketLen  The length of the ticket data.
33253
 * encLen        The encrypted/decrypted ticket length - output length.
33254
 * ctx           Ignored. Application specific data.
33255
 * returns WOLFSSL_TICKET_RET_OK to indicate success,
33256
 *         WOLFSSL_TICKET_RET_CREATE if a new ticket is required and
33257
 *         WOLFSSL_TICKET_RET_FATAL on error.
33258
 */
33259
static int wolfSSL_TicketKeyCb(WOLFSSL* ssl,
33260
        unsigned char keyName[WOLFSSL_TICKET_NAME_SZ],
33261
        unsigned char iv[WOLFSSL_TICKET_IV_SZ],
33262
        unsigned char mac[WOLFSSL_TICKET_MAC_SZ],
33263
        int enc, unsigned char* encTicket,
33264
        int encTicketLen, int* encLen, void* ctx)
33265
0
{
33266
0
    byte                    digest[WC_MAX_DIGEST_SIZE];
33267
0
#ifdef WOLFSSL_SMALL_STACK
33268
0
    WOLFSSL_EVP_CIPHER_CTX  *evpCtx;
33269
#else
33270
    WOLFSSL_EVP_CIPHER_CTX  evpCtx[1];
33271
#endif
33272
0
    WOLFSSL_HMAC_CTX        hmacCtx;
33273
0
    unsigned int            mdSz = 0;
33274
0
    int                     len = 0;
33275
0
    int                     ret = WOLFSSL_TICKET_RET_FATAL;
33276
0
    int                     res;
33277
0
    int                     totalSz = 0;
33278
33279
0
    (void)ctx;
33280
33281
0
    WOLFSSL_ENTER("wolfSSL_TicketKeyCb");
33282
33283
0
    if (ssl == NULL || ssl->ctx == NULL || ssl->ctx->ticketEncWrapCb == NULL) {
33284
0
        WOLFSSL_MSG("Bad parameter");
33285
0
        return WOLFSSL_TICKET_RET_FATAL;
33286
0
    }
33287
33288
0
#ifdef WOLFSSL_SMALL_STACK
33289
0
    evpCtx = (WOLFSSL_EVP_CIPHER_CTX *)XMALLOC(sizeof(*evpCtx), ssl->heap,
33290
0
                                               DYNAMIC_TYPE_TMP_BUFFER);
33291
0
    if (evpCtx == NULL) {
33292
0
        WOLFSSL_MSG("out of memory");
33293
0
        return WOLFSSL_TICKET_RET_FATAL;
33294
0
    }
33295
0
#endif
33296
33297
    /* Initialize the cipher and HMAC. */
33298
0
    wolfSSL_EVP_CIPHER_CTX_init(evpCtx);
33299
0
    if (wolfSSL_HMAC_CTX_Init(&hmacCtx) != WOLFSSL_SUCCESS) {
33300
0
        WOLFSSL_MSG("wolfSSL_HMAC_CTX_Init error");
33301
0
#ifdef WOLFSSL_SMALL_STACK
33302
0
        XFREE(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
33303
0
#endif
33304
0
        return WOLFSSL_TICKET_RET_FATAL;
33305
0
    }
33306
0
    res = ssl->ctx->ticketEncWrapCb(ssl, keyName,
33307
0
            iv, evpCtx, &hmacCtx, enc);
33308
0
    if (res != TICKET_KEY_CB_RET_OK && res != TICKET_KEY_CB_RET_RENEW) {
33309
0
        WOLFSSL_MSG("Ticket callback error");
33310
0
        ret = WOLFSSL_TICKET_RET_FATAL;
33311
0
        goto end;
33312
0
    }
33313
33314
0
    if (wolfSSL_HMAC_size(&hmacCtx) > WOLFSSL_TICKET_MAC_SZ) {
33315
0
        WOLFSSL_MSG("Ticket cipher MAC size error");
33316
0
        goto end;
33317
0
    }
33318
33319
0
    if (enc)
33320
0
    {
33321
        /* Encrypt in place. */
33322
0
        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
33323
0
                                      encTicket, encTicketLen))
33324
0
            goto end;
33325
0
        totalSz = len;
33326
0
        if (totalSz > *encLen)
33327
0
            goto end;
33328
0
        if (!wolfSSL_EVP_EncryptFinal(evpCtx, &encTicket[len], &len))
33329
0
            goto end;
33330
        /* Total length of encrypted data. */
33331
0
        totalSz += len;
33332
0
        if (totalSz > *encLen)
33333
0
            goto end;
33334
33335
        /* HMAC the encrypted data into the parameter 'mac'. */
33336
0
        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, totalSz))
33337
0
            goto end;
33338
0
        if (!wolfSSL_HMAC_Final(&hmacCtx, mac, &mdSz))
33339
0
            goto end;
33340
0
    }
33341
0
    else
33342
0
    {
33343
        /* HMAC the encrypted data and compare it to the passed in data. */
33344
0
        if (!wolfSSL_HMAC_Update(&hmacCtx, encTicket, encTicketLen))
33345
0
            goto end;
33346
0
        if (!wolfSSL_HMAC_Final(&hmacCtx, digest, &mdSz))
33347
0
            goto end;
33348
0
        if (XMEMCMP(mac, digest, mdSz) != 0)
33349
0
            goto end;
33350
33351
        /* Decrypt the ticket data in place. */
33352
0
        if (!wolfSSL_EVP_CipherUpdate(evpCtx, encTicket, &len,
33353
0
                                      encTicket, encTicketLen))
33354
0
            goto end;
33355
0
        totalSz = len;
33356
0
        if (totalSz > encTicketLen)
33357
0
            goto end;
33358
0
        if (!wolfSSL_EVP_DecryptFinal(evpCtx, &encTicket[len], &len))
33359
0
            goto end;
33360
        /* Total length of decrypted data. */
33361
0
        totalSz += len;
33362
0
        if (totalSz > encTicketLen)
33363
0
            goto end;
33364
0
    }
33365
0
    *encLen = totalSz;
33366
33367
0
    if (res == TICKET_KEY_CB_RET_RENEW && !IsAtLeastTLSv1_3(ssl->version)
33368
0
            && !enc)
33369
0
        ret = WOLFSSL_TICKET_RET_CREATE;
33370
0
    else
33371
0
        ret = WOLFSSL_TICKET_RET_OK;
33372
0
end:
33373
33374
0
    (void)wc_HmacFree(&hmacCtx.hmac);
33375
0
#ifdef WOLFSSL_SMALL_STACK
33376
0
    XFREE(evpCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
33377
0
#endif
33378
33379
0
    return ret;
33380
0
}
33381
33382
/* Set the callback to use when encrypting/decrypting tickets.
33383
 *
33384
 * ctx  The SSL/TLS context object.
33385
 * cb   The OpenSSL session ticket callback.
33386
 * returns WOLFSSL_SUCCESS to indicate success.
33387
 */
33388
int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *ctx, ticketCompatCb cb)
33389
0
{
33390
33391
    /* Set the ticket encryption callback to be a wrapper around OpenSSL
33392
     * callback.
33393
     */
33394
0
    ctx->ticketEncCb = wolfSSL_TicketKeyCb;
33395
0
    ctx->ticketEncWrapCb = cb;
33396
33397
0
    return WOLFSSL_SUCCESS;
33398
0
}
33399
33400
#endif /* HAVE_SESSION_TICKET */
33401
33402
#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY ||
33403
    OPENSSL_EXTRA || HAVE_LIGHTY */
33404
33405
#if defined(HAVE_SESSION_TICKET) && !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && \
33406
    !defined(NO_WOLFSSL_SERVER)
33407
/* Serialize the session ticket encryption keys.
33408
 *
33409
 * @param [in]  ctx     SSL/TLS context object.
33410
 * @param [in]  keys    Buffer to hold session ticket keys.
33411
 * @param [in]  keylen  Length of buffer.
33412
 * @return  WOLFSSL_SUCCESS on success.
33413
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
33414
 *          correct length.
33415
 */
33416
long wolfSSL_CTX_get_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
33417
     unsigned char *keys, int keylen)
33418
0
{
33419
0
    if (ctx == NULL || keys == NULL) {
33420
0
        return WOLFSSL_FAILURE;
33421
0
    }
33422
0
    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
33423
0
        return WOLFSSL_FAILURE;
33424
0
    }
33425
33426
0
    XMEMCPY(keys, ctx->ticketKeyCtx.name, WOLFSSL_TICKET_NAME_SZ);
33427
0
    keys += WOLFSSL_TICKET_NAME_SZ;
33428
0
    XMEMCPY(keys, ctx->ticketKeyCtx.key[0], WOLFSSL_TICKET_KEY_SZ);
33429
0
    keys += WOLFSSL_TICKET_KEY_SZ;
33430
0
    XMEMCPY(keys, ctx->ticketKeyCtx.key[1], WOLFSSL_TICKET_KEY_SZ);
33431
0
    keys += WOLFSSL_TICKET_KEY_SZ;
33432
0
    c32toa(ctx->ticketKeyCtx.expirary[0], keys);
33433
0
    keys += OPAQUE32_LEN;
33434
0
    c32toa(ctx->ticketKeyCtx.expirary[1], keys);
33435
33436
0
    return WOLFSSL_SUCCESS;
33437
0
}
33438
33439
/* Deserialize the session ticket encryption keys.
33440
 *
33441
 * @param [in]  ctx     SSL/TLS context object.
33442
 * @param [in]  keys    Session ticket keys.
33443
 * @param [in]  keylen  Length of data.
33444
 * @return  WOLFSSL_SUCCESS on success.
33445
 * @return  WOLFSSL_FAILURE when ctx is NULL, keys is NULL or keylen is not the
33446
 *          correct length.
33447
 */
33448
long wolfSSL_CTX_set_tlsext_ticket_keys(WOLFSSL_CTX *ctx,
33449
     unsigned char *keys, int keylen)
33450
0
{
33451
0
    if (ctx == NULL || keys == NULL) {
33452
0
        return WOLFSSL_FAILURE;
33453
0
    }
33454
0
    if (keylen != WOLFSSL_TICKET_KEYS_SZ) {
33455
0
        return WOLFSSL_FAILURE;
33456
0
    }
33457
33458
0
    XMEMCPY(ctx->ticketKeyCtx.name, keys, WOLFSSL_TICKET_NAME_SZ);
33459
0
    keys += WOLFSSL_TICKET_NAME_SZ;
33460
0
    XMEMCPY(ctx->ticketKeyCtx.key[0], keys, WOLFSSL_TICKET_KEY_SZ);
33461
0
    keys += WOLFSSL_TICKET_KEY_SZ;
33462
0
    XMEMCPY(ctx->ticketKeyCtx.key[1], keys, WOLFSSL_TICKET_KEY_SZ);
33463
0
    keys += WOLFSSL_TICKET_KEY_SZ;
33464
0
    ato32(keys, &ctx->ticketKeyCtx.expirary[0]);
33465
0
    keys += OPAQUE32_LEN;
33466
0
    ato32(keys, &ctx->ticketKeyCtx.expirary[1]);
33467
33468
0
    return WOLFSSL_SUCCESS;
33469
0
}
33470
#endif
33471
33472
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
33473
#ifdef HAVE_OCSP
33474
/* Not an OpenSSL API. */
33475
int wolfSSL_get_ocsp_response(WOLFSSL* ssl, byte** response)
33476
0
{
33477
0
    *response = ssl->ocspResp;
33478
0
    return ssl->ocspRespSz;
33479
0
}
33480
33481
/* Not an OpenSSL API. */
33482
char* wolfSSL_get_ocsp_url(WOLFSSL* ssl)
33483
0
{
33484
0
    return ssl->url;
33485
0
}
33486
33487
/* Not an OpenSSL API. */
33488
int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url)
33489
0
{
33490
0
    if (ssl == NULL)
33491
0
        return WOLFSSL_FAILURE;
33492
33493
0
    ssl->url = url;
33494
0
    return WOLFSSL_SUCCESS;
33495
0
}
33496
#endif /* OCSP */
33497
#endif /* OPENSSL_ALL || WOLFSSL_NGINX  || WOLFSSL_HAPROXY */
33498
33499
#if defined(HAVE_OCSP) && !defined(NO_ASN_TIME)
33500
int wolfSSL_get_ocsp_producedDate(
33501
    WOLFSSL *ssl,
33502
    byte *producedDate,
33503
    size_t producedDate_space,
33504
    int *producedDateFormat)
33505
0
{
33506
0
    if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
33507
0
        (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
33508
0
        return BAD_FUNC_ARG;
33509
33510
0
    if ((producedDate == NULL) || (producedDateFormat == NULL))
33511
0
        return BAD_FUNC_ARG;
33512
33513
0
    if (XSTRLEN((char *)ssl->ocspProducedDate) >= producedDate_space)
33514
0
        return BUFFER_E;
33515
33516
0
    XSTRNCPY((char *)producedDate, (const char *)ssl->ocspProducedDate, producedDate_space);
33517
0
    *producedDateFormat = ssl->ocspProducedDateFormat;
33518
33519
0
    return 0;
33520
0
}
33521
33522
0
int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, struct tm *produced_tm) {
33523
0
    int idx = 0;
33524
33525
0
    if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) &&
33526
0
        (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME))
33527
0
        return BAD_FUNC_ARG;
33528
33529
0
    if (produced_tm == NULL)
33530
0
        return BAD_FUNC_ARG;
33531
33532
0
    if (ExtractDate(ssl->ocspProducedDate,
33533
0
            (unsigned char)ssl->ocspProducedDateFormat, produced_tm, &idx))
33534
0
        return 0;
33535
0
    else
33536
0
        return ASN_PARSE_E;
33537
0
}
33538
#endif
33539
33540
33541
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
33542
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
33543
int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain)
33544
0
{
33545
0
    word32         idx;
33546
0
    word32         length;
33547
0
    WOLFSSL_STACK* node;
33548
0
    WOLFSSL_STACK* last = NULL;
33549
33550
0
    if (ctx == NULL || chain == NULL) {
33551
0
        chain = NULL;
33552
0
        return WOLFSSL_FAILURE;
33553
0
    }
33554
0
    if (ctx->x509Chain != NULL) {
33555
0
        *chain = ctx->x509Chain;
33556
0
        return WOLFSSL_SUCCESS;
33557
0
    }
33558
33559
    /* If there are no chains then success! */
33560
0
    *chain = NULL;
33561
0
    if (ctx->certChain == NULL || ctx->certChain->length == 0) {
33562
0
        return WOLFSSL_SUCCESS;
33563
0
    }
33564
33565
    /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
33566
0
    for (idx = 0; idx < ctx->certChain->length; ) {
33567
0
        node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
33568
0
                                       DYNAMIC_TYPE_OPENSSL);
33569
0
        if (node == NULL)
33570
0
            return WOLFSSL_FAILURE;
33571
0
        node->next = NULL;
33572
33573
        /* 3 byte length | X509 DER data */
33574
0
        ato24(ctx->certChain->buffer + idx, &length);
33575
0
        idx += 3;
33576
33577
        /* Create a new X509 from DER encoded data. */
33578
0
        node->data.x509 = wolfSSL_X509_d2i(NULL, ctx->certChain->buffer + idx,
33579
0
            length);
33580
0
        if (node->data.x509 == NULL) {
33581
0
            XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
33582
            /* Return as much of the chain as we created. */
33583
0
            ctx->x509Chain = *chain;
33584
0
            return WOLFSSL_FAILURE;
33585
0
        }
33586
0
        idx += length;
33587
33588
        /* Add object to the end of the stack. */
33589
0
        if (last == NULL) {
33590
0
            node->num = 1;
33591
0
            *chain = node;
33592
0
        }
33593
0
        else {
33594
0
            (*chain)->num++;
33595
0
            last->next = node;
33596
0
        }
33597
33598
0
        last = node;
33599
0
    }
33600
33601
0
    ctx->x509Chain = *chain;
33602
33603
0
    return WOLFSSL_SUCCESS;
33604
0
}
33605
33606
int wolfSSL_CTX_get_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb* cb)
33607
0
{
33608
0
    if (ctx == NULL || ctx->cm == NULL || cb == NULL)
33609
0
        return WOLFSSL_FAILURE;
33610
33611
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
33612
                               ||  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
33613
    if (ctx->cm->ocsp_stapling == NULL)
33614
        return WOLFSSL_FAILURE;
33615
33616
    *cb = ctx->cm->ocsp_stapling->statusCb;
33617
#else
33618
0
    (void)cb;
33619
0
    *cb = NULL;
33620
0
#endif
33621
33622
0
    return WOLFSSL_SUCCESS;
33623
33624
0
}
33625
33626
int wolfSSL_CTX_set_tlsext_status_cb(WOLFSSL_CTX* ctx, tlsextStatusCb cb)
33627
0
{
33628
0
    if (ctx == NULL || ctx->cm == NULL)
33629
0
        return WOLFSSL_FAILURE;
33630
33631
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
33632
                               ||  defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2))
33633
    /* Ensure stapling is on for callback to be used. */
33634
    wolfSSL_CTX_EnableOCSPStapling(ctx);
33635
33636
    if (ctx->cm->ocsp_stapling == NULL)
33637
        return WOLFSSL_FAILURE;
33638
33639
    ctx->cm->ocsp_stapling->statusCb = cb;
33640
#else
33641
0
    (void)cb;
33642
0
#endif
33643
33644
0
    return WOLFSSL_SUCCESS;
33645
0
}
33646
33647
int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx,
33648
        WOLF_STACK_OF(WOLFSSL_X509) **sk)
33649
0
{
33650
0
    WOLFSSL_ENTER("wolfSSL_CTX_get0_chain_certs");
33651
0
    if (ctx == NULL || sk == NULL) {
33652
0
        WOLFSSL_MSG("Bad parameter");
33653
0
        return WOLFSSL_FAILURE;
33654
0
    }
33655
0
    *sk = ctx->x509Chain;
33656
0
    return WOLFSSL_SUCCESS;
33657
0
}
33658
33659
#ifdef KEEP_OUR_CERT
33660
int wolfSSL_get0_chain_certs(WOLFSSL *ssl,
33661
        WOLF_STACK_OF(WOLFSSL_X509) **sk)
33662
0
{
33663
0
    WOLFSSL_ENTER("wolfSSL_get0_chain_certs");
33664
0
    if (ssl == NULL || sk == NULL) {
33665
0
        WOLFSSL_MSG("Bad parameter");
33666
0
        return WOLFSSL_FAILURE;
33667
0
    }
33668
0
    *sk = ssl->ourCertChain;
33669
0
    return WOLFSSL_SUCCESS;
33670
0
}
33671
#endif
33672
33673
WOLF_STACK_OF(WOLFSSL_STRING)* wolfSSL_sk_WOLFSSL_STRING_new(void)
33674
0
{
33675
0
    WOLF_STACK_OF(WOLFSSL_STRING)* ret = wolfSSL_sk_new_node(NULL);
33676
33677
0
    if (ret) {
33678
0
        ret->type = STACK_TYPE_STRING;
33679
0
    }
33680
33681
0
    return ret;
33682
0
}
33683
33684
void wolfSSL_WOLFSSL_STRING_free(WOLFSSL_STRING s)
33685
0
{
33686
0
    WOLFSSL_ENTER("wolfSSL_WOLFSSL_STRING_free");
33687
33688
0
    if (s != NULL)
33689
0
        XFREE(s, NULL, DYNAMIC_TYPE_OPENSSL);
33690
0
}
33691
33692
void wolfSSL_sk_WOLFSSL_STRING_free(WOLF_STACK_OF(WOLFSSL_STRING)* sk)
33693
0
{
33694
0
    WOLFSSL_STACK* tmp;
33695
0
    WOLFSSL_ENTER("wolfSSL_sk_WOLFSSL_STRING_free");
33696
33697
0
    if (sk == NULL)
33698
0
        return;
33699
33700
    /* parse through stack freeing each node */
33701
0
    while (sk) {
33702
0
        tmp = sk->next;
33703
0
        XFREE(sk->data.string, NULL, DYNAMIC_TYPE_OPENSSL);
33704
0
        XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL);
33705
0
        sk = tmp;
33706
0
    }
33707
0
}
33708
33709
WOLFSSL_STRING wolfSSL_sk_WOLFSSL_STRING_value(WOLF_STACK_OF(WOLFSSL_STRING)* strings,
33710
    int idx)
33711
0
{
33712
0
    for (; idx > 0 && strings != NULL; idx--)
33713
0
        strings = strings->next;
33714
0
    if (strings == NULL)
33715
0
        return NULL;
33716
0
    return strings->data.string;
33717
0
}
33718
33719
int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings)
33720
0
{
33721
0
    if (strings)
33722
0
        return (int)strings->num;
33723
0
    return 0;
33724
0
}
33725
33726
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
33727
33728
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \
33729
    defined(WOLFSSL_HAPROXY) || defined(HAVE_LIGHTY) || \
33730
    defined(WOLFSSL_QUIC)
33731
#ifdef HAVE_ALPN
33732
void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data,
33733
                                unsigned int *len)
33734
{
33735
    word16 nameLen;
33736
33737
    if (ssl != NULL && data != NULL && len != NULL) {
33738
        TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen);
33739
        *len = nameLen;
33740
    }
33741
}
33742
33743
int wolfSSL_select_next_proto(unsigned char **out, unsigned char *outLen,
33744
                              const unsigned char *in, unsigned int inLen,
33745
                              const unsigned char *clientNames,
33746
                              unsigned int clientLen)
33747
{
33748
    unsigned int i, j;
33749
    byte lenIn, lenClient;
33750
33751
    if (out == NULL || outLen == NULL || in == NULL || clientNames == NULL)
33752
        return OPENSSL_NPN_UNSUPPORTED;
33753
33754
    for (i = 0; i < inLen; i += lenIn) {
33755
        lenIn = in[i++];
33756
        for (j = 0; j < clientLen; j += lenClient) {
33757
            lenClient = clientNames[j++];
33758
33759
            if (lenIn != lenClient)
33760
                continue;
33761
33762
            if (XMEMCMP(in + i, clientNames + j, lenIn) == 0) {
33763
                *out = (unsigned char *)(in + i);
33764
                *outLen = lenIn;
33765
                return OPENSSL_NPN_NEGOTIATED;
33766
            }
33767
        }
33768
    }
33769
33770
    *out = (unsigned char *)clientNames + 1;
33771
    *outLen = clientNames[0];
33772
    return OPENSSL_NPN_NO_OVERLAP;
33773
}
33774
33775
void wolfSSL_CTX_set_alpn_select_cb(WOLFSSL_CTX *ctx,
33776
                                    int (*cb) (WOLFSSL *ssl,
33777
                                               const unsigned char **out,
33778
                                               unsigned char *outlen,
33779
                                               const unsigned char *in,
33780
                                               unsigned int inlen,
33781
                                               void *arg), void *arg)
33782
{
33783
    if (ctx != NULL) {
33784
        ctx->alpnSelect = cb;
33785
        ctx->alpnSelectArg = arg;
33786
    }
33787
}
33788
33789
void wolfSSL_CTX_set_next_protos_advertised_cb(WOLFSSL_CTX *s,
33790
                                           int (*cb) (WOLFSSL *ssl,
33791
                                                      const unsigned char
33792
                                                      **out,
33793
                                                      unsigned int *outlen,
33794
                                                      void *arg), void *arg)
33795
{
33796
    (void)s;
33797
    (void)cb;
33798
    (void)arg;
33799
    WOLFSSL_STUB("wolfSSL_CTX_set_next_protos_advertised_cb");
33800
}
33801
33802
void wolfSSL_CTX_set_next_proto_select_cb(WOLFSSL_CTX *s,
33803
                                      int (*cb) (WOLFSSL *ssl,
33804
                                                 unsigned char **out,
33805
                                                 unsigned char *outlen,
33806
                                                 const unsigned char *in,
33807
                                                 unsigned int inlen,
33808
                                                 void *arg), void *arg)
33809
{
33810
    (void)s;
33811
    (void)cb;
33812
    (void)arg;
33813
    WOLFSSL_STUB("wolfSSL_CTX_set_next_proto_select_cb");
33814
}
33815
33816
void wolfSSL_get0_next_proto_negotiated(const WOLFSSL *s, const unsigned char **data,
33817
                                    unsigned *len)
33818
{
33819
    (void)s;
33820
    (void)data;
33821
    (void)len;
33822
    WOLFSSL_STUB("wolfSSL_get0_next_proto_negotiated");
33823
}
33824
#endif /* HAVE_ALPN */
33825
33826
#endif /* WOLFSSL_NGINX  / WOLFSSL_HAPROXY */
33827
33828
#ifdef OPENSSL_EXTRA
33829
int wolfSSL_curve_is_disabled(WOLFSSL* ssl, word16 curve_id)
33830
0
{
33831
0
    return (curve_id <= WOLFSSL_ECC_MAX &&
33832
0
            ssl->disabledCurves &&
33833
0
            ssl->disabledCurves & (1 << curve_id));
33834
0
}
33835
#endif
33836
33837
#if defined(OPENSSL_EXTRA) && (defined(HAVE_ECC) || \
33838
    defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))
33839
static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
33840
0
{
33841
0
    int idx, start = 0, len;
33842
0
    word16 curve;
33843
0
    word32 disabled;
33844
0
    char name[MAX_CURVE_NAME_SZ];
33845
33846
    /* Disable all curves so that only the ones the user wants are enabled. */
33847
0
    disabled = 0xFFFFFFFFUL;
33848
0
    for (idx = 1; names[idx-1] != '\0'; idx++) {
33849
0
        if (names[idx] != ':' && names[idx] != '\0')
33850
0
            continue;
33851
33852
0
        len = idx - start;
33853
0
        if (len > MAX_CURVE_NAME_SZ - 1)
33854
0
            return WOLFSSL_FAILURE;
33855
33856
0
        XMEMCPY(name, names + start, len);
33857
0
        name[len] = 0;
33858
33859
0
        if ((XSTRCMP(name, "prime256v1") == 0) ||
33860
0
            (XSTRCMP(name, "secp256r1") == 0) ||
33861
0
            (XSTRCMP(name, "P-256") == 0))
33862
0
        {
33863
0
            curve = WOLFSSL_ECC_SECP256R1;
33864
0
        }
33865
0
        else if ((XSTRCMP(name, "secp384r1") == 0) ||
33866
0
                 (XSTRCMP(name, "P-384") == 0))
33867
0
        {
33868
0
            curve = WOLFSSL_ECC_SECP384R1;
33869
0
        }
33870
0
        else if ((XSTRCMP(name, "secp521r1") == 0) ||
33871
0
                 (XSTRCMP(name, "P-521") == 0))
33872
0
        {
33873
0
            curve = WOLFSSL_ECC_SECP521R1;
33874
0
        }
33875
0
    #ifdef HAVE_CURVE25519
33876
0
        else if (XSTRCMP(name, "X25519") == 0)
33877
0
        {
33878
0
            curve = WOLFSSL_ECC_X25519;
33879
0
        }
33880
0
    #endif
33881
0
    #ifdef HAVE_CURVE448
33882
0
        else if (XSTRCMP(name, "X448") == 0)
33883
0
        {
33884
0
            curve = WOLFSSL_ECC_X448;
33885
0
        }
33886
0
    #endif
33887
0
        else {
33888
0
        #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
33889
0
            int   ret;
33890
0
            const ecc_set_type *eccSet;
33891
33892
0
            ret = wc_ecc_get_curve_idx_from_name(name);
33893
0
            if (ret < 0) {
33894
0
                WOLFSSL_MSG("Could not find name in set");
33895
0
                return WOLFSSL_FAILURE;
33896
0
            }
33897
33898
0
            eccSet = wc_ecc_get_curve_params(ret);
33899
0
            if (eccSet == NULL) {
33900
0
                WOLFSSL_MSG("NULL set returned");
33901
0
                return WOLFSSL_FAILURE;
33902
0
            }
33903
33904
0
            curve = GetCurveByOID(eccSet->oidSum);
33905
        #else
33906
            WOLFSSL_MSG("API not present to search farther using name");
33907
            return WOLFSSL_FAILURE;
33908
        #endif
33909
0
        }
33910
33911
0
        if (curve >= (sizeof(word32) * WOLFSSL_BIT_SIZE)) {
33912
            /* shift left more than size of ctx->disabledCurves causes static
33913
             * analysis report */
33914
0
            WOLFSSL_MSG("curve value is too large for upcoming shift");
33915
0
            return WOLFSSL_FAILURE;
33916
0
        }
33917
33918
0
    #if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT)
33919
        /* set the supported curve so client TLS extension contains only the
33920
         * desired curves */
33921
0
        if ((ssl
33922
0
             && wolfSSL_UseSupportedCurve(ssl, curve) != WOLFSSL_SUCCESS)
33923
0
            || (ctx
33924
0
            && wolfSSL_CTX_UseSupportedCurve(ctx, curve) != WOLFSSL_SUCCESS)) {
33925
0
            WOLFSSL_MSG("Unable to set supported curve");
33926
0
            return WOLFSSL_FAILURE;
33927
0
        }
33928
0
    #endif
33929
33930
        /* Switch the bit to off and therefore is enabled. */
33931
0
        disabled &= ~(1U << curve);
33932
0
        start = idx + 1;
33933
0
    }
33934
33935
0
    if (ssl)
33936
0
        ssl->disabledCurves = disabled;
33937
0
    else
33938
0
        ctx->disabledCurves = disabled;
33939
33940
0
    return WOLFSSL_SUCCESS;
33941
0
}
33942
33943
int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
33944
0
{
33945
0
    if (ctx == NULL || names == NULL) {
33946
0
        WOLFSSL_MSG("ctx or names was NULL");
33947
0
        return WOLFSSL_FAILURE;
33948
0
    }
33949
0
    return set_curves_list(NULL, ctx, names);
33950
0
}
33951
33952
int wolfSSL_set1_curves_list(WOLFSSL* ssl, const char* names)
33953
0
{
33954
0
    if (ssl == NULL || names == NULL) {
33955
0
        WOLFSSL_MSG("ssl or names was NULL");
33956
0
        return WOLFSSL_FAILURE;
33957
0
    }
33958
0
    return set_curves_list(ssl, NULL, names);
33959
0
}
33960
#endif /* OPENSSL_EXTRA && (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) */
33961
33962
#ifdef OPENSSL_EXTRA
33963
/* Sets a callback for when sending and receiving protocol messages.
33964
 * This callback is copied to all WOLFSSL objects created from the ctx.
33965
 *
33966
 * ctx WOLFSSL_CTX structure to set callback in
33967
 * cb  callback to use
33968
 *
33969
 * return WOLFSSL_SUCCESS on success and SSL_FAILURE with error case
33970
 */
33971
int wolfSSL_CTX_set_msg_callback(WOLFSSL_CTX *ctx, SSL_Msg_Cb cb)
33972
0
{
33973
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback");
33974
0
    if (ctx == NULL) {
33975
0
        WOLFSSL_MSG("Null ctx passed in");
33976
0
        return WOLFSSL_FAILURE;
33977
0
    }
33978
33979
0
    ctx->protoMsgCb = cb;
33980
0
    return WOLFSSL_SUCCESS;
33981
0
}
33982
33983
33984
/* Sets a callback for when sending and receiving protocol messages.
33985
 *
33986
 * ssl WOLFSSL structure to set callback in
33987
 * cb  callback to use
33988
 *
33989
 * return WOLFSSL_SUCCESS on success and SSL_FAILURE with error case
33990
 */
33991
int wolfSSL_set_msg_callback(WOLFSSL *ssl, SSL_Msg_Cb cb)
33992
0
{
33993
0
    WOLFSSL_ENTER("wolfSSL_set_msg_callback");
33994
33995
0
    if (ssl == NULL) {
33996
0
        return SSL_FAILURE;
33997
0
    }
33998
33999
0
    if (cb != NULL) {
34000
0
        ssl->toInfoOn = 1;
34001
0
    }
34002
34003
0
    ssl->protoMsgCb = cb;
34004
0
    return WOLFSSL_SUCCESS;
34005
0
}
34006
34007
34008
/* set the user argument to pass to the msg callback when called
34009
 * return WOLFSSL_SUCCESS on success */
34010
int wolfSSL_CTX_set_msg_callback_arg(WOLFSSL_CTX *ctx, void* arg)
34011
0
{
34012
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_msg_callback_arg");
34013
0
    if (ctx == NULL) {
34014
0
        WOLFSSL_MSG("Null WOLFSSL_CTX passed in");
34015
0
        return WOLFSSL_FAILURE;
34016
0
    }
34017
34018
0
    ctx->protoMsgCtx = arg;
34019
0
    return WOLFSSL_SUCCESS;
34020
0
}
34021
34022
34023
int wolfSSL_set_msg_callback_arg(WOLFSSL *ssl, void* arg)
34024
0
{
34025
0
    WOLFSSL_ENTER("wolfSSL_set_msg_callback_arg");
34026
0
    if (ssl == NULL)
34027
0
        return WOLFSSL_FAILURE;
34028
34029
0
    ssl->protoMsgCtx = arg;
34030
0
    return WOLFSSL_SUCCESS;
34031
0
}
34032
34033
void *wolfSSL_OPENSSL_memdup(const void *data, size_t siz, const char* file, int line)
34034
0
{
34035
0
    void *ret;
34036
0
    (void)file;
34037
0
    (void)line;
34038
34039
0
    if (data == NULL || siz >= INT_MAX)
34040
0
        return NULL;
34041
34042
0
    ret = OPENSSL_malloc(siz);
34043
0
    if (ret == NULL) {
34044
0
        return NULL;
34045
0
    }
34046
0
    return XMEMCPY(ret, data, siz);
34047
0
}
34048
34049
void wolfSSL_OPENSSL_cleanse(void *ptr, size_t len)
34050
0
{
34051
0
    if (ptr)
34052
0
        ForceZero(ptr, (word32)len);
34053
0
}
34054
34055
int wolfSSL_CTX_set_alpn_protos(WOLFSSL_CTX *ctx, const unsigned char *p,
34056
                            unsigned int p_len)
34057
0
{
34058
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_alpn_protos");
34059
0
    if (ctx == NULL)
34060
0
        return BAD_FUNC_ARG;
34061
0
    if (ctx->alpn_cli_protos != NULL) {
34062
0
        XFREE((void*)ctx->alpn_cli_protos, ctx->heap, DYNAMIC_TYPE_OPENSSL);
34063
0
    }
34064
34065
0
    ctx->alpn_cli_protos = (const unsigned char*)XMALLOC(p_len,
34066
0
        ctx->heap, DYNAMIC_TYPE_OPENSSL);
34067
0
    if (ctx->alpn_cli_protos == NULL) {
34068
0
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34069
        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34070
         * the function reverses the return value convention.
34071
         */
34072
0
        return 1;
34073
#else
34074
        return WOLFSSL_FAILURE;
34075
#endif
34076
0
    }
34077
0
    XMEMCPY((void*)ctx->alpn_cli_protos, p, p_len);
34078
0
    ctx->alpn_cli_protos_len = p_len;
34079
34080
0
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34081
    /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34082
     * the function reverses the return value convention.
34083
     */
34084
0
    return 0;
34085
#else
34086
    return WOLFSSL_SUCCESS;
34087
#endif
34088
0
}
34089
34090
34091
#ifdef HAVE_ALPN
34092
#ifndef NO_BIO
34093
/* Sets the ALPN extension protos
34094
 *
34095
 * example format is
34096
 * unsigned char p[] = {
34097
 *      8, 'h', 't', 't', 'p', '/', '1', '.', '1'
34098
 * };
34099
 *
34100
 * returns WOLFSSL_SUCCESS on success */
34101
int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
34102
        const unsigned char* p, unsigned int p_len)
34103
{
34104
    WOLFSSL_BIO* bio;
34105
    char* pt;
34106
34107
    unsigned int sz;
34108
    unsigned int idx = 0;
34109
    int alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
34110
    WOLFSSL_ENTER("wolfSSL_set_alpn_protos");
34111
34112
    if (ssl == NULL || p_len <= 1) {
34113
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34114
        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34115
         * the function reverses the return value convention.
34116
         */
34117
        return 1;
34118
#else
34119
        return WOLFSSL_FAILURE;
34120
#endif
34121
    }
34122
34123
    bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
34124
    if (bio == NULL) {
34125
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34126
        /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34127
         * the function reverses the return value convention.
34128
         */
34129
        return 1;
34130
#else
34131
        return WOLFSSL_FAILURE;
34132
#endif
34133
    }
34134
34135
    /* convert into comma separated list */
34136
    while (idx < p_len - 1) {
34137
        unsigned int i;
34138
34139
        sz = p[idx++];
34140
        if (idx + sz > p_len) {
34141
            WOLFSSL_MSG("Bad list format");
34142
            wolfSSL_BIO_free(bio);
34143
    #if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34144
            /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34145
             * the function reverses the return value convention.
34146
             */
34147
            return 1;
34148
    #else
34149
            return WOLFSSL_FAILURE;
34150
    #endif
34151
        }
34152
        if (sz > 0) {
34153
            for (i = 0; i < sz; i++) {
34154
                wolfSSL_BIO_write(bio, &p[idx++], 1);
34155
            }
34156
            if (idx < p_len - 1)
34157
                wolfSSL_BIO_write(bio, ",", 1);
34158
        }
34159
    }
34160
    wolfSSL_BIO_write(bio, "\0", 1);
34161
34162
    /* clears out all current ALPN extensions set */
34163
    TLSX_Remove(&ssl->extensions, TLSX_APPLICATION_LAYER_PROTOCOL, ssl->heap);
34164
34165
    if ((sz = wolfSSL_BIO_get_mem_data(bio, &pt)) > 0) {
34166
        wolfSSL_UseALPN(ssl, pt, sz, (byte) alpn_opt);
34167
    }
34168
    wolfSSL_BIO_free(bio);
34169
#if defined(WOLFSSL_ERROR_CODE_OPENSSL)
34170
    /* 0 on success in OpenSSL, non-0 on failure in OpenSSL
34171
     * the function reverses the return value convention.
34172
     */
34173
    return 0;
34174
#else
34175
    return WOLFSSL_SUCCESS;
34176
#endif
34177
}
34178
#endif /* !NO_BIO */
34179
#endif /* HAVE_ALPN */
34180
#endif /* OPENSSL_EXTRA */
34181
34182
#if defined(OPENSSL_EXTRA)
34183
34184
#ifndef NO_BIO
34185
#define WOLFSSL_BIO_INCLUDED
34186
#include "src/bio.c"
34187
#endif
34188
34189
word32 nid2oid(int nid, int grp)
34190
0
{
34191
    /* get OID type */
34192
0
    switch (grp) {
34193
        /* oidHashType */
34194
0
        case oidHashType:
34195
0
            switch (nid) {
34196
0
            #ifdef WOLFSSL_MD2
34197
0
                case NID_md2:
34198
0
                    return MD2h;
34199
0
            #endif
34200
0
            #ifndef NO_MD5
34201
0
                case NID_md5:
34202
0
                    return MD5h;
34203
0
            #endif
34204
0
            #ifndef NO_SHA
34205
0
                case NID_sha1:
34206
0
                    return SHAh;
34207
0
            #endif
34208
0
                case NID_sha224:
34209
0
                    return SHA224h;
34210
0
            #ifndef NO_SHA256
34211
0
                case NID_sha256:
34212
0
                    return SHA256h;
34213
0
            #endif
34214
0
            #ifdef WOLFSSL_SHA384
34215
0
                case NID_sha384:
34216
0
                    return SHA384h;
34217
0
            #endif
34218
0
            #ifdef WOLFSSL_SHA512
34219
0
                case NID_sha512:
34220
0
                    return SHA512h;
34221
0
            #endif
34222
0
            #ifndef WOLFSSL_NOSHA3_224
34223
0
                case NID_sha3_224:
34224
0
                    return SHA3_224h;
34225
0
            #endif
34226
0
            #ifndef WOLFSSL_NOSHA3_256
34227
0
                case NID_sha3_256:
34228
0
                    return SHA3_256h;
34229
0
            #endif
34230
0
            #ifndef WOLFSSL_NOSHA3_384
34231
0
                case NID_sha3_384:
34232
0
                    return SHA3_384h;
34233
0
            #endif
34234
0
            #ifndef WOLFSSL_NOSHA3_512
34235
0
                case NID_sha3_512:
34236
0
                    return SHA3_512h;
34237
0
            #endif
34238
0
            }
34239
0
            break;
34240
34241
        /*  oidSigType */
34242
0
        case oidSigType:
34243
0
            switch (nid) {
34244
            #ifndef NO_DSA
34245
                case NID_dsaWithSHA1:
34246
                    return CTC_SHAwDSA;
34247
                case NID_dsa_with_SHA256:
34248
                    return CTC_SHA256wDSA;
34249
            #endif /* NO_DSA */
34250
0
            #ifndef NO_RSA
34251
0
                case NID_md2WithRSAEncryption:
34252
0
                    return CTC_MD2wRSA;
34253
0
                case NID_md5WithRSAEncryption:
34254
0
                    return CTC_MD5wRSA;
34255
0
                case NID_sha1WithRSAEncryption:
34256
0
                    return CTC_SHAwRSA;
34257
0
                case NID_sha224WithRSAEncryption:
34258
0
                    return CTC_SHA224wRSA;
34259
0
                case NID_sha256WithRSAEncryption:
34260
0
                    return CTC_SHA256wRSA;
34261
0
                case NID_sha384WithRSAEncryption:
34262
0
                    return CTC_SHA384wRSA;
34263
0
                case NID_sha512WithRSAEncryption:
34264
0
                    return CTC_SHA512wRSA;
34265
0
                #ifdef WOLFSSL_SHA3
34266
0
                case NID_RSA_SHA3_224:
34267
0
                    return CTC_SHA3_224wRSA;
34268
0
                case NID_RSA_SHA3_256:
34269
0
                    return CTC_SHA3_256wRSA;
34270
0
                case NID_RSA_SHA3_384:
34271
0
                    return CTC_SHA3_384wRSA;
34272
0
                case NID_RSA_SHA3_512:
34273
0
                    return CTC_SHA3_512wRSA;
34274
0
                #endif
34275
0
            #endif /* NO_RSA */
34276
0
            #ifdef HAVE_ECC
34277
0
                case NID_ecdsa_with_SHA1:
34278
0
                    return CTC_SHAwECDSA;
34279
0
                case NID_ecdsa_with_SHA224:
34280
0
                    return CTC_SHA224wECDSA;
34281
0
                case NID_ecdsa_with_SHA256:
34282
0
                    return CTC_SHA256wECDSA;
34283
0
                case NID_ecdsa_with_SHA384:
34284
0
                    return CTC_SHA384wECDSA;
34285
0
                case NID_ecdsa_with_SHA512:
34286
0
                    return CTC_SHA512wECDSA;
34287
0
                #ifdef WOLFSSL_SHA3
34288
0
                case NID_ecdsa_with_SHA3_224:
34289
0
                    return CTC_SHA3_224wECDSA;
34290
0
                case NID_ecdsa_with_SHA3_256:
34291
0
                    return CTC_SHA3_256wECDSA;
34292
0
                case NID_ecdsa_with_SHA3_384:
34293
0
                    return CTC_SHA3_384wECDSA;
34294
0
                case NID_ecdsa_with_SHA3_512:
34295
0
                    return CTC_SHA3_512wECDSA;
34296
0
                #endif
34297
0
            #endif /* HAVE_ECC */
34298
0
            }
34299
0
            break;
34300
34301
        /* oidKeyType */
34302
0
        case oidKeyType:
34303
0
            switch (nid) {
34304
            #ifndef NO_DSA
34305
                case NID_dsa:
34306
                    return DSAk;
34307
            #endif /* NO_DSA */
34308
0
            #ifndef NO_RSA
34309
0
                case NID_rsaEncryption:
34310
0
                    return RSAk;
34311
0
            #endif /* NO_RSA */
34312
0
            #ifdef HAVE_ECC
34313
0
                case NID_X9_62_id_ecPublicKey:
34314
0
                    return ECDSAk;
34315
0
            #endif /* HAVE_ECC */
34316
0
            }
34317
0
            break;
34318
34319
34320
0
    #ifdef HAVE_ECC
34321
0
        case oidCurveType:
34322
0
            switch (nid) {
34323
0
            case NID_X9_62_prime192v1:
34324
0
                return ECC_SECP192R1_OID;
34325
0
            case NID_X9_62_prime192v2:
34326
0
                return ECC_PRIME192V2_OID;
34327
0
            case NID_X9_62_prime192v3:
34328
0
                return ECC_PRIME192V3_OID;
34329
0
            case NID_X9_62_prime239v1:
34330
0
                return ECC_PRIME239V1_OID;
34331
0
            case NID_X9_62_prime239v2:
34332
0
                return ECC_PRIME239V2_OID;
34333
0
            case NID_X9_62_prime239v3:
34334
0
                return ECC_PRIME239V3_OID;
34335
0
            case NID_X9_62_prime256v1:
34336
0
                return ECC_SECP256R1_OID;
34337
0
            case NID_secp112r1:
34338
0
                return ECC_SECP112R1_OID;
34339
0
            case NID_secp112r2:
34340
0
                return ECC_SECP112R2_OID;
34341
0
            case NID_secp128r1:
34342
0
                return ECC_SECP128R1_OID;
34343
0
            case NID_secp128r2:
34344
0
                return ECC_SECP128R2_OID;
34345
0
            case NID_secp160r1:
34346
0
                return ECC_SECP160R1_OID;
34347
0
            case NID_secp160r2:
34348
0
                return ECC_SECP160R2_OID;
34349
0
            case NID_secp224r1:
34350
0
                return ECC_SECP224R1_OID;
34351
0
            case NID_secp384r1:
34352
0
                return ECC_SECP384R1_OID;
34353
0
            case NID_secp521r1:
34354
0
                return ECC_SECP521R1_OID;
34355
0
            case NID_secp160k1:
34356
0
                return ECC_SECP160K1_OID;
34357
0
            case NID_secp192k1:
34358
0
                return ECC_SECP192K1_OID;
34359
0
            case NID_secp224k1:
34360
0
                return ECC_SECP224K1_OID;
34361
0
            case NID_secp256k1:
34362
0
                return ECC_SECP256K1_OID;
34363
0
            case NID_brainpoolP160r1:
34364
0
                return ECC_BRAINPOOLP160R1_OID;
34365
0
            case NID_brainpoolP192r1:
34366
0
                return ECC_BRAINPOOLP192R1_OID;
34367
0
            case NID_brainpoolP224r1:
34368
0
                return ECC_BRAINPOOLP224R1_OID;
34369
0
            case NID_brainpoolP256r1:
34370
0
                return ECC_BRAINPOOLP256R1_OID;
34371
0
            case NID_brainpoolP320r1:
34372
0
                return ECC_BRAINPOOLP320R1_OID;
34373
0
            case NID_brainpoolP384r1:
34374
0
                return ECC_BRAINPOOLP384R1_OID;
34375
0
            case NID_brainpoolP512r1:
34376
0
                return ECC_BRAINPOOLP512R1_OID;
34377
0
            }
34378
0
            break;
34379
0
    #endif /* HAVE_ECC */
34380
34381
        /* oidBlkType */
34382
0
        case oidBlkType:
34383
0
            switch (nid) {
34384
0
            #ifdef WOLFSSL_AES_128
34385
0
                case AES128CBCb:
34386
0
                    return AES128CBCb;
34387
0
            #endif
34388
0
            #ifdef WOLFSSL_AES_192
34389
0
                case AES192CBCb:
34390
0
                    return AES192CBCb;
34391
0
            #endif
34392
0
            #ifdef WOLFSSL_AES_256
34393
0
                case AES256CBCb:
34394
0
                    return AES256CBCb;
34395
0
            #endif
34396
0
            #ifndef NO_DES3
34397
0
                case NID_des:
34398
0
                    return DESb;
34399
0
                case NID_des3:
34400
0
                    return DES3b;
34401
0
            #endif
34402
0
            }
34403
0
            break;
34404
34405
0
    #ifdef HAVE_OCSP
34406
0
        case oidOcspType:
34407
0
            switch (nid) {
34408
0
                case NID_id_pkix_OCSP_basic:
34409
0
                    return OCSP_BASIC_OID;
34410
0
                case OCSP_NONCE_OID:
34411
0
                    return OCSP_NONCE_OID;
34412
0
            }
34413
0
            break;
34414
0
    #endif /* HAVE_OCSP */
34415
34416
        /* oidCertExtType */
34417
0
        case oidCertExtType:
34418
0
            switch (nid) {
34419
0
                case NID_basic_constraints:
34420
0
                    return BASIC_CA_OID;
34421
0
                case NID_subject_alt_name:
34422
0
                    return ALT_NAMES_OID;
34423
0
                case NID_crl_distribution_points:
34424
0
                    return CRL_DIST_OID;
34425
0
                case NID_info_access:
34426
0
                    return AUTH_INFO_OID;
34427
0
                case NID_authority_key_identifier:
34428
0
                    return AUTH_KEY_OID;
34429
0
                case NID_subject_key_identifier:
34430
0
                    return SUBJ_KEY_OID;
34431
0
                case NID_inhibit_any_policy:
34432
0
                    return INHIBIT_ANY_OID;
34433
0
                case NID_key_usage:
34434
0
                    return KEY_USAGE_OID;
34435
0
                case NID_name_constraints:
34436
0
                    return NAME_CONS_OID;
34437
0
                case NID_certificate_policies:
34438
0
                    return CERT_POLICY_OID;
34439
0
                case NID_ext_key_usage:
34440
0
                    return EXT_KEY_USAGE_OID;
34441
0
            }
34442
0
            break;
34443
34444
        /* oidCertAuthInfoType */
34445
0
        case oidCertAuthInfoType:
34446
0
            switch (nid) {
34447
0
                case NID_ad_OCSP:
34448
0
                    return AIA_OCSP_OID;
34449
0
                case NID_ad_ca_issuers:
34450
0
                    return AIA_CA_ISSUER_OID;
34451
0
            }
34452
0
            break;
34453
34454
        /* oidCertPolicyType */
34455
0
        case oidCertPolicyType:
34456
0
            switch (nid) {
34457
0
                case NID_any_policy:
34458
0
                    return CP_ANY_OID;
34459
0
            }
34460
0
            break;
34461
34462
        /* oidCertAltNameType */
34463
0
        case oidCertAltNameType:
34464
0
            switch (nid) {
34465
0
                case NID_hw_name_oid:
34466
0
                    return HW_NAME_OID;
34467
0
            }
34468
0
            break;
34469
34470
        /* oidCertKeyUseType */
34471
0
        case oidCertKeyUseType:
34472
0
            switch (nid) {
34473
0
                case NID_anyExtendedKeyUsage:
34474
0
                    return EKU_ANY_OID;
34475
0
                case EKU_SERVER_AUTH_OID:
34476
0
                    return EKU_SERVER_AUTH_OID;
34477
0
                case EKU_CLIENT_AUTH_OID:
34478
0
                    return EKU_CLIENT_AUTH_OID;
34479
0
                case EKU_OCSP_SIGN_OID:
34480
0
                    return EKU_OCSP_SIGN_OID;
34481
0
            }
34482
0
            break;
34483
34484
        /* oidKdfType */
34485
0
        case oidKdfType:
34486
0
            switch (nid) {
34487
0
                case PBKDF2_OID:
34488
0
                    return PBKDF2_OID;
34489
0
            }
34490
0
            break;
34491
34492
        /* oidPBEType */
34493
0
        case oidPBEType:
34494
0
            switch (nid) {
34495
0
                case PBE_SHA1_RC4_128:
34496
0
                    return PBE_SHA1_RC4_128;
34497
0
                case PBE_SHA1_DES:
34498
0
                    return PBE_SHA1_DES;
34499
0
                case PBE_SHA1_DES3:
34500
0
                    return PBE_SHA1_DES3;
34501
0
            }
34502
0
            break;
34503
34504
        /* oidKeyWrapType */
34505
0
        case oidKeyWrapType:
34506
0
            switch (nid) {
34507
0
            #ifdef WOLFSSL_AES_128
34508
0
                case AES128_WRAP:
34509
0
                    return AES128_WRAP;
34510
0
            #endif
34511
0
            #ifdef WOLFSSL_AES_192
34512
0
                case AES192_WRAP:
34513
0
                    return AES192_WRAP;
34514
0
            #endif
34515
0
            #ifdef WOLFSSL_AES_256
34516
0
                case AES256_WRAP:
34517
0
                    return AES256_WRAP;
34518
0
            #endif
34519
0
            }
34520
0
            break;
34521
34522
        /* oidCmsKeyAgreeType */
34523
0
        case oidCmsKeyAgreeType:
34524
0
            switch (nid) {
34525
0
                #ifndef NO_SHA
34526
0
                case dhSinglePass_stdDH_sha1kdf_scheme:
34527
0
                    return dhSinglePass_stdDH_sha1kdf_scheme;
34528
0
                #endif
34529
0
                #ifdef WOLFSSL_SHA224
34530
0
                case dhSinglePass_stdDH_sha224kdf_scheme:
34531
0
                    return dhSinglePass_stdDH_sha224kdf_scheme;
34532
0
                #endif
34533
0
                #ifndef NO_SHA256
34534
0
                case dhSinglePass_stdDH_sha256kdf_scheme:
34535
0
                    return dhSinglePass_stdDH_sha256kdf_scheme;
34536
0
                #endif
34537
0
                #ifdef WOLFSSL_SHA384
34538
0
                case dhSinglePass_stdDH_sha384kdf_scheme:
34539
0
                    return dhSinglePass_stdDH_sha384kdf_scheme;
34540
0
                #endif
34541
0
                #ifdef WOLFSSL_SHA512
34542
0
                case dhSinglePass_stdDH_sha512kdf_scheme:
34543
0
                    return dhSinglePass_stdDH_sha512kdf_scheme;
34544
0
                #endif
34545
0
            }
34546
0
            break;
34547
34548
0
        default:
34549
0
            WOLFSSL_MSG("NID not in table");
34550
            /* MSVC warns without the cast */
34551
0
            return (word32)-1;
34552
0
    }
34553
34554
    /* MSVC warns without the cast */
34555
0
    return (word32)-1;
34556
0
}
34557
34558
int oid2nid(word32 oid, int grp)
34559
0
{
34560
0
    size_t i;
34561
    /* get OID type */
34562
0
    switch (grp) {
34563
        /* oidHashType */
34564
0
        case oidHashType:
34565
0
            switch (oid) {
34566
0
            #ifdef WOLFSSL_MD2
34567
0
                case MD2h:
34568
0
                    return NID_md2;
34569
0
            #endif
34570
0
            #ifndef NO_MD5
34571
0
                case MD5h:
34572
0
                    return NID_md5;
34573
0
            #endif
34574
0
            #ifndef NO_SHA
34575
0
                case SHAh:
34576
0
                    return NID_sha1;
34577
0
            #endif
34578
0
                case SHA224h:
34579
0
                    return NID_sha224;
34580
0
            #ifndef NO_SHA256
34581
0
                case SHA256h:
34582
0
                    return NID_sha256;
34583
0
            #endif
34584
0
            #ifdef WOLFSSL_SHA384
34585
0
                case SHA384h:
34586
0
                    return NID_sha384;
34587
0
            #endif
34588
0
            #ifdef WOLFSSL_SHA512
34589
0
                case SHA512h:
34590
0
                    return NID_sha512;
34591
0
            #endif
34592
0
            }
34593
0
            break;
34594
34595
        /*  oidSigType */
34596
0
        case oidSigType:
34597
0
            switch (oid) {
34598
            #ifndef NO_DSA
34599
                case CTC_SHAwDSA:
34600
                    return NID_dsaWithSHA1;
34601
                case CTC_SHA256wDSA:
34602
                    return NID_dsa_with_SHA256;
34603
            #endif /* NO_DSA */
34604
0
            #ifndef NO_RSA
34605
0
                case CTC_MD2wRSA:
34606
0
                    return NID_md2WithRSAEncryption;
34607
0
                case CTC_MD5wRSA:
34608
0
                    return NID_md5WithRSAEncryption;
34609
0
                case CTC_SHAwRSA:
34610
0
                    return NID_sha1WithRSAEncryption;
34611
0
                case CTC_SHA224wRSA:
34612
0
                    return NID_sha224WithRSAEncryption;
34613
0
                case CTC_SHA256wRSA:
34614
0
                    return NID_sha256WithRSAEncryption;
34615
0
                case CTC_SHA384wRSA:
34616
0
                    return NID_sha384WithRSAEncryption;
34617
0
                case CTC_SHA512wRSA:
34618
0
                    return NID_sha512WithRSAEncryption;
34619
0
                #ifdef WOLFSSL_SHA3
34620
0
                case CTC_SHA3_224wRSA:
34621
0
                    return NID_RSA_SHA3_224;
34622
0
                case CTC_SHA3_256wRSA:
34623
0
                    return NID_RSA_SHA3_256;
34624
0
                case CTC_SHA3_384wRSA:
34625
0
                    return NID_RSA_SHA3_384;
34626
0
                case CTC_SHA3_512wRSA:
34627
0
                    return NID_RSA_SHA3_512;
34628
0
                #endif
34629
0
            #endif /* NO_RSA */
34630
0
            #ifdef HAVE_ECC
34631
0
                case CTC_SHAwECDSA:
34632
0
                    return NID_ecdsa_with_SHA1;
34633
0
                case CTC_SHA224wECDSA:
34634
0
                    return NID_ecdsa_with_SHA224;
34635
0
                case CTC_SHA256wECDSA:
34636
0
                    return NID_ecdsa_with_SHA256;
34637
0
                case CTC_SHA384wECDSA:
34638
0
                    return NID_ecdsa_with_SHA384;
34639
0
                case CTC_SHA512wECDSA:
34640
0
                    return NID_ecdsa_with_SHA512;
34641
0
                #ifdef WOLFSSL_SHA3
34642
0
                case CTC_SHA3_224wECDSA:
34643
0
                    return NID_ecdsa_with_SHA3_224;
34644
0
                case CTC_SHA3_256wECDSA:
34645
0
                    return NID_ecdsa_with_SHA3_256;
34646
0
                case CTC_SHA3_384wECDSA:
34647
0
                    return NID_ecdsa_with_SHA3_384;
34648
0
                case CTC_SHA3_512wECDSA:
34649
0
                    return NID_ecdsa_with_SHA3_512;
34650
0
                #endif
34651
0
            #endif /* HAVE_ECC */
34652
0
            }
34653
0
            break;
34654
34655
        /* oidKeyType */
34656
0
        case oidKeyType:
34657
0
            switch (oid) {
34658
            #ifndef NO_DSA
34659
                case DSAk:
34660
                    return NID_dsa;
34661
            #endif /* NO_DSA */
34662
0
            #ifndef NO_RSA
34663
0
                case RSAk:
34664
0
                    return NID_rsaEncryption;
34665
0
            #endif /* NO_RSA */
34666
0
            #ifdef HAVE_ECC
34667
0
                case ECDSAk:
34668
0
                    return NID_X9_62_id_ecPublicKey;
34669
0
            #endif /* HAVE_ECC */
34670
0
            }
34671
0
            break;
34672
34673
34674
0
    #ifdef HAVE_ECC
34675
0
        case oidCurveType:
34676
0
            switch (oid) {
34677
0
            case ECC_SECP192R1_OID:
34678
0
                return NID_X9_62_prime192v1;
34679
0
            case ECC_PRIME192V2_OID:
34680
0
                return NID_X9_62_prime192v2;
34681
0
            case ECC_PRIME192V3_OID:
34682
0
                return NID_X9_62_prime192v3;
34683
0
            case ECC_PRIME239V1_OID:
34684
0
                return NID_X9_62_prime239v1;
34685
0
            case ECC_PRIME239V2_OID:
34686
0
                return NID_X9_62_prime239v2;
34687
0
            case ECC_PRIME239V3_OID:
34688
0
                return NID_X9_62_prime239v3;
34689
0
            case ECC_SECP256R1_OID:
34690
0
                return NID_X9_62_prime256v1;
34691
0
            case ECC_SECP112R1_OID:
34692
0
                return NID_secp112r1;
34693
0
            case ECC_SECP112R2_OID:
34694
0
                return NID_secp112r2;
34695
0
            case ECC_SECP128R1_OID:
34696
0
                return NID_secp128r1;
34697
0
            case ECC_SECP128R2_OID:
34698
0
                return NID_secp128r2;
34699
0
            case ECC_SECP160R1_OID:
34700
0
                return NID_secp160r1;
34701
0
            case ECC_SECP160R2_OID:
34702
0
                return NID_secp160r2;
34703
0
            case ECC_SECP224R1_OID:
34704
0
                return NID_secp224r1;
34705
0
            case ECC_SECP384R1_OID:
34706
0
                return NID_secp384r1;
34707
0
            case ECC_SECP521R1_OID:
34708
0
                return NID_secp521r1;
34709
0
            case ECC_SECP160K1_OID:
34710
0
                return NID_secp160k1;
34711
0
            case ECC_SECP192K1_OID:
34712
0
                return NID_secp192k1;
34713
0
            case ECC_SECP224K1_OID:
34714
0
                return NID_secp224k1;
34715
0
            case ECC_SECP256K1_OID:
34716
0
                return NID_secp256k1;
34717
0
            case ECC_BRAINPOOLP160R1_OID:
34718
0
                return NID_brainpoolP160r1;
34719
0
            case ECC_BRAINPOOLP192R1_OID:
34720
0
                return NID_brainpoolP192r1;
34721
0
            case ECC_BRAINPOOLP224R1_OID:
34722
0
                return NID_brainpoolP224r1;
34723
0
            case ECC_BRAINPOOLP256R1_OID:
34724
0
                return NID_brainpoolP256r1;
34725
0
            case ECC_BRAINPOOLP320R1_OID:
34726
0
                return NID_brainpoolP320r1;
34727
0
            case ECC_BRAINPOOLP384R1_OID:
34728
0
                return NID_brainpoolP384r1;
34729
0
            case ECC_BRAINPOOLP512R1_OID:
34730
0
                return NID_brainpoolP512r1;
34731
0
            }
34732
0
            break;
34733
0
    #endif /* HAVE_ECC */
34734
34735
        /* oidBlkType */
34736
0
        case oidBlkType:
34737
0
            switch (oid) {
34738
0
            #ifdef WOLFSSL_AES_128
34739
0
                case AES128CBCb:
34740
0
                    return AES128CBCb;
34741
0
            #endif
34742
0
            #ifdef WOLFSSL_AES_192
34743
0
                case AES192CBCb:
34744
0
                    return AES192CBCb;
34745
0
            #endif
34746
0
            #ifdef WOLFSSL_AES_256
34747
0
                case AES256CBCb:
34748
0
                    return AES256CBCb;
34749
0
            #endif
34750
0
            #ifndef NO_DES3
34751
0
                case DESb:
34752
0
                    return NID_des;
34753
0
                case DES3b:
34754
0
                    return NID_des3;
34755
0
            #endif
34756
0
            }
34757
0
            break;
34758
34759
0
    #ifdef HAVE_OCSP
34760
0
        case oidOcspType:
34761
0
            switch (oid) {
34762
0
                case OCSP_BASIC_OID:
34763
0
                    return NID_id_pkix_OCSP_basic;
34764
0
                case OCSP_NONCE_OID:
34765
0
                    return OCSP_NONCE_OID;
34766
0
            }
34767
0
            break;
34768
0
    #endif /* HAVE_OCSP */
34769
34770
        /* oidCertExtType */
34771
0
        case oidCertExtType:
34772
0
            switch (oid) {
34773
0
                case BASIC_CA_OID:
34774
0
                    return NID_basic_constraints;
34775
0
                case ALT_NAMES_OID:
34776
0
                    return NID_subject_alt_name;
34777
0
                case CRL_DIST_OID:
34778
0
                    return NID_crl_distribution_points;
34779
0
                case AUTH_INFO_OID:
34780
0
                    return NID_info_access;
34781
0
                case AUTH_KEY_OID:
34782
0
                    return NID_authority_key_identifier;
34783
0
                case SUBJ_KEY_OID:
34784
0
                    return NID_subject_key_identifier;
34785
0
                case INHIBIT_ANY_OID:
34786
0
                    return NID_inhibit_any_policy;
34787
0
                case KEY_USAGE_OID:
34788
0
                    return NID_key_usage;
34789
0
                case NAME_CONS_OID:
34790
0
                    return NID_name_constraints;
34791
0
                case CERT_POLICY_OID:
34792
0
                    return NID_certificate_policies;
34793
0
                case EXT_KEY_USAGE_OID:
34794
0
                    return NID_ext_key_usage;
34795
0
            }
34796
0
            break;
34797
34798
        /* oidCertAuthInfoType */
34799
0
        case oidCertAuthInfoType:
34800
0
            switch (oid) {
34801
0
                case AIA_OCSP_OID:
34802
0
                    return NID_ad_OCSP;
34803
0
                case AIA_CA_ISSUER_OID:
34804
0
                    return NID_ad_ca_issuers;
34805
0
            }
34806
0
            break;
34807
34808
        /* oidCertPolicyType */
34809
0
        case oidCertPolicyType:
34810
0
            switch (oid) {
34811
0
                case CP_ANY_OID:
34812
0
                    return NID_any_policy;
34813
0
            }
34814
0
            break;
34815
34816
        /* oidCertAltNameType */
34817
0
        case oidCertAltNameType:
34818
0
            switch (oid) {
34819
0
                case HW_NAME_OID:
34820
0
                    return NID_hw_name_oid;
34821
0
            }
34822
0
            break;
34823
34824
        /* oidCertKeyUseType */
34825
0
        case oidCertKeyUseType:
34826
0
            switch (oid) {
34827
0
                case EKU_ANY_OID:
34828
0
                    return NID_anyExtendedKeyUsage;
34829
0
                case EKU_SERVER_AUTH_OID:
34830
0
                    return EKU_SERVER_AUTH_OID;
34831
0
                case EKU_CLIENT_AUTH_OID:
34832
0
                    return EKU_CLIENT_AUTH_OID;
34833
0
                case EKU_OCSP_SIGN_OID:
34834
0
                    return EKU_OCSP_SIGN_OID;
34835
0
            }
34836
0
            break;
34837
34838
        /* oidKdfType */
34839
0
        case oidKdfType:
34840
0
            switch (oid) {
34841
0
                case PBKDF2_OID:
34842
0
                    return PBKDF2_OID;
34843
0
            }
34844
0
            break;
34845
34846
        /* oidPBEType */
34847
0
        case oidPBEType:
34848
0
            switch (oid) {
34849
0
                case PBE_SHA1_RC4_128:
34850
0
                    return PBE_SHA1_RC4_128;
34851
0
                case PBE_SHA1_DES:
34852
0
                    return PBE_SHA1_DES;
34853
0
                case PBE_SHA1_DES3:
34854
0
                    return PBE_SHA1_DES3;
34855
0
            }
34856
0
            break;
34857
34858
        /* oidKeyWrapType */
34859
0
        case oidKeyWrapType:
34860
0
            switch (oid) {
34861
0
            #ifdef WOLFSSL_AES_128
34862
0
                case AES128_WRAP:
34863
0
                    return AES128_WRAP;
34864
0
            #endif
34865
0
            #ifdef WOLFSSL_AES_192
34866
0
                case AES192_WRAP:
34867
0
                    return AES192_WRAP;
34868
0
            #endif
34869
0
            #ifdef WOLFSSL_AES_256
34870
0
                case AES256_WRAP:
34871
0
                    return AES256_WRAP;
34872
0
            #endif
34873
0
            }
34874
0
            break;
34875
34876
        /* oidCmsKeyAgreeType */
34877
0
        case oidCmsKeyAgreeType:
34878
0
            switch (oid) {
34879
0
                #ifndef NO_SHA
34880
0
                case dhSinglePass_stdDH_sha1kdf_scheme:
34881
0
                    return dhSinglePass_stdDH_sha1kdf_scheme;
34882
0
                #endif
34883
0
                #ifdef WOLFSSL_SHA224
34884
0
                case dhSinglePass_stdDH_sha224kdf_scheme:
34885
0
                    return dhSinglePass_stdDH_sha224kdf_scheme;
34886
0
                #endif
34887
0
                #ifndef NO_SHA256
34888
0
                case dhSinglePass_stdDH_sha256kdf_scheme:
34889
0
                    return dhSinglePass_stdDH_sha256kdf_scheme;
34890
0
                #endif
34891
0
                #ifdef WOLFSSL_SHA384
34892
0
                case dhSinglePass_stdDH_sha384kdf_scheme:
34893
0
                    return dhSinglePass_stdDH_sha384kdf_scheme;
34894
0
                #endif
34895
0
                #ifdef WOLFSSL_SHA512
34896
0
                case dhSinglePass_stdDH_sha512kdf_scheme:
34897
0
                    return dhSinglePass_stdDH_sha512kdf_scheme;
34898
0
                #endif
34899
0
            }
34900
0
            break;
34901
34902
#ifdef WOLFSSL_CERT_REQ
34903
        case oidCsrAttrType:
34904
            switch (oid) {
34905
                case PKCS9_CONTENT_TYPE_OID:
34906
                    return NID_pkcs9_contentType;
34907
                case CHALLENGE_PASSWORD_OID:
34908
                    return NID_pkcs9_challengePassword;
34909
                case SERIAL_NUMBER_OID:
34910
                    return NID_serialNumber;
34911
                case USER_ID_OID:
34912
                    return NID_userId;
34913
            }
34914
            break;
34915
#endif
34916
34917
0
        default:
34918
0
            WOLFSSL_MSG("NID not in table");
34919
0
    }
34920
    /* If not found in above switch then try the table */
34921
0
    for (i = 0; i < WOLFSSL_OBJECT_INFO_SZ; i++) {
34922
0
        if (wolfssl_object_info[i].id == (int)oid) {
34923
0
            return wolfssl_object_info[i].nid;
34924
0
        }
34925
0
    }
34926
34927
0
    return -1;
34928
0
}
34929
34930
/* when calling SetIndividualInternal, mpi should be cleared by caller if no
34931
 * longer used. ie mp_free(mpi). This is to free data when fastmath is
34932
 * disabled since a copy of mpi is made by this function and placed into bn.
34933
 */
34934
int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
34935
0
{
34936
0
    WOLFSSL_MSG("Entering SetIndividualInternal");
34937
34938
0
    if (bn == NULL || bn->internal == NULL) {
34939
0
        WOLFSSL_MSG("bn NULL error");
34940
0
        return WOLFSSL_FATAL_ERROR;
34941
0
    }
34942
34943
0
    if (mpi == NULL) {
34944
0
        WOLFSSL_MSG("mpi NULL error");
34945
0
        return WOLFSSL_FATAL_ERROR;
34946
0
    }
34947
34948
0
    if (mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
34949
0
        WOLFSSL_MSG("mp_copy error");
34950
0
        return WOLFSSL_FATAL_ERROR;
34951
0
    }
34952
34953
0
    return WOLFSSL_SUCCESS;
34954
0
}
34955
34956
34957
#ifndef NO_ASN
34958
WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai,
34959
                                       WOLFSSL_BIGNUM *bn)
34960
446
{
34961
446
#ifdef WOLFSSL_SMALL_STACK
34962
446
    mp_int* mpi = NULL;
34963
#else
34964
    mp_int mpi[1];
34965
#endif
34966
446
    word32 idx = 0;
34967
446
    int ret;
34968
34969
446
    WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_to_BN");
34970
34971
446
    if (ai == NULL) {
34972
0
        return NULL;
34973
0
    }
34974
34975
446
#ifdef WOLFSSL_SMALL_STACK
34976
446
    mpi = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
34977
446
    if (mpi == NULL) {
34978
0
        return NULL;
34979
0
    }
34980
446
#endif
34981
34982
446
    ret = GetInt(mpi, ai->data, &idx, ai->dataMax);
34983
446
    if (ret != 0) {
34984
    #if defined(WOLFSSL_QT) || defined(WOLFSSL_HAPROXY)
34985
        ret = mp_init(mpi); /* must init mpi */
34986
        if (ret != MP_OKAY) {
34987
        #ifdef WOLFSSL_SMALL_STACK
34988
            XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
34989
        #endif
34990
            return NULL;
34991
        }
34992
        /* Serial number in QT starts at index 0 of data */
34993
        if (mp_read_unsigned_bin(mpi, (byte*)ai->data, ai->length) != 0) {
34994
                mp_clear(mpi);
34995
            #ifdef WOLFSSL_SMALL_STACK
34996
                XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
34997
            #endif
34998
                return NULL;
34999
            }
35000
    #else
35001
        /* expecting ASN1 format for INTEGER */
35002
0
        WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret);
35003
0
    #ifdef WOLFSSL_SMALL_STACK
35004
0
        XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
35005
0
    #endif
35006
0
        return NULL;
35007
0
    #endif
35008
0
    }
35009
35010
    /* mp_clear needs called because mpi is copied and causes memory leak with
35011
     * --disable-fastmath */
35012
446
    ret = SetIndividualExternal(&bn, mpi);
35013
446
    mp_clear(mpi);
35014
35015
446
#ifdef WOLFSSL_SMALL_STACK
35016
446
    XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
35017
446
#endif
35018
35019
446
    if (ret != WOLFSSL_SUCCESS) {
35020
0
        return NULL;
35021
0
    }
35022
446
    return bn;
35023
446
}
35024
#endif /* !NO_ASN */
35025
35026
/* frees all nodes in the current threads error queue
35027
 *
35028
 * id  thread id. ERR_remove_state is depreciated and id is ignored. The
35029
 *     current threads queue will be free'd.
35030
 */
35031
void wolfSSL_ERR_remove_state(unsigned long id)
35032
0
{
35033
0
    WOLFSSL_ENTER("wolfSSL_ERR_remove_state");
35034
0
    (void)id;
35035
0
    if (wc_ERR_remove_state() != 0) {
35036
0
        WOLFSSL_MSG("Error with removing the state");
35037
0
    }
35038
0
}
35039
35040
35041
WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
35042
2.25k
{
35043
2.25k
    static int ctx;  /* wolfcrypt doesn't now need ctx */
35044
35045
2.25k
    WOLFSSL_MSG("wolfSSL_BN_CTX_new");
35046
2.25k
    return (WOLFSSL_BN_CTX*)&ctx;
35047
35048
2.25k
}
35049
35050
void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
35051
0
{
35052
0
    (void)ctx;
35053
0
    WOLFSSL_MSG("wolfSSL_BN_CTX_init");
35054
0
}
35055
35056
35057
void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
35058
2.25k
{
35059
2.25k
    (void)ctx;
35060
2.25k
    WOLFSSL_MSG("wolfSSL_BN_CTX_free");
35061
    /* do free since static ctx that does nothing */
35062
2.25k
}
35063
35064
/* WOLFSSL_SUCCESS on ok */
35065
int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
35066
                  const WOLFSSL_BIGNUM* b)
35067
11
{
35068
11
    WOLFSSL_MSG("wolfSSL_BN_sub");
35069
35070
11
    if (r == NULL || a == NULL || b == NULL)
35071
0
        return 0;
35072
35073
11
    if (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
35074
11
               (mp_int*)r->internal) == MP_OKAY)
35075
11
        return WOLFSSL_SUCCESS;
35076
35077
0
    WOLFSSL_MSG("wolfSSL_BN_sub mp_sub failed");
35078
0
    return 0;
35079
11
}
35080
35081
WOLFSSL_API int wolfSSL_BN_mul(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b,
35082
    WOLFSSL_BN_CTX *ctx)
35083
0
{
35084
0
    int ret = WOLFSSL_SUCCESS;
35085
35086
0
    (void)ctx;
35087
35088
0
    WOLFSSL_ENTER("wolfSSL_BN_mul");
35089
35090
0
    if (r == NULL || a == NULL || b == NULL || r->internal == NULL ||
35091
0
        a->internal == NULL || b->internal == NULL) {
35092
0
        ret = WOLFSSL_FAILURE;
35093
0
    }
35094
35095
0
    if (ret == WOLFSSL_SUCCESS) {
35096
0
        ret = mp_mul((mp_int*)a->internal, (mp_int*)b->internal,
35097
0
                     (mp_int*)r->internal);
35098
0
        if (ret == MP_OKAY) {
35099
0
            ret = WOLFSSL_SUCCESS;
35100
0
        }
35101
0
        else {
35102
0
            ret = WOLFSSL_FAILURE;
35103
0
        }
35104
0
    }
35105
35106
0
    WOLFSSL_LEAVE("wolfSSL_BN_mul", ret);
35107
35108
0
    return ret;
35109
0
}
35110
35111
#ifndef WOLFSSL_SP_MATH
35112
int wolfSSL_BN_div(WOLFSSL_BIGNUM* dv, WOLFSSL_BIGNUM* rem,
35113
                   const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* d,
35114
                   WOLFSSL_BN_CTX* ctx)
35115
0
{
35116
0
    int ret = WOLFSSL_SUCCESS;
35117
35118
0
    (void)ctx;
35119
35120
0
    WOLFSSL_ENTER("wolfSSL_BN_div");
35121
35122
0
    if (dv == NULL || rem == NULL || a == NULL || d == NULL ||
35123
0
        dv->internal == NULL || rem->internal == NULL || a->internal == NULL ||
35124
0
        d->internal == NULL) {
35125
0
        ret = WOLFSSL_FAILURE;
35126
0
    }
35127
35128
0
    if (ret == WOLFSSL_SUCCESS) {
35129
0
        ret = mp_div((mp_int*)a->internal, (mp_int*)d->internal,
35130
0
                     (mp_int*)dv->internal, (mp_int*)rem->internal);
35131
0
        if (ret == MP_OKAY) {
35132
0
            ret = WOLFSSL_SUCCESS;
35133
0
        }
35134
0
        else {
35135
0
            ret = WOLFSSL_FAILURE;
35136
0
        }
35137
0
    }
35138
35139
0
    WOLFSSL_LEAVE("wolfSSL_BN_div", ret);
35140
35141
0
    return ret;
35142
0
}
35143
#endif
35144
35145
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) /* Needed to get mp_gcd. */
35146
int wolfSSL_BN_gcd(WOLFSSL_BIGNUM* r, WOLFSSL_BIGNUM* a, WOLFSSL_BIGNUM* b,
35147
                   WOLFSSL_BN_CTX* ctx)
35148
0
{
35149
0
    int ret = WOLFSSL_SUCCESS;
35150
35151
0
    (void)ctx;
35152
35153
0
    WOLFSSL_ENTER("wolfSSL_BN_gcd");
35154
35155
0
    if (r == NULL || a == NULL || b == NULL || r->internal == NULL ||
35156
0
        a->internal == NULL || b->internal == NULL) {
35157
0
        ret = WOLFSSL_FAILURE;
35158
0
    }
35159
35160
0
    if (ret == WOLFSSL_SUCCESS) {
35161
0
        ret = mp_gcd((mp_int*)a->internal, (mp_int*)b->internal,
35162
0
                     (mp_int*)r->internal);
35163
0
        if (ret == MP_OKAY) {
35164
0
            ret = WOLFSSL_SUCCESS;
35165
0
        }
35166
0
        else {
35167
0
            ret = WOLFSSL_FAILURE;
35168
0
        }
35169
0
    }
35170
35171
0
    WOLFSSL_LEAVE("wolfSSL_BN_gcd", ret);
35172
35173
0
    return ret;
35174
0
}
35175
#endif /* !NO_RSA && WOLFSSL_KEY_GEN */
35176
35177
/* WOLFSSL_SUCCESS on ok */
35178
int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
35179
                  const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
35180
5
{
35181
5
    (void)c;
35182
5
    WOLFSSL_MSG("wolfSSL_BN_mod");
35183
35184
5
    if (r == NULL || a == NULL || b == NULL)
35185
0
        return 0;
35186
35187
5
    if (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
35188
5
               (mp_int*)r->internal) == MP_OKAY)
35189
3
        return WOLFSSL_SUCCESS;
35190
35191
2
    WOLFSSL_MSG("wolfSSL_BN_mod mp_mod failed");
35192
2
    return 0;
35193
5
}
35194
35195
35196
/* r = (a^p) % m */
35197
int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
35198
      const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
35199
373
{
35200
373
    int ret;
35201
35202
373
    WOLFSSL_ENTER("wolfSSL_BN_mod_exp");
35203
35204
373
    (void) ctx;
35205
373
    if (r == NULL || a == NULL || p == NULL || m == NULL) {
35206
0
        WOLFSSL_MSG("Bad Argument");
35207
0
        return WOLFSSL_FAILURE;
35208
0
    }
35209
35210
373
    if ((ret = mp_exptmod((mp_int*)a->internal,(mp_int*)p->internal,
35211
373
               (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
35212
364
        return WOLFSSL_SUCCESS;
35213
364
    }
35214
35215
9
    WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret);
35216
9
    (void)ret;
35217
35218
9
    return WOLFSSL_FAILURE;
35219
373
}
35220
35221
/* r = (a * p) % m */
35222
int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
35223
        const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
35224
31
{
35225
31
    int ret;
35226
35227
31
    WOLFSSL_ENTER("wolfSSL_BN_mod_mul");
35228
35229
31
    (void) ctx;
35230
31
    if (r == NULL || a == NULL || p == NULL || m == NULL) {
35231
0
        WOLFSSL_MSG("Bad Argument");
35232
0
        return SSL_FAILURE;
35233
0
    }
35234
35235
31
    if ((ret = mp_mulmod((mp_int*)a->internal,(mp_int*)p->internal,
35236
31
               (mp_int*)m->internal, (mp_int*)r->internal)) == MP_OKAY) {
35237
30
        return WOLFSSL_SUCCESS;
35238
30
    }
35239
35240
1
    WOLFSSL_LEAVE("wolfSSL_BN_mod_mul", ret);
35241
1
    (void)ret;
35242
35243
1
    return SSL_FAILURE;
35244
31
}
35245
35246
const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
35247
0
{
35248
0
    WOLFSSL_MSG("wolfSSL_BN_value_one");
35249
35250
0
    if (bn_one == NULL) {
35251
0
        bn_one = wolfSSL_BN_new();
35252
0
        if (bn_one) {
35253
0
            if (mp_set_int((mp_int*)bn_one->internal, 1) != MP_OKAY) {
35254
                /* handle error by freeing BN and returning NULL */
35255
0
                wolfSSL_BN_free(bn_one);
35256
0
                bn_one = NULL;
35257
0
            }
35258
0
        }
35259
0
    }
35260
35261
0
    return bn_one;
35262
0
}
35263
35264
/* return compliant with OpenSSL
35265
 *   size of BIGNUM in bytes, 0 if error */
35266
int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
35267
446
{
35268
446
    WOLFSSL_ENTER("wolfSSL_BN_num_bytes");
35269
35270
446
    if (bn == NULL || bn->internal == NULL)
35271
0
        return WOLFSSL_FAILURE;
35272
35273
446
    return mp_unsigned_bin_size((mp_int*)bn->internal);
35274
446
}
35275
35276
/* return compliant with OpenSSL
35277
 *   size of BIGNUM in bits, 0 if error */
35278
int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
35279
0
{
35280
0
    WOLFSSL_ENTER("wolfSSL_BN_num_bits");
35281
35282
0
    if (bn == NULL || bn->internal == NULL)
35283
0
        return WOLFSSL_FAILURE;
35284
35285
0
    return mp_count_bits((mp_int*)bn->internal);
35286
0
}
35287
35288
int wolfSSL_BN_is_negative(const WOLFSSL_BIGNUM* bn)
35289
456
{
35290
456
    if (bn == NULL)
35291
0
        return WOLFSSL_FAILURE;
35292
35293
456
    return mp_isneg((mp_int*)bn->internal);
35294
456
}
35295
35296
WOLFSSL_API void wolfSSL_BN_zero(WOLFSSL_BIGNUM* bn)
35297
0
{
35298
0
    if (bn == NULL || bn->internal == NULL) {
35299
0
        return;
35300
0
    }
35301
35302
0
    mp_zero((mp_int*)bn->internal);
35303
0
}
35304
35305
WOLFSSL_API int wolfSSL_BN_one(WOLFSSL_BIGNUM* bn)
35306
0
{
35307
0
    int ret = WOLFSSL_SUCCESS;
35308
35309
0
    if (bn == NULL || bn->internal == NULL) {
35310
0
        return WOLFSSL_FAILURE;
35311
0
    }
35312
35313
0
    if (ret == WOLFSSL_SUCCESS) {
35314
0
        ret = wolfSSL_BN_set_word(bn, 1);
35315
0
    }
35316
35317
0
    return ret;
35318
0
}
35319
35320
/* return compliant with OpenSSL
35321
 *   1 if BIGNUM is zero, 0 else */
35322
int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
35323
471
{
35324
471
    WOLFSSL_MSG("wolfSSL_BN_is_zero");
35325
35326
471
    if (bn == NULL || bn->internal == NULL)
35327
0
        return WOLFSSL_FAILURE;
35328
35329
471
    if (mp_iszero((mp_int*)bn->internal) == MP_YES)
35330
189
        return WOLFSSL_SUCCESS;
35331
35332
282
    return WOLFSSL_FAILURE;
35333
471
}
35334
35335
/* return compliant with OpenSSL
35336
 *   1 if BIGNUM is one, 0 else */
35337
int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
35338
66
{
35339
66
    WOLFSSL_MSG("wolfSSL_BN_is_one");
35340
35341
66
    if (bn == NULL || bn->internal == NULL)
35342
0
        return WOLFSSL_FAILURE;
35343
35344
66
    if (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ)
35345
12
        return WOLFSSL_SUCCESS;
35346
35347
54
    return WOLFSSL_FAILURE;
35348
66
}
35349
35350
/* return compliant with OpenSSL
35351
 *   1 if BIGNUM is odd, 0 else */
35352
int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
35353
32
{
35354
32
    WOLFSSL_MSG("wolfSSL_BN_is_odd");
35355
35356
32
    if (bn == NULL || bn->internal == NULL)
35357
0
        return WOLFSSL_FAILURE;
35358
35359
32
    if (mp_isodd((mp_int*)bn->internal) == MP_YES)
35360
22
        return WOLFSSL_SUCCESS;
35361
35362
10
    return WOLFSSL_FAILURE;
35363
32
}
35364
35365
/* return compliant with OpenSSL
35366
 *   1 if BIGNUM is word, 0 else */
35367
int wolfSSL_BN_is_word(const WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
35368
0
{
35369
0
    WOLFSSL_MSG("wolfSSL_BN_is_word");
35370
35371
0
    if (bn == NULL || bn->internal == NULL) {
35372
0
        WOLFSSL_MSG("bn NULL error");
35373
0
        return WOLFSSL_FAILURE;
35374
0
    }
35375
35376
0
    if (w <= (WOLFSSL_BN_ULONG)MP_MASK) {
35377
0
        if (mp_isword((mp_int*)bn->internal, (mp_digit)w) == MP_YES) {
35378
0
            return WOLFSSL_SUCCESS;
35379
0
        }
35380
0
    } else {
35381
0
        int ret;
35382
0
        mp_int w_mp;
35383
0
        if (mp_init(&w_mp) != MP_OKAY)
35384
0
            return WOLFSSL_FAILURE;
35385
0
        if (mp_set_int(&w_mp, w) != MP_OKAY)
35386
0
            return WOLFSSL_FAILURE;
35387
0
        ret = mp_cmp((mp_int *)bn->internal, &w_mp);
35388
0
        mp_free(&w_mp);
35389
0
        if (ret == MP_EQ)
35390
0
            return WOLFSSL_SUCCESS;
35391
0
    }
35392
35393
0
    return WOLFSSL_FAILURE;
35394
0
}
35395
35396
/* return compliant with OpenSSL
35397
 *   -1 if a < b, 0 if a == b and 1 if a > b
35398
 */
35399
int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
35400
246
{
35401
246
    int ret;
35402
35403
246
    WOLFSSL_MSG("wolfSSL_BN_cmp");
35404
35405
246
    if (a == NULL || a->internal == NULL || b == NULL || b->internal == NULL)
35406
0
        return WOLFSSL_FATAL_ERROR;
35407
35408
246
    ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
35409
35410
246
    return (ret == MP_EQ ? 0 : (ret == MP_GT ? 1 : -1));
35411
246
}
35412
35413
/* return compliant with OpenSSL
35414
 *   length of BIGNUM in bytes, -1 if error */
35415
int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
35416
266
{
35417
266
    WOLFSSL_MSG("wolfSSL_BN_bn2bin");
35418
35419
266
    if (bn == NULL || bn->internal == NULL) {
35420
0
        WOLFSSL_MSG("NULL bn error");
35421
0
        return WOLFSSL_FATAL_ERROR;
35422
0
    }
35423
35424
266
    if (r == NULL)
35425
0
        return mp_unsigned_bin_size((mp_int*)bn->internal);
35426
35427
266
    if (mp_to_unsigned_bin((mp_int*)bn->internal, r) != MP_OKAY) {
35428
0
        WOLFSSL_MSG("mp_to_unsigned_bin error");
35429
0
        return WOLFSSL_FATAL_ERROR;
35430
0
    }
35431
35432
266
    return mp_unsigned_bin_size((mp_int*)bn->internal);
35433
266
}
35434
35435
35436
WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len,
35437
                            WOLFSSL_BIGNUM* ret)
35438
11.0k
{
35439
11.0k
    int weOwn = 0;
35440
35441
11.0k
    WOLFSSL_MSG("wolfSSL_BN_bin2bn");
35442
35443
    /* if ret is null create a BN */
35444
11.0k
    if (ret == NULL) {
35445
0
        ret = wolfSSL_BN_new();
35446
0
        weOwn = 1;
35447
0
        if (ret == NULL)
35448
0
            return NULL;
35449
0
    }
35450
35451
    /* check ret and ret->internal then read in value */
35452
11.0k
    if (ret && ret->internal) {
35453
11.0k
        if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) {
35454
0
            WOLFSSL_MSG("mp_read_unsigned_bin failure");
35455
0
            if (weOwn)
35456
0
                wolfSSL_BN_free(ret);
35457
0
            return NULL;
35458
0
        }
35459
11.0k
    } else {
35460
        /* This may be overly defensive */
35461
0
        if (weOwn)
35462
0
            wolfSSL_BN_free(ret);
35463
0
        return NULL;
35464
0
    }
35465
35466
11.0k
    return ret;
35467
11.0k
}
35468
35469
/* return compliant with OpenSSL
35470
 *   1 if success, 0 if error */
35471
#ifndef NO_WOLFSSL_STUB
35472
int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
35473
0
{
35474
0
    (void)bn;
35475
0
    (void)n;
35476
0
    WOLFSSL_ENTER("wolfSSL_BN_mask_bits");
35477
0
    WOLFSSL_STUB("BN_mask_bits");
35478
0
    return SSL_FAILURE;
35479
0
}
35480
#endif
35481
35482
/* WOLFSSL_SUCCESS on ok */
35483
int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
35484
0
{
35485
0
    int ret = WOLFSSL_SUCCESS;
35486
0
    int len = (bits + 7) / 8;
35487
0
    WC_RNG* rng = &globalRNG;
35488
0
    byte* buff = NULL;
35489
35490
0
    WOLFSSL_ENTER("wolfSSL_BN_rand");
35491
35492
0
    if ((bn == NULL || bn->internal == NULL) || bits < 0 ||
35493
0
        (bits == 0 && (bottom != 0 || top != -1)) || (bits == 1 && top > 0)) {
35494
0
        WOLFSSL_MSG("Bad argument");
35495
0
        ret = WOLFSSL_FAILURE;
35496
0
    }
35497
35498
0
    if (ret == WOLFSSL_SUCCESS) {
35499
0
        if (len == 0) {
35500
0
            mp_zero((mp_int*)bn->internal);
35501
0
        }
35502
0
        else {
35503
0
            buff = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35504
0
            if (buff == NULL) {
35505
0
                WOLFSSL_MSG("Failed to allocate buffer.");
35506
0
                XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35507
0
                ret = WOLFSSL_FAILURE;
35508
0
            }
35509
35510
0
            if (ret == WOLFSSL_SUCCESS && initGlobalRNG == 0 &&
35511
0
                wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
35512
0
                WOLFSSL_MSG("Failed to use global RNG.");
35513
0
                ret = WOLFSSL_FAILURE;
35514
0
            }
35515
35516
0
            if (ret == WOLFSSL_SUCCESS &&
35517
0
                wc_RNG_GenerateBlock(rng, buff, len) != 0) {
35518
0
                WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
35519
0
                ret = WOLFSSL_FAILURE;
35520
0
            }
35521
0
            if (ret == WOLFSSL_SUCCESS &&
35522
0
                mp_read_unsigned_bin((mp_int*)bn->internal,buff,len)
35523
0
                != MP_OKAY) {
35524
0
                    WOLFSSL_MSG("mp_read_unsigned_bin failed");
35525
0
                    ret = WOLFSSL_FAILURE;
35526
0
            }
35527
0
            if (ret == WOLFSSL_SUCCESS) {
35528
                /* Truncate to requested bit length. */
35529
0
                mp_rshb((mp_int*)bn->internal, 8 - (bits % 8));
35530
35531
0
                if (top == 0) {
35532
0
                    if (mp_set_bit((mp_int*)bn->internal, bits - 1)
35533
0
                        != MP_OKAY) {
35534
0
                        WOLFSSL_MSG("Failed to set top bit");
35535
0
                        ret = WOLFSSL_FAILURE;
35536
0
                    }
35537
0
                }
35538
0
                else if (top > 0) {
35539
0
                    if (mp_set_bit((mp_int*)bn->internal, bits - 1)
35540
0
                        != MP_OKAY ||
35541
0
                        mp_set_bit((mp_int*)bn->internal, bits - 2)
35542
0
                        != MP_OKAY) {
35543
0
                        WOLFSSL_MSG("Failed to set top 2 bits");
35544
0
                        ret = WOLFSSL_FAILURE;
35545
0
                    }
35546
0
                }
35547
0
            }
35548
0
            if (ret == WOLFSSL_SUCCESS && bottom &&
35549
0
                mp_set_bit((mp_int*)bn->internal, 0) != MP_OKAY) {
35550
0
                WOLFSSL_MSG("Failed to set 0th bit");
35551
0
                ret = WOLFSSL_FAILURE;
35552
0
            }
35553
35554
0
            if (buff != NULL) {
35555
0
                XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35556
0
            }
35557
0
        }
35558
0
    }
35559
35560
0
    WOLFSSL_LEAVE("wolfSSL_BN_rand", ret);
35561
35562
0
    return ret;
35563
0
}
35564
35565
/**
35566
 * N = length of range input var
35567
 * Generate N-bit length numbers until generated number is less than range
35568
 * @param r     Output number
35569
 * @param range The upper limit of generated output
35570
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
35571
 */
35572
int wolfSSL_BN_rand_range(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *range)
35573
0
{
35574
0
    int n;
35575
0
    int iter = 0;
35576
0
    WOLFSSL_MSG("wolfSSL_BN_rand_range");
35577
35578
0
    if (r == NULL || range == NULL) {
35579
0
        WOLFSSL_MSG("Bad parameter");
35580
0
        return WOLFSSL_FAILURE;
35581
0
    }
35582
35583
0
    n = wolfSSL_BN_num_bits(range);
35584
35585
0
    if (n <= 1) {
35586
0
        wolfSSL_BN_zero(r);
35587
0
    }
35588
0
    else {
35589
0
        do {
35590
0
            if (iter >= 100) {
35591
0
                WOLFSSL_MSG("wolfSSL_BN_rand_range too many iterations");
35592
0
                return WOLFSSL_FAILURE;
35593
0
            }
35594
0
            iter++;
35595
0
            if (wolfSSL_BN_pseudo_rand(r, n, -1, 0) == WOLFSSL_FAILURE) {
35596
0
                WOLFSSL_MSG("wolfSSL_BN_rand error");
35597
0
                return WOLFSSL_FAILURE;
35598
0
            }
35599
0
        } while(wolfSSL_BN_cmp(r, range) >= 0);
35600
0
    }
35601
0
    return WOLFSSL_SUCCESS;
35602
0
}
35603
35604
/* WOLFSSL_SUCCESS on ok
35605
 * code is same as wolfSSL_BN_rand except for how top and bottom is handled.
35606
 * top -1 then leave most sig bit alone
35607
 * top 0 then most sig is set to 1
35608
 * top is 1 then first two most sig bits are 1
35609
 *
35610
 * bottom is hot then odd number */
35611
int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
35612
0
{
35613
0
    int           ret    = 0;
35614
0
    int           len;
35615
0
    int           initTmpRng = 0;
35616
0
    WC_RNG*       rng    = NULL;
35617
0
#ifdef WOLFSSL_SMALL_STACK
35618
0
    WC_RNG*       tmpRNG = NULL;
35619
0
    byte*         buff   = NULL;
35620
#else
35621
    WC_RNG        tmpRNG[1];
35622
    byte          buff[1024];
35623
#endif
35624
35625
0
    WOLFSSL_ENTER("wolfSSL_BN_pseudo_rand");
35626
35627
0
    if (bits <= 0) {
35628
0
        return WOLFSSL_FAILURE;
35629
0
    }
35630
35631
0
    len = bits / 8;
35632
0
    if (bits % 8)
35633
0
        len++;
35634
35635
    /* has to be a length of at least 1 since we set buf[0] and buf[len-1] */
35636
0
    if (top == 1 || top == 0 || bottom == 1) {
35637
0
        if (len < 1) {
35638
0
            return WOLFSSL_FAILURE;
35639
0
        }
35640
0
    }
35641
35642
0
#ifdef WOLFSSL_SMALL_STACK
35643
0
    buff   = (byte*)XMALLOC(1024,        NULL, DYNAMIC_TYPE_TMP_BUFFER);
35644
0
    tmpRNG = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER);
35645
0
    if (buff == NULL || tmpRNG == NULL) {
35646
0
        XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
35647
0
        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35648
0
        return ret;
35649
0
    }
35650
0
#endif
35651
35652
0
    if (bn == NULL || bn->internal == NULL)
35653
0
        WOLFSSL_MSG("Bad function arguments");
35654
0
    else if (wc_InitRng(tmpRNG) == 0) {
35655
0
        rng = tmpRNG;
35656
0
        initTmpRng = 1;
35657
0
    }
35658
0
    else if (initGlobalRNG)
35659
0
        rng = &globalRNG;
35660
35661
0
    if (rng) {
35662
0
        if (wc_RNG_GenerateBlock(rng, buff, len) != 0)
35663
0
            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
35664
0
        else {
35665
0
            switch (top) {
35666
0
                case -1:
35667
0
                    break;
35668
35669
0
                case 0:
35670
0
                    buff[0] |= 0x80;
35671
0
                    break;
35672
35673
0
                case 1:
35674
0
                    buff[0] |= 0x80 | 0x40;
35675
0
                    break;
35676
0
            }
35677
35678
0
            if (bottom == 1) {
35679
0
                buff[len-1] |= 0x01;
35680
0
            }
35681
35682
0
            if (mp_read_unsigned_bin((mp_int*)bn->internal,buff,len) != MP_OKAY)
35683
0
                WOLFSSL_MSG("mp read bin failed");
35684
0
            else
35685
0
                ret = WOLFSSL_SUCCESS;
35686
0
        }
35687
0
    }
35688
35689
0
    if (initTmpRng)
35690
0
        wc_FreeRng(tmpRNG);
35691
35692
0
#ifdef WOLFSSL_SMALL_STACK
35693
0
    XFREE(buff,   NULL, DYNAMIC_TYPE_TMP_BUFFER);
35694
0
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_TMP_BUFFER);
35695
0
#endif
35696
35697
0
    return ret;
35698
0
}
35699
35700
/* return code compliant with OpenSSL :
35701
 *   1 if bit set, 0 else
35702
 */
35703
int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
35704
0
{
35705
0
    if (bn == NULL || bn->internal == NULL) {
35706
0
        WOLFSSL_MSG("bn NULL error");
35707
0
        return WOLFSSL_FAILURE;
35708
0
    }
35709
35710
0
    return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
35711
0
}
35712
35713
/* return code compliant with OpenSSL :
35714
 *   1 if success, 0 else
35715
 */
35716
int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
35717
0
{
35718
0
    if (bn == NULL || bn->internal == NULL) {
35719
0
        WOLFSSL_MSG("bn NULL error");
35720
0
        return WOLFSSL_FAILURE;
35721
0
    }
35722
35723
0
    if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
35724
0
        WOLFSSL_MSG("mp_set_bit error");
35725
0
        return WOLFSSL_FAILURE;
35726
0
    }
35727
35728
0
    return WOLFSSL_SUCCESS;
35729
0
}
35730
35731
35732
int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n)
35733
0
{
35734
0
    int ret = WOLFSSL_FAILURE;
35735
#ifndef WOLFSSL_SMALL_STACK
35736
    mp_int tmp[1];
35737
#else
35738
0
    mp_int* tmp = NULL;
35739
0
#endif
35740
35741
0
    if (bn == NULL || bn->internal == NULL) {
35742
0
        WOLFSSL_MSG("bn NULL error");
35743
0
        goto end;
35744
0
    }
35745
0
    if (mp_is_bit_set((mp_int*)bn->internal, n)) {
35746
0
#ifdef WOLFSSL_SMALL_STACK
35747
0
       tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
35748
0
       if (tmp == NULL) {
35749
0
           goto end;
35750
0
       }
35751
0
#endif
35752
0
        if (mp_init(tmp) != MP_OKAY) {
35753
0
            goto end;
35754
0
        }
35755
0
        if (mp_set_bit(tmp, n) != MP_OKAY) {
35756
0
            goto cleanup;
35757
0
        }
35758
0
        if (mp_sub((mp_int*)bn->internal, tmp, (mp_int*)bn->internal) != MP_OKAY) {
35759
0
            goto cleanup;
35760
0
        }
35761
0
    } else {
35762
0
        goto end;
35763
0
    }
35764
35765
0
    ret = WOLFSSL_SUCCESS;
35766
0
cleanup:
35767
0
    mp_clear(tmp);
35768
35769
0
end:
35770
0
#ifdef WOLFSSL_SMALL_STACK
35771
0
    if (tmp)
35772
0
        XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
35773
0
#endif
35774
0
    return ret;
35775
0
}
35776
35777
35778
/* WOLFSSL_SUCCESS on ok */
35779
/* Note on use: this function expects str to be an even length. It is
35780
 * converting pairs of bytes into 8-bit values. As an example, the RSA
35781
 * public exponent is commonly 0x010001. To get it to convert, you need
35782
 * to pass in the string "010001", it will fail if you use "10001". This
35783
 * is an affect of how Base16_Decode() works.
35784
 */
35785
int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
35786
11.1k
{
35787
11.1k
    int     ret     = 0;
35788
11.1k
    word32  decSz   = 1024;
35789
11.1k
#ifdef WOLFSSL_SMALL_STACK
35790
11.1k
    byte*   decoded;
35791
#else
35792
    byte    decoded[1024];
35793
#endif
35794
11.1k
    int     weOwn = 0;
35795
11.1k
    int     strLen;
35796
35797
11.1k
    WOLFSSL_MSG("wolfSSL_BN_hex2bn");
35798
35799
11.1k
#ifdef WOLFSSL_SMALL_STACK
35800
11.1k
    decoded = (byte*)XMALLOC(decSz, NULL, DYNAMIC_TYPE_DER);
35801
11.1k
    if (decoded == NULL)
35802
0
        return ret;
35803
11.1k
#endif
35804
35805
11.1k
    if (str == NULL || str[0] == '\0') {
35806
0
        WOLFSSL_MSG("Bad function argument");
35807
0
        ret = WOLFSSL_FAILURE;
35808
11.1k
    } else {
35809
11.1k
        strLen = (int)XSTRLEN(str);
35810
        /* ignore trailing new lines */
35811
11.1k
        while (str[strLen-1] == '\n' && strLen > 0) strLen--;
35812
35813
11.1k
        if (Base16_Decode((byte*)str, strLen, decoded, &decSz) < 0)
35814
119
            WOLFSSL_MSG("Bad Base16_Decode error");
35815
11.0k
        else if (bn == NULL)
35816
0
            ret = decSz;
35817
11.0k
        else {
35818
11.0k
            if (*bn == NULL) {
35819
0
                *bn = wolfSSL_BN_new();
35820
0
                if (*bn != NULL) {
35821
0
                    weOwn = 1;
35822
0
                }
35823
0
            }
35824
35825
11.0k
            if (*bn == NULL)
35826
0
                WOLFSSL_MSG("BN new failed");
35827
11.0k
            else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) {
35828
0
                WOLFSSL_MSG("Bad bin2bn error");
35829
0
                if (weOwn == 1) {
35830
0
                    wolfSSL_BN_free(*bn); /* Free new BN */
35831
0
                }
35832
0
            }
35833
11.0k
            else
35834
11.0k
                ret = WOLFSSL_SUCCESS;
35835
11.0k
        }
35836
11.1k
    }
35837
35838
11.1k
#ifdef WOLFSSL_SMALL_STACK
35839
11.1k
    XFREE(decoded, NULL, DYNAMIC_TYPE_DER);
35840
11.1k
#endif
35841
35842
11.1k
    return ret;
35843
11.1k
}
35844
35845
35846
WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
35847
351
{
35848
351
    WOLFSSL_BIGNUM* ret;
35849
35850
351
    WOLFSSL_MSG("wolfSSL_BN_dup");
35851
35852
351
    if (bn == NULL || bn->internal == NULL) {
35853
0
        WOLFSSL_MSG("bn NULL error");
35854
0
        return NULL;
35855
0
    }
35856
35857
351
    ret = wolfSSL_BN_new();
35858
351
    if (ret == NULL) {
35859
0
        WOLFSSL_MSG("bn new error");
35860
0
        return NULL;
35861
0
    }
35862
35863
351
    if (mp_copy((mp_int*)bn->internal, (mp_int*)ret->internal) != MP_OKAY) {
35864
0
        WOLFSSL_MSG("mp_copy error");
35865
0
        wolfSSL_BN_free(ret);
35866
0
        return NULL;
35867
0
    }
35868
35869
351
    ret->neg = bn->neg;
35870
35871
351
    return ret;
35872
351
}
35873
35874
35875
WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
35876
0
{
35877
0
    WOLFSSL_MSG("wolfSSL_BN_copy");
35878
35879
0
    if (r == NULL || bn == NULL) {
35880
0
        WOLFSSL_MSG("r or bn NULL error");
35881
0
        return NULL;
35882
0
    }
35883
35884
0
    if (mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) != MP_OKAY) {
35885
0
        WOLFSSL_MSG("mp_copy error");
35886
0
        return NULL;
35887
0
    }
35888
35889
0
    r->neg = bn->neg;
35890
35891
0
    return r;
35892
0
}
35893
35894
/* return code compliant with OpenSSL :
35895
 *   1 if success, 0 else
35896
 */
35897
int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, unsigned long w)
35898
0
{
35899
0
    WOLFSSL_MSG("wolfSSL_BN_set_word");
35900
35901
0
    if (bn == NULL) {
35902
0
        WOLFSSL_MSG("bn NULL error");
35903
0
        return WOLFSSL_FAILURE;
35904
0
    }
35905
35906
0
    if (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY) {
35907
0
        WOLFSSL_MSG("mp_init_set_int error");
35908
0
        return WOLFSSL_FAILURE;
35909
0
    }
35910
35911
0
    return WOLFSSL_SUCCESS;
35912
0
}
35913
35914
0
static WOLFSSL_BN_ULONG wolfSSL_BN_get_word_1(mp_int *mp) {
35915
0
#if DIGIT_BIT >= (SIZEOF_LONG * CHAR_BIT)
35916
0
    return (WOLFSSL_BN_ULONG)mp->dp[0];
35917
#else
35918
    WOLFSSL_BN_ULONG ret = 0UL;
35919
    int digit_i;
35920
35921
    for (digit_i = 0; digit_i < mp->used; ++digit_i)
35922
        ret |= ((WOLFSSL_BN_ULONG)mp->dp[digit_i]) << (DIGIT_BIT * digit_i);
35923
35924
    return ret;
35925
#endif
35926
0
}
35927
35928
/* Returns the big number as an unsigned long if possible.
35929
 *
35930
 * bn  big number structure to get value from
35931
 *
35932
 * Returns value or 0xFFFFFFFFL if bigger than unsigned long.
35933
 */
35934
WOLFSSL_BN_ULONG wolfSSL_BN_get_word(const WOLFSSL_BIGNUM* bn)
35935
0
{
35936
0
    WOLFSSL_MSG("wolfSSL_BN_get_word");
35937
35938
0
    if (bn == NULL) {
35939
0
        WOLFSSL_MSG("Invalid argument");
35940
0
        return 0;
35941
0
    }
35942
35943
0
    if (wolfSSL_BN_num_bytes(bn) > (int)sizeof(unsigned long)) {
35944
0
        WOLFSSL_MSG("bignum is larger than unsigned long");
35945
0
        return 0xFFFFFFFFL;
35946
0
    }
35947
35948
0
    return wolfSSL_BN_get_word_1((mp_int*)bn->internal);
35949
0
}
35950
35951
/* return code compliant with OpenSSL :
35952
 *   number length in decimal if success, 0 if error
35953
 */
35954
#ifndef NO_WOLFSSL_STUB
35955
int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
35956
0
{
35957
0
    (void)bn;
35958
0
    (void)str;
35959
35960
0
    WOLFSSL_MSG("wolfSSL_BN_dec2bn");
35961
0
    WOLFSSL_STUB("BN_dec2bn");
35962
0
    return SSL_FAILURE;
35963
0
}
35964
#endif
35965
35966
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
35967
char *wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
35968
897
{
35969
897
    int len = 0;
35970
897
    char *buf;
35971
35972
897
    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
35973
35974
897
    if (bn == NULL || bn->internal == NULL) {
35975
0
        WOLFSSL_MSG("bn NULL error");
35976
0
        return NULL;
35977
0
    }
35978
35979
897
    if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_DEC, &len) != MP_OKAY) {
35980
0
        WOLFSSL_MSG("mp_radix_size failure");
35981
0
        return NULL;
35982
0
    }
35983
35984
897
    buf = (char*) XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
35985
897
    if (buf == NULL) {
35986
0
        WOLFSSL_MSG("BN_bn2dec malloc buffer failure");
35987
0
        return NULL;
35988
0
    }
35989
35990
897
    if (mp_todecimal((mp_int*)bn->internal, buf) != MP_OKAY) {
35991
0
        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
35992
0
        return NULL;
35993
0
    }
35994
35995
897
    return buf;
35996
897
}
35997
#else
35998
char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
35999
{
36000
    (void)bn;
36001
36002
    WOLFSSL_MSG("wolfSSL_BN_bn2dec");
36003
36004
    return NULL;
36005
}
36006
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
36007
36008
/* Internal function for adding/subtracting an unsigned long from a
36009
 * WOLFSSL_BIGNUM. To add, pass "sub" as 0. To subtract, pass it as 1.
36010
 * Returns 1 (WOLFSSL_SUCCESS) on success and 0 (WOLFSSL_FAILURE) on failure.
36011
 */
36012
static int wolfSSL_BN_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
36013
                                   int sub)
36014
0
{
36015
0
    int ret = WOLFSSL_SUCCESS;
36016
0
    int rc = 0;
36017
0
#ifdef WOLFSSL_SMALL_STACK
36018
0
    mp_int *w_mp = (mp_int *)XMALLOC(sizeof(*w_mp), NULL,
36019
0
                                     DYNAMIC_TYPE_TMP_BUFFER);
36020
0
    if (w_mp == NULL)
36021
0
        return WOLFSSL_FAILURE;
36022
#else
36023
    mp_int w_mp[1];
36024
#endif
36025
36026
0
    XMEMSET(w_mp, 0, sizeof(*w_mp));
36027
36028
0
    if (bn == NULL || bn->internal == NULL) {
36029
0
        WOLFSSL_MSG("bn NULL error");
36030
0
        ret = WOLFSSL_FAILURE;
36031
0
    }
36032
36033
0
    if (ret == WOLFSSL_SUCCESS) {
36034
0
        if (w <= (WOLFSSL_BN_ULONG)MP_MASK) {
36035
0
            if (sub == 1) {
36036
0
                rc = mp_sub_d((mp_int*)bn->internal, (mp_digit)w,
36037
0
                              (mp_int*)bn->internal);
36038
0
            }
36039
0
            else {
36040
0
                rc = mp_add_d((mp_int*)bn->internal, (mp_digit)w,
36041
0
                              (mp_int*)bn->internal);
36042
0
            }
36043
0
            if (rc != MP_OKAY) {
36044
0
                WOLFSSL_MSG("mp_add/sub_d error");
36045
0
                ret = WOLFSSL_FAILURE;
36046
0
            }
36047
0
        }
36048
0
        else {
36049
0
            if (mp_init(w_mp) != MP_OKAY) {
36050
0
                ret = WOLFSSL_FAILURE;
36051
0
            }
36052
0
            if (ret == WOLFSSL_SUCCESS) {
36053
0
                if (mp_set_int(w_mp, w) != MP_OKAY) {
36054
0
                    ret = WOLFSSL_FAILURE;
36055
0
                }
36056
0
            }
36057
0
            if (ret == WOLFSSL_SUCCESS) {
36058
0
                if (sub == 1) {
36059
0
                    rc = mp_sub((mp_int *)bn->internal, w_mp,
36060
0
                                (mp_int *)bn->internal);
36061
0
                }
36062
0
                else {
36063
0
                    rc = mp_add((mp_int *)bn->internal, w_mp,
36064
0
                                (mp_int *)bn->internal);
36065
0
                }
36066
0
                if (rc != MP_OKAY) {
36067
0
                    WOLFSSL_MSG("mp_add/sub error");
36068
0
                    ret = WOLFSSL_FAILURE;
36069
0
                }
36070
0
            }
36071
0
        }
36072
0
    }
36073
36074
0
    mp_free(w_mp);
36075
36076
0
#ifdef WOLFSSL_SMALL_STACK
36077
0
    XFREE(w_mp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36078
0
#endif
36079
36080
0
    return ret;
36081
0
}
36082
36083
/* return code compliant with OpenSSL :
36084
 *   1 if success, 0 else
36085
 */
36086
int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
36087
0
{
36088
0
    int ret;
36089
36090
0
    WOLFSSL_ENTER("wolfSSL_BN_add_word");
36091
36092
0
    ret = wolfSSL_BN_add_word_int(bn, w, 0);
36093
36094
0
    WOLFSSL_LEAVE("wolfSSL_BN_add_word", ret);
36095
36096
0
    return ret;
36097
0
}
36098
36099
/* return code compliant with OpenSSL :
36100
 *   1 if success, 0 else
36101
 */
36102
WOLFSSL_API int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
36103
0
{
36104
0
    int ret;
36105
36106
0
    WOLFSSL_ENTER("wolfSSL_BN_sub_word");
36107
36108
0
    ret = wolfSSL_BN_add_word_int(bn, w, 1);
36109
36110
0
    WOLFSSL_LEAVE("wolfSSL_BN_sub_word", ret);
36111
36112
0
    return ret;
36113
0
}
36114
36115
#ifndef WOLFSSL_SP_MATH
36116
/* return code compliant with OpenSSL :
36117
 *   1 if success, 0 else
36118
 */
36119
int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
36120
0
{
36121
0
    WOLFSSL_MSG("wolfSSL_BN_lshift");
36122
36123
0
    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
36124
0
        WOLFSSL_MSG("bn NULL error");
36125
0
        return WOLFSSL_FAILURE;
36126
0
    }
36127
36128
0
    if (mp_mul_2d((mp_int*)bn->internal, n, (mp_int*)r->internal) != MP_OKAY) {
36129
0
        WOLFSSL_MSG("mp_mul_2d error");
36130
0
        return WOLFSSL_FAILURE;
36131
0
    }
36132
36133
0
    return WOLFSSL_SUCCESS;
36134
0
}
36135
36136
/* return code compliant with OpenSSL :
36137
 *   1 if success, 0 else
36138
 */
36139
int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
36140
0
{
36141
0
    WOLFSSL_MSG("wolfSSL_BN_rshift");
36142
36143
0
    if (r == NULL || r->internal == NULL || bn == NULL || bn->internal == NULL){
36144
0
        WOLFSSL_MSG("bn NULL error");
36145
0
        return WOLFSSL_FAILURE;
36146
0
    }
36147
36148
0
    if (mp_div_2d((mp_int*)bn->internal, n,
36149
0
                  (mp_int*)r->internal, NULL) != MP_OKAY) {
36150
0
        WOLFSSL_MSG("mp_mul_2d error");
36151
0
        return WOLFSSL_FAILURE;
36152
0
    }
36153
36154
0
    return WOLFSSL_SUCCESS;
36155
0
}
36156
#endif
36157
36158
/* return code compliant with OpenSSL :
36159
 *   1 if success, 0 else
36160
 */
36161
int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
36162
9
{
36163
9
    WOLFSSL_MSG("wolfSSL_BN_add");
36164
36165
9
    if (r == NULL || r->internal == NULL || a == NULL || a->internal == NULL ||
36166
9
        b == NULL || b->internal == NULL) {
36167
0
        WOLFSSL_MSG("bn NULL error");
36168
0
        return WOLFSSL_FAILURE;
36169
0
    }
36170
36171
9
    if (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
36172
9
               (mp_int*)r->internal) != MP_OKAY) {
36173
0
        WOLFSSL_MSG("mp_add_d error");
36174
0
        return WOLFSSL_FAILURE;
36175
0
    }
36176
36177
9
    return WOLFSSL_SUCCESS;
36178
9
}
36179
36180
#ifndef WOLFSSL_SP_MATH
36181
/* r = a + b (mod m) */
36182
int wolfSSL_BN_mod_add(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
36183
                       const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m,
36184
                       WOLFSSL_BN_CTX *ctx)
36185
31
{
36186
31
    (void)ctx;
36187
31
    WOLFSSL_MSG("wolfSSL_BN_add");
36188
36189
31
    if (r == NULL || r->internal == NULL ||
36190
31
            a == NULL || a->internal == NULL ||
36191
31
            b == NULL || b->internal == NULL ||
36192
31
            m == NULL || m->internal == NULL) {
36193
0
        WOLFSSL_MSG("bn NULL error");
36194
0
        return WOLFSSL_FAILURE;
36195
0
    }
36196
36197
31
    if (mp_addmod((mp_int*)a->internal, (mp_int*)b->internal,
36198
31
                  (mp_int*)m->internal, (mp_int*)r->internal) != MP_OKAY) {
36199
11
        WOLFSSL_MSG("mp_add_d error");
36200
11
        return WOLFSSL_FAILURE;
36201
11
    }
36202
36203
20
    return WOLFSSL_SUCCESS;
36204
31
}
36205
#endif
36206
36207
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA))
36208
36209
int wolfSSL_BN_generate_prime_ex(WOLFSSL_BIGNUM* prime, int bits,
36210
    int safe, const WOLFSSL_BIGNUM* add, const WOLFSSL_BIGNUM* rem,
36211
    WOLFSSL_BN_GENCB* cb)
36212
0
{
36213
0
    int ret = WOLFSSL_SUCCESS;
36214
0
#ifdef WOLFSSL_SMALL_STACK
36215
0
    WC_RNG* rng = NULL;
36216
#else
36217
    WC_RNG rng[1];
36218
#endif
36219
36220
0
    (void)cb;
36221
36222
0
    WOLFSSL_ENTER("wolfSSL_BN_generate_prime_ex");
36223
36224
0
    if (safe == 1 || add != NULL || rem != NULL) {
36225
        /* These parameters aren't supported, yet. */
36226
0
        ret = WOLFSSL_FAILURE;
36227
0
    }
36228
36229
0
    if (prime == NULL || prime->internal == NULL) {
36230
0
        ret = WOLFSSL_FAILURE;
36231
0
    }
36232
36233
0
#ifdef WOLFSSL_SMALL_STACK
36234
0
    if (ret == WOLFSSL_SUCCESS) {
36235
0
        rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
36236
0
        if (rng == NULL) {
36237
0
            ret = WOLFSSL_FAILURE;
36238
0
        }
36239
0
    }
36240
0
#endif
36241
0
    if (ret == WOLFSSL_SUCCESS) {
36242
0
        XMEMSET(rng, 0, sizeof(WC_RNG));
36243
0
        if (wc_InitRng(rng) != 0) {
36244
0
            ret = WOLFSSL_FAILURE;
36245
0
        }
36246
0
    }
36247
36248
0
    if (ret == WOLFSSL_SUCCESS) {
36249
0
        if (mp_rand_prime((mp_int*)prime->internal, (bits + 7) / 8, rng, NULL)
36250
0
                != MP_OKAY) {
36251
0
            ret = WOLFSSL_FAILURE;
36252
0
        }
36253
0
    }
36254
36255
0
    wc_FreeRng(rng);
36256
0
#ifdef WOLFSSL_SMALL_STACK
36257
0
    if (rng != NULL)
36258
0
        XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
36259
0
#endif
36260
36261
0
    WOLFSSL_LEAVE("wolfSSL_BN_generate_prime_ex", ret);
36262
36263
0
    return ret;
36264
0
}
36265
36266
/* return code compliant with OpenSSL :
36267
 *   1 if prime, 0 if not, -1 if error
36268
 */
36269
int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int nbchecks,
36270
                           WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
36271
0
{
36272
0
    WC_RNG*        rng    = NULL;
36273
0
#ifdef WOLFSSL_SMALL_STACK
36274
0
    WC_RNG*        tmpRNG = NULL;
36275
#else
36276
    WC_RNG         tmpRNG[1];
36277
#endif
36278
0
    int            initTmpRng = 0;
36279
0
    int            res = MP_NO;
36280
36281
0
    (void)ctx;
36282
0
    (void)cb;
36283
36284
0
    WOLFSSL_MSG("wolfSSL_BN_is_prime_ex");
36285
36286
0
    if (bn == NULL || bn->internal == NULL) {
36287
0
        WOLFSSL_MSG("bn NULL error");
36288
0
        return WOLFSSL_FATAL_ERROR;
36289
0
    }
36290
36291
0
#ifdef WOLFSSL_SMALL_STACK
36292
0
    tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
36293
0
    if (tmpRNG == NULL)
36294
0
        return WOLFSSL_FAILURE;
36295
0
#endif
36296
0
    if (wc_InitRng(tmpRNG) == 0) {
36297
0
        rng = tmpRNG;
36298
0
        initTmpRng = 1;
36299
0
    }
36300
0
    else {
36301
0
        WOLFSSL_MSG("Bad RNG Init, trying global");
36302
0
        if (initGlobalRNG == 0) {
36303
0
            WOLFSSL_MSG("Global RNG no Init");
36304
0
        }
36305
0
        else
36306
0
            rng = &globalRNG;
36307
0
    }
36308
36309
0
    if (rng) {
36310
0
        if (mp_prime_is_prime_ex((mp_int*)bn->internal,
36311
0
                                 nbchecks, &res, rng) != MP_OKAY) {
36312
0
            WOLFSSL_MSG("mp_prime_is_prime_ex error");
36313
0
            res = MP_NO;
36314
0
        }
36315
0
    }
36316
36317
0
    if (initTmpRng)
36318
0
        wc_FreeRng(tmpRNG);
36319
0
#ifdef WOLFSSL_SMALL_STACK
36320
0
    XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
36321
0
#endif
36322
36323
0
    if (res != MP_YES) {
36324
0
        WOLFSSL_MSG("mp_prime_is_prime_ex not prime");
36325
0
        return WOLFSSL_FAILURE;
36326
0
    }
36327
36328
0
    return WOLFSSL_SUCCESS;
36329
0
}
36330
36331
/* return code compliant with OpenSSL :
36332
 *   (bn mod w) if success, -1 if error
36333
 */
36334
WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
36335
                                     WOLFSSL_BN_ULONG w)
36336
0
{
36337
0
    WOLFSSL_BN_ULONG ret = 0;
36338
36339
0
    WOLFSSL_MSG("wolfSSL_BN_mod_word");
36340
36341
0
    if (bn == NULL || bn->internal == NULL) {
36342
0
        WOLFSSL_MSG("bn NULL error");
36343
0
        return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
36344
0
    }
36345
36346
0
    if (w <= (WOLFSSL_BN_ULONG)MP_MASK) {
36347
0
        mp_digit bn_ret;
36348
0
        if (mp_mod_d((mp_int*)bn->internal, (mp_digit)w, &bn_ret) != MP_OKAY) {
36349
0
            WOLFSSL_MSG("mp_add_d error");
36350
0
            return (WOLFSSL_BN_ULONG)WOLFSSL_FATAL_ERROR;
36351
0
        }
36352
0
        ret = (WOLFSSL_BN_ULONG)bn_ret;
36353
0
    } else {
36354
0
        int mp_ret;
36355
0
        mp_int w_mp, r_mp;
36356
0
        if (mp_init(&w_mp) != MP_OKAY)
36357
0
            return (unsigned long)WOLFSSL_FAILURE;
36358
0
        if (mp_init(&r_mp) != MP_OKAY)
36359
0
            return (unsigned long)WOLFSSL_FAILURE;
36360
0
        if (mp_set_int(&w_mp, w) != MP_OKAY)
36361
0
            return (unsigned long)WOLFSSL_FAILURE;
36362
0
        mp_ret = mp_mod((mp_int *)bn->internal, &w_mp, &r_mp);
36363
0
        ret = wolfSSL_BN_get_word_1(&r_mp);
36364
0
        mp_free(&r_mp);
36365
0
        mp_free(&w_mp);
36366
0
        if (mp_ret != MP_OKAY) {
36367
0
            WOLFSSL_MSG("mp_mod error");
36368
0
            return (WOLFSSL_BN_ULONG)WOLFSSL_FAILURE;
36369
0
        }
36370
0
    }
36371
36372
0
    return ret;
36373
0
}
36374
#endif /* WOLFSSL_KEY_GEN && (!NO_RSA || !NO_DH || !NO_DSA) */
36375
36376
char *wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
36377
0
{
36378
0
    int len = 0;
36379
0
    char *buf;
36380
36381
0
    WOLFSSL_ENTER("wolfSSL_BN_bn2hex");
36382
36383
0
    if (bn == NULL || bn->internal == NULL) {
36384
0
        WOLFSSL_MSG("bn NULL error");
36385
0
        return NULL;
36386
0
    }
36387
36388
0
    if (mp_radix_size((mp_int*)bn->internal, MP_RADIX_HEX, &len) != MP_OKAY) {
36389
0
        WOLFSSL_MSG("mp_radix_size failure");
36390
0
        return NULL;
36391
0
    }
36392
36393
0
    buf = (char*)XMALLOC(len, NULL, DYNAMIC_TYPE_OPENSSL);
36394
0
    if (buf == NULL) {
36395
0
        WOLFSSL_MSG("BN_bn2hex malloc buffer failure");
36396
0
        return NULL;
36397
0
    }
36398
36399
0
    if (mp_tohex((mp_int*)bn->internal, buf) != MP_OKAY) {
36400
0
        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
36401
0
        return NULL;
36402
0
    }
36403
36404
0
    return buf;
36405
0
}
36406
36407
#ifndef NO_FILESYSTEM
36408
/* return code compliant with OpenSSL :
36409
 *   1 if success, 0 if error
36410
 */
36411
int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
36412
0
{
36413
0
    char *buf;
36414
0
    int ret;
36415
36416
0
    WOLFSSL_ENTER("wolfSSL_BN_print_fp");
36417
36418
0
    if (fp == XBADFILE || bn == NULL || bn->internal == NULL) {
36419
0
        WOLFSSL_MSG("bn NULL error");
36420
0
        return WOLFSSL_FAILURE;
36421
0
    }
36422
36423
0
    buf = wolfSSL_BN_bn2hex(bn);
36424
0
    if (buf == NULL) {
36425
0
        WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
36426
0
        return WOLFSSL_FAILURE;
36427
0
    }
36428
36429
0
    if (XFPRINTF(fp, "%s", buf) < 0)
36430
0
        ret = WOLFSSL_FAILURE;
36431
0
    else
36432
0
        ret = WOLFSSL_SUCCESS;
36433
36434
0
    XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
36435
36436
0
    return ret;
36437
0
}
36438
#endif /* !NO_FILESYSTEM */
36439
36440
36441
WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
36442
0
{
36443
    /* ctx is not used, return new Bignum */
36444
0
    (void)ctx;
36445
36446
0
    WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
36447
36448
0
    return wolfSSL_BN_new();
36449
0
}
36450
36451
#ifndef NO_WOLFSSL_STUB
36452
void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
36453
0
{
36454
0
    (void)ctx;
36455
36456
0
    WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
36457
0
    WOLFSSL_STUB("BN_CTX_start");
36458
0
    WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
36459
0
}
36460
#endif
36461
36462
36463
WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r,
36464
                                       WOLFSSL_BIGNUM *a,
36465
                                       const WOLFSSL_BIGNUM *n,
36466
                                       WOLFSSL_BN_CTX *ctx)
36467
397
{
36468
397
    int dynamic = 0;
36469
36470
    /* ctx is not used */
36471
397
    (void)ctx;
36472
36473
397
    WOLFSSL_ENTER("wolfSSL_BN_mod_inverse");
36474
36475
    /* check parameter */
36476
397
    if (r == NULL) {
36477
0
        r = wolfSSL_BN_new();
36478
0
        if (r == NULL){
36479
0
            WOLFSSL_MSG("WolfSSL_BN_new() failed");
36480
0
            return NULL;
36481
0
        }
36482
0
        dynamic = 1;
36483
0
    }
36484
36485
397
    if (a == NULL) {
36486
0
        WOLFSSL_MSG("a NULL error");
36487
0
        if (dynamic == 1) {
36488
0
            wolfSSL_BN_free(r);
36489
0
        }
36490
0
        return NULL;
36491
0
    }
36492
36493
397
    if (n == NULL) {
36494
0
        WOLFSSL_MSG("n NULL error");
36495
0
        if (dynamic == 1) {
36496
0
            wolfSSL_BN_free(r);
36497
0
        }
36498
0
        return NULL;
36499
0
    }
36500
36501
    /* Compute inverse of a modulo n and return r */
36502
397
    if (mp_invmod((mp_int *)a->internal,(mp_int *)n->internal,
36503
397
                  (mp_int*)r->internal) == MP_VAL){
36504
86
        WOLFSSL_MSG("mp_invmod() error");
36505
86
        if (dynamic == 1) {
36506
0
            wolfSSL_BN_free(r);
36507
0
        }
36508
86
        return NULL;
36509
86
    }
36510
36511
311
    return  r;
36512
397
}
36513
#endif  /* OPENSSL_EXTRA */
36514
#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && \
36515
    !defined(NO_ASN)
36516
#ifndef NO_BIO
36517
static int unprintable_char(char c)
36518
0
{
36519
0
    const unsigned char last_unprintable = 31;
36520
0
    const unsigned char LF = 10;
36521
0
    const unsigned char CR = 13;
36522
36523
0
    if (c <= last_unprintable && c != LF && c != CR) {
36524
0
        return 1;
36525
0
    }
36526
0
    return 0;
36527
0
}
36528
36529
int wolfSSL_ASN1_STRING_print(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str)
36530
0
{
36531
0
    int i;
36532
36533
0
    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_print");
36534
0
    if (out == NULL || str == NULL)
36535
0
           return WOLFSSL_FAILURE;
36536
36537
0
    for (i=0; i < str->length; i++) {
36538
0
        if (unprintable_char(str->data[i])) {
36539
0
            str->data[i] = '.';
36540
0
        }
36541
0
    }
36542
36543
0
    if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
36544
0
        return WOLFSSL_FAILURE;
36545
0
    }
36546
36547
0
    return str->length;
36548
0
}
36549
#endif /* !NO_BIO */
36550
#endif /* (WOLFSSL_QT || OPENSSL_ALL || OPENSSL_EXTRA) && !NO_ASN */
36551
36552
#if defined(OPENSSL_EXTRA)
36553
36554
const char *wolfSSL_ASN1_tag2str(int tag)
36555
0
{
36556
0
    static const char *const tag_label[31] = {
36557
0
        "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", "NULL",
36558
0
        "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", "ENUMERATED",
36559
0
        "<ASN1 11>", "UTF8STRING", "<ASN1 13>", "<ASN1 14>", "<ASN1 15>",
36560
0
        "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
36561
0
        "VIDEOTEXTSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
36562
0
        "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "UNIVERSALSTRING",
36563
0
        "<ASN1 29>", "BMPSTRING"
36564
0
    };
36565
36566
0
    if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
36567
0
        tag &= ~0x100;
36568
0
    if (tag < 0 || tag > 30)
36569
0
        return "(unknown)";
36570
0
    return tag_label[tag];
36571
0
}
36572
36573
#ifndef NO_BIO
36574
static int check_esc_char(char c, char *esc)
36575
0
{
36576
0
    char *ptr;
36577
36578
0
    ptr = esc;
36579
0
    while(*ptr != 0){
36580
0
        if (c == *ptr)
36581
0
            return 1;
36582
0
        ptr++;
36583
0
    }
36584
0
    return 0;
36585
0
}
36586
36587
int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str,
36588
                                 unsigned long flags)
36589
0
{
36590
0
    size_t str_len = 0, type_len = 0;
36591
0
    unsigned char *typebuf = NULL;
36592
0
    const char *hash="#";
36593
36594
0
    WOLFSSL_ENTER("wolfSSL_ASN1_STRING_PRINT_ex");
36595
0
    if (out == NULL || str == NULL)
36596
0
        return WOLFSSL_FAILURE;
36597
36598
    /* add ASN1 type tag */
36599
0
    if (flags & ASN1_STRFLGS_SHOW_TYPE){
36600
0
        const char *tag = wolfSSL_ASN1_tag2str(str->type);
36601
        /* colon len + tag len + null*/
36602
0
        type_len = XSTRLEN(tag) + 2;
36603
0
        typebuf = (unsigned char *)XMALLOC(type_len , NULL, DYNAMIC_TYPE_TMP_BUFFER);
36604
0
        if (typebuf == NULL){
36605
0
            WOLFSSL_MSG("memory alloc failed.");
36606
0
            return WOLFSSL_FAILURE;
36607
0
        }
36608
0
        XMEMSET(typebuf, 0, type_len);
36609
0
        if (XSNPRINTF((char*)typebuf, (size_t)type_len , "%s:", tag)
36610
0
            >= (int)type_len)
36611
0
        {
36612
0
            WOLFSSL_MSG("Buffer overrun.");
36613
0
            return WOLFSSL_FAILURE;
36614
0
        }
36615
0
        type_len--;
36616
0
    }
36617
36618
    /* dump hex */
36619
0
    if (flags & ASN1_STRFLGS_DUMP_ALL){
36620
0
        char hex_tmp[4];
36621
0
        char *str_ptr, *str_end;
36622
36623
0
        if (type_len > 0){
36624
0
            if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
36625
0
                XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36626
0
                return WOLFSSL_FAILURE;
36627
0
            }
36628
0
            str_len += type_len;
36629
0
        }
36630
0
        if (wolfSSL_BIO_write(out, hash, 1) != 1){
36631
0
            goto err_exit;
36632
0
        }
36633
0
        str_len++;
36634
0
        if (flags & ASN1_STRFLGS_DUMP_DER){
36635
0
            ByteToHexStr((byte)str->type, &hex_tmp[0]);
36636
0
            ByteToHexStr((byte)str->length, &hex_tmp[2]);
36637
0
            if (wolfSSL_BIO_write(out, hex_tmp, 4) != 4){
36638
0
                goto err_exit;
36639
0
            }
36640
0
            str_len += 4;
36641
0
            XMEMSET(hex_tmp, 0, 4);
36642
0
        }
36643
36644
0
        str_ptr = str->data;
36645
0
        str_end = str->data + str->length;
36646
0
        while (str_ptr < str_end){
36647
0
            ByteToHexStr((byte)*str_ptr, &hex_tmp[0]);
36648
0
            if (wolfSSL_BIO_write(out, hex_tmp, 2) != 2){
36649
0
                goto err_exit;
36650
0
            }
36651
0
            str_ptr++;
36652
0
            str_len += 2;
36653
0
        }
36654
0
        if (type_len > 0)
36655
0
            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36656
36657
0
        return (int)str_len;
36658
0
    }
36659
36660
0
    if (type_len > 0){
36661
0
        if (wolfSSL_BIO_write(out, typebuf, (int)type_len) != (int)type_len){
36662
0
            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36663
0
            return WOLFSSL_FAILURE;
36664
0
        }
36665
0
        str_len += type_len;
36666
0
    }
36667
36668
0
    if (flags & ASN1_STRFLGS_ESC_2253){
36669
0
        char esc_ch[] = "+;<>\\";
36670
0
        char* esc_ptr;
36671
36672
0
        esc_ptr = str->data;
36673
0
        while (*esc_ptr != 0){
36674
0
            if (check_esc_char(*esc_ptr, esc_ch)){
36675
0
                if (wolfSSL_BIO_write(out,"\\", 1) != 1)
36676
0
                    goto err_exit;
36677
0
                str_len++;
36678
0
            }
36679
0
            if (wolfSSL_BIO_write(out, esc_ptr, 1) != 1)
36680
0
                goto err_exit;
36681
0
            str_len++;
36682
0
            esc_ptr++;
36683
0
        }
36684
0
        if (type_len > 0)
36685
0
            XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36686
0
        return (int)str_len;
36687
0
    }
36688
36689
0
    if (wolfSSL_BIO_write(out, str->data, str->length) != str->length){
36690
0
        goto err_exit;
36691
0
    }
36692
0
    str_len += str->length;
36693
0
    if (type_len > 0)
36694
0
        XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36695
36696
0
    return (int)str_len;
36697
36698
0
err_exit:
36699
0
    if (type_len > 0)
36700
0
        XFREE(typebuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
36701
0
    return WOLFSSL_FAILURE;
36702
0
}
36703
#endif /* !NO_BIO */
36704
36705
#if !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
36706
36707
36708
WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t,
36709
                                    int offset_day, long offset_sec)
36710
0
{
36711
0
    const time_t sec_per_day = 24*60*60;
36712
0
    time_t t_adj = 0;
36713
0
    time_t offset_day_sec = 0;
36714
0
    char time_str[MAX_TIME_STRING_SZ];
36715
0
    int time_get;
36716
36717
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_adj");
36718
36719
0
    if (s == NULL) {
36720
0
        s = wolfSSL_ASN1_TIME_new();
36721
0
        if (s == NULL) {
36722
0
            return NULL;
36723
0
        }
36724
0
    }
36725
36726
    /* compute GMT time with offset */
36727
0
    offset_day_sec = offset_day * sec_per_day;
36728
0
    t_adj          = t + offset_day_sec + offset_sec;
36729
36730
    /* Get time string as either UTC or GeneralizedTime */
36731
0
    time_get = GetFormattedTime(&t_adj, (byte*)time_str,
36732
0
        (word32)sizeof(time_str));
36733
0
    if (time_get <= 0) {
36734
0
        wolfSSL_ASN1_TIME_free(s);
36735
0
        return NULL;
36736
0
    }
36737
36738
0
    if (wolfSSL_ASN1_TIME_set_string(s, time_str) != WOLFSSL_SUCCESS) {
36739
0
        wolfSSL_ASN1_TIME_free(s);
36740
0
        return NULL;
36741
0
    }
36742
36743
0
    return s;
36744
0
}
36745
#endif /* !NO_ASN_TIME && !USER_TIME && !TIME_OVERRIDES */
36746
36747
#ifndef NO_ASN_TIME
36748
36749
WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_new(void)
36750
0
{
36751
0
    WOLFSSL_ASN1_TIME* ret = (WOLFSSL_ASN1_TIME*)
36752
0
            XMALLOC(sizeof(WOLFSSL_ASN1_TIME), NULL, DYNAMIC_TYPE_OPENSSL);
36753
0
    if (!ret)
36754
0
        return NULL;
36755
0
    XMEMSET(ret, 0, sizeof(WOLFSSL_ASN1_TIME));
36756
0
    return ret;
36757
0
}
36758
36759
void wolfSSL_ASN1_TIME_free(WOLFSSL_ASN1_TIME* t)
36760
0
{
36761
0
    if (t) {
36762
0
        XFREE(t, NULL, DYNAMIC_TYPE_OPENSSL);
36763
0
    }
36764
0
}
36765
/* not a compatibility function - length getter for opaque type */
36766
int wolfSSL_ASN1_TIME_get_length(WOLFSSL_ASN1_TIME *t)
36767
0
{
36768
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_length");
36769
0
    if (t == NULL)
36770
0
        return WOLFSSL_FAILURE;
36771
0
    return t->length;
36772
0
}
36773
/* not a compatibility function - data getter for opaque type */
36774
unsigned char* wolfSSL_ASN1_TIME_get_data(WOLFSSL_ASN1_TIME *t)
36775
0
{
36776
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_get_data");
36777
0
    if (t == NULL)
36778
0
        return NULL;
36779
0
    return t->data;
36780
0
}
36781
36782
WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_to_generalizedtime(WOLFSSL_ASN1_TIME *t,
36783
                                                        WOLFSSL_ASN1_TIME **out)
36784
0
{
36785
0
    int time_type = 0;
36786
0
    WOLFSSL_ASN1_TIME *ret = NULL;
36787
36788
0
    WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_generalizedtime");
36789
0
    if (t == NULL) {
36790
0
        WOLFSSL_MSG("Invalid ASN_TIME value");
36791
0
    } else {
36792
0
        time_type = t->type;
36793
0
        if (time_type != ASN_UTC_TIME && time_type != ASN_GENERALIZED_TIME){
36794
0
            WOLFSSL_MSG("Invalid ASN_TIME type.");
36795
0
        } else {
36796
0
            if (out == NULL || *out == NULL) {
36797
0
                ret = wolfSSL_ASN1_TIME_new();
36798
0
                if (ret == NULL){
36799
0
                    WOLFSSL_MSG("memory alloc failed.");
36800
0
                }
36801
0
            } else {
36802
0
                ret = *out;
36803
0
            }
36804
0
        }
36805
0
    }
36806
36807
0
    if (ret != NULL) {
36808
0
        if (time_type == ASN_GENERALIZED_TIME){
36809
0
            XMEMCPY(ret->data, t->data, ASN_GENERALIZED_TIME_SIZE);
36810
0
        } else { /* ASN_UTC_TIME */
36811
            /* convert UTC to generalized time */
36812
0
            ret->type = ASN_GENERALIZED_TIME;
36813
0
            ret->length = ASN_GENERALIZED_TIME_SIZE;
36814
0
            if (t->data[0] >= '5') {
36815
0
                ret->data[0] = '1'; ret->data[1] = '9';
36816
0
            } else {
36817
0
                ret->data[0] = '2'; ret->data[1] = '0';
36818
0
            }
36819
0
            XMEMCPY(&ret->data[2], t->data, ASN_UTC_TIME_SIZE);
36820
0
        }
36821
0
    }
36822
36823
0
    return ret;
36824
0
}
36825
#endif /* !NO_ASN_TIME */
36826
36827
#ifndef NO_ASN
36828
int wolfSSL_i2c_ASN1_INTEGER(WOLFSSL_ASN1_INTEGER *a, unsigned char **pp)
36829
0
{
36830
0
    unsigned char *pptr = NULL;
36831
0
    char pad = 0 ;
36832
0
    unsigned char pad_val = 0;
36833
0
    int ret_size = 0;
36834
0
    unsigned char data1 = 0;
36835
0
    unsigned char neg = 0;
36836
0
    int i = 0;
36837
36838
0
    WOLFSSL_ENTER("wolfSSL_i2c_ASN1_INTEGER");
36839
0
    if (a == NULL)
36840
0
        return WOLFSSL_FAILURE;
36841
36842
0
    ret_size = a->intData[1];
36843
0
    if (ret_size == 0)
36844
0
        ret_size = 1;
36845
0
    else{
36846
0
        ret_size = (int)a->intData[1];
36847
0
        neg = a->negative;
36848
0
        data1 = a->intData[2];
36849
0
        if (ret_size == 1 && data1 == 0)
36850
0
            neg = 0;
36851
        /* 0x80 or greater positive number in first byte */
36852
0
        if (!neg && (data1 > 127)){
36853
0
            pad = 1;
36854
0
            pad_val = 0;
36855
0
        } else if (neg){
36856
            /* negative number */
36857
0
            if (data1 > 128){
36858
0
                pad = 1;
36859
0
                pad_val = 0xff;
36860
0
            } else if (data1 == 128){
36861
0
                for (i = 3; i < a->intData[1] + 2; i++){
36862
0
                    if (a->intData[i]){
36863
0
                        pad = 1;
36864
0
                        pad_val = 0xff;
36865
0
                        break;
36866
0
                    }
36867
0
                }
36868
0
            }
36869
0
        }
36870
0
        ret_size += (int)pad;
36871
0
    }
36872
0
    if (pp == NULL)
36873
0
        return ret_size;
36874
36875
0
    pptr = *pp;
36876
0
    if (pad)
36877
0
        *(pptr++) = pad_val;
36878
0
    if (a->intData[1] == 0)
36879
0
        *(pptr++) = 0;
36880
0
    else if (!neg){
36881
        /* positive number */
36882
0
        for (i=0; i < a->intData[1]; i++){
36883
0
            *pptr = a->intData[i+2];
36884
0
            pptr++;
36885
0
        }
36886
0
    } else {
36887
        /* negative number */
36888
0
        int str_len = 0;
36889
36890
        /* 0 padding from end of buffer */
36891
0
        str_len = (int)a->intData[1];
36892
0
        pptr += a->intData[1] - 1;
36893
0
        while (!a->intData[str_len + 2] && str_len > 1){
36894
0
            *(pptr--) = 0;
36895
0
            str_len--;
36896
0
        }
36897
        /* 2's complement next octet */
36898
0
        *(pptr--) = ((a->intData[str_len + 1]) ^ 0xff) + 1;
36899
0
        str_len--;
36900
        /* Complement any octets left */
36901
0
        while (str_len > 0){
36902
0
            *(pptr--) = a->intData[str_len + 1] ^ 0xff;
36903
0
            str_len--;
36904
0
        }
36905
0
    }
36906
0
    *pp += ret_size;
36907
0
    return ret_size;
36908
0
}
36909
#endif /* !NO_ASN */
36910
#endif /* OPENSSL_EXTRA */
36911
36912
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
36913
/* when calling SetIndividualExternal, mpi should be cleared by caller if no
36914
 * longer used. ie mp_free(mpi). This is to free data when fastmath is
36915
 * disabled since a copy of mpi is made by this function and placed into bn.
36916
 */
36917
int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
36918
446
{
36919
446
    byte dynamic = 0;
36920
36921
#ifdef WOLFSSL_DEBUG_OPENSSL
36922
    WOLFSSL_MSG("Entering SetIndividualExternal");
36923
#endif
36924
36925
446
    if (mpi == NULL || bn == NULL) {
36926
0
        WOLFSSL_MSG("mpi NULL error");
36927
0
        return WOLFSSL_FATAL_ERROR;
36928
0
    }
36929
36930
446
    if (*bn == NULL) {
36931
446
        *bn = wolfSSL_BN_new();
36932
446
        if (*bn == NULL) {
36933
0
            WOLFSSL_MSG("SetIndividualExternal alloc failed");
36934
0
            return WOLFSSL_FATAL_ERROR;
36935
0
        }
36936
446
        dynamic = 1;
36937
446
    }
36938
36939
446
    if (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY) {
36940
0
        WOLFSSL_MSG("mp_copy error");
36941
0
        if (dynamic == 1) {
36942
0
            wolfSSL_BN_free(*bn);
36943
0
        }
36944
0
        return WOLFSSL_FATAL_ERROR;
36945
0
    }
36946
36947
446
    return WOLFSSL_SUCCESS;
36948
446
}
36949
36950
36951
static void InitwolfSSL_BigNum(WOLFSSL_BIGNUM* bn)
36952
12.0k
{
36953
12.0k
    if (bn)
36954
12.0k
        XMEMSET(bn, 0, sizeof(WOLFSSL_BIGNUM));
36955
12.0k
}
36956
36957
36958
WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
36959
12.0k
{
36960
12.0k
    WOLFSSL_BIGNUM* external;
36961
12.0k
    mp_int*        mpi;
36962
36963
#ifdef WOLFSSL_DEBUG_OPENSSL
36964
    WOLFSSL_MSG("wolfSSL_BN_new");
36965
#endif
36966
36967
12.0k
#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
36968
12.0k
    mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT);
36969
12.0k
    if (mpi == NULL) {
36970
0
        WOLFSSL_MSG("wolfSSL_BN_new malloc mpi failure");
36971
0
        return NULL;
36972
0
    }
36973
12.0k
#endif
36974
36975
12.0k
    external = (WOLFSSL_BIGNUM*) XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
36976
12.0k
                                        DYNAMIC_TYPE_BIGINT);
36977
12.0k
    if (external == NULL) {
36978
0
        WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
36979
0
#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
36980
0
        XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT);
36981
0
#endif
36982
0
        return NULL;
36983
0
    }
36984
36985
#if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
36986
    mpi = &external->fp;
36987
#endif
36988
36989
12.0k
    InitwolfSSL_BigNum(external);
36990
12.0k
    if (mp_init(mpi) != MP_OKAY) {
36991
0
        wolfSSL_BN_free(external);
36992
0
        return NULL;
36993
0
    }
36994
12.0k
    external->internal = mpi;
36995
36996
12.0k
    return external;
36997
12.0k
}
36998
36999
37000
#if defined(USE_FAST_MATH) && !defined(HAVE_WOLF_BIGINT)
37001
/* This function works without BN_free only with TFM */
37002
void wolfSSL_BN_init(WOLFSSL_BIGNUM* bn)
37003
{
37004
    if(bn == NULL)return;
37005
#ifdef WOLFSSL_DEBUG_OPENSSL
37006
    WOLFSSL_MSG("wolfSSL_BN_init");
37007
#endif
37008
    InitwolfSSL_BigNum(bn);
37009
    if (mp_init(&bn->fp) != MP_OKAY)
37010
        return;
37011
    bn->internal = (void *)&bn->fp;
37012
}
37013
#endif
37014
37015
void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
37016
32.2k
{
37017
#ifdef WOLFSSL_DEBUG_OPENSSL
37018
    WOLFSSL_MSG("wolfSSL_BN_free");
37019
#endif
37020
32.2k
    if (bn) {
37021
12.0k
        if (bn->internal) {
37022
12.0k
            mp_int* bni = (mp_int*)bn->internal;
37023
12.0k
            mp_free(bni);
37024
12.0k
#if !defined(USE_FAST_MATH) || defined(HAVE_WOLF_BIGINT)
37025
12.0k
            XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT);
37026
12.0k
#endif
37027
12.0k
            bn->internal = NULL;
37028
12.0k
        }
37029
12.0k
        XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
37030
        /* bn = NULL, don't try to access or double free it */
37031
12.0k
    }
37032
37033
32.2k
}
37034
37035
void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
37036
0
{
37037
#ifdef WOLFSSL_DEBUG_OPENSSL
37038
    WOLFSSL_MSG("wolfSSL_BN_clear_free");
37039
#endif
37040
0
    if (bn) {
37041
0
        if (bn->internal) {
37042
0
            mp_int* bni = (mp_int*)bn->internal;
37043
0
            mp_forcezero(bni);
37044
0
        }
37045
0
        wolfSSL_BN_free(bn);
37046
0
    }
37047
0
}
37048
37049
void wolfSSL_BN_clear(WOLFSSL_BIGNUM* bn)
37050
0
{
37051
#ifdef WOLFSSL_DEBUG_OPENSSL
37052
    WOLFSSL_MSG("wolfSSL_BN_clear");
37053
#endif
37054
0
    if (bn && bn->internal) {
37055
0
        mp_forcezero((mp_int*)bn->internal);
37056
0
    }
37057
0
}
37058
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
37059
37060
#ifdef OPENSSL_ALL
37061
37062
#if !defined(NO_BIO) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
37063
int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
37064
                                          WOLFSSL_EVP_PKEY* pkey,
37065
                                          const WOLFSSL_EVP_CIPHER* enc,
37066
                                          char* passwd, int passwdSz,
37067
                                          wc_pem_password_cb* cb, void* ctx)
37068
0
{
37069
0
    int ret = 0;
37070
0
    char password[NAME_SZ];
37071
0
    byte* key = NULL;
37072
0
    word32 keySz;
37073
0
    byte* pem = NULL;
37074
0
    int pemSz;
37075
0
    int type = PKCS8_PRIVATEKEY_TYPE;
37076
0
    int algId;
37077
0
    const byte* curveOid;
37078
0
    word32 oidSz;
37079
0
    int encAlgId = 0;
37080
37081
0
    if (bio == NULL || pkey == NULL)
37082
0
        return -1;
37083
37084
0
    keySz = pkey->pkey_sz + 128;
37085
0
    key = (byte*)XMALLOC(keySz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37086
0
    if (key == NULL)
37087
0
        ret = MEMORY_E;
37088
37089
0
    if (ret == 0 && enc != NULL && passwd == NULL) {
37090
0
        passwdSz = cb(password, sizeof(password), 1, ctx);
37091
0
        if (passwdSz < 0)
37092
0
            ret = WOLFSSL_FAILURE;
37093
0
        passwd = password;
37094
0
    }
37095
37096
0
    if (ret == 0 && enc != NULL) {
37097
0
        WC_RNG rng;
37098
0
        ret = wc_InitRng(&rng);
37099
0
        if (ret == 0) {
37100
0
        #ifndef NO_DES3
37101
0
            if (enc == EVP_DES_CBC)
37102
0
                encAlgId = DESb;
37103
0
            else if (enc == EVP_DES_EDE3_CBC)
37104
0
                encAlgId = DES3b;
37105
0
            else
37106
0
        #endif
37107
0
        #if !defined(NO_AES) && defined(HAVE_AES_CBC)
37108
0
            #ifdef WOLFSSL_AES_256
37109
0
            if (enc == EVP_AES_256_CBC)
37110
0
                encAlgId = AES256CBCb;
37111
0
            else
37112
0
            #endif
37113
0
        #endif
37114
0
                ret = -1;
37115
0
            if (ret == 0) {
37116
0
                ret = TraditionalEnc((byte*)pkey->pkey.ptr, pkey->pkey_sz, key,
37117
0
                                       &keySz, passwd, passwdSz, PKCS5, PBES2,
37118
0
                                       encAlgId, NULL, 0, WC_PKCS12_ITT_DEFAULT,
37119
0
                                       &rng, NULL);
37120
0
                if (ret > 0) {
37121
0
                    keySz = ret;
37122
0
                    ret = 0;
37123
0
                }
37124
0
            }
37125
0
            wc_FreeRng(&rng);
37126
0
        }
37127
0
        type = PKCS8_ENC_PRIVATEKEY_TYPE;
37128
0
    }
37129
0
    if (ret == 0 && enc == NULL) {
37130
0
        type = PKCS8_PRIVATEKEY_TYPE;
37131
0
    #ifdef HAVE_ECC
37132
0
        if (pkey->type == EVP_PKEY_EC) {
37133
0
            algId = ECDSAk;
37134
0
            ret = wc_ecc_get_oid(pkey->ecc->group->curve_oid, &curveOid,
37135
0
                                                                        &oidSz);
37136
0
        }
37137
0
        else
37138
0
    #endif
37139
0
        {
37140
0
            algId = RSAk;
37141
0
            curveOid = NULL;
37142
0
            oidSz = 0;
37143
0
        }
37144
37145
0
    #ifdef HAVE_ECC
37146
0
        if (ret >= 0)
37147
0
    #endif
37148
0
        {
37149
0
            ret = wc_CreatePKCS8Key(key, &keySz, (byte*)pkey->pkey.ptr,
37150
0
                                         pkey->pkey_sz, algId, curveOid, oidSz);
37151
0
            keySz = ret;
37152
0
        }
37153
0
    }
37154
37155
0
    if (password == passwd)
37156
0
        XMEMSET(password, 0, passwdSz);
37157
37158
0
    if (ret >= 0) {
37159
0
        pemSz = 2 * keySz + 2 * 64;
37160
0
        pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37161
0
        if (pem == NULL)
37162
0
            ret = MEMORY_E;
37163
0
    }
37164
37165
0
    if (ret >= 0)
37166
0
        ret = wc_DerToPemEx(key, keySz, pem, pemSz, NULL, type);
37167
37168
0
    if (key != NULL)
37169
0
        XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37170
37171
0
    if (ret >= 0) {
37172
0
        if (wolfSSL_BIO_write(bio, pem, ret) != ret)
37173
0
            ret = -1;
37174
0
    }
37175
37176
0
    if (pem != NULL)
37177
0
        XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
37178
37179
0
    return ret < 0 ? 0 : ret;
37180
37181
0
}
37182
37183
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
37184
int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
37185
    const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz,
37186
    wc_pem_password_cb* cb, void* ctx)
37187
0
{
37188
0
    int ret = WOLFSSL_SUCCESS;
37189
0
    BIO *b;
37190
37191
0
    WOLFSSL_ENTER("wolfSSL_PEM_write_PKCS8PrivateKey");
37192
37193
0
    b = wolfSSL_BIO_new_fp(f, BIO_NOCLOSE);
37194
0
    if (b == NULL) {
37195
0
        ret = WOLFSSL_FAILURE;
37196
0
    }
37197
0
    if (ret == WOLFSSL_SUCCESS) {
37198
0
        ret = wolfSSL_PEM_write_bio_PKCS8PrivateKey(b, pkey, enc, passwd,
37199
0
                passwdSz, cb, ctx);
37200
0
    }
37201
37202
0
    wolfSSL_BIO_free(b);
37203
37204
0
    return ret;
37205
0
}
37206
#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */
37207
37208
static int bio_get_data(WOLFSSL_BIO* bio, byte** data)
37209
0
{
37210
0
    int ret = 0;
37211
0
    byte* mem = NULL;
37212
0
#ifndef NO_FILESYSTEM
37213
0
    long memSz;
37214
0
    XFILE file;
37215
0
    long curr;
37216
0
#endif
37217
37218
0
    if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
37219
0
    }
37220
0
#ifndef NO_FILESYSTEM
37221
0
    else if (bio->type == WOLFSSL_BIO_FILE) {
37222
0
        if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
37223
0
            ret = BAD_FUNC_ARG;
37224
0
        if (ret == 0) {
37225
0
            curr = XFTELL(file);
37226
0
            if (curr < 0) {
37227
0
                ret = WOLFSSL_BAD_FILE;
37228
0
            }
37229
0
            if (XFSEEK(file, 0, XSEEK_END) != 0)
37230
0
                ret = WOLFSSL_BAD_FILE;
37231
0
        }
37232
0
        if (ret == 0) {
37233
0
            memSz = XFTELL(file);
37234
0
            if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0) {
37235
0
                ret = WOLFSSL_BAD_FILE;
37236
0
            }
37237
0
        }
37238
0
        if (ret == 0) {
37239
0
            memSz -= curr;
37240
0
            ret = (int)memSz;
37241
0
            if (XFSEEK(file, curr, SEEK_SET) != 0)
37242
0
                ret = WOLFSSL_BAD_FILE;
37243
0
        }
37244
0
    }
37245
0
#endif
37246
37247
0
    if (ret > 0) {
37248
0
        mem = (byte*)XMALLOC(ret, bio->heap, DYNAMIC_TYPE_OPENSSL);
37249
0
        if (mem == NULL) {
37250
0
            WOLFSSL_MSG("Memory error");
37251
0
            ret = MEMORY_E;
37252
0
        }
37253
0
        if (ret >= 0) {
37254
0
            if ((ret = wolfSSL_BIO_read(bio, mem, ret)) <= 0) {
37255
0
                XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
37256
0
                ret = MEMORY_E;
37257
0
                mem = NULL;
37258
0
            }
37259
0
        }
37260
0
    }
37261
37262
0
    *data = mem;
37263
37264
0
    return ret;
37265
0
}
37266
37267
/* DER data is PKCS#8 encrypted. */
37268
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio,
37269
                                                  WOLFSSL_EVP_PKEY** pkey,
37270
                                                  wc_pem_password_cb* cb,
37271
                                                  void* ctx)
37272
0
{
37273
0
    int ret;
37274
0
    byte* der;
37275
0
    int len;
37276
0
    byte* p;
37277
0
    word32 algId;
37278
0
    WOLFSSL_EVP_PKEY* key;
37279
37280
0
    if ((len = bio_get_data(bio, &der)) < 0)
37281
0
        return NULL;
37282
37283
0
    if (cb != NULL) {
37284
0
        char password[NAME_SZ];
37285
0
        int passwordSz = cb(password, sizeof(password), PEM_PASS_READ, ctx);
37286
0
        if (passwordSz < 0) {
37287
0
            XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
37288
0
            return NULL;
37289
0
        }
37290
    #ifdef WOLFSSL_CHECK_MEM_ZERO
37291
        wc_MemZero_Add("wolfSSL_d2i_PKCS8PrivateKey_bio password", password,
37292
            passwordSz);
37293
    #endif
37294
37295
0
        ret = ToTraditionalEnc(der, len, password, passwordSz, &algId);
37296
0
        if (ret < 0) {
37297
0
            XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
37298
0
            return NULL;
37299
0
        }
37300
37301
0
        ForceZero(password, passwordSz);
37302
    #ifdef WOLFSSL_CHECK_MEM_ZERO
37303
        wc_MemZero_Check(password, passwordSz);
37304
    #endif
37305
0
    }
37306
37307
0
    p = der;
37308
0
    key = wolfSSL_d2i_PrivateKey_EVP(pkey, &p, len);
37309
0
    XFREE(der, bio->heap, DYNAMIC_TYPE_OPENSSL);
37310
0
    return key;
37311
0
}
37312
37313
#endif /* !NO_BIO && !NO_PWDBASED && HAVE_PKCS8 */
37314
37315
/* Detect which type of key it is before decoding. */
37316
WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey,
37317
                                             const unsigned char** pp,
37318
                                             long length)
37319
0
{
37320
0
    int ret;
37321
0
    WOLFSSL_EVP_PKEY* key = NULL;
37322
0
    const byte* der = *pp;
37323
0
    word32 idx = 0;
37324
0
    int len = 0;
37325
0
    word32 end = 0;
37326
0
    int cnt = 0;
37327
0
    int type;
37328
0
    word32 algId;
37329
0
    word32 keyLen = (word32)length;
37330
37331
    /* Take off PKCS#8 wrapper if found. */
37332
0
    if ((len = ToTraditionalInline_ex(der, &idx, keyLen, &algId)) >= 0) {
37333
0
        der += idx;
37334
0
        keyLen = len;
37335
0
    }
37336
0
    idx = 0;
37337
0
    len = 0;
37338
37339
    /* Use the number of elements in the outer sequence to determine key type.
37340
     */
37341
0
    ret = GetSequence(der, &idx, &len, keyLen);
37342
0
    if (ret >= 0) {
37343
0
        end = idx + len;
37344
0
        while (ret >= 0 && idx < end) {
37345
            /* Skip type */
37346
0
            idx++;
37347
            /* Get length and skip over - keeping count */
37348
0
            len = 0;
37349
0
            ret = GetLength(der, &idx, &len, keyLen);
37350
0
            if (ret >= 0) {
37351
0
                if (idx + len > end)
37352
0
                    ret = ASN_PARSE_E;
37353
0
                else {
37354
0
                    idx += len;
37355
0
                    cnt++;
37356
0
                }
37357
0
            }
37358
0
        }
37359
0
    }
37360
37361
0
    if (ret >= 0) {
37362
        /* ECC includes version, private[, curve][, public key] */
37363
0
        if (cnt >= 2 && cnt <= 4)
37364
0
            type = EVP_PKEY_EC;
37365
0
        else
37366
0
            type = EVP_PKEY_RSA;
37367
37368
0
        key = wolfSSL_d2i_PrivateKey(type, pkey, &der, keyLen);
37369
0
        *pp = der;
37370
0
    }
37371
37372
0
    return key;
37373
0
}
37374
#endif /* OPENSSL_ALL */
37375
37376
#ifdef WOLFSSL_STATIC_EPHEMERAL
37377
int wolfSSL_StaticEphemeralKeyLoad(WOLFSSL* ssl, int keyAlgo, void* keyPtr)
37378
{
37379
    int ret;
37380
    word32 idx = 0;
37381
    DerBuffer* der = NULL;
37382
37383
    if (ssl == NULL || ssl->ctx == NULL || keyPtr == NULL) {
37384
        return BAD_FUNC_ARG;
37385
    }
37386
37387
#ifndef SINGLE_THREADED
37388
    if (!ssl->ctx->staticKELockInit) {
37389
        return BUFFER_E; /* no keys set */
37390
    }
37391
    ret = wc_LockMutex(&ssl->ctx->staticKELock);
37392
    if (ret != 0) {
37393
        return ret;
37394
    }
37395
#endif
37396
37397
    ret = BUFFER_E; /* set default error */
37398
    switch (keyAlgo) {
37399
    #ifndef NO_DH
37400
        case WC_PK_TYPE_DH:
37401
            if (ssl != NULL)
37402
                der = ssl->staticKE.dhKey;
37403
            if (der == NULL)
37404
                der = ssl->ctx->staticKE.dhKey;
37405
            if (der != NULL) {
37406
                DhKey* key = (DhKey*)keyPtr;
37407
                WOLFSSL_MSG("Using static DH key");
37408
                ret = wc_DhKeyDecode(der->buffer, &idx, key, der->length);
37409
            }
37410
            break;
37411
    #endif
37412
    #ifdef HAVE_ECC
37413
        case WC_PK_TYPE_ECDH:
37414
            if (ssl != NULL)
37415
                der = ssl->staticKE.ecKey;
37416
            if (der == NULL)
37417
                der = ssl->ctx->staticKE.ecKey;
37418
            if (der != NULL) {
37419
                ecc_key* key = (ecc_key*)keyPtr;
37420
                WOLFSSL_MSG("Using static ECDH key");
37421
                ret = wc_EccPrivateKeyDecode(der->buffer, &idx, key, der->length);
37422
            }
37423
            break;
37424
    #endif
37425
    #ifdef HAVE_CURVE25519
37426
        case WC_PK_TYPE_CURVE25519:
37427
            if (ssl != NULL)
37428
                der = ssl->staticKE.x25519Key;
37429
            if (der == NULL)
37430
                der = ssl->ctx->staticKE.x25519Key;
37431
            if (der != NULL) {
37432
                curve25519_key* key = (curve25519_key*)keyPtr;
37433
                WOLFSSL_MSG("Using static X25519 key");
37434
                ret = wc_Curve25519PrivateKeyDecode(der->buffer, &idx, key,
37435
                    der->length);
37436
            }
37437
            break;
37438
    #endif
37439
    #ifdef HAVE_CURVE448
37440
        case WC_PK_TYPE_CURVE448:
37441
            if (ssl != NULL)
37442
                der = ssl->staticKE.x448Key;
37443
            if (der == NULL)
37444
                der = ssl->ctx->staticKE.x448Key;
37445
            if (der != NULL) {
37446
                curve448_key* key = (curve448_key*)keyPtr;
37447
                WOLFSSL_MSG("Using static X448 key");
37448
                ret = wc_Curve448PrivateKeyDecode(der->buffer, &idx, key,
37449
                    der->length);
37450
            }
37451
            break;
37452
    #endif
37453
        default:
37454
            /* not supported */
37455
            ret = NOT_COMPILED_IN;
37456
            break;
37457
    }
37458
37459
#ifndef SINGLE_THREADED
37460
    wc_UnLockMutex(&ssl->ctx->staticKELock);
37461
#endif
37462
    return ret;
37463
}
37464
37465
static int SetStaticEphemeralKey(WOLFSSL_CTX* ctx,
37466
    StaticKeyExchangeInfo_t* staticKE, int keyAlgo, const char* key,
37467
    unsigned int keySz, int format, void* heap)
37468
{
37469
    int ret = 0;
37470
    DerBuffer* der = NULL;
37471
    byte* keyBuf = NULL;
37472
#ifndef NO_FILESYSTEM
37473
    const char* keyFile = NULL;
37474
#endif
37475
37476
    /* allow empty key to free buffer */
37477
    if (staticKE == NULL || (key == NULL && keySz > 0)) {
37478
        return BAD_FUNC_ARG;
37479
    }
37480
37481
    WOLFSSL_ENTER("SetStaticEphemeralKey");
37482
37483
    /* if just free'ing key then skip loading */
37484
    if (key != NULL) {
37485
    #ifndef NO_FILESYSTEM
37486
        /* load file from filesystem */
37487
        if (key != NULL && keySz == 0) {
37488
            size_t keyBufSz = 0;
37489
            keyFile = (const char*)key;
37490
            ret = wc_FileLoad(keyFile, &keyBuf, &keyBufSz, heap);
37491
            if (ret != 0) {
37492
                return ret;
37493
            }
37494
            keySz = (unsigned int)keyBufSz;
37495
        }
37496
        else
37497
    #endif
37498
        {
37499
            /* use as key buffer directly */
37500
            keyBuf = (byte*)key;
37501
        }
37502
37503
        if (format == WOLFSSL_FILETYPE_PEM) {
37504
        #ifdef WOLFSSL_PEM_TO_DER
37505
            int keyFormat = 0;
37506
            ret = PemToDer(keyBuf, keySz, PRIVATEKEY_TYPE, &der,
37507
                heap, NULL, &keyFormat);
37508
            /* auto detect key type */
37509
            if (ret == 0 && keyAlgo == WC_PK_TYPE_NONE) {
37510
                if (keyFormat == ECDSAk)
37511
                    keyAlgo = WC_PK_TYPE_ECDH;
37512
                else if (keyFormat == X25519k)
37513
                    keyAlgo = WC_PK_TYPE_CURVE25519;
37514
                else
37515
                    keyAlgo = WC_PK_TYPE_DH;
37516
            }
37517
        #else
37518
            ret = NOT_COMPILED_IN;
37519
        #endif
37520
        }
37521
        else {
37522
            /* Detect PK type (if required) */
37523
        #ifdef HAVE_ECC
37524
            if (keyAlgo == WC_PK_TYPE_NONE) {
37525
                word32 idx = 0;
37526
                ecc_key eccKey;
37527
                ret = wc_ecc_init_ex(&eccKey, heap, INVALID_DEVID);
37528
                if (ret == 0) {
37529
                    ret = wc_EccPrivateKeyDecode(keyBuf, &idx, &eccKey, keySz);
37530
                    if (ret == 0)
37531
                        keyAlgo = WC_PK_TYPE_ECDH;
37532
                    wc_ecc_free(&eccKey);
37533
                }
37534
            }
37535
        #endif
37536
        #if !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)
37537
            if (keyAlgo == WC_PK_TYPE_NONE) {
37538
                word32 idx = 0;
37539
                DhKey dhKey;
37540
                ret = wc_InitDhKey_ex(&dhKey, heap, INVALID_DEVID);
37541
                if (ret == 0) {
37542
                    ret = wc_DhKeyDecode(keyBuf, &idx, &dhKey, keySz);
37543
                    if (ret == 0)
37544
                        keyAlgo = WC_PK_TYPE_DH;
37545
                    wc_FreeDhKey(&dhKey);
37546
                }
37547
            }
37548
        #endif
37549
        #ifdef HAVE_CURVE25519
37550
            if (keyAlgo == WC_PK_TYPE_NONE) {
37551
                word32 idx = 0;
37552
                curve25519_key x25519Key;
37553
                ret = wc_curve25519_init_ex(&x25519Key, heap, INVALID_DEVID);
37554
                if (ret == 0) {
37555
                    ret = wc_Curve25519PrivateKeyDecode(keyBuf, &idx, &x25519Key,
37556
                        keySz);
37557
                    if (ret == 0)
37558
                        keyAlgo = WC_PK_TYPE_CURVE25519;
37559
                    wc_curve25519_free(&x25519Key);
37560
                }
37561
            }
37562
        #endif
37563
        #ifdef HAVE_CURVE448
37564
            if (keyAlgo == WC_PK_TYPE_NONE) {
37565
                word32 idx = 0;
37566
                curve448_key x448Key;
37567
                ret = wc_curve448_init(&x448Key);
37568
                if (ret == 0) {
37569
                    ret = wc_Curve448PrivateKeyDecode(keyBuf, &idx, &x448Key,
37570
                        keySz);
37571
                    if (ret == 0)
37572
                        keyAlgo = WC_PK_TYPE_CURVE448;
37573
                    wc_curve448_free(&x448Key);
37574
                }
37575
            }
37576
        #endif
37577
37578
            if (keyAlgo != WC_PK_TYPE_NONE) {
37579
                ret = AllocDer(&der, keySz, PRIVATEKEY_TYPE, heap);
37580
                if (ret == 0) {
37581
                    XMEMCPY(der->buffer, keyBuf, keySz);
37582
                }
37583
            }
37584
        }
37585
    }
37586
37587
#ifndef NO_FILESYSTEM
37588
    /* done with keyFile buffer */
37589
    if (keyFile && keyBuf) {
37590
        XFREE(keyBuf, heap, DYNAMIC_TYPE_TMP_BUFFER);
37591
    }
37592
#endif
37593
37594
#ifndef SINGLE_THREADED
37595
    if (ret == 0 && !ctx->staticKELockInit) {
37596
        ret = wc_InitMutex(&ctx->staticKELock);
37597
        if (ret == 0) {
37598
            ctx->staticKELockInit = 1;
37599
        }
37600
    }
37601
#endif
37602
    if (ret == 0
37603
    #ifndef SINGLE_THREADED
37604
        && (ret = wc_LockMutex(&ctx->staticKELock)) == 0
37605
    #endif
37606
    ) {
37607
        switch (keyAlgo) {
37608
        #ifndef NO_DH
37609
            case WC_PK_TYPE_DH:
37610
                FreeDer(&staticKE->dhKey);
37611
                staticKE->dhKey = der; der = NULL;
37612
                break;
37613
        #endif
37614
        #ifdef HAVE_ECC
37615
            case WC_PK_TYPE_ECDH:
37616
                FreeDer(&staticKE->ecKey);
37617
                staticKE->ecKey = der; der = NULL;
37618
                break;
37619
        #endif
37620
        #ifdef HAVE_CURVE25519
37621
            case WC_PK_TYPE_CURVE25519:
37622
                FreeDer(&staticKE->x25519Key);
37623
                staticKE->x25519Key = der; der = NULL;
37624
                break;
37625
        #endif
37626
        #ifdef HAVE_CURVE448
37627
            case WC_PK_TYPE_CURVE448:
37628
                FreeDer(&staticKE->x448Key);
37629
                staticKE->x448Key = der; der = NULL;
37630
                break;
37631
        #endif
37632
            default:
37633
                /* not supported */
37634
                ret = NOT_COMPILED_IN;
37635
                break;
37636
        }
37637
37638
    #ifndef SINGLE_THREADED
37639
        wc_UnLockMutex(&ctx->staticKELock);
37640
    #endif
37641
    }
37642
37643
    if (ret != 0) {
37644
        FreeDer(&der);
37645
    }
37646
37647
    (void)ctx; /* not used for single threaded */
37648
37649
    WOLFSSL_LEAVE("SetStaticEphemeralKey", ret);
37650
37651
    return ret;
37652
}
37653
37654
int wolfSSL_CTX_set_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
37655
    const char* key, unsigned int keySz, int format)
37656
{
37657
    if (ctx == NULL) {
37658
        return BAD_FUNC_ARG;
37659
    }
37660
    return SetStaticEphemeralKey(ctx, &ctx->staticKE, keyAlgo,
37661
        key, keySz, format, ctx->heap);
37662
}
37663
int wolfSSL_set_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
37664
    const char* key, unsigned int keySz, int format)
37665
{
37666
    if (ssl == NULL || ssl->ctx == NULL) {
37667
        return BAD_FUNC_ARG;
37668
    }
37669
    return SetStaticEphemeralKey(ssl->ctx, &ssl->staticKE, keyAlgo,
37670
        key, keySz, format, ssl->heap);
37671
}
37672
37673
static int GetStaticEphemeralKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
37674
    int keyAlgo, const unsigned char** key, unsigned int* keySz)
37675
{
37676
    int ret = 0;
37677
    DerBuffer* der = NULL;
37678
37679
    if (key)   *key = NULL;
37680
    if (keySz) *keySz = 0;
37681
37682
#ifndef SINGLE_THREADED
37683
    if (ctx->staticKELockInit &&
37684
        (ret = wc_LockMutex(&ctx->staticKELock)) != 0) {
37685
        return ret;
37686
    }
37687
#endif
37688
37689
    switch (keyAlgo) {
37690
    #ifndef NO_DH
37691
        case WC_PK_TYPE_DH:
37692
            if (ssl != NULL)
37693
                der = ssl->staticKE.dhKey;
37694
            if (der == NULL)
37695
                der = ctx->staticKE.dhKey;
37696
            break;
37697
    #endif
37698
    #ifdef HAVE_ECC
37699
        case WC_PK_TYPE_ECDH:
37700
            if (ssl != NULL)
37701
                der = ssl->staticKE.ecKey;
37702
            if (der == NULL)
37703
                der = ctx->staticKE.ecKey;
37704
            break;
37705
    #endif
37706
    #ifdef HAVE_CURVE25519
37707
        case WC_PK_TYPE_CURVE25519:
37708
            if (ssl != NULL)
37709
                der = ssl->staticKE.x25519Key;
37710
            if (der == NULL)
37711
                der = ctx->staticKE.x25519Key;
37712
            break;
37713
    #endif
37714
    #ifdef HAVE_CURVE448
37715
        case WC_PK_TYPE_CURVE448:
37716
            if (ssl != NULL)
37717
                der = ssl->staticKE.x448Key;
37718
            if (der == NULL)
37719
                der = ctx->staticKE.x448Key;
37720
            break;
37721
    #endif
37722
        default:
37723
            /* not supported */
37724
            ret = NOT_COMPILED_IN;
37725
            break;
37726
    }
37727
37728
    if (der) {
37729
        if (key)
37730
            *key = der->buffer;
37731
        if (keySz)
37732
            *keySz = der->length;
37733
    }
37734
37735
#ifndef SINGLE_THREADED
37736
    wc_UnLockMutex(&ctx->staticKELock);
37737
#endif
37738
37739
    return ret;
37740
}
37741
37742
/* returns pointer to currently loaded static ephemeral as ASN.1 */
37743
/* this can be converted to PEM using wc_DerToPem */
37744
int wolfSSL_CTX_get_ephemeral_key(WOLFSSL_CTX* ctx, int keyAlgo,
37745
    const unsigned char** key, unsigned int* keySz)
37746
{
37747
    if (ctx == NULL) {
37748
        return BAD_FUNC_ARG;
37749
    }
37750
37751
    return GetStaticEphemeralKey(ctx, NULL, keyAlgo, key, keySz);
37752
}
37753
int wolfSSL_get_ephemeral_key(WOLFSSL* ssl, int keyAlgo,
37754
    const unsigned char** key, unsigned int* keySz)
37755
{
37756
    if (ssl == NULL || ssl->ctx == NULL) {
37757
        return BAD_FUNC_ARG;
37758
    }
37759
37760
    return GetStaticEphemeralKey(ssl->ctx, ssl, keyAlgo, key, keySz);
37761
}
37762
37763
#endif /* WOLFSSL_STATIC_EPHEMERAL */
37764
37765
#if defined(OPENSSL_EXTRA)
37766
/* wolfSSL_THREADID_current is provided as a compat API with
37767
 * CRYPTO_THREADID_current to register current thread id into given id object.
37768
 * However, CRYPTO_THREADID_current API has been deprecated and no longer
37769
 * exists in the OpenSSL 1.0.0 or later.This API only works as a stub
37770
 * like as existing wolfSSL_THREADID_set_numeric.
37771
 */
37772
void wolfSSL_THREADID_current(WOLFSSL_CRYPTO_THREADID* id)
37773
0
{
37774
0
    (void)id;
37775
0
    return;
37776
0
}
37777
/* wolfSSL_THREADID_hash is provided as a compatible API with
37778
 * CRYPTO_THREADID_hash which returns a hash value calcurated from the
37779
 * specified thread id. However, CRYPTO_THREADID_hash API has been
37780
 * deprecated and no longer exists in the OpenSSL 1.0.0 or later.
37781
 * This API only works as a stub to returns 0. This behavior is
37782
 * equivalent to the latest OpenSSL CRYPTO_THREADID_hash.
37783
 */
37784
unsigned long wolfSSL_THREADID_hash(const WOLFSSL_CRYPTO_THREADID* id)
37785
0
{
37786
0
    (void)id;
37787
0
    return 0UL;
37788
0
}
37789
/* wolfSSL_CTX_set_ecdh_auto is provided as compatible API with
37790
 * SSL_CTX_set_ecdh_auto to enable auto ecdh curve selection functionality.
37791
 * Since this functionality is enabled by default in wolfSSL,
37792
 * this API exists as a stub.
37793
 */
37794
int wolfSSL_CTX_set_ecdh_auto(WOLFSSL_CTX* ctx, int onoff)
37795
0
{
37796
0
    (void)ctx;
37797
0
    (void)onoff;
37798
0
    return WOLFSSL_SUCCESS;
37799
0
}
37800
37801
/**
37802
 * set security level (wolfSSL doesn't support security level)
37803
 * @param ctx  a pointer to WOLFSSL_EVP_PKEY_CTX structure
37804
 * @param level security level
37805
 */
37806
void wolfSSL_CTX_set_security_level(WOLFSSL_CTX* ctx, int level)
37807
0
{
37808
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_security_level");
37809
0
    (void)ctx;
37810
0
    (void)level;
37811
0
}
37812
/**
37813
 * get security level (wolfSSL doesn't support security level)
37814
 * @param ctx  a pointer to WOLFSSL_EVP_PKEY_CTX structure
37815
 * @return always 0(level 0)
37816
 */
37817
int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx)
37818
0
{
37819
0
    WOLFSSL_ENTER("wolfSSL_CTX_get_security_level");
37820
0
    (void)ctx;
37821
0
    return 0;
37822
0
}
37823
37824
37825
/**
37826
 * Determine whether a WOLFSSL_SESSION object can be used for resumption
37827
 * @param s  a pointer to WOLFSSL_SESSION structure
37828
 * @return return 1 if session is resumable, otherwise 0.
37829
 */
37830
int wolfSSL_SESSION_is_resumable(const WOLFSSL_SESSION *s)
37831
0
{
37832
0
    s = ClientSessionToSession(s);
37833
0
    if (s == NULL)
37834
0
        return 0;
37835
37836
0
#ifdef HAVE_SESSION_TICKET
37837
0
    if (s->ticketLen > 0)
37838
0
        return 1;
37839
0
#endif
37840
37841
0
    if (s->sessionIDSz > 0)
37842
0
        return 1;
37843
37844
0
    return 0;
37845
0
}
37846
37847
#if defined(OPENSSL_EXTRA) && defined(HAVE_SECRET_CALLBACK)
37848
/*
37849
 * This API accepts a user callback which puts key-log records into
37850
 * a KEY LOGFILE. The callback is stored into a CTX and propagated to
37851
 * each SSL object on its creation timing.
37852
 */
37853
void wolfSSL_CTX_set_keylog_callback(WOLFSSL_CTX* ctx, wolfSSL_CTX_keylog_cb_func cb)
37854
{
37855
    WOLFSSL_ENTER("wolfSSL_CTX_set_keylog_callback");
37856
  /* stores the callback into WOLFSSL_CTX */
37857
    if (ctx != NULL) {
37858
        ctx->keyLogCb = cb;
37859
    }
37860
}
37861
wolfSSL_CTX_keylog_cb_func wolfSSL_CTX_get_keylog_callback(
37862
    const WOLFSSL_CTX* ctx)
37863
{
37864
    WOLFSSL_ENTER("wolfSSL_CTX_get_keylog_callback");
37865
    if (ctx != NULL)
37866
        return ctx->keyLogCb;
37867
    else
37868
        return NULL;
37869
}
37870
#endif /* OPENSSL_EXTRA && HAVE_SECRET_CALLBACK */
37871
37872
#endif /* OPENSSL_EXTRA */
37873
37874
#ifndef NO_CERT
37875
#define WOLFSSL_X509_INCLUDED
37876
#include "src/x509.c"
37877
#endif
37878
37879
/*******************************************************************************
37880
 * START OF standard C library wrapping APIs
37881
 ******************************************************************************/
37882
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
37883
                             defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
37884
                             defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
37885
#ifndef NO_WOLFSSL_STUB
37886
int wolfSSL_CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
37887
                                void *(*r) (void *, size_t, const char *,
37888
                                            int), void (*f) (void *))
37889
0
{
37890
0
    (void) m;
37891
0
    (void) r;
37892
0
    (void) f;
37893
0
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_mem_ex_functions");
37894
0
    WOLFSSL_STUB("CRYPTO_set_mem_ex_functions");
37895
37896
0
    return WOLFSSL_FAILURE;
37897
0
}
37898
#endif
37899
#endif
37900
37901
#if defined(OPENSSL_EXTRA)
37902
37903
/**
37904
 * free allocated memory resouce
37905
 * @param str  a pointer to resource to be freed
37906
 * @param file dummy argument
37907
 * @param line dummy argument
37908
 */
37909
void wolfSSL_CRYPTO_free(void *str, const char *file, int line)
37910
0
{
37911
0
    (void)file;
37912
0
    (void)line;
37913
0
    XFREE(str, 0, DYNAMIC_TYPE_TMP_BUFFER);
37914
0
}
37915
/**
37916
 * allocate memory with size of num
37917
 * @param num  size of memory allocation to be malloced
37918
 * @param file dummy argument
37919
 * @param line dummy argument
37920
 * @return a pointer to allocated memory on succssesful, otherwise NULL
37921
 */
37922
void *wolfSSL_CRYPTO_malloc(size_t num, const char *file, int line)
37923
0
{
37924
0
    (void)file;
37925
0
    (void)line;
37926
0
    return XMALLOC(num, 0, DYNAMIC_TYPE_TMP_BUFFER);
37927
0
}
37928
37929
#endif
37930
37931
/*******************************************************************************
37932
 * END OF standard C library wrapping APIs
37933
 ******************************************************************************/
37934
37935
/*******************************************************************************
37936
 * START OF EX_DATA APIs
37937
 ******************************************************************************/
37938
#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \
37939
                             defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \
37940
                             defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH)))
37941
0
void wolfSSL_CRYPTO_cleanup_all_ex_data(void){
37942
0
    WOLFSSL_ENTER("CRYPTO_cleanup_all_ex_data");
37943
0
}
37944
#endif
37945
37946
#ifdef HAVE_EX_DATA
37947
void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx)
37948
{
37949
    WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data");
37950
#ifdef MAX_EX_DATA
37951
    if(ex_data && idx < MAX_EX_DATA && idx >= 0) {
37952
        return ex_data->ex_data[idx];
37953
    }
37954
#else
37955
    (void)ex_data;
37956
    (void)idx;
37957
#endif
37958
    return NULL;
37959
}
37960
37961
int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx, void *data)
37962
{
37963
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data");
37964
#ifdef MAX_EX_DATA
37965
    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
37966
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
37967
        if (ex_data->ex_data_cleanup_routines[idx]) {
37968
            if (ex_data->ex_data[idx])
37969
                ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
37970
            ex_data->ex_data_cleanup_routines[idx] = NULL;
37971
        }
37972
#endif
37973
        ex_data->ex_data[idx] = data;
37974
        return WOLFSSL_SUCCESS;
37975
    }
37976
#else
37977
    (void)ex_data;
37978
    (void)idx;
37979
    (void)data;
37980
#endif
37981
    return WOLFSSL_FAILURE;
37982
}
37983
37984
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
37985
int wolfSSL_CRYPTO_set_ex_data_with_cleanup(
37986
    WOLFSSL_CRYPTO_EX_DATA* ex_data,
37987
    int idx,
37988
    void *data,
37989
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
37990
{
37991
    WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data_with_cleanup");
37992
    if (ex_data && idx < MAX_EX_DATA && idx >= 0) {
37993
        if (ex_data->ex_data_cleanup_routines[idx] && ex_data->ex_data[idx])
37994
            ex_data->ex_data_cleanup_routines[idx](ex_data->ex_data[idx]);
37995
        ex_data->ex_data[idx] = data;
37996
        ex_data->ex_data_cleanup_routines[idx] = cleanup_routine;
37997
        return WOLFSSL_SUCCESS;
37998
    }
37999
    return WOLFSSL_FAILURE;
38000
}
38001
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
38002
38003
/**
38004
 * Issues unique index for the class specified by class_index.
38005
 * Other parameter except class_index are ignored.
38006
 * Currently, following class_index are accepted:
38007
 *  - WOLF_CRYPTO_EX_INDEX_SSL
38008
 *  - WOLF_CRYPTO_EX_INDEX_SSL_CTX
38009
 *  - WOLF_CRYPTO_EX_INDEX_X509
38010
 * @param class_index index one of CRYPTO_EX_INDEX_xxx
38011
 * @param argp  parameters to be saved
38012
 * @param argl  parameters to be saved
38013
 * @param new_func a pointer to WOLFSSL_CRYPTO_EX_new
38014
 * @param dup_func a pointer to WOLFSSL_CRYPTO_EX_dup
38015
 * @param free_func a pointer to WOLFSSL_CRYPTO_EX_free
38016
 * @return index value grater or equal to zero on success, -1 on failure.
38017
 */
38018
int wolfSSL_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
38019
                                           WOLFSSL_CRYPTO_EX_new* new_func,
38020
                                           WOLFSSL_CRYPTO_EX_dup* dup_func,
38021
                                           WOLFSSL_CRYPTO_EX_free* free_func)
38022
{
38023
    WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_new_index");
38024
38025
    WOLFSSL_CRYPTO_EX_DATA_IGNORE_PARAMS(argl, argp, new_func, dup_func,
38026
                                         free_func);
38027
38028
    return wolfssl_get_ex_new_index(class_index);
38029
}
38030
#endif /* HAVE_EX_DATA */
38031
38032
/*******************************************************************************
38033
 * END OF EX_DATA APIs
38034
 ******************************************************************************/
38035
38036
/*******************************************************************************
38037
 * START OF BUF_MEM API
38038
 ******************************************************************************/
38039
38040
#if defined(OPENSSL_EXTRA)
38041
38042
/* Begin functions for openssl/buffer.h */
38043
WOLFSSL_BUF_MEM* wolfSSL_BUF_MEM_new(void)
38044
0
{
38045
0
    WOLFSSL_BUF_MEM* buf;
38046
0
    buf = (WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), NULL,
38047
0
                                                        DYNAMIC_TYPE_OPENSSL);
38048
0
    if (buf) {
38049
0
        XMEMSET(buf, 0, sizeof(WOLFSSL_BUF_MEM));
38050
0
    }
38051
0
    return buf;
38052
0
}
38053
38054
/* non-compat API returns length of buffer on success */
38055
int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len,
38056
        char zeroFill)
38057
0
{
38058
38059
0
    int len_int = (int)len;
38060
0
    int mx;
38061
0
    char* tmp;
38062
38063
    /* verify provided arguments */
38064
0
    if (buf == NULL || len_int < 0) {
38065
0
        return 0; /* BAD_FUNC_ARG; */
38066
0
    }
38067
38068
    /* check to see if fits in existing length */
38069
0
    if (buf->length > len) {
38070
0
        buf->length = len;
38071
0
        return len_int;
38072
0
    }
38073
38074
    /* check to see if fits in max buffer */
38075
0
    if (buf->max >= len) {
38076
0
        if (buf->data != NULL && zeroFill) {
38077
0
            XMEMSET(&buf->data[buf->length], 0, len - buf->length);
38078
0
        }
38079
0
        buf->length = len;
38080
0
        return len_int;
38081
0
    }
38082
38083
    /* expand size, to handle growth */
38084
0
    mx = (len_int + 3) / 3 * 4;
38085
38086
    /* use realloc */
38087
0
    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
38088
0
    if (tmp == NULL) {
38089
0
        return 0; /* ERR_R_MALLOC_FAILURE; */
38090
0
    }
38091
0
    buf->data = tmp;
38092
38093
0
    buf->max = mx;
38094
0
    if (zeroFill)
38095
0
        XMEMSET(&buf->data[buf->length], 0, len - buf->length);
38096
0
    buf->length = len;
38097
38098
0
    return len_int;
38099
38100
0
}
38101
38102
/* returns length of buffer on success */
38103
int wolfSSL_BUF_MEM_grow(WOLFSSL_BUF_MEM* buf, size_t len)
38104
0
{
38105
0
    return wolfSSL_BUF_MEM_grow_ex(buf, len, 1);
38106
0
}
38107
38108
/* non-compat API returns length of buffer on success */
38109
int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len)
38110
0
{
38111
0
    char* tmp;
38112
0
    int mx;
38113
38114
    /* verify provided arguments */
38115
0
    if (buf == NULL || len == 0 || (int)len <= 0) {
38116
0
        return 0; /* BAD_FUNC_ARG; */
38117
0
    }
38118
38119
0
    if (len == buf->length)
38120
0
        return (int)len;
38121
38122
0
    if (len > buf->length)
38123
0
        return wolfSSL_BUF_MEM_grow_ex(buf, len, 0);
38124
38125
    /* expand size, to handle growth */
38126
0
    mx = ((int)len + 3) / 3 * 4;
38127
38128
    /* We want to shrink the internal buffer */
38129
0
    tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL);
38130
0
    if (tmp == NULL)
38131
0
        return 0;
38132
38133
0
    buf->data = tmp;
38134
0
    buf->length = len;
38135
0
    buf->max = mx;
38136
38137
0
    return (int)len;
38138
0
}
38139
38140
void wolfSSL_BUF_MEM_free(WOLFSSL_BUF_MEM* buf)
38141
0
{
38142
0
    if (buf) {
38143
0
        if (buf->data) {
38144
0
            XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL);
38145
0
            buf->data = NULL;
38146
0
        }
38147
0
        buf->max = 0;
38148
0
        buf->length = 0;
38149
0
        XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
38150
0
    }
38151
0
}
38152
/* End Functions for openssl/buffer.h */
38153
38154
#endif /* OPENSSL_EXTRA */
38155
38156
/*******************************************************************************
38157
 * END OF BUF_MEM API
38158
 ******************************************************************************/
38159
38160
#define WOLFSSL_CONF_INCLUDED
38161
#include <src/conf.c>
38162
38163
/*******************************************************************************
38164
 * START OF RAND API
38165
 ******************************************************************************/
38166
38167
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
38168
static int wolfSSL_RAND_InitMutex(void)
38169
0
{
38170
0
    if (gRandMethodsInit == 0) {
38171
0
        if (wc_InitMutex(&gRandMethodMutex) != 0) {
38172
0
            WOLFSSL_MSG("Bad Init Mutex rand methods");
38173
0
            return BAD_MUTEX_E;
38174
0
        }
38175
0
        gRandMethodsInit = 1;
38176
0
    }
38177
0
    return 0;
38178
0
}
38179
#endif
38180
38181
#ifdef OPENSSL_EXTRA
38182
38183
/* Checks if the global RNG has been created. If not then one is created.
38184
 *
38185
 * Returns WOLFSSL_SUCCESS when no error is encountered.
38186
 */
38187
int wolfSSL_RAND_Init(void)
38188
0
{
38189
0
    int ret = WOLFSSL_FAILURE;
38190
0
#ifdef HAVE_GLOBAL_RNG
38191
0
    if (wc_LockMutex(&globalRNGMutex) == 0) {
38192
0
        if (initGlobalRNG == 0) {
38193
0
            ret = wc_InitRng(&globalRNG);
38194
0
            if (ret == 0) {
38195
0
                initGlobalRNG = 1;
38196
0
                ret = WOLFSSL_SUCCESS;
38197
0
            }
38198
0
        }
38199
0
        wc_UnLockMutex(&globalRNGMutex);
38200
0
    }
38201
0
#endif
38202
0
    return ret;
38203
0
}
38204
38205
38206
/* WOLFSSL_SUCCESS on ok */
38207
int wolfSSL_RAND_seed(const void* seed, int len)
38208
0
{
38209
0
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38210
0
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38211
0
        if (gRandMethods && gRandMethods->seed) {
38212
0
            int ret = gRandMethods->seed(seed, len);
38213
0
            wc_UnLockMutex(&gRandMethodMutex);
38214
0
            return ret;
38215
0
        }
38216
0
        wc_UnLockMutex(&gRandMethodMutex);
38217
0
    }
38218
#else
38219
    (void)seed;
38220
    (void)len;
38221
#endif
38222
38223
    /* Make sure global shared RNG (globalRNG) is initialized */
38224
0
    return wolfSSL_RAND_Init();
38225
0
}
38226
38227
38228
/* Returns the path for reading seed data from.
38229
 * Uses the env variable $RANDFILE first if set, if not then used $HOME/.rnd
38230
 *
38231
 * Note uses stdlib by default unless XGETENV macro is overwritten
38232
 *
38233
 * fname buffer to hold path
38234
 * len   length of fname buffer
38235
 *
38236
 * Returns a pointer to fname on success and NULL on failure
38237
 */
38238
const char* wolfSSL_RAND_file_name(char* fname, unsigned long len)
38239
0
{
38240
0
#ifndef NO_FILESYSTEM
38241
0
    char* rt;
38242
0
    char ap[] = "/.rnd";
38243
38244
0
    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
38245
38246
0
    if (fname == NULL) {
38247
0
        return NULL;
38248
0
    }
38249
38250
0
    XMEMSET(fname, 0, len);
38251
    /* if access to stdlib.h */
38252
0
    if ((rt = XGETENV("RANDFILE")) != NULL) {
38253
0
        if (len > XSTRLEN(rt)) {
38254
0
            XMEMCPY(fname, rt, XSTRLEN(rt));
38255
0
        }
38256
0
        else {
38257
0
            WOLFSSL_MSG("RANDFILE too large for buffer");
38258
0
            rt = NULL;
38259
0
        }
38260
0
    }
38261
38262
    /* $RANDFILE was not set or is too large, check $HOME */
38263
0
    if (rt == NULL) {
38264
0
        WOLFSSL_MSG("Environment variable RANDFILE not set");
38265
0
        if ((rt = XGETENV("HOME")) == NULL) {
38266
0
            WOLFSSL_MSG("Environment variable HOME not set");
38267
0
            return NULL;
38268
0
        }
38269
38270
0
        if (len > XSTRLEN(rt) +  XSTRLEN(ap)) {
38271
0
            fname[0] = '\0';
38272
0
            XSTRNCAT(fname, rt, len);
38273
0
            XSTRNCAT(fname, ap, len - XSTRLEN(rt));
38274
0
            return fname;
38275
0
        }
38276
0
        else {
38277
0
            WOLFSSL_MSG("HOME too large for buffer");
38278
0
            return NULL;
38279
0
        }
38280
0
    }
38281
38282
0
    return fname;
38283
#else
38284
    /* no filesystem defined */
38285
    WOLFSSL_ENTER("wolfSSL_RAND_file_name");
38286
    WOLFSSL_MSG("No filesystem feature enabled, not compiled in");
38287
    (void)fname;
38288
    (void)len;
38289
    return NULL;
38290
#endif
38291
0
}
38292
38293
38294
/* Writes 1024 bytes from the RNG to the given file name.
38295
 *
38296
 * fname name of file to write to
38297
 *
38298
 * Returns the number of bytes written
38299
 */
38300
int wolfSSL_RAND_write_file(const char* fname)
38301
0
{
38302
0
    int bytes = 0;
38303
38304
0
    WOLFSSL_ENTER("RAND_write_file");
38305
38306
0
    if (fname == NULL) {
38307
0
        return SSL_FAILURE;
38308
0
    }
38309
38310
0
#ifndef NO_FILESYSTEM
38311
0
    {
38312
    #ifndef WOLFSSL_SMALL_STACK
38313
        unsigned char buf[1024];
38314
    #else
38315
0
        unsigned char* buf = (unsigned char *)XMALLOC(1024, NULL,
38316
0
                                                       DYNAMIC_TYPE_TMP_BUFFER);
38317
0
        if (buf == NULL) {
38318
0
            WOLFSSL_MSG("malloc failed");
38319
0
            return SSL_FAILURE;
38320
0
        }
38321
0
    #endif
38322
0
        bytes = 1024; /* default size of buf */
38323
38324
0
        if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
38325
0
            WOLFSSL_MSG("No RNG to use");
38326
0
        #ifdef WOLFSSL_SMALL_STACK
38327
0
            XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38328
0
        #endif
38329
0
            return 0;
38330
0
        }
38331
38332
0
        if (wc_RNG_GenerateBlock(&globalRNG, buf, bytes) != 0) {
38333
0
            WOLFSSL_MSG("Error generating random buffer");
38334
0
            bytes = 0;
38335
0
        }
38336
0
        else {
38337
0
            XFILE f;
38338
38339
        #ifdef WOLFSSL_CHECK_MEM_ZERO
38340
            wc_MemZero_Add("wolfSSL_RAND_write_file buf", buf, bytes);
38341
        #endif
38342
38343
0
            f = XFOPEN(fname, "wb");
38344
0
            if (f == XBADFILE) {
38345
0
                WOLFSSL_MSG("Error opening the file");
38346
0
                bytes = 0;
38347
0
            }
38348
0
            else {
38349
0
                size_t bytes_written = XFWRITE(buf, 1, bytes, f);
38350
0
                bytes = (int)bytes_written;
38351
0
                XFCLOSE(f);
38352
0
            }
38353
0
        }
38354
0
        ForceZero(buf, bytes);
38355
0
    #ifdef WOLFSSL_SMALL_STACK
38356
0
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38357
    #elif defined(WOLFSSL_CHECK_MEM_ZERO)
38358
        wc_MemZero_Check(buf, sizeof(buf));
38359
    #endif
38360
0
    }
38361
0
#endif
38362
38363
0
    return bytes;
38364
0
}
38365
38366
#ifndef FREERTOS_TCP
38367
38368
/* These constant values are protocol values made by egd */
38369
#if defined(USE_WOLFSSL_IO) && !defined(USE_WINDOWS_API) && !defined(HAVE_FIPS) && \
38370
    defined(HAVE_HASHDRBG) && !defined(NETOS) && defined(HAVE_SYS_UN_H)
38371
0
    #define WOLFSSL_EGD_NBLOCK 0x01
38372
    #include <sys/un.h>
38373
#endif
38374
38375
/* This collects entropy from the path nm and seeds the global PRNG with it.
38376
 *
38377
 * nm is the file path to the egd server
38378
 *
38379
 * Returns the number of bytes read.
38380
 */
38381
int wolfSSL_RAND_egd(const char* nm)
38382
0
{
38383
0
#ifdef WOLFSSL_EGD_NBLOCK
38384
0
    struct sockaddr_un rem;
38385
0
    int fd;
38386
0
    int ret = WOLFSSL_SUCCESS;
38387
0
    word32 bytes = 0;
38388
0
    word32 idx   = 0;
38389
#ifndef WOLFSSL_SMALL_STACK
38390
    unsigned char buf[256];
38391
#else
38392
0
    unsigned char* buf;
38393
0
    buf = (unsigned char*)XMALLOC(256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38394
0
    if (buf == NULL) {
38395
0
        WOLFSSL_MSG("Not enough memory");
38396
0
        return WOLFSSL_FATAL_ERROR;
38397
0
    }
38398
0
#endif
38399
38400
0
    XMEMSET(&rem, 0, sizeof(struct sockaddr_un));
38401
0
    if (nm == NULL) {
38402
0
    #ifdef WOLFSSL_SMALL_STACK
38403
0
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38404
0
    #endif
38405
0
        return WOLFSSL_FATAL_ERROR;
38406
0
    }
38407
38408
0
    fd = socket(AF_UNIX, SOCK_STREAM, 0);
38409
0
    if (fd < 0) {
38410
0
        WOLFSSL_MSG("Error creating socket");
38411
0
    #ifdef WOLFSSL_SMALL_STACK
38412
0
        XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38413
0
    #endif
38414
0
        return WOLFSSL_FATAL_ERROR;
38415
0
    }
38416
0
    rem.sun_family = AF_UNIX;
38417
0
    XSTRNCPY(rem.sun_path, nm, sizeof(rem.sun_path) - 1);
38418
0
    rem.sun_path[sizeof(rem.sun_path)-1] = '\0';
38419
38420
    /* connect to egd server */
38421
0
    if (connect(fd, (struct sockaddr*)&rem, sizeof(struct sockaddr_un)) == -1) {
38422
0
        WOLFSSL_MSG("error connecting to egd server");
38423
0
        ret = WOLFSSL_FATAL_ERROR;
38424
0
    }
38425
38426
#ifdef WOLFSSL_CHECK_MEM_ZERO
38427
    if (ret == WOLFSSL_SUCCESS) {
38428
        wc_MemZero_Add("wolfSSL_RAND_egd buf", buf, 256);
38429
    }
38430
#endif
38431
0
    while (ret == WOLFSSL_SUCCESS && bytes < 255 && idx + 2 < 256) {
38432
0
        buf[idx]     = WOLFSSL_EGD_NBLOCK;
38433
0
        buf[idx + 1] = 255 - bytes; /* request 255 bytes from server */
38434
0
        ret = (int)write(fd, buf + idx, 2);
38435
0
        if (ret != 2) {
38436
0
            if (errno == EAGAIN) {
38437
0
                ret = WOLFSSL_SUCCESS;
38438
0
                continue;
38439
0
            }
38440
0
            WOLFSSL_MSG("error requesting entropy from egd server");
38441
0
            ret = WOLFSSL_FATAL_ERROR;
38442
0
            break;
38443
0
        }
38444
38445
        /* attempting to read */
38446
0
        buf[idx] = 0;
38447
0
        ret = (int)read(fd, buf + idx, 256 - bytes);
38448
0
        if (ret == 0) {
38449
0
            WOLFSSL_MSG("error reading entropy from egd server");
38450
0
            ret = WOLFSSL_FATAL_ERROR;
38451
0
            break;
38452
0
        }
38453
0
        if (ret > 0 && buf[idx] > 0) {
38454
0
            bytes += buf[idx]; /* egd stores amount sent in first byte */
38455
0
            if (bytes + idx > 255 || buf[idx] > ret) {
38456
0
                WOLFSSL_MSG("Buffer error");
38457
0
                ret = WOLFSSL_FATAL_ERROR;
38458
0
                break;
38459
0
            }
38460
0
            XMEMMOVE(buf + idx, buf + idx + 1, buf[idx]);
38461
0
            idx = bytes;
38462
0
            ret = WOLFSSL_SUCCESS;
38463
0
            if (bytes >= 255) {
38464
0
                break;
38465
0
            }
38466
0
        }
38467
0
        else {
38468
0
            if (errno == EAGAIN || errno == EINTR) {
38469
0
                WOLFSSL_MSG("EGD would read");
38470
0
                ret = WOLFSSL_SUCCESS; /* try again */
38471
0
            }
38472
0
            else if (buf[idx] == 0) {
38473
                /* if egd returned 0 then there is no more entropy to be had.
38474
                   Do not try more reads. */
38475
0
                ret = WOLFSSL_SUCCESS;
38476
0
                break;
38477
0
            }
38478
0
            else {
38479
0
                WOLFSSL_MSG("Error with read");
38480
0
                ret = WOLFSSL_FATAL_ERROR;
38481
0
            }
38482
0
        }
38483
0
    }
38484
38485
0
    if (bytes > 0 && ret == WOLFSSL_SUCCESS) {
38486
        /* call to check global RNG is created */
38487
0
        if (wolfSSL_RAND_Init() != SSL_SUCCESS) {
38488
0
            WOLFSSL_MSG("Error with initializing global RNG structure");
38489
0
            ret = WOLFSSL_FATAL_ERROR;
38490
0
        }
38491
0
        else if (wc_RNG_DRBG_Reseed(&globalRNG, (const byte*) buf, bytes)
38492
0
                != 0) {
38493
0
            WOLFSSL_MSG("Error with reseeding DRBG structure");
38494
0
            ret = WOLFSSL_FATAL_ERROR;
38495
0
        }
38496
        #ifdef SHOW_SECRETS
38497
        else { /* print out entropy found only when no error occured */
38498
            word32 i;
38499
            printf("EGD Entropy = ");
38500
            for (i = 0; i < bytes; i++) {
38501
                printf("%02X", buf[i]);
38502
            }
38503
            printf("\n");
38504
        }
38505
        #endif
38506
0
    }
38507
38508
0
    ForceZero(buf, bytes);
38509
0
#ifdef WOLFSSL_SMALL_STACK
38510
0
    XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38511
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
38512
    wc_MemZero_Check(buf, 256);
38513
#endif
38514
0
    close(fd);
38515
38516
0
    if (ret == WOLFSSL_SUCCESS) {
38517
0
        return bytes;
38518
0
    }
38519
0
    else {
38520
0
        return ret;
38521
0
    }
38522
#else
38523
    WOLFSSL_MSG("Type of socket needed is not available");
38524
    WOLFSSL_MSG("\tor using mode where DRBG API is not available");
38525
    (void)nm;
38526
38527
    return WOLFSSL_FATAL_ERROR;
38528
#endif /* WOLFSSL_EGD_NBLOCK */
38529
0
}
38530
38531
#endif /* !FREERTOS_TCP */
38532
38533
void wolfSSL_RAND_Cleanup(void)
38534
0
{
38535
0
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38536
0
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38537
0
        if (gRandMethods && gRandMethods->cleanup)
38538
0
            gRandMethods->cleanup();
38539
0
        wc_UnLockMutex(&gRandMethodMutex);
38540
0
    }
38541
38542
0
    if (wc_FreeMutex(&gRandMethodMutex) == 0)
38543
0
        gRandMethodsInit = 0;
38544
0
#endif
38545
0
#ifdef HAVE_GLOBAL_RNG
38546
0
    if (wc_LockMutex(&globalRNGMutex) == 0) {
38547
0
        if (initGlobalRNG) {
38548
0
            wc_FreeRng(&globalRNG);
38549
0
            initGlobalRNG = 0;
38550
0
        }
38551
0
        wc_UnLockMutex(&globalRNGMutex);
38552
0
    }
38553
0
#endif
38554
0
}
38555
38556
/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
38557
int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
38558
0
{
38559
0
    int ret;
38560
0
    int hash;
38561
0
    byte secret[DRBG_SEED_LEN]; /* secret length arbitraily choosen */
38562
38563
0
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38564
0
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38565
0
        if (gRandMethods && gRandMethods->pseudorand) {
38566
0
            ret = gRandMethods->pseudorand(buf, num);
38567
0
            wc_UnLockMutex(&gRandMethodMutex);
38568
0
            return ret;
38569
0
        }
38570
0
        wc_UnLockMutex(&gRandMethodMutex);
38571
0
    }
38572
0
#endif
38573
38574
0
#ifdef WOLFSSL_HAVE_PRF
38575
0
    #ifndef NO_SHA256
38576
0
    hash = WC_SHA256;
38577
    #elif defined(WOLFSSL_SHA384)
38578
    hash = WC_SHA384;
38579
    #elif !defined(NO_SHA)
38580
    hash = WC_SHA;
38581
    #elif !defined(NO_MD5)
38582
    hash = WC_MD5;
38583
    #endif
38584
38585
    /* get secret value from source of entropy */
38586
0
    ret = wolfSSL_RAND_bytes(secret, DRBG_SEED_LEN);
38587
38588
    /* uses input buffer to seed for pseudo random number generation, each
38589
     * thread will potentially have different results this way */
38590
0
    if (ret == WOLFSSL_SUCCESS) {
38591
0
        PRIVATE_KEY_UNLOCK();
38592
0
        ret = wc_PRF(buf, num, secret, DRBG_SEED_LEN, (const byte*)buf, num,
38593
0
                hash, NULL, INVALID_DEVID);
38594
0
        PRIVATE_KEY_LOCK();
38595
0
        ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE;
38596
0
    }
38597
#else
38598
    /* fall back to just doing wolfSSL_RAND_bytes if PRF not avialbale */
38599
    ret = wolfSSL_RAND_bytes(buf, num);
38600
    (void)hash;
38601
    (void)secret;
38602
#endif
38603
0
    return ret;
38604
0
}
38605
38606
/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
38607
int wolfSSL_RAND_bytes(unsigned char* buf, int num)
38608
0
{
38609
0
    int     ret = 0;
38610
0
    WC_RNG* rng = NULL;
38611
0
#ifdef WOLFSSL_SMALL_STACK
38612
0
    WC_RNG* tmpRNG = NULL;
38613
#else
38614
    WC_RNG  tmpRNG[1];
38615
#endif
38616
0
    int initTmpRng = 0;
38617
0
    int blockCount = 0;
38618
0
#ifdef HAVE_GLOBAL_RNG
38619
0
    int used_global = 0;
38620
0
#endif
38621
38622
0
    WOLFSSL_ENTER("wolfSSL_RAND_bytes");
38623
    /* sanity check */
38624
0
    if (buf == NULL || num < 0)
38625
        /* return code compliant with OpenSSL */
38626
0
        return 0;
38627
38628
    /* if a RAND callback has been set try and use it */
38629
0
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38630
0
    if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38631
0
        if (gRandMethods && gRandMethods->bytes) {
38632
0
            ret = gRandMethods->bytes(buf, num);
38633
0
            wc_UnLockMutex(&gRandMethodMutex);
38634
0
            return ret;
38635
0
        }
38636
0
        wc_UnLockMutex(&gRandMethodMutex);
38637
0
    }
38638
0
#endif
38639
0
#ifdef HAVE_GLOBAL_RNG
38640
0
    if (initGlobalRNG) {
38641
0
        if (wc_LockMutex(&globalRNGMutex) != 0) {
38642
0
            WOLFSSL_MSG("Bad Lock Mutex rng");
38643
0
            return ret;
38644
0
        }
38645
38646
0
        rng = &globalRNG;
38647
0
        used_global = 1;
38648
0
    }
38649
0
    else
38650
0
#endif
38651
0
    {
38652
0
    #ifdef WOLFSSL_SMALL_STACK
38653
0
        tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
38654
0
        if (tmpRNG == NULL)
38655
0
            return ret;
38656
0
    #endif
38657
0
        if (wc_InitRng(tmpRNG) == 0) {
38658
0
            rng = tmpRNG;
38659
0
            initTmpRng = 1;
38660
0
        }
38661
0
    }
38662
0
    if (rng) {
38663
        /* handles size greater than RNG_MAX_BLOCK_LEN */
38664
0
        blockCount = num / RNG_MAX_BLOCK_LEN;
38665
38666
0
        while (blockCount--) {
38667
0
            ret = wc_RNG_GenerateBlock(rng, buf, RNG_MAX_BLOCK_LEN);
38668
0
            if (ret != 0) {
38669
0
                WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
38670
0
                break;
38671
0
            }
38672
0
            num -= RNG_MAX_BLOCK_LEN;
38673
0
            buf += RNG_MAX_BLOCK_LEN;
38674
0
        }
38675
38676
0
        if (ret == 0 && num)
38677
0
            ret = wc_RNG_GenerateBlock(rng, buf, num);
38678
38679
0
        if (ret != 0)
38680
0
            WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
38681
0
        else
38682
0
            ret = WOLFSSL_SUCCESS;
38683
0
    }
38684
38685
0
#ifdef HAVE_GLOBAL_RNG
38686
0
    if (used_global == 1)
38687
0
        wc_UnLockMutex(&globalRNGMutex);
38688
0
#endif
38689
0
    if (initTmpRng)
38690
0
        wc_FreeRng(tmpRNG);
38691
0
#ifdef WOLFSSL_SMALL_STACK
38692
0
    if (tmpRNG)
38693
0
        XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
38694
0
#endif
38695
38696
0
    return ret;
38697
0
}
38698
38699
38700
int wolfSSL_RAND_poll(void)
38701
0
{
38702
0
    byte  entropy[16];
38703
0
    int  ret = 0;
38704
0
    word32 entropy_sz = 16;
38705
38706
0
    WOLFSSL_ENTER("wolfSSL_RAND_poll");
38707
0
    if (initGlobalRNG == 0){
38708
0
        WOLFSSL_MSG("Global RNG no Init");
38709
0
        return  WOLFSSL_FAILURE;
38710
0
    }
38711
0
    ret = wc_GenerateSeed(&globalRNG.seed, entropy, entropy_sz);
38712
0
    if (ret != 0){
38713
0
        WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
38714
0
        ret = WOLFSSL_FAILURE;
38715
0
    }else
38716
0
        ret = WOLFSSL_SUCCESS;
38717
38718
0
    return ret;
38719
0
}
38720
38721
    /* If a valid struct is provided with function pointers, will override
38722
       RAND_seed, bytes, cleanup, add, pseudo_bytes and status.  If a NULL
38723
       pointer is passed in, it will cancel any previous function overrides.
38724
38725
       Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. */
38726
    int wolfSSL_RAND_set_rand_method(const WOLFSSL_RAND_METHOD *methods)
38727
0
    {
38728
0
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38729
0
        if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38730
0
            gRandMethods = methods;
38731
0
            wc_UnLockMutex(&gRandMethodMutex);
38732
0
            return WOLFSSL_SUCCESS;
38733
0
        }
38734
    #else
38735
        (void)methods;
38736
    #endif
38737
0
        return WOLFSSL_FAILURE;
38738
0
    }
38739
38740
    /* Returns WOLFSSL_SUCCESS if the RNG has been seeded with enough data */
38741
    int wolfSSL_RAND_status(void)
38742
0
    {
38743
0
        int ret = WOLFSSL_SUCCESS;
38744
0
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38745
0
        if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38746
0
            if (gRandMethods && gRandMethods->status)
38747
0
                ret = gRandMethods->status();
38748
0
            wc_UnLockMutex(&gRandMethodMutex);
38749
0
        }
38750
0
        else {
38751
0
            ret = WOLFSSL_FAILURE;
38752
0
        }
38753
    #else
38754
        /* wolfCrypt provides enough seed internally, so return success */
38755
    #endif
38756
0
        return ret;
38757
0
    }
38758
38759
    void wolfSSL_RAND_add(const void* add, int len, double entropy)
38760
0
    {
38761
0
    #ifndef WOLFSSL_NO_OPENSSL_RAND_CB
38762
0
        if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
38763
0
            if (gRandMethods && gRandMethods->add) {
38764
                /* callback has return code, but RAND_add does not */
38765
0
                (void)gRandMethods->add(add, len, entropy);
38766
0
            }
38767
0
            wc_UnLockMutex(&gRandMethodMutex);
38768
0
        }
38769
    #else
38770
        /* wolfSSL seeds/adds internally, use explicit RNG if you want
38771
           to take control */
38772
        (void)add;
38773
        (void)len;
38774
        (void)entropy;
38775
    #endif
38776
0
    }
38777
38778
#endif /* OPENSSL_EXTRA */
38779
38780
/*******************************************************************************
38781
 * END OF RAND API
38782
 ******************************************************************************/
38783
38784
/*******************************************************************************
38785
 * START OF EVP_CIPHER API
38786
 ******************************************************************************/
38787
38788
#ifdef OPENSSL_EXTRA
38789
38790
    /* store for external read of iv, WOLFSSL_SUCCESS on success */
38791
    int  wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
38792
790
    {
38793
790
        WOLFSSL_ENTER("wolfSSL_StoreExternalIV");
38794
38795
790
        if (ctx == NULL) {
38796
0
            WOLFSSL_MSG("Bad function argument");
38797
0
            return WOLFSSL_FATAL_ERROR;
38798
0
        }
38799
38800
790
        switch (ctx->cipherType) {
38801
0
#ifndef NO_AES
38802
0
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
38803
114
            case AES_128_CBC_TYPE :
38804
120
            case AES_192_CBC_TYPE :
38805
122
            case AES_256_CBC_TYPE :
38806
122
                WOLFSSL_MSG("AES CBC");
38807
122
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
38808
122
                break;
38809
0
#endif
38810
0
#ifdef HAVE_AESGCM
38811
53
            case AES_128_GCM_TYPE :
38812
181
            case AES_192_GCM_TYPE :
38813
288
            case AES_256_GCM_TYPE :
38814
288
                WOLFSSL_MSG("AES GCM");
38815
288
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
38816
288
                break;
38817
0
#endif /* HAVE_AESGCM */
38818
0
#ifdef HAVE_AES_ECB
38819
0
            case AES_128_ECB_TYPE :
38820
0
            case AES_192_ECB_TYPE :
38821
0
            case AES_256_ECB_TYPE :
38822
0
                WOLFSSL_MSG("AES ECB");
38823
0
                break;
38824
0
#endif
38825
0
#ifdef WOLFSSL_AES_COUNTER
38826
8
            case AES_128_CTR_TYPE :
38827
30
            case AES_192_CTR_TYPE :
38828
47
            case AES_256_CTR_TYPE :
38829
47
                WOLFSSL_MSG("AES CTR");
38830
47
                XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
38831
47
                break;
38832
0
#endif /* WOLFSSL_AES_COUNTER */
38833
0
#ifdef WOLFSSL_AES_CFB
38834
0
#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
38835
0
            case AES_128_CFB1_TYPE:
38836
0
            case AES_192_CFB1_TYPE:
38837
0
            case AES_256_CFB1_TYPE:
38838
0
                WOLFSSL_MSG("AES CFB1");
38839
0
                break;
38840
0
            case AES_128_CFB8_TYPE:
38841
0
            case AES_192_CFB8_TYPE:
38842
0
            case AES_256_CFB8_TYPE:
38843
0
                WOLFSSL_MSG("AES CFB8");
38844
0
                break;
38845
0
#endif /* !HAVE_SELFTEST && !HAVE_FIPS */
38846
0
            case AES_128_CFB128_TYPE:
38847
0
            case AES_192_CFB128_TYPE:
38848
0
            case AES_256_CFB128_TYPE:
38849
0
                WOLFSSL_MSG("AES CFB128");
38850
0
                break;
38851
0
#endif /* WOLFSSL_AES_CFB */
38852
0
#if defined(WOLFSSL_AES_OFB)
38853
0
            case AES_128_OFB_TYPE:
38854
0
            case AES_192_OFB_TYPE:
38855
0
            case AES_256_OFB_TYPE:
38856
0
                WOLFSSL_MSG("AES OFB");
38857
0
                break;
38858
0
#endif /* WOLFSSL_AES_OFB */
38859
0
#ifdef WOLFSSL_AES_XTS
38860
108
            case AES_128_XTS_TYPE:
38861
142
            case AES_256_XTS_TYPE:
38862
142
                WOLFSSL_MSG("AES XTS");
38863
142
                break;
38864
0
#endif /* WOLFSSL_AES_XTS */
38865
0
#endif /* NO_AES */
38866
38867
0
#ifndef NO_DES3
38868
173
            case DES_CBC_TYPE :
38869
173
                WOLFSSL_MSG("DES CBC");
38870
173
                XMEMCPY(ctx->iv, &ctx->cipher.des.reg, DES_BLOCK_SIZE);
38871
173
                break;
38872
38873
18
            case DES_EDE3_CBC_TYPE :
38874
18
                WOLFSSL_MSG("DES EDE3 CBC");
38875
18
                XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
38876
18
                break;
38877
0
#endif
38878
0
#ifdef WOLFSSL_DES_ECB
38879
0
            case DES_ECB_TYPE :
38880
0
                WOLFSSL_MSG("DES ECB");
38881
0
                break;
38882
0
            case DES_EDE3_ECB_TYPE :
38883
0
                WOLFSSL_MSG("DES3 ECB");
38884
0
                break;
38885
0
#endif
38886
0
            case ARC4_TYPE :
38887
0
                WOLFSSL_MSG("ARC4");
38888
0
                break;
38889
38890
0
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
38891
0
            case CHACHA20_POLY1305_TYPE:
38892
0
                break;
38893
0
#endif
38894
38895
0
            case NULL_CIPHER_TYPE :
38896
0
                WOLFSSL_MSG("NULL");
38897
0
                break;
38898
38899
0
            default: {
38900
0
                WOLFSSL_MSG("bad type");
38901
0
                return WOLFSSL_FATAL_ERROR;
38902
108
            }
38903
790
        }
38904
790
        return WOLFSSL_SUCCESS;
38905
790
    }
38906
38907
    /* set internal IV from external, WOLFSSL_SUCCESS on success */
38908
    int  wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx)
38909
0
    {
38910
38911
0
        WOLFSSL_ENTER("wolfSSL_SetInternalIV");
38912
38913
0
        if (ctx == NULL) {
38914
0
            WOLFSSL_MSG("Bad function argument");
38915
0
            return WOLFSSL_FATAL_ERROR;
38916
0
        }
38917
38918
0
        switch (ctx->cipherType) {
38919
38920
0
#ifndef NO_AES
38921
0
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
38922
0
            case AES_128_CBC_TYPE :
38923
0
            case AES_192_CBC_TYPE :
38924
0
            case AES_256_CBC_TYPE :
38925
0
                WOLFSSL_MSG("AES CBC");
38926
0
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
38927
0
                break;
38928
0
#endif
38929
0
#ifdef HAVE_AESGCM
38930
0
            case AES_128_GCM_TYPE :
38931
0
            case AES_192_GCM_TYPE :
38932
0
            case AES_256_GCM_TYPE :
38933
0
                WOLFSSL_MSG("AES GCM");
38934
0
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
38935
0
                break;
38936
0
#endif
38937
0
#ifdef HAVE_AES_ECB
38938
0
            case AES_128_ECB_TYPE :
38939
0
            case AES_192_ECB_TYPE :
38940
0
            case AES_256_ECB_TYPE :
38941
0
                WOLFSSL_MSG("AES ECB");
38942
0
                break;
38943
0
#endif
38944
0
#ifdef WOLFSSL_AES_COUNTER
38945
0
            case AES_128_CTR_TYPE :
38946
0
            case AES_192_CTR_TYPE :
38947
0
            case AES_256_CTR_TYPE :
38948
0
                WOLFSSL_MSG("AES CTR");
38949
0
                XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE);
38950
0
                break;
38951
0
#endif
38952
38953
0
#endif /* NO_AES */
38954
38955
0
#ifndef NO_DES3
38956
0
            case DES_CBC_TYPE :
38957
0
                WOLFSSL_MSG("DES CBC");
38958
0
                XMEMCPY(&ctx->cipher.des.reg, ctx->iv, DES_BLOCK_SIZE);
38959
0
                break;
38960
38961
0
            case DES_EDE3_CBC_TYPE :
38962
0
                WOLFSSL_MSG("DES EDE3 CBC");
38963
0
                XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE);
38964
0
                break;
38965
0
#endif
38966
0
#ifdef WOLFSSL_DES_ECB
38967
0
            case DES_ECB_TYPE :
38968
0
                WOLFSSL_MSG("DES ECB");
38969
0
                break;
38970
0
            case DES_EDE3_ECB_TYPE :
38971
0
                WOLFSSL_MSG("DES3 ECB");
38972
0
                break;
38973
0
#endif
38974
38975
0
            case ARC4_TYPE :
38976
0
                WOLFSSL_MSG("ARC4");
38977
0
                break;
38978
38979
0
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
38980
0
            case CHACHA20_POLY1305_TYPE:
38981
0
                break;
38982
0
#endif
38983
38984
0
            case NULL_CIPHER_TYPE :
38985
0
                WOLFSSL_MSG("NULL");
38986
0
                break;
38987
38988
0
            default: {
38989
0
                WOLFSSL_MSG("bad type");
38990
0
                return WOLFSSL_FATAL_ERROR;
38991
0
            }
38992
0
        }
38993
0
        return WOLFSSL_SUCCESS;
38994
0
    }
38995
38996
#ifndef NO_DES3
38997
38998
void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
38999
                            unsigned char* iv, int len)
39000
0
{
39001
0
    (void)len;
39002
39003
0
    WOLFSSL_MSG("wolfSSL_3des_iv");
39004
39005
0
    if (ctx == NULL || iv == NULL) {
39006
0
        WOLFSSL_MSG("Bad function argument");
39007
0
        return;
39008
0
    }
39009
39010
0
    if (doset)
39011
0
        wc_Des3_SetIV(&ctx->cipher.des3, iv);  /* OpenSSL compat, no ret */
39012
0
    else
39013
0
        XMEMCPY(iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE);
39014
0
}
39015
39016
#endif /* NO_DES3 */
39017
39018
39019
#ifndef NO_AES
39020
39021
void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset,
39022
                      unsigned char* iv, int len)
39023
0
{
39024
0
    (void)len;
39025
39026
0
    WOLFSSL_MSG("wolfSSL_aes_ctr_iv");
39027
39028
0
    if (ctx == NULL || iv == NULL) {
39029
0
        WOLFSSL_MSG("Bad function argument");
39030
0
        return;
39031
0
    }
39032
39033
0
    if (doset)
39034
0
       (void)wc_AesSetIV(&ctx->cipher.aes, iv);  /* OpenSSL compat, no ret */
39035
0
    else
39036
0
        XMEMCPY(iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE);
39037
0
}
39038
39039
#endif /* NO_AES */
39040
39041
#endif /* OPENSSL_EXTRA */
39042
39043
/*******************************************************************************
39044
 * END OF EVP_CIPHER API
39045
 ******************************************************************************/
39046
39047
#ifndef NO_CERTS
39048
39049
#define WOLFSSL_X509_STORE_INCLUDED
39050
#include <src/x509_str.c>
39051
39052
/*******************************************************************************
39053
 * START OF PKCS7 APIs
39054
 ******************************************************************************/
39055
#ifdef HAVE_PKCS7
39056
39057
#ifdef OPENSSL_ALL
39058
PKCS7* wolfSSL_PKCS7_new(void)
39059
{
39060
    WOLFSSL_PKCS7* pkcs7;
39061
    int ret = 0;
39062
39063
    pkcs7 = (WOLFSSL_PKCS7*)XMALLOC(sizeof(WOLFSSL_PKCS7), NULL,
39064
                                    DYNAMIC_TYPE_PKCS7);
39065
    if (pkcs7 != NULL) {
39066
        XMEMSET(pkcs7, 0, sizeof(WOLFSSL_PKCS7));
39067
        ret = wc_PKCS7_Init(&pkcs7->pkcs7, NULL, INVALID_DEVID);
39068
    }
39069
39070
    if (ret != 0 && pkcs7 != NULL) {
39071
        XFREE(pkcs7, NULL, DYNAMIC_TYPE_PKCS7);
39072
        pkcs7 = NULL;
39073
    }
39074
39075
    return (PKCS7*)pkcs7;
39076
}
39077
39078
/******************************************************************************
39079
* wolfSSL_PKCS7_SIGNED_new - allocates PKCS7 and initialize it for a signed data
39080
*
39081
* RETURNS:
39082
* returns pointer to the PKCS7 structure on success, otherwise returns NULL
39083
*/
39084
PKCS7_SIGNED* wolfSSL_PKCS7_SIGNED_new(void)
39085
{
39086
    byte signedData[]= { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02};
39087
    PKCS7* pkcs7 = NULL;
39088
39089
    if ((pkcs7 = wolfSSL_PKCS7_new()) == NULL)
39090
        return NULL;
39091
    pkcs7->contentOID = SIGNED_DATA;
39092
    if ((wc_PKCS7_SetContentType(pkcs7, signedData, sizeof(signedData))) < 0) {
39093
        if (pkcs7) {
39094
            wolfSSL_PKCS7_free(pkcs7);
39095
            return NULL;
39096
        }
39097
    }
39098
    return pkcs7;
39099
}
39100
39101
void wolfSSL_PKCS7_free(PKCS7* pkcs7)
39102
{
39103
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39104
39105
    if (p7 != NULL) {
39106
        if (p7->data != NULL)
39107
            XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
39108
        wc_PKCS7_Free(&p7->pkcs7);
39109
        if (p7->certs)
39110
            wolfSSL_sk_pop_free(p7->certs, NULL);
39111
        XFREE(p7, NULL, DYNAMIC_TYPE_PKCS7);
39112
    }
39113
}
39114
39115
void wolfSSL_PKCS7_SIGNED_free(PKCS7_SIGNED* p7)
39116
{
39117
    wolfSSL_PKCS7_free(p7);
39118
    return;
39119
}
39120
39121
/**
39122
 * Convert DER/ASN.1 encoded signedData structure to internal PKCS7
39123
 * structure. Note, does not support detached content.
39124
 *
39125
 * p7 - pointer to set to address of newly created PKCS7 structure on return
39126
 * in - pointer to pointer of DER/ASN.1 data
39127
 * len - length of input data, bytes
39128
 *
39129
 * Returns newly allocated and populated PKCS7 structure or NULL on error.
39130
 */
39131
PKCS7* wolfSSL_d2i_PKCS7(PKCS7** p7, const unsigned char** in, int len)
39132
{
39133
    return wolfSSL_d2i_PKCS7_ex(p7, in, len, NULL, 0);
39134
}
39135
39136
/*****************************************************************************
39137
* wolfSSL_d2i_PKCS7_ex - Converts the given unsigned char buffer of size len
39138
* into a PKCS7 object.  Optionally, accepts a byte buffer of content which
39139
* is stored as the PKCS7 object's content, to support detached signatures.
39140
* @param content The content which is signed, in case the signature is
39141
*                detached.  Ignored if NULL.
39142
* @param contentSz The size of the passed in content.
39143
*
39144
* RETURNS:
39145
* returns pointer to a PKCS7 structure on success, otherwise returns NULL
39146
*/
39147
PKCS7* wolfSSL_d2i_PKCS7_ex(PKCS7** p7, const unsigned char** in, int len,
39148
        byte* content, word32 contentSz)
39149
{
39150
    WOLFSSL_PKCS7* pkcs7 = NULL;
39151
39152
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_ex");
39153
39154
    if (in == NULL || *in == NULL || len < 0)
39155
        return NULL;
39156
39157
    if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
39158
        return NULL;
39159
39160
    pkcs7->len = len;
39161
    pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
39162
    if (pkcs7->data == NULL) {
39163
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39164
        return NULL;
39165
    }
39166
    XMEMCPY(pkcs7->data, *in, pkcs7->len);
39167
39168
    if (content != NULL) {
39169
        pkcs7->pkcs7.content = content;
39170
        pkcs7->pkcs7.contentSz = contentSz;
39171
    }
39172
    if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
39173
                                                                         != 0) {
39174
        WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
39175
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39176
        return NULL;
39177
    }
39178
39179
    if (p7 != NULL)
39180
        *p7 = (PKCS7*)pkcs7;
39181
    *in += pkcs7->len;
39182
    return (PKCS7*)pkcs7;
39183
}
39184
39185
/**
39186
 * This API was added as a helper function for libest. It
39187
 * extracts a stack of certificates from the pkcs7 object.
39188
 * @param pkcs7 PKCS7 parameter object
39189
 * @return WOLFSSL_STACK_OF(WOLFSSL_X509)*
39190
 */
39191
WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7)
39192
{
39193
    int i;
39194
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39195
    WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
39196
39197
    WOLFSSL_ENTER("wolfSSL_PKCS7_to_stack");
39198
39199
    if (!p7) {
39200
        WOLFSSL_MSG("Bad parameter");
39201
        return NULL;
39202
    }
39203
39204
    if (p7->certs)
39205
        return p7->certs;
39206
39207
    for (i = 0; i < MAX_PKCS7_CERTS && p7->pkcs7.cert[i]; i++) {
39208
        WOLFSSL_X509* x509 = wolfSSL_X509_d2i(NULL, p7->pkcs7.cert[i],
39209
            p7->pkcs7.certSz[i]);
39210
        if (!ret)
39211
            ret = wolfSSL_sk_X509_new();
39212
        if (x509) {
39213
            if (wolfSSL_sk_X509_push(ret, x509) != WOLFSSL_SUCCESS) {
39214
                wolfSSL_X509_free(x509);
39215
                WOLFSSL_MSG("wolfSSL_sk_X509_push error");
39216
                goto error;
39217
            }
39218
        }
39219
        else {
39220
            WOLFSSL_MSG("wolfSSL_X509_d2i error");
39221
            goto error;
39222
        }
39223
    }
39224
39225
    /* Save stack to free later */
39226
    if (p7->certs)
39227
        wolfSSL_sk_pop_free(p7->certs, NULL);
39228
    p7->certs = ret;
39229
39230
    return ret;
39231
error:
39232
    if (ret) {
39233
        wolfSSL_sk_pop_free(ret, NULL);
39234
    }
39235
    return NULL;
39236
}
39237
39238
/**
39239
 * Return stack of signers contained in PKCS7 cert.
39240
 * Notes:
39241
 * - Currently only PKCS#7 messages with a single signer cert is supported.
39242
 * - Returned WOLFSSL_STACK must be freed by caller.
39243
 *
39244
 * pkcs7 - PKCS7 struct to retrieve signer certs from.
39245
 * certs - currently unused
39246
 * flags - flags to control function behavior.
39247
 *
39248
 * Return WOLFSSL_STACK of signers on success, NULL on error.
39249
 */
39250
WOLFSSL_STACK* wolfSSL_PKCS7_get0_signers(PKCS7* pkcs7, WOLFSSL_STACK* certs,
39251
                                          int flags)
39252
{
39253
    WOLFSSL_X509* x509 = NULL;
39254
    WOLFSSL_STACK* signers = NULL;
39255
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39256
39257
    if (p7 == NULL)
39258
        return NULL;
39259
39260
    /* Only PKCS#7 messages with a single cert that is the verifying certificate
39261
     * is supported.
39262
     */
39263
    if (flags & PKCS7_NOINTERN) {
39264
        WOLFSSL_MSG("PKCS7_NOINTERN flag not supported");
39265
        return NULL;
39266
    }
39267
39268
    signers = wolfSSL_sk_X509_new();
39269
    if (signers == NULL)
39270
        return NULL;
39271
39272
    if (wolfSSL_d2i_X509(&x509, (const byte**)&p7->pkcs7.singleCert,
39273
                         p7->pkcs7.singleCertSz) == NULL) {
39274
        wolfSSL_sk_X509_pop_free(signers, NULL);
39275
        return NULL;
39276
    }
39277
39278
    if (wolfSSL_sk_X509_push(signers, x509) != WOLFSSL_SUCCESS) {
39279
        wolfSSL_sk_X509_pop_free(signers, NULL);
39280
        return NULL;
39281
    }
39282
39283
    (void)certs;
39284
39285
    return signers;
39286
}
39287
39288
#ifndef NO_BIO
39289
39290
PKCS7* wolfSSL_d2i_PKCS7_bio(WOLFSSL_BIO* bio, PKCS7** p7)
39291
{
39292
    WOLFSSL_PKCS7* pkcs7;
39293
    int ret;
39294
39295
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS7_bio");
39296
39297
    if (bio == NULL)
39298
        return NULL;
39299
39300
    if ((pkcs7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)
39301
        return NULL;
39302
39303
    pkcs7->len = wolfSSL_BIO_get_len(bio);
39304
    pkcs7->data = (byte*)XMALLOC(pkcs7->len, NULL, DYNAMIC_TYPE_PKCS7);
39305
    if (pkcs7->data == NULL) {
39306
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39307
        return NULL;
39308
    }
39309
39310
    if ((ret = wolfSSL_BIO_read(bio, pkcs7->data, pkcs7->len)) <= 0) {
39311
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39312
        return NULL;
39313
    }
39314
    /* pkcs7->len may change if using b64 for example */
39315
    pkcs7->len = ret;
39316
39317
    if (wc_PKCS7_VerifySignedData(&pkcs7->pkcs7, pkcs7->data, pkcs7->len)
39318
                                                                         != 0) {
39319
        WOLFSSL_MSG("wc_PKCS7_VerifySignedData failed");
39320
        wolfSSL_PKCS7_free((PKCS7*)pkcs7);
39321
        return NULL;
39322
    }
39323
39324
    if (p7 != NULL)
39325
        *p7 = (PKCS7*)pkcs7;
39326
    return (PKCS7*)pkcs7;
39327
}
39328
39329
int wolfSSL_i2d_PKCS7(PKCS7 *p7, unsigned char **out)
39330
{
39331
    byte* output = NULL;
39332
    int localBuf = 0;
39333
    int len;
39334
    WC_RNG rng;
39335
    int ret = WOLFSSL_FAILURE;
39336
    WOLFSSL_ENTER("wolfSSL_i2d_PKCS7");
39337
39338
    if (!out || !p7) {
39339
        WOLFSSL_MSG("Bad parameter");
39340
        return WOLFSSL_FAILURE;
39341
    }
39342
39343
    if (!p7->rng) {
39344
        if (wc_InitRng(&rng) != 0) {
39345
            WOLFSSL_MSG("wc_InitRng error");
39346
            return WOLFSSL_FAILURE;
39347
        }
39348
        p7->rng = &rng; // cppcheck-suppress autoVariables
39349
    }
39350
39351
    if ((len = wc_PKCS7_EncodeSignedData(p7, NULL, 0)) < 0) {
39352
        WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
39353
        goto cleanup;
39354
    }
39355
39356
    if (*out == NULL) {
39357
        output = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
39358
        if (!output) {
39359
            WOLFSSL_MSG("malloc error");
39360
            goto cleanup;
39361
        }
39362
        localBuf = 1;
39363
    }
39364
    else {
39365
        output = *out;
39366
    }
39367
39368
    if ((len = wc_PKCS7_EncodeSignedData(p7, output, len)) < 0) {
39369
        WOLFSSL_MSG("wc_PKCS7_EncodeSignedData error");
39370
        goto cleanup;
39371
    }
39372
39373
    ret = len;
39374
cleanup:
39375
    if (p7->rng == &rng) {
39376
        wc_FreeRng(&rng);
39377
        p7->rng = NULL;
39378
    }
39379
    if (ret == WOLFSSL_FAILURE && localBuf && output)
39380
        XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
39381
    if (ret != WOLFSSL_FAILURE)
39382
        *out = output;
39383
    return ret;
39384
}
39385
39386
int wolfSSL_i2d_PKCS7_bio(WOLFSSL_BIO *bio, PKCS7 *p7)
39387
{
39388
    byte* output = NULL;
39389
    int len;
39390
    int ret = WOLFSSL_FAILURE;
39391
    WOLFSSL_ENTER("wolfSSL_i2d_PKCS7_bio");
39392
39393
    if (!bio || !p7) {
39394
        WOLFSSL_MSG("Bad parameter");
39395
        return WOLFSSL_FAILURE;
39396
    }
39397
39398
    if ((len = wolfSSL_i2d_PKCS7(p7, &output)) == WOLFSSL_FAILURE) {
39399
        WOLFSSL_MSG("wolfSSL_i2d_PKCS7 error");
39400
        goto cleanup;
39401
    }
39402
39403
    if (wolfSSL_BIO_write(bio, output, len) <= 0) {
39404
        WOLFSSL_MSG("wolfSSL_BIO_write error");
39405
        goto cleanup;
39406
    }
39407
39408
    ret = WOLFSSL_SUCCESS;
39409
cleanup:
39410
    if (output)
39411
        XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER);
39412
    return ret;
39413
}
39414
39415
/**
39416
 * Creates and returns a PKCS7 signedData structure.
39417
 *
39418
 * Inner content type is set to DATA to match OpenSSL behavior.
39419
 *
39420
 * signer   - certificate to sign bundle with
39421
 * pkey     - private key matching signer
39422
 * certs    - optional additional set of certificates to include
39423
 * in       - input data to be signed
39424
 * flags    - optional set of flags to control sign behavior
39425
 *
39426
 *    PKCS7_BINARY   - Do not translate input data to MIME canonical
39427
 *                     format (\r\n line endings), thus preventing corruption of
39428
 *                     binary content.
39429
 *    PKCS7_TEXT     - Prepend MIME headers for text/plain to content.
39430
 *    PKCS7_DETACHED - Set signature detached, omit content from output bundle.
39431
 *    PKCS7_STREAM   - initialize PKCS7 struct for signing, do not read data.
39432
 *
39433
 * Flags not currently supported:
39434
 *    PKCS7_NOCERTS  - Do not include the signer cert in the output bundle.
39435
 *    PKCS7_PARTIAL  - Allow for PKCS7_sign() to be only partially set up,
39436
 *                     then signers etc to be added separately before
39437
 *                     calling PKCS7_final().
39438
 *
39439
 * Returns valid PKCS7 structure pointer, or NULL if an error occurred.
39440
 */
39441
PKCS7* wolfSSL_PKCS7_sign(WOLFSSL_X509* signer, WOLFSSL_EVP_PKEY* pkey,
39442
        WOLFSSL_STACK* certs, WOLFSSL_BIO* in, int flags)
39443
{
39444
    int err = 0;
39445
    WOLFSSL_PKCS7* p7 = NULL;
39446
    WOLFSSL_STACK* cert = certs;
39447
39448
    WOLFSSL_ENTER("wolfSSL_PKCS7_sign");
39449
39450
    if (flags & PKCS7_NOCERTS) {
39451
        WOLFSSL_MSG("PKCS7_NOCERTS flag not yet supported");
39452
        err = 1;
39453
    }
39454
39455
    if (flags & PKCS7_PARTIAL) {
39456
        WOLFSSL_MSG("PKCS7_PARTIAL flag not yet supported");
39457
        err = 1;
39458
    }
39459
39460
    if ((err == 0) && (signer == NULL || signer->derCert == NULL ||
39461
                       signer->derCert->length == 0)) {
39462
        WOLFSSL_MSG("Bad function arg, signer is NULL or incomplete");
39463
        err = 1;
39464
    }
39465
39466
    if ((err == 0) && (pkey == NULL || pkey->pkey.ptr == NULL ||
39467
                       pkey->pkey_sz <= 0)) {
39468
        WOLFSSL_MSG("Bad function arg, pkey is NULL or incomplete");
39469
        err = 1;
39470
    }
39471
39472
    if ((err == 0) && (in == NULL) && !(flags & PKCS7_STREAM)) {
39473
        WOLFSSL_MSG("input data required unless PKCS7_STREAM used");
39474
        err = 1;
39475
    }
39476
39477
    if ((err == 0) && ((p7 = (WOLFSSL_PKCS7*)wolfSSL_PKCS7_new()) == NULL)) {
39478
        WOLFSSL_MSG("Error allocating new WOLFSSL_PKCS7");
39479
        err = 1;
39480
    }
39481
39482
    /* load signer certificate */
39483
    if (err == 0) {
39484
        if (wc_PKCS7_InitWithCert(&p7->pkcs7, signer->derCert->buffer,
39485
                                  signer->derCert->length) != 0) {
39486
            WOLFSSL_MSG("Failed to load signer certificate");
39487
            err = 1;
39488
        }
39489
    }
39490
39491
    /* set signer private key, data types, defaults */
39492
    if (err == 0) {
39493
        p7->pkcs7.privateKey = (byte*)pkey->pkey.ptr;
39494
        p7->pkcs7.privateKeySz = pkey->pkey_sz;
39495
        p7->pkcs7.contentOID = DATA;  /* inner content default is DATA */
39496
        p7->pkcs7.hashOID = SHA256h;  /* default to SHA-256 hash type */
39497
        p7->type = SIGNED_DATA;       /* PKCS7_final switches on type */
39498
    }
39499
39500
    /* add additional chain certs if provided */
39501
    while (cert && (err == 0)) {
39502
        if (cert->data.x509 != NULL && cert->data.x509->derCert != NULL) {
39503
            if (wc_PKCS7_AddCertificate(&p7->pkcs7,
39504
                                cert->data.x509->derCert->buffer,
39505
                                cert->data.x509->derCert->length) != 0) {
39506
                WOLFSSL_MSG("Error in wc_PKCS7_AddCertificate");
39507
                err = 1;
39508
            }
39509
        }
39510
        cert = cert->next;
39511
    }
39512
39513
    if ((err == 0) && (flags & PKCS7_DETACHED)) {
39514
        if (wc_PKCS7_SetDetached(&p7->pkcs7, 1) != 0) {
39515
            WOLFSSL_MSG("Failed to set signature detached");
39516
            err = 1;
39517
        }
39518
    }
39519
39520
    if ((err == 0) && (flags & PKCS7_STREAM)) {
39521
        /* if streaming, return before finalizing */
39522
        return (PKCS7*)p7;
39523
    }
39524
39525
    if ((err == 0) && (wolfSSL_PKCS7_final((PKCS7*)p7, in, flags) != 1)) {
39526
        WOLFSSL_MSG("Error calling wolfSSL_PKCS7_final");
39527
        err = 1;
39528
    }
39529
39530
    if ((err != 0) && (p7 != NULL)) {
39531
        wolfSSL_PKCS7_free((PKCS7*)p7);
39532
        p7 = NULL;
39533
    }
39534
39535
    return (PKCS7*)p7;
39536
}
39537
39538
#ifdef HAVE_SMIME
39539
39540
#ifndef MAX_MIME_LINE_LEN
39541
    #define MAX_MIME_LINE_LEN 1024
39542
#endif
39543
39544
/**
39545
 * Copy input BIO to output BIO, but convert all line endings to CRLF (\r\n),
39546
 * used by PKCS7_final().
39547
 *
39548
 * in  - input WOLFSSL_BIO to be converted
39549
 * out - output WOLFSSL_BIO to hold copy of in, with line endings adjusted
39550
 *
39551
 * Return 0 on success, negative on error
39552
 */
39553
static int wolfSSL_BIO_to_MIME_crlf(WOLFSSL_BIO* in, WOLFSSL_BIO* out)
39554
{
39555
    int ret = 0;
39556
    int lineLen = 0;
39557
    word32 canonLineLen = 0;
39558
    char* canonLine = NULL;
39559
#ifdef WOLFSSL_SMALL_STACK
39560
    char* line = NULL;
39561
#else
39562
    char line[MAX_MIME_LINE_LEN];
39563
#endif
39564
39565
    if (in == NULL || out == NULL) {
39566
        return BAD_FUNC_ARG;
39567
    }
39568
39569
#ifdef WOLFSSL_SMALL_STACK
39570
    line = (char*)XMALLOC(MAX_MIME_LINE_LEN, in->heap,
39571
                          DYNAMIC_TYPE_TMP_BUFFER);
39572
    if (line == NULL) {
39573
        return MEMORY_E;
39574
    }
39575
#endif
39576
    XMEMSET(line, 0, MAX_MIME_LINE_LEN);
39577
39578
    while ((lineLen = wolfSSL_BIO_gets(in, line, (int)sizeof(line))) > 0) {
39579
39580
        if (line[lineLen - 1] == '\r' || line[lineLen - 1] == '\n') {
39581
            canonLineLen = (word32)lineLen;
39582
            if ((canonLine = wc_MIME_single_canonicalize(
39583
                                line, &canonLineLen)) == NULL) {
39584
                ret = -1;
39585
                break;
39586
            }
39587
39588
            /* remove trailing null */
39589
            if (canonLine[canonLineLen] == '\0') {
39590
                canonLineLen--;
39591
            }
39592
39593
            if (wolfSSL_BIO_write(out, canonLine, (int)canonLineLen) < 0) {
39594
                ret = -1;
39595
                break;
39596
            }
39597
            XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
39598
            canonLine = NULL;
39599
        }
39600
        else {
39601
            /* no line ending in current line, write direct to out */
39602
            if (wolfSSL_BIO_write(out, line, lineLen) < 0) {
39603
                ret = -1;
39604
                break;
39605
            }
39606
        }
39607
    }
39608
39609
    if (canonLine != NULL) {
39610
        XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
39611
    }
39612
#ifdef WOLFSSL_SMALL_STACK
39613
    XFREE(line, in->heap, DYNAMIC_TYPE_TMP_BUFFER);
39614
#endif
39615
39616
    return ret;
39617
}
39618
39619
#endif /* HAVE_SMIME */
39620
39621
/* Used by both PKCS7_final() and PKCS7_verify() */
39622
static const char contTypeText[] = "Content-Type: text/plain\r\n\r\n";
39623
39624
/**
39625
 * Finalize PKCS7 structure, currently supports signedData only.
39626
 *
39627
 * Does not generate final bundle (ie: signedData), but finalizes
39628
 * the PKCS7 structure in preparation for a output function to be called next.
39629
 *
39630
 * pkcs7 - initialized PKCS7 structure, populated with signer, etc
39631
 * in    - input data
39632
 * flags - flags to control PKCS7 behavior. Other flags except those noted
39633
 *         below are ignored:
39634
 *
39635
 *    PKCS7_BINARY - Do not translate input data to MIME canonical
39636
 *                   format (\r\n line endings), thus preventing corruption of
39637
 *                   binary content.
39638
 *    PKCS7_TEXT   - Prepend MIME headers for text/plain to content.
39639
 *
39640
 * Returns 1 on success, 0 on error
39641
 */
39642
int wolfSSL_PKCS7_final(PKCS7* pkcs7, WOLFSSL_BIO* in, int flags)
39643
{
39644
    int ret = 1;
39645
    int memSz = 0;
39646
    unsigned char* mem = NULL;
39647
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39648
    WOLFSSL_BIO* data = NULL;
39649
39650
    WOLFSSL_ENTER("wolfSSL_PKCS7_final");
39651
39652
    if (p7 == NULL || in == NULL) {
39653
        WOLFSSL_MSG("Bad input args to PKCS7_final");
39654
        ret = 0;
39655
    }
39656
39657
    if (ret == 1) {
39658
        if ((data = wolfSSL_BIO_new(wolfSSL_BIO_s_mem())) == NULL) {
39659
            WOLFSSL_MSG("Error in wolfSSL_BIO_new");
39660
            ret = 0;
39661
        }
39662
    }
39663
39664
    /* prepend Content-Type header if PKCS7_TEXT */
39665
    if ((ret == 1) && (flags & PKCS7_TEXT)) {
39666
        if (wolfSSL_BIO_write(data, contTypeText,
39667
                              (int)XSTR_SIZEOF(contTypeText)) < 0) {
39668
            WOLFSSL_MSG("Error prepending Content-Type header");
39669
            ret = 0;
39670
        }
39671
    }
39672
39673
    /* convert line endings to CRLF if !PKCS7_BINARY */
39674
    if (ret == 1) {
39675
        if (flags & PKCS7_BINARY) {
39676
39677
            /* no CRLF conversion, direct copy content */
39678
            if ((memSz = wolfSSL_BIO_get_len(in)) <= 0) {
39679
                ret = 0;
39680
            }
39681
            if (ret == 1) {
39682
                mem = (unsigned char*)XMALLOC(memSz, in->heap,
39683
                                              DYNAMIC_TYPE_TMP_BUFFER);
39684
                if (mem == NULL) {
39685
                    WOLFSSL_MSG("Failed to allocate memory for input data");
39686
                    ret = 0;
39687
                }
39688
            }
39689
39690
            if (ret == 1) {
39691
                if (wolfSSL_BIO_read(in, mem, memSz) != memSz) {
39692
                    WOLFSSL_MSG("Error reading from input BIO");
39693
                    ret = 0;
39694
                }
39695
                else if (wolfSSL_BIO_write(data, mem, memSz) < 0) {
39696
                    ret = 0;
39697
                }
39698
            }
39699
39700
            if (mem != NULL) {
39701
                XFREE(mem, in->heap, DYNAMIC_TYPE_TMP_BUFFER);
39702
            }
39703
        }
39704
        else {
39705
    #ifdef HAVE_SMIME
39706
            /* convert content line endings to CRLF */
39707
            if (wolfSSL_BIO_to_MIME_crlf(in, data) != 0) {
39708
                WOLFSSL_MSG("Error converting line endings to CRLF");
39709
                ret = 0;
39710
            }
39711
            else {
39712
                p7->pkcs7.contentCRLF = 1;
39713
            }
39714
    #else
39715
            WOLFSSL_MSG("Without PKCS7_BINARY requires wolfSSL to be built "
39716
                        "with HAVE_SMIME");
39717
            ret = 0;
39718
    #endif
39719
        }
39720
    }
39721
39722
    if ((ret == 1) && ((memSz = wolfSSL_BIO_get_mem_data(data, &mem)) < 0)) {
39723
        WOLFSSL_MSG("Error in wolfSSL_BIO_get_mem_data");
39724
        ret = 0;
39725
    }
39726
39727
    if (ret == 1) {
39728
        if (p7->data != NULL) {
39729
            XFREE(p7->data, NULL, DYNAMIC_TYPE_PKCS7);
39730
        }
39731
        p7->data = (byte*)XMALLOC(memSz, NULL, DYNAMIC_TYPE_PKCS7);
39732
        if (p7->data == NULL) {
39733
            ret = 0;
39734
        }
39735
        else {
39736
            XMEMCPY(p7->data, mem, memSz);
39737
            p7->len = memSz;
39738
        }
39739
    }
39740
39741
    if (ret == 1) {
39742
        p7->pkcs7.content = p7->data;
39743
        p7->pkcs7.contentSz = p7->len;
39744
    }
39745
39746
    if (data != NULL) {
39747
        wolfSSL_BIO_free(data);
39748
    }
39749
39750
    return ret;
39751
}
39752
39753
int wolfSSL_PKCS7_verify(PKCS7* pkcs7, WOLFSSL_STACK* certs,
39754
        WOLFSSL_X509_STORE* store, WOLFSSL_BIO* in, WOLFSSL_BIO* out, int flags)
39755
{
39756
    int i, ret = 0;
39757
    unsigned char* mem = NULL;
39758
    int memSz = 0;
39759
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
39760
    int contTypeLen;
39761
    WOLFSSL_X509* signer = NULL;
39762
    WOLFSSL_STACK* signers = NULL;
39763
39764
    WOLFSSL_ENTER("wolfSSL_PKCS7_verify");
39765
39766
    if (pkcs7 == NULL)
39767
        return WOLFSSL_FAILURE;
39768
39769
    if (in != NULL) {
39770
        if ((memSz = wolfSSL_BIO_get_mem_data(in, &mem)) < 0)
39771
            return WOLFSSL_FAILURE;
39772
39773
        p7->pkcs7.content = mem;
39774
        p7->pkcs7.contentSz = memSz;
39775
    }
39776
39777
    /* certs is the list of certificates to find the cert with issuer/serial. */
39778
    (void)certs;
39779
    /* store is the certificate store to use to verify signer certificate
39780
     * associated with the signers.
39781
     */
39782
    (void)store;
39783
39784
    ret = wc_PKCS7_VerifySignedData(&p7->pkcs7, p7->data, p7->len);
39785
    if (ret != 0)
39786
        return WOLFSSL_FAILURE;
39787
39788
    if ((flags & PKCS7_NOVERIFY) != PKCS7_NOVERIFY) {
39789
        /* Verify signer certificates */
39790
        if (store == NULL || store->cm == NULL) {
39791
            WOLFSSL_MSG("No store or store certs, but PKCS7_NOVERIFY not set");
39792
            return WOLFSSL_FAILURE;
39793
        }
39794
39795
        signers = wolfSSL_PKCS7_get0_signers(pkcs7, certs, flags);
39796
        if (signers == NULL) {
39797
            WOLFSSL_MSG("No signers found to verify");
39798
            return WOLFSSL_FAILURE;
39799
        }
39800
        for (i = 0; i < wolfSSL_sk_X509_num(signers); i++) {
39801
            signer = wolfSSL_sk_X509_value(signers, i);
39802
39803
            if (wolfSSL_CertManagerVerifyBuffer(store->cm,
39804
                        signer->derCert->buffer,
39805
                        signer->derCert->length,
39806
                        WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
39807
                WOLFSSL_MSG("Failed to verify signer certificate");
39808
                wolfSSL_sk_X509_pop_free(signers, NULL);
39809
                return WOLFSSL_FAILURE;
39810
            }
39811
        }
39812
        wolfSSL_sk_X509_pop_free(signers, NULL);
39813
    }
39814
39815
    if (flags & PKCS7_TEXT) {
39816
        /* strip MIME header for text/plain, otherwise error */
39817
        contTypeLen = XSTR_SIZEOF(contTypeText);
39818
        if ((p7->pkcs7.contentSz < (word32)contTypeLen) ||
39819
            (XMEMCMP(p7->pkcs7.content, contTypeText, contTypeLen) != 0)) {
39820
            WOLFSSL_MSG("Error PKCS7 Content-Type not found with PKCS7_TEXT");
39821
            return WOLFSSL_FAILURE;
39822
        }
39823
        p7->pkcs7.content += contTypeLen;
39824
        p7->pkcs7.contentSz -= contTypeLen;
39825
    }
39826
39827
    if (out != NULL) {
39828
        wolfSSL_BIO_write(out, p7->pkcs7.content, p7->pkcs7.contentSz);
39829
    }
39830
39831
    WOLFSSL_LEAVE("wolfSSL_PKCS7_verify", WOLFSSL_SUCCESS);
39832
39833
    return WOLFSSL_SUCCESS;
39834
}
39835
39836
/**
39837
 * This API was added as a helper function for libest. It
39838
 * encodes a stack of certificates to pkcs7 format.
39839
 * @param pkcs7 PKCS7 parameter object
39840
 * @param certs WOLFSSL_STACK_OF(WOLFSSL_X509)*
39841
 * @param out   Output bio
39842
 * @return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure
39843
 */
39844
int wolfSSL_PKCS7_encode_certs(PKCS7* pkcs7, WOLFSSL_STACK* certs,
39845
        WOLFSSL_BIO* out)
39846
{
39847
    int ret;
39848
    WOLFSSL_PKCS7* p7;
39849
    WOLFSSL_ENTER("wolfSSL_PKCS7_encode_certs");
39850
39851
    if (!pkcs7 || !certs || !out) {
39852
        WOLFSSL_MSG("Bad parameter");
39853
        return WOLFSSL_FAILURE;
39854
    }
39855
39856
    p7 = (WOLFSSL_PKCS7*)pkcs7;
39857
39858
    /* take ownership of certs */
39859
    p7->certs = certs;
39860
39861
    if (pkcs7->certList) {
39862
        WOLFSSL_MSG("wolfSSL_PKCS7_encode_certs called multiple times on same "
39863
                    "struct");
39864
        return WOLFSSL_FAILURE;
39865
    }
39866
39867
    if (certs) {
39868
        /* Save some of the values */
39869
        int hashOID = pkcs7->hashOID;
39870
        byte version = pkcs7->version;
39871
39872
        if (!certs->data.x509 || !certs->data.x509->derCert) {
39873
            WOLFSSL_MSG("Missing cert");
39874
            return WOLFSSL_FAILURE;
39875
        }
39876
39877
        if (wc_PKCS7_InitWithCert(pkcs7, certs->data.x509->derCert->buffer,
39878
                                      certs->data.x509->derCert->length) != 0) {
39879
            WOLFSSL_MSG("wc_PKCS7_InitWithCert error");
39880
            return WOLFSSL_FAILURE;
39881
        }
39882
        certs = certs->next;
39883
39884
        pkcs7->hashOID = hashOID;
39885
        pkcs7->version = version;
39886
    }
39887
39888
    /* Add the certs to the PKCS7 struct */
39889
    while (certs) {
39890
        if (!certs->data.x509 || !certs->data.x509->derCert) {
39891
            WOLFSSL_MSG("Missing cert");
39892
            return WOLFSSL_FAILURE;
39893
        }
39894
        if (wc_PKCS7_AddCertificate(pkcs7, certs->data.x509->derCert->buffer,
39895
                                      certs->data.x509->derCert->length) != 0) {
39896
            WOLFSSL_MSG("wc_PKCS7_AddCertificate error");
39897
            return WOLFSSL_FAILURE;
39898
        }
39899
        certs = certs->next;
39900
    }
39901
39902
    if (wc_PKCS7_SetSignerIdentifierType(pkcs7, DEGENERATE_SID) != 0) {
39903
        WOLFSSL_MSG("wc_PKCS7_SetSignerIdentifierType error");
39904
        return WOLFSSL_FAILURE;
39905
    }
39906
39907
    ret = wolfSSL_i2d_PKCS7_bio(out, pkcs7);
39908
39909
    return ret;
39910
}
39911
39912
/******************************************************************************
39913
* wolfSSL_PEM_write_bio_PKCS7 - writes the PKCS7 data to BIO
39914
*
39915
* RETURNS:
39916
* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
39917
*/
39918
int wolfSSL_PEM_write_bio_PKCS7(WOLFSSL_BIO* bio, PKCS7* p7)
39919
{
39920
#ifdef WOLFSSL_SMALL_STACK
39921
    byte* outputHead;
39922
    byte* outputFoot;
39923
#else
39924
    byte outputHead[2048];
39925
    byte outputFoot[2048];
39926
#endif
39927
    word32 outputHeadSz = 2048;
39928
    word32 outputFootSz = 2048;
39929
    word32 outputSz = 0;
39930
    byte*  output = NULL;
39931
    byte*  pem = NULL;
39932
    int    pemSz = -1;
39933
    enum wc_HashType hashType;
39934
    byte hashBuf[WC_MAX_DIGEST_SIZE];
39935
    word32 hashSz = -1;
39936
39937
    WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PKCS7()");
39938
39939
    if (bio == NULL || p7 == NULL)
39940
        return WOLFSSL_FAILURE;
39941
39942
#ifdef WOLFSSL_SMALL_STACK
39943
    outputHead = (byte*)XMALLOC(outputHeadSz, bio->heap,
39944
        DYNAMIC_TYPE_TMP_BUFFER);
39945
    if (outputHead == NULL)
39946
        return MEMORY_E;
39947
39948
    outputFoot = (byte*)XMALLOC(outputFootSz, bio->heap,
39949
        DYNAMIC_TYPE_TMP_BUFFER);
39950
    if (outputFoot == NULL)
39951
        goto error;
39952
39953
#endif
39954
39955
    XMEMSET(hashBuf, 0, WC_MAX_DIGEST_SIZE);
39956
    XMEMSET(outputHead, 0, outputHeadSz);
39957
    XMEMSET(outputFoot, 0, outputFootSz);
39958
39959
    hashType = wc_OidGetHash(p7->hashOID);
39960
    hashSz = wc_HashGetDigestSize(hashType);
39961
    if (hashSz > WC_MAX_DIGEST_SIZE)
39962
        return WOLFSSL_FAILURE;
39963
39964
    /* only SIGNED_DATA is supported */
39965
    switch (p7->contentOID) {
39966
        case SIGNED_DATA:
39967
            break;
39968
        default:
39969
            WOLFSSL_MSG("Unknown PKCS#7 Type");
39970
            return WOLFSSL_FAILURE;
39971
    };
39972
39973
    if ((wc_PKCS7_EncodeSignedData_ex(p7, hashBuf, hashSz,
39974
        outputHead, &outputHeadSz, outputFoot, &outputFootSz)) != 0)
39975
        return WOLFSSL_FAILURE;
39976
39977
    outputSz = outputHeadSz + p7->contentSz + outputFootSz;
39978
    output = (byte*)XMALLOC(outputSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
39979
39980
    if (!output)
39981
         return WOLFSSL_FAILURE;
39982
39983
    XMEMSET(output, 0, outputSz);
39984
    outputSz = 0;
39985
    XMEMCPY(&output[outputSz], outputHead, outputHeadSz);
39986
    outputSz += outputHeadSz;
39987
    XMEMCPY(&output[outputSz], p7->content, p7->contentSz);
39988
    outputSz += p7->contentSz;
39989
    XMEMCPY(&output[outputSz], outputFoot, outputFootSz);
39990
    outputSz += outputFootSz;
39991
39992
    /* get PEM size */
39993
    pemSz = wc_DerToPemEx(output, outputSz, NULL, 0, NULL, CERT_TYPE);
39994
    if (pemSz < 0)
39995
        goto error;
39996
39997
    pemSz++; /* for '\0'*/
39998
39999
    /* create PEM buffer and convert from DER to PEM*/
40000
    if ((pem = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER))
40001
                                                                        == NULL)
40002
        goto error;
40003
40004
    XMEMSET(pem, 0, pemSz);
40005
40006
    if (wc_DerToPemEx(output, outputSz, pem, pemSz, NULL, CERT_TYPE) < 0) {
40007
        goto error;
40008
    }
40009
    if ((wolfSSL_BIO_write(bio, pem, pemSz) == pemSz)) {
40010
        XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40011
        XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40012
#ifdef WOLFSSL_SMALL_STACK
40013
        XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40014
        XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40015
#endif
40016
        return WOLFSSL_SUCCESS;
40017
    }
40018
40019
error:
40020
#ifdef WOLFSSL_SMALL_STACK
40021
    if (outputHead) {
40022
        XFREE(outputHead, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40023
    }
40024
    if (outputFoot) {
40025
        XFREE(outputFoot, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40026
    }
40027
#endif
40028
    if (output) {
40029
        XFREE(output, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40030
    }
40031
    if (pem) {
40032
        XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40033
    }
40034
    return WOLFSSL_FAILURE;
40035
}
40036
40037
#ifdef HAVE_SMIME
40038
/*****************************************************************************
40039
* wolfSSL_SMIME_read_PKCS7 - Reads the given S/MIME message and parses it into
40040
* a PKCS7 object. In case of a multipart message, stores the signed data in
40041
* bcont.
40042
*
40043
* RETURNS:
40044
* returns pointer to a PKCS7 structure on success, otherwise returns NULL
40045
*/
40046
WOLFSSL_API PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
40047
        WOLFSSL_BIO** bcont)
40048
{
40049
    MimeHdr* allHdrs = NULL;
40050
    MimeHdr* curHdr = NULL;
40051
    MimeParam* curParam = NULL;
40052
    int inLen = 0;
40053
    byte* bcontMem = NULL;
40054
    int bcontMemSz = 0;
40055
    int sectionLen = 0;
40056
    int ret = -1;
40057
    char* section = NULL;
40058
    char* canonLine = NULL;
40059
    char* canonSection = NULL;
40060
    PKCS7* pkcs7 = NULL;
40061
    word32 outLen = 0;
40062
    word32 canonLineLen = 0;
40063
    byte* out = NULL;
40064
    byte* outHead = NULL;
40065
40066
    int canonPos = 0;
40067
    int lineLen = 0;
40068
    int remainLen = 0;
40069
    byte isEnd = 0;
40070
    size_t canonSize = 0;
40071
    size_t boundLen = 0;
40072
    char* boundary = NULL;
40073
40074
    static const char kContType[] = "Content-Type";
40075
    static const char kCTE[] = "Content-Transfer-Encoding";
40076
    static const char kMultSigned[] = "multipart/signed";
40077
    static const char kAppPkcsSign[] = "application/pkcs7-signature";
40078
    static const char kAppXPkcsSign[] = "application/x-pkcs7-signature";
40079
    static const char kAppPkcs7Mime[] = "application/pkcs7-mime";
40080
    static const char kAppXPkcs7Mime[] = "application/x-pkcs7-mime";
40081
40082
    WOLFSSL_ENTER("wolfSSL_SMIME_read_PKCS7");
40083
40084
    if (in == NULL || bcont == NULL) {
40085
        goto error;
40086
    }
40087
    inLen = wolfSSL_BIO_get_len(in);
40088
    if (inLen <= 0) {
40089
        goto error;
40090
    }
40091
    remainLen = wolfSSL_BIO_get_len(in);
40092
    if (remainLen <= 0) {
40093
        goto error;
40094
    }
40095
40096
    section = (char*)XMALLOC(remainLen+1, NULL, DYNAMIC_TYPE_PKCS7);
40097
    if (section == NULL) {
40098
        goto error;
40099
    }
40100
    lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40101
    if (lineLen <= 0) {
40102
        goto error;
40103
    }
40104
    while (isEnd == 0 && remainLen > 0) {
40105
        sectionLen += lineLen;
40106
        remainLen -= lineLen;
40107
        lineLen = wolfSSL_BIO_gets(in, &section[sectionLen], remainLen);
40108
        if (lineLen <= 0) {
40109
            goto error;
40110
        }
40111
        /* Line with just newline signals end of headers. */
40112
        if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
40113
                                     "\r\n", 2)) ||
40114
            (lineLen==1 && (section[sectionLen] == '\r' ||
40115
                            section[sectionLen] == '\n'))) {
40116
            isEnd = 1;
40117
        }
40118
    }
40119
    section[sectionLen] = '\0';
40120
    ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
40121
    if (ret < 0) {
40122
        WOLFSSL_MSG("Parsing MIME headers failed.");
40123
        goto error;
40124
    }
40125
    isEnd = 0;
40126
    section[0] = '\0';
40127
    sectionLen = 0;
40128
40129
    curHdr = wc_MIME_find_header_name(kContType, allHdrs);
40130
    if (curHdr && !XSTRNCMP(curHdr->body, kMultSigned,
40131
                            XSTR_SIZEOF(kMultSigned))) {
40132
        curParam = wc_MIME_find_param_attr("protocol", curHdr->params);
40133
        if (curParam && (!XSTRNCMP(curParam->value, kAppPkcsSign,
40134
                                   XSTR_SIZEOF(kAppPkcsSign)) ||
40135
                         !XSTRNCMP(curParam->value, kAppXPkcsSign,
40136
                                   XSTR_SIZEOF(kAppXPkcsSign)))) {
40137
            curParam = wc_MIME_find_param_attr("boundary", curHdr->params);
40138
            if (curParam == NULL) {
40139
                goto error;
40140
            }
40141
40142
            boundLen = XSTRLEN(curParam->value) + 2;
40143
            boundary = (char*)XMALLOC(boundLen+1, NULL, DYNAMIC_TYPE_PKCS7);
40144
            if (boundary == NULL) {
40145
                goto error;
40146
            }
40147
            XMEMSET(boundary, 0, (word32)(boundLen+1));
40148
            boundary[0] = boundary[1] = '-';
40149
            XSTRNCPY(&boundary[2], curParam->value, boundLen-2);
40150
40151
            /* Parse up to first boundary, ignore everything here. */
40152
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40153
            if (lineLen <= 0) {
40154
                goto error;
40155
            }
40156
            while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
40157
                   remainLen > 0) {
40158
                sectionLen += lineLen;
40159
                remainLen -= lineLen;
40160
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40161
                                           remainLen);
40162
                if (lineLen <= 0) {
40163
                    goto error;
40164
                }
40165
            }
40166
40167
            section[0] = '\0';
40168
            sectionLen = 0;
40169
            canonSize = remainLen + 1;
40170
            canonSection = (char*)XMALLOC(canonSize, NULL,
40171
                                          DYNAMIC_TYPE_PKCS7);
40172
            if (canonSection == NULL) {
40173
                goto error;
40174
            }
40175
40176
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40177
            while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
40178
                            remainLen > 0) {
40179
                canonLineLen = lineLen;
40180
                canonLine = wc_MIME_single_canonicalize(&section[sectionLen],
40181
                                                        &canonLineLen);
40182
                if (canonLine == NULL) {
40183
                    goto error;
40184
                }
40185
                /* If line endings were added, the initial length may be
40186
                 * exceeded. */
40187
                if ((canonPos + canonLineLen) >= canonSize) {
40188
                    canonSize = canonPos + canonLineLen;
40189
                    canonSection = (char*)XREALLOC(canonSection, canonSize,
40190
                                                   NULL, DYNAMIC_TYPE_PKCS7);
40191
                    if (canonSection == NULL) {
40192
                        goto error;
40193
                    }
40194
                }
40195
                XMEMCPY(&canonSection[canonPos], canonLine,
40196
                        (int)canonLineLen - 1);
40197
                canonPos += canonLineLen - 1;
40198
                XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
40199
                canonLine = NULL;
40200
40201
                sectionLen += lineLen;
40202
                remainLen -= lineLen;
40203
40204
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40205
                                           remainLen);
40206
                if (lineLen <= 0) {
40207
                    goto error;
40208
                }
40209
            }
40210
40211
            if (canonPos > 0) {
40212
                canonPos--;
40213
            }
40214
40215
            /* Strip the final trailing newline.  Support \r, \n or \r\n. */
40216
            if (canonSection[canonPos] == '\n') {
40217
                if (canonPos > 0) {
40218
                    canonPos--;
40219
                }
40220
            }
40221
40222
            if (canonSection[canonPos] == '\r') {
40223
                if (canonPos > 0) {
40224
                    canonPos--;
40225
                }
40226
            }
40227
40228
            canonSection[canonPos+1] = '\0';
40229
40230
            *bcont = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
40231
            ret = wolfSSL_BIO_write(*bcont, canonSection,
40232
                                    canonPos + 1);
40233
            if (ret != (canonPos+1)) {
40234
                goto error;
40235
            }
40236
            if ((bcontMemSz = wolfSSL_BIO_get_mem_data(*bcont, &bcontMem))
40237
                                                                          < 0) {
40238
                goto error;
40239
            }
40240
            XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
40241
            canonSection = NULL;
40242
40243
            wc_MIME_free_hdrs(allHdrs);
40244
            allHdrs = NULL;
40245
            section[0] = '\0';
40246
            sectionLen = 0;
40247
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40248
            if (lineLen <= 0) {
40249
                goto error;
40250
            }
40251
            while (isEnd == 0 && remainLen > 0) {
40252
                sectionLen += lineLen;
40253
                remainLen -= lineLen;
40254
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40255
                                           remainLen);
40256
                if (lineLen <= 0) {
40257
                    goto error;
40258
                }
40259
                /* Line with just newline signals end of headers. */
40260
                if ((lineLen==2 && !XSTRNCMP(&section[sectionLen],
40261
                                             "\r\n", 2)) ||
40262
                    (lineLen==1 && (section[sectionLen] == '\r' ||
40263
                                    section[sectionLen] == '\n'))) {
40264
                    isEnd = 1;
40265
                }
40266
            }
40267
            section[sectionLen] = '\0';
40268
            ret = wc_MIME_parse_headers(section, sectionLen, &allHdrs);
40269
            if (ret < 0) {
40270
                WOLFSSL_MSG("Parsing MIME headers failed.");
40271
                goto error;
40272
            }
40273
            curHdr = wc_MIME_find_header_name(kContType, allHdrs);
40274
            if (curHdr == NULL || (XSTRNCMP(curHdr->body, kAppPkcsSign,
40275
                                   XSTR_SIZEOF(kAppPkcsSign)) &&
40276
                                   XSTRNCMP(curHdr->body, kAppXPkcsSign,
40277
                                   XSTR_SIZEOF(kAppXPkcsSign)))) {
40278
                WOLFSSL_MSG("S/MIME headers not found inside "
40279
                            "multipart message.\n");
40280
                goto error;
40281
            }
40282
40283
            section[0] = '\0';
40284
            sectionLen = 0;
40285
            lineLen = wolfSSL_BIO_gets(in, section, remainLen);
40286
            while (XSTRNCMP(&section[sectionLen], boundary, boundLen) &&
40287
                   remainLen > 0) {
40288
                sectionLen += lineLen;
40289
                remainLen -= lineLen;
40290
                lineLen = wolfSSL_BIO_gets(in, &section[sectionLen],
40291
                                           remainLen);
40292
                if (lineLen <= 0) {
40293
                    goto error;
40294
                }
40295
            }
40296
40297
            XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
40298
            boundary = NULL;
40299
        }
40300
    }
40301
    else if (curHdr && (!XSTRNCMP(curHdr->body, kAppPkcs7Mime,
40302
                                  XSTR_SIZEOF(kAppPkcs7Mime)) ||
40303
                        !XSTRNCMP(curHdr->body, kAppXPkcs7Mime,
40304
                                  XSTR_SIZEOF(kAppXPkcs7Mime)))) {
40305
        sectionLen = wolfSSL_BIO_get_len(in);
40306
        if (sectionLen <= 0) {
40307
            goto error;
40308
        }
40309
        ret = wolfSSL_BIO_read(in, section, sectionLen);
40310
        if (ret < 0 || ret != sectionLen) {
40311
            WOLFSSL_MSG("Error reading input BIO.");
40312
            goto error;
40313
        }
40314
    }
40315
    else {
40316
        WOLFSSL_MSG("S/MIME headers not found.");
40317
        goto error;
40318
    }
40319
40320
    curHdr = wc_MIME_find_header_name(kCTE, allHdrs);
40321
    if (curHdr == NULL) {
40322
        WOLFSSL_MSG("Content-Transfer-Encoding header not found, "
40323
                    "assuming base64 encoding.");
40324
    }
40325
    else if (XSTRNCMP(curHdr->body, "base64", XSTRLEN("base64"))) {
40326
        WOLFSSL_MSG("S/MIME encodings other than base64 are not "
40327
                    "currently supported.\n");
40328
        goto error;
40329
    }
40330
40331
    if (section == NULL || sectionLen <= 0) {
40332
        goto error;
40333
    }
40334
    outLen = ((sectionLen*3+3)/4)+1;
40335
    out = (byte*)XMALLOC(outLen*sizeof(byte), NULL, DYNAMIC_TYPE_PKCS7);
40336
    outHead = out;
40337
    if (outHead == NULL) {
40338
        goto error;
40339
    }
40340
    /* Strip trailing newlines. */
40341
    while ((sectionLen > 0) &&
40342
           (section[sectionLen-1] == '\r' || section[sectionLen-1] == '\n')) {
40343
        sectionLen--;
40344
    }
40345
    section[sectionLen] = '\0';
40346
    ret = Base64_Decode((const byte*)section, sectionLen, out, &outLen);
40347
    if (ret < 0) {
40348
        WOLFSSL_MSG("Error base64 decoding S/MIME message.");
40349
        goto error;
40350
    }
40351
    pkcs7 = wolfSSL_d2i_PKCS7_ex(NULL, (const unsigned char**)&out, outLen,
40352
        bcontMem, bcontMemSz);
40353
40354
    wc_MIME_free_hdrs(allHdrs);
40355
    XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
40356
    XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
40357
40358
    return pkcs7;
40359
40360
error:
40361
    wc_MIME_free_hdrs(allHdrs);
40362
    XFREE(boundary, NULL, DYNAMIC_TYPE_PKCS7);
40363
    XFREE(outHead, NULL, DYNAMIC_TYPE_PKCS7);
40364
    XFREE(section, NULL, DYNAMIC_TYPE_PKCS7);
40365
    if (canonSection != NULL)
40366
        XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
40367
    if (bcont) {
40368
        wolfSSL_BIO_free(*bcont);
40369
        *bcont = NULL; /* reset 'bcount' pointer to NULL on failure */
40370
    }
40371
40372
    return NULL;
40373
}
40374
40375
/* Convert hash algo OID (from Hash_Sum in asn.h) to SMIME string equivalent.
40376
 * Returns hash algorithm string or "unknown" if not found */
40377
static const char* wolfSSL_SMIME_HashOIDToString(int hashOID)
40378
{
40379
    switch (hashOID) {
40380
        case MD5h:
40381
            return "md5";
40382
        case SHAh:
40383
            return "sha1";
40384
        case SHA224h:
40385
            return "sha-224";
40386
        case SHA256h:
40387
            return "sha-256";
40388
        case SHA384h:
40389
            return "sha-384";
40390
        case SHA512h:
40391
            return "sha-512";
40392
        case SHA3_224h:
40393
            return "sha3-224";
40394
        case SHA3_384h:
40395
            return "sha3-384";
40396
        case SHA3_512h:
40397
            return "sha3-512";
40398
        default:
40399
            break;
40400
    }
40401
40402
    return "unknown";
40403
}
40404
40405
/* Convert PKCS#7 type (from PKCS7_TYPES in pkcs7.h) to SMIME string.
40406
 * RFC2633 only defines signed-data, enveloped-data, certs-only.
40407
 * Returns string on success, NULL on unknown type. */
40408
static const char* wolfSSL_SMIME_PKCS7TypeToString(int type)
40409
{
40410
    switch (type) {
40411
        case SIGNED_DATA:
40412
            return "signed-data";
40413
        case ENVELOPED_DATA:
40414
            return "enveloped-data";
40415
        default:
40416
            break;
40417
    }
40418
40419
    return NULL;
40420
}
40421
40422
/**
40423
 * Convert PKCS7 structure to SMIME format, adding necessary headers.
40424
 *
40425
 * Handles generation of PKCS7 bundle (ie: signedData). PKCS7 structure
40426
 * should be set up beforehand with PKCS7_sign/final/etc. Output is always
40427
 * Base64 encoded.
40428
 *
40429
 * out   - output BIO for SMIME formatted data to be placed
40430
 * pkcs7 - input PKCS7 structure, initialized and set up
40431
 * in    - input content to be encoded into PKCS7
40432
 * flags - flags to control behavior of PKCS7 generation
40433
 *
40434
 * Returns 1 on success, 0 or negative on failure
40435
 */
40436
int wolfSSL_SMIME_write_PKCS7(WOLFSSL_BIO* out, PKCS7* pkcs7, WOLFSSL_BIO* in,
40437
                              int flags)
40438
{
40439
    int i;
40440
    int ret = 1;
40441
    WOLFSSL_PKCS7* p7 = (WOLFSSL_PKCS7*)pkcs7;
40442
    byte* p7out = NULL;
40443
    int len = 0;
40444
40445
    char boundary[33]; /* 32 chars + \0 */
40446
    byte* sigBase64 = NULL;
40447
    word32 sigBase64Len = 0;
40448
    const char* p7TypeString = NULL;
40449
40450
    static const char alphanum[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
40451
40452
    if (out == NULL || p7 == NULL) {
40453
        WOLFSSL_MSG("Bad function arguments");
40454
        return 0;
40455
    }
40456
40457
    if (in != NULL && (p7->pkcs7.content == NULL || p7->pkcs7.contentSz == 0 ||
40458
                       p7->pkcs7.contentCRLF == 0)) {
40459
        /* store and adjust content line endings for CRLF if needed */
40460
        if (wolfSSL_PKCS7_final((PKCS7*)p7, in, flags) != 1) {
40461
            ret = 0;
40462
        }
40463
    }
40464
40465
    if (ret > 0) {
40466
        /* Generate signedData bundle, DER in output (dynamic) */
40467
        if ((len = wolfSSL_i2d_PKCS7((PKCS7*)p7, &p7out)) == WOLFSSL_FAILURE) {
40468
            WOLFSSL_MSG("Error in wolfSSL_i2d_PKCS7");
40469
            ret = 0;
40470
        }
40471
    }
40472
40473
    /* Base64 encode signedData bundle */
40474
    if (ret > 0) {
40475
        if (Base64_Encode(p7out, len, NULL, &sigBase64Len) != LENGTH_ONLY_E) {
40476
            ret = 0;
40477
        }
40478
        else {
40479
            sigBase64 = (byte*)XMALLOC(sigBase64Len, NULL,
40480
                                       DYNAMIC_TYPE_TMP_BUFFER);
40481
            if (sigBase64 == NULL) {
40482
                ret = 0;
40483
            }
40484
        }
40485
    }
40486
40487
    if (ret > 0) {
40488
        XMEMSET(sigBase64, 0, sigBase64Len);
40489
        if (Base64_Encode(p7out, len, sigBase64, &sigBase64Len) < 0) {
40490
            WOLFSSL_MSG("Error in Base64_Encode of signature");
40491
            ret = 0;
40492
        }
40493
    }
40494
40495
    /* build up SMIME message */
40496
    if (ret > 0) {
40497
        if (flags & PKCS7_DETACHED) {
40498
40499
            /* generate random boundary */
40500
            if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
40501
                WOLFSSL_MSG("No RNG to use");
40502
                ret = 0;
40503
            }
40504
40505
            /* no need to generate random byte for null terminator (size-1) */
40506
            if ((ret > 0) && (wc_RNG_GenerateBlock(&globalRNG, (byte*)boundary,
40507
                                  sizeof(boundary) - 1 ) != 0)) {
40508
                    WOLFSSL_MSG("Error in wc_RNG_GenerateBlock");
40509
                    ret = 0;
40510
            }
40511
40512
            if (ret > 0) {
40513
                for (i = 0; i < (int)sizeof(boundary) - 1; i++) {
40514
                    boundary[i] =
40515
                        alphanum[boundary[i] % XSTR_SIZEOF(alphanum)];
40516
                }
40517
                boundary[sizeof(boundary)-1] = 0;
40518
            }
40519
40520
            if (ret > 0) {
40521
                /* S/MIME header beginning */
40522
                ret = wolfSSL_BIO_printf(out,
40523
                        "MIME-Version: 1.0\n"
40524
                        "Content-Type: multipart/signed; "
40525
                        "protocol=\"application/x-pkcs7-signature\"; "
40526
                        "micalg=\"%s\"; "
40527
                        "boundary=\"----%s\"\n\n"
40528
                        "This is an S/MIME signed message\n\n"
40529
                        "------%s\n",
40530
                        wolfSSL_SMIME_HashOIDToString(p7->pkcs7.hashOID),
40531
                        boundary, boundary);
40532
            }
40533
40534
            if (ret > 0) {
40535
                /* S/MIME content */
40536
                ret = wolfSSL_BIO_write(out,
40537
                        p7->pkcs7.content, p7->pkcs7.contentSz);
40538
            }
40539
40540
            if (ret > 0) {
40541
                /* S/SMIME header end boundary */
40542
                ret = wolfSSL_BIO_printf(out,
40543
                        "\n------%s\n", boundary);
40544
            }
40545
40546
            if (ret > 0) {
40547
                /* Signature and header */
40548
                ret = wolfSSL_BIO_printf(out,
40549
                        "Content-Type: application/x-pkcs7-signature; "
40550
                        "name=\"smime.p7s\"\n"
40551
                        "Content-Transfer-Encoding: base64\n"
40552
                        "Content-Disposition: attachment; "
40553
                        "filename=\"smime.p7s\"\n\n"
40554
                        "%.*s\n" /* Base64 encoded signature */
40555
                        "------%s--\n\n",
40556
                        sigBase64Len, sigBase64,
40557
                        boundary);
40558
            }
40559
        }
40560
        else {
40561
            p7TypeString = wolfSSL_SMIME_PKCS7TypeToString(p7->type);
40562
            if (p7TypeString == NULL) {
40563
                WOLFSSL_MSG("Unsupported PKCS7 SMIME type");
40564
                ret = 0;
40565
            }
40566
40567
            if (ret > 0) {
40568
                /* not detached */
40569
                ret = wolfSSL_BIO_printf(out,
40570
                        "MIME-Version: 1.0\n"
40571
                        "Content-Disposition: attachment; "
40572
                        "filename=\"smime.p7m\"\n"
40573
                        "Content-Type: application/x-pkcs7-mime; "
40574
                        "smime-type=%s; name=\"smime.p7m\"\n"
40575
                        "Content-Transfer-Encoding: base64\n\n"
40576
                        "%.*s\n" /* signature */,
40577
                        p7TypeString, sigBase64Len, sigBase64);
40578
            }
40579
        }
40580
    }
40581
40582
    if (p7out != NULL) {
40583
        XFREE(p7out, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40584
    }
40585
    if (sigBase64 != NULL) {
40586
        XFREE(sigBase64, NULL, DYNAMIC_TYPE_TMP_BUFFER);
40587
    }
40588
40589
    if (ret > 0) {
40590
        return WOLFSSL_SUCCESS;
40591
    }
40592
40593
    return WOLFSSL_FAILURE;
40594
}
40595
40596
#endif /* HAVE_SMIME */
40597
#endif /* !NO_BIO */
40598
#endif /* OPENSSL_ALL */
40599
40600
#endif /* HAVE_PKCS7 */
40601
/*******************************************************************************
40602
 * END OF PKCS7 APIs
40603
 ******************************************************************************/
40604
40605
/*******************************************************************************
40606
 * START OF PKCS12 APIs
40607
 ******************************************************************************/
40608
#ifdef OPENSSL_EXTRA
40609
40610
/* no-op function. Was initially used for adding encryption algorithms available
40611
 * for PKCS12 */
40612
void wolfSSL_PKCS12_PBE_add(void)
40613
0
{
40614
0
    WOLFSSL_ENTER("wolfSSL_PKCS12_PBE_add");
40615
0
}
40616
40617
#if !defined(NO_FILESYSTEM)
40618
WOLFSSL_X509_PKCS12 *wolfSSL_d2i_PKCS12_fp(XFILE fp,
40619
        WOLFSSL_X509_PKCS12 **pkcs12)
40620
0
{
40621
0
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_fp");
40622
0
    return (WOLFSSL_X509_PKCS12 *)wolfSSL_d2i_X509_fp_ex(fp, (void **)pkcs12,
40623
0
        PKCS12_TYPE);
40624
0
}
40625
#endif /* !NO_FILESYSTEM */
40626
40627
#endif /* OPENSSL_EXTRA */
40628
40629
#if defined(HAVE_PKCS12)
40630
40631
#ifdef OPENSSL_EXTRA
40632
40633
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
40634
40635
#ifndef NO_BIO
40636
WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12)
40637
0
{
40638
0
    WC_PKCS12* localPkcs12 = NULL;
40639
0
    unsigned char* mem = NULL;
40640
0
    long memSz;
40641
0
    int ret = -1;
40642
40643
0
    WOLFSSL_ENTER("wolfSSL_d2i_PKCS12_bio");
40644
40645
0
    if (bio == NULL) {
40646
0
        WOLFSSL_MSG("Bad Function Argument bio is NULL");
40647
0
        return NULL;
40648
0
    }
40649
40650
0
    memSz = wolfSSL_BIO_get_len(bio);
40651
0
    if (memSz <= 0) {
40652
0
        return NULL;
40653
0
    }
40654
0
    mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40655
0
    if (mem == NULL) {
40656
0
        return NULL;
40657
0
    }
40658
40659
0
    if (mem != NULL) {
40660
0
        localPkcs12 = wc_PKCS12_new();
40661
0
        if (localPkcs12 == NULL) {
40662
0
            WOLFSSL_MSG("Memory error");
40663
0
        }
40664
0
    }
40665
40666
0
    if (mem != NULL && localPkcs12 != NULL) {
40667
0
        if (wolfSSL_BIO_read(bio, mem, (int)memSz) == memSz) {
40668
0
            ret = wc_d2i_PKCS12(mem, (word32)memSz, localPkcs12);
40669
0
            if (ret < 0) {
40670
0
                WOLFSSL_MSG("Failed to get PKCS12 sequence");
40671
0
            }
40672
0
        }
40673
0
        else {
40674
0
            WOLFSSL_MSG("Failed to get data from bio struct");
40675
0
        }
40676
0
    }
40677
40678
    /* cleanup */
40679
0
    if (mem != NULL)
40680
0
        XFREE(mem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
40681
0
    if (ret < 0 && localPkcs12 != NULL) {
40682
0
        wc_PKCS12_free(localPkcs12);
40683
0
        localPkcs12 = NULL;
40684
0
    }
40685
0
    if (pkcs12 != NULL)
40686
0
        *pkcs12 = localPkcs12;
40687
40688
0
    return localPkcs12;
40689
0
}
40690
40691
/* Converts the PKCS12 to DER format and outputs it into bio.
40692
 *
40693
 * bio is the structure to hold output DER
40694
 * pkcs12 structure to create DER from
40695
 *
40696
 * return 1 for success or 0 if an error occurs
40697
 */
40698
int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12)
40699
0
{
40700
0
    int ret = WOLFSSL_FAILURE;
40701
40702
0
    WOLFSSL_ENTER("wolfSSL_i2d_PKCS12_bio");
40703
40704
0
    if ((bio != NULL) && (pkcs12 != NULL)) {
40705
0
        word32 certSz = 0;
40706
0
        byte *certDer = NULL;
40707
40708
0
        certSz = wc_i2d_PKCS12(pkcs12, &certDer, NULL);
40709
0
        if ((certSz > 0) && (certDer != NULL)) {
40710
0
            if (wolfSSL_BIO_write(bio, certDer, certSz) == (int)certSz) {
40711
0
                ret = WOLFSSL_SUCCESS;
40712
0
            }
40713
0
        }
40714
40715
0
        if (certDer != NULL) {
40716
0
            XFREE(certDer, NULL, DYNAMIC_TYPE_PKCS);
40717
0
        }
40718
0
    }
40719
40720
0
    return ret;
40721
0
}
40722
#endif /* !NO_BIO */
40723
40724
/* Creates a new WC_PKCS12 structure
40725
 *
40726
 * pass  password to use
40727
 * name  friendlyName to use
40728
 * pkey  private key to go into PKCS12 bundle
40729
 * cert  certificate to go into PKCS12 bundle
40730
 * ca    extra certificates that can be added to bundle. Can be NULL
40731
 * keyNID  type of encryption to use on the key (-1 means no encryption)
40732
 * certNID type of encryption to use on the certificate
40733
 * itt     number of iterations with encryption
40734
 * macItt  number of iterations with mac creation
40735
 * keyType flag for signature and/or encryption key
40736
 *
40737
 * returns a pointer to a new WC_PKCS12 structure on success and NULL on fail
40738
 */
40739
WC_PKCS12* wolfSSL_PKCS12_create(char* pass, char* name, WOLFSSL_EVP_PKEY* pkey,
40740
        WOLFSSL_X509* cert, WOLF_STACK_OF(WOLFSSL_X509)* ca, int keyNID,
40741
        int certNID, int itt, int macItt, int keyType)
40742
0
{
40743
0
    WC_PKCS12* pkcs12;
40744
0
    WC_DerCertList* list = NULL;
40745
0
    word32 passSz;
40746
0
    byte* keyDer = NULL;
40747
0
    word32 keyDerSz;
40748
0
    byte* certDer;
40749
0
    int certDerSz;
40750
40751
0
    WOLFSSL_ENTER("wolfSSL_PKCS12_create()");
40752
40753
0
    if (pass == NULL || pkey == NULL || cert == NULL) {
40754
0
        WOLFSSL_LEAVE("wolfSSL_PKCS12_create()", BAD_FUNC_ARG);
40755
0
        return NULL;
40756
0
    }
40757
0
    passSz = (word32)XSTRLEN(pass);
40758
40759
0
    keyDer = (byte*)pkey->pkey.ptr;
40760
0
    keyDerSz = pkey->pkey_sz;
40761
40762
0
    certDer = (byte*)wolfSSL_X509_get_der(cert, &certDerSz);
40763
0
    if (certDer == NULL) {
40764
0
        return NULL;
40765
0
    }
40766
40767
0
    if (ca != NULL) {
40768
0
        WC_DerCertList* cur;
40769
0
        unsigned long numCerts = ca->num;
40770
0
        byte* curDer;
40771
0
        int   curDerSz = 0;
40772
0
        WOLFSSL_STACK* sk = ca;
40773
40774
0
        while (numCerts > 0 && sk != NULL) {
40775
0
            cur = (WC_DerCertList*)XMALLOC(sizeof(WC_DerCertList), NULL,
40776
0
                    DYNAMIC_TYPE_PKCS);
40777
0
            if (cur == NULL) {
40778
0
                wc_FreeCertList(list, NULL);
40779
0
                return NULL;
40780
0
            }
40781
40782
0
            curDer = (byte*)wolfSSL_X509_get_der(sk->data.x509, &curDerSz);
40783
0
            if (curDer == NULL || curDerSz < 0) {
40784
0
                XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
40785
0
                wc_FreeCertList(list, NULL);
40786
0
                return NULL;
40787
0
            }
40788
40789
0
            cur->buffer = (byte*)XMALLOC(curDerSz, NULL, DYNAMIC_TYPE_PKCS);
40790
0
            if (cur->buffer == NULL) {
40791
0
                XFREE(cur, NULL, DYNAMIC_TYPE_PKCS);
40792
0
                wc_FreeCertList(list, NULL);
40793
0
                return NULL;
40794
0
            }
40795
0
            XMEMCPY(cur->buffer, curDer, curDerSz);
40796
0
            cur->bufferSz = curDerSz;
40797
0
            cur->next = list;
40798
0
            list = cur;
40799
40800
0
            sk = sk->next;
40801
0
            numCerts--;
40802
0
        }
40803
0
    }
40804
40805
0
    pkcs12 = wc_PKCS12_create(pass, passSz, name, keyDer, keyDerSz,
40806
0
            certDer, certDerSz, list, keyNID, certNID, itt, macItt,
40807
0
            keyType, NULL);
40808
40809
0
    if (ca != NULL) {
40810
0
        wc_FreeCertList(list, NULL);
40811
0
    }
40812
40813
0
    return pkcs12;
40814
0
}
40815
40816
40817
/* return WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure */
40818
int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw,
40819
          WOLFSSL_EVP_PKEY** pkey, WOLFSSL_X509** cert,
40820
          WOLF_STACK_OF(WOLFSSL_X509)** ca)
40821
0
{
40822
0
    void* heap = NULL;
40823
0
    int ret;
40824
0
    byte* certData = NULL;
40825
0
    word32 certDataSz;
40826
0
    byte* pk = NULL;
40827
0
    word32 pkSz;
40828
0
    WC_DerCertList* certList = NULL;
40829
0
#ifdef WOLFSSL_SMALL_STACK
40830
0
    DecodedCert *DeCert;
40831
#else
40832
    DecodedCert DeCert[1];
40833
#endif
40834
40835
0
    WOLFSSL_ENTER("wolfSSL_PKCS12_parse");
40836
40837
    /* make sure we init return args */
40838
0
    if (pkey) *pkey = NULL;
40839
0
    if (cert) *cert = NULL;
40840
0
    if (ca)   *ca = NULL;
40841
40842
0
    if (pkcs12 == NULL || psw == NULL || pkey == NULL || cert == NULL) {
40843
0
        WOLFSSL_MSG("Bad argument value");
40844
0
        return WOLFSSL_FAILURE;
40845
0
    }
40846
40847
0
    heap  = wc_PKCS12_GetHeap(pkcs12);
40848
40849
0
    if (ca == NULL) {
40850
0
        ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
40851
0
            NULL);
40852
0
    }
40853
0
    else {
40854
0
        ret = wc_PKCS12_parse(pkcs12, psw, &pk, &pkSz, &certData, &certDataSz,
40855
0
            &certList);
40856
0
    }
40857
0
    if (ret < 0) {
40858
0
        WOLFSSL_LEAVE("wolfSSL_PKCS12_parse", ret);
40859
0
        return WOLFSSL_FAILURE;
40860
0
    }
40861
40862
0
#ifdef WOLFSSL_SMALL_STACK
40863
0
    DeCert = (DecodedCert *)XMALLOC(sizeof(*DeCert), heap,
40864
0
                                    DYNAMIC_TYPE_DCERT);
40865
0
    if (DeCert == NULL) {
40866
0
        WOLFSSL_MSG("out of memory");
40867
0
        return WOLFSSL_FAILURE;
40868
0
    }
40869
0
#endif
40870
40871
    /* Decode cert and place in X509 stack struct */
40872
0
    if (certList != NULL) {
40873
0
        WC_DerCertList* current = certList;
40874
40875
0
        *ca = (WOLF_STACK_OF(WOLFSSL_X509)*)XMALLOC(
40876
0
            sizeof(WOLF_STACK_OF(WOLFSSL_X509)), heap, DYNAMIC_TYPE_X509);
40877
0
        if (*ca == NULL) {
40878
0
            if (pk != NULL) {
40879
0
                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
40880
0
            }
40881
0
            if (certData != NULL) {
40882
0
                XFREE(*cert, heap, DYNAMIC_TYPE_PKCS); *cert = NULL;
40883
0
            }
40884
            /* Free up WC_DerCertList and move on */
40885
0
            while (current != NULL) {
40886
0
                WC_DerCertList* next = current->next;
40887
40888
0
                XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
40889
0
                XFREE(current, heap, DYNAMIC_TYPE_PKCS);
40890
0
                current = next;
40891
0
            }
40892
0
            ret = WOLFSSL_FAILURE;
40893
0
            goto out;
40894
0
        }
40895
0
        XMEMSET(*ca, 0, sizeof(WOLF_STACK_OF(WOLFSSL_X509)));
40896
40897
        /* add list of DER certs as X509's to stack */
40898
0
        while (current != NULL) {
40899
0
            WC_DerCertList*  toFree = current;
40900
0
            WOLFSSL_X509* x509;
40901
40902
0
            x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
40903
0
                DYNAMIC_TYPE_X509);
40904
0
            InitX509(x509, 1, heap);
40905
0
            InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap);
40906
0
            if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
40907
0
                WOLFSSL_MSG("Issue with parsing certificate");
40908
0
                FreeDecodedCert(DeCert);
40909
0
                wolfSSL_X509_free(x509);
40910
0
            }
40911
0
            else {
40912
0
                if (CopyDecodedToX509(x509, DeCert) != 0) {
40913
0
                    WOLFSSL_MSG("Failed to copy decoded cert");
40914
0
                    FreeDecodedCert(DeCert);
40915
0
                    wolfSSL_X509_free(x509);
40916
0
                    wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
40917
0
                    if (pk != NULL) {
40918
0
                        XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
40919
0
                    }
40920
0
                    if (certData != NULL) {
40921
0
                        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
40922
0
                    }
40923
                    /* Free up WC_DerCertList */
40924
0
                    while (current != NULL) {
40925
0
                        WC_DerCertList* next = current->next;
40926
40927
0
                        XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
40928
0
                        XFREE(current, heap, DYNAMIC_TYPE_PKCS);
40929
0
                        current = next;
40930
0
                    }
40931
0
                    ret = WOLFSSL_FAILURE;
40932
0
                    goto out;
40933
0
                }
40934
0
                FreeDecodedCert(DeCert);
40935
40936
0
                if (wolfSSL_sk_X509_push(*ca, x509) != 1) {
40937
0
                    WOLFSSL_MSG("Failed to push x509 onto stack");
40938
0
                    wolfSSL_X509_free(x509);
40939
0
                    wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
40940
0
                    if (pk != NULL) {
40941
0
                        XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
40942
0
                    }
40943
0
                    if (certData != NULL) {
40944
0
                        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
40945
0
                    }
40946
40947
                    /* Free up WC_DerCertList */
40948
0
                    while (current != NULL) {
40949
0
                        WC_DerCertList* next = current->next;
40950
40951
0
                        XFREE(current->buffer, heap, DYNAMIC_TYPE_PKCS);
40952
0
                        XFREE(current, heap, DYNAMIC_TYPE_PKCS);
40953
0
                        current = next;
40954
0
                    }
40955
0
                    ret = WOLFSSL_FAILURE;
40956
0
                    goto out;
40957
0
                }
40958
0
            }
40959
0
            current = current->next;
40960
0
            XFREE(toFree->buffer, heap, DYNAMIC_TYPE_PKCS);
40961
0
            XFREE(toFree, heap, DYNAMIC_TYPE_PKCS);
40962
0
        }
40963
0
    }
40964
40965
40966
    /* Decode cert and place in X509 struct */
40967
0
    if (certData != NULL) {
40968
0
        *cert = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), heap,
40969
0
            DYNAMIC_TYPE_X509);
40970
0
        if (*cert == NULL) {
40971
0
            if (pk != NULL) {
40972
0
                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
40973
0
            }
40974
0
            if (ca != NULL) {
40975
0
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
40976
0
            }
40977
0
            XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
40978
0
            ret = WOLFSSL_FAILURE;
40979
0
            goto out;
40980
0
        }
40981
0
        InitX509(*cert, 1, heap);
40982
0
        InitDecodedCert(DeCert, certData, certDataSz, heap);
40983
0
        if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) != 0) {
40984
0
            WOLFSSL_MSG("Issue with parsing certificate");
40985
0
        }
40986
0
        if (CopyDecodedToX509(*cert, DeCert) != 0) {
40987
0
            WOLFSSL_MSG("Failed to copy decoded cert");
40988
0
            FreeDecodedCert(DeCert);
40989
0
            if (pk != NULL) {
40990
0
                XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
40991
0
            }
40992
0
            if (ca != NULL) {
40993
0
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
40994
0
            }
40995
0
            wolfSSL_X509_free(*cert); *cert = NULL;
40996
0
            ret = WOLFSSL_FAILURE;
40997
0
            goto out;
40998
0
        }
40999
0
        FreeDecodedCert(DeCert);
41000
0
        XFREE(certData, heap, DYNAMIC_TYPE_PKCS);
41001
0
    }
41002
41003
41004
    /* get key type */
41005
0
    ret = BAD_STATE_E;
41006
0
    if (pk != NULL) { /* decode key if present */
41007
0
        *pkey = wolfSSL_EVP_PKEY_new_ex(heap);
41008
0
        if (*pkey == NULL) {
41009
0
            wolfSSL_X509_free(*cert); *cert = NULL;
41010
0
            if (ca != NULL) {
41011
0
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41012
0
            }
41013
0
            XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY);
41014
0
            ret = WOLFSSL_FAILURE;
41015
0
            goto out;
41016
0
        }
41017
41018
0
    #ifndef NO_RSA
41019
0
        {
41020
0
            const unsigned char* pt = pk;
41021
0
            if (wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, pkey, &pt, pkSz) !=
41022
0
                    NULL) {
41023
0
                ret = 0;
41024
0
            }
41025
0
        }
41026
0
    #endif /* NO_RSA */
41027
41028
0
    #ifdef HAVE_ECC
41029
0
        if (ret != 0) { /* if is in fail state check if ECC key */
41030
0
            const unsigned char* pt = pk;
41031
0
            if (wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, pkey, &pt, pkSz) !=
41032
0
                    NULL) {
41033
0
                ret = 0;
41034
0
            }
41035
0
        }
41036
0
    #endif /* HAVE_ECC */
41037
0
        if (pk != NULL)
41038
0
            XFREE(pk, heap, DYNAMIC_TYPE_PKCS);
41039
0
        if (ret != 0) { /* if is in fail state and no PKEY then fail */
41040
0
            wolfSSL_X509_free(*cert); *cert = NULL;
41041
0
            if (ca != NULL) {
41042
0
                wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL;
41043
0
            }
41044
0
            wolfSSL_EVP_PKEY_free(*pkey); *pkey = NULL;
41045
0
            WOLFSSL_MSG("Bad PKCS12 key format");
41046
0
            ret = WOLFSSL_FAILURE;
41047
0
            goto out;
41048
0
        }
41049
41050
0
        if (pkey != NULL && *pkey != NULL) {
41051
0
            (*pkey)->save_type = 0;
41052
0
        }
41053
0
    }
41054
41055
0
    (void)ret;
41056
0
    (void)ca;
41057
41058
0
    ret = WOLFSSL_SUCCESS;
41059
41060
0
out:
41061
41062
0
#ifdef WOLFSSL_SMALL_STACK
41063
0
    XFREE(DeCert, heap, DYNAMIC_TYPE_DCERT);
41064
0
#endif
41065
41066
0
    return ret;
41067
0
}
41068
41069
int wolfSSL_PKCS12_verify_mac(WC_PKCS12 *pkcs12, const char *psw,
41070
        int pswLen)
41071
0
{
41072
0
    WOLFSSL_ENTER("wolfSSL_PKCS12_verify_mac");
41073
41074
0
    if (!pkcs12) {
41075
0
        return WOLFSSL_FAILURE;
41076
0
    }
41077
41078
0
    return wc_PKCS12_verify_ex(pkcs12, (const byte*)psw, pswLen) == 0 ?
41079
0
            WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
41080
0
}
41081
41082
#endif /* !NO_ASN && !NO_PWDBASED */
41083
41084
#endif /* OPENSSL_EXTRA */
41085
41086
#endif /* HAVE_PKCS12 */
41087
/*******************************************************************************
41088
 * END OF PKCS12 APIs
41089
 ******************************************************************************/
41090
41091
#endif /* !NO_CERTS */
41092
41093
41094
/*******************************************************************************
41095
 * BEGIN OPENSSL FIPS DRBG APIs
41096
 ******************************************************************************/
41097
#if defined(OPENSSL_EXTRA) && !defined(WC_NO_RNG) && defined(HAVE_HASHDRBG)
41098
int wolfSSL_FIPS_drbg_init(WOLFSSL_DRBG_CTX *ctx, int type, unsigned int flags)
41099
0
{
41100
0
    int ret = WOLFSSL_FAILURE;
41101
0
    if (ctx != NULL) {
41102
0
        XMEMSET(ctx, 0, sizeof(WOLFSSL_DRBG_CTX));
41103
0
        ctx->type = type;
41104
0
        ctx->xflags = flags;
41105
0
        ctx->status = DRBG_STATUS_UNINITIALISED;
41106
0
        ret = WOLFSSL_SUCCESS;
41107
0
    }
41108
0
    return ret;
41109
0
}
41110
WOLFSSL_DRBG_CTX* wolfSSL_FIPS_drbg_new(int type, unsigned int flags)
41111
0
{
41112
0
    int ret = WOLFSSL_FAILURE;
41113
0
    WOLFSSL_DRBG_CTX* ctx = (WOLFSSL_DRBG_CTX*)XMALLOC(sizeof(WOLFSSL_DRBG_CTX),
41114
0
        NULL, DYNAMIC_TYPE_OPENSSL);
41115
0
    ret = wolfSSL_FIPS_drbg_init(ctx, type, flags);
41116
0
    if (ret == WOLFSSL_SUCCESS && type != 0) {
41117
0
        ret = wolfSSL_FIPS_drbg_instantiate(ctx, NULL, 0);
41118
0
    }
41119
0
    if (ret != WOLFSSL_SUCCESS) {
41120
0
        WOLFSSL_ERROR(ret);
41121
0
        wolfSSL_FIPS_drbg_free(ctx);
41122
0
        ctx = NULL;
41123
0
    }
41124
0
    return ctx;
41125
0
}
41126
int wolfSSL_FIPS_drbg_instantiate(WOLFSSL_DRBG_CTX* ctx,
41127
    const unsigned char* pers, size_t perslen)
41128
0
{
41129
0
    int ret = WOLFSSL_FAILURE;
41130
0
    if (ctx != NULL && ctx->rng == NULL) {
41131
0
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
41132
0
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
41133
0
        ctx->rng = wc_rng_new((byte*)pers, (word32)perslen, NULL);
41134
    #else
41135
        ctx->rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
41136
        if (ctx->rng != NULL) {
41137
        #if defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)
41138
            ret = wc_InitRngNonce(ctx->rng, (byte*)pers, (word32)perslen);
41139
        #else
41140
            ret = wc_InitRng(ctx->rng);
41141
            (void)pers;
41142
            (void)perslen;
41143
        #endif
41144
            if (ret != 0) {
41145
                WOLFSSL_ERROR(ret);
41146
                XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
41147
                ctx->rng = NULL;
41148
            }
41149
        }
41150
    #endif
41151
0
    }
41152
0
    if (ctx != NULL && ctx->rng != NULL) {
41153
0
        ctx->status = DRBG_STATUS_READY;
41154
0
        ret = WOLFSSL_SUCCESS;
41155
0
    }
41156
0
    return ret;
41157
0
}
41158
int wolfSSL_FIPS_drbg_set_callbacks(WOLFSSL_DRBG_CTX* ctx,
41159
    drbg_entropy_get entropy_get, drbg_entropy_clean entropy_clean,
41160
    size_t entropy_blocklen,
41161
    drbg_nonce_get none_get, drbg_nonce_clean nonce_clean)
41162
0
{
41163
0
    int ret = WOLFSSL_FAILURE;
41164
0
    if (ctx != NULL) {
41165
0
        ctx->entropy_get = entropy_get;
41166
0
        ctx->entropy_clean = entropy_clean;
41167
0
        ctx->entropy_blocklen = entropy_blocklen;
41168
0
        ctx->none_get = none_get;
41169
0
        ctx->nonce_clean = nonce_clean;
41170
0
        ret = WOLFSSL_SUCCESS;
41171
0
    }
41172
0
    return ret;
41173
0
}
41174
void wolfSSL_FIPS_rand_add(const void* buf, int num, double entropy)
41175
0
{
41176
    /* not implemented */
41177
0
    (void)buf;
41178
0
    (void)num;
41179
0
    (void)entropy;
41180
0
}
41181
int wolfSSL_FIPS_drbg_reseed(WOLFSSL_DRBG_CTX* ctx, const unsigned char* adin,
41182
    size_t adinlen)
41183
0
{
41184
0
    int ret = WOLFSSL_FAILURE;
41185
0
    if (ctx != NULL && ctx->rng != NULL) {
41186
0
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
41187
0
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(2,0)))
41188
0
        if (wc_RNG_DRBG_Reseed(ctx->rng, adin, (word32)adinlen) == 0) {
41189
0
            ret = WOLFSSL_SUCCESS;
41190
0
        }
41191
    #else
41192
        ret = WOLFSSL_SUCCESS;
41193
        (void)adin;
41194
        (void)adinlen;
41195
    #endif
41196
0
    }
41197
0
    return ret;
41198
0
}
41199
int wolfSSL_FIPS_drbg_generate(WOLFSSL_DRBG_CTX* ctx, unsigned char* out,
41200
    size_t outlen, int prediction_resistance, const unsigned char* adin,
41201
    size_t adinlen)
41202
0
{
41203
0
    int ret = WOLFSSL_FAILURE;
41204
0
    if (ctx != NULL && ctx->rng != NULL) {
41205
0
        ret = wc_RNG_GenerateBlock(ctx->rng, out, (word32)outlen);
41206
0
        if (ret == 0) {
41207
0
            ret = WOLFSSL_SUCCESS;
41208
0
        }
41209
0
    }
41210
0
    (void)prediction_resistance;
41211
0
    (void)adin;
41212
0
    (void)adinlen;
41213
0
    return ret;
41214
0
}
41215
int wolfSSL_FIPS_drbg_uninstantiate(WOLFSSL_DRBG_CTX *ctx)
41216
0
{
41217
0
    if (ctx != NULL && ctx->rng != NULL) {
41218
0
    #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \
41219
0
        (defined(HAVE_FIPS) && FIPS_VERSION_GE(5,0)))
41220
0
        wc_rng_free(ctx->rng);
41221
    #else
41222
        wc_FreeRng(ctx->rng);
41223
        XFREE(ctx->rng, NULL, DYNAMIC_TYPE_RNG);
41224
    #endif
41225
0
        ctx->rng = NULL;
41226
0
        ctx->status = DRBG_STATUS_UNINITIALISED;
41227
0
    }
41228
0
    return WOLFSSL_SUCCESS;
41229
0
}
41230
void wolfSSL_FIPS_drbg_free(WOLFSSL_DRBG_CTX *ctx)
41231
0
{
41232
0
    if (ctx != NULL) {
41233
        /* As saftey check if free'ing the default drbg, then mark global NULL.
41234
         * Technically the user should not call free on the default drbg. */
41235
0
        if (ctx == gDrbgDefCtx) {
41236
0
            gDrbgDefCtx = NULL;
41237
0
        }
41238
0
        wolfSSL_FIPS_drbg_uninstantiate(ctx);
41239
0
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
41240
0
    }
41241
0
}
41242
WOLFSSL_DRBG_CTX* wolfSSL_FIPS_get_default_drbg(void)
41243
0
{
41244
0
    if (gDrbgDefCtx == NULL) {
41245
0
        gDrbgDefCtx = wolfSSL_FIPS_drbg_new(0, 0);
41246
0
    }
41247
0
    return gDrbgDefCtx;
41248
0
}
41249
void wolfSSL_FIPS_get_timevec(unsigned char* buf, unsigned long* pctr)
41250
0
{
41251
    /* not implemented */
41252
0
    (void)buf;
41253
0
    (void)pctr;
41254
0
}
41255
void* wolfSSL_FIPS_drbg_get_app_data(WOLFSSL_DRBG_CTX *ctx)
41256
0
{
41257
0
    if (ctx != NULL) {
41258
0
        return ctx->app_data;
41259
0
    }
41260
0
    return NULL;
41261
0
}
41262
void wolfSSL_FIPS_drbg_set_app_data(WOLFSSL_DRBG_CTX *ctx, void *app_data)
41263
0
{
41264
0
    if (ctx != NULL) {
41265
0
        ctx->app_data = app_data;
41266
0
    }
41267
0
}
41268
#endif
41269
/*******************************************************************************
41270
 * END OF OPENSSL FIPS DRBG APIs
41271
 ******************************************************************************/
41272
41273
41274
#endif /* !WOLFCRYPT_ONLY */
41275
41276
/*******************************************************************************
41277
 * START OF CRYPTO-ONLY APIs
41278
 ******************************************************************************/
41279
41280
#if defined(OPENSSL_EXTRA) || defined(HAVE_LIGHTY) || \
41281
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(HAVE_STUNNEL) || \
41282
    defined(WOLFSSL_NGINX) || defined(HAVE_POCO_LIB) || \
41283
    defined(WOLFSSL_HAPROXY)
41284
41285
#ifndef NO_SHA
41286
    /* One shot SHA1 hash of message.
41287
     *
41288
     * d  message to hash
41289
     * n  size of d buffer
41290
     * md buffer to hold digest. Should be SHA_DIGEST_SIZE.
41291
     *
41292
     * Note: if md is null then a static buffer of SHA_DIGEST_SIZE is used.
41293
     *       When the static buffer is used this function is not thread safe.
41294
     *
41295
     * Returns a pointer to the message digest on success and NULL on failure.
41296
     */
41297
    unsigned char *wolfSSL_SHA1(const unsigned char *d, size_t n,
41298
            unsigned char *md)
41299
0
    {
41300
0
        static byte dig[WC_SHA_DIGEST_SIZE];
41301
0
        byte* ret = md;
41302
0
        wc_Sha sha;
41303
41304
0
        WOLFSSL_ENTER("wolfSSL_SHA1");
41305
41306
0
        if (wc_InitSha_ex(&sha, NULL, INVALID_DEVID) != 0) {
41307
0
            WOLFSSL_MSG("SHA1 Init failed");
41308
0
            return NULL;
41309
0
        }
41310
41311
0
        if (wc_ShaUpdate(&sha, (const byte*)d, (word32)n) != 0) {
41312
0
            WOLFSSL_MSG("SHA1 Update failed");
41313
0
            return NULL;
41314
0
        }
41315
41316
0
        if (md == NULL) {
41317
0
            WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA1 IS NOT "
41318
0
                        "THREAD SAFE WHEN md == NULL");
41319
0
            ret = dig;
41320
0
        }
41321
0
        if (wc_ShaFinal(&sha, ret) != 0) {
41322
0
            WOLFSSL_MSG("SHA1 Final failed");
41323
0
            wc_ShaFree(&sha);
41324
0
            return NULL;
41325
0
        }
41326
0
        wc_ShaFree(&sha);
41327
41328
0
        return ret;
41329
0
    }
41330
#endif /* ! NO_SHA */
41331
41332
#ifdef WOLFSSL_SHA224
41333
    /* One shot SHA224 hash of message.
41334
     *
41335
     * d  message to hash
41336
     * n  size of d buffer
41337
     * md buffer to hold digest. Should be WC_SHA224_DIGEST_SIZE.
41338
     *
41339
     * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
41340
     *       When the static buffer is used this function is not thread safe.
41341
     *
41342
     * Returns a pointer to the message digest on success and NULL on failure.
41343
     */
41344
      unsigned char *wolfSSL_SHA224(const unsigned char *d, size_t n,
41345
            unsigned char *md)
41346
0
     {
41347
0
        static byte dig[WC_SHA224_DIGEST_SIZE];
41348
0
        byte* ret = md;
41349
0
        wc_Sha256 sha;
41350
41351
0
        WOLFSSL_ENTER("wolfSSL_SHA224");
41352
41353
0
        if (wc_InitSha224_ex(&sha, NULL, INVALID_DEVID) != 0) {
41354
0
            WOLFSSL_MSG("SHA224 Init failed");
41355
0
            return NULL;
41356
0
        }
41357
41358
0
        if (wc_Sha224Update(&sha, (const byte*)d, (word32)n) != 0) {
41359
0
            WOLFSSL_MSG("SHA224 Update failed");
41360
0
            return NULL;
41361
0
        }
41362
41363
0
        if (md == NULL) {
41364
0
            WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA224 IS NOT "
41365
0
                        "THREAD SAFE WHEN md == NULL");
41366
0
            ret = dig;
41367
0
        }
41368
0
        if (wc_Sha224Final(&sha, ret) != 0) {
41369
0
            WOLFSSL_MSG("SHA224 Final failed");
41370
0
            wc_Sha224Free(&sha);
41371
0
            return NULL;
41372
0
        }
41373
0
        wc_Sha224Free(&sha);
41374
41375
0
        return ret;
41376
0
    }
41377
#endif
41378
41379
#ifndef NO_SHA256
41380
    /* One shot SHA256 hash of message.
41381
     *
41382
     * d  message to hash
41383
     * n  size of d buffer
41384
     * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
41385
     *
41386
     * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
41387
     *       When the static buffer is used this function is not thread safe.
41388
     *
41389
     * Returns a pointer to the message digest on success and NULL on failure.
41390
     */
41391
    unsigned char *wolfSSL_SHA256(const unsigned char *d, size_t n,
41392
            unsigned char *md)
41393
0
    {
41394
0
        static byte dig[WC_SHA256_DIGEST_SIZE];
41395
0
        byte* ret = md;
41396
0
        wc_Sha256 sha;
41397
41398
0
        WOLFSSL_ENTER("wolfSSL_SHA256");
41399
41400
0
        if (wc_InitSha256_ex(&sha, NULL, INVALID_DEVID) != 0) {
41401
0
            WOLFSSL_MSG("SHA256 Init failed");
41402
0
            return NULL;
41403
0
        }
41404
41405
0
        if (wc_Sha256Update(&sha, (const byte*)d, (word32)n) != 0) {
41406
0
            WOLFSSL_MSG("SHA256 Update failed");
41407
0
            return NULL;
41408
0
        }
41409
41410
0
        if (md == NULL) {
41411
0
            WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA256 IS NOT "
41412
0
                        "THREAD SAFE WHEN md == NULL");
41413
0
            ret = dig;
41414
0
        }
41415
0
        if (wc_Sha256Final(&sha, ret) != 0) {
41416
0
            WOLFSSL_MSG("SHA256 Final failed");
41417
0
            wc_Sha256Free(&sha);
41418
0
            return NULL;
41419
0
        }
41420
0
        wc_Sha256Free(&sha);
41421
41422
0
        return ret;
41423
0
    }
41424
#endif /* ! NO_SHA256 */
41425
41426
#ifdef WOLFSSL_SHA384
41427
     /* One shot SHA384 hash of message.
41428
      *
41429
      * d  message to hash
41430
      * n  size of d buffer
41431
      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
41432
      *
41433
      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
41434
      *       When the static buffer is used this function is not thread safe.
41435
      *
41436
      * Returns a pointer to the message digest on success and NULL on failure.
41437
      */
41438
     unsigned char *wolfSSL_SHA384(const unsigned char *d, size_t n,
41439
             unsigned char *md)
41440
0
     {
41441
0
         static byte dig[WC_SHA384_DIGEST_SIZE];
41442
0
         byte* ret = md;
41443
0
         wc_Sha384 sha;
41444
41445
0
         WOLFSSL_ENTER("wolfSSL_SHA384");
41446
41447
0
         if (wc_InitSha384_ex(&sha, NULL, INVALID_DEVID) != 0) {
41448
0
             WOLFSSL_MSG("SHA384 Init failed");
41449
0
             return NULL;
41450
0
         }
41451
41452
0
         if (wc_Sha384Update(&sha, (const byte*)d, (word32)n) != 0) {
41453
0
             WOLFSSL_MSG("SHA384 Update failed");
41454
0
             return NULL;
41455
0
         }
41456
41457
0
         if (md == NULL) {
41458
0
             WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA384 IS NOT "
41459
0
                         "THREAD SAFE WHEN md == NULL");
41460
0
             ret = dig;
41461
0
         }
41462
0
         if (wc_Sha384Final(&sha, ret) != 0) {
41463
0
             WOLFSSL_MSG("SHA384 Final failed");
41464
0
             wc_Sha384Free(&sha);
41465
0
             return NULL;
41466
0
         }
41467
0
         wc_Sha384Free(&sha);
41468
41469
0
         return ret;
41470
0
     }
41471
#endif /* WOLFSSL_SHA384  */
41472
41473
#if defined(WOLFSSL_SHA512)
41474
     /* One shot SHA512 hash of message.
41475
      *
41476
      * d  message to hash
41477
      * n  size of d buffer
41478
      * md buffer to hold digest. Should be WC_SHA256_DIGEST_SIZE.
41479
      *
41480
      * Note: if md is null then a static buffer of WC_SHA256_DIGEST_SIZE is used.
41481
      *       When the static buffer is used this function is not thread safe.
41482
      *
41483
      * Returns a pointer to the message digest on success and NULL on failure.
41484
      */
41485
     unsigned char *wolfSSL_SHA512(const unsigned char *d, size_t n,
41486
             unsigned char *md)
41487
0
     {
41488
0
         static byte dig[WC_SHA512_DIGEST_SIZE];
41489
0
         byte* ret = md;
41490
0
         wc_Sha512 sha;
41491
41492
0
         WOLFSSL_ENTER("wolfSSL_SHA512");
41493
41494
0
         if (wc_InitSha512_ex(&sha, NULL, INVALID_DEVID) != 0) {
41495
0
             WOLFSSL_MSG("SHA512 Init failed");
41496
0
             return NULL;
41497
0
         }
41498
41499
0
         if (wc_Sha512Update(&sha, (const byte*)d, (word32)n) != 0) {
41500
0
             WOLFSSL_MSG("SHA512 Update failed");
41501
0
             return NULL;
41502
0
         }
41503
41504
0
         if (md == NULL) {
41505
0
             WOLFSSL_MSG("STATIC BUFFER BEING USED. wolfSSL_SHA512 IS NOT "
41506
0
                         "THREAD SAFE WHEN md == NULL");
41507
0
             ret = dig;
41508
0
         }
41509
0
         if (wc_Sha512Final(&sha, ret) != 0) {
41510
0
             WOLFSSL_MSG("SHA512 Final failed");
41511
0
             wc_Sha512Free(&sha);
41512
0
             return NULL;
41513
0
         }
41514
0
         wc_Sha512Free(&sha);
41515
41516
0
         return ret;
41517
0
     }
41518
#endif /* WOLFSSL_SHA512 */
41519
#endif /* OPENSSL_EXTRA || HAVE_LIGHTY || WOLFSSL_MYSQL_COMPATIBLE ||
41520
        * HAVE_STUNNEL || WOLFSSL_NGINX || HAVE_POCO_LIB || WOLFSSL_HAPROXY */
41521
41522
/*******************************************************************************
41523
 * END OF CRYPTO-ONLY APIs
41524
 ******************************************************************************/