Coverage Report

Created: 2026-11-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/src/ssl_api_cert.c
Line
Count
Source
1
/* ssl_api_cert.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if !defined(WOLFSSL_SSL_API_CERT_INCLUDED)
25
    #ifndef WOLFSSL_IGNORE_FILE_WARN
26
        #warning ssl_api_cert.c is not compiled separately from ssl.c
27
    #endif
28
#else
29
30
#ifndef NO_CERTS
31
32
/* Set whether mutual authentication is required for connections.
33
 * Server side only.
34
 *
35
 * @param [in] ctx  The SSL/TLS CTX object.
36
 * @param [in] req  1 to indicate required and 0 when not.
37
 * @return  0 on success.
38
 * @return  BAD_FUNC_ARG when ctx is NULL.
39
 * @return  SIDE_ERROR when not a server.
40
 */
41
int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req)
42
0
{
43
0
    if (ctx == NULL)
44
0
        return BAD_FUNC_ARG;
45
    /* Mutual authentication is a server-side only setting. */
46
0
    if (ctx->method->side != WOLFSSL_SERVER_END)
47
0
        return SIDE_ERROR;
48
49
0
    ctx->mutualAuth = (byte)req;
50
    /* A certificate has to be asked for to be required. */
51
0
    if (req) {
52
0
        ctx->verifyNone = 0;
53
0
        ctx->verifyPeer = 1;
54
0
    }
55
56
0
    return 0;
57
0
}
58
59
/* Set whether mutual authentication is required for the connection.
60
 * Server side only.
61
 *
62
 * @param [in, out] ssl  SSL/TLS object.
63
 * @param [in]      req  1 to indicate required and 0 when not.
64
 * @return  0 on success.
65
 * @return  BAD_FUNC_ARG when ssl is NULL.
66
 * @return  SIDE_ERROR when not a server
67
 */
68
int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
69
0
{
70
0
    if (ssl == NULL)
71
0
        return BAD_FUNC_ARG;
72
    /* Mutual authentication is a server-side only setting. */
73
0
    if (ssl->options.side != WOLFSSL_SERVER_END)
74
0
        return SIDE_ERROR;
75
76
0
    ssl->options.mutualAuth = (word16)req;
77
    /* A certificate has to be asked for to be required. */
78
0
    if (req) {
79
0
        ssl->options.verifyNone = 0;
80
0
        ssl->options.verifyPeer = 1;
81
0
    }
82
83
0
    return 0;
84
0
}
85
86
/* Get the certificate manager from the WOLFSSL_CTX.
87
 *
88
 * @param [in] ctx  SSL/TLS CTX object.
89
 * @return  Certificate manager object on success.
90
 * @return  NULL when ctx is NULL.
91
 */
92
WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
93
0
{
94
0
    WOLFSSL_CERT_MANAGER* cm = NULL;
95
96
    /* The certificate manager is owned by the context. */
97
0
    if (ctx != NULL)
98
0
        cm = ctx->cm;
99
100
0
    return cm;
101
0
}
102
103
/* Sets the max chain depth when verifying a certificate chain.
104
 *
105
 * Default depth is set to MAX_CHAIN_DEPTH.
106
 *
107
 * @param [in] ctx    WOLFSSL_CTX structure to set depth in
108
 * @param [in] depth  max depth
109
 */
110
void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth)
111
0
{
112
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
113
114
    /* Reject out-of-range depths; valid range is 0 to MAX_CHAIN_DEPTH. */
115
0
    if ((ctx == NULL) || (depth < 0) || (depth > MAX_CHAIN_DEPTH)) {
116
0
        WOLFSSL_MSG("Bad depth argument, too large or less than 0");
117
0
    }
118
0
    else {
119
0
        ctx->verifyDepth = (byte)depth;
120
0
    }
121
0
}
122
123
124
/* Get certificate chaining depth of SSL/TLS context object
125
 *
126
 * @param [in] ctx  SSL/TLS context object.
127
 * @return  Verification depth on success.
128
 * @return  BAD_FUNC_ARG when ctx is NULL.
129
 */
130
long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
131
0
{
132
0
    long ret;
133
134
0
    if (ctx == NULL) {
135
0
        ret = BAD_FUNC_ARG;
136
0
    }
137
0
    else {
138
        /* A configurable depth is only tracked with the OpenSSL extra APIs;
139
         * otherwise the fixed maximum chain depth applies. */
140
0
        #ifndef OPENSSL_EXTRA
141
0
        ret = MAX_CHAIN_DEPTH;
142
        #else
143
        ret = ctx->verifyDepth;
144
        #endif
145
0
    }
146
147
0
    return ret;
148
0
}
149
150
/* Get certificate chaining depth of SSL/TLS object
151
 *
152
 * @param [in] ssl  SSL/TLS object.
153
 * @return  Verification depth on success.
154
 * @return  BAD_FUNC_ARG when ssl is NULL.
155
 */
156
long wolfSSL_get_verify_depth(WOLFSSL* ssl)
157
0
{
158
0
    long ret;
159
160
0
    if (ssl == NULL) {
161
0
        ret = BAD_FUNC_ARG;
162
0
    }
163
0
    else {
164
        /* A configurable depth is only tracked with the OpenSSL extra APIs;
165
         * otherwise the fixed maximum chain depth applies. */
166
0
        #ifndef OPENSSL_EXTRA
167
0
        ret = MAX_CHAIN_DEPTH;
168
        #else
169
        ret = ssl->options.verifyDepth;
170
        #endif
171
0
    }
172
173
0
    return ret;
174
0
}
175
176
#if defined(HAVE_RPK)
177
/* TODO: Change this to use a bitfield. */
178
179
/* Confirm that all the byte data in the buffer is unique.
180
 *
181
 * @param [in] buf  Buffer to check.
182
 * @param [in] len  Length of buffer in bytes.
183
 * @return  1 if all the byte data in the buffer is unique.
184
 * @return  0 otherwise.
185
 */
186
static int isArrayUnique(const char* buf, size_t len)
187
{
188
    size_t i;
189
    /* Check the array is unique. */
190
    for (i = 0; i < len - 1; ++i) {
191
        size_t j;
192
        for (j = i + 1; j < len; ++j) {
193
            if (buf[i] == buf[j]) {
194
                return 0;
195
            }
196
        }
197
    }
198
    return 1;
199
}
200
/* Set user preference for the {client,server}_cert_type extension.
201
 *
202
 * Takes byte array containing cert types the caller can provide to its peer.
203
 * Cert types are in preferred order in the array.
204
 *
205
 * @param [in] cfg     Raw Public Key configuration.
206
 * @param [in] client  Indicates whether this is the client side.
207
 * @param [in] buf     List of certificate types.
208
 * @param [in] len     Length of certificate types.
209
 * @return  1 on success.
210
 * @return  BAD_FUNC_ARG when cfg is NULL.
211
 * @return  BAD_FUNC_ARG when len is too long.
212
 * @return  BAD_FUNC_ARG when buffer values are not unique.
213
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
214
 */
215
static int set_cert_type(RpkConfig* cfg, int client, const char* buf,
216
    int len)
217
{
218
    int i;
219
    byte* certTypeCnt;
220
    byte* certTypes;
221
222
    /* Validate parameters. */
223
    if ((cfg == NULL) || (len > (client ? MAX_CLIENT_CERT_TYPE_CNT :
224
                                          MAX_SERVER_CERT_TYPE_CNT))) {
225
        return BAD_FUNC_ARG;
226
    }
227
228
    /* Get preferred certificate types for side. */
229
    if (client) {
230
        certTypeCnt = &cfg->preferred_ClientCertTypeCnt;
231
        certTypes   =  cfg->preferred_ClientCertTypes;
232
    }
233
    else {
234
        certTypeCnt = &cfg->preferred_ServerCertTypeCnt;
235
        certTypes   =  cfg->preferred_ServerCertTypes;
236
    }
237
    /* If no buffer or empty buffer passed in, set the defaults. */
238
    if ((buf == NULL) || (len == 0)) {
239
        *certTypeCnt = 1;
240
        for (i = 0; i < 2; i++) {
241
            certTypes[i] = WOLFSSL_CERT_TYPE_X509;
242
        }
243
        return 1;
244
    }
245
246
    /* Check that the certificate types set are unique. */
247
    if (!isArrayUnique(buf, (size_t)len))
248
        return BAD_FUNC_ARG;
249
250
    /* Check that the certificate types being set are known and then set. */
251
    for (i = 0; i < len; i++) {
252
        if ((buf[i] != WOLFSSL_CERT_TYPE_RPK) &&
253
                (buf[i] != WOLFSSL_CERT_TYPE_X509)) {
254
            return BAD_FUNC_ARG;
255
        }
256
        certTypes[i] = (byte)buf[i];
257
    }
258
    *certTypeCnt = len;
259
260
    return 1;
261
}
262
/* Set the client certificate types against the SSL/TLS context.
263
 *
264
 * @param [in] ctx  SSL/TLS context object.
265
 * @param [in] buf  List of certificate types.
266
 * @param [in] len  Length of certificate types.
267
 * @return  1 on success.
268
 * @return  BAD_FUNC_ARG when ctx is NULL.
269
 * @return  BAD_FUNC_ARG when len is too long.
270
 * @return  BAD_FUNC_ARG when buffer values are not unique.
271
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
272
 */
273
int wolfSSL_CTX_set_client_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len)
274
{
275
    int ret;
276
277
    if (ctx == NULL) {
278
        ret = BAD_FUNC_ARG;
279
    }
280
    else {
281
        /* A side value of 1 records these as the client certificate types. */
282
        ret = set_cert_type(&ctx->rpkConfig, 1, buf, len);
283
    }
284
285
    return ret;
286
}
287
/* Set the server certificate types against the SSL/TLS context.
288
 *
289
 * @param [in] ctx  SSL/TLS context object.
290
 * @param [in] buf  List of certificate types.
291
 * @param [in] len  Length of certificate types.
292
 * @return  1 on success.
293
 * @return  BAD_FUNC_ARG when ctx is NULL.
294
 * @return  BAD_FUNC_ARG when len is too long.
295
 * @return  BAD_FUNC_ARG when buffer values are not unique.
296
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
297
 */
298
int wolfSSL_CTX_set_server_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len)
299
{
300
    int ret;
301
302
    if (ctx == NULL) {
303
        ret = BAD_FUNC_ARG;
304
    }
305
    else {
306
        /* A side value of 0 records these as the server certificate types. */
307
        ret = set_cert_type(&ctx->rpkConfig, 0, buf, len);
308
    }
309
310
    return ret;
311
}
312
/* Set the client certificate types against the SSL/TLS object.
313
 *
314
 * @param [in] ssl  SSL/TLS object.
315
 * @param [in] buf  List of certificate types.
316
 * @param [in] len  Length of certificate types.
317
 * @return  1 on success.
318
 * @return  BAD_FUNC_ARG when ssl is NULL.
319
 * @return  BAD_FUNC_ARG when len is too long.
320
 * @return  BAD_FUNC_ARG when buffer values are not unique.
321
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
322
 */
323
int wolfSSL_set_client_cert_type(WOLFSSL* ssl, const char* buf, int len)
324
{
325
    int ret;
326
327
    if (ssl == NULL) {
328
        ret = BAD_FUNC_ARG;
329
    }
330
    else {
331
        /* A side value of 1 records these as the client certificate types. */
332
        ret = set_cert_type(&ssl->options.rpkConfig, 1, buf, len);
333
    }
334
335
    return ret;
336
}
337
/* Set the server certificate types against the SSL/TLS object.
338
 *
339
 * @param [in] ssl  SSL/TLS object.
340
 * @param [in] buf  List of certificate types.
341
 * @param [in] len  Length of certificate types.
342
 * @return  1 on success.
343
 * @return  BAD_FUNC_ARG when ssl is NULL.
344
 * @return  BAD_FUNC_ARG when len is too long.
345
 * @return  BAD_FUNC_ARG when buffer values are not unique.
346
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
347
 */
348
int wolfSSL_set_server_cert_type(WOLFSSL* ssl, const char* buf, int len)
349
{
350
    int ret;
351
352
    if (ssl == NULL) {
353
        ret = BAD_FUNC_ARG;
354
    }
355
    else {
356
        /* A side value of 0 records these as the server certificate types. */
357
        ret = set_cert_type(&ssl->options.rpkConfig, 0, buf, len);
358
    }
359
360
    return ret;
361
}
362
363
/* Get negotiated client certificate type value.
364
 *
365
 * WOLFSSL_CERT_TYPE_UNKNOWN returned when no negotiation has been performed.
366
 *
367
 * @param [in]  ssl  SSL/TLS object.
368
 * @param [out] tp   Certificate type. One of:
369
 *                     -1: WOLFSSL_CERT_TYPE_UNKNOWN
370
 *                      0: WOLFSSL_CERT_TYPE_X509
371
 *                      2: WOLFSSL_CERT_TYPE_RPK
372
 * @return  1 on success.
373
 * @return  BAD_FUNC_ARG when ssl or tp is NULL.
374
 */
375
int wolfSSL_get_negotiated_client_cert_type(WOLFSSL* ssl, int* tp)
376
{
377
    int ret = 1;
378
379
    /* Validate parameters. */
380
    if ((ssl == NULL) || (tp == NULL)) {
381
        ret = BAD_FUNC_ARG;
382
    }
383
    /* Check side. */
384
    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
385
        /* Check certificate type negotiated. */
386
        if (ssl->options.rpkState.received_ClientCertTypeCnt == 1) {
387
            *tp = ssl->options.rpkState.received_ClientCertTypes[0];
388
        }
389
        else {
390
            *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
391
        }
392
    }
393
    /* Check certificate type negotiated. */
394
    else if (ssl->options.rpkState.sending_ClientCertTypeCnt == 1) {
395
        *tp = ssl->options.rpkState.sending_ClientCertTypes[0];
396
    }
397
    else {
398
        *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
399
    }
400
401
    return ret;
402
}
403
404
/* Get negotiated server certificate type value.
405
 *
406
 * WOLFSSL_CERT_TYPE_UNKNOWN returned when no negotiation has been performed.
407
 *
408
 * @param [in]  ssl  SSL/TLS object.
409
 * @param [out] tp   Certificate type. One of:
410
 *                     -1: WOLFSSL_CERT_TYPE_UNKNOWN
411
 *                      0: WOLFSSL_CERT_TYPE_X509
412
 *                      2: WOLFSSL_CERT_TYPE_RPK
413
 * @return  1 on success.
414
 * @return  BAD_FUNC_ARG when ssl or tp is NULL.
415
 */
416
int wolfSSL_get_negotiated_server_cert_type(WOLFSSL* ssl, int* tp)
417
{
418
    int ret = 1;
419
420
    /* Validate parameters. */
421
    if ((ssl == NULL) || (tp == NULL)) {
422
        ret = BAD_FUNC_ARG;
423
    }
424
    /* Check side. */
425
    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
426
        /* Check certificate type negotiated. */
427
        if (ssl->options.rpkState.received_ServerCertTypeCnt == 1) {
428
            *tp = ssl->options.rpkState.received_ServerCertTypes[0];
429
        }
430
        else {
431
            *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
432
        }
433
    }
434
    /* Check certificate type negotiated. */
435
    else if (ssl->options.rpkState.sending_ServerCertTypeCnt == 1) {
436
        *tp = ssl->options.rpkState.sending_ServerCertTypes[0];
437
    }
438
    else {
439
        *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
440
    }
441
    return ret;
442
}
443
444
#ifndef NO_SHA256
445
/* Store the SHA-256 digest of a DER SubjectPublicKeyInfo as an expected Raw
446
 * Public Key (RFC 7250) for out-of-band trust.
447
 *
448
 * @param [in] cfg     RPK configuration to add the pin to.
449
 * @param [in] spki    DER-encoded SubjectPublicKeyInfo.
450
 * @param [in] spkiSz  Length of spki in bytes.
451
 * @return  0 on success.
452
 * @return  BAD_FUNC_ARG when cfg or spki is NULL, or spkiSz is 0.
453
 * @return  BUFFER_E when no more pins can be stored.
454
 * @return  negative hashing error on failure.
455
 */
456
static int rpk_add_expected(RpkConfig* cfg, const unsigned char* spki,
457
    unsigned int spkiSz)
458
{
459
    int ret;
460
461
    if ((cfg == NULL) || (spki == NULL) || (spkiSz == 0)) {
462
        return BAD_FUNC_ARG;
463
    }
464
    if (cfg->expectedRpkCnt >= WOLFSSL_MAX_RPK_PINS) {
465
        return BUFFER_E;
466
    }
467
468
    ret = wc_Sha256Hash(spki, spkiSz, cfg->expectedRpk[cfg->expectedRpkCnt]);
469
    if (ret == 0) {
470
        cfg->expectedRpkCnt++;
471
    }
472
    return ret;
473
}
474
475
/* Pin an expected peer Raw Public Key on the SSL/TLS CTX object.
476
 *
477
 * @param [in] ctx     SSL/TLS CTX object.
478
 * @param [in] spki    DER-encoded SubjectPublicKeyInfo the peer will present.
479
 * @param [in] spkiSz  Length of spki in bytes.
480
 * @return  WOLFSSL_SUCCESS on success.
481
 * @return  BAD_FUNC_ARG when ctx or spki is NULL, or spkiSz is 0.
482
 * @return  BUFFER_E when the pin table is full (WOLFSSL_MAX_RPK_PINS reached).
483
 * @return  Other negative error code on hashing failure.
484
 */
