Coverage Report

Created: 2026-04-01 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-fastmath/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
    wolfSSL_X509_STORE_CTX_set_error(ctx, error);
322
    wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
323
}
324
325
static void SetupStoreCtxError(WOLFSSL_X509_STORE_CTX* ctx, int ret)
326
{
327
    int depth = 0;
328
329
    /* Set error depth */
330
    if (ctx->chain)
331
        depth = (int)ctx->chain->num;
332
333
    SetupStoreCtxError_ex(ctx, ret, depth);
334
}
335
336
#ifndef NO_ASN_TIME
337
/* Post certificate validation date handling. This function is called after the
338
 * certificate has been verified by the certificate manager. It then checks if
339
 * X509 store parameters are set for date validation override.
340
 * @param ctx The certificate store context
341
 * @param ret The return value from the certificate manager verify
342
 * @return The return value for the certificate date validation after override
343
 */
344
static int X509StoreVerifyCertDate(WOLFSSL_X509_STORE_CTX* ctx, int ret)
345
{
346
    byte *afterDate  = ctx->current_cert->notAfter.data;
347
    byte *beforeDate = ctx->current_cert->notBefore.data;
348
349
    /* Only override existing date errors or WOLFSSL_SUCCESS. */
350
    if (ret == WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) ||
351
            ret == WC_NO_ERR_TRACE(ASN_AFTER_DATE_E) ||
352
            ret == WC_NO_ERR_TRACE(WOLFSSL_SUCCESS)) {
353
#ifdef USE_WOLF_VALIDDATE
354
        WOLFSSL_X509_VERIFY_PARAM* param = NULL;
355
356
        /* If no external XVALIDATE_DATE was defined then use param for date
357
           validation overrides. */
358
        if (ctx->param != NULL) {
359
            param = ctx->param;
360
        }
361
        else if (ctx->store != NULL && ctx->store->param != NULL) {
362
            param = ctx->store->param;
363
        }
364
365
        if (param != NULL) {
366
            if ((param->flags & WOLFSSL_NO_CHECK_TIME) != 0) {
367
                WOLFSSL_MSG("Overriding date validation WOLFSSL_NO_CHECK_TIME");
368
                ret = WOLFSSL_SUCCESS;
369
            }
370
            else if ((param->flags & WOLFSSL_USE_CHECK_TIME) != 0 &&
371
                (param->check_time != 0)) {
372
                time_t checkTime = param->check_time;
373
                ret = WOLFSSL_SUCCESS; /* override date error and use custom set
374
                                        time for validating certificate dates */
375
                WOLFSSL_MSG("Override date validation, WOLFSSL_USE_CHECK_TIME");
376
                if (wc_ValidateDateWithTime(afterDate,
377
                    (byte)ctx->current_cert->notAfter.type, ASN_AFTER,
378
                    checkTime, ctx->current_cert->notAfter.length) < 1) {
379
                    ret = ASN_AFTER_DATE_E;
380
                }
381
                else if (wc_ValidateDateWithTime(beforeDate,
382
                    (byte)ctx->current_cert->notBefore.type, ASN_BEFORE,
383
                    checkTime, ctx->current_cert->notBefore.length) < 1) {
384
                    ret = ASN_BEFORE_DATE_E;
385
                }
386
            }
387
        #if defined(OPENSSL_ALL)
388
            else {
389
                WOLFSSL_MSG("Using system time for date validation");
390
                /* use system time for date validation */
391
                if (wc_ValidateDate(afterDate,
392
                        (byte)ctx->current_cert->notAfter.type, ASN_AFTER,
393
                        ctx->current_cert->notAfter.length) < 1) {
394
                    ret = ASN_AFTER_DATE_E;
395
                }
396
                else if (wc_ValidateDate(beforeDate,
397
                        (byte)ctx->current_cert->notBefore.type, ASN_BEFORE,
398
                        ctx->current_cert->notBefore.length) < 1) {
399
                    ret = ASN_BEFORE_DATE_E;
400
                }
401
            }
402
        #endif
403
        }
404
#else
405
        if (XVALIDATE_DATE(afterDate,
406
                (byte)ctx->current_cert->notAfter.type, ASN_AFTER,
407
                ctx->current_cert->notAfter.length) < 1) {
408
            ret = ASN_AFTER_DATE_E;
409
        }
410
        else if (XVALIDATE_DATE(beforeDate,
411
                (byte)ctx->current_cert->notBefore.type, ASN_BEFORE,
412
                ctx->current_cert->notBefore.length) < 1) {
413
            ret = ASN_BEFORE_DATE_E;
414
        }
415
#endif /* USE_WOLF_VALIDDATE */
416
    }
417
418
    return ret;
419
}
420
#endif /* NO_ASN_TIME */
421
422
static int X509StoreVerifyCert(WOLFSSL_X509_STORE_CTX* ctx)
423
{
424
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
425
    WOLFSSL_ENTER("X509StoreVerifyCert");
426
427
    if (ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
428
        ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
429
                    ctx->current_cert->derCert->buffer,
430
                    ctx->current_cert->derCert->length,
431
                    WOLFSSL_FILETYPE_ASN1);
432
    #ifndef NO_ASN_TIME
433
        /* update return value with any date validation overrides */
434
        ret = X509StoreVerifyCertDate(ctx, ret);
435
    #endif
436
        SetupStoreCtxError(ctx, ret);
437
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
438
        if (ctx->store->verify_cb)
439
            ret = ctx->store->verify_cb(ret >= 0 ? 1 : 0, ctx) == 1 ?
440
                                                        WOLFSSL_SUCCESS : ret;
441
    #endif
442
    }
443
#if !defined(NO_ASN_TIME) && defined(OPENSSL_ALL)
444
    if (ret != WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) &&
445
        ret != WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) {
446
        /* With OpenSSL, we need to check the certificate's date
447
        * after certificate manager verification,
448
        * as it skips date validation when other errors are present.
449
        */
450
        ret = X509StoreVerifyCertDate(ctx, ret);
451
        SetupStoreCtxError(ctx, ret);
452
        ret = ret == WOLFSSL_SUCCESS ? 1 : 0;
453
        if (ctx->store->verify_cb) {
454
            if (ctx->store->verify_cb(ret, ctx) == 1) {
455
                ret = WOLFSSL_SUCCESS;
456
            }
457
            else {
458
                ret = -1;
459
            }
460
        }
461
    }
462
#endif
463
    return ret;
464
}
465
466
static int addAllButSelfSigned(WOLF_STACK_OF(WOLFSSL_X509)*to,
467
                               WOLF_STACK_OF(WOLFSSL_X509)*from, int *numAdded)
468
{
469
    int ret = WOLFSSL_SUCCESS;
470
    int i = 0;
471
    int cnt = 0;
472
    WOLFSSL_X509 *x = NULL;
473
474
    for (i = 0; i < wolfSSL_sk_X509_num(from); i++) {
475
        x = wolfSSL_sk_X509_value(from, i);
476
        if (wolfSSL_X509_NAME_cmp(&x->issuer, &x->subject) != 0) {
477
            if (wolfSSL_sk_X509_push(to, x) <= 0) {
478
                ret = WOLFSSL_FAILURE;
479
                goto exit;
480
            }
481
            cnt++;
482
        }
483
    }
484
485
exit:
486
    if (numAdded != NULL) {
487
        *numAdded = cnt;
488
    }
489
    return ret;
490
}
491
492
static int X509StoreRemoveCa(WOLFSSL_X509_STORE* store,
493
                                            WOLFSSL_X509* x509, int type) {
494
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
495
    byte          hash[KEYID_SIZE];
496
497
    if (store != NULL && x509 != NULL && x509->derCert != NULL) {
498
        result = GetHashId(x509->subjKeyId, (int)x509->subjKeyIdSz,
499
                    hash, HashIdAlg(x509->sigOID));
500
        if (result) {
501
            result = WOLFSSL_FATAL_ERROR;
502
        } else {
503
            result = RemoveCA(store->cm, hash, type);
504
        }
505
    }
506
507
    return result;
508
}
509
510
static int X509StoreMoveCert(WOLFSSL_STACK *certs_stack,
511
                             WOLFSSL_STACK *dest_stack,
512
                             WOLFSSL_X509 *cert) {
513
    int i;
514
515
    if (certs_stack == NULL || dest_stack == NULL || cert == NULL)
516
        return WOLFSSL_FATAL_ERROR;
517
518
    for (i = 0; i < wolfSSL_sk_X509_num(certs_stack); i++) {
519
        if (wolfSSL_sk_X509_value(certs_stack, i) == cert) {
520
            wolfSSL_sk_X509_push(dest_stack,
521
                                 (WOLFSSL_X509*)wolfSSL_sk_pop_node(certs_stack, i));
522
            return WOLFSSL_SUCCESS;
523
        }
524
    }
525
526
    return WOLFSSL_FAILURE;
527
}
528
529
530
/* Current certificate failed, but it is possible there is an
531
 * alternative cert with the same subject key which will work.
532
 * Retry until all possible candidate certs are exhausted. */
