Coverage Report

Created: 2026-05-18 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/src/x509_str.c
Line
Count
Source
1
/* x509_str.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_X509_STORE_INCLUDED)
25
    #ifndef WOLFSSL_IGNORE_FILE_WARN
26
        #warning x509_str.c does not need to be compiled separately from ssl.c
27
    #endif
28
#else
29
30
#ifndef WOLFCRYPT_ONLY
31
32
#ifndef NO_CERTS
33
34
#ifdef OPENSSL_EXTRA
35
static int X509StoreGetIssuerEx(WOLFSSL_X509 **issuer,
36
                            WOLFSSL_STACK *certs, WOLFSSL_X509 *x);
37
static int X509StoreAddCa(WOLFSSL_X509_STORE* store,
38
                                          WOLFSSL_X509* x509, int type);
39
#endif
40
41
/* Based on OpenSSL default max depth */
42
#ifndef WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH
43
#define WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH 100
44
#endif
45
46
/******************************************************************************
47
 * START OF X509_STORE_CTX APIs
48
 *****************************************************************************/
49
50
/* This API is necessary outside of OPENSSL_EXTRA because it is used in
51
 * SetupStoreCtxCallback */
52
WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new_ex(void* heap)
53
0
{
54
0
    WOLFSSL_X509_STORE_CTX* ctx;
55
0
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_new_ex");
56
57
0
    ctx = (WOLFSSL_X509_STORE_CTX*)XMALLOC(sizeof(WOLFSSL_X509_STORE_CTX), heap,
58
0
                                    DYNAMIC_TYPE_X509_CTX);
59
0
    if (ctx != NULL) {
60
0
        XMEMSET(ctx, 0, sizeof(WOLFSSL_X509_STORE_CTX));
61
0
        ctx->heap = heap;
62
#ifdef OPENSSL_EXTRA
63
        if ((ctx->owned = wolfSSL_sk_X509_new_null()) == NULL) {
64
            XFREE(ctx, heap, DYNAMIC_TYPE_X509_CTX);
65
            ctx = NULL;
66
        }
67
        if (ctx != NULL &&
68
            wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL) !=
69
                WOLFSSL_SUCCESS) {
70
            wolfSSL_X509_STORE_CTX_free(ctx);
71
            ctx = NULL;
72
        }
73
#endif
74
0
    }
75
76
0
    return ctx;
77
0
}
78
79
/* This API is necessary outside of OPENSSL_EXTRA because it is used in
80
 * SetupStoreCtxCallback */
81
/* free's extra data */
82
void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx)
83
0
{
84
0
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_free");
85
0
    if (ctx != NULL) {
86
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
87
        wolfSSL_CRYPTO_cleanup_ex_data(&ctx->ex_data);
88
#endif
89
90
#ifdef OPENSSL_EXTRA
91
        XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL);
92
        ctx->param = NULL;
93
94
        if (ctx->chain != NULL) {
95
            wolfSSL_sk_X509_free(ctx->chain);
96
        }
97
        if (ctx->owned != NULL) {
98
            wolfSSL_sk_X509_pop_free(ctx->owned, NULL);
99
        }
100
101
        if (ctx->current_issuer != NULL) {
102
            wolfSSL_X509_free(ctx->current_issuer);
103
            ctx->current_issuer = NULL;
104
        }
105
#endif
106
107
0
        XFREE(ctx, ctx->heap, DYNAMIC_TYPE_X509_CTX);
108
0
    }
109
0
}
110
111
#ifdef OPENSSL_EXTRA
112
113
#if defined(SESSION_CERTS) || defined(WOLFSSL_SIGNER_DER_CERT)
114
115
/**
116
 * Find the issuing cert of the input cert. On a self-signed cert this
117
 * function will return an error.
118
 * @param issuer The issuer x509 struct is returned here
119
 * @param cm     The cert manager that is queried for the issuer
120
 * @param x      This cert's issuer will be queried in cm
121
 * @return       WOLFSSL_SUCCESS on success
122
 *               WOLFSSL_FAILURE on error
123
 */
124
static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm,
125
        WOLFSSL_X509 *x)
126
{
127
    Signer* ca = NULL;
128
    WC_DECLARE_VAR(cert, DecodedCert, 1, 0);
129
130
    if (cm == NULL || x == NULL || x->derCert == NULL) {
131
        WOLFSSL_MSG("No cert DER buffer or NULL cm. Defining "
132
                    "WOLFSSL_SIGNER_DER_CERT could solve the issue");
133
        return WOLFSSL_FAILURE;
134
    }
135
136
    WC_ALLOC_VAR_EX(cert, DecodedCert, 1, NULL, DYNAMIC_TYPE_DCERT,
137
        return WOLFSSL_FAILURE);
138
139
    /* Use existing CA retrieval APIs that use DecodedCert. */
140
    InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, cm->heap);
141
    if (ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL) == 0
142
            && !cert->selfSigned) {
143
    #ifndef NO_SKID
144
        if (cert->extAuthKeyIdSet)
145
            ca = GetCA(cm, cert->extAuthKeyId);
146
        if (ca == NULL)
147
            ca = GetCAByName(cm, cert->issuerHash);
148
    #else /* NO_SKID */
149
        ca = GetCA(cm, cert->issuerHash);
150
    #endif /* NO SKID */
151
    }
152
    FreeDecodedCert(cert);
153
    WC_FREE_VAR_EX(cert, NULL, DYNAMIC_TYPE_DCERT);
154
155
    if (ca == NULL)
156
        return WOLFSSL_FAILURE;
157
158
#ifdef WOLFSSL_SIGNER_DER_CERT
159
    /* populate issuer with Signer DER */
160
    if (wolfSSL_X509_d2i_ex(issuer, ca->derCert->buffer,
161
            ca->derCert->length, cm->heap) == NULL)
162
        return WOLFSSL_FAILURE;
163
#else
164
    /* Create an empty certificate as CA doesn't have a certificate. */
165
    *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
166
        DYNAMIC_TYPE_OPENSSL);
167
    if (*issuer == NULL)
168
        return WOLFSSL_FAILURE;
169
170
    InitX509((*issuer), 1, NULL);
171
#endif
172
173
    return WOLFSSL_SUCCESS;
174
}
175
#endif /* SESSION_CERTS || WOLFSSL_SIGNER_DER_CERT */
176
177
WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
178
{
179
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_new");
180
    return wolfSSL_X509_STORE_CTX_new_ex(NULL);
181
}
182
183
int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
184
     WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509,
185
     WOLF_STACK_OF(WOLFSSL_X509)* sk)
186
{
187
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
188
189
    if (ctx != NULL) {
190
        ctx->store = store;
191
        #ifndef WOLFSSL_X509_STORE_CERTS
192
        ctx->current_cert = x509;
193
        #else
194
        if(x509 != NULL){
195
            ctx->current_cert = wolfSSL_X509_d2i_ex(NULL,
196
                    x509->derCert->buffer,
197
                    x509->derCert->length,
198
                    x509->heap);
199
            if(ctx->current_cert == NULL)
200
                return WOLFSSL_FAILURE;
201
        } else
202
            ctx->current_cert = NULL;
203
        #endif
204
205
        ctx->ctxIntermediates = sk;
206
        if (ctx->chain != NULL) {
207
            wolfSSL_sk_X509_free(ctx->chain);
208
            ctx->chain = NULL;
209
        }
210
#ifdef SESSION_CERTS
211
        ctx->sesChain = NULL;
212
#endif
213
        ctx->domain = NULL;
214
#ifdef HAVE_EX_DATA
215
        XMEMSET(&ctx->ex_data, 0, sizeof(ctx->ex_data));
216
#endif
217
        ctx->userCtx = NULL;
218
        ctx->error = 0;
219
        ctx->error_depth = 0;
220
        ctx->discardSessionCerts = 0;
221
222
        if (ctx->param == NULL) {
223
            ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
224
                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
225
                           ctx->heap, DYNAMIC_TYPE_OPENSSL);
226
            if (ctx->param == NULL){
227
                WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init failed");
228
                return WOLFSSL_FAILURE;
229
            }
230
            XMEMSET(ctx->param, 0, sizeof(*ctx->param));
231
        }
232
233
        /* Copy check_time from store parameters if available */
234
        if (store != NULL && store->param != NULL) {
235
            if ((store->param->flags & WOLFSSL_USE_CHECK_TIME) != 0 &&
236
                store->param->check_time != 0) {
237
                ctx->param->check_time = store->param->check_time;
238
                ctx->param->flags |= WOLFSSL_USE_CHECK_TIME;
239
            }
240
            if ((store->param->flags & WOLFSSL_NO_CHECK_TIME) != 0) {
241
                ctx->param->flags |= WOLFSSL_NO_CHECK_TIME;
242
            }
243
        }
244
245
        return WOLFSSL_SUCCESS;
246
    }
247
    return WOLFSSL_FAILURE;
248
}
249
250
/* Its recommended to use a full free -> init cycle of all the objects
251
 * because wolfSSL_X509_STORE_CTX_init may modify the store too which doesn't
252
 * get reset here. */
253
void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
254
{
255
    if (ctx != NULL) {
256
257
        XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL);
258
        ctx->param = NULL;
259
260
        wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
261
    }
262
}
263
264
265
void wolfSSL_X509_STORE_CTX_trusted_stack(WOLFSSL_X509_STORE_CTX *ctx,
266
                                          WOLF_STACK_OF(WOLFSSL_X509) *sk)
267
{
268
    if (ctx != NULL) {
269
        ctx->setTrustedSk = sk;
270
    }
271
}
272
273
274
/* Returns corresponding X509 error from internal ASN error <e> */
275
int GetX509Error(int e)
276
{
277
    switch (e) {
278
        case WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E):
279
            return WOLFSSL_X509_V_ERR_CERT_NOT_YET_VALID;
280
        case WC_NO_ERR_TRACE(ASN_AFTER_DATE_E):
281
            return WOLFSSL_X509_V_ERR_CERT_HAS_EXPIRED;
282
        case WC_NO_ERR_TRACE(ASN_NO_SIGNER_E):
283
            /* get issuer error if no CA found locally */
284
            return WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
285
        case WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E):
286
            return WOLFSSL_X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
287
        case WC_NO_ERR_TRACE(ASN_PATHLEN_INV_E):
288
        case WC_NO_ERR_TRACE(ASN_PATHLEN_SIZE_E):
289
            return WOLFSSL_X509_V_ERR_PATH_LENGTH_EXCEEDED;
290
        case WC_NO_ERR_TRACE(ASN_SIG_OID_E):
291
        case WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E):
292
        case WC_NO_ERR_TRACE(ASN_SIG_HASH_E):
293
        case WC_NO_ERR_TRACE(ASN_SIG_KEY_E):
294
            return WOLFSSL_X509_V_ERR_CERT_SIGNATURE_FAILURE;
295
        /* We can't disambiguate if its the before or after date that caused
296
         * the error. Assume expired. */
