Coverage Report

Created: 2026-08-15 06:21

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