Coverage Report

Created: 2026-04-05 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all-8bit/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
0
    if (ctx->method->side != WOLFSSL_SERVER_END)
46
0
        return SIDE_ERROR;
47
48
0
    ctx->mutualAuth = (byte)req;
49
50
0
    return 0;
51
0
}
52
53
/* Set whether mutual authentication is required for the connection.
54
 * Server side only.
55
 *
56
 * @param [in] ssl  The SSL/TLS object.
57
 * @param [in] req  1 to indicate required and 0 when not.
58
 * @return  0 on success.
59
 * @return  BAD_FUNC_ARG when ssl is NULL.
60
 * @return  SIDE_ERROR when not a server
61
 */
62
int wolfSSL_mutual_auth(WOLFSSL* ssl, int req)
63
0
{
64
0
    if (ssl == NULL)
65
0
        return BAD_FUNC_ARG;
66
0
    if (ssl->options.side != WOLFSSL_SERVER_END)
67
0
        return SIDE_ERROR;
68
69
0
    ssl->options.mutualAuth = (word16)req;
70
71
0
    return 0;
72
0
}
73
74
/* Get the certificate manager from the WOLFSSL_CTX.
75
 *
76
 * @param [in] ctx  SSL/TLS CTX object.
77
 * @return  Certificate manager object on success.
78
 * @return  NULL when ctx is NULL.
79
 */
80
WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx)
81
0
{
82
0
    WOLFSSL_CERT_MANAGER* cm = NULL;
83
84
0
    if (ctx)
85
0
        cm = ctx->cm;
86
87
0
    return cm;
88
0
}
89
90
/* Sets the max chain depth when verifying a certificate chain.
91
 *
92
 * Default depth is set to MAX_CHAIN_DEPTH.
93
 *
94
 * @param [in] ctx    WOLFSSL_CTX structure to set depth in
95
 * @param [in] depth  max depth
96
 */
97
void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx, int depth)
98
0
{
99
0
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify_depth");
100
101
0
    if ((ctx == NULL) || (depth < 0) || (depth > MAX_CHAIN_DEPTH)) {
102
0
        WOLFSSL_MSG("Bad depth argument, too large or less than 0");
103
0
    }
104
0
    else {
105
0
        ctx->verifyDepth = (byte)depth;
106
0
    }
107
0
}
108
109
110
/* Get certificate chaining depth of SSL/TLS context object
111
 *
112
 * @param [in] ctx  SSL/TLS context object.
113
 * @return  Verification depth on success.
114
 * @return  BAD_FUNC_ARG when ctx is NULL.
115
 */
116
long wolfSSL_CTX_get_verify_depth(WOLFSSL_CTX* ctx)
117
0
{
118
0
    long ret;
119
120
0
    if (ctx == NULL) {
121
0
        ret = BAD_FUNC_ARG;
122
0
    }
123
0
    else {
124
0
    #ifndef OPENSSL_EXTRA
125
0
        ret = MAX_CHAIN_DEPTH;
126
    #else
127
        ret = ctx->verifyDepth;
128
    #endif
129
0
    }
130
131
0
    return ret;
132
0
}
133
134
/* Get certificate chaining depth of SSL/TLS object
135
 *
136
 * @param [in] ssl  SSL/TLS object.
137
 * @return  Verification depth on success.
138
 * @return  BAD_FUNC_ARG when ssl is NULL.
139
 */
140
long wolfSSL_get_verify_depth(WOLFSSL* ssl)
141
0
{
142
0
    long ret;
143
144
0
    if (ssl == NULL) {
145
0
        ret = BAD_FUNC_ARG;
146
0
    }
147
0
    else {
148
0
    #ifndef OPENSSL_EXTRA
149
0
        ret = MAX_CHAIN_DEPTH;
150
    #else
151
        ret = ssl->options.verifyDepth;
152
    #endif
153
0
    }
154
155
0
    return ret;
156
0
}
157
158
#if defined(HAVE_RPK)
159
/* TODO: Change this to use a bitfield. */
160
161
/* Confirm that all the byte data in the buffer is unique.
162
 *
163
 * @param [in] buf  Buffer to check.
164
 * @param [in] len  Length of buffer in bytes.
165
 * @return  1 if all the byte data in the buffer is unique.
166
 * @return  0 otherwise.
167
 */
168
static int isArrayUnique(const char* buf, size_t len)
169
{
170
    size_t i;
171
    /* check the array is unique */
172
    for (i = 0; i < len - 1; ++i) {
173
        size_t j;
174
        for (j = i + 1; j < len; ++j) {
175
            if (buf[i] == buf[j]) {
176
                return 0;
177
            }
178
        }
179
    }
180
    return 1;
181
}
182
/* Set user preference for the {client,server}_cert_type extension.
183
 *
184
 * Takes byte array containing cert types the caller can provide to its peer.
185
 * Cert types are in preferred order in the array.
186
 *
187
 * @param [in] cfg     Raw Public Key configuration.
188
 * @param [in] client  Indicates whether this is the client side.
189
 * @param [in] buf     List of certificate types.
190
 * @param [in] len     Length of certificate types.
191
 * @return  1 on success.
192
 * @return  BAD_FUNC_ARG when cfg is NULL.
193
 * @return  BAD_FUNC_ARG when len is too long.
194
 * @return  BAD_FUNC_ARG when buffer values are not unique.
195
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
196
 */
197
static int set_cert_type(RpkConfig* cfg, int client, const char* buf,
198
    int len)
199
{
200
    int i;
201
    byte* certTypeCnt;
202
    byte* certTypes;
203
204
    /* Validate parameters. */
205
    if ((cfg == NULL) || (len > (client ? MAX_CLIENT_CERT_TYPE_CNT :
206
                                          MAX_SERVER_CERT_TYPE_CNT))) {
207
        return BAD_FUNC_ARG;
208
    }
209
210
    /* Get preferred certificate types for side. */
211
    if (client) {
212
        certTypeCnt = &cfg->preferred_ClientCertTypeCnt;
213
        certTypes   =  cfg->preferred_ClientCertTypes;
214
    }
215
    else {
216
        certTypeCnt = &cfg->preferred_ServerCertTypeCnt;
217
        certTypes   =  cfg->preferred_ServerCertTypes;
218
    }
219
    /* If no buffer or empty buffer passed in, set the defaults. */
220
    if ((buf == NULL) || (len == 0)) {
221
        *certTypeCnt = 1;
222
        for (i = 0; i < 2; i++) {
223
            certTypes[i] = WOLFSSL_CERT_TYPE_X509;
224
        }
225
        return 1;
226
    }
227
228
    /* Check that the certificate types set are unique. */
229
    if (!isArrayUnique(buf, (size_t)len))
230
        return BAD_FUNC_ARG;
231
232
    /* Check that the certificate types being set are known and then set. */
233
    for (i = 0; i < len; i++) {
234
        if ((buf[i] != WOLFSSL_CERT_TYPE_RPK) &&
235
                (buf[i] != WOLFSSL_CERT_TYPE_X509)) {
236
            return BAD_FUNC_ARG;
237
        }
238
        certTypes[i] = (byte)buf[i];
239
    }
240
    *certTypeCnt = len;
241
242
    return 1;
243
}
244
/* Set the client certificate types against the SSL/TLS context.
245
 *
246
 * @param [in] ctx  SSL/TLS context object.
247
 * @param [in] buf  List of certificate types.
248
 * @param [in] len  Length of certificate types.
249
 * @return  1 on success.
250
 * @return  BAD_FUNC_ARG when ctx is NULL.
251
 * @return  BAD_FUNC_ARG when len is too long.
252
 * @return  BAD_FUNC_ARG when buffer values are not unique.
253
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
254
 */