297
        case WC_NO_ERR_TRACE(CRL_CERT_DATE_ERR):
298
            return WOLFSSL_X509_V_ERR_CRL_HAS_EXPIRED;
299
        case WC_NO_ERR_TRACE(CRL_CERT_REVOKED):
300
            return WOLFSSL_X509_V_ERR_CERT_REVOKED;
301
        case WC_NO_ERR_TRACE(CRL_MISSING):
302
            return WOLFSSL_X509_V_ERR_UNABLE_TO_GET_CRL;
303
        case 0:
304
        case 1:
305
            return 0;
306
        default:
307
#ifdef HAVE_WOLFSSL_MSG_EX
308
            WOLFSSL_MSG_EX("Error not configured or implemented yet: %d", e);
309
#else
310
            WOLFSSL_MSG("Error not configured or implemented yet");
311
#endif
312
            return e;
313
    }
314
}
315
316
static void SetupStoreCtxError_ex(WOLFSSL_X509_STORE_CTX* ctx, int ret,
317
                                                                    int depth)
318
{
319
    int error = GetX509Error(ret);
320
321
    /* Do not overwrite a previously recorded error with success; preserve
322
     * the worst-seen error across the chain walk. */
323
    if (error == 0 && ctx->error != 0)
324
        return;
325
326
    wolfSSL_X509_STORE_CTX_set_error(ctx, error);
327
    wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
328
}
329
330
static void SetupStoreCtxError(WOLFSSL_X509_STORE_CTX* ctx, int ret)
331
{
332
    int depth = 0;
333
334
    /* Set error depth */
335
    if (ctx->chain)
336
        depth = (int)ctx->chain->num;
337
338
    SetupStoreCtxError_ex(ctx, ret, depth);
339
}
340
341
#ifndef NO_ASN_TIME
342
/* Post certificate validation date handling. This function is called after the
343
 * certificate has been verified by the certificate manager. It then checks if
344
 * X509 store parameters are set for date validation override.
345
 * @param ctx The certificate store context
346
 * @param ret The return value from the certificate manager verify
347
 * @return The return value for the certificate date validation after override
348
 */
349
static int X509StoreVerifyCertDate(WOLFSSL_X509_STORE_CTX* ctx, int ret)
350
{
351
    byte *afterDate  = ctx->current_cert->notAfter.data;
352
    byte *beforeDate = ctx->current_cert->notBefore.data;
353
354
    /* Only override existing date errors or WOLFSSL_SUCCESS. */
355
    if (ret == WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) ||
356
            ret == WC_NO_ERR_TRACE(ASN_AFTER_DATE_E) ||
357
            ret == WC_NO_ERR_TRACE(WOLFSSL_SUCCESS)) {
358
#ifdef USE_WOLF_VALIDDATE
359
        WOLFSSL_X509_VERIFY_PARAM* param = NULL;
360
361
        /* If no external XVALIDATE_DATE was defined then use param for date
362
           validation overrides. */
363
        if (ctx->param != NULL) {
364
            param = ctx->param;
365
        }
366
        else if (ctx->store != NULL && ctx->store->param != NULL) {
367
            param = ctx->store->param;
368
        }
369
370
        if (param != NULL) {
371
            if ((param->flags & WOLFSSL_NO_CHECK_TIME) != 0) {
372
                WOLFSSL_MSG("Overriding date validation WOLFSSL_NO_CHECK_TIME");
373
                ret = WOLFSSL_SUCCESS;
374
            }
375
            else if ((param->flags & WOLFSSL_USE_CHECK_TIME) != 0 &&
376
                (param->check_time != 0)) {
377
                time_t checkTime = param->check_time;
378
                ret = WOLFSSL_SUCCESS; /* override date error and use custom set
379
                                        time for validating certificate dates */
380
                WOLFSSL_MSG("Override date validation, WOLFSSL_USE_CHECK_TIME");
381
                if (wc_ValidateDateWithTime(afterDate,
382
                    (byte)ctx->current_cert->notAfter.type, ASN_AFTER,
383
                    checkTime, ctx->current_cert->notAfter.length) < 1) {
384
                    ret = ASN_AFTER_DATE_E;
385
                }
386
                else if (wc_ValidateDateWithTime(beforeDate,
387
                    (byte)ctx->current_cert->notBefore.type, ASN_BEFORE,
388
                    checkTime, ctx->current_cert->notBefore.length) < 1) {
389
                    ret = ASN_BEFORE_DATE_E;
390
                }
391
            }
392
        #if defined(OPENSSL_ALL)
393
            else {
394
                WOLFSSL_MSG("Using system time for date validation");
395
                /* use system time for date validation */
396
                if (wc_ValidateDate(afterDate,
397
                        (byte)ctx->current_cert->notAfter.type, ASN_AFTER,
398
                        ctx->current_cert->notAfter.length) < 1) {
399
                    ret = ASN_AFTER_DATE_E;
400
                }
401
                else if (wc_ValidateDate(beforeDate,
402
                        (byte)ctx->current_cert->notBefore.type, ASN_BEFORE,
403
                        ctx->current_cert->notBefore.length) < 1) {
404
                    ret = ASN_BEFORE_DATE_E;
405
                }
406
            }
407
        #endif
408
        }
409
#else
410
        if (XVALIDATE_DATE(afterDate,
411
                (byte)ctx->current_cert->notAfter.type, ASN_AFTER,
412
                ctx->current_cert->notAfter.length) < 1) {
413
            ret = ASN_AFTER_DATE_E;
414
        }
415
        else if (XVALIDATE_DATE(beforeDate,
416
                (byte)ctx->current_cert->notBefore.type, ASN_BEFORE,
417
                ctx->current_cert->notBefore.length) < 1) {
418
            ret = ASN_BEFORE_DATE_E;
419
        }
420
#endif /* USE_WOLF_VALIDDATE */
421
    }
422
423
    return ret;
424
}
425
#endif /* NO_ASN_TIME */
426
427
static int X509StoreVerifyCert(WOLFSSL_X509_STORE_CTX* ctx)
428
{
429
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
430
    WOLFSSL_ENTER("X509StoreVerifyCert");
431
432
    if (ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
433
        ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
434
                    ctx->current_cert->derCert->buffer,
435
                    ctx->current_cert->derCert->length,
436
                    WOLFSSL_FILETYPE_ASN1);
437
    #ifndef NO_ASN_TIME
438
        /* update return value with any date validation overrides */
439
        ret = X509StoreVerifyCertDate(ctx, ret);
440
    #endif
441
        SetupStoreCtxError(ctx, ret);
442
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
443
        if (ctx->store->verify_cb)
444
            ret = ctx->store->verify_cb(ret >= 0 ? 1 : 0, ctx) == 1 ?
445
                                                        WOLFSSL_SUCCESS : ret;
446
    #endif
447
    }
448
#if !defined(NO_ASN_TIME) && defined(OPENSSL_ALL)
449
    if (ret != WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) &&
450
        ret != WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) {
451
        /* With OpenSSL, we need to check the certificate's date
452
        * after certificate manager verification,
453
        * as it skips date validation when other errors are present.
454
        */
455
        ret = X509StoreVerifyCertDate(ctx, ret);
456
        SetupStoreCtxError(ctx, ret);
457
        ret = ret == WOLFSSL_SUCCESS ? 1 : 0;
458
        if (ctx->store->verify_cb) {
459
            if (ctx->store->verify_cb(ret, ctx) == 1) {
460
                ret = WOLFSSL_SUCCESS;
461
            }
462
            else {
463
                ret = -1;
464
            }
465
        }
466
    }
467
#endif
468
    return ret;
469
}
470
471
static int addAllButSelfSigned(WOLF_STACK_OF(WOLFSSL_X509)*to,
472
                               WOLF_STACK_OF(WOLFSSL_X509)*from, int *numAdded)
473
{
474
    int ret = WOLFSSL_SUCCESS;
475
    int i = 0;
476
    int cnt = 0;
477
    WOLFSSL_X509 *x = NULL;
478
479
    for (i = 0; i < wolfSSL_sk_X509_num(from); i++) {
480
        x = wolfSSL_sk_X509_value(from, i);
481
        if (wolfSSL_X509_NAME_cmp(&x->issuer, &x->subject) != 0) {
482
            if (wolfSSL_sk_X509_push(to, x) <= 0) {
483
                ret = WOLFSSL_FAILURE;
484
                goto exit;
485
            }
486
            cnt++;
487
        }
488
    }
489
490
exit:
491
    if (numAdded != NULL) {
492
        *numAdded = cnt;
493
    }
494
    return ret;
495
}
496
497
static int X509StoreRemoveCa(WOLFSSL_X509_STORE* store,
498
                                            WOLFSSL_X509* x509, int type) {
499
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
500
    byte          hash[KEYID_SIZE];
501
502
    if (store != NULL && x509 != NULL && x509->derCert != NULL) {
503
        result = GetHashId(x509->subjKeyId, (int)x509->subjKeyIdSz,
504
                    hash, HashIdAlg(x509->sigOID));
505
        if (result) {
506
            result = WOLFSSL_FATAL_ERROR;
507
        } else {
508
            result = RemoveCA(store->cm, hash, type);
509
        }
510
    }
511
512
    return result;
513
}
514
515
static int X509StoreMoveCert(WOLFSSL_STACK *certs_stack,
516
                             WOLFSSL_STACK *dest_stack,
517
                             WOLFSSL_X509 *cert) {
518
    int i;
519
520
    if (certs_stack == NULL || dest_stack == NULL || cert == NULL)
521
        return WOLFSSL_FATAL_ERROR;
522
523
    for (i = 0; i < wolfSSL_sk_X509_num(certs_stack); i++) {
524
        if (wolfSSL_sk_X509_value(certs_stack, i) == cert) {
525
            wolfSSL_sk_X509_push(dest_stack,
526
                                 (WOLFSSL_X509*)wolfSSL_sk_pop_node(certs_stack, i));
527
            return WOLFSSL_SUCCESS;
528
        }
529
    }
530
531
    return WOLFSSL_FAILURE;
532
}
533
534
535
/* Current certificate failed, but it is possible there is an
536
 * alternative cert with the same subject key which will work.
537
 * Retry until all possible candidate certs are exhausted. */