533
static int X509VerifyCertSetupRetry(WOLFSSL_X509_STORE_CTX* ctx,
534
    WOLF_STACK_OF(WOLFSSL_X509)* certs, WOLF_STACK_OF(WOLFSSL_X509)* failed,
535
    int* depth, int origDepth) {
536
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
537
538
    WOLFSSL_MSG("X509_verify_cert current cert failed, "
539
                "retrying with other certs.");
540
    ret = X509StoreRemoveCa(ctx->store, ctx->current_cert,
541
                            WOLFSSL_TEMP_CA);
542
    X509StoreMoveCert(certs, failed, ctx->current_cert);
543
    ctx->current_cert = wolfSSL_sk_X509_pop(ctx->chain);
544
    if (*depth < origDepth)
545
        *depth += 1;
546
547
    return ret;
548
}
549
550
/* Verifies certificate chain using WOLFSSL_X509_STORE_CTX
551
 * returns 1 on success or <= 0 on failure.
552
 */
553
int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
554
{
555
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
556
    int done = 0;
557
    int added = 0;
558
    int i = 0;
559
    int numInterAdd = 0;
560
    int numFailedCerts = 0;
561
    int depth = 0;
562
    int origDepth = 0;
563
    WOLFSSL_X509 *issuer = NULL;
564
    WOLFSSL_X509 *orig = NULL;
565
    WOLF_STACK_OF(WOLFSSL_X509)* certs = NULL;
566
    WOLF_STACK_OF(WOLFSSL_X509)* certsToUse = NULL;
567
    WOLF_STACK_OF(WOLFSSL_X509)* failedCerts = NULL;
568
    WOLFSSL_ENTER("wolfSSL_X509_verify_cert");
569
570
    if (ctx == NULL || ctx->store == NULL || ctx->store->cm == NULL
571
         || ctx->current_cert == NULL || ctx->current_cert->derCert == NULL) {
572
        return WOLFSSL_FATAL_ERROR;
573
    }
574
575
    certs = ctx->store->certs;
576
577
    if (ctx->setTrustedSk != NULL) {
578
        certs = ctx->setTrustedSk;
579
    }
580
581
    if (certs == NULL &&
582
        wolfSSL_sk_X509_num(ctx->ctxIntermediates) > 0) {
583
        certsToUse = wolfSSL_sk_X509_new_null();
584
        ret = addAllButSelfSigned(certsToUse, ctx->ctxIntermediates, NULL);
585
    }
586
    else {
587
        /* Add the intermediates provided on init to the list of untrusted
588
         * intermediates to be used */
589
        ret = addAllButSelfSigned(certs, ctx->ctxIntermediates, &numInterAdd);
590
    }
591
    if (ret != WOLFSSL_SUCCESS) {
592
        goto exit;
593
    }
594
595
    if (ctx->chain != NULL) {
596
        wolfSSL_sk_X509_free(ctx->chain);
597
    }
598
    ctx->chain = wolfSSL_sk_X509_new_null();
599
600
    failedCerts = wolfSSL_sk_X509_new_null();
601
    if (!failedCerts)
602
        goto exit;
603
604
    if (ctx->depth > 0) {
605
        depth = ctx->depth + 1;
606
    }
607
    else {
608
        depth = WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH + 1;
609
    }
610
611
    orig = ctx->current_cert;
612
    origDepth = depth;
613
    while(done == 0 && depth > 0) {
614
        issuer = NULL;
615
616
        /* Try to find an untrusted issuer first */
617
        ret = X509StoreGetIssuerEx(&issuer, certs,
618
                                               ctx->current_cert);
619
        if (ret == WOLFSSL_SUCCESS) {
620
            if (ctx->current_cert == issuer) {
621
                wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
622
                break;
623
            }
624
625
            /* We found our issuer in the non-trusted cert list, add it
626
             * to the CM and verify the current cert against it */
627
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
628
            /* OpenSSL doesn't allow the cert as CA if it is not CA:TRUE for
629
             * intermediate certs.
630
             */
631
            if (!issuer->isCa) {
632
                /* error depth is current depth + 1 */
633
                SetupStoreCtxError_ex(ctx, X509_V_ERR_INVALID_CA,
634
                                (ctx->chain) ? (int)(ctx->chain->num + 1) : 1);
635
                if (ctx->store->verify_cb) {
636
                    ret = ctx->store->verify_cb(0, ctx);
637
                    if (ret != WOLFSSL_SUCCESS) {
638
                        goto exit;
639
                    }
640
                }
641
            } else
642
        #endif
643
            {
644
                ret = X509StoreAddCa(ctx->store, issuer,
645
                                                WOLFSSL_TEMP_CA);
646
                if (ret != WOLFSSL_SUCCESS) {
647
                    X509VerifyCertSetupRetry(ctx, certs, failedCerts,
648
                        &depth, origDepth);
649
                    continue;
650
                }
651
                added = 1;
652
                ret = X509StoreVerifyCert(ctx);
653
                if (ret != WOLFSSL_SUCCESS) {
654
                    if ((origDepth - depth) <= 1)
655
                        added = 0;
656
                    X509VerifyCertSetupRetry(ctx, certs, failedCerts,
657
                        &depth, origDepth);
658
                    continue;
659
                }
660
                /* Add it to the current chain and look at the issuer cert next */
661
                wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
662
            }
663
            ctx->current_cert = issuer;
664
        }
665
        else if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
666
            /* Could not find in untrusted list, only place left is
667
             * a trusted CA in the CM */
668
            ret = X509StoreVerifyCert(ctx);
669
            if (ret != WOLFSSL_SUCCESS) {
670
                if (((ctx->flags & WOLFSSL_PARTIAL_CHAIN) ||
671
                     (ctx->store->param->flags & WOLFSSL_PARTIAL_CHAIN)) &&
672
                    (added == 1)) {
673
                    wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
674
                    ret = WOLFSSL_SUCCESS;
675
                } else {
676
                    X509VerifyCertSetupRetry(ctx, certs, failedCerts,
677
                        &depth, origDepth);
678
                    continue;
679
                }
680
            }
681
682
            /* Cert verified, finish building the chain */
683
            wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
684
            issuer = NULL;
685
    #ifdef WOLFSSL_SIGNER_DER_CERT
686
            x509GetIssuerFromCM(&issuer, ctx->store->cm, ctx->current_cert);
687
            if (issuer != NULL && ctx->owned != NULL) {
688
                wolfSSL_sk_X509_push(ctx->owned, issuer);
689
            }
690
    #else
691
            if (ctx->setTrustedSk == NULL) {
692
                X509StoreGetIssuerEx(&issuer,
693
                    ctx->store->trusted, ctx->current_cert);
694
            }
695
            else {
696
                X509StoreGetIssuerEx(&issuer,
697
                    ctx->setTrustedSk, ctx->current_cert);
698
            }
699
    #endif
700
            if (issuer != NULL) {
701
                wolfSSL_sk_X509_push(ctx->chain, issuer);
702
            }
703
704
            done = 1;
705
        }
706
        else {
707
            goto exit;
708
        }
709
710
        depth--;
711
    }
712
713
exit:
714
    /* Copy back failed certs. */
715
    numFailedCerts = wolfSSL_sk_X509_num(failedCerts);
716
    for (i = 0; i < numFailedCerts; i++)
717
    {
718
        wolfSSL_sk_X509_push(certs, wolfSSL_sk_X509_pop(failedCerts));
719
    }
720
    wolfSSL_sk_X509_pop_free(failedCerts, NULL);
721
722
    /* Remove additional intermediates from init from the store */
723
    if (ctx != NULL && numInterAdd > 0) {
724
        for (i = 0; i < numInterAdd; i++) {
725
            wolfSSL_sk_X509_pop(ctx->store->certs);
726
        }
727
    }
728
    /* Remove intermediates that were added to CM */
