Coverage Report

Created: 2025-09-01 06:47

/src/wolfssl/src/x509_str.c
Line
Count
Source (jump to first uncovered line)
1
/* x509_str.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if !defined(WOLFSSL_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
#ifdef WOLFSSL_SMALL_STACK
129
    DecodedCert* cert = NULL;
130
#else
131
    DecodedCert  cert[1];
132
#endif
133
134
    if (cm == NULL || x == NULL || x->derCert == NULL) {
135
        WOLFSSL_MSG("No cert DER buffer or NULL cm. Defining "
136
                    "WOLFSSL_SIGNER_DER_CERT could solve the issue");
137
        return WOLFSSL_FAILURE;
138
    }
139
140
#ifdef WOLFSSL_SMALL_STACK
141
    cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
142
    if (cert == NULL)
143
        return WOLFSSL_FAILURE;
144
#endif
145
146
    /* Use existing CA retrieval APIs that use DecodedCert. */
147
    InitDecodedCert(cert, x->derCert->buffer, x->derCert->length, cm->heap);
148
    if (ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL) == 0
149
            && !cert->selfSigned) {
150
    #ifndef NO_SKID
151
        if (cert->extAuthKeyIdSet)
152
            ca = GetCA(cm, cert->extAuthKeyId);
153
        if (ca == NULL)
154
            ca = GetCAByName(cm, cert->issuerHash);
155
    #else /* NO_SKID */
156
        ca = GetCA(cm, cert->issuerHash);
157
    #endif /* NO SKID */
158
    }
159
    FreeDecodedCert(cert);
160
#ifdef WOLFSSL_SMALL_STACK
161
    XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
162
#endif
163
164
    if (ca == NULL)
165
        return WOLFSSL_FAILURE;
166
167
#ifdef WOLFSSL_SIGNER_DER_CERT
168
    /* populate issuer with Signer DER */
169
    if (wolfSSL_X509_d2i_ex(issuer, ca->derCert->buffer,
170
            ca->derCert->length, cm->heap) == NULL)
171
        return WOLFSSL_FAILURE;
172
#else
173
    /* Create an empty certificate as CA doesn't have a certificate. */
174
    *issuer = (WOLFSSL_X509 *)XMALLOC(sizeof(WOLFSSL_X509), 0,
175
        DYNAMIC_TYPE_OPENSSL);
176
    if (*issuer == NULL)
177
        return WOLFSSL_FAILURE;
178
179
    InitX509((*issuer), 1, NULL);
180
#endif
181
182
    return WOLFSSL_SUCCESS;
183
}
184
#endif /* SESSION_CERTS || WOLFSSL_SIGNER_DER_CERT */
185
186
WOLFSSL_X509_STORE_CTX* wolfSSL_X509_STORE_CTX_new(void)
187
{
188
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_new");
189
    return wolfSSL_X509_STORE_CTX_new_ex(NULL);
190
}
191
192
int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx,
193
     WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509,
194
     WOLF_STACK_OF(WOLFSSL_X509)* sk)
195
{
196
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_init");
197
198
    if (ctx != NULL) {
199
        ctx->store = store;
200
        #ifndef WOLFSSL_X509_STORE_CERTS
201
        ctx->current_cert = x509;
202
        #else
203
        if(x509 != NULL){
204
            ctx->current_cert = wolfSSL_X509_d2i_ex(NULL,
205
                    x509->derCert->buffer,
206
                    x509->derCert->length,
207
                    x509->heap);
208
            if(ctx->current_cert == NULL)
209
                return WOLFSSL_FAILURE;
210
        } else
211
            ctx->current_cert = NULL;
212
        #endif
213
214
        ctx->ctxIntermediates = sk;
215
        if (ctx->chain != NULL) {
216
            wolfSSL_sk_X509_free(ctx->chain);
217
            ctx->chain = NULL;
218
        }
219
#ifdef SESSION_CERTS
220
        ctx->sesChain = NULL;
221
#endif
222
        ctx->domain = NULL;
223
#ifdef HAVE_EX_DATA
224
        XMEMSET(&ctx->ex_data, 0, sizeof(ctx->ex_data));
225
#endif
226
        ctx->userCtx = NULL;
227
        ctx->error = 0;
228
        ctx->error_depth = 0;
229
        ctx->discardSessionCerts = 0;
230
231
        if (ctx->param == NULL) {
232
            ctx->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
233
                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
234
                           ctx->heap, DYNAMIC_TYPE_OPENSSL);
235
            if (ctx->param == NULL){
236
                WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init failed");
237
                return WOLFSSL_FAILURE;
238
            }
239
            XMEMSET(ctx->param, 0, sizeof(*ctx->param));
240
        }
241
242
        return WOLFSSL_SUCCESS;
243
    }
244
    return WOLFSSL_FAILURE;
245
}
246
247
/* Its recommended to use a full free -> init cycle of all the objects
248
 * because wolfSSL_X509_STORE_CTX_init may modify the store too which doesn't
249
 * get reset here. */
250
void wolfSSL_X509_STORE_CTX_cleanup(WOLFSSL_X509_STORE_CTX* ctx)
251
{
252
    if (ctx != NULL) {
253
254
        XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL);
255
        ctx->param = NULL;
256
257
        wolfSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
258
    }
259
}
260
261
262
void wolfSSL_X509_STORE_CTX_trusted_stack(WOLFSSL_X509_STORE_CTX *ctx,
263
                                          WOLF_STACK_OF(WOLFSSL_X509) *sk)
264
{
265
    if (ctx != NULL) {
266
        ctx->setTrustedSk = sk;
267
    }
268
}
269
270
271
/* Returns corresponding X509 error from internal ASN error <e> */
272
int GetX509Error(int e)
273
{
274
    switch (e) {
275
        case WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E):
276
            return WOLFSSL_X509_V_ERR_CERT_NOT_YET_VALID;
277
        case WC_NO_ERR_TRACE(ASN_AFTER_DATE_E):
278
            return WOLFSSL_X509_V_ERR_CERT_HAS_EXPIRED;
279
        case WC_NO_ERR_TRACE(ASN_NO_SIGNER_E):
280
            /* get issuer error if no CA found locally */
281
            return WOLFSSL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
282
        case WC_NO_ERR_TRACE(ASN_SELF_SIGNED_E):
283
            return WOLFSSL_X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
284
        case WC_NO_ERR_TRACE(ASN_PATHLEN_INV_E):
285
        case WC_NO_ERR_TRACE(ASN_PATHLEN_SIZE_E):
286
            return WOLFSSL_X509_V_ERR_PATH_LENGTH_EXCEEDED;
287
        case WC_NO_ERR_TRACE(ASN_SIG_OID_E):
288
        case WC_NO_ERR_TRACE(ASN_SIG_CONFIRM_E):
289
        case WC_NO_ERR_TRACE(ASN_SIG_HASH_E):
290
        case WC_NO_ERR_TRACE(ASN_SIG_KEY_E):
291
            return WOLFSSL_X509_V_ERR_CERT_SIGNATURE_FAILURE;
292
        /* We can't disambiguate if its the before or after date that caused
293
         * the error. Assume expired. */
294
        case WC_NO_ERR_TRACE(CRL_CERT_DATE_ERR):
295
            return WOLFSSL_X509_V_ERR_CRL_HAS_EXPIRED;
296
        case WC_NO_ERR_TRACE(CRL_CERT_REVOKED):
297
            return WOLFSSL_X509_V_ERR_CERT_REVOKED;
298
        case WC_NO_ERR_TRACE(CRL_MISSING):
299
            return WOLFSSL_X509_V_ERR_UNABLE_TO_GET_CRL;
300
        case 0:
301
        case 1:
302
            return 0;
303
        default:
304
#ifdef HAVE_WOLFSSL_MSG_EX
305
            WOLFSSL_MSG_EX("Error not configured or implemented yet: %d", e);
306
#else
307
            WOLFSSL_MSG("Error not configured or implemented yet");
308
#endif
309
            return e;
310
    }
311
}
312
313
static void SetupStoreCtxError_ex(WOLFSSL_X509_STORE_CTX* ctx, int ret,
314
                                                                    int depth)