485
int wolfSSL_CTX_set_expected_rpk(WOLFSSL_CTX* ctx, const unsigned char* spki,
486
    unsigned int spkiSz)
487
{
488
    int ret;
489
490
    if (ctx == NULL) {
491
        return BAD_FUNC_ARG;
492
    }
493
    ret = rpk_add_expected(&ctx->rpkConfig, spki, spkiSz);
494
    return (ret == 0) ? WOLFSSL_SUCCESS : ret;
495
}
496
497
/* Pin an expected peer Raw Public Key on the SSL/TLS object.
498
 *
499
 * @param [in] ssl     SSL/TLS object.
500
 * @param [in] spki    DER-encoded SubjectPublicKeyInfo the peer will present.
501
 * @param [in] spkiSz  Length of spki in bytes.
502
 * @return  WOLFSSL_SUCCESS on success.
503
 * @return  BAD_FUNC_ARG when ssl or spki is NULL, or spkiSz is 0.
504
 * @return  BUFFER_E when the pin table is full (WOLFSSL_MAX_RPK_PINS reached).
505
 * @return  Other negative error code on hashing failure.
506
 */
507
int wolfSSL_set_expected_rpk(WOLFSSL* ssl, const unsigned char* spki,
508
    unsigned int spkiSz)
509
{
510
    int ret;
511
512
    if (ssl == NULL) {
513
        return BAD_FUNC_ARG;
514
    }
515
    ret = rpk_add_expected(&ssl->options.rpkConfig, spki, spkiSz);
516
    return (ret == 0) ? WOLFSSL_SUCCESS : ret;
517
}
518
519
/* Remove all pinned expected peer Raw Public Keys from the SSL/TLS CTX object,
520
 * so the table can be repopulated (e.g. across a peer key rotation).
521
 *
522
 * @param [in] ctx  SSL/TLS CTX object.
523
 * @return  WOLFSSL_SUCCESS on success.
524
 * @return  BAD_FUNC_ARG when ctx is NULL.
525
 */
526
int wolfSSL_CTX_clear_expected_rpk(WOLFSSL_CTX* ctx)
527
{
528
    if (ctx == NULL) {
529
        return BAD_FUNC_ARG;
530
    }
531
    ctx->rpkConfig.expectedRpkCnt = 0;
532
    return WOLFSSL_SUCCESS;
533
}
534
535
/* Remove all pinned expected peer Raw Public Keys from the SSL/TLS object, so
536
 * the table can be repopulated (e.g. across a peer key rotation).
537
 *
538
 * @param [in, out] ssl  SSL/TLS object.
539
 * @return  WOLFSSL_SUCCESS on success.
540
 * @return  BAD_FUNC_ARG when ssl is NULL.
541
 */
542
int wolfSSL_clear_expected_rpk(WOLFSSL* ssl)
543
{
544
    if (ssl == NULL) {
545
        return BAD_FUNC_ARG;
546
    }
547
    ssl->options.rpkConfig.expectedRpkCnt = 0;
548
    return WOLFSSL_SUCCESS;
549
}
550
#endif /* !NO_SHA256 */
551
#endif /* HAVE_RPK */
552
553
/* Certificate verification options. */
554
typedef struct {
555
    /* Verify the peer certificate. */
556
    byte verifyPeer:1;
557
    /* No peer certificate verification. */
558
    byte verifyNone:1;
559
    /* Fail when no peer certificate seen. */
560
    byte failNoCert:1;
561
    /* Fail when no peer certificate except when PSK handshake performed. */
562
    byte failNoCertxPSK:1;
563
    #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
564
    /* Verify peer certificate post handshake. */
565
    byte verifyPostHandshake:1;
566
    #endif
567
} SetVerifyOptions;
568
569
/* Convert the mode flags into certificate verification options.
570
 *
571
 * WOLFSSL_VERIFY_CLIENT_ONCE is accepted and deliberately ignored - it has no
572
 * corresponding option here, is not stored anywhere, and therefore cannot be
573
 * read back by wolfSSL_[CTX_]get_verify_mode(). See the note on the enumerator
574
 * in wolfssl/ssl.h.
575
 *
576
 * Note that WOLFSSL_VERIFY_NONE is matched by equality, not as a bit: a mode
577
 * of (WOLFSSL_VERIFY_NONE | WOLFSSL_VERIFY_PEER) verifies the peer.
578
 *
579
 * @param [in] mode  Certificate verification mode flags.
580
 * @return  Certificate verification options.
581
 */
582
static SetVerifyOptions ModeToVerifyOptions(int mode)
583
{
584
    SetVerifyOptions opts;
585
586
    /* Set the options to the default - none set. */
587
    XMEMSET(&opts, 0, sizeof(SetVerifyOptions));
588
589
    /* When the mode is not default - set the options. */
590
    if (mode != WOLFSSL_VERIFY_DEFAULT) {
591
        opts.verifyNone = (mode == WOLFSSL_VERIFY_NONE);
592
        /* When not no verification, set the chosen options. */
593
        if (!opts.verifyNone) {
594
            opts.verifyPeer          =
595
                    (mode & WOLFSSL_VERIFY_PEER) != 0;
596
            opts.failNoCertxPSK      =
597
                    (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) != 0;
598
            opts.failNoCert          =
599
                    (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) != 0;
600
            /* Both only fail a certificate that was asked for, so they imply
601
             * asking. */
602
            if (opts.failNoCert || opts.failNoCertxPSK) {
603
                opts.verifyPeer = 1;
604
            }
605
            #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
606
            opts.verifyPostHandshake =
607
                    (mode & WOLFSSL_VERIFY_POST_HANDSHAKE) != 0;
608
            #endif
609
        }
610
    }
611
612
    return opts;
613
}
614
615
/* Set the verification options against the SSL/TLS context.
616
 *
617
 * @param [in] ctx              SSL/TLS context object.
618
 * @param [in] mode             Verification mode options.
619
 * @param [in] verify_callback  Verification callback.
620
 */
621
WOLFSSL_ABI
622
void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode,
623
    VerifyCallback verify_callback)
624
28
{
625
28
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
626
627
    /* Ensure we have an SSL/TLS context to work with. */
628
28
    if (ctx != NULL) {
629
28
        SetVerifyOptions opts = ModeToVerifyOptions(mode);
630
631
        /* Set the bitfield options. */
632
28
        ctx->verifyNone     = opts.verifyNone;
633
28
        ctx->verifyPeer     = opts.verifyPeer;
634
28
        ctx->failNoCert     = opts.failNoCert;
635
28
        ctx->failNoCertxPSK = opts.failNoCertxPSK;
636
        #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
637
        ctx->verifyPostHandshake = opts.verifyPostHandshake;
638
        #endif
639
640
        /* Store the user verification callback against the context. */
641
28
        ctx->verifyCallback = verify_callback;
642
28
    }
643
28
}
644
645
#ifdef OPENSSL_ALL
646
/* Set certificate verification callback and context against SSL/TLS context.
647
 *
648
 * @param [in] ctx  SSL/TLS context object.
649
 * @param [in] cb   Certificate verification callback.
650
 * @param [in] arg  Context for certification verification callback.
651
 */
652
void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx,
653
    CertVerifyCallback cb, void* arg)
654
{
655
    WOLFSSL_ENTER("wolfSSL_CTX_set_cert_verify_callback");
656
657
    /* Ensure we have an SSL/TLS context to work with. */
658
    if (ctx != NULL) {
659
        ctx->verifyCertCb = cb;
660
        ctx->verifyCertCbArg = arg;
661
    }
662
}
663
#endif
664
665
#ifdef WOLFSSL_CHAIN_VERIFY_CB
666
/* Set the callback that replaces peer certificate chain verification for
667
 * every SSL/TLS object created from the context.
668
 *
669
 * Setting a callback turns off all of wolfSSL's own checking of the peer's
670
 * certificates. See ChainVerifyCb in ssl.h.
671
 *
672
 * @param [in, out] ctx  SSL/TLS context object.
673
 * @param [in]      cb   Chain verification callback. NULL to clear.
674
 * @return  WOLFSSL_SUCCESS on success.
675
 * @return  BAD_FUNC_ARG when ctx is NULL.
676
 * @return  CHAIN_VERIFY_UNSUPPORTED_E when the context uses DTLS, raw public
677
 *          keys or OCSP stapling.
678
 */
679
int wolfSSL_CTX_SetChainVerifyCb(WOLFSSL_CTX* ctx, ChainVerifyCb cb)
680
{
681
    int ret;
682
683
    WOLFSSL_ENTER("wolfSSL_CTX_SetChainVerifyCb");
684
685
    if (ctx == NULL)
686
        return BAD_FUNC_ARG;
687
688
    if (cb != NULL) {
689
        ret = ChainVerifyCbCheckCtx(ctx);
690
        if (ret != 0)
691
            return ret;
692
    }
693
    ctx->chainVerifyCb = cb;
694
695
    return WOLFSSL_SUCCESS;
696
}
697
698
/* Set the callback that replaces peer certificate chain verification for one
699
 * SSL/TLS object. Takes precedence over the context's callback.
700
 *
701
 * @param [in, out] ssl  SSL/TLS object.
702
 * @param [in]      cb   Chain verification callback. NULL to fall back to the
703
 *                       context's.
704
 * @return  WOLFSSL_SUCCESS on success.
705
 * @return  BAD_FUNC_ARG when ssl is NULL.
706
 * @return  CHAIN_VERIFY_UNSUPPORTED_E when the object uses DTLS, raw public
707
 *          keys or OCSP stapling.
708
 */
709
int wolfSSL_SetChainVerifyCb(WOLFSSL* ssl, ChainVerifyCb cb)
710
{
711
    int ret;
712
713
    WOLFSSL_ENTER("wolfSSL_SetChainVerifyCb");
714
715
    if (ssl == NULL)
716
        return BAD_FUNC_ARG;
717
718
    if (cb != NULL) {
719
        ret = ChainVerifyCbCheckSsl(ssl);
720
        if (ret != 0)
721
            return ret;
722
    }
723
    ssl->chainVerifyCb = cb;
724
725
    return WOLFSSL_SUCCESS;
726
}
727
728
/* Set the user context passed to the chain verification callback for every
729
 * SSL/TLS object created from the context.
730
 *
731
 * @param [in, out] ctx      SSL/TLS context object.
732
 * @param [in]      userCtx  User context.
733
 */
734
void wolfSSL_CTX_SetChainVerifyCtx(WOLFSSL_CTX* ctx, void* userCtx)
735
{
736
    WOLFSSL_ENTER("wolfSSL_CTX_SetChainVerifyCtx");
737
738
    if (ctx != NULL) {
739
        ctx->chainVerifyCtx = userCtx;
740
    }
741
}
742
743
/* Set the user context passed to the chain verification callback for one
744
 * SSL/TLS object. Takes precedence over the context's.
745
 *
746
 * @param [in, out] ssl  SSL/TLS object.
747
 * @param [in]      ctx  User context. NULL to fall back to the context's.
748
 */
749
void wolfSSL_SetChainVerifyCtx(WOLFSSL* ssl, void* ctx)
750
{
751
    WOLFSSL_ENTER("wolfSSL_SetChainVerifyCtx");
752
753
    if (ssl != NULL) {
754
        ssl->chainVerifyCtx = ctx;
755
    }
756
}
757
758
/* Get the user context the chain verification callback is called with: the
759
 * SSL/TLS object's when set, otherwise the context's.
760
 *
761
 * @param [in] ssl  SSL/TLS object.
762
 * @return  User context, or NULL when none set or ssl is NULL.
763
 */
764
void* wolfSSL_GetChainVerifyCtx(const WOLFSSL* ssl)
765
{
766
    WOLFSSL_ENTER("wolfSSL_GetChainVerifyCtx");
767
768
    if (ssl != NULL) {
769
        if (ssl->chainVerifyCtx != NULL) {
770
            return ssl->chainVerifyCtx;
771
        }
772
        return ssl->ctx->chainVerifyCtx;
773
    }
774
775
    return NULL;
776
}
777
#endif /* WOLFSSL_CHAIN_VERIFY_CB */
778
779
/* Set the verification options against the SSL/TLS object.
780
 *
781
 * @param [in, out] ssl              SSL/TLS object.
782
 * @param [in]      mode             Verification mode options.
783
 * @param [in]      verify_callback  Verification callback.
784
 */
785
void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback verify_callback)
786
0
{
787
0
    WOLFSSL_ENTER("wolfSSL_set_verify");
788
789
    /* Ensure we have an SSL/TLS object to work with. */
790
0
    if (ssl != NULL) {
791
0
        SetVerifyOptions opts = ModeToVerifyOptions(mode);
792
793
        /* Set the bitfield options. */
794
0
        ssl->options.verifyNone = opts.verifyNone;
795
0
        ssl->options.verifyPeer = opts.verifyPeer;
796
0
        ssl->options.failNoCert = opts.failNoCert;
797
0
        ssl->options.failNoCertxPSK = opts.failNoCertxPSK;
798
        #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
799
        ssl->options.verifyPostHandshake = opts.verifyPostHandshake;
800
        #endif
801
802
        /* Store the user verification callback against the object. */
803
0
        ssl->verifyCallback = verify_callback;
804
0
    }
805
0
}
806
807
/* Set the certificate verification result for the SSL/TLS object.
808
 *
809
 * @param [in, out] ssl  SSL/TLS object.
810
 * @param [in]      v    Verification result.
811
 */
812
void wolfSSL_set_verify_result(WOLFSSL *ssl, long v)
813
0
{
814
0
    WOLFSSL_ENTER("wolfSSL_set_verify_result");
815
816
    /* Ensure we have an SSL/TLS object to work with. */
817
0
    if (ssl != NULL) {
818
        #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
819
        ssl->peerVerifyRet = (unsigned long)v;
820
        #else
821
0
        WOLFSSL_STUB("wolfSSL_set_verify_result");
822
0
        (void)v;
823
0
        #endif
824
0
    }
825
0
}
826
827
/* Store user ctx for verify callback into SSL/TLS context.
828
 *
829
 * @param [in] ctx      SSL/TLS context.
830
 * @param [in] userCtx  User context for verify callback.
831
 */
832
void wolfSSL_CTX_SetCertCbCtx(WOLFSSL_CTX* ctx, void* userCtx)
833
0
{
834
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetCertCbCtx");
835
836
    /* Validate parameters. */
837
0
    if (ctx != NULL) {
838
0
        ctx->verifyCbCtx = userCtx;
839
0
    }
840
0
}
841
842
/* Store user ctx for verify callback into SSL/TLS object.
843
 *
844
 * @param [in, out] ssl  SSL/TLS object.
845
 * @param [in]      ctx  User context for verify callback.
846
 */
847
void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
848
0
{
849
0
    WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
850
851
    /* Validate parameters. */
852
0
    if (ssl != NULL) {
853
0
        ssl->verifyCbCtx = ctx;
854
0
    }
855
0
}
856
857
858
859
/* Set the callback called when a CA is added to the cache.
860
 *
861
 * @param [in, out] ctx  SSL/TLS context.
862
 * @param [in]      cb   Callback to call. NULL to clear.
863
 */
864
void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
865
0
{
866
    /* Validate parameters. */
867
0
    if ((ctx != NULL) && (ctx->cm != NULL)) {
868
0
        ctx->cm->caCacheCallback = cb;
869
0
    }
870
0
}
871
872
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && \
873
    defined(WOLFSSL_POST_HANDSHAKE_AUTH)
874
/* For TLS v1.3, send authentication messages after handshake completes.
875
 *
876
 * @param [in, out] ssl  SSL/TLS object.
877
 * @return  1 on success.
878
 * @return  UNSUPPORTED_PROTO_VERSION when not a TLSv1.3 handshake.
879
 * @return  0 on other failure.
880
 */
881
int wolfSSL_verify_client_post_handshake(WOLFSSL* ssl)
882
{
883
    int ret;
884
885
    /* Do request of certificate. */
886
    ret = wolfSSL_request_certificate(ssl);
887
    if (ret != 1) {
888
        /* Special logging for wrong protocol version. */
889
        if ((ssl != NULL) && (!IsAtLeastTLSv1_3(ssl->version))) {
890
            WOLFSSL_ERROR(UNSUPPORTED_PROTO_VERSION);
891
        }
892
        else {
893
            /* Other errors - return 0. */
894
            WOLFSSL_ERROR(ret);
895
        }
896
        ret = 0;
897
    }
898
899
    return ret;
900
}
901
902
/* Set whether handshakes from this SSL/TLS context allow auth post handshake.
903
 *
904
 * @param [in] ctx  SSL/TLS context.
905
 * @param [in] val  Whether to allow post handshake authentication.
906
 * @return  1 on success.
907
 * @return  0 on failure.
908
 */