729
    if (ctx != NULL) {
730
        if (ctx->store != NULL) {
731
            if (added == 1) {
732
                wolfSSL_CertManagerUnloadTempIntermediateCerts(ctx->store->cm);
733
            }
734
        }
735
        if (orig != NULL) {
736
            ctx->current_cert = orig;
737
        }
738
    }
739
    if (certsToUse != NULL) {
740
        wolfSSL_sk_X509_free(certsToUse);
741
    }
742
743
    /* Enforce hostname / IP verification from X509_VERIFY_PARAM if set.
744
     * Always check against the leaf (end-entity) certificate, captured in
745
     * orig before the chain-building loop modified ctx->current_cert. */
746
    if (ctx->param != NULL) {
747
        if (ret == WOLFSSL_SUCCESS && ctx->param->hostName[0] != '\0') {
748
            if (wolfSSL_X509_check_host(orig,
749
                    ctx->param->hostName,
750
                    XSTRLEN(ctx->param->hostName),
751
                    ctx->param->hostFlags, NULL) != WOLFSSL_SUCCESS) {
752
                ctx->error = WOLFSSL_X509_V_ERR_HOSTNAME_MISMATCH;
753
                ctx->error_depth = 0;
754
                ctx->current_cert = orig;
755
                ret = WOLFSSL_FAILURE;
756
            }
757
        }
758
        if (ret == WOLFSSL_SUCCESS && ctx->param->ipasc[0] != '\0') {
759
            if (wolfSSL_X509_check_ip_asc(orig,
760
                    ctx->param->ipasc,
761
                    ctx->param->hostFlags) != WOLFSSL_SUCCESS) {
762
                ctx->error = WOLFSSL_X509_V_ERR_IP_ADDRESS_MISMATCH;
763
                ctx->error_depth = 0;
764
                ctx->current_cert = orig;
765
                ret = WOLFSSL_FAILURE;
766
            }
767
        }
768
    }
769
770
    return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
771
}
772
773
#endif /* OPENSSL_EXTRA */
774
775
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
776
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
777
                                            WOLFSSL_X509_STORE_CTX* ctx)
778
{
779
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
780
    if (ctx)
781
        return ctx->current_cert;
782
    return NULL;
783
}
784
785
/* get X509_STORE_CTX ex_data, max idx is MAX_EX_DATA */
786
void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
787
{
788
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
789
#ifdef HAVE_EX_DATA
790
    if (ctx != NULL) {
791
        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
792
    }
793
#else
794
    (void)ctx;
795
    (void)idx;
796
#endif
797
    return NULL;
798
}
799
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
800
801
802
    int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
803
0
    {
804
0
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
805
0
        if (ctx != NULL)
806
0
            return ctx->error;
807
0
        return 0;
808
0
    }
809
810
    int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
811
0
    {
812
0
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
813
0
        if (ctx)
814
0
            return ctx->error_depth;
815
0
        return WOLFSSL_FATAL_ERROR;
816
0
    }
817
818
#ifdef OPENSSL_EXTRA
819
    void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx,
820
                                  WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
821
    {
822
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_verify_cb");
823
        if(ctx == NULL)
824
            return;
825
        ctx->verify_cb = verify_cb;
826
    }
827
828
/* Gets pointer to X509_STORE that was used to create context.
829
 *
830
 * Return valid pointer on success, NULL if ctx was NULL or not initialized
831
 */
832
WOLFSSL_X509_STORE* wolfSSL_X509_STORE_CTX_get0_store(
833
        WOLFSSL_X509_STORE_CTX* ctx)
834
{
835
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_store");
836
837
    if (ctx == NULL)
838
        return NULL;
839
840
    return ctx->store;
841
}
842
843
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_cert(WOLFSSL_X509_STORE_CTX* ctx)
844
{
845
    if (ctx == NULL)
846
        return NULL;
847
848
    return ctx->current_cert;
849
}
850
851
void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX* ctx,
852
                                    unsigned long flags,
853
                                    time_t t)
854
{
855
    (void)flags;
856
857
    if (ctx == NULL || ctx->param == NULL)
858
        return;
859
860
    ctx->param->check_time = t;
861
    ctx->param->flags |= WOLFSSL_USE_CHECK_TIME;
862
}
863
864
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
865
#ifndef NO_WOLFSSL_STUB
866
int wolfSSL_X509_STORE_CTX_set_purpose(WOLFSSL_X509_STORE_CTX *ctx,
867
                                       int purpose)
868
{
869
    (void)ctx;
870
    (void)purpose;
871
    WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_set_purpose (not implemented)");
872
    return 0;
873
}
874
#endif /* !NO_WOLFSSL_STUB */
875
876
#endif /* WOLFSSL_QT || OPENSSL_ALL */
877
#endif /* OPENSSL_EXTRA */
878
879
#ifdef OPENSSL_EXTRA
880
881
void wolfSSL_X509_STORE_CTX_set_flags(WOLFSSL_X509_STORE_CTX *ctx,
882
        unsigned long flags)
883
{
884
    if ((ctx != NULL) && (flags & WOLFSSL_PARTIAL_CHAIN)){
885
        ctx->flags |= WOLFSSL_PARTIAL_CHAIN;
886
    }
887
}
888
889
/* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
890
 * on success, WOLFSSL_FAILURE on error. */
891
int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx,
892
                                       void *data)
893
{
894
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data");
895
#ifdef HAVE_EX_DATA
896
    if (ctx != NULL)
897
    {
898
        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
899
    }
900
#else
901
    (void)ctx;
902
    (void)idx;
903
    (void)data;
904
#endif
905
    return WOLFSSL_FAILURE;
906
}
907
908
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
909
/* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
910
 * on success, WOLFSSL_FAILURE on error. */
911
int wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup(
912
    WOLFSSL_X509_STORE_CTX* ctx,
913
    int idx,
914
    void *data,
915
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
916
{
917
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup");
918
    if (ctx != NULL)
919
    {
920
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx,
921
                                                        data, cleanup_routine);
922
    }
923
    return WOLFSSL_FAILURE;
924
}
925
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
926
927
#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL)
928
void wolfSSL_X509_STORE_CTX_set_depth(WOLFSSL_X509_STORE_CTX* ctx, int depth)
929
{
930
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_depth");
931
    if (ctx)
932
        ctx->depth = depth;
933
}
934
#endif
935
936
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_current_issuer(
937
        WOLFSSL_X509_STORE_CTX* ctx)
938
{
939
    WOLFSSL_STACK* node;
940
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_current_issuer");
941
942
    if (ctx == NULL)
943
        return NULL;
944
945
    /* get0 only checks currently built chain */
946
    if (ctx->chain != NULL) {
947
        for (node = ctx->chain; node != NULL; node = node->next) {
948
            if (wolfSSL_X509_check_issued(node->data.x509,
949
                                          ctx->current_cert) ==
950
                                                WOLFSSL_X509_V_OK) {
951
                return node->data.x509;
952
            }
953
        }
954
    }
955
956
    return NULL;
957
}
958
959
/* Set an error stat in the X509 STORE CTX
960
 *
961
 */
962
void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int er)
963
{
964
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error");
965
966
    if (ctx != NULL) {
967
        ctx->error = er;
968
    }
969
}
970
971
/* Set the error depth in the X509 STORE CTX */
972
void wolfSSL_X509_STORE_CTX_set_error_depth(WOLFSSL_X509_STORE_CTX* ctx,
973
                                                                    int depth)