538
static int X509VerifyCertSetupRetry(WOLFSSL_X509_STORE_CTX* ctx,
539
    WOLF_STACK_OF(WOLFSSL_X509)* certs, WOLF_STACK_OF(WOLFSSL_X509)* failed,
540
    int* depth, int origDepth) {
541
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
542
543
    WOLFSSL_MSG("X509_verify_cert current cert failed, "
544
                "retrying with other certs.");
545
    ret = X509StoreRemoveCa(ctx->store, ctx->current_cert,
546
                            WOLFSSL_TEMP_CA);
547
    X509StoreMoveCert(certs, failed, ctx->current_cert);
548
    ctx->current_cert = wolfSSL_sk_X509_pop(ctx->chain);
549
    if (*depth < origDepth)
550
        *depth += 1;
551
552
    return ret;
553
}
554
555
/* Returns 1 if cur and x509 have identical DER encodings, 0 otherwise. */
556
static int X509DerEquals(WOLFSSL_X509* cur, WOLFSSL_X509* x509)
557
{
558
    if (cur == NULL || cur->derCert == NULL ||
559
        x509 == NULL || x509->derCert == NULL) {
560
        return 0;
561
    }
562
    if (cur->derCert->length != x509->derCert->length)
563
        return 0;
564
    return XMEMCMP(cur->derCert->buffer, x509->derCert->buffer,
565
                   x509->derCert->length) == 0;
566
}
567
568
/* Returns 1 if x509's DER matches an entry in either origTrustedSk (an
569
 * immutable snapshot of the caller's trusted set captured before any
570
 * intermediates were injected for this verification call) or in
571
 * store->trusted.  Returns 0 otherwise.  Used by the
572
 * X509_V_FLAG_PARTIAL_CHAIN fallback to confirm that a chain actually
573
 * terminates at a caller-trusted certificate. */
574
static int X509StoreCertIsTrusted(WOLFSSL_X509_STORE* store,
575
        WOLFSSL_X509* x509, WOLF_STACK_OF(WOLFSSL_X509)* origTrustedSk)
576
{
577
    int i;
578
    int n;
579
580
    if (x509 == NULL || x509->derCert == NULL)
581
        return 0;
582
583
    if (origTrustedSk != NULL) {
584
        n = wolfSSL_sk_X509_num(origTrustedSk);
585
        for (i = 0; i < n; i++) {
586
            if (X509DerEquals(wolfSSL_sk_X509_value(origTrustedSk, i), x509))
587
                return 1;
588
        }
589
    }
590
591
    if (store != NULL && store->trusted != NULL) {
592
        n = wolfSSL_sk_X509_num(store->trusted);
593
        for (i = 0; i < n; i++) {
594
            if (X509DerEquals(wolfSSL_sk_X509_value(store->trusted, i), x509))
595
                return 1;
596
        }
597
    }
598
599
    return 0;
600
}
601
602
/* Verifies certificate chain using WOLFSSL_X509_STORE_CTX
603
 * returns 1 on success or <= 0 on failure.
604
 */
605
int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
606
{
607
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
608
    int done = 0;
609
    int added = 0;
610
    int i = 0;
611
    int numInterAdd = 0;
612
    int numFailedCerts = 0;
613
    int depth = 0;
614
    int origDepth = 0;
615
    WOLFSSL_X509 *issuer = NULL;
616
    WOLFSSL_X509 *orig = NULL;
617
    WOLF_STACK_OF(WOLFSSL_X509)* certs = NULL;
618
    WOLF_STACK_OF(WOLFSSL_X509)* certsToUse = NULL;
619
    WOLF_STACK_OF(WOLFSSL_X509)* failedCerts = NULL;
620
    WOLF_STACK_OF(WOLFSSL_X509)* origTrustedSk = NULL;
621
    WOLFSSL_ENTER("wolfSSL_X509_verify_cert");
622
623
    if (ctx == NULL || ctx->store == NULL || ctx->store->cm == NULL
624
         || ctx->current_cert == NULL || ctx->current_cert->derCert == NULL) {
625
        return WOLFSSL_FATAL_ERROR;
626
    }
627
628
    certs = ctx->store->certs;
629
630
    if (ctx->setTrustedSk != NULL) {
631
        certs = ctx->setTrustedSk;
632
    }
633
634
    if (certs == NULL &&
635
        wolfSSL_sk_X509_num(ctx->ctxIntermediates) > 0) {
636
        certsToUse = wolfSSL_sk_X509_new_null();
637
        if (certsToUse == NULL) {
638
            ret = WOLFSSL_FAILURE;
639
            goto exit;
640
        }
641
        ret = addAllButSelfSigned(certsToUse, ctx->ctxIntermediates, NULL);
642
        /* certsToUse holds only injected intermediates, none are trusted, so
643
         * leave origTrustedSk NULL (empty snapshot). */
644
        certs = certsToUse;
645
    }
646
    else {
647
        /* Snapshot the caller-trusted entries before injecting the
648
         * caller-supplied untrusted intermediates.  Only the entries already
649
         * present count as trusted for the partial-chain check below, and
650
         * we need a stable reference because X509VerifyCertSetupRetry may
651
         * remove nodes from `certs` during chain building. */
652
        if (certs != NULL && wolfSSL_sk_X509_num(certs) > 0) {
653
            int j;
654
            int n = wolfSSL_sk_X509_num(certs);
655
            origTrustedSk = wolfSSL_sk_X509_new_null();
656
            if (origTrustedSk == NULL) {
657
                ret = WOLFSSL_FAILURE;
658
                goto exit;
659
            }
660
            for (j = 0; j < n; j++) {
661
                if (wolfSSL_sk_X509_push(origTrustedSk,
662
                        wolfSSL_sk_X509_value(certs, j)) <= 0) {
663
                    ret = WOLFSSL_FAILURE;
664
                    goto exit;
665
                }
666
            }
667
        }
668
        /* Add the intermediates provided on init to the list of untrusted
669
         * intermediates to be used */
670
        ret = addAllButSelfSigned(certs, ctx->ctxIntermediates, &numInterAdd);
671
    }
672
    if (ret != WOLFSSL_SUCCESS) {
673
        goto exit;
674
    }
675
676
    if (ctx->chain != NULL) {
677
        wolfSSL_sk_X509_free(ctx->chain);
678
    }
679
    ctx->chain = wolfSSL_sk_X509_new_null();
680
681
    failedCerts = wolfSSL_sk_X509_new_null();
682
    if (!failedCerts)
683
        goto exit;
684
685
    if (ctx->depth > 0) {
686
        depth = ctx->depth + 1;
687
    }
688
    else {
689
        depth = WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH + 1;
690
    }
691
692
    orig = ctx->current_cert;
693
    origDepth = depth;
694
    while(done == 0 && depth > 0) {
695
        issuer = NULL;
696
697
        /* Try to find an untrusted issuer first */
698
        ret = X509StoreGetIssuerEx(&issuer, certs,
699
                                               ctx->current_cert);
700
        if (ret == WOLFSSL_SUCCESS) {
701
            if (ctx->current_cert == issuer) {
702
                wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
703
                break;
704
            }
705
706
            /* We found our issuer in the non-trusted cert list, add it
707
             * to the CM and verify the current cert against it */
708
        #ifndef WOLFSSL_X509_STORE_ALLOW_NON_CA_INTERMEDIATE
709
            /* RFC 5280 4.2.1.9: reject non-CA issuer. verify_cb may
710
             * suppress the INVALID_CA error to keep building the chain,
711
             * but the leaf signature must still be verified against the
712
             * issuer below - never skip X509StoreVerifyCert. */
713
            if (!issuer->isCa) {
714
                /* error depth is current depth + 1 */
715
                SetupStoreCtxError_ex(ctx, WOLFSSL_X509_V_ERR_INVALID_CA,
716
                                (ctx->chain) ? (int)(ctx->chain->num + 1) : 1);
717
            #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
718
                if (ctx->store->verify_cb) {
719
                    ret = ctx->store->verify_cb(0, ctx);
720
                    if (ret != WOLFSSL_SUCCESS) {
721
                        ret = WOLFSSL_FAILURE;
722
                        goto exit;
723
                    }
724
                }
725
                else
726
            #endif
727
                {
728
                    ret = WOLFSSL_FAILURE;
729
                    goto exit;
730
                }
731
            }
732
        #endif
733
            ret = X509StoreAddCa(ctx->store, issuer, WOLFSSL_TEMP_CA);
734
            if (ret != WOLFSSL_SUCCESS) {
735
                X509VerifyCertSetupRetry(ctx, certs, failedCerts,
736
                    &depth, origDepth);
737
                continue;
738
            }
739
            added = 1;
740
            ret = X509StoreVerifyCert(ctx);
741
            if (ret != WOLFSSL_SUCCESS) {
742
                if ((origDepth - depth) <= 1)
743
                    added = 0;
744
                X509VerifyCertSetupRetry(ctx, certs, failedCerts,
745
                    &depth, origDepth);
746
                continue;
747
            }
748
            /* Add it to the current chain and look at the issuer cert next */
749
            wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
750
            ctx->current_cert = issuer;
751
        }
752
        else if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
753
            /* Could not find in untrusted list, only place left is
754
             * a trusted CA in the CM */
755
            ret = X509StoreVerifyCert(ctx);
756
            if (ret != WOLFSSL_SUCCESS) {
757
                /* WOLFSSL_PARTIAL_CHAIN may only terminate the chain at a
758
                 * certificate the caller actually trusts.  The previous
759
                 * "added == 1" guard merely confirmed that some untrusted
760
                 * intermediate had been temporarily loaded into the
761
                 * CertManager during chain building, which would accept
762
                 * chains that never reach a trust anchor.  Verify that
763
                 * ctx->current_cert is itself in the original trust set. */
764
                if (((ctx->flags & WOLFSSL_PARTIAL_CHAIN) ||
765
                     (ctx->store->param->flags & WOLFSSL_PARTIAL_CHAIN)) &&
766
                    X509StoreCertIsTrusted(ctx->store, ctx->current_cert,
767
                        origTrustedSk)) {
768
                    wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
769
                    /* Clear error set by the failed X509StoreVerifyCert
770
                     * attempt; the partial-chain fallback accepted the
771
                     * chain at a caller-trusted certificate. */
772
                    ctx->error = 0;
773
                    ret = WOLFSSL_SUCCESS;
774
                } else {
775
                    X509VerifyCertSetupRetry(ctx, certs, failedCerts,
776
                        &depth, origDepth);
777
                    continue;
778
                }
779
            }
780
781
            /* Cert verified, finish building the chain */
782
            wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
783
            issuer = NULL;
784
    #ifdef WOLFSSL_SIGNER_DER_CERT
785
            x509GetIssuerFromCM(&issuer, ctx->store->cm, ctx->current_cert);
786
            if (issuer != NULL && ctx->owned != NULL) {
787
                wolfSSL_sk_X509_push(ctx->owned, issuer);
788
            }
789
    #else
790
            if (ctx->setTrustedSk == NULL) {
791
                X509StoreGetIssuerEx(&issuer,
792
                    ctx->store->trusted, ctx->current_cert);
793
            }
794
            else {
795
                X509StoreGetIssuerEx(&issuer,
796
                    ctx->setTrustedSk, ctx->current_cert);
797
            }
798
    #endif
799
            if (issuer != NULL) {
800
                wolfSSL_sk_X509_push(ctx->chain, issuer);
801
            }
802
803
            done = 1;
804
        }
805
        else {
806
            goto exit;
807
        }
808
809
        depth--;
810
    }
811
812
exit:
813
    /* Copy back failed certs. */
814
    numFailedCerts = wolfSSL_sk_X509_num(failedCerts);