255
int wolfSSL_CTX_set_client_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len)
256
{
257
    int ret;
258
259
    if (ctx == NULL) {
260
        ret = BAD_FUNC_ARG;
261
    }
262
    else {
263
        ret = set_cert_type(&ctx->rpkConfig, 1, buf, len);
264
    }
265
266
    return ret;
267
}
268
/* Set the server certificate types against the SSL/TLS context.
269
 *
270
 * @param [in] ctx  SSL/TLS context object.
271
 * @param [in] buf  List of certificate types.
272
 * @param [in] len  Length of certificate types.
273
 * @return  1 on success.
274
 * @return  BAD_FUNC_ARG when ctx is NULL.
275
 * @return  BAD_FUNC_ARG when len is too long.
276
 * @return  BAD_FUNC_ARG when buffer values are not unique.
277
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
278
 */
279
int wolfSSL_CTX_set_server_cert_type(WOLFSSL_CTX* ctx, const char* buf, int len)
280
{
281
    int ret;
282
283
    if (ctx == NULL) {
284
        ret = BAD_FUNC_ARG;
285
    }
286
    else {
287
        ret = set_cert_type(&ctx->rpkConfig, 0, buf, len);
288
    }
289
290
    return ret;
291
}
292
/* Set the client certificate types against the SSL/TLS object.
293
 *
294
 * @param [in] ssl  SSL/TLS object.
295
 * @param [in] buf  List of certificate types.
296
 * @param [in] len  Length of certificate types.
297
 * @return  1 on success.
298
 * @return  BAD_FUNC_ARG when ssl is NULL.
299
 * @return  BAD_FUNC_ARG when len is too long.
300
 * @return  BAD_FUNC_ARG when buffer values are not unique.
301
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
302
 */
303
int wolfSSL_set_client_cert_type(WOLFSSL* ssl, const char* buf, int len)
304
{
305
    int ret;
306
307
    if (ssl == NULL) {
308
        ret = BAD_FUNC_ARG;
309
    }
310
    else {
311
        ret = set_cert_type(&ssl->options.rpkConfig, 1, buf, len);
312
    }
313
314
    return ret;
315
}
316
/* Set the server certificate types against the SSL/TLS object.
317
 *
318
 * @param [in] ssl  SSL/TLS object.
319
 * @param [in] buf  List of certificate types.
320
 * @param [in] len  Length of certificate types.
321
 * @return  1 on success.
322
 * @return  BAD_FUNC_ARG when ssl is NULL.
323
 * @return  BAD_FUNC_ARG when len is too long.
324
 * @return  BAD_FUNC_ARG when buffer values are not unique.
325
 * @return  BAD_FUNC_ARG when buffer contains unrecognized certificate type.
326
 */
327
int wolfSSL_set_server_cert_type(WOLFSSL* ssl, const char* buf, int len)
328
{
329
    int ret;
330
331
    if (ssl == NULL) {
332
        ret = BAD_FUNC_ARG;
333
    }
334
    else {
335
        ret = set_cert_type(&ssl->options.rpkConfig, 0, buf, len);
336
    }
337
338
    return ret;
339
}
340
341
/* Get negotiated client certificate type value.
342
 *
343
 * WOLFSSL_CERT_TYPE_UNKNOWN returned when no negotiation has been performed.
344
 *
345
 * @param [in]  ssl  SSL/TLS object.
346
 * @param [out] tp   Certificate type. One of:
347
 *                     -1: WOLFSSL_CERT_TYPE_UNKNOWN
348
 *                      0: WOLFSSL_CERT_TYPE_X509
349
 *                      2: WOLFSSL_CERT_TYPE_RPK
350
 * @return  1 on success.
351
 * @return  BAD_FUNC_ARG when ssl or tp is NULL.
352
 */
353
int wolfSSL_get_negotiated_client_cert_type(WOLFSSL* ssl, int* tp)
354
{
355
    int ret = 1;
356
357
    /* Validate parameters. */
358
    if ((ssl == NULL) || (tp == NULL)) {
359
        ret = BAD_FUNC_ARG;
360
    }
361
    /* Check side. */
362
    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
363
        /* Check certificate type negotiated. */
364
        if (ssl->options.rpkState.received_ClientCertTypeCnt == 1) {
365
            *tp = ssl->options.rpkState.received_ClientCertTypes[0];
366
        }
367
        else {
368
            *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
369
        }
370
    }
371
    /* Check certificate type negotiated. */
372
    else if (ssl->options.rpkState.sending_ClientCertTypeCnt == 1) {
373
        *tp = ssl->options.rpkState.sending_ClientCertTypes[0];
374
    }
375
    else {
376
        *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
377
    }
378
379
    return ret;
380
}
381
382
/* Get negotiated server certificate type value.
383
 *
384
 * WOLFSSL_CERT_TYPE_UNKNOWN returned when no negotiation has been performed.
385
 *
386
 * @param [in]  ssl  SSL/TLS object.
387
 * @param [out] tp   Certificate type. One of:
388
 *                     -1: WOLFSSL_CERT_TYPE_UNKNOWN
389
 *                      0: WOLFSSL_CERT_TYPE_X509
390
 *                      2: WOLFSSL_CERT_TYPE_RPK
391
 * @return  1 on success.
392
 * @return  BAD_FUNC_ARG when ssl or tp is NULL.
393
 */
394
int wolfSSL_get_negotiated_server_cert_type(WOLFSSL* ssl, int* tp)
395
{
396
    int ret = 1;
397
398
    /* Validate parameters. */
399
    if ((ssl == NULL) || (tp == NULL)) {
400
        ret = BAD_FUNC_ARG;
401
    }
402
    /* Check side. */
403
    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
404
        /* Check certificate type negotiated. */
405
        if (ssl->options.rpkState.received_ServerCertTypeCnt == 1) {
406
            *tp = ssl->options.rpkState.received_ServerCertTypes[0];
407
        }
408
        else {
409
            *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
410
        }
411
    }
412
    /* Check certificate type negotiated. */
413
    else if (ssl->options.rpkState.sending_ServerCertTypeCnt == 1) {
414
        *tp = ssl->options.rpkState.sending_ServerCertTypes[0];
415
    }
416
    else {
417
        *tp = WOLFSSL_CERT_TYPE_UNKNOWN;
418
    }
419
    return ret;
420
}
421
#endif /* HAVE_RPK */
422
423
/* Certificate verification options. */
424
typedef struct {
425
    /* Verify the peer certificate. */
426
    byte verifyPeer:1;
427
    /* No peer certificate verification. */
428
    byte verifyNone:1;
429
    /* Fail when no peer certificate seen. */
430
    byte failNoCert:1;
431
    /* Fail when no peer certificate except when PSK handshake performed. */
432
    byte failNoCertxPSK:1;
433
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
434
    /* Verify peer certificate post handshake. */
435
    byte verifyPostHandshake:1;
436
#endif
437
} SetVerifyOptions;
438
439
/* Convert the mode flags into certificate verification options.
440
 *
441
 * @param [in] mode  Certificate verification mode flags.
442
 * @return  Certificate verification options.
443
 */
444
static SetVerifyOptions ModeToVerifyOptions(int mode)
445
0
{
446
0
    SetVerifyOptions opts;
447
448
    /* Set the options to the default - none set. */
449
0
    XMEMSET(&opts, 0, sizeof(SetVerifyOptions));
450
451
    /* When the mode is not default - set the options. */
452
0
    if (mode != WOLFSSL_VERIFY_DEFAULT) {
453
0
        opts.verifyNone = (mode == WOLFSSL_VERIFY_NONE);
454
        /* When not no verification, set the chosen options. */
455
0
        if (!opts.verifyNone) {
456
0
            opts.verifyPeer          =
457
0
                    (mode & WOLFSSL_VERIFY_PEER) != 0;
458
0
            opts.failNoCertxPSK      =
459
0
                    (mode & WOLFSSL_VERIFY_FAIL_EXCEPT_PSK) != 0;
460
0
            opts.failNoCert          =
461
0
                    (mode & WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT) != 0;
462
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
463
            opts.verifyPostHandshake =
464
                    (mode & WOLFSSL_VERIFY_POST_HANDSHAKE) != 0;
465
#endif
466
0
        }
467
0
    }
468
469
0
    return opts;
470
0
}
471
472
/* Set the verification options against the SSL/TLS context.
473
 *
474
 * @param [in] ctx              SSL/TLS context object.
475
 * @param [in] mode             Verification mode options.
476
 * @param [in] verify_callback  Verification callback.
477
 */