974
{
975
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error_depth");
976
977
    if (ctx != NULL) {
978
        ctx->error_depth = depth;
979
    }
980
}
981
982
WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx)
983
{
984
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_chain");
985
986
    if (ctx == NULL) {
987
        return NULL;
988
    }
989
990
#ifdef SESSION_CERTS
991
    /* if chain is null but sesChain is available then populate stack */
992
    if (ctx->chain == NULL && ctx->sesChain != NULL) {
993
        int i;
994
        int error = 0;
995
        WOLFSSL_X509_CHAIN* c = ctx->sesChain;
996
        WOLFSSL_STACK*     sk = wolfSSL_sk_new_node(ctx->heap);
997
998
        if (sk == NULL)
999
            return NULL;
1000
1001
        for (i = 0; i < c->count; i++) {
1002
            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i);
1003
1004
            if (x509 == NULL) {
1005
                WOLFSSL_MSG("Unable to get x509 from chain");
1006
                error = 1;
1007
                break;
1008
            }
1009
1010
            if (wolfSSL_sk_X509_push(sk, x509) <= 0) {
1011
                WOLFSSL_MSG("Unable to load x509 into stack");
1012
                wolfSSL_X509_free(x509);
1013
                x509 = NULL;
1014
                error = 1;
1015
                break;
1016
            }
1017
        }
1018
1019
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
1020
    defined(OPENSSL_EXTRA)
1021
        /* add CA used to verify top of chain to the list */
1022
        if (!error && c->count > 0) {
1023
            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1);
1024
            WOLFSSL_X509* issuer = NULL;
1025
            if (x509 != NULL) {
1026
                if (wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, x509)
1027
                        == WOLFSSL_SUCCESS) {
1028
                    /* check that the certificate being looked up is not self
1029
                     * signed and that a issuer was found */
1030
                    if (issuer != NULL && wolfSSL_X509_NAME_cmp(&x509->issuer,
1031
                                &x509->subject) != 0) {
1032
                        if (wolfSSL_sk_X509_push(sk, issuer) <= 0) {
1033
                            WOLFSSL_MSG("Unable to load CA x509 into stack");
1034
                            error = 1;
1035
                            wolfSSL_X509_free(issuer);
1036
                            issuer = NULL;
1037
                        }
1038
                    }
1039
                    else {
1040
                        WOLFSSL_MSG("Certificate is self signed");
1041
                        wolfSSL_X509_free(issuer);
1042
                        issuer = NULL;
1043
                    }
1044
                }
1045
                else {
1046
                    WOLFSSL_MSG("Could not find CA for certificate");
1047
                }
1048
            }
1049
            wolfSSL_X509_free(x509);
1050
            x509 = NULL;
1051
        }
1052
#endif
1053
        if (error) {
1054
            wolfSSL_sk_X509_pop_free(sk, NULL);
1055
            return NULL;
1056
        }
1057
        ctx->chain = sk;
1058
    }
1059
#endif /* SESSION_CERTS */
1060
1061
    return ctx->chain;
1062
}
1063
1064
/* like X509_STORE_CTX_get_chain(), but return a copy with data reference
1065
   counts increased */
1066
WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain(WOLFSSL_X509_STORE_CTX* ctx)
1067
{
1068
    WOLFSSL_STACK* ref;
1069
1070
    if (ctx == NULL) {
1071
        return NULL;
1072
    }
1073
1074
    /* get chain in ctx */
1075
    ref = wolfSSL_X509_STORE_CTX_get_chain(ctx);
1076
    if (ref == NULL) {
1077
        return ref;
1078
    }
1079
1080
    /* create duplicate of ctx chain */
1081
    return wolfSSL_sk_dup(ref);
1082
}
1083
1084
#ifndef NO_WOLFSSL_STUB
1085
WOLFSSL_X509_STORE_CTX *wolfSSL_X509_STORE_CTX_get0_parent_ctx(
1086
                                                   WOLFSSL_X509_STORE_CTX *ctx)
1087
{
1088
    (void)ctx;
1089
    WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_get0_parent_ctx");
1090
    return NULL;
1091
}
1092
1093
int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
1094
                            WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
1095
{
1096
    (void)ctx;
1097
    (void)idx;
1098
    (void)name;
1099
    (void)obj;
1100
    WOLFSSL_STUB("X509_STORE_get_by_subject");
1101
    return 0;
1102
}
1103
#endif
1104
1105
WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_CTX_get0_param(
1106
        WOLFSSL_X509_STORE_CTX *ctx)
1107
{
1108
    if (ctx == NULL)
1109
        return NULL;
1110
1111
    return ctx->param;
1112
}
1113
1114
#endif /* OPENSSL_EXTRA */
1115
1116
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
1117
#if defined(WOLFSSL_SIGNER_DER_CERT)
1118
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(
1119
    WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name)
1120
{
1121
    WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
1122
    int err = 0;
1123
    WOLFSSL_X509_STORE* store = NULL;
1124
    WOLFSSL_STACK* sk = NULL;
1125
    WOLFSSL_STACK* certToFilter = NULL;
1126
    WOLFSSL_X509_NAME* certToFilterName = NULL;
1127
    WOLF_STACK_OF(WOLFSSL_X509)* filteredCerts = NULL;
1128
    WOLFSSL_X509* filteredCert = NULL;
1129
1130
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
1131
1132
    if (name == NULL) {
1133
        err = 1;
1134
    }
1135
1136
    if (err == 0) {
1137
        store = wolfSSL_X509_STORE_CTX_get0_store(ctx);
1138
        if (store == NULL) {
1139
            err = 1;
1140
        }
1141
    }
1142
1143
    if (err == 0) {
1144
        filteredCerts = wolfSSL_sk_X509_new_null();
1145
        if (filteredCerts == NULL) {
1146
            err = 1;
1147
        }
1148
    }
1149
1150
    if (err == 0) {
1151
        sk = wolfSSL_CertManagerGetCerts(store->cm);
1152
        if (sk == NULL) {
1153
            err = 1;
1154
        }
1155
    }
1156
1157
    if (err == 0) {
1158
        certToFilter = sk;
1159
        while (certToFilter != NULL) {
1160
            certToFilterName = wolfSSL_X509_get_subject_name(
1161
                                    certToFilter->data.x509);
1162
            if (certToFilterName != NULL) {
1163
                if (wolfSSL_X509_NAME_cmp(certToFilterName, name) == 0) {
1164
                    filteredCert = wolfSSL_X509_dup(certToFilter->data.x509);
1165
                    if (filteredCert == NULL ||
1166
                            wolfSSL_sk_X509_push(filteredCerts, filteredCert)
1167
                                <= 0) {
1168
                        err = 1;
1169
                        wolfSSL_X509_free(filteredCert);
1170
                        filteredCert = NULL;
1171
                        break;
1172
                    }
1173
                }
1174
            }
1175
            certToFilter = certToFilter->next;
1176
        }
1177
    }
1178
1179
    if (err == 1) {
1180
        if (filteredCerts != NULL) {
1181
            wolfSSL_sk_X509_pop_free(filteredCerts, NULL);
1182
        }
1183
        ret = NULL;
1184
    }
1185
    else {
1186
        ret = filteredCerts;
1187
    }
1188
1189
    if (sk != NULL) {
1190
        wolfSSL_sk_X509_pop_free(sk, NULL);
1191
    }
1192
1193
    return ret;
1194
}
1195
#endif /* WOLFSSL_SIGNER_DER_CERT */
1196
1197
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
1198
1199
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
1200
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
1201
int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
1202
    WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
1203
{
1204
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1205
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get1_issuer");
1206
1207
    if (issuer == NULL || ctx == NULL || x == NULL)
1208
        return WOLFSSL_FATAL_ERROR;
1209
1210
    ret = X509StoreGetIssuerEx(issuer, ctx->store->certs, x);
1211
    if ((ret == WOLFSSL_SUCCESS) && (*issuer != NULL)) {
1212
        return wolfSSL_X509_up_ref(*issuer);
1213
    }
1214
1215
#ifdef WOLFSSL_SIGNER_DER_CERT
1216
    ret = x509GetIssuerFromCM(issuer, ctx->store->cm, x);
1217
#else
1218
    ret = X509StoreGetIssuerEx(issuer, ctx->store->trusted, x);
1219
    if ((ret == WOLFSSL_SUCCESS) && (*issuer != NULL)) {
1220
        return wolfSSL_X509_up_ref(*issuer);
1221
    }
1222
#endif
1223
1224
    return ret;
1225
}
1226
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
1227
1228
#ifdef OPENSSL_EXTRA
1229
1230
static int X509StoreGetIssuerEx(WOLFSSL_X509 **issuer,
1231
                            WOLFSSL_STACK * certs, WOLFSSL_X509 *x)
1232
{
1233
    int i;
1234
1235
    if (issuer == NULL || x == NULL)
1236
        return WOLFSSL_FATAL_ERROR;
1237
1238
    if (certs != NULL) {
1239
        for (i = 0; i < wolfSSL_sk_X509_num(certs); i++) {
1240
            if (wolfSSL_X509_check_issued(
1241
                    wolfSSL_sk_X509_value(certs, i), x) ==
1242
                    WOLFSSL_X509_V_OK) {
1243
                *issuer = wolfSSL_sk_X509_value(certs, i);
1244
                return WOLFSSL_SUCCESS;
1245
            }
1246
        }
1247
    }
1248
1249
    return WOLFSSL_FAILURE;
1250
}
1251
1252
#endif
1253
1254
/******************************************************************************
1255
 * END OF X509_STORE_CTX APIs
1256
 *****************************************************************************/