815
    for (i = 0; i < numFailedCerts; i++)
816
    {
817
        wolfSSL_sk_X509_push(certs, wolfSSL_sk_X509_pop(failedCerts));
818
    }
819
    wolfSSL_sk_X509_pop_free(failedCerts, NULL);
820
821
    /* Remove additional intermediates from init from the store */
822
    if (ctx != NULL && numInterAdd > 0) {
823
        for (i = 0; i < numInterAdd; i++) {
824
            wolfSSL_sk_X509_pop(ctx->store->certs);
825
        }
826
    }
827
    /* Remove intermediates that were added to CM */
828
    if (ctx != NULL) {
829
        if (ctx->store != NULL) {
830
            if (added == 1) {
831
                wolfSSL_CertManagerUnloadTempIntermediateCerts(ctx->store->cm);
832
            }
833
        }
834
        if (orig != NULL) {
835
            ctx->current_cert = orig;
836
        }
837
    }
838
    if (certsToUse != NULL) {
839
        wolfSSL_sk_X509_free(certsToUse);
840
    }
841
    if (origTrustedSk != NULL) {
842
        /* Shallow free: only the snapshot's stack nodes, not the X509s. */
843
        wolfSSL_sk_X509_free(origTrustedSk);
844
    }
845
846
    /* Enforce hostname / IP verification from X509_VERIFY_PARAM if set.
847
     * Always check against the leaf (end-entity) certificate, captured in
848
     * orig before the chain-building loop modified ctx->current_cert. */
849
    if (ctx->param != NULL) {
850
        if (ret == WOLFSSL_SUCCESS && ctx->param->hostName[0] != '\0') {
851
            if (wolfSSL_X509_check_host(orig,
852
                    ctx->param->hostName,
853
                    XSTRLEN(ctx->param->hostName),
854
                    ctx->param->hostFlags, NULL) != WOLFSSL_SUCCESS) {
855
                ctx->error = WOLFSSL_X509_V_ERR_HOSTNAME_MISMATCH;
856
                ctx->error_depth = 0;
857
                ctx->current_cert = orig;
858
                ret = WOLFSSL_FAILURE;
859
            }
860
        }
861
        if (ret == WOLFSSL_SUCCESS && ctx->param->ipasc[0] != '\0') {
862
            if (wolfSSL_X509_check_ip_asc(orig,
863
                    ctx->param->ipasc,
864
                    ctx->param->hostFlags) != WOLFSSL_SUCCESS) {
865
                ctx->error = WOLFSSL_X509_V_ERR_IP_ADDRESS_MISMATCH;
866
                ctx->error_depth = 0;
867
                ctx->current_cert = orig;
868
                ret = WOLFSSL_FAILURE;
869
            }
870
        }
871
    }
872
873
    return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
874
}
875
876
#endif /* OPENSSL_EXTRA */
877
878
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
879
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
880
                                            WOLFSSL_X509_STORE_CTX* ctx)
881
{
882
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
883
    if (ctx)
884
        return ctx->current_cert;
885
    return NULL;
886
}
887
888
/* get X509_STORE_CTX ex_data, max idx is MAX_EX_DATA */
889
void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
890
{
891
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
892
#ifdef HAVE_EX_DATA
893
    if (ctx != NULL) {
894
        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
895
    }
896
#else
897
    (void)ctx;
898
    (void)idx;
899
#endif
900
    return NULL;
901
}
902
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
903
904
905
    int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
906
0
    {
907
0
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
908
0
        if (ctx != NULL)
909
0
            return ctx->error;
910
0
        return 0;
911
0
    }
912
913
    int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
914
0
    {
915
0
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
916
0
        if (ctx)
917
0
            return ctx->error_depth;
918
0
        return WOLFSSL_FATAL_ERROR;
919
0
    }
920
921
#ifdef OPENSSL_EXTRA
922
    void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx,
923
                                  WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
924
    {
925
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_verify_cb");
926
        if(ctx == NULL)
927
            return;
928
        ctx->verify_cb = verify_cb;
929
    }
930
931
/* Gets pointer to X509_STORE that was used to create context.
932
 *
933
 * Return valid pointer on success, NULL if ctx was NULL or not initialized
934
 */
935
WOLFSSL_X509_STORE* wolfSSL_X509_STORE_CTX_get0_store(
936
        WOLFSSL_X509_STORE_CTX* ctx)
937
{
938
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_store");
939
940
    if (ctx == NULL)
941
        return NULL;
942
943
    return ctx->store;
944
}
945
946
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_cert(WOLFSSL_X509_STORE_CTX* ctx)
947
{
948
    if (ctx == NULL)
949
        return NULL;
950
951
    return ctx->current_cert;
952
}
953
954
void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX* ctx,
955
                                    unsigned long flags,
956
                                    time_t t)
957
{
958
    (void)flags;
959
960
    if (ctx == NULL || ctx->param == NULL)
961
        return;
962
963
    ctx->param->check_time = t;
964
    ctx->param->flags |= WOLFSSL_USE_CHECK_TIME;
965
}
966
967
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
968
#ifndef NO_WOLFSSL_STUB
969
int wolfSSL_X509_STORE_CTX_set_purpose(WOLFSSL_X509_STORE_CTX *ctx,
970
                                       int purpose)
971
{
972
    (void)ctx;
973
    (void)purpose;
974
    WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_set_purpose (not implemented)");
975
    return 0;
976
}
977
#endif /* !NO_WOLFSSL_STUB */
978
979
#endif /* WOLFSSL_QT || OPENSSL_ALL */
980
#endif /* OPENSSL_EXTRA */
981
982
#ifdef OPENSSL_EXTRA
983
984
void wolfSSL_X509_STORE_CTX_set_flags(WOLFSSL_X509_STORE_CTX *ctx,
985
        unsigned long flags)
986
{
987
    if ((ctx != NULL) && (flags & WOLFSSL_PARTIAL_CHAIN)){
988
        ctx->flags |= WOLFSSL_PARTIAL_CHAIN;
989
    }
990
}
991
992
/* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
993
 * on success, WOLFSSL_FAILURE on error. */
994
int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx,
995
                                       void *data)
996
{
997
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data");
998
#ifdef HAVE_EX_DATA
999
    if (ctx != NULL)
1000
    {
1001
        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
1002
    }
1003
#else
1004
    (void)ctx;
1005
    (void)idx;
1006
    (void)data;
1007
#endif
1008
    return WOLFSSL_FAILURE;
1009
}
1010
1011
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1012
/* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
1013
 * on success, WOLFSSL_FAILURE on error. */
1014
int wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup(
1015
    WOLFSSL_X509_STORE_CTX* ctx,
1016
    int idx,
1017
    void *data,
1018
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
1019
{
1020
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup");
1021
    if (ctx != NULL)
1022
    {
1023
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx,
1024
                                                        data, cleanup_routine);
1025
    }
1026
    return WOLFSSL_FAILURE;
1027
}
1028
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
1029
1030
#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL)
1031
void wolfSSL_X509_STORE_CTX_set_depth(WOLFSSL_X509_STORE_CTX* ctx, int depth)
1032
{
1033
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_depth");
1034
    if (ctx)
1035
        ctx->depth = depth;
1036
}
1037
#endif
1038
1039
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_current_issuer(
1040
        WOLFSSL_X509_STORE_CTX* ctx)
1041
{
1042
    WOLFSSL_STACK* node;
1043
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_current_issuer");
1044
1045
    if (ctx == NULL)
1046
        return NULL;
1047
1048
    /* get0 only checks currently built chain */
1049
    if (ctx->chain != NULL) {
1050
        for (node = ctx->chain; node != NULL; node = node->next) {
1051
            if (wolfSSL_X509_check_issued(node->data.x509,
1052
                                          ctx->current_cert) ==
1053
                                                WOLFSSL_X509_V_OK) {
1054
                return node->data.x509;
1055
            }
1056
        }
1057
    }
1058
1059
    return NULL;
1060
}
1061
1062
/* Set an error stat in the X509 STORE CTX
1063
 *
1064
 */
1065
void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int er)
1066
{
1067
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error");
1068
1069
    if (ctx != NULL) {
1070
        ctx->error = er;
1071
    }
1072
}
1073
1074
/* Set the error depth in the X509 STORE CTX */
1075
void wolfSSL_X509_STORE_CTX_set_error_depth(WOLFSSL_X509_STORE_CTX* ctx,
1076
                                                                    int depth)
1077
{
1078
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error_depth");
1079
1080
    if (ctx != NULL) {
1081
        ctx->error_depth = depth;
1082
    }
1083
}
1084
1085
WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx)
1086
{
1087
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_chain");
1088
1089
    if (ctx == NULL) {
1090
        return NULL;
1091
    }
1092
1093
#ifdef SESSION_CERTS
1094
    /* if chain is null but sesChain is available then populate stack */
1095
    if (ctx->chain == NULL && ctx->sesChain != NULL) {
1096
        int i;
1097
        int error = 0;
1098
        WOLFSSL_X509_CHAIN* c = ctx->sesChain;
1099
        WOLFSSL_STACK*     sk = wolfSSL_sk_new_node(ctx->heap);
1100
1101
        if (sk == NULL)
1102
            return NULL;
1103
1104
        for (i = 0; i < c->count; i++) {
1105
            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i);
1106
1107
            if (x509 == NULL) {
1108
                WOLFSSL_MSG("Unable to get x509 from chain");
1109
                error = 1;
1110
                break;
1111
            }
1112
1113
            if (wolfSSL_sk_X509_push(sk, x509) <= 0) {
1114
                WOLFSSL_MSG("Unable to load x509 into stack");
1115
                wolfSSL_X509_free(x509);
1116
                x509 = NULL;
1117
                error = 1;
1118
                break;
1119
            }
1120
        }
1121
1122
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
1123
    defined(OPENSSL_EXTRA)
1124
        /* add CA used to verify top of chain to the list */
1125
        if (!error && c->count > 0) {
1126
            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1);
1127
            WOLFSSL_X509* issuer = NULL;
1128
            if (x509 != NULL) {
1129
                if (wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, x509)
1130
                        == WOLFSSL_SUCCESS) {
1131
                    /* check that the certificate being looked up is not self
1132
                     * signed and that a issuer was found */
1133
                    if (issuer != NULL && wolfSSL_X509_NAME_cmp(&x509->issuer,
1134
                                &x509->subject) != 0) {
1135
                        if (wolfSSL_sk_X509_push(sk, issuer) <= 0) {
1136
                            WOLFSSL_MSG("Unable to load CA x509 into stack");
1137
                            error = 1;
1138
                            wolfSSL_X509_free(issuer);
1139
                            issuer = NULL;
1140
                        }
1141
                    }
1142
                    else {
1143
                        WOLFSSL_MSG("Certificate is self signed");
1144
                        wolfSSL_X509_free(issuer);
1145
                        issuer = NULL;
1146
                    }
1147
                }
1148
                else {
1149
                    WOLFSSL_MSG("Could not find CA for certificate");
1150
                }
1151
            }