909
int wolfSSL_CTX_set_post_handshake_auth(WOLFSSL_CTX* ctx, int val)
910
{
911
    int ret;
912
913
    /* Try to allow - really just checking conditions. */
914
    if (wolfSSL_CTX_allow_post_handshake_auth(ctx) == 0) {
915
        /* Set value as a bit. */
916
        ctx->postHandshakeAuth = (val != 0);
917
        ret = 1;
918
    }
919
    else {
920
        ret = 0;
921
    }
922
923
    return ret;
924
}
925
/* Set whether handshakes with this SSL/TLS object allow auth post handshake.
926
 *
927
 * @param [in, out] ssl  SSL/TLS object.
928
 * @param [in]      val  Whether to allow post handshake authentication.
929
 * @return  1 on success.
930
 * @return  0 on failure.
931
 */
932
int wolfSSL_set_post_handshake_auth(WOLFSSL* ssl, int val)
933
{
934
    int ret;
935
936
    /* Try to allow - really just checking conditions. */
937
    if (wolfSSL_allow_post_handshake_auth(ssl) == 0) {
938
        /* Set value as a bit. */
939
        ssl->options.postHandshakeAuth = (val != 0);
940
        ret = 1;
941
    }
942
    else {
943
        ret = 0;
944
    }
945
946
    return ret;
947
}
948
#endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
949
950
#if defined(PERSIST_CERT_CACHE)
951
952
#if !defined(NO_FILESYSTEM)
953
954
/* Persist certificate cache in SSL/TLS context to file.
955
 *
956
 * @param [in] ctx    SSL/TLS context.
957
 * @param [in] fname  Filename so store certificate cache to.
958
 * @return  1 on success.
959
 * @return  BAD_FUNC_ARG when ctx or fname is NULL.
960
 * @return  Other values on failure.
961
 */
962
int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
963
{
964
    int ret;
965
966
    WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
967
968
    /* Validate parameters. */
969
    if ((ctx == NULL) || (fname == NULL)) {
970
        ret = BAD_FUNC_ARG;
971
    }
972
    else {
973
        /* Save certificate cache. */
974
        ret = CM_SaveCertCache(ctx->cm, fname);
975
    }
976
977
    return ret;
978
}
979
980
981
/* Load certificate cache into SSL/TLS context from file.
982
 *
983
 * @param [in] ctx    SSL/TLS context.
984
 * @param [in] fname  Filename so store certificate cache to.
985
 * @return  1 on success.
986
 * @return  BAD_FUNC_ARG when ctx or fname is NULL.
987
 * @return  Other values on failure.
988
 */
989
int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
990
{
991
    int ret;
992
993
    WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
994
995
    /* Validate parameters. */
996
    if ((ctx == NULL) || (fname == NULL)) {
997
        ret = BAD_FUNC_ARG;
998
    }
999
    else {
1000
        /* Restore certificate cache. */
1001
        ret = CM_RestoreCertCache(ctx->cm, fname);
1002
    }
1003
1004
    return ret;
1005
}
1006
1007
#endif /* NO_FILESYSTEM */
1008
1009
/* Persist certificate cache in SSL/TLS context to memory.
1010
 *
1011
 * @param [in]  ctx   SSL/TLS context.
1012
 * @param [in]  mem   Memory to fill with certificate cache.
1013
 * @param [in]  sz    Size of memory to fill in bytes.
1014
 * @param [out] used  The number of bytes of memory used.
1015
 * @return  1 on success.
1016
 * @return  BAD_FUNC_ARG when ctx, mem or used is NULL.
1017
 * @return  BAD_FUNC_ARG when sz is less than or equal to zero.
1018
 * @return  Other values on failure.
1019
 */
1020
int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
1021
                                   int sz, int* used)
1022
{
1023
    int ret;
1024
1025
    WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
1026
1027
    /* Validate parameters. */
1028
    if ((ctx == NULL) || (mem == NULL) || (used == NULL) || (sz <= 0)) {
1029
        ret = BAD_FUNC_ARG;
1030
    }
1031
    else {
1032
        /* Persist certificate change to memory. */
1033
        ret = CM_MemSaveCertCache(ctx->cm, mem, sz, used);
1034
    }
1035
1036
    return ret;
1037
}
1038
1039
1040
/* Load certificate cache into SSL/TLS context from memory.
1041
 *
1042
 * @param [in] ctx  SSL/TLS context.
1043
 * @param [in] mem  Memory with certificate cache.
1044
 * @param [in] sz   Size of certificate cache in bytes
1045
 * @return  1 on success.
1046
 * @return  BAD_FUNC_ARG when ctx or mem is NULL.
1047
 * @return  BAD_FUNC_ARG when sz is less than or equal to zero.
1048
 * @return  Other values on failure.
1049
 */
1050
int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
1051
{
1052
    int ret;
1053
1054
    WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
1055
1056
    /* Validate parameters. */
1057
    if ((ctx == NULL) || (mem == NULL) || (sz <= 0)) {
1058
        ret = BAD_FUNC_ARG;
1059
    }
1060
    else {
1061
        /* Restore certificate cache. */
1062
        ret = CM_MemRestoreCertCache(ctx->cm, mem, sz);
1063
    }
1064
1065
    return ret;
1066
}
1067
1068
1069
/* Get size of certificate cache when persisted.
1070
 *
1071
 * @param [in] ctx  SSL/TLS context.
1072
 * @return  Size of certificate cache when pesisted in bytes.
1073
 * @return  BAD_FUNC_ARG when ctx is NULL.
1074
 */
1075
int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
1076
{
1077
    int ret;
1078
1079
    WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
1080
1081
    /* Validate parameter. */
1082
    if (ctx == NULL) {
1083
        ret = BAD_FUNC_ARG;
1084
    }
1085
    else {
1086
        /* Get size. */
1087
        ret = CM_GetCertCacheMemSize(ctx->cm);
1088
    }
1089
1090
    return ret;
1091
}
1092
1093
#endif /* PERSIST_CERT_CACHE */
1094
1095
/* Unload certificates and keys that the SSL/TLS object owns.
1096
 *
1097
 * The WOLFSSL_CTX referenced is untouched.
1098
 *
1099
 * @param [in, out] ssl  SSL/TLS object.
1100
 * @return  1 on success.
1101
 * @return  BAD_FUNC_ARG when ssl is NULL.
1102
 */
1103
int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
1104
66.2k
{
1105
66.2k
    int ret = 1;
1106
1107
    /* Validate parameter. */
1108
66.2k
    if (ssl == NULL) {
1109
0
        WOLFSSL_MSG("Null function arg");
1110
0
        ret = BAD_FUNC_ARG;
1111
0
    }
1112
66.2k
    else {
1113
66.2k
        if (ssl->buffers.weOwnCert && (!ssl->keepCert)) {
1114
55.7k
            WOLFSSL_MSG("Unloading cert");
1115
55.7k
            FreeDer(&ssl->buffers.certificate);
1116
            #ifdef KEEP_OUR_CERT
1117
            wolfSSL_X509_free(ssl->ourCert);
1118
            ssl->ourCert = NULL;
1119
            #endif
1120
55.7k
            ssl->buffers.weOwnCert = 0;
1121
55.7k
        }
1122
1123
66.2k
        if (ssl->buffers.weOwnCertChain) {
1124
0
            WOLFSSL_MSG("Unloading cert chain");
1125
0
            FreeDer(&ssl->buffers.certChain);
1126
0
            ssl->buffers.weOwnCertChain = 0;
1127
0
        }
1128
1129
        /* FreeKeyDer() zeroes the key when the last holder lets go of it. It
1130
         * can be shared with the CTX (WOLFSSL_DER_REFCOUNT), so it must not
1131
         * be zeroed here. */
1132
66.2k
        if (ssl->buffers.weOwnKey) {
1133
55.7k
            WOLFSSL_MSG("Unloading key");
1134
55.7k
            FreeKeyDer(&ssl->buffers.key);
1135
            #ifdef WOLFSSL_BLIND_PRIVATE_KEY
1136
            FreeDer(&ssl->buffers.keyMask);
1137
            #endif
1138
55.7k
            ssl->buffers.weOwnKey = 0;
1139
55.7k
        }
1140
1141
        #ifdef WOLFSSL_DUAL_ALG_CERTS
1142
        if (ssl->buffers.weOwnAltKey) {
1143
            WOLFSSL_MSG("Unloading alt key");
1144
            FreeKeyDer(&ssl->buffers.altKey);
1145
            #ifdef WOLFSSL_BLIND_PRIVATE_KEY
1146
            FreeDer(&ssl->buffers.altKeyMask);
1147
            #endif
1148
            ssl->buffers.weOwnAltKey = 0;
1149
        }
1150
        #endif /* WOLFSSL_DUAL_ALG_CERTS */
1151
66.2k
    }
1152
1153
66.2k
    return ret;
1154
66.2k
}
1155
1156
/* Unload CAs from the certificate manager of the SSL/TLS context.
1157
 *
1158
 * @param [in] ctx  SSL/TLS context.
1159
 * @return  1 on success.
1160
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
1161
 * @return  BAD_MUTEX_E when locking fails.
1162
 */
1163
int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
1164
0
{
1165
0
    int ret;
1166
1167
0
    WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
1168
1169
    /* Validate parameter. */
1170
0
    if (ctx == NULL) {
1171
0
        ret = BAD_FUNC_ARG;
1172
0
    }
1173
0
    else {
1174
0
        ret = wolfSSL_CertManagerUnloadCAs(ctx->cm);
1175
0
    }
1176
1177
0
    return ret;
1178
0
}
1179
1180
/* Unload Intermediate CAs from the certificate manager of the SSL/TLS context.
1181
 *
1182
 * @param [in] ctx  SSL/TLS context.
1183
 * @return  1 on success.
1184
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
1185
 * @return  BAD_STATE_E when another reference to the context is held.
1186
 * @return  BAD_MUTEX_E when locking fails.
1187
 */
1188
int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx)
1189
0
{
1190
0
    int ret;
1191
1192
0
    WOLFSSL_ENTER("wolfSSL_CTX_UnloadIntermediateCerts");
1193
1194
    /* Validate parameter. */
1195
0
    if (ctx == NULL) {
1196
0
        ret = BAD_FUNC_ARG;
1197
0
    }
1198
    /* Lock reference count. */
1199
0
    else if ((ret = wolfSSL_RefWithMutexLock(&ctx->ref)) == 0) {
1200
        /* Must not have another reference for this operation to be done. */
1201
0
        if (ctx->ref.count > 1) {
1202
0
            WOLFSSL_MSG("ctx object must have a ref count of 1 before "
1203
0
                        "unloading intermediate certs");
1204
0
            ret = BAD_STATE_E;
1205
0
        }
1206
0
        else {
1207
0
            ret = wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
1208
0
        }
1209
1210
        /* Unlock reference count. */
1211
0
        if (wolfSSL_RefWithMutexUnlock(&ctx->ref) != 0) {
1212
0
            WOLFSSL_MSG("Failed to unlock mutex!");
1213
0
        }
1214
0
    }
1215
1216
0
    return ret;
1217
0
}
1218
1219
1220
#ifdef WOLFSSL_TRUST_PEER_CERT
1221
/* Unload trusted peers from the certificate manager of the SSL/TLS context.
1222
 *
1223
 * @param [in] ctx  SSL/TLS context.
1224
 * @return  1 on success.
1225
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
1226
 * @return  BAD_MUTEX_E when locking fails.
1227
 */
1228
int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
1229
{
1230
    int ret;
1231
1232
    WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
1233
1234
    /* Validate parameter. */
1235
    if (ctx == NULL) {
1236
        ret = BAD_FUNC_ARG;
1237
    }
1238
    else {
1239
        ret = wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
1240
    }
1241
1242
    return ret;
1243
}
1244
1245
#ifdef WOLFSSL_LOCAL_X509_STORE
1246
/* Unload trusted peers from the certificate manager of the SSL/TLS object.
1247
 *
1248
 * @param [in, out] ssl  SSL/TLS object.
1249
 * @return  1 on success.
1250
 * @return  BAD_FUNC_ARG when ssl is NULL.
1251
 * @return  BAD_MUTEX_E when locking fails.
1252
 */
1253
int wolfSSL_Unload_trust_peers(WOLFSSL* ssl)
1254
{
1255
    int ret;
1256
1257
    WOLFSSL_ENTER("wolfSSL_Unload_trust_peers");
1258
1259
    /* Validate parameter. */
1260
    if (ssl == NULL) {
1261
        ret = BAD_FUNC_ARG;
1262
    }
1263
    else {
1264
        /* Output message when certificate manager for object. */
1265
        SSL_CM_WARNING(ssl);
1266
        return wolfSSL_CertManagerUnload_trust_peers(SSL_CM(ssl));
1267
    }
1268
1269
    return ret;
1270
}
1271
#endif /* WOLFSSL_LOCAL_X509_STORE */
1272
#endif /* WOLFSSL_TRUST_PEER_CERT */
1273
1274
#if !defined(WOLFSSL_NO_CA_NAMES) && defined(OPENSSL_EXTRA)
1275
/* Add a CA certificate to the list of CA names.
1276
 *
1277
 * @param [in, out] ca_names  List of CA certificate subject names.
1278
 * @param [in]      x509      X509 certificate.
1279
 * @return  1 on success.
1280
 * @return  0 on failure.
1281
 */
1282
static int add_to_ca_names_list(WOLFSSL_STACK* ca_names, WOLFSSL_X509* x509)
1283
{
1284
    int ret = 1;
1285
    WOLFSSL_X509_NAME *nameCopy = NULL;
1286
1287
    /* The list owns its names, so push a copy of the subject name. */
1288
    nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(x509));
1289
    if (nameCopy == NULL) {
1290
        WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
1291
        ret = 0;
1292
    }
1293
    /* On push failure the copy is not owned by the list - free it here. */
1294
    else if (wolfSSL_sk_X509_NAME_push(ca_names, nameCopy) <= 0) {
1295
        WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
1296
        wolfSSL_X509_NAME_free(nameCopy);
1297
        ret = 0;
1298
    }
1299
1300
    return ret;
1301
}
1302
1303
/* Add a client's CA to SSL/TLS context.
1304
 *
1305
 * @param [in] ctx   SSL/TLS context.
1306
 * @param [in] x509  X509 certificate.
1307
 * @return  1 on success.
1308
 * @return  0 on failure.
1309
 */
1310
int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
1311
{
1312
    int ret = 1;
1313
1314
    WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
1315
1316
    /* Validate parameters. */
1317
    if ((ctx == NULL) || (x509 == NULL)) {
1318
        WOLFSSL_MSG("Bad argument");
1319
        ret = 0;
1320
    }
1321
    /* Create a stack of names if not present. */
1322
    else if (ctx->client_ca_names == NULL) {
1323
        ctx->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1324
        if (ctx->client_ca_names == NULL) {
1325
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1326
            ret = 0;
1327
        }
1328
    }
1329
    if (ret == 1) {
1330
        /* Add certificate's subject name to client CA name list. */
1331
        ret = add_to_ca_names_list(ctx->client_ca_names, x509);
1332
    }
1333
1334
    return ret;
1335
}
1336
1337
/* Add a client's CA to SSL/TLS object.
1338
 *
1339
 * @param [in, out] ssl   SSL/TLS object.
1340
 * @param [in]      x509  X509 certificate.
1341
 * @return  1 on success.
1342
 * @return  0 on failure.
1343
 */
1344
int wolfSSL_add_client_CA(WOLFSSL* ssl, WOLFSSL_X509* x509)
1345
{
1346
    int ret = 1;
1347
1348
    WOLFSSL_ENTER("wolfSSL_add_client_CA");
1349
1350
    /* Validate parameters. */
1351
    if ((ssl == NULL) || (x509 == NULL)) {
1352
        WOLFSSL_MSG("Bad argument");
1353
        ret = 0;
1354
    }
1355
    /* Create a stack of names if not present. */
1356
    else if (ssl->client_ca_names == NULL) {
1357
        ssl->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1358
        if (ssl->client_ca_names == NULL) {
1359
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1360
            ret = 0;
1361
        }
1362
    }
1363
    if (ret == 1) {
1364
        /* Add certificate's subject name to client CA name list. */
1365
        ret = add_to_ca_names_list(ssl->client_ca_names, x509);
1366
    }
1367
1368
    return ret;
1369
}
1370
1371
/* Add a CA to SSL/TLS context.
1372
 *
1373
 * @param [in] ctx   SSL/TLS context.
1374
 * @param [in] x509  X509 certificate.
1375
 * @return  1 on success.
1376
 * @return  0 on failure.
1377
 */