315
{
316
    int error = GetX509Error(ret);
317
318
    wolfSSL_X509_STORE_CTX_set_error(ctx, error);
319
    wolfSSL_X509_STORE_CTX_set_error_depth(ctx, depth);
320
}
321
322
static void SetupStoreCtxError(WOLFSSL_X509_STORE_CTX* ctx, int ret)
323
{
324
    int depth = 0;
325
326
    /* Set error depth */
327
    if (ctx->chain)
328
        depth = (int)ctx->chain->num;
329
330
    SetupStoreCtxError_ex(ctx, ret, depth);
331
}
332
333
static int X509StoreVerifyCert(WOLFSSL_X509_STORE_CTX* ctx)
334
{
335
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
336
    WOLFSSL_ENTER("X509StoreVerifyCert");
337
338
    if (ctx->current_cert != NULL && ctx->current_cert->derCert != NULL) {
339
        ret = wolfSSL_CertManagerVerifyBuffer(ctx->store->cm,
340
                    ctx->current_cert->derCert->buffer,
341
                    ctx->current_cert->derCert->length,
342
                    WOLFSSL_FILETYPE_ASN1);
343
        SetupStoreCtxError(ctx, ret);
344
    #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
345
        if (ctx->store->verify_cb)
346
            ret = ctx->store->verify_cb(ret >= 0 ? 1 : 0, ctx) == 1 ?
347
                                                        WOLFSSL_SUCCESS : ret;
348
    #endif
349
350
    #ifndef NO_ASN_TIME
351
        if (ret != WC_NO_ERR_TRACE(ASN_BEFORE_DATE_E) &&
352
            ret != WC_NO_ERR_TRACE(ASN_AFTER_DATE_E)) {
353
            /* wolfSSL_CertManagerVerifyBuffer only returns ASN_AFTER_DATE_E or
354
             * ASN_BEFORE_DATE_E if there are no additional errors found in the
355
             * cert. Therefore, check if the cert is expired or not yet valid
356
             * in order to return the correct expected error. */
357
            byte *afterDate = ctx->current_cert->notAfter.data;
358
            byte *beforeDate = ctx->current_cert->notBefore.data;
359
360
            if (XVALIDATE_DATE(afterDate,
361
                    (byte)ctx->current_cert->notAfter.type, ASN_AFTER) < 1) {
362
                ret = ASN_AFTER_DATE_E;
363
            }
364
            else if (XVALIDATE_DATE(beforeDate,
365
                    (byte)ctx->current_cert->notBefore.type, ASN_BEFORE) < 1) {
366
                ret = ASN_BEFORE_DATE_E;
367
            }
368
            SetupStoreCtxError(ctx, ret);
369
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
370
            if (ctx->store->verify_cb)
371
                ret = ctx->store->verify_cb(ret >= 0 ? 1 : 0,
372
                                            ctx) == 1 ? WOLFSSL_SUCCESS : -1;
373
        #endif
374
        }
375
    #endif
376
    }
377
378
    return ret;
379
}
380
381
static int addAllButSelfSigned(WOLF_STACK_OF(WOLFSSL_X509)*to,
382
                               WOLF_STACK_OF(WOLFSSL_X509)*from, int *numAdded)
383
{
384
    int ret = WOLFSSL_SUCCESS;
385
    int i = 0;
386
    int cnt = 0;
387
    WOLFSSL_X509 *x = NULL;
388
389
    for (i = 0; i < wolfSSL_sk_X509_num(from); i++) {
390
        x = wolfSSL_sk_X509_value(from, i);
391
        if (wolfSSL_X509_NAME_cmp(&x->issuer, &x->subject) != 0) {
392
            if (wolfSSL_sk_X509_push(to, x) <= 0) {
393
                ret = WOLFSSL_FAILURE;
394
                goto exit;
395
            }
396
            cnt++;
397
        }
398
    }
399
400
exit:
401
    if (numAdded != NULL) {
402
        *numAdded = cnt;
403
    }
404
    return ret;
405
}
406
407
/* Verifies certificate chain using WOLFSSL_X509_STORE_CTX
408
 * returns 1 on success or <= 0 on failure.
409
 */
410
int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx)
411
{
412
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
413
    int done = 0;
414
    int added = 0;
415
    int i = 0;
416
    int numInterAdd = 0;
417
    int depth = 0;
418
    WOLFSSL_X509 *issuer = NULL;
419
    WOLFSSL_X509 *orig = NULL;
420
    WOLF_STACK_OF(WOLFSSL_X509)* certs = NULL;
421
    WOLF_STACK_OF(WOLFSSL_X509)* certsToUse = NULL;
422
    WOLFSSL_ENTER("wolfSSL_X509_verify_cert");
423
424
    if (ctx == NULL || ctx->store == NULL || ctx->store->cm == NULL
425
         || ctx->current_cert == NULL || ctx->current_cert->derCert == NULL) {
426
        return WOLFSSL_FATAL_ERROR;
427
    }
428
429
    certs = ctx->store->certs;
430
    if (ctx->setTrustedSk != NULL) {
431
        certs = ctx->setTrustedSk;
432
    }
433
434
    if (certs == NULL &&
435
        wolfSSL_sk_X509_num(ctx->ctxIntermediates) > 0) {
436
        certsToUse = wolfSSL_sk_X509_new_null();
437
        ret = addAllButSelfSigned(certsToUse, ctx->ctxIntermediates, NULL);
438
    }
439
    else {
440
        /* Add the intermediates provided on init to the list of untrusted
441
         * intermediates to be used */
442
        ret = addAllButSelfSigned(certs, ctx->ctxIntermediates, &numInterAdd);
443
    }
444
    if (ret != WOLFSSL_SUCCESS) {
445
        goto exit;
446
    }
447
448
    if (ctx->chain != NULL) {
449
        wolfSSL_sk_X509_free(ctx->chain);
450
    }
451
    ctx->chain = wolfSSL_sk_X509_new_null();
452
453
    if (ctx->depth > 0) {
454
        depth = ctx->depth + 1;
455
    }
456
    else {
457
        depth = WOLFSSL_X509_STORE_DEFAULT_MAX_DEPTH + 1;
458
    }
459
460
    orig = ctx->current_cert;
461
    while(done == 0 && depth > 0) {
462
        issuer = NULL;
463
464
        /* Try to find an untrusted issuer first */
465
        ret = X509StoreGetIssuerEx(&issuer, certs,
466
                                               ctx->current_cert);
467
        if (ret == WOLFSSL_SUCCESS) {
468
            if (ctx->current_cert == issuer) {
469
                wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
470
                break;
471
            }
472
473
            /* We found our issuer in the non-trusted cert list, add it
474
             * to the CM and verify the current cert against it */
475
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
476
            /* OpenSSL doesn't allow the cert as CA if it is not CA:TRUE for
477
             * intermediate certs.
478
             */
479
            if (!issuer->isCa) {
480
                /* error depth is current depth + 1 */
481
                SetupStoreCtxError_ex(ctx, X509_V_ERR_INVALID_CA,
482
                                (ctx->chain) ? (int)(ctx->chain->num + 1) : 1);
483
                if (ctx->store->verify_cb) {
484
                    ret = ctx->store->verify_cb(0, ctx);
485
                    if (ret != WOLFSSL_SUCCESS) {
486
                        goto exit;
487
                    }
488
                }
489
            } else {
490
        #endif
491
            ret = X509StoreAddCa(ctx->store, issuer,
492
                                            WOLFSSL_TEMP_CA);
493
            if (ret != WOLFSSL_SUCCESS) {
494
                goto exit;
495
            }
496
            added = 1;
497
            ret = X509StoreVerifyCert(ctx);
498
            if (ret != WOLFSSL_SUCCESS) {
499
                goto exit;
500
            }
501
            /* Add it to the current chain and look at the issuer cert next */
502
            wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
503
        #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
504
            }
505
        #endif
506
            ctx->current_cert = issuer;
507
        }
508
        else if (ret == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
509
            /* Could not find in untrusted list, only place left is
510
             * a trusted CA in the CM */
511
            ret = X509StoreVerifyCert(ctx);
512
            if (ret != WOLFSSL_SUCCESS) {
513
                if (((ctx->flags & WOLFSSL_PARTIAL_CHAIN) ||
514
                     (ctx->store->param->flags & WOLFSSL_PARTIAL_CHAIN)) &&
515
                    (added == 1)) {
516
                    wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
517
                    ret = WOLFSSL_SUCCESS;
518
                }
519
                goto exit;
520
            }
521
522
            /* Cert verified, finish building the chain */
523
            wolfSSL_sk_X509_push(ctx->chain, ctx->current_cert);
524
            issuer = NULL;
525
    #ifdef WOLFSSL_SIGNER_DER_CERT
526
            x509GetIssuerFromCM(&issuer, ctx->store->cm, ctx->current_cert);
527
            if (issuer != NULL && ctx->owned != NULL) {
528
                wolfSSL_sk_X509_push(ctx->owned, issuer);
529
            }
530
    #else
531
            if (ctx->setTrustedSk == NULL) {
532
                X509StoreGetIssuerEx(&issuer,
533
                    ctx->store->trusted, ctx->current_cert);
534
            }
535
            else {
536
                X509StoreGetIssuerEx(&issuer,
537
                    ctx->setTrustedSk, ctx->current_cert);
538
            }
539
    #endif
540
            if (issuer != NULL) {
541
                wolfSSL_sk_X509_push(ctx->chain, issuer);
542
            }
543
544
            done = 1;
545
        }
546
        else {
547
            goto exit;
548
        }
549
550
        depth--;
551
    }
552
553
exit:
554
    /* Remove additional intermediates from init from the store */
555
    if (ctx != NULL && numInterAdd > 0) {
556
        for (i = 0; i < numInterAdd; i++) {
557
            wolfSSL_sk_X509_pop(ctx->store->certs);
558
        }
559
    }
560
    /* Remove intermediates that were added to CM */
561
    if (ctx != NULL) {
562
        if (ctx->store != NULL) {
563
            if (added == 1) {
564
                wolfSSL_CertManagerUnloadTempIntermediateCerts(ctx->store->cm);
565
            }
566
        }
567
        if (orig != NULL) {
568
            ctx->current_cert = orig;
569
        }
570
    }
571
    if (certsToUse != NULL) {
572
        wolfSSL_sk_X509_free(certsToUse);
573
    }
574
575
    return ret == WOLFSSL_SUCCESS ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
576
}
577
578
#endif /* OPENSSL_EXTRA */
579
580
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
581
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get_current_cert(
582
                                            WOLFSSL_X509_STORE_CTX* ctx)