1152
            wolfSSL_X509_free(x509);
1153
            x509 = NULL;
1154
        }
1155
#endif
1156
        if (error) {
1157
            wolfSSL_sk_X509_pop_free(sk, NULL);
1158
            return NULL;
1159
        }
1160
        ctx->chain = sk;
1161
    }
1162
#endif /* SESSION_CERTS */
1163
1164
    return ctx->chain;
1165
}
1166
1167
/* like X509_STORE_CTX_get_chain(), but return a copy with data reference
1168
   counts increased */
1169
WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain(WOLFSSL_X509_STORE_CTX* ctx)
1170
{
1171
    WOLFSSL_STACK* ref;
1172
1173
    if (ctx == NULL) {
1174
        return NULL;
1175
    }
1176
1177
    /* get chain in ctx */
1178
    ref = wolfSSL_X509_STORE_CTX_get_chain(ctx);
1179
    if (ref == NULL) {
1180
        return ref;
1181
    }
1182
1183
    /* create duplicate of ctx chain */
1184
    return wolfSSL_sk_dup(ref);
1185
}
1186
1187
#ifndef NO_WOLFSSL_STUB
1188
WOLFSSL_X509_STORE_CTX *wolfSSL_X509_STORE_CTX_get0_parent_ctx(
1189
                                                   WOLFSSL_X509_STORE_CTX *ctx)
1190
{
1191
    (void)ctx;
1192
    WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_get0_parent_ctx");
1193
    return NULL;
1194
}
1195
1196
int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
1197
                            WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
1198
{
1199
    (void)ctx;
1200
    (void)idx;
1201
    (void)name;
1202
    (void)obj;
1203
    WOLFSSL_STUB("X509_STORE_get_by_subject");
1204
    return 0;
1205
}
1206
#endif
1207
1208
WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_CTX_get0_param(
1209
        WOLFSSL_X509_STORE_CTX *ctx)
1210
{
1211
    if (ctx == NULL)
1212
        return NULL;
1213
1214
    return ctx->param;
1215
}
1216
1217
#endif /* OPENSSL_EXTRA */
1218
1219
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
1220
#if defined(WOLFSSL_SIGNER_DER_CERT)
1221
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(
1222
    WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name)
1223
{
1224
    WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
1225
    int err = 0;
1226
    WOLFSSL_X509_STORE* store = NULL;
1227
    WOLFSSL_STACK* sk = NULL;
1228
    WOLFSSL_STACK* certToFilter = NULL;
1229
    WOLFSSL_X509_NAME* certToFilterName = NULL;
1230
    WOLF_STACK_OF(WOLFSSL_X509)* filteredCerts = NULL;
1231
    WOLFSSL_X509* filteredCert = NULL;
1232
1233
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
1234
1235
    if (name == NULL) {
1236
        err = 1;
1237
    }
1238
1239
    if (err == 0) {
1240
        store = wolfSSL_X509_STORE_CTX_get0_store(ctx);
1241
        if (store == NULL) {
1242
            err = 1;
1243
        }
1244
    }
1245
1246
    if (err == 0) {
1247
        filteredCerts = wolfSSL_sk_X509_new_null();
1248
        if (filteredCerts == NULL) {
1249
            err = 1;
1250
        }
1251
    }
1252
1253
    if (err == 0) {
1254
        sk = wolfSSL_CertManagerGetCerts(store->cm);
1255
        if (sk == NULL) {
1256
            err = 1;
1257
        }
1258
    }
1259
1260
    if (err == 0) {
1261
        certToFilter = sk;
1262
        while (certToFilter != NULL) {
1263
            certToFilterName = wolfSSL_X509_get_subject_name(
1264
                                    certToFilter->data.x509);
1265
            if (certToFilterName != NULL) {
1266
                if (wolfSSL_X509_NAME_cmp(certToFilterName, name) == 0) {
1267
                    filteredCert = wolfSSL_X509_dup(certToFilter->data.x509);
1268
                    if (filteredCert == NULL ||
1269
                            wolfSSL_sk_X509_push(filteredCerts, filteredCert)
1270
                                <= 0) {
1271
                        err = 1;
1272
                        wolfSSL_X509_free(filteredCert);
1273
                        filteredCert = NULL;
1274
                        break;
1275
                    }
1276
                }
1277
            }
1278
            certToFilter = certToFilter->next;
1279
        }
1280
    }
1281
1282
    if (err == 1) {
1283
        if (filteredCerts != NULL) {
1284
            wolfSSL_sk_X509_pop_free(filteredCerts, NULL);
1285
        }
1286
        ret = NULL;
1287
    }
1288
    else {
1289
        ret = filteredCerts;
1290
    }
1291
1292
    if (sk != NULL) {
1293
        wolfSSL_sk_X509_pop_free(sk, NULL);
1294
    }
1295
1296
    return ret;
1297
}
1298
#endif /* WOLFSSL_SIGNER_DER_CERT */
1299
1300
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
1301
1302
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
1303
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
1304
int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
1305
    WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
1306
{
1307
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1308
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get1_issuer");
1309
1310
    if (issuer == NULL || ctx == NULL || x == NULL)
1311
        return WOLFSSL_FATAL_ERROR;
1312
1313
    ret = X509StoreGetIssuerEx(issuer, ctx->store->certs, x);
1314
    if ((ret == WOLFSSL_SUCCESS) && (*issuer != NULL)) {
1315
        return wolfSSL_X509_up_ref(*issuer);
1316
    }
1317
1318
#ifdef WOLFSSL_SIGNER_DER_CERT
1319
    ret = x509GetIssuerFromCM(issuer, ctx->store->cm, x);
1320
#else
1321
    ret = X509StoreGetIssuerEx(issuer, ctx->store->trusted, x);
1322
    if ((ret == WOLFSSL_SUCCESS) && (*issuer != NULL)) {
1323
        return wolfSSL_X509_up_ref(*issuer);
1324
    }
1325
#endif
1326
1327
    return ret;
1328
}
1329
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
1330
1331
#ifdef OPENSSL_EXTRA
1332
1333
static int X509StoreGetIssuerEx(WOLFSSL_X509 **issuer,
1334
                            WOLFSSL_STACK * certs, WOLFSSL_X509 *x)
1335
{
1336
    int i;
1337
1338
    if (issuer == NULL || x == NULL)
1339
        return WOLFSSL_FATAL_ERROR;
1340
1341
    if (certs != NULL) {
1342
        for (i = 0; i < wolfSSL_sk_X509_num(certs); i++) {
1343
            if (wolfSSL_X509_check_issued(
1344
                    wolfSSL_sk_X509_value(certs, i), x) ==
1345
                    WOLFSSL_X509_V_OK) {
1346
                *issuer = wolfSSL_sk_X509_value(certs, i);
1347
                return WOLFSSL_SUCCESS;
1348
            }
1349
        }
1350
    }
1351
1352
    return WOLFSSL_FAILURE;
1353
}
1354
1355
#endif
1356
1357
/******************************************************************************
1358
 * END OF X509_STORE_CTX APIs
1359
 *****************************************************************************/
1360
1361
/******************************************************************************
1362
 * START OF X509_STORE APIs
1363
 *****************************************************************************/
1364
1365
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
1366
    defined(WOLFSSL_WPAS_SMALL)
1367
WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
1368
{
1369
    int ret;
1370
    WOLFSSL_X509_STORE* store = NULL;
1371
    WOLFSSL_ENTER("wolfSSL_X509_STORE_new");
1372
1373
    if ((store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
1374
                                    DYNAMIC_TYPE_X509_STORE)) == NULL)
1375
        goto err_exit;
1376
1377
    XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE));
1378
    store->isDynamic = 1;
1379
1380
    wolfSSL_RefInit(&store->ref, &ret);
1381
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
1382
    if (ret != 0)
1383
        goto err_exit;
1384
#else
1385
    (void)ret;
1386
#endif
1387
1388
    if ((store->cm = wolfSSL_CertManagerNew()) == NULL)
1389
        goto err_exit;
1390
1391
#ifdef OPENSSL_EXTRA
1392
    if ((store->certs = wolfSSL_sk_X509_new_null()) == NULL)
1393
        goto err_exit;
1394
1395
    if ((store->owned = wolfSSL_sk_X509_new_null()) == NULL)
1396
        goto err_exit;
1397
1398
    if ((store->trusted = wolfSSL_sk_X509_new_null()) == NULL)
1399
        goto err_exit;
1400
#endif
1401
1402
#ifdef HAVE_CRL
1403
    store->crl = store->cm->crl;
1404
#endif
1405
1406
    store->numAdded = 0;
1407
1408
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1409
1410
    /* Link store's new Certificate Manager to self by default */
1411
    store->cm->x509_store_p = store;
1412
1413
    if ((store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
1414
                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
1415
                           NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
1416
        goto err_exit;
1417
    }
1418
    XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
1419
    if ((store->lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR),
1420
                           NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
1421
        WOLFSSL_MSG("store->lookup.dir memory allocation error");
1422
        goto err_exit;
1423
    }
1424
    XMEMSET(store->lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR));
1425
    if (wc_InitMutex(&store->lookup.dirs->lock) != 0) {
1426
            WOLFSSL_MSG("Bad mutex init");
1427
            goto err_exit;
1428
    }
1429
#endif
1430
1431
    return store;
1432
1433
err_exit:
1434
    if (store == NULL)
1435
        return NULL;
1436
1437
    wolfSSL_X509_STORE_free(store);
1438
1439
    return NULL;
1440
}
1441
1442
#ifdef OPENSSL_ALL
1443
static void X509StoreFreeObjList(WOLFSSL_X509_STORE* store,
1444
                  WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* objs)
