Coverage Report

Created: 2026-10-16 06:40

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