583
{
584
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_current_cert");
585
    if (ctx)
586
        return ctx->current_cert;
587
    return NULL;
588
}
589
590
/* get X509_STORE_CTX ex_data, max idx is MAX_EX_DATA */
591
void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx)
592
{
593
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data");
594
#ifdef HAVE_EX_DATA
595
    if (ctx != NULL) {
596
        return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx);
597
    }
598
#else
599
    (void)ctx;
600
    (void)idx;
601
#endif
602
    return NULL;
603
}
604
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
605
606
607
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
608
    defined(WOLFSSL_EXTRA)
609
    int wolfSSL_X509_STORE_CTX_get_error(WOLFSSL_X509_STORE_CTX* ctx)
610
    {
611
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error");
612
        if (ctx != NULL)
613
            return ctx->error;
614
        return 0;
615
    }
616
617
    int wolfSSL_X509_STORE_CTX_get_error_depth(WOLFSSL_X509_STORE_CTX* ctx)
618
    {
619
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_error_depth");
620
        if (ctx)
621
            return ctx->error_depth;
622
        return WOLFSSL_FATAL_ERROR;
623
    }
624
#endif
625
626
#ifdef OPENSSL_EXTRA
627
    void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *ctx,
628
                                  WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
629
    {
630
        WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_verify_cb");
631
        if(ctx == NULL)
632
            return;
633
        ctx->verify_cb = verify_cb;
634
    }
635
636
/* Gets pointer to X509_STORE that was used to create context.
637
 *
638
 * Return valid pointer on success, NULL if ctx was NULL or not initialized
639
 */
640
WOLFSSL_X509_STORE* wolfSSL_X509_STORE_CTX_get0_store(
641
        WOLFSSL_X509_STORE_CTX* ctx)
642
{
643
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_store");
644
645
    if (ctx == NULL)
646
        return NULL;
647
648
    return ctx->store;
649
}
650
651
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_cert(WOLFSSL_X509_STORE_CTX* ctx)
652
{
653
    if (ctx == NULL)
654
        return NULL;
655
656
    return ctx->current_cert;
657
}
658
659
void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX* ctx,
660
                                    unsigned long flags,
661
                                    time_t t)
662
{
663
    (void)flags;
664
665
    if (ctx == NULL || ctx->param == NULL)
666
        return;
667
668
    ctx->param->check_time = t;
669
    ctx->param->flags |= WOLFSSL_USE_CHECK_TIME;
670
}
671
672
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
673
#ifndef NO_WOLFSSL_STUB
674
int wolfSSL_X509_STORE_CTX_set_purpose(WOLFSSL_X509_STORE_CTX *ctx,
675
                                       int purpose)
676
{
677
    (void)ctx;
678
    (void)purpose;
679
    WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_set_purpose (not implemented)");
680
    return 0;
681
}
682
#endif /* !NO_WOLFSSL_STUB */
683
684
#endif /* WOLFSSL_QT || OPENSSL_ALL */
685
#endif /* OPENSSL_EXTRA */
686
687
#ifdef OPENSSL_EXTRA
688
689
void wolfSSL_X509_STORE_CTX_set_flags(WOLFSSL_X509_STORE_CTX *ctx,
690
        unsigned long flags)
691
{
692
    if ((ctx != NULL) && (flags & WOLFSSL_PARTIAL_CHAIN)){
693
        ctx->flags |= WOLFSSL_PARTIAL_CHAIN;
694
    }
695
}
696
697
/* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
698
 * on success, WOLFSSL_FAILURE on error. */
699
int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx,
700
                                       void *data)
701
{
702
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data");
703
#ifdef HAVE_EX_DATA
704
    if (ctx != NULL)
705
    {
706
        return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
707
    }
708
#else
709
    (void)ctx;
710
    (void)idx;
711
    (void)data;
712
#endif
713
    return WOLFSSL_FAILURE;
714
}
715
716
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
717
/* set X509_STORE_CTX ex_data, max idx is MAX_EX_DATA. Return WOLFSSL_SUCCESS
718
 * on success, WOLFSSL_FAILURE on error. */
719
int wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup(
720
    WOLFSSL_X509_STORE_CTX* ctx,
721
    int idx,
722
    void *data,
723
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
724
{
725
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data_with_cleanup");
726
    if (ctx != NULL)
727
    {
728
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&ctx->ex_data, idx,
729
                                                        data, cleanup_routine);
730
    }
731
    return WOLFSSL_FAILURE;
732
}
733
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
734
735
#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL)
736
void wolfSSL_X509_STORE_CTX_set_depth(WOLFSSL_X509_STORE_CTX* ctx, int depth)
737
{
738
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_depth");
739
    if (ctx)
740
        ctx->depth = depth;
741
}
742
#endif
743
744
WOLFSSL_X509* wolfSSL_X509_STORE_CTX_get0_current_issuer(
745
        WOLFSSL_X509_STORE_CTX* ctx)
746
{
747
    WOLFSSL_STACK* node;
748
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get0_current_issuer");
749
750
    if (ctx == NULL)
751
        return NULL;
752
753
    /* get0 only checks currently built chain */
754
    if (ctx->chain != NULL) {
755
        for (node = ctx->chain; node != NULL; node = node->next) {
756
            if (wolfSSL_X509_check_issued(node->data.x509,
757
                                          ctx->current_cert) ==
758
                                                WOLFSSL_X509_V_OK) {
759
                return node->data.x509;
760
            }
761
        }
762
    }
763
764
    return NULL;
765
}
766
767
/* Set an error stat in the X509 STORE CTX
768
 *
769
 */
770
void wolfSSL_X509_STORE_CTX_set_error(WOLFSSL_X509_STORE_CTX* ctx, int er)
771
{
772
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error");
773
774
    if (ctx != NULL) {
775
        ctx->error = er;
776
    }
777
}
778
779
/* Set the error depth in the X509 STORE CTX */
780
void wolfSSL_X509_STORE_CTX_set_error_depth(WOLFSSL_X509_STORE_CTX* ctx,
781
                                                                    int depth)
782
{
783
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_error_depth");
784
785
    if (ctx != NULL) {
786
        ctx->error_depth = depth;
787
    }
788
}
789
790
WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx)
791
{
792
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_chain");
793
794
    if (ctx == NULL) {
795
        return NULL;
796
    }
797
798
#ifdef SESSION_CERTS
799
    /* if chain is null but sesChain is available then populate stack */
800
    if (ctx->chain == NULL && ctx->sesChain != NULL) {
801
        int i;
802
        int error = 0;
803
        WOLFSSL_X509_CHAIN* c = ctx->sesChain;
804
        WOLFSSL_STACK*     sk = wolfSSL_sk_new_node(ctx->heap);
805
806
        if (sk == NULL)
807
            return NULL;
808
809
        for (i = 0; i < c->count; i++) {
810
            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i);
811
812
            if (x509 == NULL) {
813
                WOLFSSL_MSG("Unable to get x509 from chain");
814
                error = 1;
815
                break;
816
            }
817
818
            if (wolfSSL_sk_X509_push(sk, x509) <= 0) {
819
                WOLFSSL_MSG("Unable to load x509 into stack");
820
                wolfSSL_X509_free(x509);
821
                x509 = NULL;
822
                error = 1;
823
                break;
824
            }
825
        }
826
827
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
828
    defined(OPENSSL_EXTRA)
829
        /* add CA used to verify top of chain to the list */
830
        if (!error && c->count > 0) {
831
            WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1);
832
            WOLFSSL_X509* issuer = NULL;
833
            if (x509 != NULL) {
834
                if (wolfSSL_X509_STORE_CTX_get1_issuer(&issuer, ctx, x509)
835
                        == WOLFSSL_SUCCESS) {
836
                    /* check that the certificate being looked up is not self
837
                     * signed and that a issuer was found */
838
                    if (issuer != NULL && wolfSSL_X509_NAME_cmp(&x509->issuer,
839
                                &x509->subject) != 0) {
840
                        if (wolfSSL_sk_X509_push(sk, issuer) <= 0) {
841
                            WOLFSSL_MSG("Unable to load CA x509 into stack");
842
                            error = 1;
843
                            wolfSSL_X509_free(issuer);
844
                            issuer = NULL;
845
                        }
846
                    }
847
                    else {
848
                        WOLFSSL_MSG("Certificate is self signed");
849
                        wolfSSL_X509_free(issuer);
850
                        issuer = NULL;
851
                    }
852
                }
853
                else {
854
                    WOLFSSL_MSG("Could not find CA for certificate");
855
                }
856
            }
857
            wolfSSL_X509_free(x509);
858
            x509 = NULL;
859
        }