478
WOLFSSL_ABI void wolfSSL_CTX_set_verify(WOLFSSL_CTX* ctx, int mode,
479
    VerifyCallback verify_callback)
480
28
{
481
28
    WOLFSSL_ENTER("wolfSSL_CTX_set_verify");
482
483
    /* Ensure we have an SSL/TLS context to work with. */
484
28
    if (ctx != NULL) {
485
28
        SetVerifyOptions opts = ModeToVerifyOptions(mode);
486
487
        /* Set the bitfield options. */
488
28
        ctx->verifyNone     = opts.verifyNone;
489
28
        ctx->verifyPeer     = opts.verifyPeer;
490
28
        ctx->failNoCert     = opts.failNoCert;
491
28
        ctx->failNoCertxPSK = opts.failNoCertxPSK;
492
    #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
493
        ctx->verifyPostHandshake = opts.verifyPostHandshake;
494
    #endif
495
496
        /* Store the user verification callback against the context. */
497
28
        ctx->verifyCallback = verify_callback;
498
28
    }
499
28
}
500
501
#ifdef OPENSSL_ALL
502
/* Set certificate verification callback and context against SSL/TLS context.
503
 *
504
 * @param [in] ctx  SSL/TLS context object.
505
 * @param [in] cb   Certificate verification callback.
506
 * @param [in] arg  Context for certification verification callback.
507
 */
508
void wolfSSL_CTX_set_cert_verify_callback(WOLFSSL_CTX* ctx,
509
    CertVerifyCallback cb, void* arg)
510
{
511
    WOLFSSL_ENTER("wolfSSL_CTX_set_cert_verify_callback");
512
513
    /* Ensure we have an SSL/TLS context to work with. */
514
    if (ctx != NULL) {
515
        ctx->verifyCertCb = cb;
516
        ctx->verifyCertCbArg = arg;
517
    }
518
}
519
#endif
520
521
/* Set the verification options against the SSL/TLS object.
522
 *
523
 * @param [in] ssl              SSL/TLS object.
524
 * @param [in] mode             Verification mode options.
525
 * @param [in] verify_callback  Verification callback.
526
 */
527
void wolfSSL_set_verify(WOLFSSL* ssl, int mode, VerifyCallback verify_callback)
528
0
{
529
0
    WOLFSSL_ENTER("wolfSSL_set_verify");
530
531
    /* Ensure we have an SSL/TLS object to work with. */
532
0
    if (ssl != NULL) {
533
0
        SetVerifyOptions opts = ModeToVerifyOptions(mode);
534
535
        /* Set the bitfield options. */
536
0
        ssl->options.verifyNone = opts.verifyNone;
537
0
        ssl->options.verifyPeer = opts.verifyPeer;
538
0
        ssl->options.failNoCert = opts.failNoCert;
539
0
        ssl->options.failNoCertxPSK = opts.failNoCertxPSK;
540
    #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
541
        ssl->options.verifyPostHandshake = opts.verifyPostHandshake;
542
    #endif
543
544
        /* Store the user verification callback against the object. */
545
0
        ssl->verifyCallback = verify_callback;
546
0
    }
547
0
}
548
549
/* Set the certificate verification result for the SSL/TLS object.
550
 *
551
 * @param [in] ssl  SSL/TLS object.
552
 * @param [in] v    Verification result.
553
 */
554
void wolfSSL_set_verify_result(WOLFSSL *ssl, long v)
555
0
{
556
0
    WOLFSSL_ENTER("wolfSSL_set_verify_result");
557
558
    /* Ensure we have an SSL/TLS object to work with. */
559
0
    if (ssl != NULL) {
560
    #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
561
        ssl->peerVerifyRet = (unsigned long)v;
562
    #else
563
0
        WOLFSSL_STUB("wolfSSL_set_verify_result");
564
0
        (void)v;
565
0
    #endif
566
0
    }
567
0
}
568
569
/* Store user ctx for verify callback into SSL/TLS context.
570
 *
571
 * @param [in] ctx      SSL/TLS context.
572
 * @param [in] userCtx  User context for verify callback.
573
 */
574
void wolfSSL_CTX_SetCertCbCtx(WOLFSSL_CTX* ctx, void* userCtx)
575
0
{
576
0
    WOLFSSL_ENTER("wolfSSL_CTX_SetCertCbCtx");
577
578
    /* Validate parameters. */
579
0
    if (ctx != NULL) {
580
0
        ctx->verifyCbCtx = userCtx;
581
0
    }
582
0
}
583
584
/* Store user ctx for verify callback into SSL/TLS object.
585
 *
586
 * @param [in] ssl  SSL/TLS object.
587
 * @param [in] ctx  User context for verify callback.
588
 */
589
void wolfSSL_SetCertCbCtx(WOLFSSL* ssl, void* ctx)
590
0
{
591
0
    WOLFSSL_ENTER("wolfSSL_SetCertCbCtx");
592
593
    /* Validate parameters. */
594
0
    if (ssl != NULL) {
595
0
        ssl->verifyCbCtx = ctx;
596
0
    }
597
0
}
598
599
600
601
/* Store context CA Cache addition callback into SSL/TLS context.
602
 *
603
 * @param [in] ctx      SSL/TLS context.
604
 * @param [in] userCtx  User context for verify callback.
605
 */
606
void wolfSSL_CTX_SetCACb(WOLFSSL_CTX* ctx, CallbackCACache cb)
607
0
{
608
    /* Validate parameters. */
609
0
    if ((ctx != NULL) && (ctx->cm != NULL)) {
610
0
        ctx->cm->caCacheCallback = cb;
611
0
    }
612
0
}
613
614
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_TLS13) && \
615
    defined(WOLFSSL_POST_HANDSHAKE_AUTH)
616
/* For TLS v1.3, send authentication messages after handshake completes.
617
 *
618
 * @return  1 on success.
619
 * @return  UNSUPPORTED_PROTO_VERSION when not a TLSv1.3 handshake.
620
 * @return  0 on other failure.
621
 */
622
int wolfSSL_verify_client_post_handshake(WOLFSSL* ssl)
623
{
624
    int ret;
625
626
    /* Do request of certificate. */
627
    ret = wolfSSL_request_certificate(ssl);
628
    if (ret != 1) {
629
        /* Special logging for wrong protocol version. */
630
        if ((ssl != NULL) && !IsAtLeastTLSv1_3(ssl->version)) {
631
            WOLFSSL_ERROR(UNSUPPORTED_PROTO_VERSION);
632
        }
633
        else {
634
            /* Other errors - return 0. */
635
            WOLFSSL_ERROR(ret);
636
        }
637
        ret = 0;
638
    }
639
640
    return ret;
641
}
642
643
/* Set whether handshakes from this SSL/TLS context allow auth post handshake.
644
 *
645
 * @param [in] ctx  SSL/TLS context.
646
 * @param [in] val  Whether to allow post handshake authentication.
647
 * @return  1 on success.
648
 * @return  0 on failure.
649
 */
650
int wolfSSL_CTX_set_post_handshake_auth(WOLFSSL_CTX* ctx, int val)
651
{
652
    int ret;
653
654
    /* Try to allow - really just checking conditions. */
655
    if (wolfSSL_CTX_allow_post_handshake_auth(ctx) == 0) {
656
        /* Set value as a bit. */
657
        ctx->postHandshakeAuth = (val != 0);
658
        ret = 1;
659
    }
660
    else {
661
        ret = 0;
662
    }
663
664
    return ret;
665
}
666
/* Set whether handshakes with this SSL/TLS object allow auth post handshake.
667
 *
668
 * @param [in] ctx  SSL/TLS context.
669
 * @param [in] val  Whether to allow post handshake authentication.
670
 * @return  1 on success.
671
 * @return  0 on failure.
672
 */