1257
1258
/******************************************************************************
1259
 * START OF X509_STORE APIs
1260
 *****************************************************************************/
1261
1262
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
1263
    defined(WOLFSSL_WPAS_SMALL)
1264
WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
1265
{
1266
    int ret;
1267
    WOLFSSL_X509_STORE* store = NULL;
1268
    WOLFSSL_ENTER("wolfSSL_X509_STORE_new");
1269
1270
    if ((store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
1271
                                    DYNAMIC_TYPE_X509_STORE)) == NULL)
1272
        goto err_exit;
1273
1274
    XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE));
1275
    store->isDynamic = 1;
1276
1277
    wolfSSL_RefInit(&store->ref, &ret);
1278
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
1279
    if (ret != 0)
1280
        goto err_exit;
1281
#else
1282
    (void)ret;
1283
#endif
1284
1285
    if ((store->cm = wolfSSL_CertManagerNew()) == NULL)
1286
        goto err_exit;
1287
1288
#ifdef OPENSSL_EXTRA
1289
    if ((store->certs = wolfSSL_sk_X509_new_null()) == NULL)
1290
        goto err_exit;
1291
1292
    if ((store->owned = wolfSSL_sk_X509_new_null()) == NULL)
1293
        goto err_exit;
1294
1295
    if ((store->trusted = wolfSSL_sk_X509_new_null()) == NULL)
1296
        goto err_exit;
1297
#endif
1298
1299
#ifdef HAVE_CRL
1300
    store->crl = store->cm->crl;
1301
#endif
1302
1303
    store->numAdded = 0;
1304
1305
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1306
1307
    /* Link store's new Certificate Manager to self by default */
1308
    store->cm->x509_store_p = store;
1309
1310
    if ((store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
1311
                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
1312
                           NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
1313
        goto err_exit;
1314
    }
1315
    XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
1316
    if ((store->lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR),
1317
                           NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
1318
        WOLFSSL_MSG("store->lookup.dir memory allocation error");
1319
        goto err_exit;
1320
    }
1321
    XMEMSET(store->lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR));
1322
    if (wc_InitMutex(&store->lookup.dirs->lock) != 0) {
1323
            WOLFSSL_MSG("Bad mutex init");
1324
            goto err_exit;
1325
    }
1326
#endif
1327
1328
    return store;
1329
1330
err_exit:
1331
    if (store == NULL)
1332
        return NULL;
1333
1334
    wolfSSL_X509_STORE_free(store);
1335
1336
    return NULL;
1337
}
1338
1339
#ifdef OPENSSL_ALL
1340
static void X509StoreFreeObjList(WOLFSSL_X509_STORE* store,
1341
                  WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* objs)
1342
{
1343
    int i;
1344
    WOLFSSL_X509_OBJECT *obj = NULL;
1345
    int cnt = store->numAdded;
1346
1347
    /* -1 here because it is later used as an index value into the object stack.
1348
     * With there being the chance that the only object in the stack is one from
1349
     * the numAdded to the store >= is used when comparing to 0. */
1350
    i = wolfSSL_sk_X509_OBJECT_num(objs) - 1;
1351
    while (cnt > 0 && i >= 0) {
1352
        /* The inner X509 is owned by somebody else, NULL out the reference */
1353
        obj = (WOLFSSL_X509_OBJECT *)wolfSSL_sk_X509_OBJECT_value(objs, i);
1354
        if (obj != NULL) {
1355
            obj->type = (WOLFSSL_X509_LOOKUP_TYPE)0;
1356
            obj->data.ptr = NULL;
1357
        }
1358
        cnt--;
1359
        i--;
1360
    }
1361
1362
    wolfSSL_sk_X509_OBJECT_pop_free(objs, NULL);
1363
}
1364
#endif
1365
1366
void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
1367
{
1368
    int doFree = 0;
1369
    if (store != NULL && store->isDynamic) {
1370
        int ret;
1371
        wolfSSL_RefDec(&store->ref, &doFree, &ret);
1372
    #ifdef WOLFSSL_REFCNT_ERROR_RETURN
1373
        if (ret != 0) {
1374
            WOLFSSL_MSG("Couldn't lock store mutex");
1375
        }
1376
    #else
1377
        (void)ret;
1378
    #endif
1379
1380
        if (doFree) {
1381
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1382
            wolfSSL_CRYPTO_cleanup_ex_data(&store->ex_data);
1383
#endif
1384
            if (store->cm != NULL) {
1385
                wolfSSL_CertManagerFree(store->cm);
1386
                store->cm = NULL;
1387
            }
1388
#if defined(OPENSSL_EXTRA)
1389
            if (store->certs != NULL) {
1390
                wolfSSL_sk_X509_pop_free(store->certs, NULL);
1391
                store->certs = NULL;
1392
            }
1393
            if (store->owned != NULL) {
1394
                wolfSSL_sk_X509_pop_free(store->owned, NULL);
1395
                store->owned = NULL;
1396
            }
1397
            if (store->trusted != NULL) {
1398
                wolfSSL_sk_X509_pop_free(store->trusted, NULL);
1399
                store->trusted = NULL;
1400
            }
1401
#endif
1402
#ifdef OPENSSL_ALL
1403
            if (store->objs != NULL) {
1404
                X509StoreFreeObjList(store, store->objs);
1405
            }
1406
#endif
1407
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1408
            XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL);
1409
            store->param = NULL;
1410
1411
            if (store->lookup.dirs != NULL) {
1412
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1413
                if (store->lookup.dirs->dir_entry) {
1414
                    wolfSSL_sk_BY_DIR_entry_free(
1415
                        store->lookup.dirs->dir_entry);
1416
                }
1417
#endif
1418
                wc_FreeMutex(&store->lookup.dirs->lock);
1419
                XFREE(store->lookup.dirs, NULL, DYNAMIC_TYPE_OPENSSL);
1420
                store->lookup.dirs = NULL;
1421
            }
1422
#endif
1423
            wolfSSL_RefFree(&store->ref);
1424
            XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
1425
        }
1426
    }
1427
}
1428
1429
/**
1430
 * Get ex_data in WOLFSSL_STORE at given index
1431
 * @param store a pointer to WOLFSSL_X509_STORE structure
1432
 * @param idx   Index of ex_data to get data from
1433
 * @return void pointer to ex_data on success or NULL on failure
1434
 */
1435
void* wolfSSL_X509_STORE_get_ex_data(WOLFSSL_X509_STORE* store, int idx)
1436
{
1437
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get_ex_data");
1438
#ifdef HAVE_EX_DATA
1439
    if (store != NULL && idx < MAX_EX_DATA && idx >= 0) {
1440
        return wolfSSL_CRYPTO_get_ex_data(&store->ex_data, idx);
1441
    }
1442
#else
1443
    (void)store;
1444
    (void)idx;
1445
#endif
1446
    return NULL;
1447
}
1448
1449
int wolfSSL_X509_STORE_up_ref(WOLFSSL_X509_STORE* store)
1450
{
1451
    if (store) {
1452
        int ret;
1453
        wolfSSL_RefInc(&store->ref, &ret);
1454
    #ifdef WOLFSSL_REFCNT_ERROR_RETURN
1455
        if (ret != 0) {
1456
            WOLFSSL_MSG("Failed to lock store mutex");
1457
            return WOLFSSL_FAILURE;
1458
        }
1459
    #else
1460
        (void)ret;
1461
    #endif
1462
1463
        return WOLFSSL_SUCCESS;
1464
    }
1465
1466
    return WOLFSSL_FAILURE;
1467
}
1468
1469
/**
1470
 * Set ex_data for WOLFSSL_STORE
1471
 * @param store a pointer to WOLFSSL_X509_STORE structure
1472
 * @param idx   Index of ex data to set
1473
 * @param data  Data to set in ex data
1474
 * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
1475
 */
1476
int wolfSSL_X509_STORE_set_ex_data(WOLFSSL_X509_STORE* store, int idx,
1477
                                                                void *data)
1478
{
1479
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data");
1480
#ifdef HAVE_EX_DATA
1481
    if (store != NULL && idx < MAX_EX_DATA) {
1482
        return wolfSSL_CRYPTO_set_ex_data(&store->ex_data, idx, data);
1483
    }
1484
#else
1485
    (void)store;
1486
    (void)idx;
1487
    (void)data;
1488
#endif
1489
    return WOLFSSL_FAILURE;
1490
}
1491
1492
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1493
/**
1494
 * Set ex_data for WOLFSSL_STORE
1495
 * @param store a pointer to WOLFSSL_X509_STORE structure
1496
 * @param idx   Index of ex data to set
1497
 * @param data  Data to set in ex data
1498
 * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
1499
 */