860
#endif
861
        if (error) {
862
            wolfSSL_sk_X509_pop_free(sk, NULL);
863
            return NULL;
864
        }
865
        ctx->chain = sk;
866
    }
867
#endif /* SESSION_CERTS */
868
869
    return ctx->chain;
870
}
871
872
/* like X509_STORE_CTX_get_chain(), but return a copy with data reference
873
   counts increased */
874
WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain(WOLFSSL_X509_STORE_CTX* ctx)
875
{
876
    WOLFSSL_STACK* ref;
877
878
    if (ctx == NULL) {
879
        return NULL;
880
    }
881
882
    /* get chain in ctx */
883
    ref = wolfSSL_X509_STORE_CTX_get_chain(ctx);
884
    if (ref == NULL) {
885
        return ref;
886
    }
887
888
    /* create duplicate of ctx chain */
889
    return wolfSSL_sk_dup(ref);
890
}
891
892
#ifndef NO_WOLFSSL_STUB
893
WOLFSSL_X509_STORE_CTX *wolfSSL_X509_STORE_CTX_get0_parent_ctx(
894
                                                   WOLFSSL_X509_STORE_CTX *ctx)
895
{
896
    (void)ctx;
897
    WOLFSSL_STUB("wolfSSL_X509_STORE_CTX_get0_parent_ctx");
898
    return NULL;
899
}
900
901
int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, int idx,
902
                            WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj)
903
{
904
    (void)ctx;
905
    (void)idx;
906
    (void)name;
907
    (void)obj;
908
    WOLFSSL_STUB("X509_STORE_get_by_subject");
909
    return 0;
910
}
911
#endif
912
913
WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_CTX_get0_param(
914
        WOLFSSL_X509_STORE_CTX *ctx)
915
{
916
    if (ctx == NULL)
917
        return NULL;
918
919
    return ctx->param;
920
}
921
922
#endif /* OPENSSL_EXTRA */
923
924
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
925
#if defined(WOLFSSL_SIGNER_DER_CERT)
926
WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs(
927
    WOLFSSL_X509_STORE_CTX* ctx, WOLFSSL_X509_NAME* name)
928
{
929
    WOLF_STACK_OF(WOLFSSL_X509)* ret = NULL;
930
    int err = 0;
931
    WOLFSSL_X509_STORE* store = NULL;
932
    WOLFSSL_STACK* sk = NULL;
933
    WOLFSSL_STACK* certToFilter = NULL;
934
    WOLFSSL_X509_NAME* certToFilterName = NULL;
935
    WOLF_STACK_OF(WOLFSSL_X509)* filteredCerts = NULL;
936
    WOLFSSL_X509* filteredCert = NULL;
937
938
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get1_certs");
939
940
    if (name == NULL) {
941
        err = 1;
942
    }
943
944
    if (err == 0) {
945
        store = wolfSSL_X509_STORE_CTX_get0_store(ctx);
946
        if (store == NULL) {
947
            err = 1;
948
        }
949
    }
950
951
    if (err == 0) {
952
        filteredCerts = wolfSSL_sk_X509_new_null();
953
        if (filteredCerts == NULL) {
954
            err = 1;
955
        }
956
    }
957
958
    if (err == 0) {
959
        sk = wolfSSL_CertManagerGetCerts(store->cm);
960
        if (sk == NULL) {
961
            err = 1;
962
        }
963
    }
964
965
    if (err == 0) {
966
        certToFilter = sk;
967
        while (certToFilter != NULL) {
968
            certToFilterName = wolfSSL_X509_get_subject_name(
969
                                    certToFilter->data.x509);
970
            if (certToFilterName != NULL) {
971
                if (wolfSSL_X509_NAME_cmp(certToFilterName, name) == 0) {
972
                    filteredCert = wolfSSL_X509_dup(certToFilter->data.x509);
973
                    if (filteredCert == NULL ||
974
                            wolfSSL_sk_X509_push(filteredCerts, filteredCert)
975
                                <= 0) {
976
                        err = 1;
977
                        wolfSSL_X509_free(filteredCert);
978
                        filteredCert = NULL;
979
                        break;
980
                    }
981
                }
982
            }
983
            certToFilter = certToFilter->next;
984
        }
985
    }
986
987
    if (err == 1) {
988
        if (filteredCerts != NULL) {
989
            wolfSSL_sk_X509_pop_free(filteredCerts, NULL);
990
        }
991
        ret = NULL;
992
    }
993
    else {
994
        ret = filteredCerts;
995
    }
996
997
    if (sk != NULL) {
998
        wolfSSL_sk_X509_pop_free(sk, NULL);
999
    }
1000
1001
    return ret;
1002
}
1003
#endif /* WOLFSSL_SIGNER_DER_CERT */
1004
1005
#endif /* OPENSSL_EXTRA && !NO_FILESYSTEM */
1006
1007
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
1008
    defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
1009
int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
1010
    WOLFSSL_X509_STORE_CTX *ctx, WOLFSSL_X509 *x)
1011
{
1012
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1013
    WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get1_issuer");
1014
1015
    if (issuer == NULL || ctx == NULL || x == NULL)
1016
        return WOLFSSL_FATAL_ERROR;
1017
1018
    ret = X509StoreGetIssuerEx(issuer, ctx->store->certs, x);
1019
    if ((ret == WOLFSSL_SUCCESS) && (*issuer != NULL)) {
1020
        return wolfSSL_X509_up_ref(*issuer);
1021
    }
1022
1023
#ifdef WOLFSSL_SIGNER_DER_CERT
1024
    ret = x509GetIssuerFromCM(issuer, ctx->store->cm, x);
1025
#else
1026
    ret = X509StoreGetIssuerEx(issuer, ctx->store->trusted, x);
1027
    if ((ret == WOLFSSL_SUCCESS) && (*issuer != NULL)) {
1028
        return wolfSSL_X509_up_ref(*issuer);
1029
    }
1030
#endif
1031
1032
    return ret;
1033
}
1034
#endif /* WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || OPENSSL_ALL */
1035
1036
#ifdef OPENSSL_EXTRA
1037
1038
static int X509StoreGetIssuerEx(WOLFSSL_X509 **issuer,
1039
                            WOLFSSL_STACK * certs, WOLFSSL_X509 *x)
1040
{
1041
    int i;
1042
1043
    if (issuer == NULL || x == NULL)
1044
        return WOLFSSL_FATAL_ERROR;
1045
1046
    if (certs != NULL) {
1047
        for (i = 0; i < wolfSSL_sk_X509_num(certs); i++) {
1048
            if (wolfSSL_X509_check_issued(
1049
                    wolfSSL_sk_X509_value(certs, i), x) ==
1050
                    WOLFSSL_X509_V_OK) {
1051
                *issuer = wolfSSL_sk_X509_value(certs, i);
1052
                return WOLFSSL_SUCCESS;
1053
            }
1054
        }
1055
    }
1056
1057
    return WOLFSSL_FAILURE;
1058
}
1059
1060
#endif
1061
1062
/******************************************************************************
1063
 * END OF X509_STORE_CTX APIs
1064
 *****************************************************************************/
1065
1066
/******************************************************************************
1067
 * START OF X509_STORE APIs
1068
 *****************************************************************************/
1069
1070
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
1071
    defined(WOLFSSL_WPAS_SMALL)
