Coverage Report

Created: 2026-02-14 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-heapmath/src/ssl_api_cert.c
Line
Count
Source
1
/* ssl_api_cert.c
2
 *
3
 * Copyright (C) 2006-2025 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
81.3k
{
846
81.3k
    int ret = 1;
847
848
    /* Validate parameter. */
849
81.3k
    if (ssl == NULL) {
850
0
        WOLFSSL_MSG("Null function arg");
851
0
        ret = BAD_FUNC_ARG;
852
0
    }
853
81.3k
    else {
854
81.3k
        if (ssl->buffers.weOwnCert && !ssl->keepCert) {
855
65.6k
            WOLFSSL_MSG("Unloading cert");
856
65.6k
            FreeDer(&ssl->buffers.certificate);
857
        #ifdef KEEP_OUR_CERT
858
            wolfSSL_X509_free(ssl->ourCert);
859
            ssl->ourCert = NULL;
860
        #endif
861
65.6k
            ssl->buffers.weOwnCert = 0;
862
65.6k
        }
863
864
81.3k
        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
81.3k
        if (ssl->buffers.weOwnKey) {
871
65.6k
            WOLFSSL_MSG("Unloading key");
872
65.6k
            ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
873
65.6k
            FreeDer(&ssl->buffers.key);
874
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
875
            FreeDer(&ssl->buffers.keyMask);
876
        #endif
877
65.6k
            ssl->buffers.weOwnKey = 0;
878
65.6k
    }
879
880
    #ifdef WOLFSSL_DUAL_ALG_CERTS
881
        if (ssl->buffers.weOwnAltKey) {
882
            WOLFSSL_MSG("Unloading alt key");
883
            ForceZero(ssl->buffers.altKey->buffer, ssl->buffers.altKey->length);
884
            FreeDer(&ssl->buffers.altKey);
885
        #ifdef WOLFSSL_BLIND_PRIVATE_KEY
886
            FreeDer(&ssl->buffers.altKeyMask);
887
        #endif
888
            ssl->buffers.weOwnAltKey = 0;
889
        }
890
    #endif /* WOLFSSL_DUAL_ALG_CERTS */
891
81.3k
    }
892
893
81.3k
    return ret;
894
81.3k
}
895
896
/* Unload CAs from the certificate manager of the SSL/TLS context.
897
 *
898
 * @param [in] ctx  SSL/TLS context.
899
 * @return  1 on success.
900
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
901
 * @return  BAD_MUTEX_E when locking fails.
902
 */
903
int wolfSSL_CTX_UnloadCAs(WOLFSSL_CTX* ctx)
904
0
{
905
0
    int ret;
906
907
0
    WOLFSSL_ENTER("wolfSSL_CTX_UnloadCAs");
908
909
    /* Validate parameter. */
910
0
    if (ctx == NULL) {
911
0
        ret = BAD_FUNC_ARG;
912
0
    }
913
0
    else {
914
0
        ret = wolfSSL_CertManagerUnloadCAs(ctx->cm);
915
0
    }
916
917
0
    return ret;
918
0
}
919
920
/* Unload Intermediate CAs from the certificate manager of the SSL/TLS context.
921
 *
922
 * @param [in] ctx  SSL/TLS context.
923
 * @return  1 on success.
924
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
925
 * @return  BAD_MUTEX_E when locking fails.
926
 */
927
int wolfSSL_CTX_UnloadIntermediateCerts(WOLFSSL_CTX* ctx)
928
0
{
929
0
    int ret;
930
931
0
    WOLFSSL_ENTER("wolfSSL_CTX_UnloadIntermediateCerts");
932
933
    /* Validate parameter. */
934
0
    if (ctx == NULL) {
935
0
        ret = BAD_FUNC_ARG;
936
0
    }
937
    /* Lock reference count. */
938
0
    else if ((ret = wolfSSL_RefWithMutexLock(&ctx->ref)) == 0) {
939
        /* Must not have another reference for this operation to be done. */
940
0
        if (ctx->ref.count > 1) {
941
0
            WOLFSSL_MSG("ctx object must have a ref count of 1 before "
942
0
                        "unloading intermediate certs");
943
0
            ret = BAD_STATE_E;
944
0
        }
945
0
        else {
946
0
            ret = wolfSSL_CertManagerUnloadIntermediateCerts(ctx->cm);
947
0
        }
948
949
        /* Unlock reference count. */
950
0
        if (wolfSSL_RefWithMutexUnlock(&ctx->ref) != 0) {
951
0
            WOLFSSL_MSG("Failed to unlock mutex!");
952
0
        }
953
0
    }
954
955
0
    return ret;
956
0
}
957
958
959
#ifdef WOLFSSL_TRUST_PEER_CERT
960
/* Unload trusted peers from the certificate manager of the SSL/TLS context.
961
 *
962
 * @param [in] ctx  SSL/TLS context.
963
 * @return  1 on success.
964
 * @return  BAD_FUNC_ARG when ctx or ctx->cm is NULL.
965
 * @return  BAD_MUTEX_E when locking fails.
966
 */