1378
int wolfSSL_CTX_add1_to_CA_list(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
1379
{
1380
    int ret = 1;
1381
1382
    WOLFSSL_ENTER("wolfSSL_CTX_add1_to_CA_list");
1383
1384
    /* Validate parameters. */
1385
    if ((ctx == NULL) || (x509 == NULL)) {
1386
        WOLFSSL_MSG("Bad argument");
1387
        ret = 0;
1388
    }
1389
    /* Create a stack of names if not present. */
1390
    else if (ctx->ca_names == NULL) {
1391
        ctx->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1392
        if (ctx->ca_names == NULL) {
1393
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1394
            ret = 0;
1395
        }
1396
    }
1397
    if (ret == 1) {
1398
        /* Add certificate's subject name to CA name list. */
1399
        ret = add_to_ca_names_list(ctx->ca_names, x509);
1400
    }
1401
1402
    return ret;
1403
}
1404
1405
/* Add a CA to SSL/TLS object.
1406
 *
1407
 * @param [in, out] ssl   SSL/TLS object.
1408
 * @param [in]      x509  X509 certificate.
1409
 * @return  1 on success.
1410
 * @return  0 on failure.
1411
 */
1412
int wolfSSL_add1_to_CA_list(WOLFSSL* ssl, WOLFSSL_X509* x509)
1413
{
1414
    int ret = 1;
1415
1416
    WOLFSSL_ENTER("wolfSSL_add1_to_CA_list");
1417
1418
    /* Validate parameters. */
1419
    if ((ssl == NULL) || (x509 == NULL)) {
1420
        WOLFSSL_MSG("Bad argument");
1421
        ret = 0;
1422
    }
1423
    /* Create a stack of names if not present. */
1424
    else if (ssl->ca_names == NULL) {
1425
        ssl->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1426
        if (ssl->ca_names == NULL) {
1427
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1428
            ret = 0;
1429
        }
1430
    }
1431
    if (ret == 1) {
1432
        /* Add certificate's subject name to CA name list. */
1433
        ret = add_to_ca_names_list(ssl->ca_names, x509);
1434
    }
1435
1436
    return ret;
1437
}
1438
1439
/* Set the client CA list into SSL/TLS context.
1440
 *
1441
 * @param [in] ctx    SSL/TLS context.
1442
 * @param [in] names  List of CA subject names.
1443
 */
1444
void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
1445
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1446
{
1447
    WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
1448
1449
    /* Validate parameters. */
1450
    if (ctx != NULL) {
1451
        /* Dispose of any existing list. */
1452
        wolfSSL_sk_X509_NAME_pop_free(ctx->client_ca_names, NULL);
1453
        /* Take ownership of names list. */
1454
        ctx->client_ca_names = names;
1455
    }
1456
}
1457
1458
/* Set the client CA list into SSL/TLS object.
1459
 *
1460
 * @param [in] ssl    SSL/TLS object.
1461
 * @param [in] names  List of CA subject names.
1462
 */
1463
void wolfSSL_set_client_CA_list(WOLFSSL* ssl,
1464
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1465
{
1466
    WOLFSSL_ENTER("wolfSSL_set_client_CA_list");
1467
1468
    /* Validate parameters. */
1469
    if (ssl != NULL) {
1470
        /* Dispose of any existing list if the object owns it. */
1471
        if (ssl->client_ca_names != ssl->ctx->client_ca_names) {
1472
            wolfSSL_sk_X509_NAME_pop_free(ssl->client_ca_names, NULL);
1473
        }
1474
        /* Take ownership of names list. */
1475
        ssl->client_ca_names = names;
1476
    }
1477
}
1478
1479
/* Set the CA list into SSL/TLS context.
1480
 *
1481
 * @param [in] ctx    SSL/TLS context.
1482
 * @param [in] names  List of CA subject names.
1483
 */
1484
void wolfSSL_CTX_set0_CA_list(WOLFSSL_CTX* ctx,
1485
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1486
{
1487
    WOLFSSL_ENTER("wolfSSL_CTX_set0_CA_list");
1488
1489
    /* Validate parameters. */
1490
    if (ctx != NULL) {
1491
        /* Dispose of any existing list. */
1492
        wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
1493
        /* Take ownership of names list. */
1494
        ctx->ca_names = names;
1495
    }
1496
}
1497
1498
/* Set the client CA list into SSL/TLS object.
1499
 *
1500
 * @param [in] ssl    SSL/TLS object.
1501
 * @param [in] names  List of CA subject names.
1502
 */
1503
void wolfSSL_set0_CA_list(WOLFSSL* ssl,
1504
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1505
{
1506
    WOLFSSL_ENTER("wolfSSL_set0_CA_list");
1507
1508
    /* Validate parameters. */
1509
    if (ssl != NULL) {
1510
        /* Dispose of any existing list if the object owns it. */
1511
        if (ssl->ca_names != ssl->ctx->ca_names) {
1512
            wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
1513
        }
1514
        /* Take ownership of names list. */
1515
        ssl->ca_names = names;
1516
    }
1517
}
1518
1519
/* Get the list of client CA subject names from the SSL/TLS context.
1520
 *
1521
 * @param [in] ctx  SSL/TLS context.
1522
 * @return  List of CA subject names on success.
1523
 * @return  NULL when ctx is NULL or no names set.
1524
 */
1525
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
1526
        const WOLFSSL_CTX *ctx)
1527
{
1528
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1529
1530
    WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list");
1531
1532
    /* Validate parameter. */
1533
    if (ctx == NULL) {
1534
        WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get_client_CA_list");
1535
        ret = NULL;
1536
    }
1537
    else {
1538
        ret = ctx->client_ca_names;
1539
    }
1540
1541
    return ret;
1542
}
1543
1544
/* Get the list of client CA subject names from the SSL/TLS object.
1545
 *
1546
 * On server side: returns the CAs set via *_set_client_CA_list();
1547
 * On client side: returns the CAs received from server -- same as
1548
 * wolfSSL_get0_peer_CA_list().
1549
 *
1550
 * @param [in] ssl  SSL/TLS object.
1551
 * @return  List of CA subject names on success.
1552
 * @return  NULL when ssl is NULL or no names set.
1553
 */
1554
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list(const WOLFSSL* ssl)
1555
{
1556
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1557
1558
    WOLFSSL_ENTER("wolfSSL_get_client_CA_list");
1559
1560
    /* Validate parameter. */
1561
    if (ssl == NULL) {
1562
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get_client_CA_list");
1563
        ret = NULL;
1564
    }
1565
    /* Client side return peer CA names. */
1566
    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
1567
        ret = ssl->peer_ca_names;
1568
    }
1569
    /* Server side return client CA names. */
1570
    else {
1571
        ret = SSL_CLIENT_CA_NAMES(ssl);
1572
    }
1573
1574
    return ret;
1575
}
1576
1577
/* Get the list of CA subject names from the SSL/TLS context.
1578
 *
1579
 * @param [in] ctx  SSL/TLS context.
1580
 * @return  List of CA subject names on success.
1581
 * @return  NULL when ctx is NULL or no names set.
1582
 */
1583
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get0_CA_list(
1584
    const WOLFSSL_CTX *ctx)
1585
{
1586
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1587
1588
    WOLFSSL_ENTER("wolfSSL_CTX_get0_CA_list");
1589
1590
    /* Validate parameter. */
1591
    if (ctx == NULL) {
1592
        WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get0_CA_list");
1593
        ret = NULL;
1594
    }
1595
    else {
1596
        /* Return list directly. */
1597
        ret = ctx->ca_names;
1598
    }
1599
1600
    return ret;
1601
}
1602
1603
/* Get the list of CA subject names from the SSL/TLS object.
1604
 *
1605
 * Always returns the CA's set via *_set0_CA_list.
1606
 *
1607
 * @param [in] ssl  SSL/TLS object.
1608
 * @return  List of CA subject names on success.
1609
 * @return  NULL when ssl is NULL or no names set.
1610
 */
1611
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get0_CA_list(const WOLFSSL *ssl)
1612
{
1613
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1614
1615
    WOLFSSL_ENTER("wolfSSL_get0_CA_list");
1616
1617
    /* Validate parameter. */
1618
    if (ssl == NULL) {
1619
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get0_CA_list");
1620
        ret = NULL;
1621
    }
1622
    else {
1623
        /* Return list directly from object, if available, or context. */
1624
        ret = SSL_CA_NAMES(ssl);
1625
    }
1626
1627
    return ret;
1628
}
1629
1630
/* Get the list of peer CA subject names from the SSL/TLS object.
1631
 *
1632
 * Always returns the CA's received from the peer.
1633
 *
1634
 * @param [in] ssl  SSL/TLS object.
1635
 * @return  List of CA subject names on success.
1636
 * @return  NULL when ssl is NULL or no names set.
1637
 */
1638
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get0_peer_CA_list(const WOLFSSL* ssl)
1639
{
1640
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1641
1642
    WOLFSSL_ENTER("wolfSSL_get0_peer_CA_list");
1643
1644
    /* Validate parameter. */
1645
    if (ssl == NULL) {
1646
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get0_peer_CA_list");
1647
        ret = NULL;
1648
    }
1649
    else {
1650
        /* Return list directly from object. */
1651
        ret = ssl->peer_ca_names;
1652
    }
1653
1654
    return ret;
1655
}
1656
1657
#ifndef NO_BIO
1658
/* Load the client CA subject names from file.
1659
 *
1660
 * @param [in] fname  Name of file containing client CA certificates.
1661
 * @return  A list of certificate names on success.
1662
 * @return  NULL on error.
1663
 */
1664
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
1665
{
1666
    /* The webserver build is using this to load a CA into the server
1667
     * for client authentication as an option. Have this return NULL in
1668
     * that case. If OPENSSL_EXTRA is enabled, go ahead and include
1669
     * the function. */
1670
    #ifdef OPENSSL_EXTRA
1671
    WOLFSSL_STACK *list = NULL;
1672
    WOLFSSL_BIO* bio = NULL;
1673
    WOLFSSL_X509 *cert = NULL;
1674
    int err = 0;
1675
    unsigned long error;
1676
1677
    WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
1678
1679
    /* Create a file BIO to read. */
1680
    bio = wolfSSL_BIO_new_file(fname, "rb");
1681
    if (bio == NULL) {
1682
        WOLFSSL_MSG("wolfSSL_BIO_new_file error");
1683
        err = 1;
1684
    }
1685
1686
    if (!err) {
1687
        /* Create an empty list of certificate names - default compare cb. */
1688
        list = wolfSSL_sk_X509_NAME_new(NULL);
1689
        if (list == NULL) {
1690
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1691
            err = 1;
1692
        }
1693
    }
1694
1695
    /* Read each certificate in the chain out of the file. */
1696
    while ((!err) && (wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL)) {
1697
        WOLFSSL_X509_NAME *nameCopy;
1698
1699
        /* Need a persistent copy of the subject name. */
1700
        nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(cert));
1701
        if (nameCopy == NULL) {
1702
            WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
1703
            err = 1;
1704
        }
1705
        else {
1706
            /* Original certificate will be freed - clear reference to it. */
1707
            nameCopy->x509 = NULL;
1708
1709
            if (wolfSSL_sk_X509_NAME_push(list, nameCopy) <= 0) {
1710
                WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
1711
                /* Name not stored - free now as only place needing to. */
1712
                wolfSSL_X509_NAME_free(nameCopy);
1713
                err = 1;
1714
            }
1715
        }
1716
1717
        /* Dispose of certificate read. */
1718
        wolfSSL_X509_free(cert);
1719
        cert = NULL;
1720
    }
1721
1722
    /* Clear any error due to no more certificates. */
1723
    CLEAR_ASN_NO_PEM_HEADER_ERROR(error);
1724
1725
    if (err) {
1726
        /* Error occurred so return NULL. */
1727
        wolfSSL_sk_X509_NAME_pop_free(list, NULL);
1728
        list = NULL;
1729
    }
1730
    wolfSSL_BIO_free(bio);
1731
    return list;
1732
    #else
1733
    (void)fname;
1734
    return NULL;
1735
    #endif
1736
}
1737
#endif /* !NO_BIO */
1738
#endif /* WOLFSSL_NO_CA_NAMES */
1739
1740
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1741
/* Get the certificate store of the SSL/TLS context.
1742
 *
1743
 * @param [in] ctx  SSL/TLS context.
1744
 * @return  X509 certificate store on success.
1745
 * @return  NULL when ctx is NULL.
1746
 */
1747
WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(const WOLFSSL_CTX* ctx)
1748
{
1749
    WOLFSSL_X509_STORE* ret;
1750
1751
    /* Validate parameter. */
1752
    if (ctx == NULL) {
1753
        ret = NULL;
1754
    }
1755
    /* Use pointer to external store if set. */
1756
    else if (ctx->x509_store_pt != NULL) {
1757
        ret = ctx->x509_store_pt;
1758
    }
1759
    else {
1760
        /* Return reference to store that is part of the context. */
1761
        ret = (WOLFSSL_X509_STORE*)&ctx->x509_store;
1762
    }
1763
1764
    return ret;
1765
}
1766
1767
/* Set the certificate store of the SSL/TLS context.
1768
 *
1769
 * The store is not taken when it shares the context's certificate manager.
1770
 *
1771
 * Ownership: the caller's reference to the store is taken over - no reference
1772
 * is added here, and the context releases it on free. A caller that means to
1773
 * keep using the store must take its own reference first with
1774
 * wolfSSL_X509_STORE_up_ref(). A reference is added to the store's
1775
 * certificate manager, which the context then uses as its own.
1776
 *
1777
 * @param [in, out] ctx  SSL/TLS context.
1778
 * @param [in]      str  X509 certificate store to use.
1779
 */
1780
void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
1781
{
1782
    WOLFSSL_ENTER("wolfSSL_CTX_set_cert_store");
1783
1784
    /* Validate parameters. */
1785
    if ((ctx == NULL) || (str == NULL) || (ctx->cm == str->cm)) {
1786
        WOLFSSL_MSG("Invalid parameters");
1787
    }
1788
    else if (wolfSSL_CertManager_up_ref(str->cm) != 1) {
1789
        WOLFSSL_MSG("wolfSSL_CertManager_up_ref error");
1790
    }
1791
    else {
1792
        /* Free any cert manager. */
1793
        wolfSSL_CertManagerFree(ctx->cm);
1794
        /* Free any external store. */
1795
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
1796
        /* Set the certificate manager into context. */
1797
        ctx->cm               = str->cm;
1798
        ctx->x509_store.cm    = str->cm;
1799
        ctx->x509_store.cache = str->cache;
1800
        /* Take ownership of store and free it with context free. */
1801
        ctx->x509_store_pt    = str;
1802
        /* Context has ownership and free it with context free. */
1803
        ctx->cm->x509_store_p = ctx->x509_store_pt;
1804
1805
        #ifdef OPENSSL_EXTRA
1806
        /* Non-self-signed certs (intermediates) added via
1807
         * X509_STORE_add_cert only go into store->certs, not the
1808
         * CertManager. Push them into the CM now so that all
1809
         * verification paths can find them. */
1810
        if (X509StorePushCertsToCM(str) != WOLFSSL_SUCCESS) {
1811
            WOLFSSL_MSG("wolfSSL_CTX_set_cert_store: failed to push some "
1812
                        "certs to CertManager");
1813
        }
1814
        #endif
1815
    }
1816
}
1817
1818
#ifdef OPENSSL_ALL
1819
/* Set certificate store into SSL/TLS context but don't take ownership.
1820
 *
1821
 * A NULL store is refused, which is a deviation from OpenSSL, where
1822
 * SSL_CTX_set1_verify_cert_store(ctx, NULL) returns 1 and releases the verify
1823
 * store so the context falls back to its own. OpenSSL keeps two stores on a
1824
 * context, the one set by SSL_CTX_set_cert_store() and the verify store this
1825
 * call sets; both live in ctx->x509_store_pt here, so releasing it on NULL
1826
 * would also throw away the store handed to wolfSSL_CTX_set_cert_store() and
1827
 * drop the context back to its own, which is not set up for certificate
1828
 * lookup by issuer. Until the two are held separately the request cannot be
1829
 * honoured, and refusing it is what keeps that visible - returning success
1830
 * without clearing would leave the caller verifying against the store it
1831
 * asked to be rid of.
1832
 *
1833
 * Note the asymmetry with the object-level setters:
1834
 * wolfSSL_set0_verify_cert_store() and wolfSSL_set1_verify_cert_store() do
1835
 * clear on NULL, because an object reverts to the context's store rather than
1836
 * having a second store of its own to throw away.
1837
 *
1838
 * @param [in] ctx  SSL/TLS context.
1839
 * @param [in] str  Certificate store. NULL is refused.
1840
 * @return  1 on success.
1841
 * @return  0 when ctx or str is NULL, or on other error.
1842
 */
1843
int wolfSSL_CTX_set1_verify_cert_store(WOLFSSL_CTX* ctx,
1844
    WOLFSSL_X509_STORE* str)
1845
{
1846
    int ret;
1847
1848
    WOLFSSL_ENTER("wolfSSL_CTX_set1_verify_cert_store");
1849
1850
    /* Validate parameters. A NULL store is refused rather than accepted and
1851
     * ignored. OpenSSL keeps two stores on a context - the one set by
1852
     * SSL_CTX_set_cert_store() and the verify store this call sets - and
1853
     * clearing the verify store leaves the other alone. Both live in
1854
     * ctx->x509_store_pt here, so releasing it on NULL would throw away the
1855
     * store handed to wolfSSL_CTX_set_cert_store() and drop the context back
1856
     * to its own, which is not set up for certificate lookup by issuer.
1857
     * Reporting failure keeps that unsupported request visible: returning
1858
     * success without clearing would leave the caller verifying against the
1859
     * store it asked to be rid of, with no way to tell. */
1860
    if ((ctx == NULL) || (str == NULL)) {
1861
        WOLFSSL_MSG("Bad parameter");
1862
        ret = 0;
1863
    }
1864
    /* Nothing to do when store being set is the same as existing in context. */
1865
    else if (str == CTX_STORE(ctx)) {
1866
        ret = 1;
1867
    }
1868
    /* Take a reference so the pointer can be stored and released with the
1869
     * context. A store that is part of another object has none to take - the
1870
     * pointer is then kept without anything protecting it. */
1871
    else if (wolfSSL_X509_STORE_up_ref(str) != 1) {
1872
        WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
1873
        ret = 0;
1874
    }
1875
    else {
1876
        /* Free any external store. */
1877
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
1878
        /* Ref count increased - store pointer and free with context free. */
1879
        ctx->x509_store_pt = str;
1880
        /* As above: the store just released may have been the one this
1881
         * manager names, which leaves the manager with no store for the
1882
         * lookup by issuer. Unlike wolfSSL_CTX_set_cert_store(), this setter
1883
         * does not adopt the new store's manager - str carries its own, and
1884
         * that is the one verification resolves through, so pairing this
1885
         * manager with str would cross-link two independent managers. The
1886
         * context's own store is used instead: what the manager needs is a
1887
         * store that stays valid for as long as it does, not the one
1888
         * currently in use. */
1889
        if ((ctx->cm != NULL) && (ctx->cm->x509_store_p == NULL)) {
1890
            ctx->cm->x509_store_p = &ctx->x509_store;
1891
        }
1892
        ret = 1;
1893
    }
1894
1895
    return ret;
1896
}
1897
#endif
1898
1899
1900
/* Set the certificate store used for verification by the SSL/TLS object.
1901
 *
1902
 * Ownership: with ref set, a reference is taken here (set1 semantics);
1903
 * without it the caller's reference is handed over (set0 semantics). With
1904
 * ref set the accounting always nets to zero - the reference taken is kept
1905
 * with the stored pointer, or released again when no pointer is kept.
1906
 *
1907
 * A set0 caller's reference is consumed by being kept, except on the two
1908
 * paths that keep no pointer and cannot safely release it either: being
1909
 * handed the store the object already uses, and being handed the context's
1910
 * store while the object holds one of its own. Both leak that reference by
1911
 * design - see the comments on those branches; releasing it would free a
1912
 * reference a misusing caller never took.
1913
 *
1914
 * A store that is part of another object has no reference count to take, so
1915
 * nothing keeps it alive for as long as the pointer is held here - see
1916
 * wolfSSL_X509_STORE_up_ref(). Storing one that belongs to a different
1917
 * object outlives its owner only by luck.
1918
 *
1919
 * A set0 caller must therefore own a reference. Handing over a borrowed
1920
 * pointer, such as one straight from wolfSSL_CTX_get_cert_store(), releases
1921
 * a reference the caller never took and can destroy a store still in use.
1922
 *
1923
 * The object uses the context's store by keeping no pointer of its own, so
1924
 * that is how both a NULL store, which clears, and being handed the store the
1925
 * context already uses are done. Clearing on NULL rather than rejecting it
1926
 * matches OpenSSL.
1927
 *
1928
 * "The store the context already uses" is what CTX_STORE() resolves to, which
1929
 * is the context's own store when no other has been set on it. So handing
1930
 * over wolfSSL_CTX_get_cert_store() of such a context makes the object follow
1931
 * the context rather than pinning that store: a later
1932
 * wolfSSL_CTX_set1_verify_cert_store() then changes what the object verifies
1933
 * against. OpenSSL's SSL_set1_verify_cert_store() pins instead, and so did
1934
 * this before the context's own store was included in the comparison.
1935
 * Following is the safer of the two here, because a store that is part of
1936
 * another object has no reference count and pinning it stores a pointer with
1937
 * nothing keeping it alive.
1938
 *
1939
 * @param [in, out] ssl  SSL/TLS object.
1940
 * @param [in]      str  X509 certificate store to use. NULL to clear.
1941
 * @param [in]      ref  Whether to take a reference to the store.
1942
 * @return  1 on success.
1943
 * @return  0 when ssl is NULL, or the reference cannot be taken.
1944
 */
1945
static int wolfssl_set_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str,
1946
    int ref)