1445
{
1446
    int i;
1447
    WOLFSSL_X509_OBJECT *obj = NULL;
1448
    int cnt = store->numAdded;
1449
1450
    /* -1 here because it is later used as an index value into the object stack.
1451
     * With there being the chance that the only object in the stack is one from
1452
     * the numAdded to the store >= is used when comparing to 0. */
1453
    i = wolfSSL_sk_X509_OBJECT_num(objs) - 1;
1454
    while (cnt > 0 && i >= 0) {
1455
        /* The inner X509 is owned by somebody else, NULL out the reference */
1456
        obj = (WOLFSSL_X509_OBJECT *)wolfSSL_sk_X509_OBJECT_value(objs, i);
1457
        if (obj != NULL) {
1458
            obj->type = (WOLFSSL_X509_LOOKUP_TYPE)0;
1459
            obj->data.ptr = NULL;
1460
        }
1461
        cnt--;
1462
        i--;
1463
    }
1464
1465
    wolfSSL_sk_X509_OBJECT_pop_free(objs, NULL);
1466
}
1467
#endif
1468
1469
void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
1470
{
1471
    int doFree = 0;
1472
    if (store != NULL && store->isDynamic) {
1473
        int ret;
1474
        wolfSSL_RefDec(&store->ref, &doFree, &ret);
1475
    #ifdef WOLFSSL_REFCNT_ERROR_RETURN
1476
        if (ret != 0) {
1477
            WOLFSSL_MSG("Couldn't lock store mutex");
1478
        }
1479
    #else
1480
        (void)ret;
1481
    #endif
1482
1483
        if (doFree) {
1484
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1485
            wolfSSL_CRYPTO_cleanup_ex_data(&store->ex_data);
1486
#endif
1487
            if (store->cm != NULL) {
1488
                wolfSSL_CertManagerFree(store->cm);
1489
                store->cm = NULL;
1490
            }
1491
#if defined(OPENSSL_EXTRA)
1492
            if (store->certs != NULL) {
1493
                wolfSSL_sk_X509_pop_free(store->certs, NULL);
1494
                store->certs = NULL;
1495
            }
1496
            if (store->owned != NULL) {
1497
                wolfSSL_sk_X509_pop_free(store->owned, NULL);
1498
                store->owned = NULL;
1499
            }
1500
            if (store->trusted != NULL) {
1501
                wolfSSL_sk_X509_pop_free(store->trusted, NULL);
1502
                store->trusted = NULL;
1503
            }
1504
#endif
1505
#ifdef OPENSSL_ALL
1506
            if (store->objs != NULL) {
1507
                X509StoreFreeObjList(store, store->objs);
1508
            }
1509
#endif
1510
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1511
            XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL);
1512
            store->param = NULL;
1513
1514
            if (store->lookup.dirs != NULL) {
1515
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1516
                if (store->lookup.dirs->dir_entry) {
1517
                    wolfSSL_sk_BY_DIR_entry_free(
1518
                        store->lookup.dirs->dir_entry);
1519
                }
1520
#endif
1521
                wc_FreeMutex(&store->lookup.dirs->lock);
1522
                XFREE(store->lookup.dirs, NULL, DYNAMIC_TYPE_OPENSSL);
1523
                store->lookup.dirs = NULL;
1524
            }
1525
#endif
1526
            wolfSSL_RefFree(&store->ref);
1527
            XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
1528
        }
1529
    }
1530
}
1531
1532
/**
1533
 * Get ex_data in WOLFSSL_STORE at given index
1534
 * @param store a pointer to WOLFSSL_X509_STORE structure
1535
 * @param idx   Index of ex_data to get data from
1536
 * @return void pointer to ex_data on success or NULL on failure
1537
 */
1538
void* wolfSSL_X509_STORE_get_ex_data(WOLFSSL_X509_STORE* store, int idx)
1539
{
1540
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get_ex_data");
1541
#ifdef HAVE_EX_DATA
1542
    if (store != NULL && idx < MAX_EX_DATA && idx >= 0) {
1543
        return wolfSSL_CRYPTO_get_ex_data(&store->ex_data, idx);
1544
    }
1545
#else
1546
    (void)store;
1547
    (void)idx;
1548
#endif
1549
    return NULL;
1550
}
1551
1552
int wolfSSL_X509_STORE_up_ref(WOLFSSL_X509_STORE* store)
1553
{
1554
    if (store) {
1555
        int ret;
1556
        wolfSSL_RefInc(&store->ref, &ret);
1557
    #ifdef WOLFSSL_REFCNT_ERROR_RETURN
1558
        if (ret != 0) {
1559
            WOLFSSL_MSG("Failed to lock store mutex");
1560
            return WOLFSSL_FAILURE;
1561
        }
1562
    #else
1563
        (void)ret;
1564
    #endif
1565
1566
        return WOLFSSL_SUCCESS;
1567
    }
1568
1569
    return WOLFSSL_FAILURE;
1570
}
1571
1572
/**
1573
 * Set ex_data for WOLFSSL_STORE
1574
 * @param store a pointer to WOLFSSL_X509_STORE structure
1575
 * @param idx   Index of ex data to set
1576
 * @param data  Data to set in ex data
1577
 * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
1578
 */
1579
int wolfSSL_X509_STORE_set_ex_data(WOLFSSL_X509_STORE* store, int idx,
1580
                                                                void *data)
1581
{
1582
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data");
1583
#ifdef HAVE_EX_DATA
1584
    if (store != NULL && idx < MAX_EX_DATA) {
1585
        return wolfSSL_CRYPTO_set_ex_data(&store->ex_data, idx, data);
1586
    }
1587
#else
1588
    (void)store;
1589
    (void)idx;
1590
    (void)data;
1591
#endif
1592
    return WOLFSSL_FAILURE;
1593
}
1594
1595
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1596
/**
1597
 * Set ex_data for WOLFSSL_STORE
1598
 * @param store a pointer to WOLFSSL_X509_STORE structure
1599
 * @param idx   Index of ex data to set
1600
 * @param data  Data to set in ex data
1601
 * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
1602
 */
1603
int wolfSSL_X509_STORE_set_ex_data_with_cleanup(
1604
    WOLFSSL_X509_STORE* store,
1605
    int idx,
1606
    void *data,
1607
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
1608
{
1609
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data_with_cleanup");
1610
    if (store != NULL && idx < MAX_EX_DATA) {
1611
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&store->ex_data, idx,
1612
                                                       data, cleanup_routine);
1613
    }
1614
    return WOLFSSL_FAILURE;
1615
}
1616
1617
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
1618
1619
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER || WOLFSSL_WPAS_SMALL */
1620
1621
#ifdef OPENSSL_EXTRA
1622
1623
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
1624
void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st,
1625
        WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
1626
{
1627
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_verify_cb");
1628
    if (st != NULL) {
1629
        st->verify_cb = verify_cb;
1630
    }
1631
}
1632
1633
void wolfSSL_X509_STORE_set_get_crl(WOLFSSL_X509_STORE *st,
1634
        WOLFSSL_X509_STORE_CTX_get_crl_cb get_cb)
1635
{
1636
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_get_crl");
1637
    if (st != NULL) {
1638
        st->get_crl_cb = get_cb;
1639
    }
1640
}
1641
1642
#ifndef NO_WOLFSSL_STUB
1643
void wolfSSL_X509_STORE_set_check_crl(WOLFSSL_X509_STORE *st,
1644
        WOLFSSL_X509_STORE_CTX_check_crl_cb check_crl)
1645
{
1646
    (void)st;
1647
    (void)check_crl;
1648
    WOLFSSL_STUB("wolfSSL_X509_STORE_set_check_crl (not implemented)");
1649
}
1650
#endif
1651
#endif /* WOLFSSL_QT || OPENSSL_ALL */
1652
1653
WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
1654
                                               WOLFSSL_X509_LOOKUP_METHOD* m)
1655
{
1656
    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_lookup");
1657
    if (store == NULL || m == NULL)
1658
        return NULL;
1659
1660
    /* Make sure the lookup has a back reference to the store. */
1661
    store->lookup.store = store;
1662
    /* store a type to know which method wants to be used for */
1663
    store->lookup.type = m->type;
1664
    return &store->lookup;
1665
}
1666
1667
static int X509StoreAddCa(WOLFSSL_X509_STORE* store,
1668
                                          WOLFSSL_X509* x509, int type)
1669
{
1670
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1671
    DerBuffer* derCert = NULL;
1672
    int verify = VERIFY;
1673
1674
    WOLFSSL_ENTER("X509StoreAddCa");
1675
    if (store != NULL && x509 != NULL && x509->derCert != NULL) {
1676
        /* Check if NO_CHECK_TIME flag is set - if so, skip date validation */
1677
        if (store->param != NULL &&
1678
            (store->param->flags & WOLFSSL_NO_CHECK_TIME) != 0) {
1679
            verify = VERIFY_SKIP_DATE;
1680
        }
1681
        result = AllocDer(&derCert, x509->derCert->length,
1682
            x509->derCert->type, NULL);
1683
        if (result == 0) {
1684
            /* AddCA() frees the buffer. */
1685
            XMEMCPY(derCert->buffer,
1686
                            x509->derCert->buffer, x509->derCert->length);
1687
            result = AddCA(store->cm, &derCert, type, verify);
1688
        }
1689
    }
1690
1691
    return result;
1692
}
1693
1694
/* Push certificates from the store's X509 stacks (certs and trusted) into the
1695
 * CertManager, then free and NULL the stacks to signal that this store is now
1696
 * owned by an SSL_CTX.
1697
 *
1698
 * This is needed when an X509_STORE is attached to an SSL_CTX via
1699
 * SSL_CTX_set_cert_store: self-signed CAs are already in the CM (added by
1700
 * X509StoreAddCa during X509_STORE_add_cert), but non-self-signed intermediates
1701
 * are only in store->certs and must be explicitly added to the CM so that all
1702
 * verification paths (including CertManagerVerify) can find them. */