967
int wolfSSL_CTX_Unload_trust_peers(WOLFSSL_CTX* ctx)
968
{
969
    int ret;
970
971
    WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
972
973
    /* Validate parameter. */
974
    if (ctx == NULL) {
975
        ret = BAD_FUNC_ARG;
976
    }
977
    else {
978
        ret = wolfSSL_CertManagerUnload_trust_peers(ctx->cm);
979
    }
980
981
    return ret;
982
}
983
984
#ifdef WOLFSSL_LOCAL_X509_STORE
985
/* Unload trusted peers from the certificate manager of the SSL/TLS object.
986
 *
987
 * @param [in] ctx  SSL/TLS context.
988
 * @return  1 on success.
989
 * @return  BAD_FUNC_ARG when ssl is NULL.
990
 * @return  BAD_MUTEX_E when locking fails.
991
 */
992
int wolfSSL_Unload_trust_peers(WOLFSSL* ssl)
993
{
994
    int ret;
995
996
    WOLFSSL_ENTER("wolfSSL_CTX_Unload_trust_peers");
997
998
    /* Validate parameter. */
999
    if (ssl == NULL) {
1000
        ret = BAD_FUNC_ARG;
1001
    }
1002
    else {
1003
        /* Output message when certificate manager for object. */
1004
        SSL_CM_WARNING(ssl);
1005
        return wolfSSL_CertManagerUnload_trust_peers(SSL_CM(ssl));
1006
    }
1007
1008
    return ret;
1009
}
1010
#endif /* WOLFSSL_LOCAL_X509_STORE */
1011
#endif /* WOLFSSL_TRUST_PEER_CERT */
1012
1013
#ifndef WOLFSSL_NO_CA_NAMES
1014
/* Add a CA certificate to the list of CA names.
1015
 *
1016
 * @param [in, out] ca_names  List of CA certificate subject names.
1017
 * @param [in]      x509      X509 certificate.
1018
 * @return  1 on success.
1019
 * @return  0 on failure.
1020
 */
1021
static int add_to_ca_names_list(WOLFSSL_STACK* ca_names, WOLFSSL_X509* x509)
1022
{
1023
    int ret = 1;
1024
    WOLFSSL_X509_NAME *nameCopy = NULL;
1025
1026
    nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(x509));
1027
    if (nameCopy == NULL) {
1028
        WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
1029
        ret = 0;
1030
    }
1031
    else if (wolfSSL_sk_X509_NAME_push(ca_names, nameCopy) <= 0) {
1032
        WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
1033
        wolfSSL_X509_NAME_free(nameCopy);
1034
        ret = 0;
1035
    }
1036
1037
    return ret;
1038
}
1039
1040
/* Add a client's CA to SSL/TLS context.
1041
 *
1042
 * @param [in] ctx   SSL/TLS context.
1043
 * @param [in] x509  X509 certificate.
1044
 * @return  1 on success.
1045
 * @return  0 on failure.
1046
 */