1947
{
1948
    int ret;
1949
1950
    WOLFSSL_ENTER("wolfssl_set_verify_cert_store");
1951
1952
    /* Validate parameters. */
1953
    if (ssl == NULL) {
1954
        WOLFSSL_MSG("Bad parameter");
1955
        ret = 0;
1956
    }
1957
    /* Already the store this object uses - its own, or the context's when it
1958
     * has none of its own: leave every reference where it is, as the original
1959
     * code did. Consuming one here would release a reference the object or
1960
     * the context still relies on when a set0 caller passed a pointer it did
1961
     * not own, which is a use-after-free for the object's store and a second
1962
     * free at wolfSSL_CTX_free() for the context's. A leaked reference is the
1963
     * safer of the two outcomes for an entry point applications reach through
1964
     * the OpenSSL compatibility layer. */
1965
    else if (str == SSL_STORE(ssl)) {
1966
        ret = 1;
1967
    }
1968
    /* Take the reference to become responsible for before releasing the one
1969
     * the object holds below. The two name different stores - the store the
1970
     * object already uses is caught by the early exit above. */
1971
    else if (ref && (str != NULL) && (wolfSSL_X509_STORE_up_ref(str) != 1)) {
1972
        WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
1973
        ret = 0;
1974
    }
1975
    else {
1976
        /* The object uses the context's store by keeping no pointer, so that
1977
         * is what being handed that store means here. A NULL store, which
1978
         * clears, is kept as it is and so keeps no pointer either. */
1979
        WOLFSSL_X509_STORE* keep = (str == CTX_STORE(ssl->ctx)) ? NULL : str;
1980
1981
        /* Release the store held, if any, and take on the new one. The
1982
         * reference this call is responsible for - taken above for set1,
1983
         * handed over for set0 - is consumed by being kept. */
1984
        wolfSSL_X509_STORE_free(ssl->x509_store_pt);
1985
        ssl->x509_store_pt = keep;
1986
        if ((keep == NULL) && ref) {
1987
            /* Nothing kept the reference taken above, so give it back. Only
1988
             * set1 gets here: a set0 caller's reference must be left alone,
1989
             * as the store it named is the context's and releasing it would
1990
             * leave ctx->x509_store_pt pointing at memory freed a second
1991
             * time by wolfSSL_CTX_free(). */
1992
            wolfSSL_X509_STORE_free(str);
1993
        }
1994
        ret = 1;
1995
    }
1996
1997
    return ret;
1998
}
1999
2000
/* Set certificate store into SSL/TLS object and take ownership.
2001
 *
2002
 * The caller must own a reference to the store - it is consumed here. A NULL
2003
 * store clears any store previously set on the object. *
2004
 * Passing the store the context is currently using - what
2005
 * wolfSSL_CTX_get_cert_store() returns - makes the object track the context
2006
 * instead of pinning that store, so a later
2007
 * wolfSSL_CTX_set1_verify_cert_store() changes what this object verifies
2008
 * against. OpenSSL's equivalent pins the store. See
2009
 * wolfssl_set_verify_cert_store() for why following is preferred here.
2010
 *
2011
 * @param [in, out] ssl  SSL/TLS object.
2012
 * @param [in] str  Certificate store. NULL to clear.
2013
 * @return  1 on success.
2014
 * @return  0 when ssl is NULL or on other error.
2015
 */
2016
int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
2017
{
2018
    WOLFSSL_ENTER("wolfSSL_set0_verify_cert_store");
2019
2020
    return wolfssl_set_verify_cert_store(ssl, str, 0);
2021
}
2022
2023
/* Set certificate store into SSL/TLS object but don't take ownership.
2024
 *
2025
 * A NULL store clears any store previously set on the object. *
2026
 * Passing the store the context is currently using - what
2027
 * wolfSSL_CTX_get_cert_store() returns - makes the object track the context
2028
 * instead of pinning that store, so a later
2029
 * wolfSSL_CTX_set1_verify_cert_store() changes what this object verifies
2030
 * against. OpenSSL's equivalent pins the store. See
2031
 * wolfssl_set_verify_cert_store() for why following is preferred here.
2032
 *
2033
 * @param [in, out] ssl  SSL/TLS object.
2034
 * @param [in] str  Certificate store. NULL to clear.
2035
 * @return  1 on success.
2036
 * @return  0 when ssl is NULL or on other error.
2037
 */
2038
int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
2039
{
2040
    WOLFSSL_ENTER("wolfSSL_set1_verify_cert_store");
2041
2042
    return wolfssl_set_verify_cert_store(ssl, str, 1);
2043
}
2044
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
2045
2046
/* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
2047
   KEEP_OUR_CERT is to ensure ability to return ssl certificate */
2048
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
2049
    defined(KEEP_OUR_CERT)
2050
/* Get the certificate in the SSL/TLS context.
2051
 *
2052
 * @param [in] ctx  SSL/TLS context.
2053
 * @return  Certificate being sent to peer.
2054
 * @return  NULL when ctx is NULL, no certificate set or on other error.
2055
 */
2056
WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx)
2057
{
2058
    WOLFSSL_X509* ret = NULL;
2059
2060
    /* Validate parameters. */
2061
    if (ctx == NULL) {
2062
        WOLFSSL_MSG("Invalid parameter");
2063
    }
2064
    else {
2065
        /* Check if we already have a certificate allocated. */
2066
        if (ctx->ourCert == NULL) {
2067
            /* Check if there is a raw certificate. */
2068
            if (ctx->certificate == NULL) {
2069
                WOLFSSL_MSG("Ctx Certificate buffer not set!");
2070
            }
2071
            #ifndef WOLFSSL_X509_STORE_CERTS
2072
            else {
2073
                /* Create a certificate object from raw data. */
2074
                ctx->ourCert = wolfSSL_X509_d2i_ex(NULL,
2075
                    ctx->certificate->buffer, (int)ctx->certificate->length,
2076
                    ctx->heap);
2077
                ctx->ownOurCert = 1;
2078
            }
2079
            #endif
2080
        }
2081
        /* Return certificate cached against SSL/TLS context. */
2082
        ret = ctx->ourCert;
2083
    }
2084
2085
    return ret;
2086
}
2087
2088
/* Get the certificate in the SSL/TLS object.
2089
 *
2090
 * @param [in, out] ssl  SSL/TLS object.
2091
 * @return  Certificate being sent to peer.
2092
 * @return  NULL when ssl is NULL, no certificate set or on other error.
2093
 */
2094
WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
2095
{
2096
    WOLFSSL_X509* ret = NULL;
2097
2098
    /* Validate parameters. */
2099
    if (ssl == NULL) {
2100
        WOLFSSL_MSG("Invalid parameter");
2101
    }
2102
    /* Use certificate in SSL/TLS object if we own it. */
2103
    else if (ssl->buffers.weOwnCert) {
2104
        /* Check if we already have a certificate allocated. */
2105
        if (ssl->ourCert == NULL) {
2106
            /* Check if ctx has ourCert set - if so, use it instead of creating
2107
             * a new X509. This maintains pointer compatibility with
2108
             * applications (like nginx OCSP stapling) that use the X509 pointer
2109
             * from SSL_CTX_use_certificate as a lookup key. */
2110
            if ((ssl->ctx != NULL) && (ssl->ctx->ourCert != NULL)) {
2111
                /* Compare cert buffers to make sure they are the same. The
2112
                 * SSL may hold the CTX's own buffer (WOLFSSL_DER_REFCOUNT). */
2113
                if ((ssl->buffers.certificate == NULL) ||
2114
                    (ssl->buffers.certificate->buffer == NULL) ||
2115
                    (ssl->buffers.certificate == ssl->ctx->certificate) ||
2116
                   ((ssl->ctx->certificate != NULL) &&
2117
                    (ssl->buffers.certificate->length ==
2118
                     ssl->ctx->certificate->length) &&
2119
                    (XMEMCMP(ssl->buffers.certificate->buffer,
2120
                             ssl->ctx->certificate->buffer,
2121
                             ssl->buffers.certificate->length) == 0))) {
2122
                    return ssl->ctx->ourCert;
2123
                }
2124
            }
2125
            /* We own certificate so this should never happen. */
2126
            if (ssl->buffers.certificate == NULL) {
2127
                WOLFSSL_MSG("Certificate buffer not set!");
2128
            }
2129
            #ifndef WOLFSSL_X509_STORE_CERTS
2130
            else {
2131
                /* Create a certificate object from raw data. */
2132
                ssl->ourCert = wolfSSL_X509_d2i_ex(NULL,
2133
                    ssl->buffers.certificate->buffer,
2134
                    (int)ssl->buffers.certificate->length, ssl->heap);
2135
            }
2136
            #endif
2137
        }
2138
        /* Return certificate cached against SSL/TLS object. */
2139
        ret = ssl->ourCert;
2140
    }
2141
    else {
2142
        /* Use any certificate in SSL/TLS context instead. */
2143
        ret = wolfSSL_CTX_get0_certificate(ssl->ctx);
2144
    }
2145
2146
    return ret;
2147
}
2148
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && KEEP_OUR_CERT */
2149
2150
#endif /* !NO_CERTS */
2151
2152
#ifndef WOLFCRYPT_ONLY
2153
2154
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
2155
/* Get the index at which the object is stored in an X509 store context's
2156
 * external data.
2157
 *
2158
 * @return  Index of the SSL/TLS object (0).
2159
 */
2160
int wolfSSL_get_ex_data_X509_STORE_CTX_idx(void)
2161
{
2162
    WOLFSSL_ENTER("wolfSSL_get_ex_data_X509_STORE_CTX_idx");
2163
2164
    /* store SSL at index 0 */
2165
    return 0;
2166
}
2167
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
2168
2169
2170
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
2171
    defined(OPENSSL_ALL)
2172
/* Get the result of peer certificate verification.
2173
 *
2174
 * @param [in] ssl  SSL/TLS object.
2175
 * @return  Verification result code on success.
2176
 * @return  WOLFSSL_X509_V_ERR_APPLICATION_VERIFICATION when ssl is NULL.
2177
 */
2178
long wolfSSL_get_verify_result(const WOLFSSL *ssl)
2179
{
2180
    long ret;
2181
2182
    if (ssl == NULL) {
2183
        /* Return a non-zero error so the OpenSSL-idiomatic
2184
         * "!= X509_V_OK" check does not mistake a NULL ssl for a
2185
         * successful verification (X509_V_OK is 0). */
2186
        ret = WOLFSSL_X509_V_ERR_APPLICATION_VERIFICATION;
2187
    }
2188
    else {
2189
        /* Result of verifying the peer's certificate chain. */
2190
        ret = (long)ssl->peerVerifyRet;
2191
    }
2192
2193
    return ret;
2194
}
2195
#endif
2196
2197
2198
#if defined(OPENSSL_EXTRA) && defined(KEEP_PEER_CERT) && \
2199
    defined(HAVE_EX_DATA) && !defined(NO_FILESYSTEM)
2200
/* Compare the peer's certificate against a PEM certificate file.
2201
 *
2202
 * @param [in] ssl    SSL/TLS object.
2203
 * @param [in] fname  Path to a PEM certificate file.
2204
 * @return  0 when the certificates match.
2205
 * @return  WOLFSSL_FATAL_ERROR when arguments are NULL or they do not match.
2206
 * @return  WOLFSSL_BAD_FILE when the file cannot be read.
2207
 */