673
int wolfSSL_set_post_handshake_auth(WOLFSSL* ssl, int val)
674
{
675
    int ret;
676
677
    /* Try to allow - really just checking conditions. */
678
    if (wolfSSL_allow_post_handshake_auth(ssl) == 0) {
679
        /* Set value as a bit. */
680
        ssl->options.postHandshakeAuth = (val != 0);
681
        ret = 1;
682
    }
683
    else {
684
        ret = 0;
685
    }
686
687
    return ret;
688
}
689
#endif /* OPENSSL_EXTRA && WOLFSSL_TLS13 && WOLFSSL_POST_HANDSHAKE_AUTH */
690
691
#if defined(PERSIST_CERT_CACHE)
692
693
#if !defined(NO_FILESYSTEM)
694
695
/* Persist certificate cache in SSL/TLS context to file.
696
 *
697
 * @param [in] ctx    SSL/TLS context.
698
 * @param [in] fname  Filename so store certificate cache to.
699
 * @return  1 on success.
700
 * @return  BAD_FUNC_ARG when ctx or fname is NULL.
701
 * @return  Other values on failure.
702
 */
703
int wolfSSL_CTX_save_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
704
{
705
    int ret;
706
707
    WOLFSSL_ENTER("wolfSSL_CTX_save_cert_cache");
708
709
    /* Validate parameters. */
710
    if ((ctx == NULL) || (fname == NULL)) {
711
        ret = BAD_FUNC_ARG;
712
    }
713
    else {
714
        /* Save certificate cache. */
715
        ret = CM_SaveCertCache(ctx->cm, fname);
716
    }
717
718
    return ret;
719
}
720
721
722
/* Load certificate cache into SSL/TLS context from file.
723
 *
724
 * @param [in] ctx    SSL/TLS context.
725
 * @param [in] fname  Filename so store certificate cache to.
726
 * @return  1 on success.
727
 * @return  BAD_FUNC_ARG when ctx or fname is NULL.
728
 * @return  Other values on failure.
729
 */
730
int wolfSSL_CTX_restore_cert_cache(WOLFSSL_CTX* ctx, const char* fname)
731
{
732
    int ret;
733
734
    WOLFSSL_ENTER("wolfSSL_CTX_restore_cert_cache");
735
736
    /* Validate parameters. */
737
    if ((ctx == NULL) || (fname == NULL)) {
738
        ret = BAD_FUNC_ARG;
739
    }
740
    else {
741
        /* Restore certificate cache. */
742
        ret = CM_RestoreCertCache(ctx->cm, fname);
743
    }
744
745
    return ret;
746
}
747
748
#endif /* NO_FILESYSTEM */
749
750
/* Persist certificate cache in SSL/TLS context to memory.
751
 *
752
 * @param [in]  ctx   SSL/TLS context.
753
 * @param [in]  mem   Memory to fill with certificate cache.
754
 * @param [in]  sz    Size of memory to fill in bytes.
755
 * @param [out] used  The number of bytes of memory used.
756
 * @return  1 on success.
757
 * @return  BAD_FUNC_ARG when ctx, mem or used is NULL.
758
 * @return  BAD_FUNC_ARG when sz is less than or equal to zero.
759
 * @return  Other values on failure.
760
 */
761
int wolfSSL_CTX_memsave_cert_cache(WOLFSSL_CTX* ctx, void* mem,
762
                                   int sz, int* used)
763
{
764
    int ret;
765
766
    WOLFSSL_ENTER("wolfSSL_CTX_memsave_cert_cache");
767
768
    /* Validate parameters. */
769
    if ((ctx == NULL) || (mem == NULL) || (used == NULL) || (sz <= 0)) {
770
        ret = BAD_FUNC_ARG;
771
    }
772
    else {
773
        /* Persist certificate change to memory. */
774
        ret = CM_MemSaveCertCache(ctx->cm, mem, sz, used);
775
    }
776
777
    return ret;
778
}
779
780
781
/* Load certificate cache into SSL/TLS context from memory.
782
 *
783
 * @param [in]  ctx   SSL/TLS context.
784
 * @param [in]  mem   Memory with certificate cache.
785
 * @param [in]  sz    Size of certificate cache in bytes
786
 * @return  1 on success.
787
 * @return  BAD_FUNC_ARG when ctx or mem is NULL.
788
 * @return  BAD_FUNC_ARG when sz is less than or equal to zero.
789
 * @return  Other values on failure.
790
 */
791
int wolfSSL_CTX_memrestore_cert_cache(WOLFSSL_CTX* ctx, const void* mem, int sz)
792
{
793
    int ret;
794
795
    WOLFSSL_ENTER("wolfSSL_CTX_memrestore_cert_cache");
796
797
    /* Validate parameters. */
798
    if ((ctx == NULL) || (mem == NULL) || (sz <= 0)) {
799
        ret = BAD_FUNC_ARG;
800
    }
801
    else {
802
        /* Restore certificate cache. */
803
        ret = CM_MemRestoreCertCache(ctx->cm, mem, sz);
804
    }
805
806
    return ret;
807
}
808
809
810
/* Get size of certificate cache when persisted.
811
 *
812
 * @param [in] ctx  SSL/TLS context.
813
 * @return  Size of certificate cache when pesisted in bytes.
814
 * @return  BAD_FUNC_ARG when ctx is NULL.
815
 */
816
int wolfSSL_CTX_get_cert_cache_memsize(WOLFSSL_CTX* ctx)
817
{
818
    int ret;
819
820
    WOLFSSL_ENTER("wolfSSL_CTX_get_cert_cache_memsize");
821
822
    /* Validate parameter. */
823
    if (ctx == NULL) {
824
        ret = BAD_FUNC_ARG;
825
    }
826
    else {
827
        /* Get size. */
828
        ret = CM_GetCertCacheMemSize(ctx->cm);
829
    }
830
831
    return ret;
832
}
833
834
#endif /* PERSIST_CERT_CACHE */
835
836
/* Unload certificates and keys that the SSL/TLS object owns.
837
 *
838
 * The WOLFSSL_CTX referenced is untouched.
839
 *
840
 * @param [in] ssl  SSL/TLS object.
841
 * @return  1 on success.
842
 * @return  BAD_FUNC_ARG when ssl is NULL.
843
 */
844
int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl)
845
91.5k
{
846
91.5k
    int ret = 1;
847
848
    /* Validate parameter. */
849
91.5k
    if (ssl == NULL) {
850
0
        WOLFSSL_MSG("Null function arg");
851
0
        ret = BAD_FUNC_ARG;
852
0
    }
853
91.5k
    else {
854
91.5k
        if (ssl->buffers.weOwnCert && !ssl->keepCert) {
855
73.6k
            WOLFSSL_MSG("Unloading cert");
856
73.6k
            FreeDer(&ssl->buffers.certificate);
857
        #ifdef KEEP_OUR_CERT
858
            wolfSSL_X509_free(ssl->ourCert);
859
            ssl->ourCert = NULL;
860
        #endif
861
73.6k
            ssl->buffers.weOwnCert = 0;
862
73.6k
        }
863
864
91.5k
        if (ssl->buffers.weOwnCertChain) {
865
0
            WOLFSSL_MSG("Unloading cert chain");
866
0
            FreeDer(&ssl->buffers.certChain);
867
0
            ssl->buffers.weOwnCertChain = 0;
868
0
        }
869
870
91.5k
        if (ssl->buffers.weOwnKey) {
871
73.6k
            WOLFSSL_MSG("Unloading key");
872
73.6k
            if (ssl->buffers.key != NULL && ssl->buffers.key->buffer != NULL)
873
73.6k
                ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
874
73.6k
            FreeDer(&ssl->buffers.key);
875
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
876
            FreeDer(&ssl->buffers.keyMask);
877
        #endif
878
73.6k
            ssl->buffers.weOwnKey = 0;
879
73.6k
    }
880
881
    #ifdef WOLFSSL_DUAL_ALG_CERTS
882
        if (ssl->buffers.weOwnAltKey) {
883
            WOLFSSL_MSG("Unloading alt key");
884
            if (ssl->buffers.altKey != NULL &&
885
                    ssl->buffers.altKey->buffer != NULL) {
886
                ForceZero(ssl->buffers.altKey->buffer,
887
                          ssl->buffers.altKey->length);
888
            }
889
            FreeDer(&ssl->buffers.altKey);
890
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
891
            FreeDer(&ssl->buffers.altKeyMask);
892
        #endif
893
            ssl->buffers.weOwnAltKey = 0;
894
        }
895
    #endif /* WOLFSSL_DUAL_ALG_CERTS */
896
91.5k
    }
897
898
91.5k
    return ret;
899
91.5k
}
900
901
/* Unload CAs from the certificate manager of the SSL/TLS context.
902
 *
903
 * @param [in] ctx  SSL/TLS context.
904
 * @return  1 on success.
905
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
906
 * @return  BAD_MUTEX_E when locking fails.
907
 */