1703
WOLFSSL_LOCAL int X509StorePushCertsToCM(WOLFSSL_X509_STORE* store)
1704
{
1705
    int i;
1706
    int num;
1707
    int ret;
1708
    int anyFail = 0;
1709
    WOLFSSL_X509* x509;
1710
1711
    WOLFSSL_ENTER("X509StorePushCertsToCM");
1712
1713
    if (store == NULL || store->cm == NULL)
1714
        return WOLFSSL_SUCCESS;
1715
1716
    /* Push non-self-signed intermediates from store->certs into the CM. */
1717
    if (store->certs != NULL) {
1718
        num = wolfSSL_sk_X509_num(store->certs);
1719
        for (i = 0; i < num; i++) {
1720
            x509 = wolfSSL_sk_X509_value(store->certs, i);
1721
            if (x509 != NULL) {
1722
                ret = X509StoreAddCa(store, x509, WOLFSSL_USER_CA);
1723
                if (ret != WOLFSSL_SUCCESS) {
1724
                    WOLFSSL_MSG("X509StorePushCertsToCM: failed to add cert");
1725
                    anyFail = 1;
1726
                }
1727
            }
1728
        }
1729
        /* Free and NULL to mark store as CTX-owned. Future add_cert calls
1730
         * will go directly to the CertManager. */
1731
        wolfSSL_sk_X509_pop_free(store->certs, NULL);
1732
        store->certs = NULL;
1733
    }
1734
1735
    /* Push trusted certs too. Self-signed CAs are typically already in the CM
1736
     * (added during X509_STORE_add_cert), but AddCA handles duplicates. */
1737
    if (store->trusted != NULL) {
1738
        num = wolfSSL_sk_X509_num(store->trusted);
1739
        for (i = 0; i < num; i++) {
1740
            x509 = wolfSSL_sk_X509_value(store->trusted, i);
1741
            if (x509 != NULL) {
1742
                ret = X509StoreAddCa(store, x509, WOLFSSL_USER_CA);
1743
                if (ret != WOLFSSL_SUCCESS) {
1744
                    WOLFSSL_MSG("X509StorePushCertsToCM: failed to add "
1745
                                "trusted cert");
1746
                    anyFail = 1;
1747
                }
1748
            }
1749
        }
1750
        wolfSSL_sk_X509_pop_free(store->trusted, NULL);
1751
        store->trusted = NULL;
1752
    }
1753
1754
    if (anyFail) {
1755
        return WOLFSSL_FATAL_ERROR;
1756
    }
1757
    return WOLFSSL_SUCCESS;
1758
}
1759
1760
int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
1761
{
1762
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1763
1764
    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
1765
    if (store != NULL && store->cm != NULL && x509 != NULL
1766
                                                && x509->derCert != NULL) {
1767
        /* Mimic the openssl behavior, must be self signed to be considered
1768
         * trusted, addCA() internals will do additional checks for
1769
         * CA=TRUE */
1770
        if (wolfSSL_X509_NAME_cmp(&x509->issuer, &x509->subject) == 0) {
1771
            result = X509StoreAddCa(store, x509, WOLFSSL_USER_CA);
1772
            if (result == WOLFSSL_SUCCESS && store->trusted != NULL) {
1773
                result = wolfSSL_X509_up_ref(x509);
1774
                if (result == WOLFSSL_SUCCESS) {
1775
                    result = wolfSSL_sk_X509_push(store->trusted, x509);
1776
                    if (result > 0) {
1777
                        result = WOLFSSL_SUCCESS;
1778
                    }
1779
                    else {
1780
                        result = WOLFSSL_FATAL_ERROR;
1781
                        wolfSSL_X509_free(x509);
1782
                        x509 = NULL;
1783
                    }
1784
                }
1785
            }
1786
        }
1787
        else {
1788
            if (store->certs != NULL) {
1789
                result = wolfSSL_X509_up_ref(x509);
1790
                if (result == WOLFSSL_SUCCESS) {
1791
                    result = wolfSSL_sk_X509_push(store->certs, x509);
1792
                    if (result > 0) {
1793
                        result = WOLFSSL_SUCCESS;
1794
                    }
1795
                    else {
1796
                        result = WOLFSSL_FATAL_ERROR;
1797
                        wolfSSL_X509_free(x509);
1798
                        x509 = NULL;
1799
                    }
1800
                }
1801
            }
1802
            else {
1803
                /* If store->certs is NULL, this is an X509_STORE managed by an
1804
                 * SSL_CTX, preserve behavior and always add as USER_CA */
1805
                result = X509StoreAddCa(
1806
                            store, x509, WOLFSSL_USER_CA);
1807
            }
1808
        }
1809
    }
1810
1811
    WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
1812
1813
    if (result != WOLFSSL_SUCCESS) {
1814
        result = WOLFSSL_FATAL_ERROR;
1815
    }
1816
1817
    return result;
1818
}
1819
1820
int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
1821
{
1822
    int ret = WOLFSSL_SUCCESS;
1823
1824
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags");
1825
1826
    if (store == NULL)
1827
        return WOLFSSL_FAILURE;
1828
1829
    if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
1830
        ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
1831
    }
1832
#if defined(OPENSSL_COMPATIBLE_DEFAULTS)
1833
    else if (flag == 0) {
1834
        ret = wolfSSL_CertManagerDisableCRL(store->cm);
1835
    }
1836
#endif
1837
    if (flag & WOLFSSL_PARTIAL_CHAIN) {
1838
        store->param->flags |= WOLFSSL_PARTIAL_CHAIN;
1839
    }
1840
    return ret;
1841
}
1842
1843
int X509StoreLoadCertBuffer(WOLFSSL_X509_STORE *str,
1844
                                        byte *buf, word32 bufLen, int type)
1845
{
1846
    int ret = WOLFSSL_SUCCESS;
1847
    WOLFSSL_X509 *x509 = NULL;
1848
1849
    if (str == NULL || buf == NULL) {
1850
        return WOLFSSL_FAILURE;
1851
    }
1852
1853
    /* OpenSSL X509_STORE_load_file fails on DER file, we will as well */
1854
    x509 = wolfSSL_X509_load_certificate_buffer(buf, bufLen, type);
1855
    if (x509 != NULL) {
1856
        ret = wolfSSL_X509_STORE_add_cert(str, x509);
1857
        if (ret != WOLFSSL_SUCCESS) {
1858
            WOLFSSL_MSG("Failed to load file");
1859
            ret = WOLFSSL_FAILURE;
1860
        }
1861
        if (ret == WOLFSSL_SUCCESS && str->owned != NULL) {
1862
            if (wolfSSL_sk_X509_push(str->owned, x509) <= 0) {
1863
                ret = WOLFSSL_FAILURE;
1864
            }
1865
            else {
1866
                x509 = NULL;
1867
            }
1868
        }
1869
        wolfSSL_X509_free(x509);
1870
        x509 = NULL;
1871
    }
1872
    else {
1873
        ret = WOLFSSL_FAILURE;
1874
    }
1875
1876
    return ret;
1877
}
1878
1879
#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1880
1881
static int X509StoreReadFile(const char *fname,
1882
                StaticBuffer *content, word32 *bytesRead, int *type)
1883
{
1884
    int ret = -1;
1885
    long sz = 0;
1886
#ifdef HAVE_CRL
1887
    const char* header = NULL;
1888
    const char* footer = NULL;
1889
#endif
1890
1891
    ret = wolfssl_read_file_static(fname, content, NULL, DYNAMIC_TYPE_FILE,
1892
        &sz);
1893
    if (ret == 0) {
1894
        *type = CERT_TYPE;
1895
        *bytesRead = (word32)sz;
1896
#ifdef HAVE_CRL
1897
        /* Look for CRL header and footer. */
1898
        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
1899
                (XSTRNSTR((char*)content->buffer, header, sz) !=
1900
                    NULL)) {
1901
            *type = CRL_TYPE;
1902
        }
1903
#endif
1904
    }
1905
1906
    return (ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
1907
}
1908
1909
static int X509StoreLoadFile(WOLFSSL_X509_STORE *str,
1910
                                        const char *fname)
1911
{
1912
    int ret = WOLFSSL_SUCCESS;
1913
    int type = 0;
1914
#ifndef WOLFSSL_SMALL_STACK
1915
    byte   stackBuffer[FILE_BUFFER_SIZE];
1916
#endif
1917
    StaticBuffer content;
1918
    word32 contentLen = 0;
1919
1920
#ifdef WOLFSSL_SMALL_STACK
1921
    static_buffer_init(&content);
1922
#else
1923
    static_buffer_init(&content, stackBuffer, FILE_BUFFER_SIZE);
1924
#endif
1925
1926
    WOLFSSL_MSG_EX("X509StoreLoadFile: Loading file: %s", fname);
1927
1928
    ret = X509StoreReadFile(fname, &content, &contentLen, &type);
1929
    if (ret != WOLFSSL_SUCCESS) {
1930
        WOLFSSL_MSG("Failed to load file");
1931
        ret = WOLFSSL_FAILURE;
1932
    }
1933
1934
    if ((ret == WOLFSSL_SUCCESS) && (type == CERT_TYPE)) {
1935
        ret = X509StoreLoadCertBuffer(str, content.buffer,
1936
                                        contentLen, WOLFSSL_FILETYPE_PEM);
1937
    }
1938
#ifdef HAVE_CRL
1939
    else if ((ret == WOLFSSL_SUCCESS) && (type == CRL_TYPE)) {
1940
        ret = BufferLoadCRL(str->cm->crl, content.buffer, contentLen,
1941
                                        WOLFSSL_FILETYPE_PEM, 0);
1942
    }
1943
#endif
1944
1945
    static_buffer_free(&content, NULL, DYNAMIC_TYPE_FILE);
1946
    return ret;
1947
}
1948
1949
/* Loads certificate(s) files in pem format into X509_STORE struct from either
1950
 * a file or directory.
1951
 * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE if an error occurs.
1952
 */
1953
int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
1954
                                            const char *file, const char *dir)