2208
int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
2209
{
2210
    int ret = 0;
2211
2212
    WOLFSSL_ENTER("wolfSSL_cmp_peer_cert_to_file");
2213
2214
    if ((ssl == NULL) || (fname == NULL)) {
2215
        ret = WOLFSSL_FATAL_ERROR;
2216
    }
2217
    else {
2218
        #ifdef WOLFSSL_SMALL_STACK
2219
        byte staticBuffer[1]; /* force heap usage */
2220
        #else
2221
        byte staticBuffer[FILE_BUFFER_SIZE];
2222
        #endif
2223
        byte* myBuf = staticBuffer;
2224
        XFILE file = XBADFILE;
2225
        long sz = 0;
2226
        void* heap = ssl->ctx->heap;
2227
        const DerBuffer* peerDer = GetPeerCertDer(ssl);
2228
        DerBuffer* fileDer = NULL;
2229
2230
        /* handle gracefully if called before handshake, or if peer did not
2231
         * present a cert. */
2232
        if (peerDer == NULL) {
2233
            WOLFSSL_MSG("wolfSSL_cmp_peer_cert_to_file without peer cert");
2234
            ret = WOLFSSL_FATAL_ERROR;
2235
        }
2236
2237
        if (ret == 0) {
2238
            /* Open the file and determine its size. From here, ret == 0
2239
             * indicates processing is still on track. */
2240
            file = XFOPEN(fname, "rb");
2241
            ret = wolfssl_file_len(file, &sz);
2242
        }
2243
        /* Use a heap buffer when the file is bigger than the stack buffer. */
2244
        if ((ret == 0) && (sz > (long)sizeof(staticBuffer))) {
2245
            WOLFSSL_MSG("Getting dynamic buffer");
2246
            myBuf = (byte*)XMALLOC((size_t)sz, heap, DYNAMIC_TYPE_FILE);
2247
            if (myBuf == NULL) {
2248
                ret = WOLFSSL_FATAL_ERROR;
2249
            }
2250
        }
2251
        /* Read the whole file into the buffer. */
2252
        if ((ret == 0) && (XFREAD(myBuf, 1, (size_t)sz, file) != (size_t)sz)) {
2253
            ret = WOLFSSL_FATAL_ERROR;
2254
        }
2255
        /* Convert the PEM file contents to DER. */
2256
        if ((ret == 0) && (PemToDer(myBuf, sz, CERT_TYPE, &fileDer, heap, NULL,
2257
                                    NULL) != 0)) {
2258
            ret = WOLFSSL_FATAL_ERROR;
2259
        }
2260
        /* Peer certificate matches when the DER lengths and bytes are equal. */
2261
        if ((ret == 0) && ((fileDer->length == 0) ||
2262
                (fileDer->length != peerDer->length) ||
2263
                (XMEMCMP(peerDer->buffer, fileDer->buffer,
2264
                         fileDer->length) != 0))) {
2265
            ret = WOLFSSL_FATAL_ERROR;
2266
        }
2267
2268
        /* Dispose of the DER, any heap buffer and close the file. */
2269
        FreeDer(&fileDer);
2270
        if (myBuf != staticBuffer) {
2271
            XFREE(myBuf, heap, DYNAMIC_TYPE_FILE);
2272
        }
2273
        if (file != XBADFILE) {
2274
            XFCLOSE(file);
2275
        }
2276
    }
2277
2278
    return ret;
2279
}
2280
#endif
2281
2282
2283
#ifdef WOLFSSL_ALT_CERT_CHAINS
2284
/* Determine whether the peer was verified using an alternate cert chain.
2285
 *
2286
 * @param [in] ssl  SSL/TLS object.
2287
 * @return  1 when an alternate certificate chain was used.
2288
 * @return  0 otherwise, or when ssl is NULL.
2289
 */
2290
int wolfSSL_is_peer_alt_cert_chain(const WOLFSSL* ssl)
2291
{
2292
    return (ssl != NULL) && ssl->options.usingAltCertChain;
2293
}
2294
#endif /* WOLFSSL_ALT_CERT_CHAINS */
2295
2296
2297
#ifdef SESSION_CERTS
2298
2299
#ifdef WOLFSSL_ALT_CERT_CHAINS
2300
/* Get the peer's alternate certificate chain.
2301
 *
2302
 * @param [in] ssl  SSL/TLS object.
2303
 * @return  Alternate certificate chain on success.
2304
 * @return  NULL when ssl is NULL.
2305
 */
2306
WOLFSSL_X509_CHAIN* wolfSSL_get_peer_alt_chain(WOLFSSL* ssl)
2307
{
2308
    WOLFSSL_X509_CHAIN* chain = NULL;
2309
2310
    WOLFSSL_ENTER("wolfSSL_get_peer_alt_chain");
2311
2312
    if (ssl != NULL) {
2313
        /* The alternate chain is held within the session. */
2314
        chain = &ssl->session->altChain;
2315
    }
2316
2317
    return chain;
2318
}
2319
#endif /* WOLFSSL_ALT_CERT_CHAINS */
2320
2321
2322
/* Get the peer's certificate chain.
2323
 *
2324
 * @param [in] ssl  SSL/TLS object.
2325
 * @return  Certificate chain on success.
2326
 * @return  NULL when ssl is NULL.
2327
 */
2328
WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl)
2329
{
2330
    WOLFSSL_X509_CHAIN* chain = NULL;
2331
2332
    WOLFSSL_ENTER("wolfSSL_get_peer_chain");
2333
2334
    if (ssl != NULL) {
2335
        /* The peer chain is held within the session. */
2336
        chain = &ssl->session->chain;
2337
    }
2338
2339
    return chain;
2340
}
2341
2342
2343
/* Get the number of certificates in a certificate chain.
2344
 *
2345
 * @param [in] chain  Certificate chain object.
2346
 * @return  Number of certificates on success.
2347
 * @return  0 when chain is NULL.
2348
 */
2349
int wolfSSL_get_chain_count(WOLFSSL_X509_CHAIN* chain)
2350
{
2351
    int count = 0;
2352
2353
    WOLFSSL_ENTER("wolfSSL_get_chain_count");
2354
2355
    if (chain != NULL) {
2356
        /* Number of certificates captured in the chain. */
2357
        count = chain->count;
2358
    }
2359
2360
    return count;
2361
}
2362
2363
2364
/* Get the length, in bytes, of the DER certificate at an index in a chain.
2365
 *
2366
 * @param [in] chain  Certificate chain object.
2367
 * @param [in] idx    Index of the certificate in the chain.
2368
 * @return  Length of the DER certificate in bytes on success.
2369
 * @return  0 when chain is NULL or idx is out of range.
2370
 */
2371
int wolfSSL_get_chain_length(WOLFSSL_X509_CHAIN* chain, int idx)
2372
{
2373
    int length = 0;
2374
2375
    WOLFSSL_ENTER("wolfSSL_get_chain_length");
2376
2377
    if ((chain != NULL) && (idx >= 0) && (idx < chain->count)) {
2378
        /* DER length of the certificate stored at the given index. */
2379
        length = chain->certs[idx].length;
2380
    }
2381
2382
    return length;
2383
}
2384
2385
2386
/* Get the DER certificate at an index in a certificate chain.
2387
 *
2388
 * @param [in] chain  Certificate chain object.
2389
 * @param [in] idx    Index of the certificate in the chain.
2390
 * @return  Buffer holding the DER certificate on success.
2391
 * @return  0 when chain is NULL, idx is out of range or the certificate did
2392
 *          not fit its slot.
2393
 */
2394
byte* wolfSSL_get_chain_cert(WOLFSSL_X509_CHAIN* chain, int idx)
2395
{
2396
    byte* cert = NULL;
2397
2398
    WOLFSSL_ENTER("wolfSSL_get_chain_cert");
2399
2400
    if ((chain != NULL) && (idx >= 0) && (idx < chain->count) &&
2401
            (chain->certs[idx].length > 0)) {
2402
        /* DER buffer of the certificate stored at the given index. */
2403
        cert = chain->certs[idx].buffer;
2404
    }
2405
2406
    return cert;
2407
}
2408
2409
2410
/* Decode DER certificate data into a WOLFSSL_X509 object. Defined in
2411
 * src/ssl.c. */
2412
static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len);
2413
2414
/* Get the certificate at an index in a chain as a new X509 object.
2415
 *
2416
 * The returned object must be freed by the caller with wolfSSL_X509_free().
2417
 *
2418
 * @param [in] chain  Certificate chain object.
2419
 * @param [in] idx    Index of the certificate in the chain.
2420
 * @return  Newly allocated X509 certificate object on success.
2421
 * @return  NULL when chain is NULL, idx is out of range or on error.
2422
 */
2423
WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx)
2424
{
2425
    WOLFSSL_X509* x509 = NULL;
2426
2427
    WOLFSSL_ENTER("wolfSSL_get_chain_X509");
2428
2429
    if ((chain != NULL) && (idx >= 0) && (idx < chain->count) &&
2430
            (chain->certs[idx].length > 0)) {
2431
        x509 = (WOLFSSL_X509*)XMALLOC(sizeof(WOLFSSL_X509), NULL,
2432
            DYNAMIC_TYPE_X509);
2433
        if (x509 == NULL) {
2434
            WOLFSSL_MSG("Failed alloc X509");
2435
        }
2436
        else {
2437
            /* Pre-init with dynamicMemory=1 so DecodeToX509 skips its own
2438
             * InitX509 (and we still own the buffer for X509_free). */
2439
            InitX509(x509, 1, NULL);
2440
            if (DecodeToX509(x509, chain->certs[idx].buffer,
2441
                             chain->certs[idx].length) != 0) {
2442
                WOLFSSL_MSG("Failed to decode cert");
2443
                wolfSSL_X509_free(x509);
2444
                x509 = NULL;
2445
            }
2446
        }
2447
    }
2448
2449
    return x509;
2450
}
2451
2452
2453
/* Get the certificate at an index in a chain as PEM.
2454
 *
2455
 * When buf is NULL, the length required is returned in outLen.
2456
 *
2457
 * @param [in]  chain   Certificate chain object.
2458
 * @param [in]  idx     Index of the certificate in the chain.
2459
 * @param [out] buf     Buffer to hold PEM. May be NULL to get the length.
2460
 * @param [in]  inLen   Length of buffer in bytes.
2461
 * @param [out] outLen  Length of PEM data in bytes.
2462
 * @return  WOLFSSL_SUCCESS on success.
2463
 * @return  LENGTH_ONLY_E when buf is NULL and outLen has been set.
2464
 * @return  BAD_FUNC_ARG when a required argument is NULL or idx is invalid.
2465
 * @return  WOLFSSL_FAILURE on error.
2466
 */
2467
int  wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
2468
                               unsigned char* buf, int inLen, int* outLen)
2469
{
2470
    #ifdef WOLFSSL_DER_TO_PEM
2471
    int ret = WOLFSSL_SUCCESS;
2472
2473
    WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
2474
    if ((chain == NULL) || (outLen == NULL) || (idx < 0) ||
2475
            (idx >= wolfSSL_get_chain_count(chain)) ||
2476
            (chain->certs[idx].length <= 0)) {
2477
        ret = BAD_FUNC_ARG;
2478
    }
2479
    /* Delegate to wc_DerToPem when DER-to-PEM is available. */
2480
    if (ret == WOLFSSL_SUCCESS) {
2481
        if (buf == NULL) {
2482
            inLen = 0;
2483
        }
2484
        else if (inLen < 0) {
2485
            ret = BAD_FUNC_ARG;
2486
        }
2487
    }
2488
    if (ret == WOLFSSL_SUCCESS) {
2489
        int n = wc_DerToPem(chain->certs[idx].buffer,
2490
            (word32)chain->certs[idx].length, buf, (word32)inLen, CERT_TYPE);
2491
        if (n < 0) {
2492
            if (buf == NULL) {
2493
                ret = WOLFSSL_FAILURE;
2494
            }
2495
            else {
2496
                ret = n;
2497
            }
2498
        }
2499
        else {
2500
            *outLen = n;
2501
            if (buf == NULL) {
2502
                ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
2503
            }
2504
        }
2505
    }
2506
2507
    return ret;
2508
    #elif defined(WOLFSSL_PEM_TO_DER)
2509
    int ret = WOLFSSL_SUCCESS;
2510
    const char* header = NULL;
2511
    const char* footer = NULL;
2512
    int headerLen;
2513
    int footerLen;
2514
    int i;
2515
    int err;
2516
2517
    WOLFSSL_ENTER("wolfSSL_get_chain_cert_pem");
2518
    if ((chain == NULL) || (outLen == NULL) || (idx < 0) ||
2519
            (idx >= wolfSSL_get_chain_count(chain)) ||
2520
            (chain->certs[idx].length <= 0)) {
2521
        ret = BAD_FUNC_ARG;
2522
    }
2523
    if (ret == WOLFSSL_SUCCESS) {
2524
        if ((err = wc_PemGetHeaderFooter(CERT_TYPE, &header, &footer)) != 0) {
2525
            ret = err;
2526
        }
2527
    }
2528
    if (ret == WOLFSSL_SUCCESS) {
2529
        headerLen = (int)XSTRLEN(header);
2530
        footerLen = (int)XSTRLEN(footer);
2531
2532
        /* Null output buffer returns size needed in outLen. */
2533
        if (buf == NULL) {
2534
            word32 szNeeded = 0;
2535
2536
            if (Base64_Encode(chain->certs[idx].buffer,
2537
                    (word32)chain->certs[idx].length, NULL,
2538
                    &szNeeded) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
2539
                ret = WOLFSSL_FAILURE;
2540
            }
2541
            else {
2542
                *outLen = (int)szNeeded + headerLen + footerLen;
2543
                ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
2544
            }
2545
        }
2546
        /* buf == NULL, ret will not be WOLFSSL_SUCCESS. */
2547
    }
2548
    /* Don't even try when inLen is too short. */
2549
    if ((ret == WOLFSSL_SUCCESS) &&
2550
            (inLen < headerLen + footerLen + chain->certs[idx].length)) {
2551
        ret = BAD_FUNC_ARG;
2552
    }
2553
    if (ret == WOLFSSL_SUCCESS) {
2554
        /* Write the PEM header. */
2555
        XMEMCPY(buf, header, (size_t)headerLen);
2556
        i = headerLen;
2557
2558
        /* Space left for Base64 data after header and before footer. */
2559
        *outLen = inLen - headerLen - footerLen;
2560
        if ((err = Base64_Encode(chain->certs[idx].buffer,
2561
                (word32)chain->certs[idx].length, buf + i,
2562
                (word32*)outLen)) < 0) {
2563
            ret = err;
2564
        }
2565
    }
2566
    if (ret == WOLFSSL_SUCCESS) {
2567
        i += *outLen;
2568
2569
        /* Write the PEM footer. */
2570
        XMEMCPY(buf + i, footer, (size_t)footerLen);
2571
        *outLen += headerLen + footerLen;
2572
    }
2573
2574
    return ret;
2575
    #else
2576
    (void)chain;
2577
    (void)idx;
2578
    (void)buf;
2579
    (void)inLen;
2580
    (void)outLen;
2581
    return WOLFSSL_FAILURE;
2582
    #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
2583
}
2584
2585
#endif /* SESSION_CERTS */
2586
2587
2588
#if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \
2589
    || defined(WOLFSSL_NGINX) || defined(WOLFSSL_QT)
2590
#ifndef NO_WOLFSSL_STUB
2591
/* Clear the extra certificate chain set on the context.
2592
 *
2593
 * Not implemented - stub for OpenSSL compatibility.
2594
 *
2595
 * @param [in] ctx  SSL/TLS context object.
2596
 * @return  Result of the SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS control command.
2597
 */
2598
long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx)
2599
{
2600
    return wolfSSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0L, NULL);
2601
}
2602
#endif
2603
2604
/* Get the verify callback set on the object.
2605
 *
2606
 * @param [in] ssl  SSL/TLS object.
2607
 * @return  Verify callback on success.
2608
 * @return  NULL when ssl is NULL or no callback is set.
2609
 */
2610
VerifyCallback wolfSSL_get_verify_callback(WOLFSSL* ssl)
2611
{
2612
    VerifyCallback cb = NULL;
2613
2614
    WOLFSSL_ENTER("wolfSSL_get_verify_callback");
2615
2616
    if (ssl != NULL) {
2617
        /* Verify callback configured on the object. */
2618
        cb = ssl->verifyCallback;
2619
    }
2620
2621
    return cb;
2622
}
2623
2624
#endif
2625
2626
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
2627
/* Get the verify callback set on the context.
2628
 *
2629
 * @param [in] ctx  SSL/TLS context object.
2630
 * @return  Verify callback on success.
2631
 * @return  NULL when ctx is NULL or no callback is set.
2632
 */
2633
VerifyCallback wolfSSL_CTX_get_verify_callback(WOLFSSL_CTX* ctx)
2634
{
2635
    VerifyCallback cb = NULL;
2636
2637
    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_callback");
2638
2639
    if (ctx != NULL) {
2640
        /* Verify callback configured on the context. */
2641
        cb = ctx->verifyCallback;
2642
    }
2643
2644
    return cb;
2645
}
2646
2647
#endif
2648
2649
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(HAVE_STUNNEL) || \
2650
    defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX)