908
int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
909
0
{
910
0
    int ret;
911
912
0
    WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
913
914
    /* Validate parameter. */
915
0
    if (ctx == NULL) {
916
0
        ret = BAD_FUNC_ARG;
917
0
    }
918
0
    else {
919
0
        ret = wolfSSL_CertManagerUnloadCAs(ctx->cm);
920
0
    }
921
922
0
    return ret;
923
0
}
924
925
/* Unload Intermediate CAs from the certificate manager of the SSL/TLS context.
926
 *
927
 * @param [in] ctx  SSL/TLS context.
928
 * @return  1 on success.
929
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
930
 * @return  BAD_MUTEX_E when locking fails.
931
 */
932
int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx)
933
0
{
934
0
    int ret;
935
936
0
    WOLFSSL_ENTER("wolfSSL_CTX_UnloadIntermediateCerts");
937
938
    /* Validate parameter. */
939
0
    if (ctx == NULL) {
940
0
        ret = BAD_FUNC_ARG;
941
0
    }
942
    /* Lock reference count. */
943
0
    else if ((ret = wolfSSL_RefWithMutexLock(&ctx->ref)) == 0) {
944
        /* Must not have another reference for this operation to be done. */
945
0
        if (ctx->ref.count > 1) {
946
0
            WOLFSSL_MSG("ctx object must have a ref count of 1 before "
947
0
                        "unloading intermediate certs");
948
0
            ret = BAD_STATE_E;
949
0
        }
950
0
        else {
951
0
            ret = wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
952
0
        }
953
954
        /* Unlock reference count. */
955
0
        if (wolfSSL_RefWithMutexUnlock(&ctx->ref) != 0) {
956
0
            WOLFSSL_MSG("Failed to unlock mutex!");
957
0
        }
958
0
    }
959
960
0
    return ret;
961
0
}
962
963
964
#ifdef WOLFSSL_TRUST_PEER_CERT
965
/* Unload trusted peers from the certificate manager of the SSL/TLS context.
966
 *
967
 * @param [in] ctx  SSL/TLS context.
968
 * @return  1 on success.
969
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
970
 * @return  BAD_MUTEX_E when locking fails.
971
 */
972
int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
973
{
974
    int ret;
975
976
    WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
977
978
    /* Validate parameter. */
979
    if (ctx == NULL) {
980
        ret = BAD_FUNC_ARG;
981
    }
982
    else {
983
        ret = wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
984
    }
985
986
    return ret;
987
}
988
989
#ifdef WOLFSSL_LOCAL_X509_STORE
990
/* Unload trusted peers from the certificate manager of the SSL/TLS object.
991
 *
992
 * @param [in] ctx  SSL/TLS context.
993
 * @return  1 on success.
994
 * @return  BAD_FUNC_ARG when ssl is NULL.
995
 * @return  BAD_MUTEX_E when locking fails.
996
 */
997
int wolfSSL_Unload_trust_peers(WOLFSSL* ssl)
998
{
999
    int ret;
1000
1001
    WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
1002
1003
    /* Validate parameter. */
1004
    if (ssl == NULL) {
1005
        ret = BAD_FUNC_ARG;
1006
    }
1007
    else {
1008
        /* Output message when certificate manager for object. */
1009
        SSL_CM_WARNING(ssl);
1010
        return wolfSSL_CertManagerUnload_trust_peers(SSL_CM(ssl));
1011
    }
1012
1013
    return ret;
1014
}
1015
#endif /* WOLFSSL_LOCAL_X509_STORE */
1016
#endif /* WOLFSSL_TRUST_PEER_CERT */
1017
1018
#ifndef WOLFSSL_NO_CA_NAMES
1019
/* Add a CA certificate to the list of CA names.
1020
 *
1021
 * @param [in, out] ca_names  List of CA certificate subject names.
1022
 * @param [in]      x509      X509 certificate.
1023
 * @return  1 on success.
1024
 * @return  0 on failure.
1025
 */
1026
static int add_to_ca_names_list(WOLFSSL_STACK* ca_names, WOLFSSL_X509* x509)
1027
{
1028
    int ret = 1;
1029
    WOLFSSL_X509_NAME *nameCopy = NULL;
1030
1031
    nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(x509));
1032
    if (nameCopy == NULL) {
1033
        WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
1034
        ret = 0;
1035
    }
1036
    else if (wolfSSL_sk_X509_NAME_push(ca_names, nameCopy) <= 0) {
1037
        WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
1038
        wolfSSL_X509_NAME_free(nameCopy);
1039
        ret = 0;
1040
    }
1041
1042
    return ret;
1043
}
1044
1045
/* Add a client's CA to SSL/TLS context.
1046
 *
1047
 * @param [in] ctx   SSL/TLS context.
1048
 * @param [in] x509  X509 certificate.
1049
 * @return  1 on success.
1050
 * @return  0 on failure.
1051
 */
1052
int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
1053
{
1054
    int ret = 1;
1055
1056
    WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
1057
1058
    /* Validate parameters. */
1059
    if ((ctx == NULL) || (x509 == NULL)) {
1060
        WOLFSSL_MSG("Bad argument");
1061
        ret = 0;
1062
    }
1063
    /* Create a stack of names if not present. */
1064
    else if (ctx->client_ca_names == NULL) {
1065
        ctx->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1066
        if (ctx->client_ca_names == NULL) {
1067
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1068
            ret = 0;
1069
        }
1070
    }
1071
    if (ret == 1) {
1072
        /* Add certificate's subject name to client CA name list. */
1073
        ret = add_to_ca_names_list(ctx->client_ca_names, x509);
1074
    }
1075
1076
    return ret;
1077
}
1078
1079
/* Add a client's CA to SSL/TLS object.
1080
 *
1081
 * @param [in] ssl   SSL/TLS object.
1082
 * @param [in] x509  X509 certificate.
1083
 * @return  1 on success.
1084
 * @return  0 on failure.
1085
 */
1086
int wolfSSL_add_client_CA(WOLFSSL* ssl, WOLFSSL_X509* x509)
1087
{
1088
    int ret = 1;
1089
1090
    WOLFSSL_ENTER("wolfSSL_add_client_CA");
1091
1092
    /* Validate parameters. */
1093
    if ((ssl == NULL) || (x509 == NULL)) {
1094
        WOLFSSL_MSG("Bad argument");
1095
        ret = 0;
1096
    }
1097
    /* Create a stack of names if not present. */
1098
    else if (ssl->client_ca_names == NULL) {
1099
        ssl->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1100
        if (ssl->client_ca_names == NULL) {
1101
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1102
            ret = 0;
1103
        }
1104
    }
1105
    if (ret == 1) {
1106
        /* Add certificate's subject name to client CA name list. */
1107
        ret = add_to_ca_names_list(ssl->client_ca_names, x509);
1108
    }
1109
1110
    return ret;
1111
}
1112
1113
/* Add a CA to SSL/TLS context.
1114
 *
1115
 * @param [in] ctx   SSL/TLS context.
1116
 * @param [in] x509  X509 certificate.
1117
 * @return  1 on success.
1118
 * @return  0 on failure.
1119
 */