1500
int wolfSSL_X509_STORE_set_ex_data_with_cleanup(
1501
    WOLFSSL_X509_STORE* store,
1502
    int idx,
1503
    void *data,
1504
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
1505
{
1506
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data_with_cleanup");
1507
    if (store != NULL && idx < MAX_EX_DATA) {
1508
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&store->ex_data, idx,
1509
                                                       data, cleanup_routine);
1510
    }
1511
    return WOLFSSL_FAILURE;
1512
}
1513
1514
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
1515
1516
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER || WOLFSSL_WPAS_SMALL */
1517
1518
#ifdef OPENSSL_EXTRA
1519
1520
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
1521
void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st,
1522
        WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
1523
{
1524
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_verify_cb");
1525
    if (st != NULL) {
1526
        st->verify_cb = verify_cb;
1527
    }
1528
}
1529
1530
void wolfSSL_X509_STORE_set_get_crl(WOLFSSL_X509_STORE *st,
1531
        WOLFSSL_X509_STORE_CTX_get_crl_cb get_cb)
1532
{
1533
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_get_crl");
1534
    if (st != NULL) {
1535
        st->get_crl_cb = get_cb;
1536
    }
1537
}
1538
1539
#ifndef NO_WOLFSSL_STUB
1540
void wolfSSL_X509_STORE_set_check_crl(WOLFSSL_X509_STORE *st,
1541
        WOLFSSL_X509_STORE_CTX_check_crl_cb check_crl)
1542
{
1543
    (void)st;
1544
    (void)check_crl;
1545
    WOLFSSL_STUB("wolfSSL_X509_STORE_set_check_crl (not implemented)");
1546
}
1547
#endif
1548
#endif /* WOLFSSL_QT || OPENSSL_ALL */
1549
1550
WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
1551
                                               WOLFSSL_X509_LOOKUP_METHOD* m)
1552
{
1553
    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_lookup");
1554
    if (store == NULL || m == NULL)
1555
        return NULL;
1556
1557
    /* Make sure the lookup has a back reference to the store. */
1558
    store->lookup.store = store;
1559
    /* store a type to know which method wants to be used for */
1560
    store->lookup.type = m->type;
1561
    return &store->lookup;
1562
}
1563
1564
static int X509StoreAddCa(WOLFSSL_X509_STORE* store,
1565
                                          WOLFSSL_X509* x509, int type)
1566
{
1567
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1568
    DerBuffer* derCert = NULL;
1569
    int verify = VERIFY;
1570
1571
    WOLFSSL_ENTER("X509StoreAddCa");
1572
    if (store != NULL && x509 != NULL && x509->derCert != NULL) {
1573
        /* Check if NO_CHECK_TIME flag is set - if so, skip date validation */
1574
        if (store->param != NULL &&
1575
            (store->param->flags & WOLFSSL_NO_CHECK_TIME) != 0) {
1576
            verify = VERIFY_SKIP_DATE;
1577
        }
1578
        result = AllocDer(&derCert, x509->derCert->length,
1579
            x509->derCert->type, NULL);
1580
        if (result == 0) {
1581
            /* AddCA() frees the buffer. */
1582
            XMEMCPY(derCert->buffer,
1583
                            x509->derCert->buffer, x509->derCert->length);
1584
            result = AddCA(store->cm, &derCert, type, verify);
1585
        }
1586
    }
1587
1588
    return result;
1589
}
1590
1591
int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
1592
{
1593
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1594
1595
    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
1596
    if (store != NULL && store->cm != NULL && x509 != NULL
1597
                                                && x509->derCert != NULL) {
1598
        /* Mimic the openssl behavior, must be self signed to be considered
1599
         * trusted, addCA() internals will do additional checks for
1600
         * CA=TRUE */
1601
        if (wolfSSL_X509_NAME_cmp(&x509->issuer, &x509->subject) == 0) {
1602
            result = X509StoreAddCa(store, x509, WOLFSSL_USER_CA);
1603
            if (result == WOLFSSL_SUCCESS && store->trusted != NULL) {
1604
                result = wolfSSL_X509_up_ref(x509);
1605
                if (result == WOLFSSL_SUCCESS) {
1606
                    result = wolfSSL_sk_X509_push(store->trusted, x509);
1607
                    if (result > 0) {
1608
                        result = WOLFSSL_SUCCESS;
1609
                    }
1610
                    else {
1611
                        result = WOLFSSL_FATAL_ERROR;
1612
                        wolfSSL_X509_free(x509);
1613
                        x509 = NULL;
1614
                    }
1615
                }
1616
            }
1617
        }
1618
        else {
1619
            if (store->certs != NULL) {
1620
                result = wolfSSL_X509_up_ref(x509);
1621
                if (result == WOLFSSL_SUCCESS) {
1622
                    result = wolfSSL_sk_X509_push(store->certs, x509);
1623
                    if (result > 0) {
1624
                        result = WOLFSSL_SUCCESS;
1625
                    }
1626
                    else {
1627
                        result = WOLFSSL_FATAL_ERROR;
1628
                        wolfSSL_X509_free(x509);
1629
                        x509 = NULL;
1630
                    }
1631
                }
1632
            }
1633
            else {
1634
                /* If store->certs is NULL, this is an X509_STORE managed by an
1635
                 * SSL_CTX, preserve behavior and always add as USER_CA */
1636
                result = X509StoreAddCa(
1637
                            store, x509, WOLFSSL_USER_CA);
1638
            }
1639
        }
1640
    }
1641
1642
    WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
1643
1644
    if (result != WOLFSSL_SUCCESS) {
1645
        result = WOLFSSL_FATAL_ERROR;
1646
    }
1647
1648
    return result;
1649
}
1650
1651
int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
1652
{
1653
    int ret = WOLFSSL_SUCCESS;
1654
1655
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags");
1656
1657
    if (store == NULL)
1658
        return WOLFSSL_FAILURE;
1659
1660
    if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
1661
        ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
1662
    }
1663
#if defined(OPENSSL_COMPATIBLE_DEFAULTS)
1664
    else if (flag == 0) {
1665
        ret = wolfSSL_CertManagerDisableCRL(store->cm);
1666
    }
1667
#endif
1668
    if (flag & WOLFSSL_PARTIAL_CHAIN) {
1669
        store->param->flags |= WOLFSSL_PARTIAL_CHAIN;
1670
    }
1671
    return ret;
1672
}
1673
1674
int X509StoreLoadCertBuffer(WOLFSSL_X509_STORE *str,
1675
                                        byte *buf, word32 bufLen, int type)
1676
{
1677
    int ret = WOLFSSL_SUCCESS;
1678
    WOLFSSL_X509 *x509 = NULL;
1679
1680
    if (str == NULL || buf == NULL) {
1681
        return WOLFSSL_FAILURE;
1682
    }
1683
1684
    /* OpenSSL X509_STORE_load_file fails on DER file, we will as well */
1685
    x509 = wolfSSL_X509_load_certificate_buffer(buf, bufLen, type);
1686
    if (x509 != NULL) {
1687
        ret = wolfSSL_X509_STORE_add_cert(str, x509);
1688
        if (ret != WOLFSSL_SUCCESS) {
1689
            WOLFSSL_MSG("Failed to load file");
1690
            ret = WOLFSSL_FAILURE;
1691
        }
1692
        if (ret == WOLFSSL_SUCCESS && str->owned != NULL) {
1693
            if (wolfSSL_sk_X509_push(str->owned, x509) <= 0) {
1694
                ret = WOLFSSL_FAILURE;
1695
            }
1696
            else {
1697
                x509 = NULL;
1698
            }
1699
        }
1700
        wolfSSL_X509_free(x509);
1701
        x509 = NULL;
1702
    }
1703
    else {
1704
        ret = WOLFSSL_FAILURE;
1705
    }
1706
1707
    return ret;
1708
}
1709
1710
#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1711
1712
static int X509StoreReadFile(const char *fname,
1713
                StaticBuffer *content, word32 *bytesRead, int *type)