2651
2652
/* Get the verification mode set on the object.
2653
 *
2654
 * WOLFSSL_VERIFY_CLIENT_ONCE is never reported: wolfSSL_set_verify() accepts
2655
 * and ignores it rather than storing it. Neither is WOLFSSL_VERIFY_DEFAULT -
2656
 * it clears every option, so a mode of 0 is returned for it.
2657
 *
2658
 * @param [in] ssl  SSL/TLS object.
2659
 * @return  Bitmask of WOLFSSL_VERIFY_* flags on success.
2660
 * @return  WOLFSSL_FAILURE when ssl is NULL.
2661
 */
2662
int wolfSSL_get_verify_mode(const WOLFSSL* ssl)
2663
{
2664
    int mode = 0;
2665
2666
    WOLFSSL_ENTER("wolfSSL_get_verify_mode");
2667
2668
    if (ssl == NULL) {
2669
        mode = WOLFSSL_FAILURE;
2670
    }
2671
    else if (ssl->options.verifyNone) {
2672
        /* VERIFY_NONE is exclusive of the other verify flags. */
2673
        mode = WOLFSSL_VERIFY_NONE;
2674
    }
2675
    else {
2676
        /* Build the mode as a bitmask of the enabled verify flags. */
2677
        if (ssl->options.verifyPeer) {
2678
            mode |= WOLFSSL_VERIFY_PEER;
2679
        }
2680
        if (ssl->options.failNoCert) {
2681
            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2682
        }
2683
        if (ssl->options.failNoCertxPSK) {
2684
            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
2685
        }
2686
        #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
2687
        if (ssl->options.verifyPostHandshake) {
2688
            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
2689
        }
2690
        #endif
2691
    }
2692
2693
    WOLFSSL_LEAVE("wolfSSL_get_verify_mode", mode);
2694
    return mode;
2695
}
2696
2697
/* Get the verification mode set on the context.
2698
 *
2699
 * WOLFSSL_VERIFY_CLIENT_ONCE is never reported: wolfSSL_CTX_set_verify()
2700
 * accepts and ignores it rather than storing it. Neither is
2701
 * WOLFSSL_VERIFY_DEFAULT - it clears every option, so a mode of 0 is
2702
 * returned for it.
2703
 *
2704
 * @param [in] ctx  SSL/TLS context object.
2705
 * @return  Bitmask of WOLFSSL_VERIFY_* flags on success.
2706
 * @return  WOLFSSL_FAILURE when ctx is NULL.
2707
 */
2708
int wolfSSL_CTX_get_verify_mode(const WOLFSSL_CTX* ctx)
2709
{
2710
    int mode = 0;
2711
2712
    WOLFSSL_ENTER("wolfSSL_CTX_get_verify_mode");
2713
2714
    if (ctx == NULL) {
2715
        mode = WOLFSSL_FAILURE;
2716
    }
2717
    else if (ctx->verifyNone) {
2718
        /* VERIFY_NONE is exclusive of the other verify flags. */
2719
        mode = WOLFSSL_VERIFY_NONE;
2720
    }
2721
    else {
2722
        /* Build the mode as a bitmask of the enabled verify flags. */
2723
        if (ctx->verifyPeer) {
2724
            mode |= WOLFSSL_VERIFY_PEER;
2725
        }
2726
        if (ctx->failNoCert) {
2727
            mode |= WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2728
        }
2729
        if (ctx->failNoCertxPSK) {
2730
            mode |= WOLFSSL_VERIFY_FAIL_EXCEPT_PSK;
2731
        }
2732
        #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
2733
        if (ctx->verifyPostHandshake) {
2734
            mode |= WOLFSSL_VERIFY_POST_HANDSHAKE;
2735
        }
2736
        #endif
2737
    }
2738
2739
    WOLFSSL_LEAVE("wolfSSL_CTX_get_verify_mode", mode);
2740
    return mode;
2741
}
2742
2743
#endif
2744
2745
2746
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
2747
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
2748
/* Create a stack of X509 certificates from a DER encoded certificate chain.
2749
 *
2750
 * The chain buffer holds each certificate as: 3 byte length | X509 DER data.
2751
 *
2752
 * @param [in]  der     DER encoded certificate chain.
2753
 * @param [in]  derLen  Length of certificate chain buffer in bytes.
2754
 * @param [in]  heap    Dynamic memory hint.
2755
 * @param [out] chain   Stack of X509 certificates. Holds as much of the
2756
 *                      chain as was created on failure.
2757
 * @return  WOLFSSL_SUCCESS on success.
2758
 * @return  WOLFSSL_FAILURE on allocation or decode error.
2759
 */
2760
static int wolfssl_certchain_to_x509_stack(byte* der, word32 derLen,
2761
    void* heap, WOLF_STACK_OF(X509)** chain)
2762
{
2763
    int            ret = WOLFSSL_SUCCESS;
2764
    word32         idx;
2765
    word32         length;
2766
    WOLFSSL_STACK* node;
2767
    WOLFSSL_STACK* last = NULL;
2768
2769
    /* Create a new stack of WOLFSSL_X509 object from chain buffer. */
2770
    for (idx = 0; idx < derLen; ) {
2771
        /* Need 3 bytes for the length of the DER encoded certificate. */
2772
        if ((derLen - idx) < 3) {
2773
            ret = WOLFSSL_FAILURE;
2774
            break;
2775
        }
2776
2777
        /* Format: 3 byte length | X509 DER data. */
2778
        ato24(der + idx, &length);
2779
        idx += 3;
2780
2781
        /* Ensure the DER encoded certificate is contained in the buffer. */
2782
        if (length > (derLen - idx)) {
2783
            ret = WOLFSSL_FAILURE;
2784
            break;
2785
        }
2786
2787
        node = wolfSSL_sk_X509_new_null();
2788
        if (node == NULL) {
2789
            ret = WOLFSSL_FAILURE;
2790
            break;
2791
        }
2792
        node->next = NULL;
2793
2794
        /* Create a new X509 from DER encoded data. */
2795
        node->data.x509 = wolfSSL_X509_d2i_ex(NULL, der + idx, (int)length,
2796
            heap);
2797
        if (node->data.x509 == NULL) {
2798
            XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
2799
            /* Return as much of the chain as we created. */
2800
            ret = WOLFSSL_FAILURE;
2801
            break;
2802
        }
2803
        idx += length;
2804
2805
        /* Add object to the end of the stack. */
2806
        if (last == NULL) {
2807
            node->num = 1;
2808
            *chain = node;
2809
        }
2810
        else {
2811
            (*chain)->num++;
2812
            last->next = node;
2813
        }
2814
2815
        last = node;
2816
    }
2817
2818
    return ret;
2819
}
2820
2821
/* Get the extra certificate chain set on the context as a stack of X509.
2822
 *
2823
 * Builds the stack from the context's certificate chain buffer when needed.
2824
 *
2825
 * @param [in]  ctx    SSL/TLS context object.
2826
 * @param [out] chain  Stack of X509 certificates.
2827
 * @return  WOLFSSL_SUCCESS on success.
2828
 * @return  WOLFSSL_FAILURE when ctx or chain is NULL, or on allocation error.
2829
 */
2830
int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx,
2831
    WOLF_STACK_OF(X509)** chain)
2832
{
2833
    int ret = WOLFSSL_SUCCESS;
2834
2835
    if ((ctx == NULL) || (chain == NULL)) {
2836
        ret = WOLFSSL_FAILURE;
2837
    }
2838
    else if (ctx->x509Chain != NULL) {
2839
        *chain = ctx->x509Chain;
2840
    }
2841
    else {
2842
        /* If there are no chains then success! */
2843
        *chain = NULL;
2844
        if ((ctx->certChain != NULL) && (ctx->certChain->length != 0)) {
2845
            /* Build a stack of X509 from the DER certificate chain buffer. */
2846
            ret = wolfssl_certchain_to_x509_stack(ctx->certChain->buffer,
2847
                ctx->certChain->length, ctx->heap, chain);
2848
            /* Cache the chain - holds as much as was created on failure. */
2849
            ctx->x509Chain = *chain;
2850
        }
2851
    }
2852
2853
    return ret;
2854
}
2855
2856
/* Get the certificate chain set on the context.
2857
 *
2858
 * @param [in]  ctx  SSL/TLS context object.
2859
 * @param [out] sk   Stack of X509 certificates.
2860
 * @return  WOLFSSL_SUCCESS on success.
2861
 * @return  WOLFSSL_FAILURE when ctx or sk is NULL.
2862
 */
2863
int wolfSSL_CTX_get0_chain_certs(WOLFSSL_CTX *ctx,
2864
        WOLF_STACK_OF(WOLFSSL_X509) **sk)
2865
{
2866
    int ret;
2867
2868
    WOLFSSL_ENTER("wolfSSL_CTX_get0_chain_certs");
2869
2870
    if ((ctx == NULL) || (sk == NULL)) {
2871
        WOLFSSL_MSG("Bad parameter");
2872
        ret = WOLFSSL_FAILURE;
2873
    }
2874
    else {
2875
        /* This function should return ctx->x509Chain if it is populated,
2876
         * otherwise it should be populated from ctx->certChain.  This matches
2877
         * the behavior of wolfSSL_CTX_get_extra_chain_certs, so it is used
2878
         * directly. */
2879
        ret = wolfSSL_CTX_get_extra_chain_certs(ctx, sk);
2880
    }
2881
2882
    return ret;
2883
}
2884
2885
#ifdef KEEP_OUR_CERT
2886
/* Get our certificate chain set on the object.
2887
 *
2888
 * @param [in]  ssl  SSL/TLS object.
2889
 * @param [out] sk   Stack of X509 certificates.
2890
 * @return  WOLFSSL_SUCCESS on success.
2891
 * @return  WOLFSSL_FAILURE when ssl or sk is NULL.
2892
 */
2893
int wolfSSL_get0_chain_certs(WOLFSSL *ssl, WOLF_STACK_OF(WOLFSSL_X509) **sk)
2894
{
2895
    int ret = WOLFSSL_SUCCESS;
2896
2897
    WOLFSSL_ENTER("wolfSSL_get0_chain_certs");
2898
2899
    if ((ssl == NULL) || (sk == NULL)) {
2900
        WOLFSSL_MSG("Bad parameter");
2901
        ret = WOLFSSL_FAILURE;
2902
    }
2903
    else {
2904
        /* Return our own certificate chain held on the object. */
2905
        *sk = ssl->ourCertChain;
2906
    }
2907
2908
    return ret;
2909
}
2910
#endif
2911
2912
#endif
2913
2914
#ifdef WOLFSSL_CERT_SETUP_CB
2915
/* ctx->CBClientCert is only in the structure under OPENSSL_EXTRA, so the
2916
 * setter cannot be compiled more widely than that. */
2917
#ifdef OPENSSL_EXTRA
2918
/* Set the callback that supplies a client certificate and key.
2919
 *
2920
 * Called during the handshake when the server asks for client authentication
2921
 * and no certificate and key have been loaded.
2922
 *
2923
 * @param [in, out] ctx  SSL/TLS CTX object.
2924
 * @param [in]      cb   Callback to call. NULL to clear.
2925
 */
2926
void wolfSSL_CTX_set_client_cert_cb(WOLFSSL_CTX *ctx, client_cert_cb cb)
2927
{
2928
    WOLFSSL_ENTER("wolfSSL_CTX_set_client_cert_cb");
2929
2930
    if (ctx != NULL) {
2931
        ctx->CBClientCert = cb;
2932
    }
2933
}
2934
#endif
2935
2936
/* Set the certificate setup callback on the SSL/TLS CTX object.
2937
 *
2938
 * The callback is called during the handshake to allow the certificate and
2939
 * key to be chosen or loaded on demand.
2940
 *
2941
 * @param [in, out] ctx  SSL/TLS CTX object.
2942
 * @param [in]      cb   Certificate setup callback. NULL to clear.
2943
 * @param [in]      arg  Context to pass to the callback.
2944
 */
2945
void wolfSSL_CTX_set_cert_cb(WOLFSSL_CTX* ctx,
2946
    CertSetupCallback cb, void *arg)
2947
{
2948
    WOLFSSL_ENTER("wolfSSL_CTX_set_cert_cb");
2949
2950
    if (ctx != NULL) {
2951
        ctx->certSetupCb = cb;
2952
        ctx->certSetupCbArg = arg;
2953
    }
2954
}
2955
2956
/* Call the certificate setup callback and translate its result.
2957
 *
2958
 * @param [in, out] ssl  SSL/TLS object.
2959
 * @return  0 when no callback is set or the callback reported success.
2960
 * @return  CLIENT_CERT_CB_ERROR when the callback failed or returned an
2961
 *          unrecognized value. A fatal alert is sent when it failed.
2962
 * @return  WOLFSSL_ERROR_WANT_X509_LOOKUP when the callback returned a
2963
 *          negative value to ask to be called again.
2964
 * @return  BAD_STATE_E when the callback replaced a certificate or key on the
2965
 *          CTX that the SSL uses. A fatal alert is sent.
2966
 */
2967
int CertSetupCbWrapper(WOLFSSL* ssl)
2968
{
2969
    int ret = 0;
2970
2971
    if (ssl->ctx->certSetupCb != NULL) {
2972
        WOLFSSL_MSG("Calling user cert setup callback");
2973
        ret = ssl->ctx->certSetupCb(ssl, ssl->ctx->certSetupCbArg);
2974
    #ifndef NO_CERTS
2975
        if (CheckSSL_CTX_CertsAndKeys(ssl) != 0) {
2976
            SendAlert(ssl, alert_fatal, internal_error);
2977
            return BAD_STATE_E;
2978
        }
2979
    #endif
2980
        if (ret == 1) {
2981
            WOLFSSL_MSG("User cert callback returned success");
2982
            ret = 0;
2983
        }
2984
        else if (ret == 0) {
2985
            SendAlert(ssl, alert_fatal, internal_error);
2986
            ret = CLIENT_CERT_CB_ERROR;
2987
        }
2988
        else if (ret < 0) {
2989
            ret = WOLFSSL_ERROR_WANT_X509_LOOKUP;
2990
        }
2991
        else {
2992
            WOLFSSL_MSG("Unexpected user callback return");
2993
            ret = CLIENT_CERT_CB_ERROR;
2994
        }
2995
    }
2996
    return ret;
2997
}
2998
#endif /* WOLFSSL_CERT_SETUP_CB */
2999
3000
3001
#ifdef SESSION_CERTS
3002
/* Decode the X509 DER encoded certificate into a WOLFSSL_X509 object.
3003
 *
3004
 * @param [in, out] x509  WOLFSSL_X509 object to decode into.
3005
 * @param [in]      in    X509 DER data.
3006
 * @param [in]      len   Length of the X509 DER data.
3007
 * @return  0 on success.
3008
 * @return  BAD_FUNC_ARG when x509 or in is NULL, or len is not positive.
3009
 * @return  MEMORY_E when dynamic memory allocation fails.
3010
 * @return  Other negative value when the certificate cannot be parsed.
3011
 */
3012
static int DecodeToX509(WOLFSSL_X509* x509, const byte* in, int len)
3013
{
3014
    int ret = 0;
3015
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
3016
3017
    /* Validate parameters. */
3018
    if ((x509 == NULL) || (in == NULL) || (len <= 0)) {
3019
        ret = BAD_FUNC_ARG;
3020
    }
3021
3022
    if (ret == 0) {
3023
        WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
3024
            ret = MEMORY_E);
3025
    }
3026
3027
    if (ret == 0) {
3028
        /* Create a DecodedCert object and copy fields into WOLFSSL_X509
3029
         * object. */
3030
        InitDecodedCert(cert, (byte*)in, (word32)len, NULL);
3031
        ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL);
3032
        if (ret == 0) {
3033
        /* Check if x509 was not previously initialized by wolfSSL_X509_new() */
3034
            if (x509->dynamicMemory != TRUE) {
3035
                /* A non-dynamic x509 (e.g. ssl->peerCert) may already hold
3036
                 * decoded contents; free them before re-populating. ReinitX509
3037
                 * keeps the object's heap and reference state, as the object
3038
                 * may be referenced elsewhere. */
3039
                ReinitX509(x509);
3040
            }
3041
            ret = CopyDecodedToX509(x509, cert);
3042
        }
3043
        FreeDecodedCert(cert);
3044
        WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
3045
    }
3046
3047
    return ret;
3048
}
3049
#endif /* SESSION_CERTS */
3050
3051
3052
#ifdef KEEP_PEER_CERT
3053
/* Get the kept peer certificate, owned by the SSL/TLS object.
3054
 *
3055
 * The certificate is built from its kept encoding on first use. Otherwise it
3056
 * is decoded from the session chain, and kept, when not already available on
3057
 * the object.
3058
 *
3059
 * @param [in, out] ssl  SSL/TLS object.
3060
 * @return  Kept peer certificate on success.
3061
 * @return  NULL when no peer certificate is available or it cannot be
3062
 *          decoded.
3063
 */