1120
int wolfSSL_CTX_add1_to_CA_list(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
1121
{
1122
    int ret = 1;
1123
1124
    WOLFSSL_ENTER("wolfSSL_CTX_add1_to_CA_list");
1125
1126
    /* Validate parameters. */
1127
    if ((ctx == NULL) || (x509 == NULL)) {
1128
        WOLFSSL_MSG("Bad argument");
1129
        ret = 0;
1130
    }
1131
    /* Create a stack of names if not present. */
1132
    else if (ctx->ca_names == NULL) {
1133
        ctx->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1134
        if (ctx->ca_names == NULL) {
1135
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1136
            ret = 0;
1137
        }
1138
    }
1139
    if (ret == 1) {
1140
        /* Add certificate's subject name to CA name list. */
1141
        ret = add_to_ca_names_list(ctx->ca_names, x509);
1142
    }
1143
1144
    return ret;
1145
}
1146
1147
/* Add a CA to SSL/TLS object.
1148
 *
1149
 * @param [in] ssl   SSL/TLS object.
1150
 * @param [in] x509  X509 certificate.
1151
 * @return  1 on success.
1152
 * @return  0 on failure.
1153
 */
1154
int wolfSSL_add1_to_CA_list(WOLFSSL* ssl, WOLFSSL_X509* x509)
1155
{
1156
    int ret = 1;
1157
1158
    WOLFSSL_ENTER("wolfSSL_add1_to_CA_list");
1159
1160
    /* Validate parameters. */
1161
    if ((ssl == NULL) || (x509 == NULL)) {
1162
        WOLFSSL_MSG("Bad argument");
1163
        ret = 0;
1164
    }
1165
    /* Create a stack of names if not present. */
1166
    else if (ssl->ca_names == NULL) {
1167
        ssl->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1168
        if (ssl->ca_names == NULL) {
1169
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1170
            ret = 0;
1171
        }
1172
    }
1173
    if (ret == 1) {
1174
        /* Add certificate's subject name to CA name list. */
1175
        ret = add_to_ca_names_list(ssl->ca_names, x509);
1176
    }
1177
1178
    return ret;
1179
}
1180
1181
/* Set the client CA list into SSL/TLS context.
1182
 *
1183
 * @param [in] ctx    SSL/TLS context.
1184
 * @param [in] names  List of CA subject names.
1185
 */
1186
void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
1187
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1188
{
1189
    WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
1190
1191
    /* Validate parameters. */
1192
    if (ctx != NULL) {
1193
        /* Dispose of any existing list. */
1194
        wolfSSL_sk_X509_NAME_pop_free(ctx->client_ca_names, NULL);
1195
        /* Take ownership of names list. */
1196
        ctx->client_ca_names = names;
1197
    }
1198
}
1199
1200
/* Set the client CA list into SSL/TLS object.
1201
 *
1202
 * @param [in] ssl    SSL/TLS object.
1203
 * @param [in] names  List of CA subject names.
1204
 */
1205
void wolfSSL_set_client_CA_list(WOLFSSL* ssl,
1206
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1207
{
1208
    WOLFSSL_ENTER("wolfSSL_set_client_CA_list");
1209
1210
    /* Validate parameters. */
1211
    if (ssl != NULL) {
1212
        /* Dispose of any existing list if the object owns it. */
1213
        if (ssl->client_ca_names != ssl->ctx->client_ca_names) {
1214
            wolfSSL_sk_X509_NAME_pop_free(ssl->client_ca_names, NULL);
1215
        }
1216
        /* Take ownership of names list. */
1217
        ssl->client_ca_names = names;
1218
    }
1219
}
1220
1221
/* Set the CA list into SSL/TLS context.
1222
 *
1223
 * @param [in] ctx    SSL/TLS context.
1224
 * @param [in] names  List of CA subject names.
1225
 */
1226
void wolfSSL_CTX_set0_CA_list(WOLFSSL_CTX* ctx,
1227
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1228
{
1229
    WOLFSSL_ENTER("wolfSSL_CTX_set0_CA_list");
1230
1231
    /* Validate parameters. */
1232
    if (ctx != NULL) {
1233
        /* Dispose of any existing list. */
1234
        wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
1235
        /* Take ownership of names list. */
1236
        ctx->ca_names = names;
1237
    }
1238
}
1239
1240
/* Set the client CA list into SSL/TLS object.
1241
 *
1242
 * @param [in] ssl    SSL/TLS object.
1243
 * @param [in] names  List of CA subject names.
1244
 */
1245
void wolfSSL_set0_CA_list(WOLFSSL* ssl,
1246
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1247
{
1248
    WOLFSSL_ENTER("wolfSSL_set0_CA_list");
1249
1250
    /* Validate parameters. */
1251
    if (ssl != NULL) {
1252
        /* Dispose of any existing list if the object owns it. */
1253
        if (ssl->ca_names != ssl->ctx->ca_names) {
1254
            wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
1255
        }
1256
        /* Take ownership of names list. */
1257
        ssl->ca_names = names;
1258
    }
1259
}
1260
1261
/* Get the list of client CA subject names from the SSL/TLS context.
1262
 *
1263
 * @param [in] ctx  SSL/TLS context.
1264
 * @return  List of CA subject names on success.
1265
 * @return  NULL when ctx is NULL or no names set.
1266
 */
1267
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
1268
        const WOLFSSL_CTX *ctx)
1269
{
1270
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1271
1272
    WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list");
1273
1274
    /* Validate parameter. */
1275
    if (ctx == NULL) {
1276
        WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get_client_CA_list");
1277
        ret = NULL;
1278
    }
1279
    else {
1280
        ret = ctx->client_ca_names;
1281
    }
1282
1283
    return ret;
1284
}
1285
1286
/* Get the list of client CA subject names from the SSL/TLS object.
1287
 *
1288
 * On server side: returns the CAs set via *_set_client_CA_list();
1289
 * On client side: returns the CAs received from server -- same as
1290
 * wolfSSL_get0_peer_CA_list().
1291
 *
1292
 * @param [in] ssl  SSL/TLS object.
1293
 * @return  List of CA subject names on success.
1294
 * @return  NULL when ssl is NULL or no names set.
1295
 */
1296
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list(const WOLFSSL* ssl)
1297
{
1298
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1299
1300
    WOLFSSL_ENTER("wolfSSL_get_client_CA_list");
1301
1302
    /* Validate parameter. */
1303
    if (ssl == NULL) {
1304
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get_client_CA_list");
1305
        ret = NULL;
1306
    }
1307
    /* Client side return peer CA names. */
1308
    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
1309
        ret = ssl->peer_ca_names;
1310
    }
1311
    /* Server side return client CA names. */
1312
    else {
1313
        ret = SSL_CLIENT_CA_NAMES(ssl);
1314
    }
1315
1316
    return ret;
1317
}
1318
1319
/* Get the list of CA subject names from the SSL/TLS context.
1320
 *
1321
 * @param [in] ctx  SSL/TLS context.
1322
 * @return  List of CA subject names on success.
1323
 * @return  NULL when ctx is NULL or no names set.
1324
 */
1325
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get0_CA_list(
1326
    const WOLFSSL_CTX *ctx)
1327
{
1328
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1329
1330
    WOLFSSL_ENTER("wolfSSL_CTX_get0_CA_list");
1331
1332
    /* Validate parameter. */
1333
    if (ctx == NULL) {
1334
        WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get0_CA_list");
1335
        ret = NULL;
1336
    }
1337
    else {
1338
        /* Return list directly. */
1339
        ret = ctx->ca_names;
1340
    }
1341
1342
    return ret;
1343
}
1344
1345
/* Get the list of CA subject names from the SSL/TLS object.
1346
 *
1347
 * Always returns the CA's set via *_set0_CA_list.
1348
 *
1349
 * @param [in] ssl  SSL/TLS object.
1350
 * @return  List of CA subject names on success.
1351
 * @return  NULL when ssl is NULL or no names set.
1352
 */
1353
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get0_CA_list(const WOLFSSL *ssl)
1354
{
1355
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1356
1357
    WOLFSSL_ENTER("wolfSSL_get0_CA_list");
1358
1359
    /* Validate parameter. */
1360
    if (ssl == NULL) {
1361
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get0_CA_list");
1362
        ret = NULL;
1363
    }
1364
    else {
1365
        /* Return list directly from object, if available, or context. */
1366
        ret = SSL_CA_NAMES(ssl);
1367
    }
1368
1369
    return ret;
1370
}
1371
1372
/* Get the list of peer CA subject names from the SSL/TLS object.
1373
 *
1374
 * Always returns the CA's received from the peer.
1375
 *
1376
 * @param [in] ssl  SSL/TLS object.
1377
 * @return  List of CA subject names on success.
1378
 * @return  NULL when ssl is NULL or no names set.
1379
 */
1380
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get0_peer_CA_list(const WOLFSSL* ssl)
1381
{
1382
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1383
1384
    WOLFSSL_ENTER("wolfSSL_get0_peer_CA_list");
1385
1386
    /* Validate parameter. */
1387
    if (ssl == NULL) {
1388
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get0_peer_CA_list");
1389
        ret = NULL;
1390
    }
1391
    else {
1392
        /* Return list directly from object. */
1393
        ret = ssl->peer_ca_names;
1394
    }
1395
1396
    return ret;
1397
}
1398
1399
#ifndef NO_BIO
1400
/* Load the client CA subject names from file.
1401
 *
1402
 * @param [in] fname  Name of file containing client CA certificates.
1403
 * @return  A list of certificate names on success.
1404
 * @return  NULL on error.
1405
 */
1406
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
1407
{
1408
    /* The webserver build is using this to load a CA into the server
1409
     * for client authentication as an option. Have this return NULL in
1410
     * that case. If OPENSSL_EXTRA is enabled, go ahead and include
1411
     * the function. */
1412
#ifdef OPENSSL_EXTRA
1413
    WOLFSSL_STACK *list = NULL;
1414
    WOLFSSL_BIO* bio = NULL;
1415
    WOLFSSL_X509 *cert = NULL;
1416
    int err = 0;
1417
    unsigned long error;
1418
1419
    WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
1420
1421
    /* Create a file BIO to read. */
1422
    bio = wolfSSL_BIO_new_file(fname, "rb");
1423
    if (bio == NULL) {
1424
        WOLFSSL_MSG("wolfSSL_BIO_new_file error");
1425
        err = 1;
1426
    }
1427
1428
    if (!err) {
1429
        /* Create an empty list of certificate names - default compare cb. */
1430
        list = wolfSSL_sk_X509_NAME_new(NULL);
1431
        if (list == NULL) {
1432
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1433
            err = 1;
1434
        }
1435
    }
1436
1437
    /* Read each certificate in the chain out of the file. */
1438
    while (!err && wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
1439
        WOLFSSL_X509_NAME *nameCopy;
1440
1441
        /* Need a persistent copy of the subject name. */
1442
        nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(cert));
1443
        if (nameCopy == NULL) {
1444
            WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
1445
            err = 1;
1446
        }
1447
        else {
1448
            /* Original certificate will be freed - clear reference to it. */
1449
            nameCopy->x509 = NULL;
1450
1451
            if (wolfSSL_sk_X509_NAME_push(list, nameCopy) <= 0) {
1452
                WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
1453
                /* Name not stored - free now as only place needing to. */
1454
                wolfSSL_X509_NAME_free(nameCopy);
1455
                err = 1;
1456
            }
1457
        }
1458
1459
        /* Dispose of certificate read. */
1460
        wolfSSL_X509_free(cert);
1461
        cert = NULL;
1462
    }
1463
1464
    /* Clear any error due to no more certificates. */
1465
    CLEAR_ASN_NO_PEM_HEADER_ERROR(error);
1466
1467
    if (err) {
1468
        /* Error occurred so return NULL. */
1469
        wolfSSL_sk_X509_NAME_pop_free(list, NULL);
1470
        list = NULL;
1471
    }
1472
    wolfSSL_BIO_free(bio);
1473
    return list;
1474
#else
1475
    (void)fname;
1476
    return NULL;
1477
#endif
1478
}
1479
#endif /* !NO_BIO */
1480
#endif /* WOLFSSL_NO_CA_NAMES */
1481
1482
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1483
/* Get the certificate store of the SSL/TLS context.
1484
 *
1485
 * @param [in] ctx  SSL/TLS context.
1486
 * @return  X509 certificate store on success.
1487
 * @return  NULL when ctx is NULL.
1488
 */
1489
WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(const WOLFSSL_CTX* ctx)
1490
{
1491
    WOLFSSL_X509_STORE* ret;
1492
1493
    /* Validate parameter. */
1494
    if (ctx == NULL) {
1495
        ret = NULL;
1496
    }
1497
    /* Use pointer to external store if set. */
1498
    else if (ctx->x509_store_pt != NULL) {
1499
        ret = ctx->x509_store_pt;
1500
    }
1501
    else {
1502
        /* Return reference to store that is part of the context. */
1503
        ret = (WOLFSSL_X509_STORE*)&ctx->x509_store;
1504
    }
1505
1506
    return ret;
1507
}
1508
1509
/* Set the certificate store of the SSL/TLS context.
1510
 *
1511
 * @param [in] ctx  SSL/TLS context.
1512
 * @return  X509 certificate store on success.
1513
 * @return  NULL when ctx is NULL.
1514
 */
1515
void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
1516
{
1517
    WOLFSSL_ENTER("wolfSSL_CTX_set_cert_store");
1518
1519
    /* Validate parameters. */
1520
    if ((ctx == NULL) || (str == NULL) || (ctx->cm == str->cm)) {
1521
        WOLFSSL_MSG("Invalid parameters");
1522
    }
1523
    else if (wolfSSL_CertManager_up_ref(str->cm) != 1) {
1524
        WOLFSSL_MSG("wolfSSL_CertManager_up_ref error");
1525
    }
1526
    else {
1527
        /* Free any cert manager. */
1528
        wolfSSL_CertManagerFree(ctx->cm);
1529
        /* Free any external store. */
1530
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
1531
        /* Set the certificate manager into context. */
1532
        ctx->cm               = str->cm;
1533
        ctx->x509_store.cm    = str->cm;
1534
        ctx->x509_store.cache = str->cache;
1535
        /* Take ownership of store and free it with context free. */
1536
        ctx->x509_store_pt    = str;
1537
        /* Context has ownership and free it with context free. */
1538
        ctx->cm->x509_store_p = ctx->x509_store_pt;
1539
    }
1540
}
1541
1542
#ifdef OPENSSL_ALL
1543
/* Set certificate store into SSL/TLS context but don't take ownership.
1544
 *
1545
 * @param [in] ctx  SSL/TLS context.
1546
 * @param [in] str  Certificate store.
1547
 * @return  1 on success.
1548
 * @return  0 when ctx or str is NULL or on other error.
1549
 */
1550
int wolfSSL_CTX_set1_verify_cert_store(WOLFSSL_CTX* ctx,
1551
    WOLFSSL_X509_STORE* str)
1552
{
1553
    int ret;
1554
1555
    WOLFSSL_ENTER("wolfSSL_CTX_set1_verify_cert_store");
1556
1557
    /* Validate parameters. */
1558
    if ((ctx == NULL) || (str == NULL)) {
1559
        WOLFSSL_MSG("Bad parameter");
1560
        ret = 0;
1561
    }
1562
    /* Nothing to do when store being set is the same as existing in context. */
1563
    else if (str == CTX_STORE(ctx)) {
1564
        ret = 1;
1565
    }
1566
    /* Increase ref so we can store pointer and free it with context free. */
1567
    else if (wolfSSL_X509_STORE_up_ref(str) != 1) {
1568
        WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
1569
        ret = 0;
1570
    }
1571
    else {
1572
        /* Free any external store. */
1573
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
1574
        /* Ref count increased - store pointer and free with context free. */
1575
        ctx->x509_store_pt = str;
1576
        ret = 1;
1577
    }
1578
1579
    return ret;
1580
}
1581
#endif
1582
1583
1584
/* Set certificate store into SSL/TLS object.
1585
 *
1586
 * @param [in] ssl  SSL/TLS object.
1587
 * @param [in] str  Certificate store.
1588
 * @param [in] ref  Take a reference to passed in certificate store.
1589
 * @return  1 on success.
1590
 * @return  0 when ssl or str is NULL or on other error.
1591
 */
1592
static int wolfssl_set_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str,
1593
    int ref)