1072
WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void)
1073
{
1074
    int ret;
1075
    WOLFSSL_X509_STORE* store = NULL;
1076
    WOLFSSL_ENTER("wolfSSL_X509_STORE_new");
1077
1078
    if ((store = (WOLFSSL_X509_STORE*)XMALLOC(sizeof(WOLFSSL_X509_STORE), NULL,
1079
                                    DYNAMIC_TYPE_X509_STORE)) == NULL)
1080
        goto err_exit;
1081
1082
    XMEMSET(store, 0, sizeof(WOLFSSL_X509_STORE));
1083
    store->isDynamic = 1;
1084
1085
    wolfSSL_RefInit(&store->ref, &ret);
1086
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
1087
    if (ret != 0)
1088
        goto err_exit;
1089
#else
1090
    (void)ret;
1091
#endif
1092
1093
    if ((store->cm = wolfSSL_CertManagerNew()) == NULL)
1094
        goto err_exit;
1095
1096
#ifdef OPENSSL_EXTRA
1097
    if ((store->certs = wolfSSL_sk_X509_new_null()) == NULL)
1098
        goto err_exit;
1099
1100
    if ((store->owned = wolfSSL_sk_X509_new_null()) == NULL)
1101
        goto err_exit;
1102
1103
    if ((store->trusted = wolfSSL_sk_X509_new_null()) == NULL)
1104
        goto err_exit;
1105
#endif
1106
1107
#ifdef HAVE_CRL
1108
    store->crl = store->cm->crl;
1109
#endif
1110
1111
    store->numAdded = 0;
1112
1113
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1114
1115
    /* Link store's new Certificate Manager to self by default */
1116
    store->cm->x509_store_p = store;
1117
1118
    if ((store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC(
1119
                           sizeof(WOLFSSL_X509_VERIFY_PARAM),
1120
                           NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
1121
        goto err_exit;
1122
    }
1123
    XMEMSET(store->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM));
1124
    if ((store->lookup.dirs = (WOLFSSL_BY_DIR*)XMALLOC(sizeof(WOLFSSL_BY_DIR),
1125
                           NULL, DYNAMIC_TYPE_OPENSSL)) == NULL) {
1126
        WOLFSSL_MSG("store->lookup.dir memory allocation error");
1127
        goto err_exit;
1128
    }
1129
    XMEMSET(store->lookup.dirs, 0, sizeof(WOLFSSL_BY_DIR));
1130
    if (wc_InitMutex(&store->lookup.dirs->lock) != 0) {
1131
            WOLFSSL_MSG("Bad mutex init");
1132
            goto err_exit;
1133
    }
1134
#endif
1135
1136
    return store;
1137
1138
err_exit:
1139
    if (store == NULL)
1140
        return NULL;
1141
1142
    wolfSSL_X509_STORE_free(store);
1143
1144
    return NULL;
1145
}
1146
1147
#ifdef OPENSSL_ALL
1148
static void X509StoreFreeObjList(WOLFSSL_X509_STORE* store,
1149
                  WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* objs)
1150
{
1151
    int i;
1152
    WOLFSSL_X509_OBJECT *obj = NULL;
1153
    int cnt = store->numAdded;
1154
1155
    /* -1 here because it is later used as an index value into the object stack.
1156
     * With there being the chance that the only object in the stack is one from
1157
     * the numAdded to the store >= is used when comparing to 0. */
1158
    i = wolfSSL_sk_X509_OBJECT_num(objs) - 1;
1159
    while (cnt > 0 && i >= 0) {
1160
        /* The inner X509 is owned by somebody else, NULL out the reference */
1161
        obj = (WOLFSSL_X509_OBJECT *)wolfSSL_sk_X509_OBJECT_value(objs, i);
1162
        if (obj != NULL) {
1163
            obj->type = (WOLFSSL_X509_LOOKUP_TYPE)0;
1164
            obj->data.ptr = NULL;
1165
        }
1166
        cnt--;
1167
        i--;
1168
    }
1169
1170
    wolfSSL_sk_X509_OBJECT_pop_free(objs, NULL);
1171
}
1172
#endif
1173
1174
void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store)
1175
{
1176
    int doFree = 0;
1177
    if (store != NULL && store->isDynamic) {
1178
        int ret;
1179
        wolfSSL_RefDec(&store->ref, &doFree, &ret);
1180
    #ifdef WOLFSSL_REFCNT_ERROR_RETURN
1181
        if (ret != 0) {
1182
            WOLFSSL_MSG("Couldn't lock store mutex");
1183
        }
1184
    #else
1185
        (void)ret;
1186
    #endif
1187
1188
        if (doFree) {
1189
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1190
            wolfSSL_CRYPTO_cleanup_ex_data(&store->ex_data);
1191
#endif
1192
            if (store->cm != NULL) {
1193
                wolfSSL_CertManagerFree(store->cm);
1194
                store->cm = NULL;
1195
            }
1196
#if defined(OPENSSL_EXTRA)
1197
            if (store->certs != NULL) {
1198
                wolfSSL_sk_X509_pop_free(store->certs, NULL);
1199
                store->certs = NULL;
1200
            }
1201
            if (store->owned != NULL) {
1202
                wolfSSL_sk_X509_pop_free(store->owned, NULL);
1203
                store->owned = NULL;
1204
            }
1205
            if (store->trusted != NULL) {
1206
                wolfSSL_sk_X509_pop_free(store->trusted, NULL);
1207
                store->trusted = NULL;
1208
            }
1209
#endif
1210
#ifdef OPENSSL_ALL
1211
            if (store->objs != NULL) {
1212
                X509StoreFreeObjList(store, store->objs);
1213
            }
1214
#endif
1215
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
1216
            XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL);
1217
            store->param = NULL;
1218
1219
            if (store->lookup.dirs != NULL) {
1220
#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1221
                if (store->lookup.dirs->dir_entry) {
1222
                    wolfSSL_sk_BY_DIR_entry_free(
1223
                        store->lookup.dirs->dir_entry);
1224
                }
1225
#endif
1226
                wc_FreeMutex(&store->lookup.dirs->lock);
1227
                XFREE(store->lookup.dirs, NULL, DYNAMIC_TYPE_OPENSSL);
1228
                store->lookup.dirs = NULL;
1229
            }
1230
#endif
1231
            wolfSSL_RefFree(&store->ref);
1232
            XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE);
1233
        }
1234
    }
1235
}
1236
1237
/**
1238
 * Get ex_data in WOLFSSL_STORE at given index
1239
 * @param store a pointer to WOLFSSL_X509_STORE structure
1240
 * @param idx   Index of ex_data to get data from
1241
 * @return void pointer to ex_data on success or NULL on failure
1242
 */
1243
void* wolfSSL_X509_STORE_get_ex_data(WOLFSSL_X509_STORE* store, int idx)
1244
{
1245
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get_ex_data");
1246
#ifdef HAVE_EX_DATA
1247
    if (store != NULL && idx < MAX_EX_DATA && idx >= 0) {
1248
        return wolfSSL_CRYPTO_get_ex_data(&store->ex_data, idx);
1249
    }
1250
#else
1251
    (void)store;
1252
    (void)idx;
1253
#endif
1254
    return NULL;
1255
}
1256
1257
int wolfSSL_X509_STORE_up_ref(WOLFSSL_X509_STORE* store)
1258
{
1259
    if (store) {
1260
        int ret;
1261
        wolfSSL_RefInc(&store->ref, &ret);
1262
    #ifdef WOLFSSL_REFCNT_ERROR_RETURN
1263
        if (ret != 0) {
1264
            WOLFSSL_MSG("Failed to lock store mutex");
1265
            return WOLFSSL_FAILURE;
1266
        }
1267
    #else
1268
        (void)ret;
1269
    #endif
1270
1271
        return WOLFSSL_SUCCESS;
1272
    }
1273
1274
    return WOLFSSL_FAILURE;
1275
}
1276
1277
/**
1278
 * Set ex_data for WOLFSSL_STORE
1279
 * @param store a pointer to WOLFSSL_X509_STORE structure
1280
 * @param idx   Index of ex data to set
1281
 * @param data  Data to set in ex data
1282
 * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
1283
 */
1284
int wolfSSL_X509_STORE_set_ex_data(WOLFSSL_X509_STORE* store, int idx,
1285
                                                                void *data)
1286
{
1287
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data");
1288
#ifdef HAVE_EX_DATA
1289
    if (store != NULL && idx < MAX_EX_DATA) {
1290
        return wolfSSL_CRYPTO_set_ex_data(&store->ex_data, idx, data);
1291
    }
1292
#else
1293
    (void)store;
1294
    (void)idx;
1295
    (void)data;
1296
#endif
1297
    return WOLFSSL_FAILURE;
1298
}
1299
1300
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
1301
/**
1302
 * Set ex_data for WOLFSSL_STORE
1303
 * @param store a pointer to WOLFSSL_X509_STORE structure
1304
 * @param idx   Index of ex data to set
1305
 * @param data  Data to set in ex data
1306
 * @return WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE on failure
1307
 */
1308
int wolfSSL_X509_STORE_set_ex_data_with_cleanup(
1309
    WOLFSSL_X509_STORE* store,
1310
    int idx,
1311
    void *data,
1312
    wolfSSL_ex_data_cleanup_routine_t cleanup_routine)
