Coverage Report

Created: 2025-11-16 07:15

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