1714
{
1715
    int ret = -1;
1716
    long sz = 0;
1717
#ifdef HAVE_CRL
1718
    const char* header = NULL;
1719
    const char* footer = NULL;
1720
#endif
1721
1722
    ret = wolfssl_read_file_static(fname, content, NULL, DYNAMIC_TYPE_FILE,
1723
        &sz);
1724
    if (ret == 0) {
1725
        *type = CERT_TYPE;
1726
        *bytesRead = (word32)sz;
1727
#ifdef HAVE_CRL
1728
        /* Look for CRL header and footer. */
1729
        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
1730
                (XSTRNSTR((char*)content->buffer, header, (word32)sz) !=
1731
                    NULL)) {
1732
            *type = CRL_TYPE;
1733
        }
1734
#endif
1735
    }
1736
1737
    return (ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
1738
}
1739
1740
static int X509StoreLoadFile(WOLFSSL_X509_STORE *str,
1741
                                        const char *fname)
1742
{
1743
    int ret = WOLFSSL_SUCCESS;
1744
    int type = 0;
1745
#ifndef WOLFSSL_SMALL_STACK
1746
    byte   stackBuffer[FILE_BUFFER_SIZE];
1747
#endif
1748
    StaticBuffer content;
1749
    word32 contentLen = 0;
1750
1751
#ifdef WOLFSSL_SMALL_STACK
1752
    static_buffer_init(&content);
1753
#else
1754
    static_buffer_init(&content, stackBuffer, FILE_BUFFER_SIZE);
1755
#endif
1756
1757
    WOLFSSL_MSG_EX("X509StoreLoadFile: Loading file: %s", fname);
1758
1759
    ret = X509StoreReadFile(fname, &content, &contentLen, &type);
1760
    if (ret != WOLFSSL_SUCCESS) {
1761
        WOLFSSL_MSG("Failed to load file");
1762
        ret = WOLFSSL_FAILURE;
1763
    }
1764
1765
    if ((ret == WOLFSSL_SUCCESS) && (type == CERT_TYPE)) {
1766
        ret = X509StoreLoadCertBuffer(str, content.buffer,
1767
                                        contentLen, WOLFSSL_FILETYPE_PEM);
1768
    }
1769
#ifdef HAVE_CRL
1770
    else if ((ret == WOLFSSL_SUCCESS) && (type == CRL_TYPE)) {
1771
        ret = BufferLoadCRL(str->cm->crl, content.buffer, contentLen,
1772
                                        WOLFSSL_FILETYPE_PEM, 0);
1773
    }
1774
#endif
1775
1776
    static_buffer_free(&content, NULL, DYNAMIC_TYPE_FILE);
1777
    return ret;
1778
}
1779
1780
/* Loads certificate(s) files in pem format into X509_STORE struct from either
1781
 * a file or directory.
1782
 * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE if an error occurs.
1783
 */
1784
int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
1785
                                            const char *file, const char *dir)
1786
{
1787
    WOLFSSL_CTX* ctx;
1788
    char *name = NULL;
1789
    int ret = WOLFSSL_SUCCESS;
1790
    WC_DECLARE_VAR(readCtx, ReadDirCtx, 1, 0);
1791
1792
    WOLFSSL_ENTER("wolfSSL_X509_STORE_load_locations");
1793
1794
    if (str == NULL || str->cm == NULL || (file == NULL  && dir == NULL))
1795
        return WOLFSSL_FAILURE;
1796
1797
    /* tmp ctx for setting our cert manager */
1798
    ctx = wolfSSL_CTX_new_ex(cm_pick_method(str->cm->heap), str->cm->heap);
1799
    if (ctx == NULL)
1800
        return WOLFSSL_FAILURE;
1801
1802
    wolfSSL_CertManagerFree(ctx->cm);
1803
    ctx->cm = str->cm;
1804
1805
#ifdef HAVE_CRL
1806
    if (str->cm->crl == NULL) {
1807
        /* Workaround to allocate the internals to load CRL's but don't enable
1808
         * CRL checking by default */
1809
        if (wolfSSL_CertManagerEnableCRL(str->cm, WOLFSSL_CRL_CHECK)
1810
                != WOLFSSL_SUCCESS ||
1811
                wolfSSL_CertManagerDisableCRL(str->cm) != WOLFSSL_SUCCESS) {
1812
            WOLFSSL_MSG("Enable CRL failed");
1813
            wolfSSL_CTX_free(ctx);
1814
            return WOLFSSL_FAILURE;
1815
        }
1816
    }
1817
#endif
1818
1819
    /* Load individual file */
1820
    if (file) {
1821
        ret = X509StoreLoadFile(str, file);
1822
        if (ret != WOLFSSL_SUCCESS) {
1823
            WOLFSSL_MSG("Failed to load file");
1824
            ret = WOLFSSL_FAILURE;
1825
        }
1826
    }
1827
1828
    /* Load files in dir */
1829
    if (dir && ret == WOLFSSL_SUCCESS) {
1830
        int successes = 0;
1831
1832
        #ifdef WOLFSSL_SMALL_STACK
1833
            readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
1834
                                                    DYNAMIC_TYPE_TMP_BUFFER);
1835
            if (readCtx == NULL) {
1836
                WOLFSSL_MSG("Memory error");
1837
                wolfSSL_CTX_free(ctx);
1838
                return WOLFSSL_FAILURE;
1839
            }
1840
        #endif
1841
1842
        /* try to load each regular file in dir */
1843
        ret = wc_ReadDirFirst(readCtx, dir, &name);
1844
        while (ret == 0 && name) {
1845
            WOLFSSL_MSG(name);
1846
1847
            ret = X509StoreLoadFile(str, name);
1848
            /* Not failing on load errors */
1849
            if (ret != WOLFSSL_SUCCESS)
1850
                WOLFSSL_MSG("Failed to load file in path, continuing");
1851
            else
1852
                successes++;
1853
1854
            ret = wc_ReadDirNext(readCtx, dir, &name);
1855
        }
1856
        wc_ReadDirClose(readCtx);
1857
1858
        /* Success if at least one file in dir was loaded */
1859
        if (successes > 0)
1860
            ret = WOLFSSL_SUCCESS;
1861
        else {
1862
            WOLFSSL_ERROR(ret);
1863
            ret = WOLFSSL_FAILURE;
1864
        }
1865
1866
            WC_FREE_VAR_EX(readCtx, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
1867
    }
1868
1869
    ctx->cm = NULL;
1870
    wolfSSL_CTX_free(ctx);
1871
1872
    return ret;
1873
}
1874
1875
#if defined(XGETENV) && !defined(NO_GETENV)
1876
int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE *str)
1877
{
1878
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1879
    char* certDir = NULL;
1880
    char* certFile = NULL;
1881
1882
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_default_paths");
1883
1884
    certFile = wc_strdup_ex(XGETENV("SSL_CERT_FILE"), DYNAMIC_TYPE_TMP_BUFFER);
1885
    certDir = wc_strdup_ex(XGETENV("SSL_CERT_DIR"), DYNAMIC_TYPE_TMP_BUFFER);
1886
1887
    ret = wolfSSL_X509_STORE_load_locations(str, certFile, certDir);
1888
1889
    XFREE(certFile, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1890
    XFREE(certDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1891
    return ret;
1892
}
1893
#endif /* XGETENV && !NO_GETENV */
1894
1895
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
1896
1897
int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store)
1898
{
1899
    int cnt_ret = 0;
1900
    Signer **table;
1901
1902
    WOLFSSL_ENTER("wolfSSL_X509_CA_num");
1903
    if (store == NULL || store->cm == NULL){
1904
        WOLFSSL_MSG("invalid parameter");
1905
        return WOLFSSL_FAILURE;
1906
    }
1907
1908
    table = store->cm->caTable;
1909
    if (table || (store->certs != NULL)){
1910
        if (wc_LockMutex(&store->cm->caLock) == 0){
1911
            if (table) {
1912
                int i = 0;
1913
                for (i = 0; i < CA_TABLE_SIZE; i++) {
1914
                    Signer* signer = table[i];
1915
                    while (signer) {
1916
                        Signer* next = signer->next;
1917
                        cnt_ret++;
1918
                        signer = next;
1919
                    }
1920
                }
1921
            }
1922
1923
            if (store->certs != NULL) {
1924
                cnt_ret += wolfSSL_sk_X509_num(store->certs);
1925
            }
1926
            wc_UnLockMutex(&store->cm->caLock);
1927
        }
1928
    }
1929
1930
    return cnt_ret;
1931
}
1932
1933
/******************************************************************************
1934
* wolfSSL_X509_STORE_GetCerts - retrieve stack of X509 in a certificate
1935
*                               store ctx
1936
*
1937
* This API can be used in SSL verify callback function to view cert chain
1938
* See examples/client/client.c and myVerify() function in test.h
1939
*
1940
* RETURNS:
1941
* returns stack of X509 certs on success, otherwise returns a NULL.
1942
*/
1943
WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s)
1944
{
1945
    int  certIdx = 0;
1946
    WOLFSSL_BUFFER_INFO* cert = NULL;
1947
    DecodedCert* dCert = NULL;
1948
    WOLFSSL_X509* x509 = NULL;
1949
    WOLFSSL_STACK* sk = NULL;
1950
    int found = 0;
1951
1952
    if (s == NULL) {
1953
        return NULL;
1954
    }
1955
1956
    sk = wolfSSL_sk_X509_new_null();
1957
1958
    if (sk == NULL) {
1959
        return NULL;
1960
    }
1961
1962
    for (certIdx = s->totalCerts - 1; certIdx >= 0; certIdx--) {
1963
        /* get certificate buffer */
1964
        cert = &s->certs[certIdx];
1965
1966
        dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
1967
                                                DYNAMIC_TYPE_DCERT);
1968
1969
        if (dCert == NULL) {
1970
            goto error;
1971
        }
1972
        XMEMSET(dCert, 0, sizeof(DecodedCert));
1973
1974
        InitDecodedCert(dCert, cert->buffer, cert->length, NULL);
1975
1976
        /* Parse Certificate */
1977
        if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL)){
1978
            goto error;
1979
        }