3064
static WOLFSSL_X509* LoadPeerCert(WOLFSSL* ssl)
3065
{
3066
    WOLFSSL_X509* peer = GetPeerCert(ssl);
3067
3068
    #ifdef SESSION_CERTS
3069
    if (((peer == NULL) || (peer->issuer.sz == 0)) &&
3070
            (ssl->session->chain.count > 0)) {
3071
        #ifdef WOLFSSL_DYNAMIC_PEER_CERT
3072
        WOLFSSL_X509* x509 = wolfSSL_X509_new_ex(ssl->heap);
3073
        if ((x509 != NULL) && (DecodeToX509(x509,
3074
                ssl->session->chain.certs[0].buffer,
3075
                ssl->session->chain.certs[0].length) == 0)) {
3076
            FreePeerCert(ssl);
3077
            ssl->peerCert = x509;
3078
            peer = x509;
3079
        }
3080
        else {
3081
            wolfSSL_X509_free(x509);
3082
            peer = NULL;
3083
        }
3084
        #else
3085
        if (DecodeToX509(peer, ssl->session->chain.certs[0].buffer,
3086
                ssl->session->chain.certs[0].length) != 0) {
3087
            peer = NULL;
3088
        }
3089
        #endif
3090
    }
3091
    #endif
3092
    if ((peer != NULL) && (peer->issuer.sz == 0)) {
3093
        peer = NULL;
3094
    }
3095
3096
    return peer;
3097
}
3098
3099
/* Get the peer's certificate.
3100
 *
3101
 * The certificate is decoded from the session chain, and kept, when not
3102
 * already available on the object. With WOLFSSL_DYNAMIC_PEER_CERT and X509
3103
 * reference counting (OPENSSL_EXTRA or OPENSSL_EXTRA_X509_SMALL) the kept
3104
 * object is returned with a new reference, as OpenSSL does; otherwise a copy
3105
 * is returned. Either way the caller must free the returned certificate with
3106
 * wolfSSL_X509_free() and it stays valid after the SSL/TLS object is freed.
3107
 *
3108
 * @param [in, out] ssl  SSL/TLS object.
3109
 * @return  Peer's X509 certificate on success.
3110
 * @return  NULL when ssl is NULL, no peer certificate was kept or dynamic
3111
 *          memory allocation fails.
3112
 */
3113
WOLFSSL_ABI
3114
WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl)
3115
{
3116
    WOLFSSL_X509* ret = NULL;
3117
    WOLFSSL_X509* peer = NULL;
3118
3119
    WOLFSSL_ENTER("wolfSSL_get_peer_certificate");
3120
3121
    if (ssl != NULL) {
3122
        peer = LoadPeerCert(ssl);
3123
    }
3124
    if (peer != NULL) {
3125
    #if defined(WOLFSSL_DYNAMIC_PEER_CERT) && \
3126
        (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
3127
        if (wolfSSL_X509_up_ref(peer) == WOLFSSL_SUCCESS) {
3128
            ret = peer;
3129
        }
3130
    #else
3131
        ret = wolfSSL_X509_dup(peer);
3132
    #endif
3133
    }
3134
    WOLFSSL_LEAVE("wolfSSL_get_peer_certificate", ret != NULL);
3135
    return ret;
3136
}
3137
3138
#endif /* KEEP_PEER_CERT */
3139
3140
/* NO_CERTS is part of the guard so that the declaration of
3141
 * x509GetIssuerFromCM() in src/ssl.c, its definition in src/x509_str.c and
3142
 * the call below all agree on when they exist. */
3143
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) && !defined(NO_CERTS)
3144
/* Get the stack of the peer's certificates.
3145
 *
3146
 * The stack is owned by the SSL/TLS object and is disposed of with it, so the
3147
 * caller must not free it.
3148
 *
3149
 * @param [in, out] ssl  SSL/TLS object. Declared const, but the chain is
3150
 *                       built into it on the first call.
3151
 * @return  Stack of the peer's certificates on success.
3152
 * @return  NULL when ssl is NULL or no chain was received.
3153
 */
3154
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl)
3155
{
3156
    WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
3157
3158
    WOLFSSL_ENTER("wolfSSL_get_peer_cert_chain");
3159
3160
    if (ssl != NULL) {
3161
        /* Try to populate when not present or empty. */
3162
        if ((ssl->peerCertChain == NULL) ||
3163
                (wolfSSL_sk_X509_num(ssl->peerCertChain) == 0)) {
3164
            wolfSSL_set_peer_cert_chain((WOLFSSL*)ssl);
3165
        }
3166
        ret = ssl->peerCertChain;
3167
    }
3168
3169
    return ret;
3170
}
3171
3172
/* Push the chain of issuing CAs onto the stack.
3173
 *
3174
 * Each certificate's issuer is looked up in turn, stopping when no further
3175
 * issuer is known or the maximum chain depth is reached.
3176
 *
3177
 * @param [in]      cm  Certificate manager queried for each issuer.
3178
 * @param [in]      x   Certificate whose issuer is looked up first.
3179
 * @param [in, out] sk  Stack the issuers are pushed onto.
3180
 * @return  0 on success or when no issuer was found.
3181
 * @return  WOLFSSL_FATAL_ERROR when an issuer could not be pushed.
3182
 */
3183
static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm,
3184
        WOLFSSL_X509 *x, WOLFSSL_STACK* sk)
3185
{
3186
    int ret = 0;
3187
    int i;
3188
3189
    for (i = 0; (ret == 0) && (i < MAX_CHAIN_DEPTH); i++) {
3190
        WOLFSSL_X509* issuer = NULL;
3191
3192
        /* No more issuers known - chain is as complete as it can be. */
3193
        if (x509GetIssuerFromCM(&issuer, cm, x) != WOLFSSL_SUCCESS) {
3194
            break;
3195
        }
3196
        if (wolfSSL_sk_X509_push(sk, issuer) <= 0) {
3197
            /* Not stored on the stack - dispose of it here. */
3198
            wolfSSL_X509_free(issuer);
3199
            ret = WOLFSSL_FATAL_ERROR;
3200
        }
3201
        else {
3202
            x = issuer;
3203
        }
3204
    }
3205
3206
    return ret;
3207
}
3208
3209
3210
/* Decode one certificate of the session chain onto the stack.
3211
 *
3212
 * A certificate that did not fit its slot holds an empty one. The peer's own
3213
 * certificate, index 0, is taken from the copy kept on the SSL/TLS object
3214
 * instead; any other is left out of the stack, as it was before it had a slot.
3215
 *
3216
 * @param [in, out] ssl     SSL/TLS object. The kept peer certificate may be
3217
 *                          built from its encoding.
3218
 * @param [in]      idx     Index of the certificate in the chain.
3219
 * @param [in, out] sk      Stack to add the certificate to.
3220
 * @param [out]     pushed  Certificate added to the stack, NULL when the slot
3221
 *                          was empty. Owned by the stack.
3222
 * @return  0 on success.
3223
 * @return  MEMORY_E when the certificate object cannot be created.
3224
 * @return  Other negative value when the certificate cannot be decoded or
3225
 *          stored.
3226
 */
3227
static int PushPeerCertToChain(WOLFSSL* ssl, int idx, WOLFSSL_STACK* sk,
3228
    WOLFSSL_X509** pushed)
3229
{
3230
    int ret = 0;
3231
    WOLFSSL_X509* x509 = NULL;
3232
3233
    *pushed = NULL;
3234
3235
    if (ssl->session->chain.certs[idx].length == 0) {
3236
    #ifdef KEEP_PEER_CERT
3237
        WOLFSSL_X509* peer = (idx == 0) ? GetPeerCert(ssl) : NULL;
3238
3239
        if ((peer != NULL) && (peer->issuer.sz > 0)) {
3240
            x509 = wolfSSL_X509_dup(peer);
3241
            if (x509 == NULL) {
3242
                WOLFSSL_MSG("Error duplicating peer certificate");
3243
                ret = MEMORY_E;
3244
            }
3245
        }
3246
    #endif
3247
        if ((ret == 0) && (x509 == NULL)) {
3248
            /* An issuer must never slide into the leaf's slot. */
3249
            if (idx == 0) {
3250
                return WOLFSSL_FATAL_ERROR;
3251
            }
3252
            /* Nothing to add for this index. */
3253
            return 0;
3254
        }
3255
    }
3256
    else {
3257
        x509 = wolfSSL_X509_new_ex(ssl->heap);
3258
        if (x509 == NULL) {
3259
            WOLFSSL_MSG("Error Creating X509");
3260
            ret = MEMORY_E;
3261
        }
3262
        else {
3263
            ret = DecodeToX509(x509, ssl->session->chain.certs[idx].buffer,
3264
                ssl->session->chain.certs[idx].length);
3265
        }
3266
    }
3267
3268
    if (ret == 0) {
3269
        if (wolfSSL_sk_X509_push(sk, x509) <= 0) {
3270
            ret = WOLFSSL_FATAL_ERROR;
3271
        }
3272
        else {
3273
            /* The stack owns the certificate from here on. */
3274
            *pushed = x509;
3275
            x509 = NULL;
3276
        }
3277
    }
3278
    if (ret != 0) {
3279
        WOLFSSL_MSG("Error decoding cert");
3280
        /* NULL once the stack has taken ownership, and freeing NULL does
3281
         * nothing, so this only releases a certificate that never got there. */
3282
        wolfSSL_X509_free(x509);
3283
    }
3284
3285
    return ret;
3286
}
3287
3288
/* Build a stack of the peer's certificates from the session chain.
3289
 *
3290
 * For a verified chain the CA certificates known for the last certificate are
3291
 * placed at the bottom of the stack.
3292
 *
3293
 * @param [in, out] ssl           SSL/TLS object. The kept peer certificate
3294
 *                                may be built from its encoding.
3295
 * @param [in]      verifiedFlag  Whether to append the known CA chain.
3296
 * @return  Stack of the peer's certificates on success.
3297
 * @return  NULL when ssl is NULL, the session holds no chain, or a certificate
3298
 *          cannot be created, decoded or stored.
3299
 */
3300
static WOLF_STACK_OF(WOLFSSL_X509)* CreatePeerCertChain(WOLFSSL* ssl,
3301
    int verifiedFlag)
3302
{
3303
    WOLFSSL_STACK* sk = NULL;
3304
    int err = 0;
3305
3306
    WOLFSSL_ENTER("CreatePeerCertChain");
3307
3308
    /* There is nothing to build from without a session chain. */
3309
    if ((ssl == NULL) || (ssl->session->chain.count == 0)) {
3310
        err = 1;
3311
    }
3312
    else {
3313
        sk = wolfSSL_sk_X509_new_null();
3314
        if (sk == NULL) {
3315
            WOLFSSL_MSG("Error creating stack");
3316
            err = 1;
3317
        }
3318
    }
3319
3320
    if (!err) {
3321
        WOLFSSL_X509* last = NULL;
3322
        int i;
3323
3324
        for (i = 0; i < ssl->session->chain.count; i++) {
3325
            WOLFSSL_X509* pushed = NULL;
3326
3327
            if (PushPeerCertToChain(ssl, i, sk, &pushed) != 0) {
3328
                err = 1;
3329
                break;
3330
            }
3331
            if (pushed != NULL) {
3332
                last = pushed;
3333
            }
3334
        }
3335
3336
        /* Append the CA chain known for the last certificate of a verified
3337
         * chain. It is owned by the stack, so it is still there to look the
3338
         * issuers up with. */
3339
        if ((!err) && verifiedFlag && (last != NULL)) {
3340
            SSL_CM_WARNING(ssl);
3341
            if (PushCAx509Chain(SSL_CM(ssl), last, sk) != 0) {
3342
                err = 1;
3343
            }
3344
        }
3345
    }
3346
3347
    if (err) {
3348
        /* Certificates already pushed are freed with the stack. */
3349
        wolfSSL_sk_X509_pop_free(sk, NULL);
3350
        sk = NULL;
3351
    }
3352
3353
    return sk;
3354
}
3355
3356
3357
/* Build and store the stack of the peer's certificates.
3358
 *
3359
 * On the server the leaf certificate is moved out of the stack and kept as the
3360
 * session's peer. The stack is disposed of when the SSL/TLS object is.
3361
 *
3362
 * @param [in, out] ssl  SSL/TLS object.
3363
 * @return  Stack of the peer's certificates on success.
3364
 * @return  NULL when ssl is NULL, the session holds no chain, or the stack
3365
 *          cannot be built.
3366
 */
3367
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl)
3368
{
3369
    WOLFSSL_STACK* sk = NULL;
3370
3371
    WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain");
3372
3373
    /* Validate parameters. */
3374
    if ((ssl != NULL) && (ssl->session->chain.count > 0)) {
3375
        sk = CreatePeerCertChain(ssl, 0);
3376
    }
3377
3378
    if (sk != NULL) {
3379
        if (ssl->options.side == WOLFSSL_SERVER_END) {
3380
            /* Replace any peer kept from a previous call. */
3381
            if (ssl->session->peer != NULL) {
3382
                wolfSSL_X509_free(ssl->session->peer);
3383
            }
3384
3385
            ssl->session->peer = wolfSSL_sk_X509_shift(sk);
3386
            ssl->session->peerVerifyRet = ssl->peerVerifyRet;
3387
        }
3388
        if (ssl->peerCertChain != NULL) {
3389
            wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL);
3390
        }
3391
        /* This is Free'd when ssl is Free'd */
3392
        ssl->peerCertChain = sk;
3393
    }
3394
3395
    return sk;
3396
}
3397
3398
#ifdef KEEP_PEER_CERT
3399
/* Get the peer's certificate chain, verified against the store.
3400
 *
3401
 * Implemented in a similar way to ngx_ssl_ocsp_validate() when
3402
 * SSL_get0_verified_chain is not available. The chain is stored on the SSL/TLS
3403
 * object and disposed of with it, so the caller must not free it.
3404
 *
3405
 * @param [in, out] ssl  SSL/TLS object. Declared const, but the verified
3406
 *                       chain is stored into it.
3407
 * @return  Stack of verified certificates on success.
3408
 * @return  NULL when ssl or its context is NULL, no peer certificate was kept,
3409
 *          the chain cannot be built, or verification fails.
3410
 */
3411
WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl)
3412
{
3413
    WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL;
3414
    WOLFSSL_X509_STORE_CTX* storeCtx = NULL;
3415
    WOLFSSL_X509* peerCert = NULL;
3416
    int err = 0;
3417
3418
    WOLFSSL_ENTER("wolfSSL_get0_verified_chain");
3419
3420
    /* Validate parameters. */
3421
    if ((ssl == NULL) || (ssl->ctx == NULL)) {
3422
        WOLFSSL_MSG("Bad parameter");
3423
        err = 1;
3424
    }
3425
3426
    if (!err) {
3427
        /* Owned by ssl, so not freed here. */
3428
        peerCert = LoadPeerCert((WOLFSSL*)ssl);
3429
        if (peerCert == NULL) {
3430
            WOLFSSL_MSG("No peer certificate");
3431
            err = 1;
3432
        }
3433
    }
3434
3435
    if (!err) {
3436
        chain = CreatePeerCertChain((WOLFSSL*)ssl, 1);
3437
        if (chain == NULL) {
3438
            WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error");
3439
            err = 1;
3440
        }
3441
        else {
3442
            /* Replace any chain kept from a previous call. */
3443
            if (ssl->verifiedChain != NULL) {
3444
                wolfSSL_sk_X509_pop_free(ssl->verifiedChain, NULL);
3445
            }
3446
            /* This is Free'd when ssl is Free'd */
3447
            ((WOLFSSL*)ssl)->verifiedChain = chain;
3448
        }
3449
    }
3450
3451
    if (!err) {
3452
        storeCtx = wolfSSL_X509_STORE_CTX_new();
3453
        if (storeCtx == NULL) {
3454
            WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error");
3455
            err = 1;
3456
        }
3457
    }
3458
3459
    if (!err) {
3460
        if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl), peerCert,
3461
                chain) != WOLFSSL_SUCCESS) {
3462
            WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error");
3463
            err = 1;
3464
        }
3465
        else if (wolfSSL_X509_verify_cert(storeCtx) <= 0) {
3466
            WOLFSSL_MSG("wolfSSL_X509_verify_cert error");
3467
            err = 1;
3468
        }
3469
    }
3470
3471
    wolfSSL_X509_STORE_CTX_free(storeCtx);
3472
    if (err) {
3473
        /* The chain stays owned by the object; report failure only. */
3474
        chain = NULL;
3475
    }
3476
3477
    return chain;
3478
}
3479
#endif /* KEEP_PEER_CERT */
3480
#endif /* SESSION_CERTS && OPENSSL_EXTRA && !NO_CERTS */
3481
3482
#endif /* !WOLFCRYPT_ONLY */
3483
3484
#endif /* !WOLFSSL_SSL_API_CERT_INCLUDED */