1594
{
1595
    int ret;
1596
1597
    WOLFSSL_ENTER("wolfssl_set_verify_cert_store");
1598
1599
    /* Validate parameters. */
1600
    if ((ssl == NULL) || (str == NULL)) {
1601
        WOLFSSL_MSG("Bad parameter");
1602
        ret = 0;
1603
    }
1604
    /* Nothing to do when store being set is the same as existing in object. */
1605
    else if (str == SSL_STORE(ssl)) {
1606
        ret = 1;
1607
    }
1608
    else if (ref && (wolfSSL_X509_STORE_up_ref(str) != 1)) {
1609
        WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
1610
        ret = 0;
1611
    }
1612
    else {
1613
        /* Free any external store. */
1614
        wolfSSL_X509_STORE_free(ssl->x509_store_pt);
1615
        if (str == ssl->ctx->x509_store_pt) {
1616
            /* Setting ctx store - just revert to using that instead. */
1617
            ssl->x509_store_pt = NULL;
1618
        }
1619
        else {
1620
            /* Ref count increased - store pointer and free with object free. */
1621
            ssl->x509_store_pt = str;
1622
        }
1623
        ret = 1;
1624
    }
1625
1626
    return ret;
1627
}
1628
1629
/* Set certificate store into SSL/TLS object and take ownership.
1630
 *
1631
 * @param [in] ssl  SSL/TLS object.
1632
 * @param [in] str  Certificate store.
1633
 * @return  1 on success.
1634
 * @return  0 when ssl or str is NULL or on other error.
1635
 */