1313
{
1314
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_ex_data_with_cleanup");
1315
    if (store != NULL && idx < MAX_EX_DATA) {
1316
        return wolfSSL_CRYPTO_set_ex_data_with_cleanup(&store->ex_data, idx,
1317
                                                       data, cleanup_routine);
1318
    }
1319
    return WOLFSSL_FAILURE;
1320
}
1321
1322
#endif /* HAVE_EX_DATA_CLEANUP_HOOKS */
1323
1324
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER || WOLFSSL_WPAS_SMALL */
1325
1326
#ifdef OPENSSL_EXTRA
1327
1328
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL)
1329
void wolfSSL_X509_STORE_set_verify_cb(WOLFSSL_X509_STORE *st,
1330
        WOLFSSL_X509_STORE_CTX_verify_cb verify_cb)
1331
{
1332
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_verify_cb");
1333
    if (st != NULL) {
1334
        st->verify_cb = verify_cb;
1335
    }
1336
}
1337
1338
void wolfSSL_X509_STORE_set_get_crl(WOLFSSL_X509_STORE *st,
1339
        WOLFSSL_X509_STORE_CTX_get_crl_cb get_cb)
1340
{
1341
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_get_crl");
1342
    if (st != NULL) {
1343
        st->get_crl_cb = get_cb;
1344
    }
1345
}
1346
1347
#ifndef NO_WOLFSSL_STUB
1348
void wolfSSL_X509_STORE_set_check_crl(WOLFSSL_X509_STORE *st,
1349
        WOLFSSL_X509_STORE_CTX_check_crl_cb check_crl)
1350
{
1351
    (void)st;
1352
    (void)check_crl;
1353
    WOLFSSL_STUB("wolfSSL_X509_STORE_set_check_crl (not implemented)");
1354
}
1355
#endif
1356
#endif /* WOLFSSL_QT || OPENSSL_ALL */
1357
1358
WOLFSSL_X509_LOOKUP* wolfSSL_X509_STORE_add_lookup(WOLFSSL_X509_STORE* store,
1359
                                               WOLFSSL_X509_LOOKUP_METHOD* m)
1360
{
1361
    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_lookup");
1362
    if (store == NULL || m == NULL)
1363
        return NULL;
1364
1365
    /* Make sure the lookup has a back reference to the store. */
1366
    store->lookup.store = store;
1367
    /* store a type to know which method wants to be used for */
1368
    store->lookup.type = m->type;
1369
    return &store->lookup;
1370
}
1371
1372
static int X509StoreAddCa(WOLFSSL_X509_STORE* store,
1373
                                          WOLFSSL_X509* x509, int type)
1374
{
1375
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1376
    DerBuffer* derCert = NULL;
1377
1378
    WOLFSSL_ENTER("X509StoreAddCa");
1379
    if (store != NULL && x509 != NULL && x509->derCert != NULL) {
1380
        result = AllocDer(&derCert, x509->derCert->length,
1381
            x509->derCert->type, NULL);
1382
        if (result == 0) {
1383
            /* AddCA() frees the buffer. */
1384
            XMEMCPY(derCert->buffer,
1385
                            x509->derCert->buffer, x509->derCert->length);
1386
            result = AddCA(store->cm, &derCert, type, VERIFY);
1387
        }
1388
    }
1389
1390
    return result;
1391
}
1392
1393
1394
int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509)
1395
{
1396
    int result = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
1397
1398
    WOLFSSL_ENTER("wolfSSL_X509_STORE_add_cert");
1399
    if (store != NULL && store->cm != NULL && x509 != NULL
1400
                                                && x509->derCert != NULL) {
1401
        /* Mimic the openssl behavior, must be self signed to be considered
1402
         * trusted, addCA() internals will do additional checks for
1403
         * CA=TRUE */
1404
        if (wolfSSL_X509_NAME_cmp(&x509->issuer, &x509->subject) == 0) {
1405
            result = X509StoreAddCa(store, x509, WOLFSSL_USER_CA);
1406
            if (result == WOLFSSL_SUCCESS && store->trusted != NULL) {
1407
                result = wolfSSL_X509_up_ref(x509);
1408
                if (result == WOLFSSL_SUCCESS) {
1409
                    result = wolfSSL_sk_X509_push(store->trusted, x509);
1410
                    if (result > 0) {
1411
                        result = WOLFSSL_SUCCESS;
1412
                    }
1413
                    else {
1414
                        result = WOLFSSL_FATAL_ERROR;
1415
                        wolfSSL_X509_free(x509);
1416
                        x509 = NULL;
1417
                    }
1418
                }
1419
            }
1420
        }
1421
        else {
1422
            if (store->certs != NULL) {
1423
                result = wolfSSL_X509_up_ref(x509);
1424
                if (result == WOLFSSL_SUCCESS) {
1425
                    result = wolfSSL_sk_X509_push(store->certs, x509);
1426
                    if (result > 0) {
1427
                        result = WOLFSSL_SUCCESS;
1428
                    }
1429
                    else {
1430
                        result = WOLFSSL_FATAL_ERROR;
1431
                        wolfSSL_X509_free(x509);
1432
                        x509 = NULL;
1433
                    }
1434
                }
1435
            }
1436
            else {
1437
                /* If store->certs is NULL, this is an X509_STORE managed by an
1438
                 * SSL_CTX, preserve behavior and always add as USER_CA */
1439
                result = X509StoreAddCa(
1440
                            store, x509, WOLFSSL_USER_CA);
1441
            }
1442
        }
1443
    }
1444
1445
    WOLFSSL_LEAVE("wolfSSL_X509_STORE_add_cert", result);
1446
1447
    if (result != WOLFSSL_SUCCESS) {
1448
        result = WOLFSSL_FATAL_ERROR;
1449
    }
1450
1451
    return result;
1452
}
1453
1454
int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag)
1455
{
1456
    int ret = WOLFSSL_SUCCESS;
1457
1458
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_flags");
1459
1460
    if (store == NULL)
1461
        return WOLFSSL_FAILURE;
1462
1463
    if ((flag & WOLFSSL_CRL_CHECKALL) || (flag & WOLFSSL_CRL_CHECK)) {
1464
        ret = wolfSSL_CertManagerEnableCRL(store->cm, (int)flag);
1465
    }
1466
#if defined(OPENSSL_COMPATIBLE_DEFAULTS)
1467
    else if (flag == 0) {
1468
        ret = wolfSSL_CertManagerDisableCRL(store->cm);
1469
    }
1470
#endif
1471
    if (flag & WOLFSSL_PARTIAL_CHAIN) {
1472
        store->param->flags |= WOLFSSL_PARTIAL_CHAIN;
1473
    }
1474
    return ret;
1475
}
1476
1477
int X509StoreLoadCertBuffer(WOLFSSL_X509_STORE *str,
1478
                                        byte *buf, word32 bufLen, int type)
1479
{
1480
    int ret = WOLFSSL_SUCCESS;
1481
    WOLFSSL_X509 *x509 = NULL;
1482
1483
    if (str == NULL || buf == NULL) {
1484
        return WOLFSSL_FAILURE;
1485
    }
1486
1487
    /* OpenSSL X509_STORE_load_file fails on DER file, we will as well */
1488
    x509 = wolfSSL_X509_load_certificate_buffer(buf, bufLen, type);
1489
    if (x509 != NULL) {
1490
        ret = wolfSSL_X509_STORE_add_cert(str, x509);
1491
        if (ret != WOLFSSL_SUCCESS) {
1492
            WOLFSSL_MSG("Failed to load file");
1493
            ret = WOLFSSL_FAILURE;
1494
        }
1495
        if (ret == WOLFSSL_SUCCESS && str->owned != NULL) {
1496
            if (wolfSSL_sk_X509_push(str->owned, x509) <= 0) {
1497
                ret = WOLFSSL_FAILURE;
1498
            }
1499
            else {
1500
                x509 = NULL;
1501
            }
1502
        }
1503
        wolfSSL_X509_free(x509);
1504
        x509 = NULL;
1505
    }
1506
    else {
1507
        ret = WOLFSSL_FAILURE;
1508
    }
1509
1510
    return ret;
1511
}
1512
1513
#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
1514
1515
static int X509StoreReadFile(const char *fname,
1516
                StaticBuffer *content, word32 *bytesRead, int *type)
1517
{
1518
    int ret = -1;
1519
    long sz = 0;
1520
#ifdef HAVE_CRL
1521
    const char* header = NULL;
1522
    const char* footer = NULL;
1523
#endif
1524
1525
    ret = wolfssl_read_file_static(fname, content, NULL, DYNAMIC_TYPE_FILE,
1526
        &sz);
1527
    if (ret == 0) {
1528
        *type = CERT_TYPE;
1529
        *bytesRead = (word32)sz;
1530
#ifdef HAVE_CRL
1531
        /* Look for CRL header and footer. */
1532
        if (wc_PemGetHeaderFooter(CRL_TYPE, &header, &footer) == 0 &&
1533
                (XSTRNSTR((char*)content->buffer, header, (word32)sz) !=
1534
                    NULL)) {
1535
            *type = CRL_TYPE;
1536
        }
1537
#endif
1538
    }
1539
1540
    return (ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE);
1541
}
1542
1543
static int X509StoreLoadFile(WOLFSSL_X509_STORE *str,
1544
                                        const char *fname)
