Coverage Report

Created: 2024-11-21 07:03

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