1980
        x509 = wolfSSL_X509_new();
1981
1982
        if (x509 == NULL) {
1983
            goto error;
1984
        }
1985
        InitX509(x509, 1, NULL);
1986
1987
        if (CopyDecodedToX509(x509, dCert) == 0) {
1988
1989
            if (wolfSSL_sk_X509_push(sk, x509) <= 0) {
1990
                WOLFSSL_MSG("Unable to load x509 into stack");
1991
                wolfSSL_X509_free(x509);
1992
                x509 = NULL;
1993
                goto error;
1994
            }
1995
        }
1996
        else {
1997
            goto error;
1998
        }
1999
        found = 1;
2000
2001
        FreeDecodedCert(dCert);
2002
        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
2003
        dCert = NULL;
2004
    }
2005
2006
    if (!found) {
2007
        wolfSSL_sk_X509_pop_free(sk, NULL);
2008
        sk = NULL;
2009
    }
2010
    return sk;
2011
2012
error:
2013
    if (dCert) {
2014
        FreeDecodedCert(dCert);
2015
        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
2016
    }
2017
2018
    if (sk)
2019
        wolfSSL_sk_X509_pop_free(sk, NULL);
2020
2021
    return NULL;
2022
}
2023
#endif /* OPENSSL_EXTRA */
2024
2025
#ifdef OPENSSL_ALL
2026
WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
2027
    WOLFSSL_X509_STORE* store)
2028
{
2029
    WOLFSSL_STACK* ret = NULL;
2030
    WOLFSSL_STACK* cert_stack = NULL;
2031
#if ((defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)) || \
2032
     (defined(HAVE_CRL)))
2033
    WOLFSSL_X509_OBJECT* obj = NULL;
2034
#endif
2035
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
2036
    WOLFSSL_X509* x509 = NULL;
2037
    int i = 0;
2038
#endif
2039
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects");
2040
2041
    if (store == NULL || store->cm == NULL) {
2042
        WOLFSSL_MSG("Missing or empty store");
2043
        return NULL;
2044
    }
2045
2046
    if (store->objs != NULL) {
2047
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
2048
        /* want to update objs stack by cm stack again before returning it*/
2049
        X509StoreFreeObjList(store, store->objs);
2050
        store->objs = NULL;
2051
#else
2052
        if (wolfSSL_sk_X509_OBJECT_num(store->objs) == 0) {
2053
            /* Let's try generating the stack again */
2054
            wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL);
2055
            store->objs = NULL;
2056
        }
2057
        else
2058
            return store->objs;
2059
#endif
2060
    }
2061
2062
    if ((ret = wolfSSL_sk_X509_OBJECT_new()) == NULL) {
2063
        WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error");
2064
        goto err_cleanup;
2065
    }
2066
2067
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
2068
    cert_stack = wolfSSL_CertManagerGetCerts(store->cm);
2069
    store->numAdded = 0;
2070
    if (cert_stack == NULL && wolfSSL_sk_X509_num(store->certs) > 0) {
2071
        cert_stack = wolfSSL_sk_X509_new_null();
2072
        if (cert_stack == NULL) {
2073
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error");
2074
            goto err_cleanup;
2075
        }
2076
    }
2077
    for (i = 0; i < wolfSSL_sk_X509_num(store->certs); i++) {
2078
        if (wolfSSL_sk_X509_push(cert_stack,
2079
                             wolfSSL_sk_X509_value(store->certs, i)) > 0) {
2080
            store->numAdded++;
2081
        }
2082
    }
2083
    /* Do not modify stack until after we guarantee success to
2084
     * simplify cleanup logic handling cert merging above */
2085
    for (i = 0; i < wolfSSL_sk_X509_num(cert_stack); i++) {
2086
        x509 = (WOLFSSL_X509 *)wolfSSL_sk_value(cert_stack, i);
2087
        obj  = wolfSSL_X509_OBJECT_new();
2088
        if (obj == NULL) {
2089
            WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
2090
            goto err_cleanup;
2091
        }
2092
        if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) {
2093
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
2094
            wolfSSL_X509_OBJECT_free(obj);
2095
            goto err_cleanup;
2096
        }
2097
        obj->type = WOLFSSL_X509_LU_X509;
2098
        obj->data.x509 = x509;
2099
    }
2100
2101
    while (wolfSSL_sk_X509_num(cert_stack) > 0) {
2102
        wolfSSL_sk_X509_pop(cert_stack);
2103
    }
2104
#endif
2105
2106
#ifdef HAVE_CRL
2107
    if (store->cm->crl != NULL) {
2108
        int res;
2109
        obj = wolfSSL_X509_OBJECT_new();
2110
        if (obj == NULL) {
2111
            WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
2112
            goto err_cleanup;
2113
        }
2114
        if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) {
2115
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
2116
            wolfSSL_X509_OBJECT_free(obj);
2117
            goto err_cleanup;
2118
        }
2119
        obj->type = WOLFSSL_X509_LU_CRL;
2120
        wolfSSL_RefInc(&store->cm->crl->ref, &res);
2121
        if (res != 0) {
2122
            WOLFSSL_MSG("Failed to lock crl mutex");
2123
            goto err_cleanup;
2124
        }
2125
        obj->data.crl = store->cm->crl;
2126
    }
2127
#endif
2128
2129
    if (cert_stack)
2130
        wolfSSL_sk_X509_pop_free(cert_stack, NULL);
2131
    store->objs = ret;
2132
    return ret;
2133
err_cleanup:
2134
    if (ret != NULL)
2135
        X509StoreFreeObjList(store, ret);
2136
    if (cert_stack != NULL) {
2137
        while (store->numAdded > 0) {
2138
            wolfSSL_sk_X509_pop(cert_stack);
2139
            store->numAdded--;
2140
        }
2141
        wolfSSL_sk_X509_pop_free(cert_stack, NULL);
2142
    }
2143
    return NULL;
2144
}
2145
#endif /* OPENSSL_ALL */
2146
2147
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
2148
    defined(WOLFSSL_WPAS_SMALL)
2149
WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_get0_param(
2150
        const WOLFSSL_X509_STORE *ctx)
2151
{
2152
    if (ctx == NULL)
2153
        return NULL;
2154
    return ctx->param;
2155
}
2156
2157
#ifdef OPENSSL_EXTRA
2158
int wolfSSL_X509_STORE_set1_param(WOLFSSL_X509_STORE *ctx,
2159
        WOLFSSL_X509_VERIFY_PARAM *param)
2160
{
2161
    if (ctx == NULL)
2162
        return WOLFSSL_FAILURE;
2163
    return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, param);
2164
}
2165
#endif
2166
#endif
2167
2168
/******************************************************************************
2169
 * END OF X509_STORE APIs
2170
 *****************************************************************************/
2171
2172
#endif /* NO_CERTS */
2173
2174
#endif /* !WOLFCRYPT_ONLY */
2175
2176
#endif /* !WOLFSSL_X509_STORE_INCLUDED */
2177