1545
{
1546
    int ret = WOLFSSL_SUCCESS;
1547
    int type = 0;
1548
#ifndef WOLFSSL_SMALL_STACK
1549
    byte   stackBuffer[FILE_BUFFER_SIZE];
1550
#endif
1551
    StaticBuffer content;
1552
    word32 contentLen = 0;
1553
1554
#ifdef WOLFSSL_SMALL_STACK
1555
    static_buffer_init(&content);
1556
#else
1557
    static_buffer_init(&content, stackBuffer, FILE_BUFFER_SIZE);
1558
#endif
1559
1560
    WOLFSSL_MSG_EX("X509StoreLoadFile: Loading file: %s", fname);
1561
1562
    ret = X509StoreReadFile(fname, &content, &contentLen, &type);
1563
    if (ret != WOLFSSL_SUCCESS) {
1564
        WOLFSSL_MSG("Failed to load file");
1565
        ret = WOLFSSL_FAILURE;
1566
    }
1567
1568
    if ((ret == WOLFSSL_SUCCESS) && (type == CERT_TYPE)) {
1569
        ret = X509StoreLoadCertBuffer(str, content.buffer,
1570
                                        contentLen, WOLFSSL_FILETYPE_PEM);
1571
    }
1572
#ifdef HAVE_CRL
1573
    else if ((ret == WOLFSSL_SUCCESS) && (type == CRL_TYPE)) {
1574
        ret = BufferLoadCRL(str->cm->crl, content.buffer, contentLen,
1575
                                        WOLFSSL_FILETYPE_PEM, 0);
1576
    }
1577
#endif
1578
1579
    static_buffer_free(&content, NULL, DYNAMIC_TYPE_FILE);
1580
    return ret;
1581
}
1582
1583
/* Loads certificate(s) files in pem format into X509_STORE struct from either
1584
 * a file or directory.
1585
 * Returns WOLFSSL_SUCCESS on success or WOLFSSL_FAILURE if an error occurs.
1586
 */
1587
int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str,
1588
                                            const char *file, const char *dir)
1589
{
1590
    WOLFSSL_CTX* ctx;
1591
    char *name = NULL;
1592
    int ret = WOLFSSL_SUCCESS;
1593
#ifdef WOLFSSL_SMALL_STACK
1594
    ReadDirCtx* readCtx = NULL;
1595
#else
1596
    ReadDirCtx  readCtx[1];
1597
#endif
1598
1599
    WOLFSSL_ENTER("wolfSSL_X509_STORE_load_locations");
1600
1601
    if (str == NULL || str->cm == NULL || (file == NULL  && dir == NULL))
1602
        return WOLFSSL_FAILURE;
1603
1604
    /* tmp ctx for setting our cert manager */
1605
    ctx = wolfSSL_CTX_new_ex(cm_pick_method(str->cm->heap), str->cm->heap);
1606
    if (ctx == NULL)
1607
        return WOLFSSL_FAILURE;
1608
1609
    wolfSSL_CertManagerFree(ctx->cm);
1610
    ctx->cm = str->cm;
1611
1612
#ifdef HAVE_CRL
1613
    if (str->cm->crl == NULL) {
1614
        /* Workaround to allocate the internals to load CRL's but don't enable
1615
         * CRL checking by default */
1616
        if (wolfSSL_CertManagerEnableCRL(str->cm, WOLFSSL_CRL_CHECK)
1617
                != WOLFSSL_SUCCESS ||
1618
                wolfSSL_CertManagerDisableCRL(str->cm) != WOLFSSL_SUCCESS) {
1619
            WOLFSSL_MSG("Enable CRL failed");
1620
            wolfSSL_CTX_free(ctx);
1621
            return WOLFSSL_FAILURE;
1622
        }
1623
    }
1624
#endif
1625
1626
    /* Load individual file */
1627
    if (file) {
1628
        ret = X509StoreLoadFile(str, file);
1629
        if (ret != WOLFSSL_SUCCESS) {
1630
            WOLFSSL_MSG("Failed to load file");
1631
            ret = WOLFSSL_FAILURE;
1632
        }
1633
    }
1634
1635
    /* Load files in dir */
1636
    if (dir && ret == WOLFSSL_SUCCESS) {
1637
        int successes = 0;
1638
1639
        #ifdef WOLFSSL_SMALL_STACK
1640
            readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
1641
                                                    DYNAMIC_TYPE_TMP_BUFFER);
1642
            if (readCtx == NULL) {
1643
                WOLFSSL_MSG("Memory error");
1644
                wolfSSL_CTX_free(ctx);
1645
                return WOLFSSL_FAILURE;
1646
            }
1647
        #endif
1648
1649
        /* try to load each regular file in dir */
1650
        ret = wc_ReadDirFirst(readCtx, dir, &name);
1651
        while (ret == 0 && name) {
1652
            WOLFSSL_MSG(name);
1653
1654
            ret = X509StoreLoadFile(str, name);
1655
            /* Not failing on load errors */
1656
            if (ret != WOLFSSL_SUCCESS)
1657
                WOLFSSL_MSG("Failed to load file in path, continuing");
1658
            else
1659
                successes++;
1660
1661
            ret = wc_ReadDirNext(readCtx, dir, &name);
1662
        }
1663
        wc_ReadDirClose(readCtx);
1664
1665
        /* Success if at least one file in dir was loaded */
1666
        if (successes > 0)
1667
            ret = WOLFSSL_SUCCESS;
1668
        else {
1669
            WOLFSSL_ERROR(ret);
1670
            ret = WOLFSSL_FAILURE;
1671
        }
1672
1673
        #ifdef WOLFSSL_SMALL_STACK
1674
            XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
1675
        #endif
1676
    }
1677
1678
    ctx->cm = NULL;
1679
    wolfSSL_CTX_free(ctx);
1680
1681
    return ret;
1682
}
1683
1684
#if defined(XGETENV) && !defined(NO_GETENV)
1685
int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE *str)
1686
{
1687
    int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
1688
    char* certDir = NULL;
1689
    char* certFile = NULL;
1690
1691
    WOLFSSL_ENTER("wolfSSL_X509_STORE_set_default_paths");
1692
1693
    certFile = wc_strdup_ex(XGETENV("SSL_CERT_FILE"), DYNAMIC_TYPE_TMP_BUFFER);
1694
    certDir = wc_strdup_ex(XGETENV("SSL_CERT_DIR"), DYNAMIC_TYPE_TMP_BUFFER);
1695
1696
    ret = wolfSSL_X509_STORE_load_locations(str, certFile, certDir);
1697
1698
    XFREE(certFile, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1699
    XFREE(certDir, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1700
    return ret;
1701
}
1702
#endif /* XGETENV && !NO_GETENV */
1703
1704
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
1705
1706
int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store)
1707
{
1708
    int cnt_ret = 0;
1709
    Signer **table;
1710
1711
    WOLFSSL_ENTER("wolfSSL_X509_CA_num");
1712
    if (store == NULL || store->cm == NULL){
1713
        WOLFSSL_MSG("invalid parameter");
1714
        return WOLFSSL_FAILURE;
1715
    }
1716
1717
    table = store->cm->caTable;
1718
    if (table || (store->certs != NULL)){
1719
        if (wc_LockMutex(&store->cm->caLock) == 0){
1720
            if (table) {
1721
                int i = 0;
1722
                for (i = 0; i < CA_TABLE_SIZE; i++) {
1723
                    Signer* signer = table[i];
1724
                    while (signer) {
1725
                        Signer* next = signer->next;
1726
                        cnt_ret++;
1727
                        signer = next;
1728
                    }
1729
                }
1730
            }
1731
1732
            if (store->certs != NULL) {
1733
                cnt_ret += wolfSSL_sk_X509_num(store->certs);
1734
            }
1735
            wc_UnLockMutex(&store->cm->caLock);
1736
        }
1737
    }
1738
1739
    return cnt_ret;
1740
}
1741
1742
/******************************************************************************
1743
* wolfSSL_X509_STORE_GetCerts - retrieve stack of X509 in a certificate
1744
*                               store ctx
1745
*
1746
* This API can be used in SSL verify callback function to view cert chain
1747
* See examples/client/client.c and myVerify() function in test.h
1748
*
1749
* RETURNS:
1750
* returns stack of X509 certs on success, otherwise returns a NULL.
1751
*/
1752
WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s)
1753
{
1754
    int  certIdx = 0;
1755
    WOLFSSL_BUFFER_INFO* cert = NULL;
1756
    DecodedCert* dCert = NULL;
1757
    WOLFSSL_X509* x509 = NULL;
1758
    WOLFSSL_STACK* sk = NULL;
1759
    int found = 0;
1760
1761
    if (s == NULL) {
1762
        return NULL;
1763
    }
1764
1765
    sk = wolfSSL_sk_X509_new_null();
1766
1767
    if (sk == NULL) {
1768
        return NULL;
1769
    }
1770
1771
    for (certIdx = s->totalCerts - 1; certIdx >= 0; certIdx--) {
1772
        /* get certificate buffer */
1773
        cert = &s->certs[certIdx];
1774
1775
        dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
1776
                                                DYNAMIC_TYPE_DCERT);
1777
1778
        if (dCert == NULL) {
1779
            goto error;
1780
        }
1781
        XMEMSET(dCert, 0, sizeof(DecodedCert));
1782
1783
        InitDecodedCert(dCert, cert->buffer, cert->length, NULL);
1784
1785
        /* Parse Certificate */
1786
        if (ParseCert(dCert, CERT_TYPE, NO_VERIFY, NULL)){
1787
            goto error;
1788
        }
1789
        x509 = wolfSSL_X509_new();
1790
1791
        if (x509 == NULL) {
1792
            goto error;
1793
        }
1794
        InitX509(x509, 1, NULL);
1795
1796
        if (CopyDecodedToX509(x509, dCert) == 0) {
1797
1798
            if (wolfSSL_sk_X509_push(sk, x509) <= 0) {
1799
                WOLFSSL_MSG("Unable to load x509 into stack");
1800
                wolfSSL_X509_free(x509);
1801
                x509 = NULL;
1802
                goto error;
1803
            }
1804
        }
1805
        else {
1806
            goto error;
1807
        }
1808
        found = 1;
1809
1810
        FreeDecodedCert(dCert);
1811
        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
1812
        dCert = NULL;
1813
    }