1636
int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
1637
{
1638
    WOLFSSL_ENTER("wolfSSL_set0_verify_cert_store");
1639
1640
    return wolfssl_set_verify_cert_store(ssl, str, 0);
1641
}
1642
1643
/* Set certificate store into SSL/TLS object but don't take ownership.
1644
 *
1645
 * @param [in] ssl  SSL/TLS object.
1646
 * @param [in] str  Certificate store.
1647
 * @return  1 on success.
1648
 * @return  0 when ssl or str is NULL or on other error.
1649
 */
1650
int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
1651
{
1652
    WOLFSSL_ENTER("wolfSSL_set1_verify_cert_store");
1653
1654
    return wolfssl_set_verify_cert_store(ssl, str, 1);
1655
}
1656
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
1657
1658
/* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
1659
   KEEP_OUR_CERT is to ensure ability to return ssl certificate */
1660
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
1661
    defined(KEEP_OUR_CERT)
1662
/* Get the certificate in the SSL/TLS context.
1663
 *
1664
 * @param [in] ctx  SSL/TLS context.
1665
 * @return  Certificate being sent to peer.
1666
 * @return  NULL when ctx is NULL, no certificate set or on other error.
1667
 */
1668
WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx)
1669
{
1670
    WOLFSSL_X509* ret = NULL;
1671
1672
    /* Validate parameters. */
1673
    if (ctx == NULL) {
1674
        WOLFSSL_MSG("Invalid parameter");
1675
    }
1676
    else {
1677
        /* Check if we already have a certificate allocated. */
1678
        if (ctx->ourCert == NULL) {
1679
            /* Check if there is a raw certificate. */
1680
            if (ctx->certificate == NULL) {
1681
                WOLFSSL_MSG("Ctx Certificate buffer not set!");
1682
            }
1683
        #ifndef WOLFSSL_X509_STORE_CERTS
1684
            else {
1685
                /* Create a certificate object from raw data. */
1686
                ctx->ourCert = wolfSSL_X509_d2i_ex(NULL,
1687
                    ctx->certificate->buffer, (int)ctx->certificate->length,
1688
                    ctx->heap);
1689
                ctx->ownOurCert = 1;
1690
            }
1691
        #endif
1692
        }
1693
        /* Return certificate cached against SSL/TLS context. */
1694
        ret = ctx->ourCert;
1695
    }
1696
1697
    return ret;
1698
}
1699
1700
/* Get the certificate in the SSL/TLS object.
1701
 *
1702
 * @param [in] ssl  SSL/TLS object.
1703
 * @return  Certificate being sent to peer.
1704
 * @return  NULL when ssl is NULL, no certificate set or on other error.
1705
 */
1706
WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
1707
{
1708
    WOLFSSL_X509* ret = NULL;
1709
1710
    /* Validate parameters. */
1711
    if (ssl == NULL) {
1712
        WOLFSSL_MSG("Invalid parameter");
1713
    }
1714
    /* Use certificate in SSL/TLS object if we own it. */
1715
    else if (ssl->buffers.weOwnCert) {
1716
        /* Check if we already have a certificate allocated. */
1717
        if (ssl->ourCert == NULL) {
1718
            /* Check if ctx has ourCert set - if so, use it instead of creating
1719
             * a new X509. This maintains pointer compatibility with
1720
             * applications (like nginx OCSP stapling) that use the X509 pointer
1721
             * from SSL_CTX_use_certificate as a lookup key. */
1722
            if (ssl->ctx != NULL && ssl->ctx->ourCert != NULL) {
1723
                /* Compare cert buffers to make sure they are the same */
1724
                if (ssl->buffers.certificate == NULL ||
1725
                    ssl->buffers.certificate->buffer == NULL ||
1726
                   (ssl->buffers.certificate->length ==
1727
                    ssl->ctx->certificate->length &&
1728
                    XMEMCMP(ssl->buffers.certificate->buffer,
1729
                             ssl->ctx->certificate->buffer,
1730
                             ssl->buffers.certificate->length) == 0)) {
1731
                    return ssl->ctx->ourCert;
1732
                }
1733
            }
1734
            /* We own certificate so this should never happen. */
1735
            if (ssl->buffers.certificate == NULL) {
1736
                WOLFSSL_MSG("Certificate buffer not set!");
1737
            }
1738
        #ifndef WOLFSSL_X509_STORE_CERTS
1739
            else {
1740
                /* Create a certificate object from raw data. */
1741
                ssl->ourCert = wolfSSL_X509_d2i_ex(NULL,
1742
                    ssl->buffers.certificate->buffer,
1743
                    (int)ssl->buffers.certificate->length, ssl->heap);
1744
            }
1745
        #endif
1746
        }
1747
        /* Return certificate cached against SSL/TLS object. */
1748
        ret = ssl->ourCert;
1749
    }
1750
    else {
1751
        /* Use any certificate in SSL/TLS context instead. */
1752
        ret = wolfSSL_CTX_get0_certificate(ssl->ctx);
1753
    }
1754
1755
    return ret;
1756
}
1757
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && KEEP_OUR_CERT */
1758
1759
#endif /* !NO_CERTS */
1760
1761
#endif /* !WOLFSSL_SSL_API_CERT_INCLUDED */