1955
{
1956
    WOLFSSL_CTX* ctx;
1957
    char *name = NULL;
1958
    int ret = WOLFSSL_SUCCESS;
1959
    WC_DECLARE_VAR(readCtx, ReadDirCtx, 1, 0);
1960
1961
    WOLFSSL_ENTER("wolfSSL_X509_STORE_load_locations");
1962
1963
    if (str == NULL || str->cm == NULL || (file == NULL  && dir == NULL))
1964
        return WOLFSSL_FAILURE;
1965
1966
    /* tmp ctx for setting our cert manager */
1967
    ctx = wolfSSL_CTX_new_ex(cm_pick_method(str->cm->heap), str->cm->heap);
1968
    if (ctx == NULL)
1969
        return WOLFSSL_FAILURE;
1970
1971
    wolfSSL_CertManagerFree(ctx->cm);
1972
    ctx->cm = str->cm;
1973
1974
#ifdef HAVE_CRL
1975
    if (str->cm->crl == NULL) {
1976
        /* Workaround to allocate the internals to load CRL's but don't enable
1977
         * CRL checking by default */
1978
        if (wolfSSL_CertManagerEnableCRL(str->cm, WOLFSSL_CRL_CHECK)
1979
                != WOLFSSL_SUCCESS ||
1980
                wolfSSL_CertManagerDisableCRL(str->cm) != WOLFSSL_SUCCESS) {
1981
            WOLFSSL_MSG("Enable CRL failed");
1982
            wolfSSL_CTX_free(ctx);
1983
            return WOLFSSL_FAILURE;
1984
        }
1985
    }
1986
#endif
1987
1988
    /* Load individual file */
1989
    if (file) {
1990
        ret = X509StoreLoadFile(str, file);
1991
        if (ret != WOLFSSL_SUCCESS) {
1992
            WOLFSSL_MSG("Failed to load file");
1993
            ret = WOLFSSL_FAILURE;
1994
        }
1995
    }
1996
1997
    /* Load files in dir */
1998
    if (dir && ret == WOLFSSL_SUCCESS) {
1999
        int successes = 0;
2000
2001
        #ifdef WOLFSSL_SMALL_STACK
2002
            readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
2003
                                                    DYNAMIC_TYPE_TMP_BUFFER);
2004
            if (readCtx == NULL) {
2005
                WOLFSSL_MSG("Memory error");
2006
                wolfSSL_CTX_free(ctx);
2007
                return WOLFSSL_FAILURE;
2008
            }
2009
        #endif
2010
2011
        /* try to load each regular file in dir */
2012
        ret = wc_ReadDirFirst(readCtx, dir, &name);
2013
        while (ret == 0 && name) {
2014
            WOLFSSL_MSG(name);
2015
2016
            ret = X509StoreLoadFile(str, name);
2017
            /* Not failing on load errors */
2018
            if (ret != WOLFSSL_SUCCESS)
2019
                WOLFSSL_MSG("Failed to load file in path, continuing");
2020
            else
2021
                successes++;
2022
2023
            ret = wc_ReadDirNext(readCtx, dir, &name);
2024
        }
2025
        wc_ReadDirClose(readCtx);
2026
2027
        /* Success if at least one file in dir was loaded */
2028
        if (successes > 0)
2029
            ret = WOLFSSL_SUCCESS;
2030
        else {
2031
            WOLFSSL_ERROR(ret);
2032
            ret = WOLFSSL_FAILURE;
2033
        }
2034
2035
            WC_FREE_VAR_EX(readCtx, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
2036
    }
2037
2038
    ctx->cm = NULL;
2039
    wolfSSL_CTX_free(ctx);
2040
2041
    return ret;
2042
}
2043
2044
#if defined(XGETENV) && !defined(NO_GETENV)
2045
int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE *str)
2046
{
2047
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
2048
    char* certDir = NULL;
2049
    char* certFile = NULL;
2050
2051
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_default_paths");
2052
2053
    certFile = wc_strdup_ex(XGETENV("SSL_CERT_FILE"), DYNAMIC_TYPE_TMP_BUFFER);
2054
    certDir = wc_strdup_ex(XGETENV("SSL_CERT_DIR"), DYNAMIC_TYPE_TMP_BUFFER);
2055
2056
    ret = wolfSSL_X509_STORE_load_locations(str, certFile, certDir);
2057
2058
    XFREE(certFile, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2059
    XFREE(certDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2060
    return ret;
2061
}
2062
#endif /* XGETENV && !NO_GETENV */
2063
2064
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
2065
2066
int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store)
2067
{
2068
    int cnt_ret = 0;
2069
    Signer **table;
2070
2071
    WOLFSSL_ENTER("wolfSSL_X509_CA_num");
2072
    if (store == NULL || store->cm == NULL){
2073
        WOLFSSL_MSG("invalid parameter");
2074
        return WOLFSSL_FAILURE;
2075
    }
2076
2077
    table = store->cm->caTable;
2078
    if (table || (store->certs != NULL)){
2079
        if (wc_LockMutex(&store->cm->caLock) == 0){
2080
            if (table) {
2081
                int i = 0;
2082
                for (i = 0; i < CA_TABLE_SIZE; i++) {
2083
                    Signer* signer = table[i];
2084
                    while (signer) {
2085
                        Signer* next = signer->next;
2086
                        cnt_ret++;
2087
                        signer = next;
2088
                    }
2089
                }
2090
            }
2091
2092
            if (store->certs != NULL) {
2093
                cnt_ret += wolfSSL_sk_X509_num(store->certs);
2094
            }
2095
            wc_UnLockMutex(&store->cm->caLock);
2096
        }
2097
    }
2098
2099
    return cnt_ret;
2100
}
2101
2102
/******************************************************************************
2103
* wolfSSL_X509_STORE_GetCerts - retrieve stack of X509 in a certificate
2104
*                               store ctx
2105
*
2106
* This API can be used in SSL verify callback function to view cert chain
2107
* See examples/client/client.c and myVerify() function in test.h
2108
*
2109
* RETURNS:
2110
* returns stack of X509 certs on success, otherwise returns a NULL.
2111
*/
2112
WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s)
2113
{
2114
    int  certIdx = 0;
2115
    WOLFSSL_BUFFER_INFO* cert = NULL;
2116
    DecodedCert* dCert = NULL;
2117
    WOLFSSL_X509* x509 = NULL;
2118
    WOLFSSL_STACK* sk = NULL;
2119
    int found = 0;
2120
2121
    if (s == NULL) {
2122
        return NULL;
2123
    }
2124
2125
    sk = wolfSSL_sk_X509_new_null();
2126
2127
    if (sk == NULL) {
2128
        return NULL;
2129
    }
2130
2131
    for (certIdx = s->totalCerts - 1; certIdx >= 0; certIdx--) {
2132
        /* get certificate buffer */
2133
        cert = &s->certs[certIdx];
2134
2135
        dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
2136
                                                DYNAMIC_TYPE_DCERT);
2137
2138
        if (dCert == NULL) {
2139
            goto error;
2140
        }
2141
        XMEMSET(dCert, 0, sizeof(DecodedCert));
2142
2143
        InitDecodedCert(dCert, cert->buffer, cert->length, NULL);
2144
2145
        /* Parse Certificate */
2146
        if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL)){
2147
            goto error;
2148
        }
2149
        x509 = wolfSSL_X509_new();
2150
2151
        if (x509 == NULL) {
2152
            goto error;
2153
        }
2154
        InitX509(x509, 1, NULL);
2155
2156
        if (CopyDecodedToX509(x509, dCert) == 0) {
2157
2158
            if (wolfSSL_sk_X509_push(sk, x509) <= 0) {
2159
                WOLFSSL_MSG("Unable to load x509 into stack");
2160
                wolfSSL_X509_free(x509);
2161
                x509 = NULL;
2162
                goto error;
2163
            }
2164
        }
2165
        else {
2166
            goto error;
2167
        }
2168
        found = 1;
2169
2170
        FreeDecodedCert(dCert);
2171
        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
2172
        dCert = NULL;
2173
    }
2174
2175
    if (!found) {
2176
        wolfSSL_sk_X509_pop_free(sk, NULL);
2177
        sk = NULL;
2178
    }
2179
    return sk;
2180
2181
error:
2182
    if (dCert) {
2183
        FreeDecodedCert(dCert);
2184
        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
2185
    }
2186
2187
    if (sk)
2188
        wolfSSL_sk_X509_pop_free(sk, NULL);
2189
2190
    return NULL;
2191
}
2192
#endif /* OPENSSL_EXTRA */
2193
2194
#ifdef OPENSSL_ALL
2195
WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
2196
    WOLFSSL_X509_STORE* store)
2197
{
2198
    WOLFSSL_STACK* ret = NULL;
2199
    WOLFSSL_STACK* cert_stack = NULL;
2200
#if ((defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)) || \
2201
     (defined(HAVE_CRL)))
2202
    WOLFSSL_X509_OBJECT* obj = NULL;
2203
#endif
2204
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
2205
    WOLFSSL_X509* x509 = NULL;
2206
    int i = 0;
2207
#endif
2208
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects");
2209
2210
    if (store == NULL || store->cm == NULL) {
2211
        WOLFSSL_MSG("Missing or empty store");
2212
        return NULL;
2213
    }
2214
2215
    if (store->objs != NULL) {
2216
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
2217
        /* want to update objs stack by cm stack again before returning it*/
2218
        X509StoreFreeObjList(store, store->objs);
2219
        store->objs = NULL;
2220
#else
2221
        if (wolfSSL_sk_X509_OBJECT_num(store->objs) == 0) {
2222
            /* Let's try generating the stack again */
2223
            wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL);
2224
            store->objs = NULL;
2225
        }
2226
        else
2227
            return store->objs;
2228
#endif
2229
    }
2230
2231
    if ((ret = wolfSSL_sk_X509_OBJECT_new()) == NULL) {
2232
        WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error");
2233
        goto err_cleanup;
2234
    }
2235
2236
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
2237
    cert_stack = wolfSSL_CertManagerGetCerts(store->cm);
2238
    store->numAdded = 0;
2239
    if (cert_stack == NULL && wolfSSL_sk_X509_num(store->certs) > 0) {
2240
        cert_stack = wolfSSL_sk_X509_new_null();
2241
        if (cert_stack == NULL) {
2242
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error");
2243
            goto err_cleanup;
2244
        }
2245
    }
2246
    for (i = 0; i < wolfSSL_sk_X509_num(store->certs); i++) {
2247
        if (wolfSSL_sk_X509_push(cert_stack,
2248
                             wolfSSL_sk_X509_value(store->certs, i)) > 0) {
2249
            store->numAdded++;
2250
        }
2251
    }
2252
    /* Do not modify stack until after we guarantee success to
2253
     * simplify cleanup logic handling cert merging above */
2254
    for (i = 0; i < wolfSSL_sk_X509_num(cert_stack); i++) {
2255
        x509 = (WOLFSSL_X509 *)wolfSSL_sk_value(cert_stack, i);
2256
        obj  = wolfSSL_X509_OBJECT_new();
2257
        if (obj == NULL) {
2258
            WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
2259
            goto err_cleanup;
2260
        }
2261
        if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) {
2262
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
2263
            wolfSSL_X509_OBJECT_free(obj);
2264
            goto err_cleanup;
2265
        }
2266
        obj->type = WOLFSSL_X509_LU_X509;
2267
        obj->data.x509 = x509;
2268
    }
2269
2270
    while (wolfSSL_sk_X509_num(cert_stack) > 0) {
2271
        wolfSSL_sk_X509_pop(cert_stack);
2272
    }
2273
#endif
2274
2275
#ifdef HAVE_CRL
2276
    if (store->cm->crl != NULL) {
2277
        int res;
2278
        obj = wolfSSL_X509_OBJECT_new();
2279
        if (obj == NULL) {
2280
            WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
2281
            goto err_cleanup;
2282
        }
2283
        if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) {
2284
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
2285
            wolfSSL_X509_OBJECT_free(obj);
2286
            goto err_cleanup;
2287
        }
2288
        obj->type = WOLFSSL_X509_LU_CRL;
2289
        wolfSSL_RefInc(&store->cm->crl->ref, &res);
2290
        if (res != 0) {
2291
            WOLFSSL_MSG("Failed to lock crl mutex");
2292
            goto err_cleanup;
2293
        }
2294
        obj->data.crl = store->cm->crl;
2295
    }
2296
#endif
2297
2298
    if (cert_stack)
2299
        wolfSSL_sk_X509_pop_free(cert_stack, NULL);
2300
    store->objs = ret;
2301
    return ret;
2302
err_cleanup:
2303
    if (ret != NULL)
2304
        X509StoreFreeObjList(store, ret);
2305
    if (cert_stack != NULL) {
2306
        while (store->numAdded > 0) {
2307
            wolfSSL_sk_X509_pop(cert_stack);
2308
            store->numAdded--;
2309
        }
2310
        wolfSSL_sk_X509_pop_free(cert_stack, NULL);
2311
    }
2312
    return NULL;
2313
}
2314
#endif /* OPENSSL_ALL */
2315
2316
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
2317
    defined(WOLFSSL_WPAS_SMALL)
2318
WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_get0_param(
2319
        const WOLFSSL_X509_STORE *ctx)
2320
{
2321
    if (ctx == NULL)
2322
        return NULL;
2323
    return ctx->param;
2324
}
2325
2326
#ifdef OPENSSL_EXTRA
2327
int wolfSSL_X509_STORE_set1_param(WOLFSSL_X509_STORE *ctx,
2328
        WOLFSSL_X509_VERIFY_PARAM *param)
2329
{
2330
    if (ctx == NULL)
2331
        return WOLFSSL_FAILURE;
2332
    return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, param);
2333
}
2334
#endif
2335
#endif
2336
2337
/******************************************************************************
2338
 * END OF X509_STORE APIs
2339
 *****************************************************************************/
2340
2341
#endif /* NO_CERTS */
2342
2343
#endif /* !WOLFCRYPT_ONLY */
2344
2345
#endif /* !WOLFSSL_X509_STORE_INCLUDED */