1814
1815
    if (!found) {
1816
        wolfSSL_sk_X509_pop_free(sk, NULL);
1817
        sk = NULL;
1818
    }
1819
    return sk;
1820
1821
error:
1822
    if (dCert) {
1823
        FreeDecodedCert(dCert);
1824
        XFREE(dCert, NULL, DYNAMIC_TYPE_DCERT);
1825
    }
1826
1827
    if (sk)
1828
        wolfSSL_sk_X509_pop_free(sk, NULL);
1829
1830
    return NULL;
1831
}
1832
#endif /* OPENSSL_EXTRA */
1833
1834
#ifdef OPENSSL_ALL
1835
WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects(
1836
    WOLFSSL_X509_STORE* store)
1837
{
1838
    WOLFSSL_STACK* ret = NULL;
1839
    WOLFSSL_STACK* cert_stack = NULL;
1840
#if ((defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)) || \
1841
     (defined(HAVE_CRL)))
1842
    WOLFSSL_X509_OBJECT* obj = NULL;
1843
#endif
1844
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
1845
    WOLFSSL_X509* x509 = NULL;
1846
    int i = 0;
1847
#endif
1848
    WOLFSSL_ENTER("wolfSSL_X509_STORE_get0_objects");
1849
1850
    if (store == NULL || store->cm == NULL) {
1851
        WOLFSSL_MSG("Missing or empty store");
1852
        return NULL;
1853
    }
1854
1855
    if (store->objs != NULL) {
1856
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
1857
        /* want to update objs stack by cm stack again before returning it*/
1858
        X509StoreFreeObjList(store, store->objs);
1859
        store->objs = NULL;
1860
#else
1861
        if (wolfSSL_sk_X509_OBJECT_num(store->objs) == 0) {
1862
            /* Let's try generating the stack again */
1863
            wolfSSL_sk_X509_OBJECT_pop_free(store->objs, NULL);
1864
            store->objs = NULL;
1865
        }
1866
        else
1867
            return store->objs;
1868
#endif
1869
    }
1870
1871
    if ((ret = wolfSSL_sk_X509_OBJECT_new()) == NULL) {
1872
        WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error");
1873
        goto err_cleanup;
1874
    }
1875
1876
#if defined(WOLFSSL_SIGNER_DER_CERT) && !defined(NO_FILESYSTEM)
1877
    cert_stack = wolfSSL_CertManagerGetCerts(store->cm);
1878
    store->numAdded = 0;
1879
    if (cert_stack == NULL && wolfSSL_sk_X509_num(store->certs) > 0) {
1880
        cert_stack = wolfSSL_sk_X509_new_null();
1881
        if (cert_stack == NULL) {
1882
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_new error");
1883
            goto err_cleanup;
1884
        }
1885
    }
1886
    for (i = 0; i < wolfSSL_sk_X509_num(store->certs); i++) {
1887
        if (wolfSSL_sk_X509_push(cert_stack,
1888
                             wolfSSL_sk_X509_value(store->certs, i)) > 0) {
1889
            store->numAdded++;
1890
        }
1891
    }
1892
    /* Do not modify stack until after we guarantee success to
1893
     * simplify cleanup logic handling cert merging above */
1894
    for (i = 0; i < wolfSSL_sk_X509_num(cert_stack); i++) {
1895
        x509 = (WOLFSSL_X509 *)wolfSSL_sk_value(cert_stack, i);
1896
        obj  = wolfSSL_X509_OBJECT_new();
1897
        if (obj == NULL) {
1898
            WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
1899
            goto err_cleanup;
1900
        }
1901
        if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) {
1902
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
1903
            wolfSSL_X509_OBJECT_free(obj);
1904
            goto err_cleanup;
1905
        }
1906
        obj->type = WOLFSSL_X509_LU_X509;
1907
        obj->data.x509 = x509;
1908
    }
1909
1910
    while (wolfSSL_sk_X509_num(cert_stack) > 0) {
1911
        wolfSSL_sk_X509_pop(cert_stack);
1912
    }
1913
#endif
1914
1915
#ifdef HAVE_CRL
1916
    if (store->cm->crl != NULL) {
1917
        int res;
1918
        obj = wolfSSL_X509_OBJECT_new();
1919
        if (obj == NULL) {
1920
            WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error");
1921
            goto err_cleanup;
1922
        }
1923
        if (wolfSSL_sk_X509_OBJECT_push(ret, obj) <= 0) {
1924
            WOLFSSL_MSG("wolfSSL_sk_X509_OBJECT_push error");
1925
            wolfSSL_X509_OBJECT_free(obj);
1926
            goto err_cleanup;
1927
        }
1928
        obj->type = WOLFSSL_X509_LU_CRL;
1929
        wolfSSL_RefInc(&store->cm->crl->ref, &res);
1930
        if (res != 0) {
1931
            WOLFSSL_MSG("Failed to lock crl mutex");
1932
            goto err_cleanup;
1933
        }
1934
        obj->data.crl = store->cm->crl;
1935
    }
1936
#endif
1937
1938
    if (cert_stack)
1939
        wolfSSL_sk_X509_pop_free(cert_stack, NULL);
1940
    store->objs = ret;
1941
    return ret;
1942
err_cleanup:
1943
    if (ret != NULL)
1944
        X509StoreFreeObjList(store, ret);
1945
    if (cert_stack != NULL) {
1946
        while (store->numAdded > 0) {
1947
            wolfSSL_sk_X509_pop(cert_stack);
1948
            store->numAdded--;
1949
        }
1950
        wolfSSL_sk_X509_pop_free(cert_stack, NULL);
1951
    }
1952
    return NULL;
1953
}
1954
#endif /* OPENSSL_ALL */
1955
1956
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) || \
1957
    defined(WOLFSSL_WPAS_SMALL)
1958
WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_get0_param(
1959
        const WOLFSSL_X509_STORE *ctx)
1960
{
1961
    if (ctx == NULL)
1962
        return NULL;
1963
    return ctx->param;
1964
}
1965
1966
#ifdef OPENSSL_EXTRA
1967
int wolfSSL_X509_STORE_set1_param(WOLFSSL_X509_STORE *ctx,
1968
        WOLFSSL_X509_VERIFY_PARAM *param)
1969
{
1970
    if (ctx == NULL)
1971
        return WOLFSSL_FAILURE;
1972
    return wolfSSL_X509_VERIFY_PARAM_set1(ctx->param, param);
1973
}
1974
#endif
1975
#endif
1976
1977
/******************************************************************************
1978
 * END OF X509_STORE APIs
1979
 *****************************************************************************/
1980
1981
#endif /* NO_CERTS */
1982
1983
#endif /* !WOLFCRYPT_ONLY */
1984
1985
#endif /* !WOLFSSL_X509_STORE_INCLUDED */
1986