1047
int wolfSSL_CTX_add_client_CA(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
1048
{
1049
    int ret = 1;
1050
1051
    WOLFSSL_ENTER("wolfSSL_CTX_add_client_CA");
1052
1053
    /* Validate parameters. */
1054
    if ((ctx == NULL) || (x509 == NULL)) {
1055
        WOLFSSL_MSG("Bad argument");
1056
        ret = 0;
1057
    }
1058
    /* Create a stack of names if not present. */
1059
    else if (ctx->client_ca_names == NULL) {
1060
        ctx->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1061
        if (ctx->client_ca_names == NULL) {
1062
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1063
            ret = 0;
1064
        }
1065
    }
1066
    if (ret == 1) {
1067
        /* Add certificate's subject name to client CA name list. */
1068
        ret = add_to_ca_names_list(ctx->client_ca_names, x509);
1069
    }
1070
1071
    return ret;
1072
}
1073
1074
/* Add a client's CA to SSL/TLS object.
1075
 *
1076
 * @param [in] ssl   SSL/TLS object.
1077
 * @param [in] x509  X509 certificate.
1078
 * @return  1 on success.
1079
 * @return  0 on failure.
1080
 */
1081
int wolfSSL_add_client_CA(WOLFSSL* ssl, WOLFSSL_X509* x509)
1082
{
1083
    int ret = 1;
1084
1085
    WOLFSSL_ENTER("wolfSSL_add_client_CA");
1086
1087
    /* Validate parameters. */
1088
    if ((ssl == NULL) || (x509 == NULL)) {
1089
        WOLFSSL_MSG("Bad argument");
1090
        ret = 0;
1091
    }
1092
    /* Create a stack of names if not present. */
1093
    else if (ssl->client_ca_names == NULL) {
1094
        ssl->client_ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1095
        if (ssl->client_ca_names == NULL) {
1096
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1097
            ret = 0;
1098
        }
1099
    }
1100
    if (ret == 1) {
1101
        /* Add certificate's subject name to client CA name list. */
1102
        ret = add_to_ca_names_list(ssl->client_ca_names, x509);
1103
    }
1104
1105
    return ret;
1106
}
1107
1108
/* Add a CA to SSL/TLS context.
1109
 *
1110
 * @param [in] ctx   SSL/TLS context.
1111
 * @param [in] x509  X509 certificate.
1112
 * @return  1 on success.
1113
 * @return  0 on failure.
1114
 */
1115
int wolfSSL_CTX_add1_to_CA_list(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509)
1116
{
1117
    int ret = 1;
1118
1119
    WOLFSSL_ENTER("wolfSSL_CTX_add1_to_CA_list");
1120
1121
    /* Validate parameters. */
1122
    if ((ctx == NULL) || (x509 == NULL)) {
1123
        WOLFSSL_MSG("Bad argument");
1124
        ret = 0;
1125
    }
1126
    /* Create a stack of names if not present. */
1127
    else if (ctx->ca_names == NULL) {
1128
        ctx->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1129
        if (ctx->ca_names == NULL) {
1130
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1131
            ret = 0;
1132
        }
1133
    }
1134
    if (ret == 1) {
1135
        /* Add certificate's subject name to CA name list. */
1136
        ret = add_to_ca_names_list(ctx->ca_names, x509);
1137
    }
1138
1139
    return ret;
1140
}
1141
1142
/* Add a CA to SSL/TLS object.
1143
 *
1144
 * @param [in] ssl   SSL/TLS object.
1145
 * @param [in] x509  X509 certificate.
1146
 * @return  1 on success.
1147
 * @return  0 on failure.
1148
 */
1149
int wolfSSL_add1_to_CA_list(WOLFSSL* ssl, WOLFSSL_X509* x509)
1150
{
1151
    int ret = 1;
1152
1153
    WOLFSSL_ENTER("wolfSSL_add1_to_CA_list");
1154
1155
    /* Validate parameters. */
1156
    if ((ssl == NULL) || (x509 == NULL)) {
1157
        WOLFSSL_MSG("Bad argument");
1158
        ret = 0;
1159
    }
1160
    /* Create a stack of names if not present. */
1161
    else if (ssl->ca_names == NULL) {
1162
        ssl->ca_names = wolfSSL_sk_X509_NAME_new(NULL);
1163
        if (ssl->ca_names == NULL) {
1164
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1165
            ret = 0;
1166
        }
1167
    }
1168
    if (ret == 1) {
1169
        /* Add certificate's subject name to CA name list. */
1170
        ret = add_to_ca_names_list(ssl->ca_names, x509);
1171
    }
1172
1173
    return ret;
1174
}
1175
1176
/* Set the client CA list into SSL/TLS context.
1177
 *
1178
 * @param [in] ctx    SSL/TLS context.
1179
 * @param [in] names  List of CA subject names.
1180
 */
1181
void wolfSSL_CTX_set_client_CA_list(WOLFSSL_CTX* ctx,
1182
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1183
{
1184
    WOLFSSL_ENTER("wolfSSL_CTX_set_client_CA_list");
1185
1186
    /* Validate parameters. */
1187
    if (ctx != NULL) {
1188
        /* Dispose of any existing list. */
1189
        wolfSSL_sk_X509_NAME_pop_free(ctx->client_ca_names, NULL);
1190
        /* Take ownership of names list. */
1191
        ctx->client_ca_names = names;
1192
    }
1193
}
1194
1195
/* Set the client CA list into SSL/TLS object.
1196
 *
1197
 * @param [in] ssl    SSL/TLS object.
1198
 * @param [in] names  List of CA subject names.
1199
 */
1200
void wolfSSL_set_client_CA_list(WOLFSSL* ssl,
1201
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1202
{
1203
    WOLFSSL_ENTER("wolfSSL_set_client_CA_list");
1204
1205
    /* Validate parameters. */
1206
    if (ssl != NULL) {
1207
        /* Dispose of any existing list if the object owns it. */
1208
        if (ssl->client_ca_names != ssl->ctx->client_ca_names) {
1209
            wolfSSL_sk_X509_NAME_pop_free(ssl->client_ca_names, NULL);
1210
        }
1211
        /* Take ownership of names list. */
1212
        ssl->client_ca_names = names;
1213
    }
1214
}
1215
1216
/* Set the CA list into SSL/TLS context.
1217
 *
1218
 * @param [in] ctx    SSL/TLS context.
1219
 * @param [in] names  List of CA subject names.
1220
 */
1221
void wolfSSL_CTX_set0_CA_list(WOLFSSL_CTX* ctx,
1222
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1223
{
1224
    WOLFSSL_ENTER("wolfSSL_CTX_set0_CA_list");
1225
1226
    /* Validate parameters. */
1227
    if (ctx != NULL) {
1228
        /* Dispose of any existing list. */
1229
        wolfSSL_sk_X509_NAME_pop_free(ctx->ca_names, NULL);
1230
        /* Take ownership of names list. */
1231
        ctx->ca_names = names;
1232
    }
1233
}
1234
1235
/* Set the client CA list into SSL/TLS object.
1236
 *
1237
 * @param [in] ssl    SSL/TLS object.
1238
 * @param [in] names  List of CA subject names.
1239
 */
1240
void wolfSSL_set0_CA_list(WOLFSSL* ssl,
1241
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* names)
1242
{
1243
    WOLFSSL_ENTER("wolfSSL_set0_CA_list");
1244
1245
    /* Validate parameters. */
1246
    if (ssl != NULL) {
1247
        /* Dispose of any existing list if the object owns it. */
1248
        if (ssl->ca_names != ssl->ctx->ca_names) {
1249
            wolfSSL_sk_X509_NAME_pop_free(ssl->ca_names, NULL);
1250
        }
1251
        /* Take ownership of names list. */
1252
        ssl->ca_names = names;
1253
    }
1254
}
1255
1256
/* Get the list of client CA subject names from the SSL/TLS context.
1257
 *
1258
 * @param [in] ctx  SSL/TLS context.
1259
 * @return  List of CA subject names on success.
1260
 * @return  NULL when ctx is NULL or no names set.
1261
 */
1262
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get_client_CA_list(
1263
        const WOLFSSL_CTX *ctx)
1264
{
1265
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1266
1267
    WOLFSSL_ENTER("wolfSSL_CTX_get_client_CA_list");
1268
1269
    /* Validate parameter. */
1270
    if (ctx == NULL) {
1271
        WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get_client_CA_list");
1272
        ret = NULL;
1273
    }
1274
    else {
1275
        ret = ctx->client_ca_names;
1276
    }
1277
1278
    return ret;
1279
}
1280
1281
/* Get the list of client CA subject names from the SSL/TLS object.
1282
 *
1283
 * On server side: returns the CAs set via *_set_client_CA_list();
1284
 * On client side: returns the CAs received from server -- same as
1285
 * wolfSSL_get0_peer_CA_list().
1286
 *
1287
 * @param [in] ssl  SSL/TLS object.
1288
 * @return  List of CA subject names on success.
1289
 * @return  NULL when ssl is NULL or no names set.
1290
 */
1291
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get_client_CA_list(const WOLFSSL* ssl)
1292
{
1293
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1294
1295
    WOLFSSL_ENTER("wolfSSL_get_client_CA_list");
1296
1297
    /* Validate parameter. */
1298
    if (ssl == NULL) {
1299
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get_client_CA_list");
1300
        ret = NULL;
1301
    }
1302
    /* Client side return peer CA names. */
1303
    else if (ssl->options.side == WOLFSSL_CLIENT_END) {
1304
        ret = ssl->peer_ca_names;
1305
    }
1306
    /* Server side return client CA names. */
1307
    else {
1308
        ret = SSL_CLIENT_CA_NAMES(ssl);
1309
    }
1310
1311
    return ret;
1312
}
1313
1314
/* Get the list of CA subject names from the SSL/TLS context.
1315
 *
1316
 * @param [in] ctx  SSL/TLS context.
1317
 * @return  List of CA subject names on success.
1318
 * @return  NULL when ctx is NULL or no names set.
1319
 */
1320
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_CTX_get0_CA_list(
1321
    const WOLFSSL_CTX *ctx)
1322
{
1323
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1324
1325
    WOLFSSL_ENTER("wolfSSL_CTX_get0_CA_list");
1326
1327
    /* Validate parameter. */
1328
    if (ctx == NULL) {
1329
        WOLFSSL_MSG("Bad argument passed to wolfSSL_CTX_get0_CA_list");
1330
        ret = NULL;
1331
    }
1332
    else {
1333
        /* Return list directly. */
1334
        ret = ctx->ca_names;
1335
    }
1336
1337
    return ret;
1338
}
1339
1340
/* Get the list of CA subject names from the SSL/TLS object.
1341
 *
1342
 * Always returns the CA's set via *_set0_CA_list.
1343
 *
1344
 * @param [in] ssl  SSL/TLS object.
1345
 * @return  List of CA subject names on success.
1346
 * @return  NULL when ssl is NULL or no names set.
1347
 */
1348
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get0_CA_list(const WOLFSSL *ssl)
1349
{
1350
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1351
1352
    WOLFSSL_ENTER("wolfSSL_get0_CA_list");
1353
1354
    /* Validate parameter. */
1355
    if (ssl == NULL) {
1356
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get0_CA_list");
1357
        ret = NULL;
1358
    }
1359
    else {
1360
        /* Return list directly from object, if available, or context. */
1361
        ret = SSL_CA_NAMES(ssl);
1362
    }
1363
1364
    return ret;
1365
}
1366
1367
/* Get the list of peer CA subject names from the SSL/TLS object.
1368
 *
1369
 * Always returns the CA's received from the peer.
1370
 *
1371
 * @param [in] ssl  SSL/TLS object.
1372
 * @return  List of CA subject names on success.
1373
 * @return  NULL when ssl is NULL or no names set.
1374
 */
1375
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_get0_peer_CA_list(const WOLFSSL* ssl)
1376
{
1377
    WOLF_STACK_OF(WOLFSSL_X509_NAME)* ret;
1378
1379
    WOLFSSL_ENTER("wolfSSL_get0_peer_CA_list");
1380
1381
    /* Validate parameter. */
1382
    if (ssl == NULL) {
1383
        WOLFSSL_MSG("Bad argument passed to wolfSSL_get0_peer_CA_list");
1384
        ret = NULL;
1385
    }
1386
    else {
1387
        /* Return list directly from object. */
1388
        ret = ssl->peer_ca_names;
1389
    }
1390
1391
    return ret;
1392
}
1393
1394
#ifndef NO_BIO
1395
/* Load the client CA subject names from file.
1396
 *
1397
 * @param [in] fname  Name of file containing client CA certificates.
1398
 * @return  A list of certificate names on success.
1399
 * @return  NULL on error.
1400
 */
1401
WOLF_STACK_OF(WOLFSSL_X509_NAME)* wolfSSL_load_client_CA_file(const char* fname)
1402
{
1403
    /* The webserver build is using this to load a CA into the server
1404
     * for client authentication as an option. Have this return NULL in
1405
     * that case. If OPENSSL_EXTRA is enabled, go ahead and include
1406
     * the function. */
1407
#ifdef OPENSSL_EXTRA
1408
    WOLFSSL_STACK *list = NULL;
1409
    WOLFSSL_BIO* bio = NULL;
1410
    WOLFSSL_X509 *cert = NULL;
1411
    int err = 0;
1412
    unsigned long error;
1413
1414
    WOLFSSL_ENTER("wolfSSL_load_client_CA_file");
1415
1416
    /* Create a file BIO to read. */
1417
    bio = wolfSSL_BIO_new_file(fname, "rb");
1418
    if (bio == NULL) {
1419
        WOLFSSL_MSG("wolfSSL_BIO_new_file error");
1420
        err = 1;
1421
    }
1422
1423
    if (!err) {
1424
        /* Create an empty list of certificate names - default compare cb. */
1425
        list = wolfSSL_sk_X509_NAME_new(NULL);
1426
        if (list == NULL) {
1427
            WOLFSSL_MSG("wolfSSL_sk_X509_NAME_new error");
1428
            err = 1;
1429
        }
1430
    }
1431
1432
    /* Read each certificate in the chain out of the file. */
1433
    while (!err && wolfSSL_PEM_read_bio_X509(bio, &cert, NULL, NULL) != NULL) {
1434
        WOLFSSL_X509_NAME *nameCopy;
1435
1436
        /* Need a persistent copy of the subject name. */
1437
        nameCopy = wolfSSL_X509_NAME_dup(wolfSSL_X509_get_subject_name(cert));
1438
        if (nameCopy == NULL) {
1439
            WOLFSSL_MSG("wolfSSL_X509_NAME_dup error");
1440
            err = 1;
1441
        }
1442
        else {
1443
            /* Original certificate will be freed - clear reference to it. */
1444
            nameCopy->x509 = NULL;
1445
1446
            if (wolfSSL_sk_X509_NAME_push(list, nameCopy) <= 0) {
1447
                WOLFSSL_MSG("wolfSSL_sk_X509_NAME_push error");
1448
                /* Name not stored - free now as only place needing to. */
1449
                wolfSSL_X509_NAME_free(nameCopy);
1450
                err = 1;
1451
            }
1452
        }
1453
1454
        /* Dispose of certificate read. */
1455
        wolfSSL_X509_free(cert);
1456
        cert = NULL;
1457
    }
1458
1459
    /* Clear any error due to no more certificates. */
1460
    CLEAR_ASN_NO_PEM_HEADER_ERROR(error);
1461
1462
    if (err) {
1463
        /* Error occurred so return NULL. */
1464
        wolfSSL_sk_X509_NAME_pop_free(list, NULL);
1465
        list = NULL;
1466
    }
1467
    wolfSSL_BIO_free(bio);
1468
    return list;
1469
#else
1470
    (void)fname;
1471
    return NULL;
1472
#endif
1473
}
1474
#endif /* !NO_BIO */
1475
#endif /* WOLFSSL_NO_CA_NAMES */
1476
1477
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1478
/* Get the certificate store of the SSL/TLS context.
1479
 *
1480
 * @param [in] ctx  SSL/TLS context.
1481
 * @return  X509 certificate store on success.
1482
 * @return  NULL when ctx is NULL.
1483
 */
1484
WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(const WOLFSSL_CTX* ctx)
1485
{
1486
    WOLFSSL_X509_STORE* ret;
1487
1488
    /* Validate parameter. */
1489
    if (ctx == NULL) {
1490
        ret = NULL;
1491
    }
1492
    /* Use pointer to external store if set. */
1493
    else if (ctx->x509_store_pt != NULL) {
1494
        ret = ctx->x509_store_pt;
1495
    }
1496
    else {
1497
        /* Return reference to store that is part of the context. */
1498
        ret = (WOLFSSL_X509_STORE*)&ctx->x509_store;
1499
    }
1500
1501
    return ret;
1502
}
1503
1504
/* Set the certificate store of the SSL/TLS context.
1505
 *
1506
 * @param [in] ctx  SSL/TLS context.
1507
 * @return  X509 certificate store on success.
1508
 * @return  NULL when ctx is NULL.
1509
 */
1510
void wolfSSL_CTX_set_cert_store(WOLFSSL_CTX* ctx, WOLFSSL_X509_STORE* str)
1511
{
1512
    WOLFSSL_ENTER("wolfSSL_CTX_set_cert_store");
1513
1514
    /* Validate parameters. */
1515
    if ((ctx == NULL) || (str == NULL) || (ctx->cm == str->cm)) {
1516
        WOLFSSL_MSG("Invalid parameters");
1517
    }
1518
    else if (wolfSSL_CertManager_up_ref(str->cm) != 1) {
1519
        WOLFSSL_MSG("wolfSSL_CertManager_up_ref error");
1520
    }
1521
    else {
1522
        /* Free any cert manager. */
1523
        wolfSSL_CertManagerFree(ctx->cm);
1524
        /* Free any external store. */
1525
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
1526
        /* Set the certificate manager into context. */
1527
        ctx->cm               = str->cm;
1528
        ctx->x509_store.cm    = str->cm;
1529
        ctx->x509_store.cache = str->cache;
1530
        /* Take ownership of store and free it with context free. */
1531
        ctx->x509_store_pt    = str;
1532
        /* Context has ownership and free it with context free. */
1533
        ctx->cm->x509_store_p = ctx->x509_store_pt;
1534
    }
1535
}
1536
1537
#ifdef OPENSSL_ALL
1538
/* Set certificate store into SSL/TLS context but don't take ownership.
1539
 *
1540
 * @param [in] ctx  SSL/TLS context.
1541
 * @param [in] str  Certificate store.
1542
 * @return  1 on success.
1543
 * @return  0 when ctx or str is NULL or on other error.
1544
 */
1545
int wolfSSL_CTX_set1_verify_cert_store(WOLFSSL_CTX* ctx,
1546
    WOLFSSL_X509_STORE* str)
1547
{
1548
    int ret;
1549
1550
    WOLFSSL_ENTER("wolfSSL_CTX_set1_verify_cert_store");
1551
1552
    /* Validate parameters. */
1553
    if ((ctx == NULL) || (str == NULL)) {
1554
        WOLFSSL_MSG("Bad parameter");
1555
        ret = 0;
1556
    }
1557
    /* Nothing to do when store being set is the same as existing in context. */
1558
    else if (str == CTX_STORE(ctx)) {
1559
        ret = 1;
1560
    }
1561
    /* Increase ref so we can store pointer and free it with context free. */
1562
    else if (wolfSSL_X509_STORE_up_ref(str) != 1) {
1563
        WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
1564
        ret = 0;
1565
    }
1566
    else {
1567
        /* Free any external store. */
1568
        wolfSSL_X509_STORE_free(ctx->x509_store_pt);
1569
        /* Ref count increased - store pointer and free with context free. */
1570
        ctx->x509_store_pt = str;
1571
        ret = 1;
1572
    }
1573
1574
    return ret;
1575
}
1576
#endif
1577
1578
1579
/* Set certificate store into SSL/TLS object.
1580
 *
1581
 * @param [in] ssl  SSL/TLS object.
1582
 * @param [in] str  Certificate store.
1583
 * @param [in] ref  Take a reference to passed in certificate store.
1584
 * @return  1 on success.
1585
 * @return  0 when ssl or str is NULL or on other error.
1586
 */
1587
static int wolfssl_set_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str,
1588
    int ref)
1589
{
1590
    int ret;
1591
1592
    WOLFSSL_ENTER("wolfssl_set_verify_cert_store");
1593
1594
    /* Validate parameters. */
1595
    if ((ssl == NULL) || (str == NULL)) {
1596
        WOLFSSL_MSG("Bad parameter");
1597
        ret = 0;
1598
    }
1599
    /* Nothing to do when store being set is the same as existing in object. */
1600
    else if (str == SSL_STORE(ssl)) {
1601
        ret = 1;
1602
    }
1603
    else if (ref && (wolfSSL_X509_STORE_up_ref(str) != 1)) {
1604
        WOLFSSL_MSG("wolfSSL_X509_STORE_up_ref error");
1605
        ret = 0;
1606
    }
1607
    else {
1608
        /* Free any external store. */
1609
        wolfSSL_X509_STORE_free(ssl->x509_store_pt);
1610
        if (str == ssl->ctx->x509_store_pt) {
1611
            /* Setting ctx store - just revert to using that instead. */
1612
            ssl->x509_store_pt = NULL;
1613
        }
1614
        else {
1615
            /* Ref count increased - store pointer and free with object free. */
1616
            ssl->x509_store_pt = str;
1617
        }
1618
        ret = 1;
1619
    }
1620
1621
    return ret;
1622
}
1623
1624
/* Set certificate store into SSL/TLS object and take ownership.
1625
 *
1626
 * @param [in] ssl  SSL/TLS object.
1627
 * @param [in] str  Certificate store.
1628
 * @return  1 on success.
1629
 * @return  0 when ssl or str is NULL or on other error.
1630
 */
1631
int wolfSSL_set0_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
1632
{
1633
    WOLFSSL_ENTER("wolfSSL_set0_verify_cert_store");
1634
1635
    return wolfssl_set_verify_cert_store(ssl, str, 0);
1636
}
1637
1638
/* Set certificate store into SSL/TLS object but don't take ownership.
1639
 *
1640
 * @param [in] ssl  SSL/TLS object.
1641
 * @param [in] str  Certificate store.
1642
 * @return  1 on success.
1643
 * @return  0 when ssl or str is NULL or on other error.
1644
 */
1645
int wolfSSL_set1_verify_cert_store(WOLFSSL *ssl, WOLFSSL_X509_STORE* str)
1646
{
1647
    WOLFSSL_ENTER("wolfSSL_set1_verify_cert_store");
1648
1649
    return wolfssl_set_verify_cert_store(ssl, str, 1);
1650
}
1651
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
1652
1653
/* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function
1654
   KEEP_OUR_CERT is to ensure ability to return ssl certificate */
1655
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
1656
    defined(KEEP_OUR_CERT)
1657
/* Get the certificate in the SSL/TLS context.
1658
 *
1659
 * @param [in] ctx  SSL/TLS context.
1660
 * @return  Certificate being sent to peer.
1661
 * @return  NULL when ctx is NULL, no certificate set or on other error.
1662
 */
1663
WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx)
1664
{
1665
    WOLFSSL_X509* ret = NULL;
1666
1667
    /* Validate parameters. */
1668
    if (ctx == NULL) {
1669
        WOLFSSL_MSG("Invalid parameter");
1670
    }
1671
    else {
1672
        /* Check if we already have a certificate allocated. */
1673
        if (ctx->ourCert == NULL) {
1674
            /* Check if there is a raw certificate. */
1675
            if (ctx->certificate == NULL) {
1676
                WOLFSSL_MSG("Ctx Certificate buffer not set!");
1677
            }
1678
        #ifndef WOLFSSL_X509_STORE_CERTS
1679
            else {
1680
                /* Create a certificate object from raw data. */
1681
                ctx->ourCert = wolfSSL_X509_d2i_ex(NULL,
1682
                    ctx->certificate->buffer, (int)ctx->certificate->length,
1683
                    ctx->heap);
1684
                ctx->ownOurCert = 1;
1685
            }
1686
        #endif
1687
        }
1688
        /* Return certificate cached against SSL/TLS context. */
1689
        ret = ctx->ourCert;
1690
    }
1691
1692
    return ret;
1693
}
1694
1695
/* Get the certificate in the SSL/TLS object.
1696
 *
1697
 * @param [in] ssl  SSL/TLS object.
1698
 * @return  Certificate being sent to peer.
1699
 * @return  NULL when ssl is NULL, no certificate set or on other error.
1700
 */
1701
WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl)
1702
{
1703
    WOLFSSL_X509* ret = NULL;
1704
1705
    /* Validate parameters. */
1706
    if (ssl == NULL) {
1707
        WOLFSSL_MSG("Invalid parameter");
1708
    }
1709
    /* Use certificate in SSL/TLS object if we own it. */
1710
    else if (ssl->buffers.weOwnCert) {
1711
        /* Check if we already have a certificate allocated. */
1712
        if (ssl->ourCert == NULL) {
1713
            /* We own certificate so this should never happen. */
1714
            if (ssl->buffers.certificate == NULL) {
1715
                WOLFSSL_MSG("Certificate buffer not set!");
1716
            }
1717
        #ifndef WOLFSSL_X509_STORE_CERTS
1718
            else {
1719
                /* Create a certificate object from raw data. */
1720
                ssl->ourCert = wolfSSL_X509_d2i_ex(NULL,
1721
                    ssl->buffers.certificate->buffer,
1722
                    (int)ssl->buffers.certificate->length, ssl->heap);
1723
            }
1724
        #endif
1725
        }
1726
        /* Return certificate cached against SSL/TLS object. */
1727
        ret = ssl->ourCert;
1728
    }
1729
    else {
1730
        /* Use any certificate in SSL/TLS context instead. */
1731
        ret = wolfSSL_CTX_get0_certificate(ssl->ctx);
1732
    }
1733
1734
    return ret;
1735
}
1736
#endif /* (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) && KEEP_OUR_CERT */
1737
1738
#endif /* !NO_CERTS */
1739
1740
#endif /* !WOLFSSL_SSL_API_CERT_INCLUDED */